如何直观地比较 Linux 上由 SVN 版本控制的文件夹的两个修订版?

How to visually compare two revisions of a folder versioned by SVN on Linux?

我可以使用以下命令将当前文件夹状态与其最新版本进行比较:

meld .

meld 显示已更改文件的列表。可以单击每个文件并查看差异。

是否可以将当前文件夹状态与其特定版本(不是最新版本)进行比较?

TortoiseSVN 允许比较任意修订,但它仅适用于 Windows。 SmartSVN 是专有的。 SVN CLI 不适用于大的变更集(CLI diff 适用于小型提交,但很难将其用于分支比较和大量变更)。

也许我可以签出修订版以比较到一个单独的文件夹中并使用 meld 比较两个文件夹。但我想应该有一个更简单的方法。

前言

这里的问题是题外话:正如评论中已经提到的,这是软件推荐网站的问题

  1. 在 SVN 中具有历史记录的每个版本化对象 都可以使用 PEG-revision 来引用其历史状态
  2. SVN-repo 中的文件夹 是版本控制的对象
  3. 为了比较两个文件夹,您必须拥有文件夹差异工具(对于您的 OS)并且知道(命令行)options 来调用它

根据Slant's comparison

  • Meld 可以在 Linux 上用于文件夹差异
  • 最好的文件夹差异工具是 Beyond Compare

从上面的第 1-3 点可以看出,Meld 可以用于您的任务形式

meld folder@REV1 folder@REV2

代码审查或分支合并通常需要文件夹比较。看来最简单的做法是:

  1. 查找合并到当前分支的最后一个主干修订
  2. 如果当前分支不是从trunk合并而来,则查找分支创建修订
  3. 对某个文件夹进行指定修订的结帐主干
  4. 比较trunk文件夹和brach文件夹

我没有找到任何支持它的现有工具。这是我使用的 bash 脚本,也许对某人有用:

TRUNK_BASE_PATH=~/tmp

BRANCH_RELATIVE_URL=$(svn info --no-newline --show-item relative-url)
if [[ "$BRANCH_RELATIVE_URL" != *"/branches/"* ]]; then
  echo "Run it in a branch. Relative URL should contain /branches/. Given: $BRANCH_RELATIVE_URL"
  exit 1
fi

TRUNK_RELATIVE_URL=${BRANCH_RELATIVE_URL%%/branches/*}/trunk
echo "Trunk relative URL: $TRUNK_RELATIVE_URL"

ROOT_URL=$(svn info --no-newline --show-item repos-root-url)
TRUNK_URL=${ROOT_URL}${TRUNK_RELATIVE_URL:1}
echo "Trunk URL: $TRUNK_URL"

TRUNK_PATH=${TRUNK_BASE_PATH}/${TRUNK_URL#*://}
echo "Trunk local copy path: $TRUNK_PATH"

BRANCH_PATH=$(svn info --no-newline --show-item wc-root)
echo "Branch local copy path: $BRANCH_PATH"

SUBFOLDER=$(realpath --relative-to="$BRANCH_PATH" .)
echo "Comparing subfolders: $SUBFOLDER"

TRUNK_REVISION=$(svn mergeinfo --show-revs merged -R "$TRUNK_RELATIVE_URL" "$BRANCH_PATH" | tail -n 1)
if [[ -z "$TRUNK_REVISION" ]]; then
  TRUNK_REVISION=$(svn log -r 1:HEAD --limit 1 --stop-on-copy -q | grep -oP "^r\K[0-9]+")
  echo "Comparison with trunk@$TRUNK_REVISION from which the current branch was copied"
else
  echo "Comparison with trunk@$TRUNK_REVISION with which the current branch was last merged"
fi

if [[ -d "$TRUNK_PATH/.svn" ]]; then
  echo "Found .svn subfolder in the local trunk copy, updating it"
  svn update -r $TRUNK_REVISION "$TRUNK_PATH"
else
  echo "Not found .svn subfolder in the local trunk copy, checking out it"
  svn checkout "$TRUNK_URL" -r $TRUNK_REVISION "$TRUNK_PATH"
fi

meld "$TRUNK_PATH/$SUBFOLDER" . &!