Git Diff and Copy



我想对已添加或修改的文件运行静态代码分析(PMD)报告,作为bitbucket上的拉取请求的一部分。已经被修改等文件是可用的本地管道图像,但我需要做一个git diff来识别源分支(从)和目标分支(合并到)之间的变化。然后,我将对一个目录执行PMD CLI(带有规则集等),该目录将只包含"更改的文件"。

我基本上想复制出git diff结果中指示的文件。我希望这能提供更多的背景信息。

我试着找了一些例子并做了测试,但是我只是没有得到正确的,因为我缺乏对这些疯狂的linux命令的理解:)

到目前为止,我有下面的命令,但结果是一个空文件夹。

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

xargs在处理多个文件时可能会出现问题——参数太大。我建议使用

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

因此,您将把所有这些文件放在一个目录中(没有目录树)。另一个问题是,它真的是你所需要的吗?

首先,当前解决方案的问题:

  1. xargs不能很好地处理包含空格的文件名。你现在可能没有这个问题,你可以解决它,但如果可能的话,最好避免这个问题。
  2. cp不构建目录树-你可以简单地验证-所以它无论如何都不会做你所要求的。
  3. git不生成相对于当前路径的路径名,而是生成相对于工作树基的路径名。
  4. git diff $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH生成的文件名甚至不必存在于您的工作树中,但只需在(至少一个)分支中。
  5. 如果一个文件的两个版本之间有差异,你没有说你想要复制哪一个!

使用标准文件工具的功能脚本看起来像:

#!/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 -

在git中可能是更好的方法,但是我不知道。

如果您有cpxargs的GNU变种,您可以这样做:

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

这不会为每个文件生成一个cp,而是用一个cp进程复制尽可能多的文件。通过指定--target-directory,可以在cp命令中首先显示目标文件,并且xargs可以在cp命令的末尾粘贴任意多的源文件名。--parents保留源文件的目录名。

git diff中的-z用NUL字符而不是换行符分隔文件名,xargs中的-0知道如何将NUL分隔的路径列表分开,而不会在文件名中出现空白字符。

最新更新