1275

2つのコミットを1つにマージしようとしているので、gitreadyから「リベースでコミットを押しつぶす」に従いました。

走った

git rebase --interactive HEAD~2

結果のエディターで、に変更picksquashてから保存-終了しますが、リベースがエラーで失敗します

事前のコミットなしで「スカッシュ」することはできません

作業ツリーがこの状態に達したため、回復に問題があります。

コマンドは次のようgit rebase --interactive HEAD~2に失敗します:

インタラクティブリベースはすでに開始されています

git rebase --continue失敗します

事前のコミットなしで「スカッシュ」することはできません

4

14 に答える 14

1872

概要

エラーメッセージ

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

は、「下に押しつぶそう」とした可能性が高いことを意味します。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。)

bpickを に変更するsquashと、先ほど見たエラーが発生しますが、代わりに todo リストを

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オプションが必要です。または、リモート リポジトリの権限によっては、最初に古いブランチを削除してから、リベースされたバージョンをプッシュすることもできます。作業を破壊する可能性のあるコマンドの例は、この回答の範囲外です。

パスワードやその他の機密情報を漏洩するなどの非常に正当な理由なしに他の人と作業しているブランチで既に公開されている履歴を書き換えることは、共同作業者に影響を与え、反社会的であり、他の開発者を悩ませます。ドキュメント「アップストリーム リベースからの回復」セクションでは、git rebase強調を加えて説明しています。

他の人が作業のベースにしているブランチをリベース (またはその他の形式のリライト) することは悪い考えです。その下流にいる人は、自分の履歴を手動で修正することを余儀なくされます。このセクションでは、ダウンストリームの観点から修正を行う方法について説明します。ただし、本当の修正は、そもそもアップストリームのリベースを避けることです。

于 2010-04-02T19:04:45.223 に答える
468

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

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

git reset --soft "HEAD^"
git commit --amend
于 2014-07-11T05:31:04.467 に答える
59

まず、コミットの数を確認する必要があります。

git log

次の 2 つのステータスがあります。

1 つは、コミットが 2 つしかないことです。

例えば:

commit A
commit B

(この場合、git rebase を使用して行うことはできません) 次のことを行う必要があります。

$ git reset --soft HEAD^1

$ git commit --amend

もう 1 つは、2 つ以上のコミットがあることです。コミット 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/をお読みください。

于 2014-05-27T19:01:46.700 に答える
43

あなたが自分のトピックブランチにいたと仮定します。最後の 2 つのコミットを 1 つにマージしてヒーローのように見せたい場合は、最後の 2 つのコミットを行う直前にコミットを分岐します (相対コミット名 HEAD~2 で指定)。

git checkout -b temp_branch HEAD~2

次に、この新しいブランチの他のブランチを squash コミットします。

git merge branch_with_two_commits --squash

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

git commit -m "my message"

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

于 2013-10-23T23:44:46.783 に答える
25

でリベースをキャンセルできます

git rebase --abort

インタラクティブな rebase コマンドを再度実行すると、'squash; commit は、リスト内の pick commit の下にある必要があります

于 2010-04-01T20:59:48.203 に答える
19

私はしばしばgit reset --mixedを使用して、マージしたい複数のコミットの前にベース バージョンを元に戻します。次に、新しいコミットを作成します。これにより、コミットが最新になり、サーバーにプッシュした後にバージョンが HEAD であることを保証できます。

commit ac72a4308ba70cc42aace47509a5e
Author: <me@me.com>
Date:   Tue Jun 11 10:23:07 2013 +0500

    Added algorithms for Cosine-similarity

commit 77df2a40e53136c7a2d58fd847372
Author: <me@me.com>
Date:   Tue Jun 11 13:02:14 2013 -0700

    Set stage for similar objects

commit 249cf9392da197573a17c8426c282
Author: Ralph <ralph@me.com>
Date:   Thu Jun 13 16:44:12 2013 -0700

    Fixed a bug in space world automation

ヘッドの 2 つのコミットを 1 つにマージする場合は、最初に次を使用します。

git reset --mixed 249cf9392da197573a17c8426c282

「249cf9392da197573a17c8426c282」は 3 番目のバージョンであり、マージ前のベース バージョンでもあります。その後、新しいコミットを行います。

git add .
git commit -m 'some commit message'

それだけです、希望は誰にとっても別の方法です。

参考までに、 からgit reset --help:

 --mixed
     Resets the index but not the working tree (i.e., the changed files are
     preserved but not marked for commit) and reports what has not been
     updated. This is the default action.
于 2013-09-09T02:48:53.283 に答える
18

$ git rebase --abort

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

$ git rebase -i HEAD~2

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

  • [最新のコミットが一番下になります]。最後のコミットをスカッシュに変更します。スカッシュは以前のコミットと融合するため。
  • 次に、esc キーを押して :wq と入力し、保存して閉じます。

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

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

2 コミット メッセージが表示されます。1 つを選択するか、独自のコミット メッセージを作成し、保存して終了します [:wq]

注 2: rebase コマンドを実行する場合、変更をリモート リポジトリに強制的にプッシュする必要がある場合があります。

$ git push -f

$ git push -f origin master

于 2017-02-20T21:49:38.510 に答える
4

私は何にでも使うので、ここでも使う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>
于 2015-11-26T10:52:43.060 に答える