我正在尝试将单个提交与版本1000(影响六个Java文件)从主干合并到一个分支中。执行以下命令显示完全相同的效果:
svn merge -c1000 https://<my-project>/trunk
svn merge -r999:1000 https://<my-project>/trunk
这不仅会导致预期的六个Java文件发生变化,还会导致许多其他文件和目录(但不是repo中的所有内容)。为什么会这样?在查看文件中的确切更改时,我预计完全没有任何更改,它总是看起来像这样:
> svn diff SomeOtherFile.java
Property changes on: SomeOtherFile.java
___________________________________________________________________
Modified: svn:mergeinfo
Merged SomeOtherFile.java:r1000
是否可以恢复所有已更改的svn:mergeinfo
文件和目录,并且只提交我原本认为要合并的六个Java文件?有什么后果?
答案 0 :(得分:5)
当您在Subversion中进行合并时,您几乎应该始终合并到项目的基础。即使您正在合并的文件的目标深埋在目录层次结构中,也是如此。
Subversion使用属性(特别是svn:mergeinfo
属性)来跟踪合并。此属性将添加到进行合并的基础。如果仅从项目的根目录进行合并,则只有项目根目录才具有此属性。如果您在整个地方合并,则整个项目中将分散svn:mergeinfo
个属性。无论何时合并发生,并且该目录层次结构中的某个地方都有svn:mergeinfo
属性,该属性必须更新。
即使它们所在的目录没有更改,也不要忽略这些属性。子目录中可能存在依赖于svn:mergeinfo
的文件。
将Subversion版本视为更改集。也就是说,单个修订是可能影响多个文件的单个更改。合并也是如此。假设你的项目看起来像这样:
foo
src
test
...
main
resources
...
java
com
vegicorp
...
munge
frapify
purèe.java
在分支上,您有一个修订版,其中包含要合并到trunk中的purèe.java的更改。很容易进入foo/src/main/java/com/vegicorp/munge/frapify
目录并从那里处理合并。这会在svn:merginfo
目录上创建一个frapify
,它将永远与您永远在一起。每次在任何父目录中进行合并时,您都会使用svn:mergeinfo
进行更改。
而是在项目的根目录foo
目录上进行合并。您的合并仍将仅影响purèe.java文件,但更改的svn:mergeinfo
将是foo
目录中将进行所有其他合并的文件。
所以,你不能忽视svn:mergeinfo
。最好的情况是Subversion会认为某个特定的修订版本尚未合并,并且会再次与该修订版合并。最糟糕的是你弄乱了合并结果,你最终会加倍合并。
有办法清理这个烂摊子。浏览层次结构中的所有svn:mergeinfo
属性,并确保项目的根目录在其合并信息中包含所有这些修订。如果没有,请在根目录中合并这些更改。一旦您拥有包含每个合并的根svn:mergeinfo
,您就可以删除分散在整个项目中的其他svn:mergeinfo
。
但是,如果你没有让你的开发人员在项目的根目录中进行合并,那么几个月后你就会陷入同样的困境。因此,培训开发人员非常重要。
开发人员是坚持以自己的方式做事的顽固生物。我们在现场使用了Maven,它有一个默认的目录布局,一个团队坚持认为他们更喜欢自己的目录布局。它给我们带来了项目的各种问题,但是由于这个团队的诡计导致大规模的部署失败,他们被告知要么按照其他人的方式(以及Maven想要的方式)这样做,要么找一份新工作
即使在那之后,项目负责人仍然告诉我目录布局有多么错误,如果项目中的其他人只是遵循他的逻辑和改进的目录布局,一切都会没问题。