215

A、BCの 3 つのコミットを含む履歴があるとします。

A-B-C

2 つのコミットABを 1 つのコミットABに結合したいと思います。

AB-C

私は試した

git rebase -i A

これにより、次の内容でエディターが開きます。

pick e97a17b B
pick asd314f C

これを次のように変更します

squash e97a17b B
pick asd314f C

次に、Git 1.6.0.4 は次のように述べています。

Cannot 'squash' without a previous commit

方法はありますか、それとも不可能ですか?

4

8 に答える 8

195

git rebase -i --root Gitバージョン 1.7.12 以降で使用します。

インタラクティブなリベース ファイルで、コミットBの 2 行目をsquashに変更し、残りの行はpickのままにします。

pick f4202da A
squash bea708e B
pick a8c6abc C

これにより、2 つのコミットABが 1 つのコミットABに結合されます。

この回答にあります。

于 2014-02-09T02:14:48.493 に答える
126

あなたがしようとした:

git rebase -i A

editではなく続行すると、そのように開始できますsquash

edit e97a17b B
pick asd314f C

次に実行します

git reset --soft HEAD^
git commit --amend
git rebase --continue

終わり。

于 2009-02-12T14:29:00.527 に答える
66

A最初のコミットでしたが、今度は最初のコミットになりたいと思いますB。git commitはツリー全体であり、それらが導入するdiffの観点から通常記述および表示されている場合でも、diffではありません。

このレシピは、AとB、およびBとCの間に複数のコミットがある場合でも機能します。

# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>

# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>

# amend the initial tree using the tree from 'B'
git commit --amend

# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp

# go back to the original branch (assume master for this example)
git checkout master

# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>

# remove the temporary tag
git tag -d tmp
于 2009-01-12T18:46:20.810 に答える
10

インタラクティブなリベースの場合、リストが次のようになるように、A の前にそれを行う必要があります。

pick A
pick B
pick C

なる:

pick A
squash B
pick C

A が最初のコミットである場合、A の前に別の最初のコミットを行う必要があります。Git は違いを考慮し、(A と B) と (B と C) の違いで機能します。したがって、スカッシュはあなたの例では機能しません。

于 2009-01-12T15:05:39.883 に答える
10

数百または数千のコミットがある場合、kostmo の回答を使用して

git rebase -i --root

リベース スクリプトが2 回処理しなければならないコミットの数が多いため、実用的ではなく、遅くなる可能性があります。コミットの再適用。

最初に対話型リベースを使用しないことで、対話型リベース エディター リストを生成する時間コストを回避する代替ソリューションを次に示します。このように、Charles Bailey のソリューションに似ています。2 番目のコミットから孤立したブランチを作成し、その上にすべての子孫コミットをリベースするだけです。

git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master

ドキュメンテーション

于 2014-07-23T15:00:27.867 に答える
1

関連する質問で、私は最初のコミットに対して押しつぶす必要がある別のアプローチを考え出すことができました。

興味がある場合: git: 最初にコミットを挿入し、他のすべてをシフトする方法は?

于 2009-03-14T08:15:03.477 に答える
0

分隊の Git コマンド: git rebase -i HEAD~[コミット数]

以下の git commit 履歴があるとします。


pick 5152061 feat: 画像保存のサポートが追加されました。(A)
pick 39c5a04 Fix: バグ修正。(B)
839c6b3 修正を選択: 競合が解決されました。(ハ)

A と B を AB にスカッシュするには、以下の手順を実行します。


pick 5152061 feat: 画像保存のサポートが追加されました。(A)
s 39c5a04 修正: バグ修正。(B)
839c6b3 修正を選択: 競合が解決されました。(ハ)

注: コミットのスカッシュには、squash または s を使用できます。最終結果は次のようになります:
pick 5152061 feat: 画像保存のサポートが追加されました。(AB)
839c6b3 の修正を選択: 競合が解決されました。(ハ)

于 2018-11-22T06:35:18.700 に答える
-1

コマンドラインの魔法を少し実行する必要があります。

git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a

これで、コミットとしてABとCを持つブランチが残ります。

于 2009-01-12T15:36:17.530 に答える