简体   繁体   English

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

[英]Git diff --name-only and copy that list

I just want to get a list of changed files between two revisions, which is simple:我只想获取两个修订版之间已更改文件的列表,这很简单:

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

But, what should I write, if I want copy all that listed files to another place?但是,如果我想将所有列出的文件复制到另一个地方,我应该写什么? And I need completely identical directory structure for copied files.我需要完全相同的目录结构来复制文件。

For example, I have modified and added files:例如,我修改并添加了文件:

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

I want to have in /home/changes/ all those changed and added files:我想在/home/changes/所有更改和添加的文件:

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

尝试以下我已经测试过的命令:

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

The following should work fine:以下应该可以正常工作:

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

To explain further:进一步解释:

  • The -z to with git diff --name-only means to output the list of files separated with NUL bytes instead of newlines, just in case your filenames have unusual characters in them. -z to 与git diff --name-only意味着输出用 NUL 字节而不是换行符分隔的文件列表,以防万一您的文件名中有不寻常的字符。

  • The -0 to xargs says to interpret standard input as a NUL-separated list of parameters. -0xargs表示将标准输入解释为以 NUL 分隔的参数列表。

  • The -IREPLACE is needed since by default xargs would append the parameters to the end of the rsync command. -IREPLACE是必需的,因为默认情况下xargs会将参数附加到rsync命令的末尾。 Instead, that says to put them where the later REPLACE is.相反,这表示将它们放在后面的REPLACE所在的位置。 (That's a nice tip from this Server Fault answer .) (这是这个 Server Fault answer的一个很好的提示。)

  • The -a parameter to rsync means to preserve permissions, ownership, etc. if possible. rsync-a参数意味着在可能的情况下保留权限、所有权等。 The -R means to use the full relative path when creating the files in the destination. -R表示在目标中创建文件时使用完整的相对路径。

Update: if you have an old version of xargs , you'll need to use the -i option instead of -I .更新:如果您有旧版本的xargs ,则需要使用-i选项而不是-I (The former is deprecated in later versions of findutils .) (前者在findutils更高版本中已弃用。)

Here's a one-liner:这是一个单行:

List changed files & pack them as *.zip:列出更改的文件并将它们打包为 *.zip:

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

List last committed changed files & pack them as *.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 https://stackoverflow.com/users/79061/sebastian-paaske-t%c3%b8rholm

It works perfectly.它完美地工作。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM