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

Re: Commiting, tree conflicts and keep-local

From: Julian Foad <julian.foad_at_wandisco.com>
Date: Tue, 24 Aug 2010 15:09:14 +0100

I'm looking at the tree_conflict_tests.py 17 failure in single-DB.

  FAIL: tree_conflict_tests.py 17: --keep-local del on dir with TCs

Neels, you might be able to shed some light on this.

What's the test for?

The test says: if you have a directory with tree conflicts inside it,
you should be able to delete that directory (with the "--keep-local"
flag) and then commit the result, without having to resolve the tree
conflicts as an explicit step.

I'm not sure if that is really desired behaviour any more. AFAIK, the
intention is that the user must always resolve conflicts before

But the steps it goes through are odd. It first schedules the dir for
deletion, but leaving tree conflicts visible inside it, like Philip
observed back in May (see quoted msg below). Then it tries to commit
that delete-a-directory-with-conflicts-inside, which definitely seems
wrong, even if it "worked" in 1.6. And why is the "--keep-local"
command-line flag involved? I see no logical reason why that should
make a difference.

I wonder if the test is just preserving historical but unwanted

What happens in multi-DB mode?

The "svn delete --keep-local" marks the directory as to-be-deleted and
sets the "keep_local" flag in the DB, to tell the post-commit processing
not to remove the directory after committing its deletion. So far so
good. But it leaves the directory's children marked as conflicted,
which shows up in "status":

$ svn status
D 3 3 jrandom A/C
? C A/C/file
> local edit, incoming delete upon update
? C A/C/dir
> local edit, incoming delete upon update

At commit time, harvest_committables() says:

  if (! keep_local)
    SVN_ERR(bail_on_tree_conflicted_children(..., local_abspath,
                                             db_kind, ...));

Thus it doesn't check for conflicted children, and the commit goes
ahead. In commit post-processing, the directory is left on disk but its
metadata is all removed so it no longer has any conflicts recorded in

What happens in single-DB mode?

The same, except that no "keep_local" flag is stored in the DB, and when
harvest_committables() tries to read it back it sees FALSE. Thus
harvest_committables() DOES call bail_on_tree_conflicted_children() and
the commit fails because there are tree-conflicted children.

What should happen?

I think the required changes are:

* Commit should unconditionally bail out if there are any conflicts
inside a node being committed. No more testing the 'keep_local' flag at
this stage.

* Either the regression test should call "svn resolved" before
attempting the commit, or the "svn delete" that it performs should clear
the conflicts from inside the directory that it deleted.

* None of this behaviour should depend on whether the user wants an
unversioned copy of the node to be kept on disk.

Neels, in the IRC log below it looks like you had a patch for making
"svn delete" clear tree conflicts when "--force" or "--keep-local" is
given. I don't see why we'd want "--keep-local" to behave specially,
but with "--force", sure, that should clear conflicts. Do you still
have the patch? (The paste linked from IRC has expired.)


- Julian

On Wed, 2010-05-12, Greg Stein wrote:
> Temp function. It can be used in entries.c, too.
> It'll only last until single-db.
> Not blasting conflict info is good, in case of reverts.
> On May 12, 2010 2:17 PM, "Philip Martin" <philip.martin_at_wandisco.com> wrote:
> The only thing keeping me from finally removing svn_wc_entry_t from
> harvest_committables is keep_local. There was some discussion on IRC
> a few days ago
> http://colabti.org/irclogger/irclogger_log/svn-dev?date=2010-05-06#l44
> but it really resolve things. It includes pointers to Neels patch to
> make keep-local remove tree conflicts.
> Tree conflicts generally prevent a commit, however if the conflict is
> inside a directory that has been deleted with "svn rm --keep-local"
> then the commit will be allowed. So
> rm -rf repo wc
> svnadmin create repo
> svn mkdir -mm file://`pwd`/repo/A
> svn mkdir -mm file://`pwd`/repo/A/B
> svn co -r1 file://`pwd`/repo wc
> svn cp file://`pwd`/repo/A wc/A/B
> svn up wc # creates tree conflict for A/B
> svn ci -mm wc # fails because of tree conflict
> svn rm wc/foo # fails because of tree conflict
> svn rm --keep-local wc/A # succeeds
> svn ci -mm wc # succeeds
> When A is rm'd the tree conflict is sort of still present, it shows up
> in status, but it's all a bit dodgy. After the commit the unversioned
> directory A/B still contains a .svn directory. If I revert, rather
> than commit, then wc/A/B becomes unversioned.
> In wc-metadata.sql there is a comment about working_node.keep_local
> being temporary.
> My immediate problem is how to replace entry->keep_local in
> harvest_committables. Two options are:
> 1. XFAIL tree_conflicts 17.
> 2. Add svn_wc__db_temp_get_keep_local.
> 3. Use Neels' patch to make rm --keep-local/--force remove tree conflicts.
> Any other ideas?
> --
> Philip
Received on 2010-08-24 16:10:13 CEST

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