回答:
git rebase --interactive
D を実行してBの前に並べ替え、DをAにスカッシュできます。
Gitがエディターを開き、次のようなファイルが表示されます。 git rebase --interactive HEAD~4
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ではなく、Dのコミットメッセージを保持したくないsquash
場合は、fixup
キーワードを使用します。詳細fixup
については、git rebase
ドキュメントを参照するか、いくつかの良い答えがあるこの質問をチェックしてください。
There is no tracking information for the current branch
リベース時にエラーが発生します。この場合、次のように、処理するコミットの数を指定する必要がありますgit rebase -i HEAD~4
。この回答を参照してください。
注:結果がわかっていない限り、別のリポジトリにプッシュされたコミットを変更しないでください。
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
新しいコミットメッセージをどのように表示するかをテキストに変更します。私は、このコミットの変更の説明であることをお勧めします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を取得しました。
PSは、自動モードでこの手順を実行するためのbash スクリプトです。
$ gitチェックアウトマスター
$ git log --oneline
D
C
B
A
$ git rebase --onto HEAD ^^^ HEAD ^
$ git log --oneline
D
A
--oneline
か?そして、あなたが落としたように見えます、C
そしてB
、それはOPが意図していたものではありません。
git show A
)にマージせず、D、C、Bは私の参照ログで失われました。しなければならなかったgit rebase D
取り戻すために。