在Subversion中跨分支合并时,为什么不会添加所有新文件?

25
我在Subversion中有一个源代码树,其中包含几个分支。我刚刚在一个活跃的分支上完成了一次相当强烈的调试工作,现在需要将更改合并到新分支。新分支是最近从trunk(表示发布的代码)中分出来的,在旧分支的所有开发之后(显然),但在我提交所有调试之前。然而,尝试使用svn merge将更改合并时,并没有合并所有被添加的文件。它添加了一些,但不是全部。
以下是时间轴:
- 从trunk中分支出dev1分支。 - 在dev1中编写代码,修改文件并添加文件。 - 从trunk中分支出dev2分支。 - 在dev1中进行错误修复,修改文件但未添加文件。 - 将dev1中的所有更改合并到dev2中。
正如预期的那样,有许多更改,包括新文件,但不是全部。这是因为我要合并的版本范围包括创建dev2分支的版本吗?或者我应该先将更改合并到trunk,然后再合并到dev2?
编辑:所有代码都已完全提交到Subversion。但是我认为可能发生的情况是文件添加不会通过合并传播。也就是说,之前合并到dev1的合并添加了一些文件,但涵盖了来自dev1的提交的合并却不包括添加的文件。
不过我仍在检查。
6个回答

30

我一直知道svn警告是subversion表明你某方面出了问题的指示。然后我遇到了上述情况,在从一个分支合并时,我得到了许多被跳过的文件,但我知道我已经正确地输入了合并路径。这些被跳过的文件都是在分支上添加和更改但尚不存在于主干上的文件。

随后我意识到,所有这些文件都已经存在于我的主干工作副本中(未版本化),因为我一个星期前进行了一次测试合并(不是干运行),但我撤销了该操作,但是这些文件从未被SVN客户端物理删除。当我从我的主干工作副本中物理删除它们时,问题就解决了!


5
感谢您记录这个。这正是我的问题。 - Craig McQueen
4
这也正是我的问题所在。如果svn能够说“嘿,这些文件已经存在于你的本地副本中了”,而不是默默跳过并且没有任何解释,那将会很好。 - Shezan Baig
3
这正是我所经历的情况(树冲突,文件被跳过,文件未被添加--> 再次出现树冲突)。 - fmuecke
为了修复svn revert后的剩余文件,我使用了这个答案中的svnclean脚本。 - rescdsk
3
同意-“跳过”不够描述。告诉我他们已经到那里了! - Alex
然后我意识到所有这些文件都已经存在,尽管没有版本控制。这也是我的问题。感谢您指出这一点(+1)。 - magicandre1981

30
以下陈述是不正确的:

在分支上添加并更改的文件在跨多个版本合并时不会被添加

这意味着合并完全失效。
当您执行合并操作时,确保合并创建文件的版本,否则将收到有关目标不存在的警告。
另一件需要注意的事情是如果您将合并操作合并到工作副本中,然后决定不满意并撤销所有更改,则新添加的文件仍将留在工作副本中。因此,如果再次进行合并,则未加版本控制的文件将阻止新文件的合并,从而使您错过它们。因此运行 "svn status" 并删除未加版本控制的文件将确保合并正常工作。
有关添加空文件的评论不应该执行,因为新文件没有其来源的历史记录。换句话说,它不是一个复制,因此 "svn log" 不会显示其历史记录。最后,如果文件是一个千兆字节的照片,您不希望将其合并到新文件中,因为存储库将具有两个完全相同的内容副本。合并和复制带有历史记录可节省存储库存储空间(至少在引入 rep-sharing 之前)。

有道理。我想我需要做一些棘手的合并... :-( - staticsan
5
谢谢您指出“svn revert”会破坏合并,这正是我的问题所在。+1 - Dean Povey
我不同意。当您合并两个分支和所有修订版本时,如果您的两个分支都有GB级别的数据,则会丢失很多文件。 - flik

1

在一个分支中添加并更改的文件,在跨多个版本进行合并时不会被添加,因为Subversion试图将上下文差异应用于工作目录中不存在的文件(新文件)。您将看到来自svn的警告,例如“跳过缺少的文件blah.c ...”

有两种基本方法来处理这个问题。提交您的分支(这总是一个好主意,因为合并有时会弄乱事情,并且简单地能够还原要好得多),然后按顺序合并每个特定添加文件的修订版本(一次一个)以确保文件实际上被添加到您的工作目录中。

您可以选择的另一种选项是为所有跨修订版本添加的文件创建空文件(例如使用unix touch命令),然后使用整个修订列表(如-r 1023:1040)运行合并(您可以通过使用--dry-run说明符执行合并并注意所有“跳过缺少的文件”警告来获取这些文件的列表)。这将把更改合并到新的空文件中,一切都应该很好 :)


