Git 差异和复制
Git Diff and Copy
我想要 运行 针对作为 bitbucket 拉取请求的一部分添加或修改的文件的静态代码分析 (PMD) 报告。已修改的文件等在管道映像中本地可用,但是我需要做一个 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
因此,您会将所有这些文件放在一个目录中(没有目录树)。另一个问题是它真的是你需要的。
首先,您当前解决方案存在的问题:
xargs
不能很好地处理包含空格的文件名。你现在可能没有这个问题,你可以解决它,但最好尽可能避免这种情况。
cp
不会构建目录树 - 您可以轻松验证 - 因此无论如何它都不会执行您的要求。
git
不产生相对于当前路径的路径名,而是相对于工作树基的路径名。
git diff $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH
生成的文件名甚至不必存在于您的工作树中,而只存在于(至少一个)分支中。
- 如果一个文件的两个版本之间存在差异,您还没有说明要复制哪个版本!
使用标准文件工具的功能脚本类似于:
#!/bin/bash
# diffcopy.sh
#
DESTDIR=""
BRANCH1=""
BRANCH2=""
# 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中可能是更好的方法,但我不知道。
如果你有 cp
和 xargs
的 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分隔的路径分开列出而不会绊倒文件名中的空白字符。
我想要 运行 针对作为 bitbucket 拉取请求的一部分添加或修改的文件的静态代码分析 (PMD) 报告。已修改的文件等在管道映像中本地可用,但是我需要做一个 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
因此,您会将所有这些文件放在一个目录中(没有目录树)。另一个问题是它真的是你需要的。
首先,您当前解决方案存在的问题:
xargs
不能很好地处理包含空格的文件名。你现在可能没有这个问题,你可以解决它,但最好尽可能避免这种情况。cp
不会构建目录树 - 您可以轻松验证 - 因此无论如何它都不会执行您的要求。git
不产生相对于当前路径的路径名,而是相对于工作树基的路径名。git diff $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH
生成的文件名甚至不必存在于您的工作树中,而只存在于(至少一个)分支中。- 如果一个文件的两个版本之间存在差异,您还没有说明要复制哪个版本!
使用标准文件工具的功能脚本类似于:
#!/bin/bash
# diffcopy.sh
#
DESTDIR=""
BRANCH1=""
BRANCH2=""
# 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中可能是更好的方法,但我不知道。
如果你有 cp
和 xargs
的 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分隔的路径分开列出而不会绊倒文件名中的空白字符。