Git diff –name-only并复制该列表

我只想获得两个修订版本之间更改的文件列表,这很简单:

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 

尝试下面的命令,我已经testing过了:

 $ cp -pv --parents `git diff --name-only` DESTINATION-DIRECTORY 

以下应该工作正常:

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

进一步解释:

  • -zgit diff --name-only意味着输出用NUL字节而不是换行符分隔的文件列表,以防万一你的文件名有不寻常的字符。

  • -0xargs表示将标准input解释为NUL分隔的参数列表。

  • -IREPLACE是必需的,因为默认情况下, xargs会将这些参数附加到rsync命令的末尾。 相反,那就是把它放在后面REPLACE位置。 (这是一个很好的提示,从这个服务器故障的答案 。)

  • rsync-a参数意味着保留权限,所有权等,如果可能的话。 -R表示在目标中创build文件时使用完整的相对path。

更新:如果你有一个老版本的xargs ,你需要使用-i选项而不是-I 。 (前者在更高版本的findutils被弃用。)

这里是一个单行的:

列出更改的文件并将其打包为* .zip:

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

列出上次提交的更改文件并将其打包为* .zip:

 git diff --name-only HEAD~ HEAD | zip patched.zip -@ 
 zip update.zip $(git diff --name-only commit commit) 
 #!/bin/bash # Target directory TARGET=/target/directory/here for i in $(git diff --name-only) do # First create the target directory, if it doesn't exist. mkdir -p "$TARGET/$(dirname $i)" # Then copy over the file. cp -rf "$i" "$TARGET/$i" done 

https://stackoverflow.com/users/79061/sebastian-paaske-t%c3%b8rholm

它完美的作品。

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

没有人提到了易于input的cpio ,创build硬链接并处理文件名中的空格:

 git diff --name-only $from..$to | cpio -pld outdir