You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Julian Foad <ju...@btopenworld.com> on 2008/07/14 12:22:54 UTC

[RFC] Property conflicts should save old/theirs/mine versions

Howdy folks.

I was talking to Mike a couple of weeks ago.

When we get a property conflict, we store a message in "<filename>.prej"
that says:

> Trying to change property 'p' from 'v1' to 'v2',
> but property has been locally changed from 'v1' to 'wcval'.

That's OK for a short plain-text value, but is not human-readable for a
very long value or a "binary" value, and not machine-parseable if the
value contains a single-quote character.

Mike and I agree it's totally obvious - "d'uh" - that we should store
the "old" and "theirs" and "mine" values in a more rigorous,
programmatically-accessible form, as we do for the file text in a file
text conflict. This would enable tools built on top of Subversion to
offer proper property conflict resolution.

I see two solutions (Mike, I only thought of (1) until after talking to
you last week, and then I realised you were probably thinking of (2)):

(1) Save the item's "old", "theirs" and "mine" properties in the admin
area if there is any property conflict on the item.

  * Save each of these three sets of properties as a property hash file,
just like the "base" properties file.

  * Provide APIs (and possibly a UI in "svn") to read these properties
in a way that is very similar to reading the base properties.

(2) For each property that conflicts, create "old", "theirs" and "mine"
files holding the bare value of that property in the user's WC
directory. (This is where we write the files for text conflicts.)

  * Provide a way to access the names of these files. (They can't be
quite as simple as "<filename>.old" as there can be multiple properties
conflicting on one item.)


With (1), we store all the properties if any of them conflict. If a
property that conflicts is closely related to another property that
doesn't, say "svnmerge-integrated" and "svn:mergeinfo", then both
properties' values will be available to help the user in the resolution.

Solution (1) requires a libsvn_wc API to retrieve the old/theirs/mine
properties, and a UI extension if we want "svn" users to benefit.
Solution (2) requires exposing the file names through svn_wc_entry_t,
and optionally exposing them to the user through "svn info", or perhaps
through text in the existing "<filename>.prej".

I have implemented the basics of (1): that is, storing the properties,
an API to retrieve them, and a suggestion for a UI. The "retrieve" API
looks something like this:

> Index: subversion/include/svn_wc.h
> ===================================================================
>  svn_error_t *
>  svn_wc_prop_list(apr_hash_t **props,
>                   const char *path,
>                   svn_wc_adm_access_t *adm_access,
>                   apr_pool_t *pool);
> 
> +/* A type to specify which of the versions held in the WC. Types 'pristine'
> + * and 'working' are always meaningful (though they may be in the
> + * "nonexistent" state), whereas types 'conflict_*' are only valid when the WC
> + * item is in a state of conflict. */
> +typedef enum svn_wc_rev_kind_t
> +{
> +  svn_wc_rev_kind_pristine,      /* the 'pristine' or 'base' version */
> +  svn_wc_rev_kind_working,       /* the version that can be locally edited */
> +  svn_wc_rev_kind_conflict_old,  /* the incoming change's 'old' or 'left' side */
> +  svn_wc_rev_kind_conflict_new,  /* the incoming change's 'new' or 'right' side */
> +  svn_wc_rev_kind_conflict_mine  /* what was 'working' before the conflict */
> +} svn_wc_rev_kind_t;
> +
> +/** Set @a *props to a hash table mapping <tt>char *</tt> names onto
> + * <tt>svn_string_t *</tt> values for all the regular properties of
> + * @a path.  Allocate the table, names, and values in @a pool.  If
> + * the node has no properties, or does not exist in the working copy,
> + * then an empty hash is returned.  @a adm_access is an access baton
> + * set that contains @a path.
> + * @a rev_kind specified whether to access the pristine or working or
> + * one of the conflict artifact versions of this WC item.
> + */
> +svn_error_t *
> +svn_wc_prop_list2(apr_hash_t **props,
> +                  const char *path,
> +                  svn_wc_rev_kind_t rev_kind,
> +                  svn_wc_adm_access_t *adm_access,
> +                  apr_pool_t *pool);
> +

I can then see a command-line UI something like

  svn propget --conflict-artifact=old|theirs|mine TARGET

The sort of ultimate solution I would like to see at some point in the future would be one where all svn commands could access these pseudo-versions just as easily as they can access BASE or WORKING:

  svn propget -r mine TARGET

... and have the file content conflict versions handled the same way, so:

  svn cat -r theirs TARGET
  svn diff -r old:theirs TARGET
  svn merge -r123:theirs TARGET wc

Maybe pie-in-the-sky unrealistic for this season, but I think a move towards it are good. This kind of capability is what we will the user will eventually need to properly resolve large and complex tree conflicts. It is also something that I expect WC-ng will make much easier to implement.

Comments?

