Subversion:提取 diff+log 并重放

Subversion:提取 diff+log 并重放

我发现自己处于这样的情况:客户为我们提供了一台计算机,我可以使用 VPN 接入他们的网络,以便访问他们的 SVN 存储库。但是我们不可能都在这台计算机上进行开发,所以我们导出了“我们的分支”,然后将其导入我们自己的 SVN 存储库。由于客户并不真正关心我们的日常工作,我们计划在方便的时候简单地放入大型变更集。我相信这一切都会奏效。

最近我一直在想是否有任何简单的方法可以从我们的 SVN 中获取变更集(即差异 + 消息),然后将其重播到客户端的 SVN 中。类似于什么git format-patchgit am允许。

从表面上看,svn log --diff这似乎是可行的,但我必须编写一些脚本将输出分离为补丁(使用 进行应用svn patch)和提交消息(提供给svn commit -F)。我希望有一个解决方案不需要我编写这样的脚本 ;)

答案1

  1. LAST_MOVED 是最后移动的提交。一开始是0,后来会增加。

  2. 获取提交列表:

    svn log -q -r $LAST_MOVED:HEAD | grep -o ^r[0-9]*

    这将产生类似

    R10
    R12
    R16
    R22

  3. 对于每个修订版,您需要获得差异:

    svn diff -c $REVISION> $REVISION.diff

    并提交消息:

    svn log -c $REVISION | tail -n -2 | head -n -1>$REVISION.txt

    你将会拥有:

    r10.差异
    r10.txt

    r12.差异
    r12.txt

    r16.差异
    r16.txt

    r22.差异
    r22.txt

  4. 将这些文件发送到目标机器,

  5. 跑步svn update

  6. 对每个r*.diff文件r*.txt运行:

    • patch -p0 -i r{number}.diff

    • svn commit -a -m --file r{number}.txt

有一个问题svn 不区分二进制数据,因此使用此方法不会传输任何二进制数据。对于每个二进制文件,您将获得:

索引:path/to/file/something.jar
=========================================================================
无法显示:文件标记为二进制类型。svn
:mime-type = application/octet-stream

您应该在不同的文件中检测此字符串,对于这些文件,您可以使用中描述的外部差异命令https://stackoverflow.com/a/2255846/146745

答案2

我猜@andrej 他的答案在提交消息不超过一行文本时有效。现在它给你留下了一个空的提交消息:

$ svn log -c r80 test/ | tail -n 2 | head -n 1

$

注意:我假设您的版本svn log支持所呈现的选项。

更好的方法是从 svn 根目录中的某个路径 grep 修订版本并使用。如果您有以单个开头的提交消息,则svn log正则表达式会调整为不匹配单个。r

以下命令根据影响目录的修订创建补丁dir

$ dir=test/
$ svn log "${dir}" | grep -oE '^r[0-9]+' \
        | while read -r rev; do
                svn log --diff -c ${rev} "${dir}" > "${rev}-${dir/\/*/}.patch";
        done

修补 r80-test.patch 的命令:

$ patch -p 0 < r80-test.patch

使用 svn 版本 1.9.5 进行测试。

答案3

已弃用,请参阅我的其他答案

  1. 更改文件
  2. 跑步svn add *
  3. 跑步svn diff > file.diff
  4. 将 file.diff 复制到客户端电脑
  5. 在客户端电脑上运行svn update
  6. 跑步patch -p0 -i file.diff
  7. 跑步svn commit -a
  8. 享受!

相关内容