46

私は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>

子:

888ddd Review markups <bob>

D:

999eee Further markups <bob>

このプルリクエストを喜んで受け入れます。しかし、マークアップ前のバージョンが私のレポになかったほうがいいです。次のすべてを達成できますか?そしてどうやって?

  • B、C、D を 1 つのコミットとしてリポジトリにマージする
  • 「Merge pull request #99 into ...」コミットも生成します
  • プル リクエストを github に自動的にクローズさせる
4

5 に答える 5

17

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

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

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

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

于 2016-04-02T18:51:29.543 に答える
10

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

git squash拡張機能は、必要なことを行います。現在の HEAD を指定されたベースにリベースし、間にコミットを自動的に押しつぶします。また、リベースによって競合が発生しない場合に、最終的に押しつぶされたコミットでメッセージを設定するコマンドライン オプションも提供します。

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 
于 2013-05-13T03:24:51.740 に答える
9

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

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

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

欠点は、マスターの履歴がこのコミットを彼のブランチからのマージとして表示しないことです。自分で作業を行ったように見えるだけで、Bob の功績は認められません。

于 2012-07-31T17:41:26.367 に答える
3

git リベースの使用

1 つのアイデアは、ブランチをチェックアウトし、反復リベースを使用してすべてのコミットを 1 つにスカッシュし、プッシュを強制してプル リクエストを更新し、マージすることです (ただし、この作業の一部は 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 環境変数です。最初の行を除くすべての行の先頭にある単語picks(という意味の ) に置き換えるインライン スクリプトに設定します(これはパターン内の です)。スクリプトに渡されるコミット リストは単純なテキスト ファイルです。その後、Git はリベースを続行し、最終的なコミット メッセージを編集できるようにします。squash2,\$sed

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

git merge --squash の使用

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

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"
于 2015-12-23T20:56:07.183 に答える