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


2764

Gitでファイルを変更した場合、一部の変更のみをコミットするにはどうすればよいですか?

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


3
関連するstackoverflow.com/q/34609924/52074:ハンクをより小さなハンクに分割する必要がある場合。
Trevor Boyd Smith、

要約:機能に関して:git gui= git add -e> git add -i -p; 利便性の面で:git gui> git add -i -p> git add -e。だから、:選ぶgit guiあなたはX.ピックへのアクセス権を持っている場合git add -i -p、単純なもののため、あなたが持っているか、Xを使用したくないときgit add -eX.せずに、複雑なステージングのために
Penghe庚

回答:


3687

あなたは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ツール-インタラクティブステージング


83
は、便利なインタラクティブモードを開始するコマンド-p/--patch内のパッチアクションへのショートカットであることに注意してください-i/--interactive
tutuDajuju 2015

5
>そのファイルがすでにステージングされている場合はどうなりますか?ステージングされていない変更のみが表示されます。と同じgit diffです。
Eugen Konkov

3
現在のハンクを手動で編集するにはどうすればよいですか?eと入力した後、どうすればよいかわかりません。
Hunsu、2015年

23
押した後e、手動で置き換えることにより、塊を編集することができ+たり-#
veksen

1
これは素晴らしいですが、実際にどのようにプッシュしますか?私がそうgit pushするなら、それはすでに最新であると言います。そして私が私がそうするならば、私はgit diff私が言った塊を見るn。もし私がgit diff --stagedコミットを確認したら、プッシュしたいです。コミットをプッシュできると仮定して、私が言ったハンクをどのように削除noしますか?
2017年

250

git add --interactiveor を使用してから、(not)を使用できます。git-addマンページのインタラクティブモードを参照するか、単に指示に従ってください。git add -p <file>git commit git commit -a

最新のGitにはgit commit --interactivegit commit --patchインタラクティブコミットのパッチオプションへのショートカットである)もあります。

GUIから行う場合は、git-guiを使用できます。コミットに含めたいチャンクをマークするだけです。個人的にはを使用するよりも簡単だと思いますgit add -i。QGitやGitXなどの他のgit GUIもこの機能を備えている場合があります。


1
興味深いことに、windows.github.com ...部分的なファイルのコミットをサポートしていたが、最近それを落としているようだ
樹里

1
@Juri私は部分的なファイルのコミットのサポートが後ろにあると思います。
Ela782

@Juriどういたしまして。私は実際にそれが以前にそこにあったことに気づかなかった-私は先週それを見て、そして「ああ、なんと驚くべき新機能」だと思った!:-)
Ela782 2015

1
現在、windows.github.comは、ブランド変更されたGitHubデスクトップにリダイレクトします。これは、Git GUIよりも優れており、部分的なコミットをサポートしていますが、コミット署名はサポートしていません。はぁ。

147

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


13
複雑なパッチの場合、これは通常、私にとって最も速いアプローチです。
hochl 2015

7
これは、ステージング領域に細かい方法で変更を追加するための非常に効率的で直感的な方法です。また、複数の行を選択することができ、その選択内のすべての変更が追加されます。
jox 2015

これはではありませんがgitk、Git Bash for Windowsに含まれています。あなたはそれのためのスタートメニューエントリを持っているべきです、またはコマンドでそれを始めることができgit guiます。また、stage this hunkおそらくより便利なものもありstage this lineます。この回答は10年前に作成されたため、新しい可能性があります。
Chris

82

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

追加されたコンテンツ:

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

削除されたコンテンツ:

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

変更されたコンテンツ:

変更されたコンテンツは、「-」行(古いコンテンツを削除)に続いて「+」行(置換コンテンツを追加)で表されます。「-」行を「」に変換し、「+」行を削除することで、変更のステージングを防ぐことができます。ペアの半分だけを変更すると、インデックスに混乱を招く変更が導入される可能性があることに注意してください。

に関するすべての詳細git addは、git --help add


7
これらの行を実際に選択する方法(つまり、入力する実際のコマンド)のどこかに明確な説明がある場合、これはさらに役立ちます。ドキュメントに見つかりませんでした。参照を追加できますか?
Alex

4
省略オプション-eが嫌いな人のために、です--edit
Kolyunya 2016年

2
セクションの編集パッチからのものであるtheFreedomBananaによって追加された参照符を@Alexgit --help add
ランドール

