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

时间:2009-04-15 22:59:35

标签: svn merge branch

我在Subversion中有一个带有几个分支的源代码树。我刚刚在一个活跃的分支中完成了一个相当激烈的调试会话,现在需要将更改合并到新分支。最近,在旧分支中的所有开发(显然)之后但在我提交所有调试之前,新分支被取下了trunk(代表已发布的代码)。但是,尝试svn merge时,不会合并所有已添加的文件。它增加了一些,但不是全部。

以下是时间表:

  • 分支中继以创建分支dev1。
  • dev1中的代码,修改文件和添加文件。
  • 分支中继以创建分支dev2。
  • 修复dev1中的错误,修改文件但不添加文件。
  • 将dev1中的所有更改合并到dev2。

正如所料,有许多变化,包括新文件,但不是全部。是因为我合并的版本范围包括dev2分支的版本吗?或者我应该合并到主干然后下到dev2?

编辑:所有代码都完全提交到Subversion。但我认为可能发生的事情是文件添加不会通过合并传播。也就是说,先前合并 dev1添加了一些文件,但是来自 dev1的合并包含来自先前合并的提交不包含添加的文件。

但我还在检查。

6 个答案:

答案 0 :(得分:28)

以下陈述不正确:

  

在跨多个修订版进行合并时,添加到分支然后在分支上更改的文件不会被添加

这意味着合并完全被打破了。

进行合并时,您需要确保合并创建该文件的修订版,否则您将收到有关无目标的警告。

要注意的另一件事是,如果你合并到一个工作副本,然后决定你不满意并恢复一切,新添加的文件仍将在工作副本中,所以如果你合并再次,未版本控制的文件将阻止新文件的合并,所以你会错过它们。因此,运行“svn status”并删除未版本控制的文件将确保合并正常工作。

不应该关于添加空文件的注释,因为新文件没有来自何处的历史记录。换句话说,它不是副本,因此“svn log”不会显示其历史记录。最后,如果文件是一个千兆字节的照片,你不希望将它合并到一个新文件中,因为那时存储库将有两个完全相同的上下文副本。使用历史记录进行合并和复制可以节省存储库存储(至少在放入代理共享之前)。

答案 1 :(得分:28)

我一直都知道svn警告是颠覆的迹象表明你搞砸了。然后我遇到了上面的情况,我从一个分支合并得到了很多跳过的文件,但我知道我有合并的正确路径。跳过的文件是在分支上添加和更改但在主干上尚未存在的所有文件。

然后我意识到所有这些文件已经存在,虽然没有版本化,但是在我的工作副本上还没有 - 我在一周之前完成了测试合并(不是干运行)并且还原了,但文件从未被物理删除由我的SVN客户端。一旦我从我的工作副本中删除它们,问题就消失了!

答案 2 :(得分:1)

在跨多个修订版进行合并时,添加到分支然后在分支上更改的文件不会被添加,因为subversion正在尝试将上下文差异应用于工作中不存在的文件目录(新文件)。您将看到来自svn的警告,声明类似“跳过丢失文件blah.c ...”

有两种基本方法可以解决这个问题。提交你的分支(这总是一个好主意,因为合并有时可能会搞砸事情,而且简单地能够恢复更好),然后合并每个添加文件的特定修订(一次一个)以确保文件实际上已添加到您的工作目录。

您拥有的另一个选项是为修订版中添加的所有文件创建空文件(例如,使用unix touch命令)(您可以通过简单地与 - 合并来获取这些文件的列表 - 干运行说明符并记下所有“跳过丢失文件”警告),然后运行与整个修订列表的合并(如-r 1023:1040)。这会将更改合并到新的空文件中,所有内容都应该是peachy:)

答案 3 :(得分:0)

(因为这似乎是搜索此问题的最佳帖子,我将评论相同行为的另一个可能原因。)

在我的情况下,我尝试合并的修订版中的某些更改已由其他开发人员手动合并,而在先前版本中提交。 SVN注意到这些更改已经合并,而不是列出合并中的文件。

在这种情况下,您应该只验证文件确实已正确合并并正常继续。

答案 4 :(得分:0)

首先,你需要慢慢地合并分支,我的意思是先修改一些,然后再进行其他一些修改,依此类推。

当您完成所有修订时,只需单击svn中的添加文件按钮,我就使用RapidSVN。它很容易使用。

注意:在跨多个修订版进行合并时,添加到分支然后在分支上更改的文件不会被添加,因为subversion正在尝试将上下文差异应用于不存在的文件工作目录(新文件)。

您将看到svn发出警告,说明“跳过丢失的文件......”

答案 5 :(得分:0)

一点点工作可能会对你有所帮助:

  1. 安装Tortoise SVN时,请不要忘记启用命令行客户端工具(更详细at here)。
  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 - Setting done! Using uninstall.bat to remove this feature. echo - In order to use: echo 1.Right-click on which folder you want export files echo 2.Select 'Get modified files' to run command. echo 3.It will create and copy modified files into new folder. set /p BYE=- Hoping it useful! Good bye!

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

  6. 现在,您可以通过右键单击要获取所有文件的SVN文件夹来获取所有已修改的文件,然后在菜单中选择获取所有已修改的文件
  7. 希望我的代码对您有用!