Git diff ——只有名字,复制名单

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

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
170540 次浏览

以下措施应该可以奏效:

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

进一步解释:

  • -z to 和 git diff --name-only意味着输出用 NUL 字节而不是换行分隔的文件列表,以防文件名中有不寻常的字符。

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

  • -IREPLACE是必需的,因为在默认情况下,xargs会将参数追加到 rsync命令的末尾。相反,这意味着把它们放在后面的 REPLACE所在的位置。(这是一个来自 此服务器故障答案的很好的提示。)

  • rsync-a参数意味着尽可能保留权限、所有权等。-R表示在目标文件中创建文件时使用完整的相对路径。

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

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

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

下面是一句俏皮话:

列出已更改的文件并将其打包为 * . 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

没有人提到 cpio,它易于输入、创建硬链接和处理文件名中的空格:

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