単一のファイルのバージョンを1つのgitブランチから別のgitブランチにコピーするにはどうすればよいですか?


944

完全にマージされた2つのブランチがあります。

ただし、マージが完了した後、1つのファイルがマージによってめちゃくちゃになっていることに気づき(他の誰かが自動フォーマットを実行しました)、もう一方のブランチで新しいバージョンに変更する方が簡単です。次に、1行の変更をブランチに持ってきてから、それを再度挿入します。

では、gitでこれを行う最も簡単な方法は何ですか?


3
受け入れられた回答では、最初のソリューションは変更をステージングし、2番目のソリューションはステージングしないことに注意してください。stackoverflow.com/a/56045704/151841
user151841

回答:


1674

ファイルを作成するブランチからこれを実行します。

git checkout otherbranch myfile.txt

一般式:

git checkout <commit_hash> <relative_path_to_file_or_dir>
git checkout <remote_name>/<branch_name> <file_or_dir>

いくつかのメモ(コメントから):

  • コミットハッシュを使用すると、任意のコミットからファイルをプルできます
  • これはファイルとディレクトリで機能します
  • ファイルmyfile.txtを上書きし、mydir
  • ワイルドカードは機能しませんが、相対パスは機能します
  • 複数のパスを指定できます

代替:

git show commit_id:path/to/file > path/to/file

13
はい、そうです。しかし、それが問題の意図でした。
Ikke

37
おそらく明白ですが、完全なファイル名を使用する必要があります...ワイルドカードは機能しません!
Chris Hart

6
しかし、それも良い方法です:git show commit_id:path / to / file> path / to / file
milushov

14
リモート:git checkout origin / otherbranch myfile.txt
Roman Rhrn Nesterov 2013

6
ワイルドカードを使用しても機能します。それらをラップして''、シェルによって解釈されないようにする必要があります。
Wiktor Czajkowski、

82

私は同様の検索でこの質問に終わった。私の場合、別のブランチから現在の作業ディレクトリに、ファイルの元の場所とは異なるファイルを抽出しようとしていました。答え

git show TREEISH:path/to/file >path/to/local/file

18
「git show」の目的は、ファイルの内容と正確に一致することが保証されていない、読み取り可能な形式で端末にデータを出力することです。ワードドキュメント全体をコピーし、そのコンテンツを別のドキュメントにコピーアンドペーストしないほうがよいのと同じです。
権念

内容を現在のブランチと比較できるように表示したかっただけです(コードの一部を確認してください)。これでvimを使用したいのですが...構文の強調表示などのために
isaaclw

3
チェックアウトを行う前に内容を比較するには、git diff <other branch> <path to file>うまくいきます。
Randall

2
@Gonen:gitバージョン2.21.0以降では、「git show」のマニュアルページに「プレーンなblobの場合、プレーンなコンテンツが表示される」と記載されています。これが私たちが常に良いことを意味するかどうかはわかりません。私はそのように画像を取得するのにちょっと警戒
心があり

52

チェックアウトコマンドの使用について:

  git diff --stat "$branch"
  git checkout --merge "$branch" "$file"
  git diff --stat "$branch"

8
ファイルが両方のブランチに存在しない場合、マージ(2番目のコマンド)は機能しないことに注意してください
simpleuser '23

うーん。私はdiffstatを持っていません。聞いたことがないので、それは特定のバージョンのdiffツールですか(そして、私はそれに切り替えるべきですか?):D
dudewad

git diff--stat基本的にdiffstatと同じことを行う引数をサポートします。
hlovdal 2016

これを機能させるには、両方のブランチをローカルでチェックアウトする必要がありました。
UnitasBrooks 2017年

18

1)ファイルのコピーが必要なブランチにいることを確認します。例:私はサブブランチファイルをマスターにしたいので、チェックアウトする必要があるか、マスターにいる必要がありますgit checkout master

2)サブブランチからマスターに必要な特定のファイルだけをチェックアウトします。

git checkout sub_branch file_path/my_file.ext

