25

I've got a source code tree in subversion with several branches. I've just finished a fairly intense debugging session in an otherwise active branch and now need to merge the changes across to the new branch. The new branch was taken off trunk (which represents released code) recently, after all the development in the old branch (obviously) but before I committed all my debugging. Attempting to svn merge, however, doesn't merge across all the files that were added. It adds some, but not all.

Here's the time line:

  • Branch off trunk to create branch dev1.
  • Code in dev1, modifying files and adding files.
  • Branch off trunk to create branch dev2.
  • Bug fix in dev1, modifying files but not adding files.
  • Merge all changes in dev1 over to dev2.

As expected, there are many changes, including new files, but not all of them. Is it because the range of versions I'm merging from includes the version that made the dev2 branch? Or should I be merging to trunk and then down to dev2?

Edit: All code is fully committed into Subversion. But I think what might be happening is that file additions do not propagate through merges. That is, a prior merge to dev1 added a few files, but a merge from dev1 that encompasses the commit from the prior merge does not include the added files.

But I'm still checking.

Eddie
  • 53,828
  • 22
  • 125
  • 145
staticsan
  • 29,935
  • 4
  • 60
  • 73

6 Answers6

30

I have always known svn warnings to be subversion's indication that you screwed up somehow. Then I ran into the above case where I was getting a lot of skipped files on a merge from a branch, but I knew I had the correct paths for the merge. The skipped files were all files that were added and changes on the branch but did not yet exist on trunk.

Then I realized that all of these files already existed, though unversioned, on my working copy of trunk -- I had done a test merge (not a dry run) a week earlier and reverted, but the files never got physically removed by my SVN client. As soon as I deleted them physically from my working copy of trunk the issue went away!

JasonZ
  • 494
  • 4
  • 13
  • 5
    Thanks for documenting this. This was my exact problem. – Craig McQueen Nov 12 '10 at 06:34
  • 4
    This was also my exact problem. It would have been great if svn said "hey these files already exist in your WC", instead of just skipping it with no explanation – Shezan Baig Feb 16 '11 at 15:31
  • 3
    +1 That is exactly what happened to me (tree conflict, files were skipped, files were not added --> again tree conflict) – fmuecke Sep 20 '11 at 09:36
  • To fix the leftover files after `svn revert`, I used the `svnclean` script from [this answer](http://stackoverflow.com/a/9144984/88198) – rescdsk Apr 04 '12 at 20:02
  • 3
    Agreed - 'skipped' is not descriptive enough. Tell me they're already there! – Alex Jun 27 '12 at 09:24
  • "Then I realized that all of these files already existed, though unversioned". this was also my issue. thanks for pointing this out (+1) – magicandre1981 Aug 06 '13 at 08:51
30

The following statement is not true:

Files that were added to a branch and then changed on the branch don't get added when doing a merge across number of revisions

That would imply merging is totally broken.

When you do the merge, you need to make sure that you do merge the revision that created the file, otherwise you'll get those warnings about no target.

The other thing to watch out for is if you do a merge into a working copy, then decide you're not happy with it and revert everything, the newly added files will still be in the working copy, so if you merge again, the unversioned files will prevent the merge of new files there, so you will miss them. So running "svn status" and removing unversioned files will ensure the merge works properly.

The comment about adding an empty file should not be done, because then the new file has no history of where it came from. In other words, it's not a copy, so "svn log" will not show its history. And finally, if the file were a gigabyte photo, you wouldn't want to merge it into a new file, because then the repository would have two copies of the exact same context. Merging and copying with history saves repository storage (at least until rep-sharing is put in).

Blair Zajac
  • 4,555
  • 3
  • 25
  • 36
1

Files that were added to a branch and then changed on the branch don't get added when doing a merge across a number of revisions because subversion is trying to apply a context diff to a file that doesn't exist in the working directory (the new file). You will see a warning from svn stating something like "Skipping missing file blah.c..."

There are two basic ways to deal with this. Commit your branch (this is always a good idea since merging can mess things up sometimes and it's much nicer to simply be able to revert), then merge each specific revision that adds files (one at a time) in order to ensure that the files actually get added to your working directory.

The other option you have is to create empty files (e.g., using the unix touch command) for all the files that were added across the revisions (you can get a list of these files by simply doing the merge with the --dry-run specifier and taking note of all the "Skipping missing file" warnings), then run the merge with your entire revision list (like -r 1023:1040). That will merge the changes into the new empty files and everything should be peachy :)

Jason Coco
  • 77,985
  • 20
  • 184
  • 180
  • 1
    I like the "add empty files first" trick. Then it's just one delta with all of the "diff meat" in it. Cool. – Roboprog Apr 16 '09 at 01:26
0

(Since this seems to be the top post when searching for this problem, I'll comment on another possible cause of the same behaviour).

In my case, some of the changes in the revision that I was trying to merge were already merged manually by another developer and commited in a previous revision. SVN was noticing that the changes were already merged and not listing the files in the merge.

In this case, you should just verify that the files are indeed merged correctly and continue normally.

user2580621
  • 132
  • 6
0

Simple first you need merge branches slowly, I mean few revision first then other few revisions and so on.

When you done all revisions just click add files button in svn, I use RapidSVN. It is easy to use.

Note: Files that were added to a branch and then changed on the branch don't get added when doing a merge across a number of revisions because subversion is trying to apply a context diff to a file that doesn't exist in the working directory (the new file).

You will see a warning from svn stating something like "Skipping missing files..."

flik
  • 3,433
  • 2
  • 20
  • 30
0

A little work may help you:

  1. When you install Tortoise SVN , don't forget enable Command line client tools (more detail at here).
  2. Create an empty folder.
  3. Open Notepad then copy codes below and save as 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. Open Notepad then copy codes below and save as 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. Run Install.bat file with Administrator by right-click in order to add registry this command.

  6. Now you can get all modified files by right-click on SVN folder that you want get all files and choose Get all modified files in menu.

Hope my codes is useful with you!

KhanhNT
  • 1
  • 1