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.







Reply via email to