Magitを使用して以前のコミットに変更を追加する


43

プッシュの準備ができている2つのコミット、A、Bがあります。Aに何かを追加するのを忘れたことに気付きました。

Magitを使用してこの変更をAに追加するにはどうすればよいですか?Gitドキュメントのどの部分を見るべきかさえわかりません。

回答:


68

少しの間、HEADコミットに何かを追加するふりをしましょう。例では、「2番目のコミットB」です。

上のコミットポップアップにcは、バインディング「a修正」があります。そのキーを押すと、HEADコミットに対する段階的な変更が「修正」されます。Gitではコミットは変更できないため、実際には古いコミットが新しいコミットに置き換えられます。古いコミットメッセージのあるバッファがポップアップ表示されるため、追加した変更でメ​​ッセージの調整が必要になった場合に変更できます。いつものように、C-c C-cメッセージの編集が終了したらを押します。これはgit commit --amend、コマンドラインで実行するのと同じです。

  • a 改正 -への段階的な変化を追加しHEADてコミットメッセージや編集を

多くの場合、変更またはメッセージを調整するだけでよいため、Magitには次の2つのバリエーションがあります。

  • e 拡張 - HEADコミットメッセージを編集せずに段階的な変更を追加します
  • w 言い換え - HEAD段階的な変更を追加せずにメッセージを変更します

でないコミットを編集するHEAD場合、上記は機能しません。これらのコマンドは、HEADコミットを常に「変​​更」(置換)します。Gitはコミットを変更するための単一のコマンドを提供しませんHEADが、これはもう少し複雑です。

Magit そのようなコマンドを提供ますが、複数のステップでこれを行うことが望ましい状況があるため、最初にそれについて説明します。

コミット以外の変更は、HEAD3つのステップに分割できます。

  1. 一時的にその他のcommit(A)を作成しHEADます。
  2. HEAD(上記のように)変更して、commitを作成しA'ます。
  3. 続いコミットを再適用するためにGitを知らせるAが、の上A'

これは、インタラクティブなリベースを使用して実行できます。タイプrして、リベースポップアップを表示します。次にm、「コミットの編集」リベースバリアントを呼び出すために入力します。最近のコミットを含むバッファが表示されます。変更するコミットに移動し、入力C-c C-cして選択します。その後、Gitはそのコミットに履歴を巻き戻し、進行中のリベースに関する情報をステータスバッファーに表示します。

HEAD上記のように変更します。次に、を入力して完了したことをGitに伝えますr r。競合が発生した場合A'Bリベースは停止しB、競合を解決する必要があります。完了したら、を押しr rて続行します。

への変更がAと競合することがわかっているB場合は、上記の手順に従ってください。それ以外の場合は、次のアプローチを使用してください。


Gitでは、を使用して「修正コミット」を作成できますgit commit --fixup A。これにより、新しいコミットが作成され、「別のコミットで行われたはずの」変更が記録されます。そのコミットは新しいものになりHEADます。--squashバリアントも存在します。違いについては、git-commitmanページを参照してください。

Aコミットと新しいコミットを実際に組み合わせて、その上にA'再適用するBには、リベースを使用する必要があります。Magitはそうするための便利なコマンドを提供しr fます。

上記のアプローチとの主な違いは、ここでは最初に新しいコミットを作成し、次にそれを「ターゲット」と組み合わせて再適用するためにリベースすることですB。上記では、コミットする代わりにリベースすることから始めました。

Magitでは両方--fixup--squash変異体はより入手可能である上、ポップアップをコミットfしてs。しかしMagitもの「インスタント」フィックスアップの変種とスカッシュのコマンドを提供FしてS。これらのバリアントは、「非インスタント」バリアントのような新しいコミットを作成しますが、別のコマンドを呼び出さなくても、rebaseを使用してフィックスアップコミットとターゲットコミットを即座に結合します。

「インスタントフィックスアップは、」( c F)は、本質的に「延長と同じものであるHEAD(」c e)、任意のコミットのためにそれだけではなく、働くことを除いてHEAD


参考文献:


クリスタルクリア!ありがとう、素晴らしいパッケージBTW。
マチューマルケス

1
さて、私の答えの後半には、どろどろした部分があると思います。しかし、それらを避けるために、私はこのすでに長い答えの長さを2倍にしなければならないので、私はこれがあなたのために働くことをうれしく思います
;

この回答tarsiusに感謝します。これは本当に役に立ちます。
-anquegi

この説明の前半が明快であるため、後半を読むのが難しくなり、非常にイライラします!
リンヘッドリー

git-commitgit-rebase(1)これらの行があるmanページのリダイレクト:折り畳まれたコミットの推奨コミットメッセージは、最初のコミットのコミットメッセージと「squash」コマンドのコミットメッセージの連結ですが、「fixup」のコミットのコミットメッセージは省略します。コマンド。IOW、前回のコミットのコードを修正したい場合はfixupを使用し、コミットメッセージも修正したい場合はsquashを使用します。
司保志

3

git commit --amend –C HEADは探しているGitコマンドであり、Magitで修正を行うことができますC-c C-a


最新C-c C-aバージョンのMagitを使用していますが、古いバージョンのものです(私は思う)。さらに、ヘルプバッファー(?)に「修正」の痕跡はありません。
マチューマルケス

magit 2.xの同等物については、Rémiの回答を参照してください。
npostavs

3

したがって、1つのワークフローは次のとおりです。

  • 変更を加える
  • c(コミット)f(修正-修正のコミットを選択)

それから

  • r(リベース)-a(自動スカッシュ、デフォルト設定可能)i(インタラクティブ)

自動スカッシュは、すべての!fixupコミットを自動的に適切な場所に移動し、リベースでスカッシュされるように設定します。


私があなたが言わなかった唯一のことは、最初の弾丸と2番目の弾丸の間にステージングすることでした。打つことiは私をもたらしますCannot rebase: Your index contains uncommitted changes. Please commit or stash them.。ただし、コミットされていない変更はありません。:/
マチューマルケス

引っ張った後、もう一度試してみましたProceed despite merge in rebase range? [c]ontinue, [s]elect other, [a]bort。私の修正が今後のマージでうんざりする可能性があることを教えようとしていますか?
マチューマルケス

@MathieuMarques:「コミットされていない変更がない限り」-gitはあなたがそうだと思っています。メッセージは、ステージングされていない変更ではなく、ステージングされた変更を示唆していることに注意してください。Re merge in rebase:、を参照してくださいgit help rebase。アップストリームをプルする前に修正を行うことをお勧めします。
npostavs

1

最後のコミットを修正するには、「c a」です。Fixupは、古いコミットを修正するためのものです。


そうです、私はA B をコミットしました。明確にするために投稿を更新しました。
マチューマルケス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.