コミット全体ではなく、1つのファイルの変更のみを選択する方法


108

あるブランチで導入された変更を別のブランチに適用する必要があります。チェリーピックを使ってそれを行うことができます。ただし、私の場合、1つのファイルにのみ関連する変更を適用したいので、コミット全体を選択する必要はありません。どうやってするか?


回答:


137

達成したいことに基づいて、さまざまなオプションがあります。

ファイルの内容をターゲットブランチと同じにする場合は、を使用できますgit checkout <branch> -- <filename>。ただし、これは単一のコミットで発生した変更を「選択」するのではなく、そのファイルの結果の状態を取得するだけです。したがって、コミットに行を追加したが、以前のコミットがさらに変更され、他の変更を加えずにその行のみを追加したい場合、チェックアウトは希望どおりではありません。

それ以外の場合、コミットで導入されたパッチを単一のファイルにのみ適用する場合は、複数のオプションがあります。実行できますgit cherry-pick -n。つまり、コミットせずに、コミットを編集します(たとえば、を使用git reset -- .してすべてのファイルをリセットし、実際に変更したいファイルのみを使用して追加しますgit add <filename>)。または、ファイルの差分を作成し、その差分を適用することもできます。

git diff <branch>^..<branch> -- <filename> | git apply

22

を作成しpatch fileて適用します。

git diff branchname -- filename > patchfile
git apply patchfile

編集:

変更をコミットから取得する必要があるため、次のようなパッチを作成します。

git show sha1 -- filename > patchfile

1
git diff sha1(またはgit diff branch、ブランチが同じハッシュを指している場合は同じです)、そのハッシュに関して現在の作業ディレクトリの差分のみを生成しますが、それ自体で導入されたコミットを変更するものは生成しません。
突く

正しい。回答を編集しました。ありがとう。
Sailesh 2013

1
git checkoutファイル名付きの-1 は、この爪に最適なハンマーです。これらのオプションはどちらも不必要に複雑です。
Rein Henrichs 2013

7
この特定のケースでは、はい。ただし、一般的に、特定のファイルに対して行われたコミットから変更を選択するcheckout場合は、機能しません。これには、他の不要な以前の変更が含まれている可能性があり、現在のブランチで行われた変更が含まれていない可能性があるためです。
Sailesh 2013

11

もう1つの便利なことは、ローカルでパッチを入手して使用することです。

git checkout {<name_of_branch>, commit's SHA} <path to the file> 

それはチェリーピッキングではありませんが。


2
警告:@pokeが彼の答えで言っているように、これは変更をコピーしません。ファイルの状態全体をコピーします。したがって、コミットの変更をファイルに追加する場合は、このようにチェックアウトすると、不適切な新しい変更が上書きされてしまいます
アレクサンダーバード

7

Gitはすべて準備が整っています:)

使うだけ git checkout <sha> <path-to-file>


4
それはチェリーピックではありません-ファイル全体をチェックアウトします。目標は、コミットから特定の変更を加えることです。多くの場合、これらは同じものですが、異なる場合もあります。
AndrewF

6
git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension

これは、別のブランチの単一のファイルを現在作業中のブランチにコピーする場合に機能します


1
注意してください。他のブランチのバージョンにないファイルで行われた変更は失われます。
PatrickSchlüter17年

それに同意します。これは、ファイルのコピーが必要で、現在のブランチでそれを変更したい場合に便利です
Ismail Iqbal

1
グロブ(パス/ *)を使用して複数のパス/ファイルを指定できます
Todd

1

これはあなたが探しているものです:

git checkout target-branch sha1 path/to/file

sha1はオプションです


11
いいえ、「コミットでの変更の選択」は「ファイル全体の選択」ではありません
Abyx

1

私がしがちなのは使うことです git ls-tree

ただやる:

git ls-tree -r <commit-id> |grep 'your filename'
# there will be output that shows a SHA1 of your file
git show ${SHA1 of your file} > 'your filename'

これは、grepに一致するすべてのファイル名を出力し、コミット内のファイルのSHA1キーを提供します。

Gitショーはブランチ外のファイルにも使用できます。>シェルから使用して出力をファイルにパイプすると、探している結果が得られます。


0

これを試すことができます:

git show COMMIT_ID -- path/to/specific-file | git apply

例えば:

git show 3feaf20 -- app/views/home/index.html | git apply

-9
git reset HEAD~1

ファイルをコミット前の段階に移動します

git stash

メモリから削除します

これで、ブランチはかなりクリーンです(前のコミットに戻ります)

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