- Julian



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by "C. Michael Pilato" <cm...@collab.net>.
Karl Fogel wrote:
> Stefan Sperling <st...@elego.de> writes:
>> So Julian's approach to storing property conflicts data in the auth
>> is consistent with what we have already done on the tree conflicts
>> branch.
>>
>> While maintaining consistency between the way text conflicts and
>> other types of conflicts are handled is certainly desirable, I don't
>> think it's viable. The way we currently deal with text conflicts is fine.
>> But it is also much simpler than how we want to deal with tree and property
>> conflicts. And the way our current trunk code is dealing with either
>> of those is, well, suboptimal.
> 
> *nod*  Okay, that all sounds reasonable to me.  (Assuming you mean
> "admin area" where you write "auth area").

Man, I hope so.  If "auth area" was really what was intended, I'll have to 
hit the local sporting goods shop to purchase enough red flags to wave.

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand


Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Stefan Sperling <st...@elego.de>.
On Thu, Jul 24, 2008 at 12:33:31PM -0400, Karl Fogel wrote:
> Stefan Sperling <st...@elego.de> writes:
> > So Julian's approach to storing property conflicts data in the auth
> > is consistent with what we have already done on the tree conflicts
> > branch.
> >
> > While maintaining consistency between the way text conflicts and
> > other types of conflicts are handled is certainly desirable, I don't
> > think it's viable. The way we currently deal with text conflicts is fine.
> > But it is also much simpler than how we want to deal with tree and property
> > conflicts. And the way our current trunk code is dealing with either
> > of those is, well, suboptimal.
> 
> *nod*  Okay, that all sounds reasonable to me.  (Assuming you mean
> "admin area" where you write "auth area").

Your assumption is correct, I mixed that up, sorry.

Don't worry, no one wants to store conflict meta data in the
authentication cache :)

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Karl Fogel <kf...@red-bean.com>.
Stefan Sperling <st...@elego.de> writes:
> So Julian's approach to storing property conflicts data in the auth
> is consistent with what we have already done on the tree conflicts
> branch.
>
> While maintaining consistency between the way text conflicts and
> other types of conflicts are handled is certainly desirable, I don't
> think it's viable. The way we currently deal with text conflicts is fine.
> But it is also much simpler than how we want to deal with tree and property
> conflicts. And the way our current trunk code is dealing with either
> of those is, well, suboptimal.

*nod*  Okay, that all sounds reasonable to me.  (Assuming you mean
"admin area" where you write "auth area").

-Karl

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Stefan Sperling <st...@elego.de>.
On Tue, Jul 22, 2008 at 06:37:38PM +0100, Julian Foad wrote:
> On Tue, 2008-07-22 at 17:56 +0100, Julian Foad wrote:
> > On Tue, 2008-07-22 at 14:52 +0100, Julian Foad wrote:
> > > Now, that's still quite a bit of work and may well be too much to bite
> > > off now (though large chunks of it are temptingly easy). But I think we
> > > need to be considering moves like this, and to something in this
> > > direction sooner or later.
> > 
> > For anyone interested, the attached patch contains my work in progress
> > on this.
> 
> Of course, I know how unfriendly is a patch without a log message.

Julian,

I read through the whole thread and I totally agree with the
general idea. Being smarter about property conflicts is a
very good thing.

I haven't looked at the patch in detail. But looking at the size
of it, I think you're already close to having enough code to justify
a new branch. If you decided to keep the scope of the branch limited
to the first steps needed towards your long-term goal, and named the
branch accordingly, it might even help preventing the diff from growing
too many new features prematurely. Given the size of what you're aiming
for, I guess anything that helps drawing a line somewhere is probably
a good thing :)


Karl,

even though I totally agree that the API is more important than
where the data ends up being stored, I have a comment on this:

On the tree conflicts branch, we already store conflict data in
the auth area. Here's why:

There may be multiple tree conflicts in a directory, just as there
may be multiple property conflicts on a file or directory.

We want to be able to block commits from tree-conflicted directories
if any of their multiple tree conflicts were not resolved yet.
This is important because the entire point of tree conflict handling
is preventing users from shooting themselves in the foot during
complex merges. Commits that could cause damage without the user
being aware of the potential damage need to be blocked.

