[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Do we need to store redundant mergeinfo?

From: Paul Burba <ptburba_at_gmail.com>
Date: Thu, 10 Nov 2011 14:43:46 -0500

On Thu, Nov 10, 2011 at 12:13 PM, Julian Foad <julian.foad_at_wandisco.com> wrote:
>          2  3   4  5
> BranchA--o-----------------------------------------
>           \
>            \      "A:2"
> BranchB-----o---o----------------------------------
>                  \
>                   \  "A:2 B:3-4"
> BranchC------------o-------------------------------
>
> Philip and I were prompted by a customer to consider why Subversion copies
> mergeinfo from branch to branch, in transitive merges (branch A -> branch B
> -> branch C).  Why do we need mergeinfo on branch C that refers directly to
> A?

Hi Julian,

It's not clear from your diagram: is BranchB is a copy of BranchA or a
copy of their common parent? If the latter we do need to copy the
mergeinfo contained in the diff in merges from BranchB to BranchC, in
addition to recording mergeinfo describing that merge. For example:

# Start with a vanilla greek tree from our test suite.
# Make two branches:

>svn copy A branchA
  A branchA

>svn copy A branchB
  A branchB

>svn ci -m "create two branches from 'trunk'"
  Adding branchA
  Adding branchB

  Committed revision 2.

# Make a change on our "trunk":

>echo trunk edit > A\mu

>svn ci -m "trunk edit"
  Sending A\mu
  Transmitting file data .
  Committed revision 3.

# Merge that "trunk" change to our first branch:

>svn merge ^^/A branchA -c3
  --- Merging r3 into 'branchA':
  U branchA\mu
  --- Recording mergeinfo for merge of r3 into 'branchA':
   U branchA

>svn pl -vR
  Properties on 'branchA':
    svn:mergeinfo
      /A:3

>svn ci -m "Merge a trunk change from ^/A to ^/branchA"
  Sending branchA
  Sending branchA\mu
  Transmitting file data .
  Committed revision 4.

# Now merge that merge from branchA to branchB:

>svn merge ^^/branchA branchB -c4
  --- Merging r4 into 'branchB':
  U branchB\mu
   U branchB
  --- Recording mergeinfo for merge of r4 into 'branchB':
   G branchB

>svn st
   M branchB
  M branchB\mu

# The mergeinfo from the first merge is copied and new mergeinfo
# is set to describe *this* merge:

>svn diff --depth empty branchB
  Index: branchB
  ===================================================================
  --- branchB (revision 2)
  +++ branchB (working copy)

  Property changes on: branchB
  ___________________________________________________________________
  Added: svn:mergeinfo
     Merged /A:r3
     Merged /branchA:r4

# Commit the second merge:

>svn ci -m "Merge from ^/branchA to ^/branchB of the prior merge
  from ^/A to /branchA"
  Sending branchB
  Sending branchB\mu
  Transmitting file data .
  Committed revision 5.

# Make a local change to branchB that would conflict with r3
# if that revision were re-merged:

>svn up -q

>echo local edit > branchB\mu

# Try to remerge r3 from ^/A to branchB, this is a non-conflicting
# noop because of the mergeinfo '/A:3' on the target carried from
# the merge in r5:

>svn merge ^^/A branchB -c3
  --- Recording mergeinfo for merge of r3 into 'branchB':
   U branchB

>svn revert -R .
  Reverted 'branchB\mu'

# Now let's manually erase the that mergeinfo with a propset:

>svn ps svn:mergeinfo /branchA:4 branchB
  property 'svn:mergeinfo' set on 'branchB'

>svn diff
  Index: branchB
  ===================================================================
  --- branchB (revision 5)
  +++ branchB (working copy)

  Property changes on: branchB
  ___________________________________________________________________
  Modified: svn:mergeinfo
     Reverse-merged /A:r3

>svn pl -vR
  Properties on 'branchA':
    svn:mergeinfo
      /A:3
  Properties on 'branchB':
    svn:mergeinfo
      /branchA:4

>svn ci -m "Erase transitive mergeinfo"
  Sending branchB

  Committed revision 6.

# It's probably obvious what the problem is going to be...
# ...but if not, now let's try that merge of r3 from ^/A to
# branchB again:

>svn up -q

# Again we make a local change to branchB that would
# conflict with r3:

>echo local edit > branchB\mu

# And BOOM:

>svn merge ^^/A branchB -c3
  Conflict discovered in
'C:/SVN/src-trunk/Debug/subversion/tests/cmdline/svn-test-work/working_copies/merge_tests-123/branchB/mu'.
  Select: (p) postpone, (df) diff-full, (e) edit,
          (mc) mine-conflict, (tc) theirs-conflict,
          (s) show all options: p
  --- Merging r3 into 'branchB':
  C branchB\mu
  --- Recording mergeinfo for merge of r3 into 'branchB':
   U branchB
  Summary of conflicts:
    Text conflicts: 1

Now if instead you meant that BranchC is a copy of BranchB is a copy
of BranchA, then we still have a similar problem. I won't show the
whole example, but in the above example we instead copied ^/A to
^/branchA in r2, copied ^/branchA to ^/branchB in r3, made an edit to
^/A/mu in r4, merged r4 from ^/A to ^/branchA in r5, and merged r5
from ^/branchA to /branchB in r6, then we still have a similar
problem:

>svn ps svn:mergeinfo /branchA:5 branchB
  property 'svn:mergeinfo' set on 'branchB'

>echo local edit > branchB\mu

>svn merge ^^/A branchB -c4
  Conflict discovered in
'C:/SVN/src-trunk/Debug/subversion/tests/cmdline/svn-test-work/working_copies/merge_tests-124/branchB/mu'.
  Select: (p) postpone, (df) diff-full, (e) edit,
          (mc) mine-conflict, (tc) theirs-conflict,
          (s) show all options: p
  --- Merging r4 into 'branchB':
  C branchB\mu
  --- Recording mergeinfo for merge of r4 into 'branchB':
   G branchB
  Summary of conflicts:
    Text conflicts: 1

Does this answer your question at all (or did I answer a different question ;-)

Paul

> If, as I believe to be the case, Subversion only supports merge tracking
> if the branching graph is tree-shaped, then the only merges allowed to or
> from branch C are those to or from branch B (and those to or any further
> branches to the "right" of it: D1, D2).  And thus the mergeinfo on C that
> refers to A is not useful.  It's redundant anyway, in the sense that if we
> hadn't stored it explicitly then we could crawl the branching graph to find
> it, but that's not my concern; rather, I wonder if it is ever actually
> providing any benefit.
>
> It seems to me that we must have done this (propagate mergeinfo) because we
> intended that Subversion's merging should support merging patterns more
> complex than that.  But do we?  The big question for me at the moment is: do
> people in reality rely on Subversion doing kinds of merging that make use of
> this transitive mergeinfo?
>
> - Julian
>
>
Received on 2011-11-10 20:44:19 CET

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.