web-dev-qa-db-ja.com

古いGitコミットを修正する方法は?

3つのgitコミットを行いましたが、プッシュされていません。古いもの(ddc6859af44)と最新のものではない(47175e84c)を修正するにはどうすればよいですか?

$git log
commit f4074f289b8a49250b15a4f25ca4b46017454781
Date:   Tue Jan 10 10:57:27 2012 -0800

commit ddc6859af448b8fd2e86dd0437c47b6014380a7f
Date:   Mon Jan 9 16:29:30 2012 -0800

commit 47175e84c2cb7e47520f7dde824718eae3624550
Date:   Mon Jan 9 13:13:22 2012 -0800
141
michael
git rebase -i HEAD^^^

ここで、修正したいものをeditまたはeでマークします(pickを置き換えます)。ここで保存して終了します。

変更を加えてから、

git add -A
git commit --amend --no-edit
git rebase --continue

追加の削除を追加する場合は、commitコマンドからオプションを削除します。メッセージを調整する場合は、--no-editオプションのみを省略してください。

178
Adam Dymitruk

古いもので修正したいコミットを準備しましたが、リベース-iが変更をコミットしていないと不満を言うのを見て驚きました。しかし、古いコミットの編集オプションを指定して、もう一度変更を加えたくありませんでした。そのため、ソリューションは非常に簡単で簡単でした。

  1. 古いコミットへの更新を準備し、追加してコミットします
  2. git rebase -i <commit you want to amend>^-^に注意してください。テキストエディターに上記のコミットが表示されます。
  3. 次のようになります。

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
    pick e23d23a fix indentation of jgroups.xml
    
  4. e23d23aと8c83e24を組み合わせるために、行の順序を変更し、次のようにスカッシュを使用できます。

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync    
    squash e23d23a fix indentation of jgroups.xml
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
    
  5. ファイルを書き込んで終了すると、コミットメッセージをマージするためのエディターが表示されます。そうしてテキスト文書を保存/終了します

  6. 完了し、コミットが修正されました

クレジット: http://git-scm.com/book/en/Git-Tools-Rewriting-History 他にも便利なデモンストレーションされたgitマジックがあります。

99
akostadinov

git rebaseを使用して、コミット履歴を書き換えることができます。これは変更を破壊する可能性があるため、注意して使用してください。

最初に、通常のコミットとして「修正」の変更をコミットします。次に、最も古いコミットの親から対話型のリベースを開始します

git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^

これにより、すべてのコミットでエディターが起動します。 「修正」コミットが修正したいコミットより下になるように、それらを並べ替えます。次に、行の最初のWordを「修正」コミットのsに置き換えます。これは、それを前のコミットと結合(s quash)します。エディターを保存して終了し、指示に従います。

13

私は数回、別の方法を使用しました。実際、それは手動のgit rebase -iであり、いくつかのコミットを押しつぶしたり分割したりするなど、いくつかのコミットを再配置したい場合に便利です。主な利点は、すべてのコミットの運命を一度に決定する必要がないことです。また、リベース中とは異なり、プロセス中にすべてのGit機能を使用できます。たとえば、元の履歴と書き換えられた履歴の両方のログをいつでも表示したり、別のリベースを実行することもできます!

以下の方法でコミットを参照するので、簡単に読むことができます。

C # good commit after a bad one
B # bad commit
A # good commit before a bad one

最初の履歴は次のようになります。

x - A - B - C
|           |
|           master
|
Origin/master

このように再作成します。

x - A - B*- C'
|           |
|           master
|
Origin/master

手順

git checkout B       # get working-tree to the state of commit B
git reset --soft A   # tell Git that we are working before commit B
git checkout -b rewrite-history   # switch to a new branch for alternative history

git addgit add -igit stashなど)を使用して、古いコミットを改善します。古いコミットを2つ以上に分割することもできます。

git commit           # recreate commit B (result = B*)
git cherry-pick C    # copy C to our new branch (result = C')

中間結果:

x - A - B - C 
|    \      |
|     \     master
|      \
|       B*- C'
|           |
|           rewrite-history
|
Origin/master

終わりましょう:

git checkout master
git reset --hard rewrite-history  # make this branch master

これで、Push進捗状況を確認できます。

11
Melebius

git rebase --interactive を使用して、修正するコミットでeditコマンドを使用できます。

10
Avi

OPが1に指定された2つのコミットをスカッシュしたい場合は、リベースせずにそれを行う別の方法があります

git checkout HEAD^               # go to the first commit you want squashed
git reset --soft HEAD^           # go to the second one but keep the tree and index the same
git commit --amend -C HEAD@{1}   # use the message from first commit (omit this to change)
git checkout HEAD@{3} -- .       # get the tree from the commit you did not want to touch
git add -A                       # add everything
git commit -C HEAD@{3}           # commit again using the message from that commit

@{N)構文は、参照した場所の履歴を参照できるため便利です。この場合、現在のコミットを表すHEADです。

2
Adam Dymitruk