svn merge 的工作原理
svn merge 命令以多种不同的方式使用,但从根本上说,它总是按顺序做两件事:1)通过比较两个来源来创建 diff,以及 2)应用该 差异到一个目标。
这两个源和目标由命令行参数指定,但在许多情况下,如果merge 可以隐式确定它们应该是什么,则可以省略一个或多个参数。
一般来说,命令行调用的形式是
$ svn merge [create diff] [apply to target]
更详细的,
1) [创建差异]
svn merge 比较源 A 和源 B 以创建 diff,这是将源 A 转换为源 B 所需的指令集。
源可以是文件集的任何元素:主干或分支、目录子树或单个文件。源可以是工作副本的一个元素(在这种情况下,它由其文件路径标识)或存储库的一个元素(在这种情况下,它由其 repo URL 标识)。源可以引用存储库的任何修订;如果未指定修订,则通常假定为最新修订 (HEAD)。
2) [适用于目标]
一旦创建了 diff,merge 就会将该组指令应用于目标。目标必须是工作副本的一个元素; merge 命令通常假定在此工作副本中执行。
显然,如果目标与用于创建 diff 的两个来源完全无关,那么当 diff 指令应用于它时,您将变得无意义.目标也必须是与两个源相同的“事物类型”;也就是说,如果 diff 比较两个分支或分支/主干,那么目标也应该是一个分支或主干。如果两个源都是文件,那么目标应该是一个文件,以此类推。
这就是为什么merge 命令必须小心构造的原因。不过不要太担心:因为目标必须是工作副本的一个元素,merge 只能影响工作副本,而不是 repo。只要您不检查merge 的结果而不commit,如果您错误地merge,则很容易修复。
反向合并
还原文件的“反向合并”是cherry-pick merge 的一种形式,它将单个元素的两个不同版本作为其两个来源。因此,我们在命令行中只指定一个源名称,并附上-r 或-c 标志来说明哪两个修订版本将是源。
-r 标志及其参数指定修订,可以是绝对数字N 或范围N:M。
-c 标志指定由修订所做的更改。这在某些情况下很有用,但在这种情况下却没有用,因为当前文件(rev 30)和所需文件(rev 10)之间的差异跨越了 20 个不同修订版的许多更改 - 我不想还原单个更改,但多达二十个!
就我假设的samplefile.txt而言,
[create diff] = -r 10:30 <URL of repository>/path/to/samplefile.txt
生成将@987654343@ 转换为samplefile.txt@30 的指令集。不过,这不是我想要的——我想要相反的指令集,将当前的samplefile.txt@30 带回samplefile.txt@10。这可以通过反转转速数来指定,即
[create diff] = -r 30:10 <URL of repository>/path/to/samplefile.txt
这就是使它成为“反向合并”的原因。 (请注意,-r 标志与“反向”一词无关。)
我的目标是我的工作副本中的文件samplefile.txt,或者
[apply to target] = WC_root/filepath/to/samplefile.txt
由于 diff 构造为采用 samplefile.txt@30 -> samplefile.txt@10,因此我的工作副本中的副本必须是最新版本(rev 30)。检查这一点很重要,因为我之前直观地将文件更新为 rev 10,但由于某种原因,尝试将该内容作为修订版 31 提交回存储库是徒劳的。所以总是一定要update 在执行 merge 命令之前。
使用反向合并恢复文件
将[create diff] 和[apply to target] 放在一起,使用反向合并将samplefile.txt 从其rev 30 内容恢复到rev 10 内容的命令是
$ svn update
$ svn merge -r 30:10 <URL of repository>/path/to/samplefile.txt WC_root/filepath/to/samplefile.txt
如果一切顺利,并且samplefile.txt 的当前内容确实是修订版 10 的内容,那么我现在提交 repo:
$ svn commit -m "reverting file to rev 10" WC_root/filepath/to/samplefile.txt
为其他开发人员的利益锁定文件还原。
参考资料:
我能找到的关于如何定义merge 命令的最佳通用文档在此处的 SVN Book 中给出:
Merge Syntax
@bahrep 链接的手册部分提供了几个示例,说明如何使用merge 完成不同的任务。 (我不能在这里重复链接,因为这使我超过了 2 个链接的限制。)
当然还有svn help merge,阅读这些链接后会更清楚(希望是这个答案)。
非常感谢@alroc 和@bahrep 帮助我解决这个问题!