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

issue-2897(reflective merge solution)

From: Kamesh Jayachandran <kamesh_at_collab.net>
Date: Thu, 31 Jul 2008 19:50:48 +0530

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi All,

Little bit background for the purpose of general audience.

Problem:
- ---------------------
- - Create /feature_branch from /trunk.
- - Synch up change(rX) from /trunk to /feature_branch and commit at rY
along with some other local changes 'Z'.
- - When you merge /feature_branch to /trunk later it should merge only
'Z' not rX again to /trunk as it is not a change originated in
/feature_branch.

Available solution:
- ------------------------
Solution 1: One can use '--reintegrate' switch to 'merge' command, but
it has lots of expectation on merge-target, which makes it unusable on a
feature_branch with renamed subtrees which is common when someone does a
refactoring there.(issue-3128).

Solution 2: issue-2897 branch 'extract non-reflective changes from a
reflective revision and apply'.
   This branch relies on availability of 'what revisions+merge_sources
got merged in a commit'. It had this information implemented in 'sqlite'
 our old 'mergeinfo' store.
   In January we have changed this 'sqlite' based mergeinfo storage to a
'fs' based 'storage', which this implementation has not caught up with yet.
   Given the issue-3128 in 'Solution 1' it seems 'Solution 2' is worth a
try.

Solution 2 explained:

Part 1: Store mergeinfo_added in a commit in the back ground(Currently I
have kind of local patch implementing the same for bdb, I will initiate
a separate discussion once my local patch becomes clean and mature).

Part 2: Retrieve the 'reflective rev and reflected merge ranges' within
a given merge range via the API. See API doc of
'svn_fs_get_commit_and_merge_ranges'
http://svn.collab.net/repos/svn/branches/issue-2897/subversion/include/svn_fs.h

Part 3: Treat the reflective revision specially as detailed below by
custom merge call back.

a) reflective text changes:
 reflective_merge_file_changed(mine, older, yours)
 mine = WC file.
 older = file_at_reflective_rev-1
 yours = file_at_reflective_rev

Normal merge_file_changed applies diff(older, yours) to mine.
This diff can contain the changes 'synch up from trunk' as well as the
local adhoc changes and conflict resolutions.

Applying the diff directly is going to cause lots of headaches.

So objective is to have a meaningful diff of *only local adhoc changes
done before committing the merge*.

Let me take the example and explain,

Case1:

We merge -r13, -r17, -r29 from /trunk to /feature_branch and commit at
r40 (Assume this is the only synch up)

Now we merge /feature_branch -r1:40 back to /trunk.

It does a merge of -r1:39 which is a normal merge.
It does a reflective merge of 40.
Let us say /feature_branch/test.c got a change from a merge at r40(Our
first merge)

To calculate the *meaningful diff*, We apply -r13 change to OLDER, and
r17 change to OLDER, r29 change to OLDER.

Now in this case after the above 3 merges(r13, r17, r29) OLDER becomes
YOURS and hence no change is applied to MINE.

Case2:

We merge -r13, -r17, -r29 from /trunk to /feature_branch + local
non-conflicting change to /feature_branch/test.c and commit at r40
(Assume this is the only synch up)

Now we merge /feature_branch -r1:40 back to /trunk.

It does a merge of -r1:39 which is a normal merge.
It does a reflective merge of r40.
Let us say /feature_branch/test.c got a change from a merge at r40(Our
first merge)

To calculate the *meaningful diff*, We apply -r13 change to OLDER, and
r17 change to OLDER, r29 change to OLDER.

Now in this case after the above 3 merges(r13, r17, r29) OLDER becomes
(YOURS-'*local non conflicting changes*') and hence
(YOURS-YOURS +'*local non conflicting changes*') is applied to MINE. i.e
'*local non conflicting changes*'

Case3:

We merge -r13, -r17(conflicting), -r29 from /trunk to /feature_branch +
local non-conflicting change + conflict resolution to r17 to
/feature_branch/test.c and commit at r40
(Assume this is the only synch up)

Now we merge /feature_branch -r1:40 back to /trunk.

It does a merge of -r1:39 which is a normal merge.
It does a reflective merge of 40.
Let us say /feature_branch/test.c got a change from a merge at r40(Our
first merge)

To calculate the *meaningful diff*, We apply -r13 change to OLDER, and
r29 change to OLDER. (SEE WE DONT APPLY r17 as it is a conflicting one)/

Now in this case after the above 2 merges(r13, r29) OLDER becomes
(YOURS-local non conflicting changes - r17 - conflict resolution to r17)
and hence
(YOURS-YOURS +local non conflicting changes + r17 + conflict resolution
to r17) is applied to MINE. i.e local non conflicting changes + r17 +
conflict resolution to r17. Moral: If synch up gave a conflict reverse
also would give.

b)reflective tree_changes dir_added/dir_deleted/file_added/file_deleted

We have code to handle some cases, have to think extensively on this
before calling it to be complete.

As things have changed quite a lot in the last 6 months, I cut one more
branch issue-2897-take2 where I will extract changes from issue-2897.

Thanks
With regards
Kamesh Jayachandran
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIkco/3WHvyO0YTCwRAnhVAJ9zaBBok5ab+meTcpDC1A/9QAQhHACgg0dO
A0kWMWI3V6VkwBjjZQEsYHM=
=xd43
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-07-31 16:21:58 CEST

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.