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

tree conflicts with replace

From: Neels Janosch Hofmeyr <neels_at_elego.de>
Date: Thu, 13 Aug 2009 02:43:42 +0200

Hi tree-conflicts folks,

the irony, we were just discussing atomic replace, when a tree-conflict
failure with replaces in it pops up.

stsp received this issue on IRC from "KeeperOfTheSoul" on June 11th, his
paste was called m201b7297, which is attached in slightly tweaked form.
Let's discuss.

The reproduction script has two working copies, and *both* of them *replace*
a file 'alpha' atomically, BTW with conflicting content.
svn delete alpha;
echo "stuff" > alpha;
svn add alpha

The first WC commits fine. The second WC is forced to update and encounters
a tree-conflict.

`svn info' says:
Tree conflict: local delete, incoming delete upon update
  Source left: (file) ^/trunk/alpha_at_1
  Source right: (none) ^/trunk/alpha_at_2

--> IMHO that should say "local replace, incoming replace...". Replace is
not represented in the TC-info API (action/reason only have 'add', 'del',
etc. values. Maybe it's a nice bite-sized issue to add 'replace'?)

So, the user figures: "I revert my local changes, update and carry on from
$ svn revert
Reverted 'alpha'
$ svn st
? alpha

--> Wait, the local changes were both a "delete" and an "add". Only the
"add" got reverted. Is that intended? BASE seems to be in-between the atomic
replace (sorry for the language). That's bad.

User figures: "I move alpha away so it won't become an obstruction when I
`update' the alpha from the repos".
$ mv alpha alpha.tmp
$ svn update
At revision 2.

No alpha is downloaded from the repos! The file is in fact missing but svn
thinks it is up-to-date.

Oh, but, if alpha is passed as an explicit target, everything is fine:
$ svn update alpha
A alpha

I can now compare alpha with alpha.tmp and manually merge the changes.


--> The file alpha is in a weird state where it:
 - is ignored in a recursive update, but not in an explicit one;
 - has no marking at all (status omits it, seems up-to-date);
 - does not exist in the WC but exists in the repos.
At first I tried to find a way to make "update" include "alpha" in the
recursive update. But now, I think it is better to prevent this state from
manifesting in the first place...

svn should ideally show a text-conflict on the two new 'alpha' files at some
point. It's the first thing any user would do: "what, the repos replaced the
file? I want to see the differences it has to my WC." Still, the user should
be notified that this is a tree-conflict, we can't just "silently" show a
text conflict.

What's the state of interactive tree-conflict resolution? I guess nonexistent.

This would also make sense: the first "update" should create those typical
text-conflict files in addition to marking the tree-conflict:
$ svn ci
'out of date'
$ svn up
C C alpha
$ svn st
? alpha.mine
? alpha.r2
C C alpha
> local replace, incoming replace upon update
$ svn info alpha
Tree conflict: local replace, incoming replace upon update
  Source left: (file) file:///home/neels/.../repos/trunk/alpha_at_1
  Source right: (file) file:///home/neels/.../repos/trunk/alpha_at_2
  There is a text conflict.
  Local version file: alpha.mine
  Repos version file: alpha.r2
where alpha would be the (possibly completely conflicted) text merge of the
two (do this even though they are not "related").
So there is a text-conflict in the WC, plus the node 'alpha' is marked
tree-conflicted. 'alpha' could also be marked text-conflicted at the same
time. `svn info' should hint at the text conflict files. The user has all
the information available, fixes, runs `resolved', commits.
Plus, we skip the whole conflict thing if the resulting files are identical.

...so far I mentioned only the case where both sides replaced a file. But it
is also applicable in two more cases, where a replace collides with an edit,
see *:

incoming replace, local replace --> have text conflict files, mark TC *
incoming replace, local edit --> have text conflict files, mark TC *
incoming replace, local delete --> create file 'locally added', mark TC
incoming replace, local add --> not possible, must be a replace

incoming edit, local replace --> have text conflict files, mark TC *
incoming delete, local replace --> mark 'locally added', mark TC
incoming add, local replace --> not possible, must be a replace

possibly read "run interactive text conflict resolution" instead of "have
text conflict files", or even "run interactive resolution, revert to text
conflict files when postponed".

How does this translate to replacing directories? -- seems close to a
nightmare; this mail is long enough already.

Am I saddling the horse the right way here?



Received on 2009-08-13 02:46:58 CEST

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