2つのコミットを1つにマージしようとしているので、git readyの 「コミットをrebaseで潰す」 に従ってください。
私は走った
git rebase --interactive HEAD~2
結果のエディタで、pick
をsquash
に変更してからsave-quitしますが、リベースはエラーで失敗します。
前回のコミットなしでは「潰す」ことはできません
作業ツリーがこの状態になったので、復旧できません。コマンドgit rebase --interactive HEAD~2
は失敗して失敗します
対話式リベースはすでに開始されています
そしてgit rebase --continue
は失敗します
前回のコミットなしでは「潰す」ことはできません
エラーメッセージ
前回のコミットなしでは「スカッシュ」できません
おそらく「下方に押しつぶす」ことを試みたことを意味します。Gitは常に、より新しいコミットを古いコミットに押しつぶしますまたはインタラクティブなリベースtodoリストで表示される「上方」 、それは前の行のコミットです。 ToDoリストの最初の行のコマンドをsquash
に変更すると、最初のコミットが押しつぶされることがないため、常にこのエラーが発生します。
最初に元の場所に戻ります
$ git rebase --abort
あなたの歴史は
$ git log --pretty=oneline
a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c
b76d157d507e819d7511132bdb5a80dd421d854f b
df239176e1a2ffac927d8b496ea00d5488481db5 a
つまり、aが最初のコミットで、次にb、最後にcでした。 cをコミットした後、bとcを一緒に押しつぶすことにします。
(注:git log
を実行すると、出力がページャにパイプされます。ほとんどのプラットフォームでは、デフォルトで less
。ページャを終了してコマンドプロンプトに戻るには、q
キーを押します。 )
git rebase --interactive HEAD~2
を実行すると、エディターが提供されます。
pick b76d157 b
pick a931ac7 c
# Rebase df23917..a931ac7 onto df23917
#
# 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
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
(このtodoリストはgit log
の出力と比較すると逆順であることに注意してください。)
Bのpick
をsquash
に変更すると、エラーが表示されますが、代わりにtodoリストを変更してcをbに押しつぶします(より古いコミットまたは「上に押しつぶす」)
pick b76d157 b
squash a931ac7 c
エディターを保存終了すると、コンテンツが別のエディターになります
# This is a combination of 2 commits.
# The first commit's message is:
b
# This is the 2nd commit message:
c
保存して終了すると、編集されたファイルの内容は、新しい結合コミットのコミットメッセージになります。
$ git log --pretty=oneline
18fd73d3ce748f2a58d1b566c03dd9dafe0b6b4f b and c
df239176e1a2ffac927d8b496ea00d5488481db5 a
インタラクティブなリベースは履歴を書き換えます。古い履歴を含むリモートへのプッシュは、早送りではないため失敗します。
リベースしたブランチがトピックまたは機能ブランチである場合自分で作業している、大したことはありません。別のリポジトリにプッシュするには--force
オプションが必要です。または、リモートリポジトリの権限に応じて、最初に古いブランチを削除してからリベースバージョンをプッシュすることもできます。潜在的に作業を破壊するこれらのコマンドの例は、この回答の範囲外です。
veryを使用せずに他の人と作業しているブランチで既に公開された履歴を書き換えると、パスワードやその他の機密情報を漏らすなどの正当な理由が協力者に働き、反社会的であり、他の開発者を悩ますでしょう。 git rebase
ドキュメンテーションの「アップストリームリベースからの回復」セクション に、さらに重点を置いて説明しています。
他の人が作業のベースにしているブランチをリベース(または他の形式の書き換え)するのは悪い考えです。このセクションでは、ダウンストリームの観点から修正方法を説明します。 ただし、実際の修正は、最初にアップストリームのリベースを回避することです。…
コミットが複数ある場合は、git rebase -i
を使用して2つのコミットを1つにまとめることができます。
マージしたいコミットが2つしかなく、それらが「最新の2つ」である場合は、次のコマンドを使用して2つのコミットを1つにまとめることができます。
git reset --soft "HEAD^"
git commit --amend
最も頻繁なシナリオのためのより簡単な方法。
実際に必要なのは 最近のいくつかのコミットを1つにまとめるだけです しかしdrop
、reword
、その他のリベース作業は不要です。
git reset --soft "HEAD~n"
~n
がそっとアンコミットするためのコミットの数であると仮定します(すなわち~1
、~2
、...)。その後、次のコマンドを使用してコミットメッセージを修正します。
git commit --amend
これは長い範囲のsquash
と1つのpick
とほとんど同じです。
そしてそれは上の答えが促したようにn回のコミットではなく2回のコミットではうまくいきます。
まず、コミット数を確認してください。
git log
2つのステータスがあります。
1つは、 only 2つのコミットがあることです。
例えば:
commit A
commit B
(この場合、git rebaseを使うことはできません)次のようにする必要があります。
$ git reset --soft HEAD^1
$ git commit --amend
もう1つは、コミットが3つ以上あるということです。コミットCとDをマージします。
例えば:
commit A
commit B
commit C
commit D
(この状態では、git rebaseを使えます)
git rebase -i B
そして「スカッシュ」を使うよりも。残りは非常に簡単です。それでもわからない場合は、 http://zerodie.github.io/blog/2012/01/19/git-rebase-i/ を読んでください。
あなたがあなた自身のトピックブランチにいたと仮定します。最後の2つのコミットを1つにマージして英雄のように見たい場合は、最後の2つのコミットを行う直前にコミットを分岐してください。
git checkout -b temp_branch HEAD^2
それからこの新しいブランチの他のブランチをスカッシュコミットします。
git merge branch_with_two_commits --squash
それは変更をもたらしますが、それらをコミットしません。だからそれらをコミットするだけで完了です。
git commit -m "my message"
これで、この新しいトピックブランチをあなたのメインブランチにマージすることができます。
あなたはでリベースをキャンセルすることができます
git rebase --abort
そして対話的なrebaseコマンドをもう一度実行すると 'スカッシュ。コミットはリスト内の選択コミットの下になければなりません
$ git rebase --abort
Git rebaseを元に戻したい場合は、いつでもこのコードを実行してください。
$ git rebase -i HEAD~2
最後の2つのコミットを再適用します。上記のコマンドはコードエディタを開きます
の後:wqあなたはアクティブなリベースモードになります
注 :警告/エラーメッセージが表示されない場合は別のエディタが表示されます。エラーが発生した場合や別のエディタが表示されない場合は$ git rebase --abort
を実行して中止できます。それ以外の場合は$ git rebase --continue
を実行して続行します
2コミットメッセージが表示されます。一つ選択するか、あなた自身のコミットメッセージを書いて保存して終了してください:[:wq]
注2: rebaseコマンドを実行した場合は、強制的に変更内容をリモートリポジトリにプッシュする必要があるかもしれません。
$ git Push -f
$ git Push -f Origin master
私はgit cherry-pick
をほぼすべてのものに使っているので、ここでもそうするのは自然なことです。
私はbranchX
がチェックアウトしていて、その先端に2つのコミットがあるので、それらの内容を組み合わせて1つのコミットを作成したいのですが、これを行います。
git checkout HEAD^ // Checkout the privious commit
git cherry-pick --no-commit branchX // Cherry pick the content of the second commit
git commit --amend // Create a new commit with their combined content
もしbranchX
も同様に更新したいのであれば(そしてこれがこのメソッドの悪い面であると思います)、私はまたそうしなければなりません:
git checkout branchX
git reset --hard <the_new_commit>
最近の2つのコミットを結合して古いコミットのメッセージだけを使用したい場合は、 expect
を使用してプロセスを自動化できます。
私が想定し:
私はgit version 2.14.3 (Apple Git-98)
でテストしました。
#!/usr/bin/env expect
spawn git rebase -i HEAD~2
# down, delete Word, insert 's' (for squash), Escape, save and quit
send "jdwis \033:wq\r"
expect "# This is a"
# down 4, delete 3 lines, save and quit
send "4j3d\r:wq\r"
interact
あなたのマスターブランチgit log
が次のようになっているとします。
commit ac72a4308ba70cc42aace47509a5e
Author: <[email protected]>
Date: Tue Jun 11 10:23:07 2013 +0500
Added algorithms for Cosine-similarity
commit 77df2a40e53136c7a2d58fd847372
Author: <[email protected]>
Date: Tue Jun 11 13:02:14 2013 -0700
Set stage for similar objects
commit 249cf9392da197573a17c8426c282
Author: Ralph <[email protected]>
Date: Thu Jun 13 16:44:12 2013 -0700
Fixed a bug in space world automation
上位2つのコミットをマージしたい場合は、次の簡単な手順を実行してください。
git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
git cherry-pick -n -x ac72a4308ba70cc42aace47509a5e
として選択してください。 (競合が発生した場合は解決します)git commit --amend
を実行します。それでおしまい。お望みなら、このマージバージョンをブランチ "merged-commits"にプッシュすることもできます。
また、マスターブランチで2つのコミットを続けて破棄することもできます。マスターブランチを以下のように更新するだけです。
git checkout master
git reset --hard Origin/master (CAUTION: This command will remove any local changes to your master branch)
git pull