ここでsub_branchは、コピーする必要があるファイル名が後に続くそのファイルがある場所を意味します。


非常に便利でよく説明されています。
Abk

15

madlepの答えに従って、ディレクトリblobを持つ別のブランチから1つのディレクトリをコピーすることもできます。

git checkout other-branch app/**

opの質問に関しては、ファイルを1つだけ変更した場合、これは正常に機能します^ _ ^


1
最初に両方のブランチを適切にプルするかorigin/other-branch、repoブランチを参照するために使用する必要があることに注意してください。基本、でも私を噛んで。(答えは素晴らしいです-編集は必要ありません)
akauppi 2015

8

私は使用しますgit restore(git 2.23以降で利用可能)

git restore --source otherbranch path/to/myfile.txt


なぜ他のオプションよりも優れているのですか?

git checkout otherbranch -- path/to/myfile.txt-ファイルを作業ディレクトリにコピーするだけでなく、ステージング領域にもコピーします(このファイルを手動でコピーgit addして実行した場合と同様の効果があります)。git restoreステージング領域には触れません(--stagedオプションで指示されない限り)。

git show otherbranch:path/to/myfile.txt > path/to/myfile.txt標準のシェルリダイレクトを使用します。Powershellを使用する場合、テキストのエンコードに問題があるか、バイナリの場合はファイルが壊れる可能性があります。でgit restore変更するファイルのすべてで行われるgit実行可能。

別の利点は、次のようにしてフォルダー全体を復元できることです。

git restore --source otherbranch path/to

または、git restore --overlay --source otherbranch path/toファイルの削除を避けたい場合。たとえばotherbranch、現在の作業ディレクトリよりもファイルが少ない場合(およびこれらのファイルが追跡される場合)、--overlayオプションgit restoreを指定しないとファイルが削除されます。しかし、これは適切なデフォルトの動作です。おそらく、otherbranch「同じですが、現在のブランチに追加のファイルがある場合」ではなく、のようにディレクトリの状態を同じにする必要があります。


いい答えだ。git restoreソースブランチからターゲットブランチの新しいファイルにファイルをコピーする方法はありますか?git showを使用すると、シェルリダイレクト(git show otherbranch:path/to/file1.txt > path/to/file2.txt)でこれを行うことができますが、あなたが言及した理由により、シェルリダイレクトを回避したいと思います。
AdamaalAdama

1
@AdmiralAdamaはそうではありません。そして、私はそれを得る大きなチャンスはないと思いますgit restore(しかし誰が知っているか;))。このリダイレクトの問題は基本的にはPowershellの問題であり、他のシェルに問題があるかどうかはわかりません。私は通常「git bash」または「cmd」に戻って、「git showwith redirection」コマンドを使用する必要があります。または、GitExtensionsのようなGUIを使用して、コミットのファイルツリーを参照し、任意のファイルで[名前を付けて保存]をクリックします。
Mariusz Pawelski

ああ、分かった。私はPowershellを使用していないので、おそらくシェルのリダイレクトはnpです。情報をありがとう。
AdamaalAdama

3

受け入れられた回答では、最初のオプションは(実行されたように)他のブランチからファイル全体をステージングgit add ...し、2番目のオプションはファイルをコピーするだけですが、変更をステージングしないことに注意してください(ファイルを手動で編集しただけで、顕著な違いがありました)。

ステージングせずに別のブランチからGitコピーファイル

段階的な変更(例git add filename)

$ git checkout directory/somefile.php feature-B

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   directory/somefile.php

未処理の変更(ステージングまたはコミットされていない):

$ git show feature-B:directory/somefile.php > directory/somefile.php

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   directory/somefile.php

no changes added to commit (use "git add" and/or "git commit -a")

「feature-Bはファイルではありません」と表示され、ブランチ名が最初に来ます。これについて-> "> directory / somefile.php"とすると、ファイルのエンコードが変更される可能性がありますか?
Tiago Oliveira de Freitas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.