Also, we want to be as supportive as we can, and enabling users to
deal with the conflicts one after another is one part of this goal.
With each tree conflict, we associate a ``victim'', i.e. a file or
directory which may be lost or damaged if the conflict is not resolved.
We can then explain each tree conflict (e.g. "The update tried to delete
file foo.c, which you edited") to the user separately.

Users should then be able to tell us "OK, I've resolved the tree
conflict which affects foo.c". We then clear the meta data
corresponding to that tree conflict.

(Note that this is currently not implemented as described.
In the current implementation, running "svn resolved" on a
tree-conflicted directory will clear all tree conflict information.
But the long-term goal is the above behaviour. See issue #3145.)

We first toyed with the idea of storing tree conflict information
in a user-visible file. The file would explain to the user what kinds
of tree conflicts had happened in its containing directory.
There are two possible ways to block commits in such a setup:

1) Don't care about the file's content. Check if the file is still
   present. If it is, disallow commits. If it is not, allow commits.
   This means that we do not have more fine-grained information other
   than "this directory contains one or more tree conflicts".

   Note that this approach is used for text conflicts, by checking
   the presence of .mine, .rX, and .rY and such files.
   It works there because a binary logic is fine in this case:
   The entire file is either text-conflicted or not. We don't
   care about further details, so we don't need more information.

2) Make the file somewhat machine parsable while keeping it
   human-readable, and get per-conflict data from the file.

We (Steve and myself) were inclined to go with 2), but then realised
that any change made by the user to that data could cause us to lose
information about what kind of tree conflicts we had detected during
updates/merges. So we could be tricked into forgetting about some tree
conflicts when the user deleted wrong parts of that file, for example.
We did not like this. Such sensitive data should be in the auth area.
Then it's pretty clear that if users are messing with the data directly,
it's their fault.

So we decided to hide plain tree conflict meta data from users, and put
it in the auth area, and provided an API that translates the meta data
into a human readable form. This is already implemented.
This way, we have the best of both worlds: We control the meta data,
and users are still presented with human-reable information about
tree conflicts.

So Julian's approach to storing property conflicts data in the auth
is consistent with what we have already done on the tree conflicts
branch.

While maintaining consistency between the way text conflicts and
other types of conflicts are handled is certainly desirable, I don't
think it's viable. The way we currently deal with text conflicts is fine.
But it is also much simpler than how we want to deal with tree and property
conflicts. And the way our current trunk code is dealing with either
of those is, well, suboptimal.

Stefan

RE: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Bert Huijben <be...@qqmail.nl>.
> -----Original Message-----
> From: Julian Foad [mailto:julianfoad@btopenworld.com]
> Sent: woensdag 6 augustus 2008 15:28
> To: dev@subversion.tigris.org
> Cc: Karl Fogel
> Subject: Re: [RFC] Property conflicts should save old/theirs/mine
> versions
> 
> Would anybody be able to review the concepts and APIs in this? The
> feedback would be really helpful. I'm really just looking for people's
> feeling about whether this is going in the right direction - like
> contributing to the goals of wc-ng - or going the wrong way.

	Hi Julia,

I really like the idea of using a specific revision to specify these special
(local) files.


For a gui implementation (in AnkhSVN) I would like to have a way to retrieve
which of the properties are conflicted to really make this feature useful to
our users. 

