別のブランチから1つのファイルのみを取得する方法


1267

私はgitを使用して、masterブランチで作業しています。このブランチにはというファイルがありますapp.js

私はexperimentたくさんの変更とたくさんのコミットをしたブランチを持っています。ここで、app.jsfrom だけに行われたすべての変更experimentmasterブランチに持っていきたいです。

それ、どうやったら出来るの?

もう一度私はマージしたくない。すべての変更をブランチapp.jsからexperimentブランチに持ち込みたいだけですmaster



1
今日の時点での回答を除いて、他の人はファイルの内容をコピーする方法を回答しています。ただし、正確に読み取る場合、Nickはフルテキストではなく変更を加えたかったため、ファイルmasterがから分岐する可能性がありますexperiment。一方、PSはマージしたくありませんが、私が知る限り、git merge用語はブランチのみであり、特定のファイルではないため、ここでは矛盾しません。
Alexei Martianov

回答:


1605
git checkout master               # first get back to master
git checkout experiment -- app.js # then copy the version of app.js 
                                  # from branch "experiment"

1つのファイルの変更を元に戻す方法gitを参照してください


2019年8月更新、Git 2.23

新しいとgit switchしてgit restoreコマンド、それは次のようになります。

git switch master
git restore -s experiment -- app.js

デフォルトでは、作業ツリーのみが復元されます。
あなたにもインデックスを更新する場合(ファイルの内容を復元し、意味 1つのコマンドでインデックスに追加):

git restore -s experiment --staged --worktree -- app.js
# shorter:
git restore -s experiment -WS -- app.js

以下のようヤクブNarębskiはコメントで言及します:

git show experiment:path/to/app.js > path/to/app.js

ただし、SOの質問「Gitの特定のリビジョンから単一のファイルを取得する方法」で詳しく説明されているように、リポジトリのルートディレクトリからの完全パスを使用する必要があります。
したがって、Jakubが彼の例で使用したパス/to/app.jsです。

以下のようフロスティはコメントに言及します:

app.jsの最新の状態のみを取得します

しかし、git checkoutまたはgit showについては、SO質問「git gui内のファイルのgit checkoutリビジョン」で示されているように、実際に必要なリビジョンを参照できます。

$ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME

$ FILENAMEはバージョン管理されたファイルの完全パスです。

$REVISIONに示すようにすることができますgit rev-parse

experiment@{yesterday}:app.js # app.js as it was yesterday 
experiment^:app.js            # app.js on the first commit parent
experiment@{2}:app.js         # app.js two commits ago

等々。

schmijosコメントに追加します

スタッシュからこれを行うこともできます:

git checkout stash -- app.js

これは、2つのブランチで作業していて、コミットしたくない場合に非常に便利です。


13
注:app.jsの最新の状態のみが取得され、実験ブランチから引き継がれた履歴は取得されません。
Frosty

2
@ThomasReggiを使用すると、任意のブランチから現在のブランチにファイルをインポート(チェックアウト)できるはずです。できない場合は、正確なエラーメッセージや使用しているGitとOSのバージョンなどの具体的な詳細を含めて、ここで質問することをお勧めします。
VonC、2014年

2
サブディレクトリでは、も使用できますexperiment:./app.js。(絶対パスを指定する必要はありません。)gitがくれた非常に役立つエラーメッセージのおかげで、これを学びました。 ./file.xsl '? " はい、しました!致命的なエラーメッセージにそれほど満足したことはありません。
Evan Lenz

1
@TomaszGandorはい、私はstackoverflow.com/a/21066489/6309で言及しています。ここで、git showはインデックスを変更しませんが、git checkoutはインデックスを変更します。
VonC

1
@FriedBrice私の答えを参照してください。最近では、それはgit restore -s new-feature path/to/app.js
VonC

360

すべてがはるかに簡単です。そのためにgit checkoutを使用してください。

you're on masterブランチを想定し、ブランチを取得するには、次のようにapp.js from new-featureします。

git checkout new-feature path/to/app.js

// note that there is no leading slash in the path!

これにより、目的のファイルの内容が表示されます。いつものように、new-featureブランチ名の代わりにsha1の一部を使用 して、その特定のコミットでのファイルを取得できます。

:リモートブランチではなく、ローカルブランチでnew-featureある必要があります。


77
git checkout origin/source_branch path/to/fileローカルリポジトリのソースブランチの更新を怠った場合は、古いバージョンのファイルを取得する可能性があるため、常にオリジンを指定することは役に立ちます。;)
タリル語2014年

3
@Mymozaaa質問ではリモートについて言及していなかったため、これは純粋にローカルリポジトリであるという仮定
Dmitry Avtonomov

1
このコマンドはファイルの履歴をもたらしますか、それともファイルの最後のバージョンのみをもたらしますか?
user1366265