8
これは、s対話型パッチモードでハンクを小さくできない場合に、行ごとに行を追加/削除する問題を解決する唯一の回答(gitのみが必要)です。
cdosborn 2017

3
このコマンド(git add -e)は*ディスク上のファイルの内容を変更しない*ことを理解しておくと役立ちます。変更の一部を非ステージングからステージング(インデックス)に移動するだけです。
Penghe Geng

44

vimを使用している場合は、fugitiveと呼ばれる優れたプラグインを試してみてください。

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

ここで非常に優れた紹介スクリーンキャスト(特にパート2を参照)。


このリンクをありがとうございました。私が必要としているものとまったく同じです。特に:diffget/:diffputビジュアルモードでは、リセット/コミットしたい特定の行を選択できます。だから、もう一度確認してください:vimは素晴らしいです。
goodniceweb 2015

30

アトラシアンのSourceTreeを使用することを強くお勧めします。(無料です。)これは簡単です。個々のコードの塊または個々のコード行をすばやく簡単にステージングできます。

ここに画像の説明を入力してください


1
SourceTreeは、この目的に適したツールであることに同意します。これは、コマンドラインで実行できるよりもきめ細かい制御ができるためです。

19
@cupcake私は反対を主張しますが、SourceTreeはおそらくそれらのコマンドラインgit実行可能ファイルを使用するため、本質的に「コマンドライン」を介して常に同じ(またはそれ以上の)きめの細かいアクションを実行できます。
tutuDajuju 2015

2
細かい議論に関係なく、ハンクと個々の行のステージングは​​非常に簡単であるため、SourceTreeを強くお勧めします。i.imgur.com / 85bNu4C.png
Mars Robertson

1
@tutuDajujuこの場合、それが本当かどうかはわかりません。SourceTreeは、ステージにどのような部分を選択する能力がある行ずつ。全体をステージングする必要はありません。ハンクの真ん中に2行をステージングできます。しかし、それがどのようにしてそれを達成するのかはわかりません。(現時点では、追跡されていないファイルの特定の行をステージングできないSourceTreeを回避しようとしています。回避策を探してここに着陸しましたが、gitが行単位の機能を提供していないようですまったく。少なくとも単純な方法ではありません。)
jpmc26

1
@Sunでは、50行目をクリックし、Shiftキーを押しながら100行目をクリックして、ステージングできます。Sourcetreeで行50-100を簡単にステージングできます:)
ryan123

26

新しいファイルに使用するにgit add --patchは、最初にファイルをインデックスに追加する必要があることに注意してください:git add --intent-to-add

git add -N file
git add -p file

23

多くの変更があり、その変更からいくつかのコミットが作成される場合は、ステージングの前に一時的に開始点を保存します。

このような:

$ 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の答えは、私が通常行うことです。ただし、多くの変更があり、ステージング中にミスを犯す可能性があること、および2回目のパスにフォールバックできるコミット状態が必要であることがわかる場合もあります。


12

emacsを使用する場合は、emacsのgitインターフェースを提供するMagitをご覧ください。ハンク(ファイルの一部)のステージングを非常にうまくサポートします。


Mxシェルウィンドウから実行したときに、エディターを開きたいgitコマンドをよくトリップします。magitはその狂気を阻止し、そのための新しいバッファを開くだけですか?(background-emacs-daemonのヒントは使用しないでください。とにかく感謝しますが、人生は短すぎます)。
user2066657

いいえ、私が知る限り、これを妨害することはありません。(1)私はEmacsでシェルウィンドウをほとんど使用していません。(2)通常はemacsclientを使用しているためです。そう言っても、emacsclient オプションである場合、少なくとも、emacsを含む追加のウィンドウが開かれず、「COMMIT_EDITMSG」バッファーが既存のEmacsウィンドウで開かれていました。
マークファンレント


9

Git Extensionsを使用する場合:

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


2
「選択した行sをステージングする」ためのGit拡張機能のキーボードショートカットは-コミットするファイルの一部をすばやくステージングするのに非常に便利です。
Alchemistmatt

8

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 commit --amend、後でスタッシュをポップできないようです、またはこれを行う方法はありますか?
マーク

7

前の回答に加えて、コマンドラインを使用しgit add -e myfileたい場合は、次のように入力すると、コミットする対象を1行ずつ選択する選択肢が表示されます。

ここに画像の説明を入力してください