The only method to detect property conflicts per property in 1.5 (without
walking all properties myself) is via the interactive conflict handler :(
I would like a method to provide a non-modal list of properties to resolve
later on. (Perhaps allowing per property resolving, etc.)

	Bert

> 
> Thanks,
> - Julian


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
Would anybody be able to review the concepts and APIs in this? The
feedback would be really helpful. I'm really just looking for people's
feeling about whether this is going in the right direction - like
contributing to the goals of wc-ng - or going the wrong way.

Thanks,
- Julian


On Mon, 2008-07-28 at 12:29 +0100, Julian Foad wrote:
> On Tue, 2008-07-22 at 18:37 +0100, Julian Foad wrote:
> > On Tue, 2008-07-22 at 17:56 +0100, Julian Foad wrote:
> > > For anyone interested, the attached patch contains my work in progress
> > > on this.
> > 
> > Of course, I know how unfriendly is a patch without a log message.
> 
> For anyone interested, here's a revised patch, this time including a log
> message.
> 
> - Julian



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

RE: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
On Sat, 2008-09-06 at 16:56 +0200, Bert Huijben wrote:
> 	Hi Julian,
> 
> This week on irc we talked about hiding properties and missing support for
> showing what properties had changed on a file. I remembered something on
> this thread from July.
> 
> Just pinging this thread again, to find out its current status.

Hi Bert. There's been no status change in this thread! I'd like to get
back to it, and will do at some point, but have other things to do as
well.

- Julian

> In the AnkhSVN gui, I could really use support like this in combination with
> a function to retrieve which of the properties are changed and which are in
> conflict.
> 
> 	Bert
> 
> > -----Original Message-----
> > From: Julian Foad [mailto:julianfoad@btopenworld.com]
> > Sent: maandag 28 juli 2008 13:29
> > To: dev@subversion.tigris.org
> > Cc: Karl Fogel
> > Subject: Re: [RFC] Property conflicts should save old/theirs/mine
> > versions
> > 
> > On Tue, 2008-07-22 at 18:37 +0100, Julian Foad wrote:
> > > On Tue, 2008-07-22 at 17:56 +0100, Julian Foad wrote:
> > > > For anyone interested, the attached patch contains my work in
> > progress
> > > > on this.
> > >
> > > Of course, I know how unfriendly is a patch without a log message.
> > 
> > For anyone interested, here's a revised patch, this time including a
> > log
> > message.
> 
> 	
> 
> > 
> > - Julian
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

RE: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Bert Huijben <be...@vmoo.com>.
	Hi Julian,

This week on irc we talked about hiding properties and missing support for
showing what properties had changed on a file. I remembered something on
this thread from July.

Just pinging this thread again, to find out its current status.

In the AnkhSVN gui, I could really use support like this in combination with
a function to retrieve which of the properties are changed and which are in
conflict.

	Bert

> -----Original Message-----
> From: Julian Foad [mailto:julianfoad@btopenworld.com]
> Sent: maandag 28 juli 2008 13:29
> To: dev@subversion.tigris.org
> Cc: Karl Fogel
> Subject: Re: [RFC] Property conflicts should save old/theirs/mine
> versions
> 
> On Tue, 2008-07-22 at 18:37 +0100, Julian Foad wrote:
> > On Tue, 2008-07-22 at 17:56 +0100, Julian Foad wrote:
> > > For anyone interested, the attached patch contains my work in
> progress
> > > on this.
> >
> > Of course, I know how unfriendly is a patch without a log message.
> 
> For anyone interested, here's a revised patch, this time including a
> log
> message.

	

> 
> - Julian



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
On Tue, 2008-07-22 at 18:37 +0100, Julian Foad wrote:
> On Tue, 2008-07-22 at 17:56 +0100, Julian Foad wrote:
> > For anyone interested, the attached patch contains my work in progress
> > on this.
> 
> Of course, I know how unfriendly is a patch without a log message.

For anyone interested, here's a revised patch, this time including a log
message.

- Julian


Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
On Tue, 2008-07-22 at 17:56 +0100, Julian Foad wrote:
> On Tue, 2008-07-22 at 14:52 +0100, Julian Foad wrote:
> > Now, that's still quite a bit of work and may well be too much to bite
> > off now (though large chunks of it are temptingly easy). But I think we
> > need to be considering moves like this, and to something in this
> > direction sooner or later.
> 
> For anyone interested, the attached patch contains my work in progress
> on this.

Of course, I know how unfriendly is a patch without a log message.
That's one thing I owe you, and the other is a description of the
concept of the WC's "mine" and "old" and "new" versions in terms of what
their behaviour should be expected to look like in comparison to the
"working" and "base" versions.

I'll write something about that, but at the same time I think I should
step back from pursuing this line for the moment and more importantly
look at what of the earlier phases of tree conflict detection can be
brought out into the daylight of "trunk".

- Julian



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
On Tue, 2008-07-22 at 14:52 +0100, Julian Foad wrote:
> Now, that's still quite a bit of work and may well be too much to bite
> off now (though large chunks of it are temptingly easy). But I think we
> need to be considering moves like this, and to something in this
> direction sooner or later.

For anyone interested, the attached patch contains my work in progress
on this.

- Julian
 

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
On Mon, 2008-07-21 at 15:27 -0400, Karl Fogel wrote:
> Agreed.  But, couple of thoughts:
> 
>    - No need for "_rev", just call it "svn_wc_kind_t" :-)

Heh. Or whatever.

>    - To convert all the existing code to use this sounds like a truly
>      stunning amount of work.  Am I overestimating?  Is this getting
>      close to the amount of work required for libsvn_wc_ng?

It's certainly doing something that libsvn_wc_ng wants to do: making the
WC APIs access the various trees that it knows about (working, base,
etc.) more consistently.

I think it's much less effort than the whole wc-ng, though. Only a few
of Subversion's features actually read data (text and props) from an
arbitrary revision that can include "base" and "working". Estimation of
the work needed to "upgrade" these features, listed per svn subcommand:

Significant effort:

  * diff - must communicate this through the diff editor, and there are
different implementations.

  * merge (as source) - if we want this to work, which could be
important for resolving tree conflicts, we would first need to teach it
to read from a local-mod source. After that, would be similar to (one
mode of) diff.

  * copy (as source) - compared to simpler operations below, there is
the complication of storing and retrieving enough metadata to "install"
the copy into the WC.

Pretty simple:

  * cat
  * propget
  * proplist
  * info
  * list
  * mergeinfo
  * export - less important

These could conceivably be upgraded to read from a local-mod source but
don't currently support it so are not in scope:

  * blame

The other "svn" subcommands are not affected.


Now, that's still quite a bit of work and may well be too much to bite
off now (though large chunks of it are temptingly easy). But I think we
need to be considering moves like this, and to something in this
direction sooner or later.

