Author: stsp
Date: Sat Jan 26 11:38:47 2013
New Revision: 1438879
URL: http://svn.apache.org/viewvc?rev=1438879&view=rev
Log:
At the interactive conflict prompt, make the 'show-diff' option show
more sensible diffs.
We used to always show a diff between 'base' and 'merged', which shows how
the pristine version of the file differs from the merged version.
However, with conflicts recorded during 'svn merge', the 'base' version
of the file is the 3-way merge base, which can be a file on a different
branch. Thus the diff would be unnecessarily large, and show changes that
don't actually appear when the user runs 'svn diff' in the working copy.
In some cases the 'show-diff' option was entirely useless to help identify
the incoming changes (e.g. try a merge of r1438602 into a 1.7.x@1438875
and select the 'show-diff' option during the conflict prompt).
To fix this, show the diff between 'mine' and 'merged' during merges,
and show the diff between 'theirs' and 'merged' during updates (this
doesn't actually change behaviour, since 'base' matches 'theirs' during
updates, but eliminates an unnecessary non-NULL check for the 'base' abspath).
A simple example of the resuling visible change in behaviour:
Consider the file ^/trunk/alpha which changed its content from 'alpha'
to 'foo' in r3, and a ^/branch off trunk@2, where 'alpha' was changed from
'alpha' to 'boo' in r4 on the branch.
When merging trunk into a branch there is a conflict, and we used to show:
--- /tmp/svn-sOVNQg Sat Jan 26 12:00:28 2013
+++ /tmp/svn-sandbox/branch/.svn/tmp/alpha.tmp Sat Jan 26 12:00:28 2013
@@ -1 +1,5 @@
-alpha
+<<<<<<< .working
+boo
+=======
+foo
+>>>>>>> .merge-right.r4
This is actually diffing 'alpha' as it appeared on trunk in r2 with
the merged file, showing the content which is already present on the
branch as newly added. This is clearly confusing (and even more confusing
in real life with large files).
Now, diff-full shows:
--- /tmp/svn-sandbox/branch/alpha.working Sat Jan 26 12:03:25 2013
+++ /tmp/svn-sandbox/branch/alpha Sat Jan 26 12:03:25 2013
@@ -1 +1,5 @@
+<<<<<<< .working
boo
+=======
+foo
+>>>>>>> .merge-right.r4
which clearly shows the change brought in during the merge, and matches
what 'svn diff' shows when we postpone the conflict.
* subversion/svn/conflict-callbacks.c
(show_diff): Tweak docstring and implementation as per above.
Modified:
subversion/trunk/subversion/svn/conflict-callbacks.c
Modified: subversion/trunk/subversion/svn/conflict-callbacks.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/conflict-callbacks.c?rev=1438879&r1=1438878&r2=1438879&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/conflict-callbacks.c (original)
+++ subversion/trunk/subversion/svn/conflict-callbacks.c Sat Jan 26 11:38:47
2013
@@ -115,8 +115,8 @@ svn_cl__accept_from_word(const char *wor
}
-/* Print on stdout a diff between the 'base' and 'merged' files, if both of
- * those are available, else between 'their' and 'my' files, of DESC. */
+/* Print on stdout a diff that shows incoming conflicting changes
+ * corresponding to the conflict described in DESC. */
static svn_error_t *
show_diff(const svn_wc_conflict_description2_t *desc,
apr_pool_t *pool)
@@ -126,15 +126,29 @@ show_diff(const svn_wc_conflict_descript
svn_stream_t *output;
svn_diff_file_options_t *options;
- if (desc->merged_file && desc->base_abspath)
+ if (desc->merged_file)
{
- /* Show the conflict markers to the user */
- path1 = desc->base_abspath;
+ /* For conflicts recorded by the 'merge' operation, show a diff between
+ * 'mine' (the working version of the file as it appeared before the
+ * 'merge' operation was run) and 'merged' (the version of the file
+ * as it appears after the merge operation).
+ *
+ * For conflicts recorded by the 'update' and 'switch' operations,
+ * show a diff beween 'theirs' (the new pristine version of the
+ * file) and 'merged' (the version of the file as it appears with
+ * local changes merged with the new pristine version).
+ *
+ * This way, the diff is always minimal and clearly identifies changes
+ * brought into the working copy by the update/switch/merge operation. */
+ if (desc->operation == svn_wc_operation_merge)
+ path1 = desc->my_abspath;
+ else
+ path1 = desc->their_abspath;
path2 = desc->merged_file;
}
else
{
- /* There's no base file, but we can show the
+ /* There's no merged file, but we can show the
difference between mine and theirs. */
path1 = desc->their_abspath;
path2 = desc->my_abspath;