web-dev-qa-db-ja.com

GitHubプルリクエストの1つの「適切な」コミットのみにスカッシュ

私はgithubに他の誰か(ボブ、議論のために)がプルリクエストを発行したリポジトリを持っています。彼のコードは完全ではないため、数回のマークアップを行います。私が理解しているように、彼はマークアップされた変更のセットごとにコミットし、プルリクエストにプッシュします。

だから私のリポジトリは次のようになります:

master: ---o A (Chowlett
           |
           |
pull-req:  o---o---o---o
               B   C   D (all Bob)

コミットSHAおよびメッセージは次のとおりです。

A:

123456 Good commit <chowlett>

B:

777ccc Fix the widget bug <bob>

C:

888ddd Review markups <bob>

D:

999eee Further markups <bob>

私は今、このプルリクエストを受け入れて満足しています。しかし、私はむしろ事前マークアップバージョンが私のリポジトリにないことを望みます。次のすべてを達成できますか?そしてどうやって?

  • B、C、Dを1つのコミットとして私のリポジトリにマージ
  • 「プルリクエストのマージ#99を...に」コミットも生成します
  • Githubに自動的にプルリクエストを閉じさせる
46
Chowlett

ボブはGitHub PRを作成しているときにコミットを押しつぶす必要がないことに注意してください。
2016年3月以降、PRを受け入れるメンテナ(あなた)にその操作を任せることができます。

" Squash your commits "とその 新しいドキュメント を参照してください

これは、マージボタンを使用してマージされたすべてのプルリクエストに対して強制的にスカッシュを強制できる新しいオプションです。

https://help.github.com/assets/images/help/pull_requests/squash-and-merge.png

17
VonC

gitには、2つの「スカッシュ」関数が組み込まれています。 git merge --squashがあり、git rebase --interactiveにはsquashアクションがあります。前者は作者や日付の情報を保持せず、一連のコミットからすべての変更をローカルの作業コピーに収集するだけです。後者は対話を必要とするため、迷惑です。

git squash拡張子 は必要なことを行います。現在のHEADを指定したベースにリベースし、その間にコミットを自動的に押しつぶします。また、リベースが失敗した場合に、最後の押しつぶされたコミットにメッセージを設定するコマンドラインオプションを提供しますt衝突を引き起こします。

これを hub および ghi と一緒に投げると、次の行に沿ってスクリプトを作成できる場合があります。

git pull upstream master
hub checkout https://github.com/$user/$repo/pull/$issue
git squash master
rev=$(git rev-parse --short HEAD)
git checkout master
git merge $rev
git commit --amend "Merged pull request #$issue"
git Push upstream master
ghi close $issue $user/$repo
ghi comment $issue "Merged as $rev" $user/$repo 
10
joeln

マージには--squashオプションを使用できます

git merge <remote url> <remote branch> --squash

ただし、これはマージコミットを生成しません。代わりに、手動ですべての変更をコピーに適用した場合と同じように、通常の作業ツリーの変更セットを生成します。その後、通常どおりにコミットします。

欠点は、マスターの履歴にこのコミットが彼のブランチからのマージとして表示されないことです。それはあなたが自分で仕事をしたように見え、ボブにクレジットを与えません。

9
D-Rock

Git rebaseを使用する

1つのアイデアは、ブランチをチェックアウトし、反復リベースを使用してすべてのコミットを1つに押しつぶし、Pushにプルリクエストを更新させてマージすることです(ただし、この作業の一部をBobに委任することもできます)。

ブランチから最初のコミットにすべてのコミットを自動的に押しつぶし、これをプルリクエストに適用するには、次のコマンドを使用できます。

$ git checkout pull-req
$ GIT_SEQUENCE_EDITOR='sed -i "2,\$s/^pick/s/g" $1' git rebase -i Origin/master
$ git Push --force

GIT_SEQUENCE_EDITOR は、リベースコミットリストの一時エディターを設定するためのGit環境変数です。最初の行(pickパターンの2,\$)を除くすべての行の先頭で、Wordのssquash(つまりsed)に置き換えるインラインスクリプトに設定します。スクリプトに渡されるコミットリストは、単純なテキストファイルです。その後、Gitはリベースを続行し、最終的なコミットメッセージを編集できるようにします。

また、gitフックを使用すると、この最終メッセージを必要に応じて多かれ少なかれ簡単に編集できます(たとえば、押しつぶされたコミットのメッセージの間に視覚的な区切りを追加します)。

Git merge --squashの使用

git merge --squashを使用してスカッシュすることもできます。 2つの方法の違いについては こちら を参照してください。以下のスクリプトは、mergeコマンドを使用して、ブランチのコミットを1つのコミットに押しつぶします。また、ブランチのバックアップも作成します(念のため)。

MAINBRANCH="master"    
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

# update current feature branch with master
git pull Origin $MAINBRANCH

# delete existing backup
git branch -D "$CURRENT_BRANCH-backup"

# backup current feature branch and go back
git checkout -b "$CURRENT_BRANCH-backup" && git checkout -

# checkout and update master branch
git checkout $MAINBRANCH && git pull

# create new branch from master
git checkout -b "$CURRENT_BRANCH-squashed"

# set it to track the corresponding feature branch
git branch "$CURRENT_BRANCH-squashed" --set-upstream-to "$CURRENT_BRANCH"

# merge and squash the feature branch into the one created
git merge --squash $CURRENT_BRANCH

# commit the squashed changes
git commit

# force Push to the corresponding feature branch
git Push -f . HEAD:$CURRENT_BRANCH

# checkout the feature branch
git checkout $CURRENT_BRANCH

# delete the squashed copy
git branch -D "$CURRENT_BRANCH-squashed"
2
Samir Aguiar

これでうまくいきました。

  • devtools_import_exportでの私の仕事はそのまま残ります。
  • アップストリーム/マスターへのissue35squashedのプルリクエストには、コミットが1つしかありません。
  • 残念ながら、マージは記録されていませんが、コミットメッセージにはすべての詳細が含まれています。

これが私が実際に行ったことです( https://github.com/anaran/devtools-snippets/network を参照)

git checkout master
git status # all clean
git checkout -B issue35squashed master
git merge --squash devtools_import_export
git status # looks good
git commit # review and commit via emacs
git log --graph --abbrev-commit --stat --pretty --decorate=full --branches
git Push --all -v

git merge --no-ff ...を使用した私の以前の試みはissue35take2にあり、そのプルリクエストにはdevtools_import_exportからの個々のコミットがすべて含まれています。不正解です。)

1
stackunderflow