Gitでファイルを変更したとき、どのように変更の一部だけをコミットすることができますか?
たとえば、ファイル内で変更された30行のうち15行だけをコミットするにはどうすればよいでしょうか。
あなたはgit add --patch <filename>
(または略して-p
)を使うことができます、そしてgitはあなたのファイルをそれが賢明な「ハンク」(ファイルの一部)であると思うものに分割し始めます。それはそれからこの質問であなたを促します:
Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?
これが各オプションの説明です。
ファイルがまだリポジトリにない場合は、最初にgit add -N <filename>
を実行できます。その後はgit add -p <filename>
を続けてください。
その後、あなたが使用することができます:
git diff --staged
git reset -p
git commit -v
。これは、コミットデータをgit format-patch
ファイルに解析することを目的としている.patch
コマンドとは大きく異なります。
将来の参考資料: Git Tools - Interactive Staging
git add --interactive
またはgit add -p <file>
を使用してからgit commit
( not git commit -a
)を使用することができます。 git-add manpageの対話型モードを参照するか、単に指示に従ってください。
Modern Gitにはgit commit --interactive
(とgit commit --patch
があります。これは対話的コミットのパッチオプションへのショートカットです)。
GUIから実行したい場合は、 git-gui を使用できます。コミットに含めたいチャンクを単にマークすることができます。個人的にはgit add -i
を使うよりも簡単だと思います。 QGitやGitXのような他のgit GUIもこの機能を持っているかもしれません。
git gui は差分ビューの下でこの機能を提供します。関心のある行を右クリックすると、「この行をコミットするようにステージング」というメニュー項目が表示されます。
私はgit add -e myfile
が単にテキストエディタを開き、あなたがどの行をステージしたいか、どのラインをしないかを選ぶことができるので、最も簡単な方法であると思います(少なくとも私の好みです)。編集コマンドについて
追加コンテンツ:
追加されたコンテンツは "+"で始まる行で表されます。追加行を削除することで、追加行のステージングを防ぐことができます。
削除されたコンテンツ:
削除されたコンテンツは " - "で始まる行で表されます。 " - "を ""(スペース)に変換することで、それらが削除されるのを防ぐことができます。
変更内容
変更されたコンテンツは " - "行(古いコンテンツを削除する)とそれに続く "+"行(置換コンテンツを追加する)で表されます。 " - "行を ""に変換し、 "+"行を削除することで、変更の段階付けを防ぐことができます。ペアの半分だけを変更すると、インデックスに混乱を招くような変更が加えられる可能性があります。
git add
に関するすべての詳細は、git --help add
で入手できます。
Atlassianの SourceTree を使用することを強くお勧めします。 (無料です。)これは簡単なことです。あなたは迅速かつ容易に個々のコードの塊や個々のコード行を上演することができます。
新しいファイルにgit add --patch
を使用することに注目する価値があります 最初にgit add --intent-to-add
でインデックスにファイルを追加する必要があります:
git add -N file
git add -p file
たくさんの変更があり、最終的にその変更からいくつかのコミットを作成することになったら、物事をステージングする前に私の出発点を一時的に保存したいと思います。
このような:
$ git stash -u
Saved working directory and index state WIP on master: 47a1413 ...
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 1st commit"
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 2nd commit"
$ git stash pop
Whymarrhの答えは私が普段していることですが、時々たくさんの変更があり、物事をステージングしているときにミスをするかもしれないと言うことができます。
Jdsumsionの答えのように、現在の作業を隠しておくこともできますが、meldなどのdifftoolを使用して、選択した変更を隠し場所から引き出します。そうすれば、ハンクを手動で非常に簡単に編集することもできます。これは、git add -p
の場合は少し苦痛です:
$ git stash -u
$ git difftool -d -t meld stash
$ git commit -a -m "some message"
$ git stash pop
Stashメソッドを使用すると、コードをコミットする前に、コードが引き続き機能するかどうかをテストできます。
Git Extensions を使う人のために:
[コミット]ウィンドウで、部分的にコミットするファイルを選択してから、右側のペインでコミットするテキストを選択してから、選択部分を右クリックしてコンテキストメニューから[選択行のステージング]を選択します。
Intellij IDEA (およびこのシリーズの他のすべての製品はv2018.1以降の部分コミットのサポートを組み込んでいると思います)
vim-gitgutter プラグインはvimエディタを使わずにハンクをステージングできます
:GitGutterStageHunk
これに加えて、それはいくつかの現代のIDEのようにdiff signカラムのような他のクールな機能を提供します。
塊の一部だけを上演する場合 vim-fugitive
:Gdiff
個々の行の変更をステージング/元に戻すために、:'<,'>diffput
または:'<,'>diffget
の範囲を視覚的に選択できます。
git add -p filename.x
を試しましたが、Macでは、gitx( http://gitx.frim.nl/ または https://github.com/pieter/gitx )がコミットするのがはるかに簡単であることがわかりました。まさに私がやりたかった線です。
TortoiseGitの場合
ファイルを右クリックして
Context Menu → Restore after commit
を使用してください。これにより、ファイルのコピーがそのまま作成されます。その後、ファイルを編集できます。 TortoiseGitMergeで、コミットしたくない変更をすべて元に戻します。これらの変更を保存したら、ファイルをコミットできます。
git-meld-index - ウェブサイトからの引用:
git-meld-indexはmeld - あるいは他のgit difftool(kdiff3、diffuseなど) - を実行して、gitインデックスへの変更を対話的にステージングすることを可能にします(gitステージングエリアとしても知られています)。
これはgit add -pとgit add --interactiveの機能に似ています。場合によっては、git add -pよりもmeldの方が使いやすいです。それは、meldによって、例えば以下のことが可能になるからです。
使用方法
Gitリポジトリで、以下を実行してください。
git meld-index
あなたはmeld(またはあなたの設定されたgit difftool)が次のようにポップアップするのを見るでしょう:
_ left _ :作業ディレクトリからコピーされた一時ディレクトリ
_ right _ :インデックスの内容を含む一時ディレクトリ。これには、まだインデックスには含まれていないが作業コピーでは変更されている、または追跡されていないファイルも含まれます。この場合、HEADのファイルの内容が表示されます。
幸せになるまでインデックス(右側)を編集します。必要に応じて保存することを忘れないでください。
完了したら、meldを閉じます。git-meld-indexは、編集したばかりのmeldの右側にある一時ディレクトリの内容と一致するようにインデックスを更新します。
前回の回答に加えて、コマンドラインを使用する場合は、git add -e myfile
と入力すると、コミットする内容を1行ずつ選択することができます。
+
で始まる行は追加ですが、-
で始まる行は削除です。そう:
-
をスペースに置き換えてください。これがgit add -h
がこの方法でファイルを追加することについてのものです(ファイルにパッチを当てる):
追加コンテンツ 追加コンテンツは "+"で始まる行で表されます。追加行を削除することで、追加行のステージングを防ぐことができます。
削除されたコンテンツ: 削除されたコンテンツは " - "で始まる行で表されます。 " - "を ""(スペース)に変換することで、それらが削除されるのを防ぐことができます。
変更内容: 変更内容は " - "行(古い内容の削除)とそれに続く "+"行(置換内容の追加)で表されます。 " - "行を ""に変換し、 "+"行を削除することで、変更の段階付けを防ぐことができます。ペアの半分だけを変更すると、インデックスに混乱を招くような変更が加えられる可能性があります。
注意:これは変更するのに適した場所ではありません。削除または追加した行の演算子を変更するだけです。
Emacsには gitsum もあります。
one answer 上記のように、あなたはgit add --patch filename.txt
を使うことができます
または省略形のgit add -p filename.txt
...しかし、すでにリポジトリにあるファイルの場合は、commitコマンドで--patchフラグを直接使用するほうがはるかに良いでしょう(最近の十分なバージョンのgitを使用している場合):git commit --patch filename.txt
...または、やはり省略形のgit commit -p filename.txt
...そして、コミットに含める行を選択するために、前述のキー(y/nなど)を使用します。
この質問が出されてから10年が経ちました。そしてこの答えが誰かに役立つことを願っています。 Andrew Shaduraの crecord拡張 は、答えが here で述べられているように、GUIはオプションではありません。コミットする行を選択できるncursesウィンドウを表示するのに役立ちます。
次のように拡張子を設定します。
git clone https://github.com/andrewshadura/git-crecord
cd git-crecord
./setup.py install
ln -s $PWD/git-crecord ~/.local/bin/git-crecord
gitリポジトリにcdして、次のように起動します。
git crecord
これにより、以下に示すように使用できるncursesインタフェースが表示されます。 ncursesウィンドウで次のキーを押すと、特定のアクションが実行されます。
f hunk toggle fold (arrow keys can also be used)
space toggle hunk selection
a toggle commit or amend
c confirm and open commit window
使用例を示すスクリーンキャスト
git-cola は素晴らしいGUIであり、この機能も内蔵しています。ステージする線を選択してを押すだけです。 S。何も選択されていない場合は、完全な塊がステージングされます。
もしそれがWindows
プラットフォームであれば、私の意見ではgit gui
はstage
からcommit
/unstaged
数行への非常に良いツールです。
1.ハンクの賢明な:
unstagged Changes
セクションからファイルを選択してくださいStage Hunk for commit
を選択2.行単位:
unstagged Changes
セクションからファイルを選択してくださいStage Lines for commit
を選択3. 2行を除いて完全なファイルをステージングしたい場合は、 /
unstagged Changes
セクションからファイルを選択してくださいCtrl+T (Stage file to commit)
を押すStaged Changes
セクションに移動しますUnStage Lines for commit
を選択