简体   繁体   English

Git 差异和复制

[英]Git Diff and Copy

I am wanting to run a Static Code Analysis (PMD) report against the files that have been added or modified as part of a pull request on bitbucket.我想针对在 bitbucket 上的拉取请求中添加或修改的文件运行静态代码分析 (PMD) 报告。 The files that have been modified etc are available locally within the pipeline image, however I need to do a git diff to identify the changes ONLY between the source branch (pulling from) and the target branch (to be merged into).已修改的文件等在管道映像中本地可用,但是我需要执行 git diff 以仅识别源分支(从中提取)和目标分支(要合并到)之间的更改。 I will then be executing the PMD CLI (with rulesets etc) against a directory that will contain only the "changed files" to highlight any issues with those files specifically as part of the change.然后,我将对一个仅包含“已更改文件”的目录执行 PMD CLI(带有规则集等),以突出这些文件的任何问题,特别是作为更改的一部分。

I basically want to copy out the files indicated in the git diff result.我基本上想复制 git diff 结果中指示的文件。 I hope this provides some more context.我希望这能提供更多背景信息。

I have tried finding some examples and done testing however I am just not getting it right due to my lack of understanding on these crazy linux commands :)我已经尝试找到一些示例并进行了测试,但是由于我对这些疯狂的 linux 命令缺乏了解,我只是没有做对:)

So far I have the below command, but results in an empty folder.到目前为止,我有以下命令,但结果是一个空文件夹。

git diff --name-only --pretty $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH | xargs -i {} cp {} -t ~/branch-diff/

xargs might have problems will a number of files - argument would be too big. xargs 可能会对多个文件有问题 - 参数太大。 I Propose something like我提出类似的建议

for name in $(git diff --name-only --pretty $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH); do cp $name ~/branch-diff/; done

As a result you will have all these files in one directory (without directory tree).结果,您将所有这些文件都放在一个目录中(没有目录树)。 Other question is that is it really what you need.另一个问题是这真的是你需要的。

Firstly, the issues with your current solution:首先,您当前解决方案的问题:

  1. xargs doesn't play nicely with filenames which have spaces in. You may not have that problem now, and you can work around it, but it's better to just avoid this if possible. xargs不能很好地处理包含空格的文件名。您现在可能没有这个问题,您可以解决它,但如果可能的话最好避免这种情况。
  2. cp does not build a directory tree - which you can trivially verify - so it wouldn't do what you asked anyway. cp不会构建目录树-您可以轻松验证-因此无论如何它都不会按照您的要求进行操作。
  3. git does not produce pathnames relative to the current path, but to the working tree base. git不会产生相对于当前路径的路径名,而是相对于工作树的基础。
  4. The filenames produced by git diff $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH don't even have to exist in your working tree, but only in (at least one of) the branches. git diff $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH生成的文件名甚至不必存在于您的工作树中,而只存在于(至少一个)分支中。
  5. If there's a diff between the two versions of a file, you haven't said which one you want copied!如果文件的两个版本之间存在差异,那么您还没有说要复制哪个版本!

A functional script using standard file tools would look something like:使用标准文件工具的功能脚本如下所示:

#!/bin/bash
# diffcopy.sh
#
DESTDIR="$1"
BRANCH1="$2"
BRANCH2="$3"

# so relative paths match git output
SRCDIR="$(git rev-parse --show-toplevel)"

# choose the branch whose files we want to copy
git checkout "$BRANCH2"

# make the output directory
mkdir -p "$DESTDIR"

# sync the changed files
rsync -a --files-from=<(git diff --name-only "${BRANCH1}".."${BRANCH2}") "$SRCDIR" "$DESTDIR"

# restore working copy
git checkout -

There may be a better way to do this purely in git, but I don't know it.纯粹在 git 中可能有更好的方法来做到这一点,但我不知道。

If you have the GNU variant of cp and xargs , you can do this:如果你有cpxargs的 GNU 变体,你可以这样做:

git diff --name-only -z $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH |
   xargs -0 cp --target-directory="$HOME/branch-diff/" --parents

This does not spawn a cp per file, but copies as many files as possible with one cp process.这不会为每个文件生成一个cp ,而是使用一个cp进程复制尽可能多的文件。 By specifying --target-directory , the destination can come first on the cp command, and xargs can paste as many source file names at the and of the cp command as it likes.通过指定--target-directory ,目标可以在cp命令的前面出现,并且xargs可以根据需要在cp命令的 和 粘贴任意数量的源文件名。 --parents keeps the directory names of the source files. --parents保留源文件的目录名称。

The -z in git diff separates file names by a NUL character instead of line breaks, and the -0 of xargs knows how to take the NUL separated path list apart without stumbling over whitespace characters in file names. git diff中的-z用 NUL 字符而不是换行符分隔文件名,并且xargs-0知道如何将 NUL 分隔的路径列表分开,而不会绊倒文件名中的空白字符。

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

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