Git diff --name-onlyとそのリストをコピーします


151

2つのリビジョン間で変更されたファイルのリストを取得するだけです。これは簡単です。

git diff -–name-only commit1 commit2 > /path/to/my/file

しかし、リストされているすべてのファイルを別の場所にコピーしたい場合、何を書けばよいですか?そして、私はコピーされたファイルのために完全に同一のディレクトリ構造が必要です。

たとえば、私はファイルを変更して追加しました:

/protected/texts/file1.txt
/protected/scripts/index.php
/public/pics/pic1.png

/home/changes/変更および追加されたすべてのファイルに入れたい:

/home/changes/protected/texts/file1.txt
/home/changes/protected/scripts/index.php
/home/changes/public/pics/pic1.png

1
あなたが何を達成しようとしているのかよくわからない…別のクローンへの変更の伝播?パッチを作成しますか?gitリポジトリ外のファイルにパッチを適用していますか?
knittl

パッチではなく、変更されたファイルの正確なコピー構造。パッチに似ていますが、ソリッドファイルが含まれています
BazZy

そして、はい、gitリポジトリ外のファイルにパッチを適用します-私にとって最も近いターゲット:)
BazZy

3
ごめんなさい。何?ファイルの変更とツリーの変更をキャプチャして再生しますか?それはパッチです。git format-patchコミット範囲に対してこれを行うことができます。
knittl

1
git diff commit1 commit2 > my.patchそしてcd other/path; patch -p1 < my.patch。ファイルの完全なコピーを使用する必要があるのはなぜですか?パッチが適用されない可能性があり、他のディレクトリが実際にはcommit1状態にないためと考えられる場合は、状態からすべてを実際にコピーする必要がありcommit2ます...
Cascabel

回答:


118

私がテストした次のコマンドを試してください:

$ cp -pv --parents $(git diff --name-only) DESTINATION-DIRECTORY

2
cp --parentsヒントをありがとう、私は何年もそのオプションが欲しかったし、それが存在することを知りませんでした!..明らかに、私はそれを探すことを決して気にしませんでした= \
Stephan Henningsen

2
--parentsオプションがcp利用できないため、これはMacでは機能しないことに注意してください。
M.ジャスティン

ファイルに異常な文字が含まれている場合に使用するためのヒントはありますか?空白、ノルディック文字。
Halvor Holsten Strand 2017

@HalvorStrand、私はそれをテストしていませんが、IFS=$'\n'最初に設定することでそれを行うことができます。(元のIFS値を台無しにしないように、サブシェルで実行するのが望ましいです。)
ワイルドカード

cp: cannot stat 'git diff --name-only': No such file or directoryWindowsのgit bashでエラーが発生します。何が悪いのですか?宛先ディレクトリが存在します
Shiva

14

以下は正常に動作するはずです。

git diff -z --name-only commit1 commit2 | xargs -0 -IREPLACE rsync -aR REPLACE /home/changes/protected/

さらに説明するには:

  • -zとにgit diff --name-onlyNULで区切られたファイルの出力のための手段のリストは、あなたのファイル名は、それらに異常な文字を持っているだけの場合には、代わりに改行のバイト。

  • パラメータのNUL区切りリストとして標準入力を解釈すると言います。-0xargs

  • -IREPLACEデフォルトxargsではrsyncコマンドの最後にパラメータが追加されるため、これが必要です。代わりに、後者をどこに置くかということREPLACEです。(これは、このサーバー障害の回答からの良いヒントです。)

  • -aパラメータrsync可能な場合などの権限、所有権を、維持するための手段。-R先のファイルを作成するときに、完全な相対パスを使用することを意味します。

更新:の古いバージョンxargsを使用している-i場合は、の代わりにオプションを使用する必要があります-I。(前者は、以降のバージョンので非推奨ですfindutils。)


それは奇妙です-どのオペレーティングシステムを使用していますか?それがLinuxディストリビューションの場合、どのディストリビューションで、何をxargs --version言いますか?
Mark Longair、2011

1
ああ、そのバージョンのxargs -iでは代わりに使用する必要がありますが、これは新しいバージョンでは非推奨です-4.1は現在かなり古いものです。回答を更新します。
Mark Longair、2011

@Mark:-Iバージョンによってはスペースが必要な場所を読んだことを覚えているので、-I REPLACE代わりに試してみてください。
ミケル

気にしないで。それも機能しません。 -Ifindutils、2004
Mikel

--diff-filter=d削除したファイルをリストから除外するには、追加する必要があります。そうしないと、それらを変更フォルダーにコピーしようとしたときにエラーが発生します。そうでなければ素晴らしい答え。ありがとう!
taymless

11

ここにワンライナーがあります:

変更されたファイルを一覧表示し、*。zipとしてパックします。

git diff --name-only | zip patched.zip -@

最後にコミットされた変更済みファイルをリストし、それらを* .zipとしてパックします。

git diff --name-only HEAD~ HEAD | zip patched.zip -@

Windowsを使用している場合は、sourceforge.net
projects / gnuwin32 / files /

@ Radon8472インストールしますsed.exeか?まだzipWindowsで見つかりません。
シバ

いいえ、リンクはsedではなくzip.exeのダウンロードを指しています。コマンドラインでzipを使用できない場合は、zip.exeがインストールされているフォルダーを環境PATH変数に追加する必要があります。
Radon8472



2

それは完全に動作します。

git diff 1526043 82a4f7d --name-only | xargs zip update.zip

git diff 1526043 82a4f7d --name-only |xargs -n 10 zip update.zip

1

cpio入力しやすく、ハードリンクを作成し、ファイル名のスペースを処理する方法については誰も言及していません。

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