- Julian



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Karl Fogel <kf...@red-bean.com>.
Julian Foad <ju...@btopenworld.com> writes:
> I think this achieves:
>
>   * An improvement in WC API self-consistency, and thereby a
> simplification of calling code in users such as svn_client_cat() and
> svn_client_propget().
>
>   * A way to access text conflict artifact files that is consistent with
> how we access text base files.
>
>   * A way to access property conflict artifacts which we will want to
> store soon, however we choose to store them, that is consistent with how
> we access base and working properties.
>
>   * An identification mechanism that we can also apply to tree conflict
> artifacts. Although difficult-to-resolve tree conflicts may occur less
> often than "normal" conflicts, when it does occur the need to access
> these things through a consistent programmatic interface may be greater
> than the need currently is for text and prop conflicts.

Agreed.  But, couple of thoughts:

   - No need for "_rev", just call it "svn_wc_kind_t" :-)

   - To convert all the existing code to use this sounds like a truly
     stunning amount of work.  Am I overestimating?  Is this getting
     close to the amount of work required for libsvn_wc_ng?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
On Tue, 2008-07-15 at 13:21 -0400, Karl Fogel wrote: 
> You know, I kind of think the way to go about this is to propose the API
> *first*, and then worry about where we're going to store the property
> conflicts afterwards.  The API is the key thing here.

OK...

Libsvn_wc presently stores two "versions" or "revision kinds" of a given
node locally:

  * pristine base version (read-only)

  * working version (read-write)

and provides APIs for accessing these versions of a file's text ...

  case svn_opt_revision_base:
    SVN_ERR(svn_wc_get_pristine_copy_path(wc_path, &base_path, pool));
  case svn_opt_revision_working:
    working_path = wc_path;  /* no API as such: we know the path */

