私はgitのリベース機能全体に少し慣れています。私が次のコミットをしたとしましょう:
A -> B -> C -> D
その後、D
に追加されたいくつかの新しいコードに依存する修正がA
に含まれており、これらのコミットが一緒になっていることに気付きました。 A
&D
をまとめてスカッシュし、B
&C
をそのままにする方法を教えてください。
git rebase --interactive
を実行し、Bの前にDを並べ替え、DをAに押しつぶすことができます。
Gitはエディターを開き、次のようなファイルが表示されます。
pick aaaaaaa Commit A
pick bbbbbbb Commit B
pick ccccccc Commit C
pick ddddddd Commit D
# Rebase aaaaaaa..ddddddd onto 1234567 (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using Shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
ここで、ファイルを次のように変更します。
pick aaaaaaa Commit A
squash ddddddd Commit D
pick bbbbbbb Commit B
pick ccccccc Commit C
GitはAとDの変更を1つのコミットにまとめ、その後BとCをコミットします。 Dのコミットメッセージを保持したくない場合は、「fix」キーワードを使用することもできます。
注意:プッシュされたコミットを変更しないでくださいは、 結果を知っている場合を除き、何らかの方法で別のリポジトリにする必要があります。
git log --oneline -4
D commit_message_for_D
C commit_message_for_C
B commit_message_for_B
A commit_message_for_A
git rebase --interactive
pick D commit_message_for_D
pick C commit_message_for_C
pick B commit_message_for_B
pick A commit_message_for_A
タイプi
(挿入モードでVIM)
リストを次のように変更します(コミットメッセージを削除または含める必要はありません)。 squash
!のスペルを間違えないでください!:
pick C commit_message_for_C
pick B commit_message_for_B
pick A commit_message_for_A
squash D
タイプ Esc 次にZZ
(VIMを保存して終了)
# This is a combination of 2 commits.
# The first commit's message is:
commit_message_for_D
# This is the 2nd commit message:
commit_message_for_A
タイプi
テキストを、新しいコミットメッセージの外観に変更します。これをcommit A
およびD
の変更の説明にすることをお勧めします。
new_commit_message_for_A_and_D
タイプ Esc 次にZZ
git log --oneline -4
E new_commit_message_for_A_and_D
C commit_message_for_C
B commit_message_for_B
git show E
(You should see a diff showing a combination of changes from A and D)
これで、新しいコミットE
が作成されました。コミットA
およびD
は履歴にありませんが、消えていません。この時点でしばらくは、git rebase --hard D
(git rebase --hard
はローカルの変更を破棄します!)。
SourceTree を使用している場合:
コミットをプッシュしていないことを確認してください。
Squash with previous
をクリックしますインタラクティブなリベースは、ブランチでコミットしている間に20-30のコミットやマスターからのマージのカップル、または競合を修正する大きな機能ブランチができるまでうまく機能します。履歴からコミットを見つけ、pick
をsquash
に置き換えても、ここでは機能しません。だから私は別の方法を探していて、これを見つけました 記事 。私はこれを別のブランチで動作するように変更しました:
git checkout master
git fetch
git pull
git merge branch-name
git reset Origin/master
git branch -D branch-name
git checkout -b branch-name
git add --all
#Do some commit
git Push -f --set-upstream Origin branch-name
この前に、マスターからの2〜3回のマージと競合の修正を含む約30のコミットでプルリクエストを受け取りました。そしてこの後、私は1回のコミットで明確なPRを得ました。
追伸自動モードでこの手順を実行するには、bash script を使用します。