web-dev-qa-db-ja.com

すでにリベースを開始している場合、2つのコミットを1つにマージする方法はありますか。

2つのコミットを1つにマージしようとしているので、git readyの 「コミットをrebaseで潰す」 に従ってください。

私は走った

git rebase --interactive HEAD~2

結果のエディタで、picksquashに変更してからsave-quitしますが、リベースはエラーで失敗します。

前回のコミットなしでは「潰す」ことはできません

作業ツリーがこの状態になったので、復旧できません。コマンドgit rebase --interactive HEAD~2は失敗して失敗します

対話式リベースはすでに開始されています

そしてgit rebase --continueは失敗します

前回のコミットなしでは「潰す」ことはできません

1072
michael

概要

エラーメッセージ

前回のコミットなしでは「スカッシュ」できません

おそらく「下方に押しつぶす」ことを試みたことを意味します。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のpicksquashに変更すると、エラーが表示されますが、代わりに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ドキュメンテーションの「アップストリームリベースからの回復」セクション に、さらに重点を置いて説明しています。

他の人が作業のベースにしているブランチをリベース(または他の形式の書き換え)するのは悪い考えです。このセクションでは、ダウンストリームの観点から修正方法を説明します。 ただし、実際の修正は、最初にアップストリームのリベースを回避することです。

1675
Greg Bacon

コミットが複数ある場合は、git rebase -iを使用して2つのコミットを1つにまとめることができます。

マージしたいコミットが2つしかなく、それらが「最新の2つ」である場合は、次のコマンドを使用して2つのコミットを1つにまとめることができます。

git reset --soft "HEAD^"
git commit --amend
372
user3828059

Rebase:あなたはそれを必要としないのです:

最も頻繁なシナリオのためのより簡単な方法。

ほとんどの場合:

実際に必要なのは 最近のいくつかのコミットを1つにまとめるだけです しかしdropreword、その他のリベース作業は不要です。

あなたは単にすることができます:

git reset --soft "HEAD~n"
  • ~nがそっとアンコミットするためのコミットの数であると仮定します(すなわち~1~2、...)。

その後、次のコマンドを使用してコミットメッセージを修正します。

git commit --amend

これは長い範囲のsquashと1つのpickとほとんど同じです。

そしてそれは上の答えが促したようにn回のコミットではなく2回のコミットではうまくいきます。

81
pambda

まず、コミット数を確認してください。

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/ を読んでください。

52
Haimei

あなたがあなた自身のトピックブランチにいたと仮定します。最後の2つのコミットを1つにマージして英雄のように見たい場合は、最後の2つのコミットを行う直前にコミットを分岐してください。

git checkout -b temp_branch HEAD^2

それからこの新しいブランチの他のブランチをスカッシュコミットします。

git merge branch_with_two_commits --squash

それは変更をもたらしますが、それらをコミットしません。だからそれらをコミットするだけで完了です。

git commit -m "my message"

これで、この新しいトピックブランチをあなたのメインブランチにマージすることができます。

28
Homan

あなたはでリベースをキャンセルすることができます

git rebase --abort

そして対話的なrebaseコマンドをもう一度実行すると 'スカッシュ。コミットはリスト内の選択コミットの下になければなりません

22
Leom Burke

$ git rebase --abort

Git rebaseを元に戻したい場合は、いつでもこのコードを実行してください。

$ git rebase -i HEAD~2

最後の2つのコミットを再適用します。上記のコマンドはコードエディタを開きます

  • [ 最新のコミットは一番下になります ]。最後のコミットをsquashに変更してください。カボチャは前回のコミットと融合するので。
  • 次にescキーを押して「wq」と入力し、保存して閉じます。

の後:wqあなたはアクティブなリベースモードになります

:警告/エラーメッセージが表示されない場合は別のエディタが表示されます。エラーが発生した場合や別のエディタが表示されない場合は$ git rebase --abortを実行して中止できます。それ以外の場合は$ git rebase --continueを実行して続行します

2コミットメッセージが表示されます。一つ選択するか、あなた自身のコミットメッセージを書いて保存して終了してください:[:wq]

注2: rebaseコマンドを実行した場合は、強制的に変更内容をリモートリポジトリにプッシュする必要があるかもしれません。

$ git Push -f

$ git Push -f Origin master

11
Gnanasekar S

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

最近の2つのコミットを結合して古いコミットのメッセージだけを使用したい場合は、 expect を使用してプロセスを自動化できます。

私が想定し:

  • あなたはあなたのエディタとしてviを使っています
  • あなたのコミットはそれぞれ一行です

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

あなたのマスターブランチ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つのコミットをマージしたい場合は、次の簡単な手順を実行してください。

  1. 最初に安全なサイドチェックアウトを行い、最後の2番目のコミットを別のブランチに入れます。ブランチには何でも名前を付けることができます。 git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
  2. それでは、最後のコミットからこの新しいブランチへの変更点を、git cherry-pick -n -x ac72a4308ba70cc42aace47509a5eとして選択してください。 (競合が発生した場合は解決します)
  3. だから今、あなたの最後のコミットの変更はあなたの2番目の最後のコミットにあります。しかし、まだコミットする必要があるので、最初に選択した変更を追加してから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
1
Undefined