1
我喜欢“先添加空文件”的技巧。然后只需一个增量,其中包含所有的“diff meat”。很酷。 - Roboprog

0

(由于这似乎是搜索此问题时的顶部帖子,因此我将评论另一个可能导致相同行为的原因。)

在我的情况下,我尝试合并的修订版本中的一些更改已被另一位开发人员手动合并并在先前的修订版本中提交。 SVN 注意到更改已经合并,并且没有在合并中列出文件。

在这种情况下,您应该仅验证文件是否正确合并并继续正常操作。


0
一点点工作可能会帮助你:
  1. 安装Tortoise SVN时,不要忘记启用命令行客户端工具(更多细节请参见此处)。
  2. 创建一个空文件夹。
  3. 打开记事本,然后复制下面的代码并保存为Get_all_modified_files.bat
    @echo off set SRC_PATH=%1 set /a COUNTER=1 :SET_DES_DIR set DES_PATH=%SRC_PATH%_%COUNTER% if exist %DES_PATH% ( set /a COUNTER=%COUNTER% + 1 goto :SET_DES_DIR ) :GET_MODIFIED_FILES pushd %1 svn st | find "M" > LIST_FILES for /f "tokens=2" %%b in (LIST_FILES) do ( echo f | xcopy "%SRC_PATH%\%%b" "%DES_PATH%\%%b" ) del LIST_FILES popd pause
  4. 打开记事本,然后复制下面的代码并保存为Install.bat

    @echo off setlocal enabledelayedexpansion :PREPARE if exist Install.reg del Install.reg if exist Uninstall.bat del Uninstall.bat if exist LIST_FILES del LIST_FILES :GET_DETAIL dir "%0\.." /s /b /o:gn > LIST_FILES set /a COUNTER=1 for /f "tokens=*" %%b in (LIST_FILES) do ( if !COUNTER! == 1 set Get_all_modified_files=%%b set /a COUNTER=!COUNTER! + 1 ) set Get_all_modified_files=!Get_all_modified_files:\=\\! set Get_all_modified_files=@="!Get_all_modified_files! %%1" :CREATE_INSTALL_FILE echo Windows Registry Editor Version 5.00>>Install.reg echo. >>Install.reg echo [HKEY_CLASSES_ROOT\Directory\shell\Get modified files]>>Install.reg echo. >>Install.reg echo [HKEY_CLASSES_ROOT\Directory\shell\Get modified files\command]>>Install.reg echo !Get_all_modified_files!>>Install.reg echo @echo off>Uninstall.bat echo echo yes ^| reg delete "HKEY_CLASSES_ROOT\Directory\shell\Get modified files">>Uninstall.bat echo set ^/p BYE^=Enter any key to exit...>>Uninstall.bat :RUN_AND_REMOVE regedit /s Install.reg if exist Install.reg del Install.reg if exist LIST_FILES del LIST_FILES endlocal :INSTRUCTION echo - 设置完成!使用uninstall.bat来删除此功能。 echo - 使用方法: echo 1.右键单击要导出文件的文件夹 echo 2.选择“获取修改的文件”以运行命令。 echo 3.它将创建并复制修改后的文件到新文件夹中。 set /p BYE=- 希望它有用!再见!

  5. 以管理员身份右键单击Install.bat文件,以添加注册表此命令。

  6. 现在,您可以右键单击要获取所有文件的SVN文件夹,并在菜单中选择Get all modified files来获取所有修改后的文件。

希望我的代码对你有用!


0

首先,您需要慢慢合并分支,我的意思是先合并几个版本,然后再合并其他几个版本,以此类推。

当您完成所有修订后,只需在svn中点击“添加文件”按钮,我使用的是RapidSVN。它很容易使用。

注意:将文件添加到分支上,然后在分支上进行更改时,在跨越多个版本进行合并时不会添加这些文件,因为Subversion试图将上下文差异应用于工作目录中不存在的文件(新文件)。

您将看到来自svn的警告,指出类似“跳过缺失文件…”的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接