【问题标题】:Updated file will not commit更新的文件不会提交
【发布时间】:2016-11-28 16:42:11
【问题描述】:

许多修改回来了,我的 SVN 存储库中的一个好文件被覆盖了。比方说,修订版 10 包含所需格式的文件 samplefile.txt;当前版本为 30。

我用修订版 10 samplefile.txt 更新我的工作副本:

$ svn update -r 10 samplefile.txt

我确认我的文件工作副本中有这个旧的但需要的内容。现在,我想将此文件提交到 repo,形成版本 31。

$ svn commit -m "reverting file to 10" samplefile.txt

然而,这永远不会提交。执行该命令会返回到终端提示符,而没有通常的 SVN 输出来确认新修订,并且更新的文件不会出现在存储库中。

如何使用 SVN 命令提交此内容?

【问题讨论】:

  • @alroc 谢谢,我找不到!虽然我的问题与提问者的问题基本相同,但我不理解任何答案,即使不是全部,也大部分都与“反向合并”有关。提问者似乎同意反向合并是一个不令人满意的解决方案,即使他们确实接受了答案。另一方面,@twm 的答案在您的链接中的任何答案中都找不到,如果它有效,它似乎正是我正在寻找的(我明天将对其进行测试以确保)。
  • 反向合并是最正确的解决方案,所以你应该花时间去了解它是如何工作的。另请参阅下面 bahrep 的回答,因为他已链接到手册的相关部分。
  • @alroc 我已经阅读了手册的链接部分,我已经阅读了链接的 SO 问题,我已经阅读了svn help merge,我已经搜索了更多信息,但我仍然没有'没有足够详细地了解merge 命令,无法将其评估为解决方案。在解决此问题之前,我必须将其作为一个单独的问题提出。
  • 这很不幸。我发现 Subverison 手册是我读过的一些最好的软件文档。

标签: svn


【解决方案1】:

您应该在工作副本中运行以下命令:

svn merge ^/trunk . -c-10

并提交此更改:

svn commit -m "Revert changes made in r10"

阅读SVNBook | Undoing Changes。

【讨论】:

  • 感谢您的链接!不过,这是我见过的最糟糕的文档。我已经阅读了它两次以及其他来源,但我仍然不明白merge 命令是如何定义的,更不用说反向合并是什么了。感谢您的回复,但如果没有进一步的解释,我不能接受这个作为答案。
  • @PiotrChernin 这不是参考,而是手册章节。你检查过svnbook.red-bean.com/en/1.8/svn.ref.svn.c.merge.html 吗?
  • 您收到的有关在此上下文中合并的任何进一步解释都将基于您已链接到的文档,因此重写手册中已经详细解释的内容没有多大意义。这是正确的答案,无论你是否理解。
  • @alroc 我正在考虑从头开始编写一个关于 svn 的新文档。在我看来,目前形式的 SVNBook 并不能真正帮助用户。 SVNBook 长篇大论。
  • @bahrep 有一个宾果游戏。定义merge 命令所需的信息分布在两个或三个不同的部分,其中大部分是关于变更集和mergeinfo 的潜在不相关场景和转移——虽然这对于理解merge 如何在幕后工作很重要, 一般不需要学习如何使用该命令。我已经写了一个简化的解释并将其发布。
【解决方案2】:

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 帮助我解决这个问题!

【讨论】:

    【解决方案3】:

    试试这个:

    svn update samplefile.txt
    svn cat -r 10 samplefile.txt > samplefile.txt
    svn commit -m "reverting file to 10" samplefile.txt
    

    【讨论】:

    • 这些步骤将打破历史记录,因此不会显示修订版 10 被“拉到”当前 HEAD 修订版。
    • @alroc 提交注释表明该文件的来源是修订版 10。除此之外,我不明白它为什么重要。这会破坏 SVN 的任何关键功能,还是您只是担心全面的文档?
    • @PiotrChernin 它将破坏svn:mergeinfo,因为不会记录任何合并信息。
    • @bahrep 我已经使用 SVN 一段时间了,这是svn:mergeinfo 第一次出现,所以我怀疑这对我来说一定不重要。如果我这样做,使用 SVN 存储库的哪些日常功能会中断? @twm 的解决方案不就像提交一个文件,其更改恰好使其与文件的先前版本相同吗?我一直这样做,到目前为止我没有遇到任何问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2019-09-10
    • 2012-08-18
    • 1970-01-01
    • 2020-08-13
    • 2012-11-19
    相关资源
    最近更新 更多