在 Subversion 中跨分支合并并不是添加所有新文件。为啥不?

Posted

技术标签:

【中文标题】在 Subversion 中跨分支合并并不是添加所有新文件。为啥不?【英文标题】:Merging across branches in Subversion isn't adding all the new files. Why not?在 Subversion 中跨分支合并并不是添加所有新文件。为什么不? 【发布时间】:2010-10-19 17:43:46 【问题描述】:

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

时间线如下:

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

正如预期的那样,有很多变化,包括新文件,但不是全部。是因为我要合并的版本范围包括创建 dev2 分支的版本吗?还是我应该先合并到主干,然后再合并到 dev2?

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

但我仍在检查。

【问题讨论】:

【参考方案1】:

以下说法不正确:

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

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

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

另一件需要注意的事情是,如果您合并到工作副本中,然后决定您对它不满意并还原所有内容,新添加的文件仍将在工作副本中,所以如果您合并同样,未版本化的文件将阻止新文件的合并,因此您会错过它们。因此,运行“svn status”并删除未版本控制的文件将确保合并正常工作。

关于添加空文件的评论不应该做,因为这样新文件就没有它来自哪里的历史记录。换句话说,它不是一个副本,所以“svn log”不会显示它的历史。最后,如果该文件是一张千兆字节的照片,您不会希望将其合并到一个新文件中,因为这样存储库就会有两个完全相同的上下文副本。与历史记录合并和复制可以节省存储库的存储空间(至少在放入 rep-sharing 之前)。

【讨论】:

这是有道理的。我想我有一些棘手的合并要做...... :-( +1 指出“svn revert”会破坏合并,这是我的问题。 我不同意。当您合并两个分支和所有修订时。如果你的两个分支都有 GBs 的数据,它会丢失很多文件。【参考方案2】:

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

然后我意识到所有这些文件已经存在于我的主干工作副本中,尽管没有版本化——我在一周前进行了测试合并(不是试运行)并恢复,但这些文件从未被物理删除通过我的 SVN 客户端。一旦我从主干的工作副本中物理删除它们,问题就消失了!

【讨论】:

感谢您记录此内容。这正是我的问题。 这也是我的确切问题。如果 svn 说“嘿,这些文件已经存在于你的 WC 中”,而不是直接跳过它而不做任何解释,那就太好了 +1 这正是发生在我身上的事情(树冲突,文件被跳过,文件没有被添加 --> 又是树冲突) 为了修复svn revert之后的剩余文件,我使用了this answer中的svnclean脚本 同意 - “跳过”的描述性不够。告诉我他们已经在那里了!【参考方案3】:

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

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

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

【讨论】:

我喜欢“先添加空文件”的技巧。那么它只是一个包含所有“差异肉”的三角洲。酷。【参考方案4】:

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

就我而言,我试图合并的修订版中的一些更改已经由另一位开发人员手动合并,并且在以前的修订版中提交。 SVN 注意到更改已经合并,并且没有列出合并中的文件。

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

【讨论】:

【参考方案5】:

简单的首先你需要慢慢合并分支,我的意思是先进行几个修订,然后再进行其他几个修订,依此类推。

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

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

您将看到来自 svn 的警告,说明类似“正在跳过丢失的文件...”

【讨论】:

【参考方案6】:

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

    安装 Tortoise SVN 时,别忘了启用命令行客户端工具(更多详情at here)。 创建一个空文件夹。 打开记事本,然后复制下面的代码并保存为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

    打开记事本,然后复制下面的代码并保存为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!

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

    现在您可以通过右键单击要获取所有文件的 SVN 文件夹并在菜单中选择获取所有修改的文件来获取所有修改的文件。

希望我的代码对你有用!

【讨论】:

以上是关于在 Subversion 中跨分支合并并不是添加所有新文件。为啥不?的主要内容,如果未能解决你的问题,请参考以下文章

Subversion 合并后树冲突 - “本地删除,合并时传入编辑”

在 Subversion 中合并分支时的冲突预防

为啥我在 Subversion 中遇到树冲突?

Subversion:如何找到所有未合并到主干的修订?

为啥“合并后删除分支”只删除远程GIT分支而不是本地?

Git将修补程序合并到多个分支