1
@ user1366265このコマンドは、指定した特定のコミットまたは指定したブランチの先頭にあったファイルを配置します。「ファイルの履歴」というようなものはなく、すべての履歴情報はブランチにのみ保存されます。
ドミトリーアヴトノモフ2016年

3
これは、チェックアウトされたファイルを自動的にステージングするようです。ステージングせずに同じことを行うことは可能ですか?
bluenote10 2017年

44
git checkout branch_name file_name

例:

git checkout master App.java

ブランチ名にピリオドが含まれている場合、これは機能しません。

git checkout "fix.june" alive.html
error: pathspec 'fix.june' did not match any file(s) known to git.

@PhilipRegoこの答えは正しいです。私はあなたのブランチに異なる大文字や句読点があるか、ローカルブランチではなくリモートブランチしかないと思います。:gitのチェックアウトのドキュメントを参照してくださいgit-scm.com/docs/git-checkout#Documentation/...
ブレット

@Bretブランチ名にピリオドがあると機能しません。編集を提案しました
フィリップレゴ

これが最良の答えです。この回答が最高の評価であったといいのですが。現在の最高のものは非常に混乱していて簡単ではありません
ラッセルレゴ

41

VonCとchhhの回答の補足。

git show experiment:path/to/relative/app.js > app.js
# If your current working directory is relative than just use
git show experiment:app.js > app.js

または

git checkout experiment -- app.js

2
涼しい!長いパスを指定するのは嫌いです。--ブランチ名とパスの間の二重ダッシュ()はオプションですか?ダッシュで始まるパスがオプション/スイッチとして扱われるのを防ぐだけですか?
Tomasz Gandor

正直、わかりません。あなたがこれを指摘するまで、私はダブルダッシュを忘れていたことに気づきませんでした。
AlexLordThorsen

6
@TomaszGandor --はオプションですが、ブランチ名との競合を回避する方が便利です。たとえば、git checkout -- foo「ファイルfooをHEADからチェックアウトする」(つまり、fooのローカル変更を上書きする、つまりのサブセットgit reset --hard)をgit checkout foo意味しますが、それは「ブランチfooに移動しましょう」を意味する場合があります。
Alois Mahdal

8

または、別のブランチのすべてのファイルが必要な場合:

git checkout <branch name> -- .

24
最初のクエストには「ファイルが1つだけ」含まれています。
greatvovan 2017

1
これはマージするのではなく既存のファイルを置き換えます
Amare

3
これ.により、大きな違いが生じます。別のブランチに移動する代わりに、そこからすべてのファイルをコピーし、現在のファイルをそのまま残します。あなたはそれに行くことなく他のブランチからコンテンツを取得します。
Xeverous、

4

githubでファイルを確認し、そこからプルします

これは、OPに直接応答しない実用的なアプローチですが、一部のユーザーは便利です。

問題のブランチがGitHubにある場合は、GitHubが提供する多くのツールのいずれかを使用して目的のブランチとファイルに移動し、[Raw]をクリックしてプレーンテキストを表示し、(オプションで)テキストをコピーして貼り付けます。望ましい。

ローカルマシンにプルする前にリモートファイル全体を確認できるため、このアプローチが気に入っています。


2
ただし、rawファイルをコピーして貼り付けると、git diffで不要な文字が変更される可能性があります。ファイルを直接プロジェクトに保存して、変更がないことを確認する方が安全です。
フィリップレゴ

0

特定のコミット(任意のブランチ)からのファイルが必要な場合は、06f8251fと言います。

git checkout 06f8251f path_to_file

たとえば、Windowsでは:

git checkout 06f8251f C:\ A \ B \ C \ D \ file.h


1
お時間を割いていただきありがとうございます!しかし、これは質問に答えるものではなく、非常に詳細な良い答えがすでに9年前に投稿されています。質問をぶつける必要はありません。
Nathan

これは有効な実際的なシナリオです。答えはブランチを正しく処理しますが、ブランチの特定のコミットについてはどうでしょうか。
arupjbasu

0

別の方法は、違いのあるパッチを作成し、それをマスターブランチに適用することです。app.jsでの作業を開始する前の最後のコミットが00000aaaaaで、必要なバージョンを含むコミットが00000bbbbbだとします

これを実験ブランチで実行します。

git diff 00000aaaaa 00000bbbbb app.js > ~/app_changes.git

これにより、app.jsの2つのコミット間のすべての違いを含むファイルが作成され、どこにでも適用できます。そのファイルはプロジェクト外のどこにでも保持できます

次に、マスターで実行するだけです:

git apply ~/app_changes.git

これで、手動で行ったかのようにプロジェクトの変更が表示されます。


-3
git checkout master               -go to the master branch first
git checkout <your-branch> -- <your-file> --copy your file data from your branch.

git show <your-branch>:path/to/<your-file> 

これがお役に立てば幸いです。ご不明な点がございましたらお知らせください。

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