... and its properties:

  case svn_opt_revision_base:
    SVN_ERR(svn_wc_get_prop_diffs(NULL, &base_props, wc_path, adm...);
  case svn_opt_revision_working:
    SVN_ERR(svn_wc_prop_list(&working_props, path, adm_access, pool));

(ugh, look: that's two different APIs).


Let libsvn_wc store three additional versions of a given node when a
conflict (any kind of conflict) occurs:

  * "old" or "merge-left" version (read-only)

  * "new" or "merge-right" or "their" version (read-only)

  * previous-working or "my" version (read-only)


Let libsvn_wc provide a uniform API for operations that can be common
across all five versions:

> /* A type to select one of the versions that the WC holds of a node.  Types
>  * 'pristine' and 'working' are meaningful unless the node is schedule-add
>  * or schedule-delete respectively. The three 'conflict_*' types are
>  * meaningful only while the node is in a state of conflict. */
> typedef enum svn_wc_rev_kind_t
> {
>   svn_wc_rev_kind_pristine,      /* the 'pristine' or 'base' version */
>   svn_wc_rev_kind_working,       /* the version that can be locally edited */
>   svn_wc_rev_kind_conflict_old,  /* the incoming change's 'old' or 'left' side */
>   svn_wc_rev_kind_conflict_new,  /* the incoming change's 'new' or 'right' side */
>   svn_wc_rev_kind_conflict_mine  /* what was 'working' before the conflict */
> } svn_wc_rev_kind_t;
> 
>  /** Set @a *props to a hash table mapping <tt>char *</tt> names onto
>   * <tt>svn_string_t *</tt> values for all the regular properties of
>  * @a path.  Allocate the table, names, and values in @a pool.
>  * If the node has no properties, return an empty hash.
>  * If the node does not exist in the working copy, return an error.
>  * @a adm_access is an access baton set that contains @a path.
>  * @a rev_kind specifies which version of the node to access: the pristine base,
>  * the working version, or one of the conflict artifacts.
>  */
> svn_error_t *
> svn_wc_prop_list2(apr_hash_t **props,
>                   const char *path,
>                   svn_wc_rev_kind_t rev_kind,
>                   svn_wc_adm_access_t *adm_access,
>                   apr_pool_t *pool);
> 
> /** Like svn_wc_prop_list2() except that only the working properties can be
>  * obtained, and if the node does not exist in the working copy then an
>  * empty hash is returned.
>  *
>  * @deprecated ...
>  */
> svn_error_t *
> svn_wc_prop_list(apr_hash_t **props,
>                  const char *path,
>                  svn_wc_adm_access_t *adm_access,
>                  apr_pool_t *pool);

... and likewise for propget, and similarly for the various diff
functions ...

> /* Get an editor to describe the differences between the WC-local
>  * version @a rev_kind and a repository version of the target. ...
>  */
> svn_error_t *
> svn_wc_get_diff_editor5(svn_wc_adm_access_t *anchor,
>                         const char *target,
>                         [...]
>                         svn_wc_rev_kind_t rev_kind,
>                         [...]);
> 
> /* @deprecated ... */
> svn_error_t *
> svn_wc_get_diff_editor4(svn_wc_adm_access_t *anchor,
>                         const char *target,
>                         [...]
>                         svn_boolean_t use_text_base,
>                         [...]);

... and similarly for svn_wc_diff5() to diff between two arbitrary
WC-local versions, where the present version only does base to working.

I'm pretty confident of the part of this approach that is saying:
"libsvn_wc, for this node, give me access to a version that you I know
you're holding that's identified by this parameter REV_KIND."

I'm less certain that the type of the parameter REV_KIND should be an
enum of these particular values.

The "theirs" and "old" versions are normally (always, in present svn
client) going to be repository versions, so we could instead use
repository version numbers (which we can get by querying the conflict
ibnfo) to request access to these versions, either via the WC API or via
the repository access API. But the special-identifier way is consistent
with how we request "base": we don't look up the corresponding
repository rev number and then pass that to the (WC or RA) APIs.

The "mine" version is like "working" in that it often doesn't have a
repository equivalent, as it may contain local mods, so it has to have a
special identifier. (The identifier could possibly be something that is
dynamically generated by libsvn_wc rather than a fixed constant, looking
forward to a time when it may be able to store more than one
work-in-progress per node, but that seems premature.)


I think this achieves:

  * An improvement in WC API self-consistency, and thereby a
simplification of calling code in users such as svn_client_cat() and
svn_client_propget().

  * A way to access text conflict artifact files that is consistent with
how we access text base files.

  * A way to access property conflict artifacts which we will want to
store soon, however we choose to store them, that is consistent with how
we access base and working properties.

  * An identification mechanism that we can also apply to tree conflict
artifacts. Although difficult-to-resolve tree conflicts may occur less
often than "normal" conflicts, when it does occur the need to access
these things through a consistent programmatic interface may be greater
than the need currently is for text and prop conflicts.


I'd like to know what folks think is right and wrong with this :-)

- Julian



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Karl Fogel <kf...@red-bean.com>.
Julian Foad <ju...@btopenworld.com> writes:
> Did you appreciate it's not just "store here" versus "store there", but
> "store all props in a hash file hidden behind an API" versus "store each
> prop's raw value in a separate visible file and we'll tell you the three
> filenames for each prop of each WC item"?

Yes, or at least I thought I appreciated that.  I assume there would
still be an API for getting them, no?

>> > (2) For each property that conflicts, create "old", "theirs" and "mine"
>> > files holding the bare value of that property in the user's WC
>> > directory. (This is where we write the files for text conflicts.)
>> 
>> ...ah, I see you were ahead of me :-).  Yes, (2), and then there can
>> still be a human-readable .prej file to serve as a readme, explaining
>> what the other files are.
>
> Do you have time to mention why you think (2) is the better option? Is
> it because it's less work to get something that users can see?

I preferred (2) because of its simplicity: the files are out there in
the open, so users can deal with them manually or the user's client can
deal with them via our APIs.  And its consistent with what we do with
text conflicts.

> Let me share my goal.
>
> (I'll go and write this up more coherently than I've managed to
> articulate it below.)
>
> TREE CONFLICTS
>
> I've been looking at tree conflicts and how to manage them. We need to
> be able to say to libsvn_wc things like, "Save this copy of this file or
> directory tree somewhere, and give me a reference to it (which I'll call
> 'mine') by which I can access it later." And then the "resolve
> --accept=mine" command needs to say, "Copy the target 'mine' version
> onto its working version." Not, "Copy this property and that property"
> but "copy the whole target including its properties."
>
> The only interest I have in storing properties' old/theirs/mine versions
> is in so far as it helps up build our infrasturcture towards full
> support for tree conflicts.

Aaaaah, okay.

> TEXT CONFLICTS versus PROP CONFLICTS
>
> For text conflicts, we store copies of the file in the user's directory
> and report the file name as a reference. This allows the user to use
> their text editor or other file-based tools, just like they would with
> their working version, but does not allow them to use "svn diff" and the
> like so it's not great.

But note that this limitation is not inherent in storing the files in
the working area.  If we were to decide on an 'svn diff' interface to
accessing those files, then they could be accessed in the working area
as easily as in the .svn/ area.

> For property conflicts, I am looking to do something as good or better.
> Saving each separate property value in a file is, I contend, a step in
> the wrong direction.
>
>   * Users are not accustomed to interacting with their properties as
> files but rather through the "svn propXXX" commands. We will be exposing
> a way of interacting with property conflicts that I think we will not
> want to support for long.
>
>   * The filenames need to be generated: maybe like
> "TARGET.UNIQUEID.mine" or maybe like "TARGET.FUZZYPROPNAME.mine" where
> FUZZYPROPNAME is some fuzzy encoding purged of special characters like
> ":" and restricted in length and uniquified. These filenames will be
> found indirectly through "svn info".

Mmm.  That is a problem, yes (and a problem that we don't have with the
working files, by definition).

> "THE ITEM IS IN CONFLICT" versus "THE ITEM HAS SEVERAL CONFLICTS"
>
> It makes sense to resolve all of a file's properties together, and
> together with its text. For example, if the properties do not conflict
> and the text does, and the user chooses to keep "their" version of the
> text, he almost certainly wants to keep "their" version of the
> properties too, not the merged version. (It's also useful to be able to
> look at one property in isolation too, of course.)
>
> In other words, though we presently treat them separately, there is
> logically one conflict on the file, and this conflict involves the text
> and/or one or more properties, and the conflict has one "old" revision
> number (not one for each property and another one for the text), and one
> "their" revision number, and one "mine" version.

Agreed.

> In fact, that is how the "svn resolved" command works - it resolves the
> conflict(s) on the whole file or directory - and that is also what the
> "svn resolve --accept=X" command looks like it should do but in fact it
> quietly ignores properties. (I think "svn resolved --accept=theirs|mine"
> is buggy, accepting the "merged" or "working" version of the properties
> rather than the requested version.)

Also agreed (about how 'svn resolved --accept=X' should behave).

> LONG-TERM GOAL
>
> I want to be able to type "svn diff -r old:mine" to see the entire
> differences in text and props, not "here are the names of some temporary
> files: you have a look at them with your operating system's commands and
> see what you can do with them".

Sure.  You can have that no matter where prop conflicts are stored.

> [[[
>   $ svn status f
>    C     f            # file 'f' has property conflict(s)
>
>   $ svn diff -r old:theirs foo.c
>   
>   Property changes on: f
>   ___________________________________________________________________
>   Modified: p
>      - v1
>      + their-value
> ]]]
>
> STEPS
>
> Now, getting Subversion to that point is a big task, and something we
> can only tackle step by step.
>
> To take a step now, I'd want to store the entire "theirs" set of
> properties in a single "property hash" file, like we do for the "base"
> set of properties and the "working" set (well, we use a sort of diff for
> that, but that's an implementation detail), and such a file is not
> human-readable. It needs an API (and a UI) to access it. Therefore we
> wouldn't put it in the user's directory.
>
> Of course, it only becomes a value-added step to take when we provide
> the API and the UI to access this data, hence this request for comments.

You know, I kind of think the way to go about this is to propose the API
*first*, and then worry about where we're going to store the property
conflicts afterwards.  The API is the key thing here.

-Karl

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Julian Foad <ju...@btopenworld.com>.
On Mon, 2008-07-14 at 19:14 -0400, Karl Fogel wrote: 
> Julian Foad <ju...@btopenworld.com> writes:
> > When we get a property conflict, we store a message in "<filename>.prej"
> > that says:
> >
> >> Trying to change property 'p' from 'v1' to 'v2',
> >> but property has been locally changed from 'v1' to 'wcval'.
> >
> > That's OK for a short plain-text value, but is not human-readable for a
> > very long value or a "binary" value, and not machine-parseable if the
> > value contains a single-quote character.
> >
> > Mike and I agree it's totally obvious - "d'uh" - that we should store
> > the "old" and "theirs" and "mine" values in a more rigorous,
> > programmatically-accessible form, as we do for the file text in a file
> > text conflict. This would enable tools built on top of Subversion to
> > offer proper property conflict resolution.
> >
> > I see two solutions (Mike, I only thought of (1) until after talking to
> > you last week, and then I realised you were probably thinking of (2)):
> >
> > (1) Save the item's "old", "theirs" and "mine" properties in the admin
> > area if there is any property conflict on the item.
> 
> Why in the admin area?  Why not in the working area?

Did you appreciate it's not just "store here" versus "store there", but
"store all props in a hash file hidden behind an API" versus "store each
prop's raw value in a separate visible file and we'll tell you the three
filenames for each prop of each WC item"?

> > (2) For each property that conflicts, create "old", "theirs" and "mine"
> > files holding the bare value of that property in the user's WC
> > directory. (This is where we write the files for text conflicts.)
> 
> ...ah, I see you were ahead of me :-).  Yes, (2), and then there can
> still be a human-readable .prej file to serve as a readme, explaining
> what the other files are.

Do you have time to mention why you think (2) is the better option? Is
it because it's less work to get something that users can see?

Let me share my goal.

(I'll go and write this up more coherently than I've managed to
articulate it below.)


TREE CONFLICTS

I've been looking at tree conflicts and how to manage them. We need to
be able to say to libsvn_wc things like, "Save this copy of this file or
directory tree somewhere, and give me a reference to it (which I'll call
'mine') by which I can access it later." And then the "resolve
--accept=mine" command needs to say, "Copy the target 'mine' version
onto its working version." Not, "Copy this property and that property"
but "copy the whole target including its properties."

The only interest I have in storing properties' old/theirs/mine versions
is in so far as it helps up build our infrasturcture towards full
support for tree conflicts.

TEXT CONFLICTS versus PROP CONFLICTS

For text conflicts, we store copies of the file in the user's directory
and report the file name as a reference. This allows the user to use
their text editor or other file-based tools, just like they would with
their working version, but does not allow them to use "svn diff" and the
like so it's not great.

For property conflicts, I am looking to do something as good or better.
Saving each separate property value in a file is, I contend, a step in
the wrong direction.

  * Users are not accustomed to interacting with their properties as
files but rather through the "svn propXXX" commands. We will be exposing
a way of interacting with property conflicts that I think we will not
want to support for long.

  * The filenames need to be generated: maybe like
"TARGET.UNIQUEID.mine" or maybe like "TARGET.FUZZYPROPNAME.mine" where
FUZZYPROPNAME is some fuzzy encoding purged of special characters like
":" and restricted in length and uniquified. These filenames will be
found indirectly through "svn info".

"THE ITEM IS IN CONFLICT" versus "THE ITEM HAS SEVERAL CONFLICTS"

It makes sense to resolve all of a file's properties together, and
together with its text. For example, if the properties do not conflict
and the text does, and the user chooses to keep "their" version of the
text, he almost certainly wants to keep "their" version of the
properties too, not the merged version. (It's also useful to be able to
look at one property in isolation too, of course.)

In other words, though we presently treat them separately, there is
logically one conflict on the file, and this conflict involves the text
and/or one or more properties, and the conflict has one "old" revision
number (not one for each property and another one for the text), and one
"their" revision number, and one "mine" version.

In fact, that is how the "svn resolved" command works - it resolves the
conflict(s) on the whole file or directory - and that is also what the
"svn resolve --accept=X" command looks like it should do but in fact it
quietly ignores properties. (I think "svn resolved --accept=theirs|mine"
is buggy, accepting the "merged" or "working" version of the properties
rather than the requested version.)

LONG-TERM GOAL

I want to be able to type "svn diff -r old:mine" to see the entire
differences in text and props, not "here are the names of some temporary
files: you have a look at them with your operating system's commands and
see what you can do with them".

[[[
  $ svn status f
   C     f            # file 'f' has property conflict(s)

  $ svn diff -r old:theirs foo.c
  
  Property changes on: f
  ___________________________________________________________________
  Modified: p
     - v1
     + their-value
]]]


STEPS

Now, getting Subversion to that point is a big task, and something we
can only tackle step by step.

To take a step now, I'd want to store the entire "theirs" set of
properties in a single "property hash" file, like we do for the "base"
set of properties and the "working" set (well, we use a sort of diff for
that, but that's an implementation detail), and such a file is not
human-readable. It needs an API (and a UI) to access it. Therefore we
wouldn't put it in the user's directory.

Of course, it only becomes a value-added step to take when we provide
the API and the UI to access this data, hence this request for comments.

CONCLUSION

To me, saving individual properties' values in files in the working area
is the clumsy option. It doesn't make much progress towards the above
goals, I think.

This was a "quick fix" idea that came out of discussion about tree
conflicts. From this little excursion into evaluating ways of storing
property-conflict artifacts, it no longer looks like such a quick fix
and it's looking to me now like this might not be the best time to
tackle this. Getting other parts of tree conflicts sorted out is where I
need to spend my time.

Whadd'ya make of that?

- Julian



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: [RFC] Property conflicts should save old/theirs/mine versions

Posted by Karl Fogel <kf...@red-bean.com>.
Julian Foad <ju...@btopenworld.com> writes:
> When we get a property conflict, we store a message in "<filename>.prej"
> that says:
>
>> Trying to change property 'p' from 'v1' to 'v2',
>> but property has been locally changed from 'v1' to 'wcval'.
>
> That's OK for a short plain-text value, but is not human-readable for a
> very long value or a "binary" value, and not machine-parseable if the
> value contains a single-quote character.
>
> Mike and I agree it's totally obvious - "d'uh" - that we should store
> the "old" and "theirs" and "mine" values in a more rigorous,
> programmatically-accessible form, as we do for the file text in a file
> text conflict. This would enable tools built on top of Subversion to
> offer proper property conflict resolution.
>
> I see two solutions (Mike, I only thought of (1) until after talking to
> you last week, and then I realised you were probably thinking of (2)):
>
> (1) Save the item's "old", "theirs" and "mine" properties in the admin
> area if there is any property conflict on the item.

Why in the admin area?  Why not in the working area?

> (2) For each property that conflicts, create "old", "theirs" and "mine"
> files holding the bare value of that property in the user's WC
> directory. (This is where we write the files for text conflicts.)

...ah, I see you were ahead of me :-).  Yes, (2), and then there can
still be a human-readable .prej file to serve as a readme, explaining
what the other files are.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org