web-dev-qa-db-ja.com

Gitでファイルの一部だけをコミットする

Gitでファイルを変更したとき、どのように変更の一部だけをコミットすることができますか?

たとえば、ファイル内で変更された30行のうち15行だけをコミットするにはどうすればよいでしょうか。

2480
freddiefujiwara

あなたはgit add --patch <filename>(または略して-p)を使うことができます、そしてgitはあなたのファイルをそれが賢明な「ハンク」(ファイルの一部)であると思うものに分割し始めます。それはそれからこの質問であなたを促します:

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?

これが各オプションの説明です。

  • y この塊を次のコミットのためにステージングする
  • n 次のコミットのためにこの塊をステージしないでください
  • q 終了する;このハンクや残りのハンクをステージングしないでください
  • a この塊とそれ以降のすべての塊をファイルにステージングする
  • d このハンクやそれ以降のハンクをファイルにステージングしないでください。
  • g に行くために塊を選択してください
  • / 与えられた正規表現にマッチするかたまりを探す
  • j この塊を未決定のままにしておく、次の未決定の塊を参照
  • J この塊を未決定のままにして、次の塊を見てください
  • k この塊を未決定のままにしておく、前の未決定の塊を参照
  • K 前の塊を見なさい
  • 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

3319
cloudhead

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もこの機能を持っているかもしれません。

232
Jakub Narębski

git gui は差分ビューの下でこの機能を提供します。関心のある行を右クリックすると、「この行をコミットするようにステージング」というメニュー項目が表示されます。

126
Ionuț G. Stan

私はgit add -e myfileが単にテキストエディタを開き、あなたがどの行をステージしたいか、どのラインをしないかを選ぶことができるので、最も簡単な方法であると思います(少なくとも私の好みです)。編集コマンドについて

追加コンテンツ:

追加されたコンテンツは "+"で始まる行で表されます。追加行を削除することで、追加行のステージングを防ぐことができます。

削除されたコンテンツ:

削除されたコンテンツは " - "で始まる行で表されます。 " - "を ""(スペース)に変換することで、それらが削除されるのを防ぐことができます。

変更内容

変更されたコンテンツは " - "行(古いコンテンツを削除する)とそれに続く "+"行(置換コンテンツを追加する)で表されます。 " - "行を ""に変換し、 "+"行を削除することで、変更の段階付けを防ぐことができます。ペアの半分だけを変更すると、インデックスに混乱を招くような変更が加えられる可能性があります。

git addに関するすべての詳細は、git --help addで入手できます。

67

もしあなたがvimを使っているのなら、 fugitive という優れたプラグインを試してみた方が良いかもしれません。

作業コピーとインデックス間のファイルの差分を:Gdiffで確認してから、dpのような従来のvim diffコマンドを使用して、インデックスに行またはハンクを追加できます。変更をインデックスに保存して:Gcommitでコミットすれば完了です。

とても良い入門用スクリーンキャスト ここ (esp。 パート2 を参照).

42
François

Atlassianの SourceTree を使用することを強くお勧めします。 (無料です。)これは簡単なことです。あなたは迅速かつ容易に個々のコードの塊や個々のコード行を上演することができます。

enter image description here

28
user486646

新しいファイルにgit add --patchを使用することに注目する価値があります 最初にgit add --intent-to-addでインデックスにファイルを追加する必要があります:

git add -N file
git add -p file
24
user1338062

たくさんの変更があり、最終的にその変更からいくつかのコミットを作成することになったら、物事をステージングする前に私の出発点を一時的に保存したいと思います。

このような:

$ 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の答えは私が普段していることですが、時々たくさんの変更があり、物事をステージングしているときにミスをするかもしれないと言うことができます。

21
jdsumsion

Emacsを使うべきなら、 Magit を見てください。これはemacsのためのgitインターフェースを提供します。 ステージングハンク (ファイルの一部)を非常にうまくサポートしています。

12
Mark van Lent

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メソッドを使用すると、コードをコミットする前に、コードが引き続き機能するかどうかをテストできます。

8
derhoch

Git Extensions を使う人のために:

[コミット]ウィンドウで、部分的にコミットするファイルを選択してから、右側のペインでコミットするテキストを選択してから、選択部分を右クリックしてコンテキストメニューから[選択行のステージング]を選択します。

8
srgstm

Intellij IDEA (およびこのシリーズの他のすべての製品はv2018.1以降の部分コミットのサポートを組み込んでいると思います)

enter image description here

7
Holger Brandl