で始まる行+は追加であることがわかっている可能性があるため、で始まる行-は削除です。そう:

  • 追加をステージングしない場合は、その行を削除してください。
  • 削除をステージングしない場合は-、スペースで置き換えてください

これは、git add -hこの方法でファイルを追加することについて述べています(パッチファイル)。

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

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

変更されたコンテンツ: 変更されたコンテンツは、「-」行(古いコンテンツを削除)に続いて「+」行(置換コンテンツを追加)で表されます。「-」行を「」に変換し、「+」行を削除することで、変更のステージングを防ぐことができます。ペアの半分のみを変更すると、インデックスに混乱を招く変更が導入される可能性があることに注意してください。

注意:ファイルの内容は変更しないでください。変更するのは適切ではありません。削除または追加された行の演算子を変更するだけです。


以前の答えは?回答は、ポイントの数に基づいて保存されます。したがって、あなたの答えは、他の答えと比較して、あなたが書いたときとは別の場所にあります。
KulaGGin

参照されている答えは@theFreedomBanana
K. Symbol

6

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

:GitGutterStageHunk

これに加えて、いくつかの最新のIDEのように、差分記号列のような他のクールな機能を提供します

hunkの一部のみをvim-fugitiveでステージングする必要がある場合

:Gdiff

視覚的な範囲選択を可能にする:'<,'>diffput:'<,'>diffget、個々のラインの変更をステージング/元に戻します。



4

TortoiseGitの場合:

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


4

この質問が出されてから10年になります。そして、私はこの答えが誰かに役立つことを願っています。ここでの回答述べたように、GUIはオプションではありませんが、Andrew Shaduracrecord拡張機能は、コミットする行を選択できる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 repoに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

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




2

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

git-meld-indexはmeld-またはその他のgit difftool(kdiff3、diffuseなど)-を実行して、gitインデックス(gitステージング領域とも呼ばれます)への変更をインタラクティブにステージングできるようにします。

これはgit add -pとgit add --interactiveの機能に似ています。場合によっては、git add -pよりもmeldの方が簡単/高速です。これは、meldを使用すると、たとえば次のことが可能になるためです。

  • コンテキストをもっと見る
  • 行内差分を見る
  • 手で編集して「ライブ」差分更新を確認(キーを押すたびに更新)
  • スキップするすべての変更に「n」を言わずに変更に移動する

使用法

gitリポジトリで、次のコマンドを実行します。

git meld-index

meld(または設定したgit difftool)が次のようにポップアップ表示されます。

LEFT:作業ツリーからコピーされたファイルを含む一時ディレクトリ

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

満足するまでインデックス(右側)を編集します。必要に応じて保存してください。

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


2

それがWindowsプラットフォーム上にある場合、私の意見でgit guiは、ファイルからstage/ commit数行に非常に良いツールunstagedです

1.賢い塊:

  • unstagged Changesセクションからファイルを選択
  • ステージングする必要があるコードのチャンクを右クリックします
  • 選択する Stage Hunk for commit

2.賢い線:

  • unstagged Changesセクションからファイルを選択
  • ステージングする行を選択します
  • 右クリックして選択 Stage Lines for commit

3.数行を除いて完全なファイルをステージングする場合:

  • unstagged Changesセクションからファイルを選択
  • 押す Ctrl+T (Stage file to commit)
  • 選択したファイルはStaged Changesセクションに移動します
  • ステージングする行を選択します
  • 右クリックして選択 UnStage Lines for commit

1

1つの答えが示す上記は、使用することができます git add --patch filename.txt

またはショートフォーム git add -p filename.txt

...しかし、すでにリポジトリにあるファイルの場合、sはcommitコマンドで--patchフラグを直接使用する方がはるかに優れています(gitの最新バージョンを使用している場合)。 git commit --patch filename.txt

...または、もう一度、短い形式 git commit -p filename.txt

...次に、前述のキー(y / nなど)を使用して、コミットに含める行を選択します。


git add -p filename.txtエラーの余地が少ないことに加えて、「」が何をもたらすのでしょうか。部分的なファイルの変更をめちゃくちゃにする場合は、コミットを取り消すよりも、追加を取り消す方が適切です。
CTMacUser 2014

理由はわかりませんが、「n」と言うと行が含まれます。2番目のハンクで「y」と言うと、行も含まれます。
がっしりした

1

git-colaは素晴らしいGUIであり、この機能も組み込まれています。ステージングするラインを選択してを押すだけSです。選択を行わない場合、完全なハンクがステージングされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.