Hi, I tested with a reproduction scenario and found this:
A) If I do an svn update on the top-level WC before the merge command, the merge goes through OK and I can checkin. B) If I don't do an svn update on the top-level WC before the merge command, the merge goes wrong and svn complains about out-of-date when I do the checkin. A following svn update seems to not change anything and I can checkin the wrong merge without problems. There are a few things still not clear to me: 1) Before this svn update, svn stat -u shows nothing out-of-date, so it's strange that an update makes any difference. 2) svn update itself does not mention any updates, it just says "At revision 6." 3) If I check the relevant svn:mergeinfo properties before / after this svn update, I see no changes at all. However, if I check with the svn mergeinfo command, then I do see a change after the update. What else is being used to calculate the actual mergeinfo? 4) If I don't do the update before svn merge, why does svn complain about out-of-date at checkin instead of at the merge itself? See attachment for reproduction script + output for both cases. Kind regards and thanks for the help, Pieter-Jan On 3 November 2010 10:17, Johan Corveleyn <jcor...@gmail.com> wrote: > On Tue, Nov 2, 2010 at 11:29 AM, Pieter-Jan Busschaert > <pieterjan.busscha...@gmail.com> wrote: >> Hello, >> >> Here is some more information: >> >>>> Inside branch1/subfolder, we do a merge from trunk/subfolder. >>> >>> Do you mean trunk/project/subfolder here? >> >> yes >> >>> Anyway, branch1/subfolder does not have any mergeinfo, >>> since the previous merge was done on branch1. So Subversion >>> does not know that you have already merged the changes to line 1. >> >> Correct, but isn't SVN supposed to crawl up the tree to find >> mergeinfo? I thought this was the most simple usecase of inherited >> mergeinfo, which is described in various places, for instance here: >> http://help.collab.net/index.jsp?topic=/faq/mergeinfo.html > > Yes, you are absolutely right. Mergeinfo is normally inherited, so any > mergeinfo set on the branch1 folder applies to the entire subtree (and > svn indeed crawls up the tree to find all the mergeinfo that applies). > Except if the mergeinfo is marked with an asterisk '*', which means > "non-inheritable mergeinfo". For more in-depth information about > mergeinfo, see [1]. > >>> Merges from trunk to branch and vice-versa should always be done >>> from the root of the project (in your case branches/project/branch1) >> >> I can not believe this is true. I can not control the other users and >> I have had reports of similar issues from a few different users here, >> so it seems a real use case. > > Well, it's *recommended* to do merges always from the project root, > but it's not required. SVN supports so-called "subtree merges" (which > have the potential to only merge part of a revision). > > The reason it's recommended to do merges from the project root, is > that it avoids explicit mergeinfo all over your tree. For every > subtree merge, SVN records explicit mergeinfo on that subtree root. > This means that that subtree will no longer inherit mergeinfo from > higher up the tree. For this reason, explicit mergeinfo needs to be > maintained all the time by SVN (because it will no longer crawl up > from that point). Every subsequent merge at the project root causes > those explicit-mergeinfo-paths to have their mergeinfo properties > updated, even if they are not affected by the merge, which can be > quite confusing to users. Other than that, subtree merges work just > fine in SVN, just because of the explicit mergeinfo on the subtrees. > > (the upcoming 1.7 release will improve the situation a bit, IIUC: the > not-affected-subtrees will no longer have their mergeinfo updated all > the time, only if they are affected by the merge). > >>> I don't think so, as I think Subversion did the correct thing, given the >>> information it has. >> >> Well, I still think it did not do the correct thing, as it had more >> info available than it actually used. >> >>> However, I recommend you to push for an upgrade of SVN, as I remember 1.5 >>> was not particularly good with merging. >> >> I have just tested with 1.6.13 on a test pc and it behaves exactly the same. >> >> >> >> By reading the details of inherited mergeinfo in the collabnet FAQ, >> maybe the bug is because mergeinfo is not up to date in the working >> copy and SVN uses that instead of contacting the repository. If this >> is the case, I would expect SVN to give me a "please update" warning >> when I do the merge command. > > Yes, maybe that's the problem. Can you retest this with an update at > the right place, to see if the problem still occurs? > > Maybe you should check out the section "Mixed Revision Working Copies > and Mergeinfo" in the above mentioned article [1], to see if it > describes what you're seeing. > > If that's the case, you are probably right about the warning. I think > this is being addressed in the upcoming 1.7 as well (see [2] and [3]). > > If the problem is something else, please try to come up with a simple > reproduction recipe, starting with the creation of an empty repository > (svnadmin create ...), demonstrating the problem. > > Cheers, > -- > Johan > > [1] http://www.collab.net/community/subversion/articles/merge-info.html > [2] http://svn.haxx.se/dev/archive-2010-10/0000.shtml > [3] http://svn.apache.org/viewvc?view=revision&revision=1027970 >
$ svnadmin create repo $ REPO=file://$PWD/repo $ svn mkdir --parents $REPO/trunk/subdir -m mkdir Commited revision 1. $ svn co $REPO wc A wc/trunk A wc/trunk/subdir Checked out revision 1. $ cd wc $ echo -e "line1 orig\n\nline2 orig\n\nline3 orig\n" > trunk/subdir/test.txt $ svn add trunk/subdir/test.txt A trunk/subdir/test.txt $ svn ci -m orig Adding trunk/subdir/test.txt Transmitting file data . Committed revision 2. $ svn cp $REPO/trunk $REPO/branch -m createbranch Committed revision 3. $ svn stat -u * branch/subdir/test.txt * branch/subdir * branch * 1 . Status against revision: 3 $ svn up A branch A branch/subdir A branch/subdir/test.txt Updated to revision 3. $ echo -e "line1 orig\n\nline2 change1\n\nline3 orig\n" > trunk/subdir/test.txt $ svn ci -m change1 Sending trunk/subdir/test.txt Transmitting file data . Committed revision 4. $ cd branch $ svn merge $REPO/trunk --- Merging r3 through r4 into '.': U subdir/test.txt $ svn stat -u -v .. 4 4 pjbu ../trunk/subdir/test.txt 3 2 pjbu ../trunk/subdir 3 2 pjbu ../trunk 3 2 pjbu ../branch/subdir M 3 2 pjbu ../branch/subdir/test.txt M 3 3 pjbu ../branch 3 3 pjbu .. Status against revision: 4 $ svn ci -m merge1 Sending branch Sending branch/subdir/test.txt Transmitting file data . Committed revision 5. $ svn stat -u -v .. 4 4 pjbu ../trunk/subdir/test.txt 3 2 pjbu ../trunk/subdir 3 2 pjbu ../trunk 5 5 pjbu ../branch/subdir/test.txt 3 2 pjbu ../branch/subdir 5 5 pjbu ../branch 3 3 pjbu .. Status against revision: 5 $ cd .. $ echo -e "line1 orig\n\nline2 orig\n\nline3 change2\n" > trunk/subdir/test.txt $ svn ci -m change2 Sending trunk/subdir/test.txt Transmitting file data . Committed revision 6. ############################################## ## START : no svn update before merge -> bad ############################################## $ svn stat -u -v 6 6 pjbu trunk/subdir/test.txt 3 2 pjbu trunk/subdir 3 2 pjbu trunk 5 5 pjbu branch/subdir/test.txt 3 2 pjbu branch/subdir 5 5 pjbu branch 3 3 pjbu . Status against revision: 6 $ cd branch/subdir $ svn propget svn:mergeinfo . $ svn propget svn:mergeinfo .. /trunk:3-4 $ svn mergeinfo $REPO/trunk --show-revs eligible r1 r2 r4 r6 $ svn mergeinfo $REPO/trunk --show-revs merged $ svn mergeinfo $REPO/trunk/subdir --show-revs eligible r4 r6 $ svn mergeinfo $REPO/trunk/subdir --show-revs merged $ svn merge $REPO/trunk/subdir --- Merging r3 through r6 into '.': U test.txt $ cat test.txt line1 orig line2 change1 line3 change2 $ svn stat -u ../.. M 5 ../../branch/subdir/test.txt M 3 ../../branch/subdir Status against revision: 6 $ svn ci -m merge2 Sending subdir svn: Commit failed (details follow): svn: Directory '/branch/subdir' is out of date $ svn up At revision 6. $ svn stat -u ../.. M 6 ../../branch/subdir/test.txt M 6 ../../branch/subdir Status against revision: 6 $ svn ci -m merge2 Sending subdir Sending subdir/test.txt Transmitting file data . Committed revision 7. ############################################## ## STOP : no svn update before merge -> bad ############################################## ## START : svn update before merge -> good ############################################## $ svn up At revision 6. $ svn stat -u -v 6 6 pjbu trunk/subdir 6 6 pjbu trunk/subdir/test.txt 6 6 pjbu trunk 6 5 pjbu branch/subdir 6 5 pjbu branch/subdir/test.txt 6 5 pjbu branch 6 6 pjbu . Status against revision: 6 $ cd branch/subdir $ svn propget svn:mergeinfo . $ svn propget svn:mergeinfo .. /trunk:3-4 $ svn mergeinfo $REPO/trunk --show-revs eligible r1 r2 r4 r6 $ svn mergeinfo $REPO/trunk --show-revs merged $ svn mergeinfo $REPO/trunk/subdir --show-revs eligible r6 $ svn mergeinfo $REPO/trunk/subdir --show-revs merged r4 $ svn merge $REPO/trunk/subdir --- Merging r5 through r6 into '.': U test.txt $ cat test.txt line1 orig line2 orig line3 change2 $ svn stat -u ../.. M 6 ../../branch/subdir M 6 ../../branch/subdir/test.txt Status against revision: 6 $ svn ci -m merge2 Sending subdir Sending subdir/test.txt Transmitting file data . Committed revision 7.