vim-gitgutter プラグインはvimエディタを使わずにハンクをステージングできます

:GitGutterStageHunk

これに加えて、それはいくつかの現代のIDEのようにdiff signカラムのような他のクールな機能を提供します。

塊の一部だけを上演する場合 vim-fugitive

:Gdiff

個々の行の変更をステージング/元に戻すために、:'<,'>diffputまたは:'<,'>diffgetの範囲を視覚的に選択できます。

6
c0ffeeartc

git add -p filename.xを試しましたが、Macでは、gitx( http://gitx.frim.nl/ または https://github.com/pieter/gitx )がコミットするのがはるかに簡単であることがわかりました。まさに私がやりたかった線です。

5
jasongregori

TortoiseGitの場合

ファイルを右クリックしてContext Menu → Restore after commitを使用してください。これにより、ファイルのコピーがそのまま作成されます。その後、ファイルを編集できます。 TortoiseGitMergeで、コミットしたくない変更をすべて元に戻します。これらの変更を保存したら、ファイルをコミットできます。

4
Fr0sT

Atom usersの場合、パッケージ github にはgit guiのスタイルのインタラクティブステージングが含まれています。ショートカットについては、パッケージの ドキュメント を参照してください。

Atomを使用すると、背景が暗いテーマで作業することができます(デフォルトでは、 git gui は背景が白です)。

3

git-meld-index - ウェブサイトからの引用:

git-meld-indexはmeld - あるいは他のgit difftool(kdiff3、diffuseなど) - を実行して、gitインデックスへの変更を対話的にステージングすることを可能にします(gitステージングエリアとしても知られています)。

これはgit add -pとgit add --interactiveの機能に似ています。場合によっては、git add -pよりもmeldの方が使いやすいです。それは、meldによって、例えば以下のことが可能になるからです。

  • もっと見る
  • 行内差分を見る
  • 手動で編集して 'live' diffの更新を見ます(キーを押すたびに更新されます)。
  • スキップしたいすべての変更に 'n'を付けずに変更にナビゲートする

使用方法

Gitリポジトリで、以下を実行してください。

git meld-index

あなたはmeld(またはあなたの設定されたgit difftool)が次のようにポップアップするのを見るでしょう:

_ left _ :作業ディレクトリからコピーされた一時ディレクトリ

_ right _ :インデックスの内容を含む一時ディレクトリ。これには、まだインデックスには含まれていないが作業コピーでは変更されている、または追跡されていないファイルも含まれます。この場合、HEADのファイルの内容が表示されます。

幸せになるまでインデックス(右側)を編集します。必要に応じて保存することを忘れないでください。

完了したら、meldを閉じます。git-meld-indexは、編集したばかりのmeldの右側にある一時ディレクトリの内容と一致するようにインデックスを更新します。

2
Croad Langshan

前回の回答に加えて、コマンドラインを使用する場合は、git add -e myfileと入力すると、コミットする内容を1行ずつ選択することができます。

enter image description here

+で始まる行は追加ですが、-で始まる行は削除です。そう:

  • 追加を行わないようにするには、その行を削除するだけです。
  • 削除を行わないようにするには、-をスペースに置き換えてください。

これがgit add -hがこの方法でファイルを追加することについてのものです(ファイルにパッチを当てる):

追加コンテンツ 追加コンテンツは "+"で始まる行で表されます。追加行を削除することで、追加行のステージングを防ぐことができます。

削除されたコンテンツ: 削除されたコンテンツは " - "で始まる行で表されます。 " - "を ""(スペース)に変換することで、それらが削除されるのを防ぐことができます。

変更内容: 変更内容は " - "行(古い内容の削除)とそれに続く "+"行(置換内容の追加)で表されます。 " - "行を ""に変換し、 "+"行を削除することで、変更の段階付けを防ぐことができます。ペアの半分だけを変更すると、インデックスに混乱を招くような変更が加えられる可能性があります。

注意:これは変更するのに適した場所ではありません。削除または追加した行の演算子を変更するだけです。

2
Beto Aveiga

Emacsには gitsum もあります。

2
zut

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など)を使用します。

1
Samuel Lampa

この質問が出されてから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

使用例を示すスクリーンキャストExample

1
Arun

git-cola は素晴らしいGUIであり、この機能も内蔵しています。ステージする線を選択してを押すだけです。 S。何も選択されていない場合は、完全な塊がステージングされます。

0
AndiDog

もしそれがWindowsプラットフォームであれば、私の意見ではgit guistageから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を選択
0