Johan Corveleyn wrote on Tue, Dec 13, 2011 at 22:04:33 +0100:
> On Tue, Dec 13, 2011 at 8:16 PM, Daniel Shahaf <d...@daniel.shahaf.name> 
> wrote:
> > C. Michael Pilato wrote on Tue, Dec 13, 2011 at 14:01:45 -0500:
> >> On 12/13/2011 01:25 PM, Eric S. Raymond wrote:
> >> > C. Michael Pilato <cmpil...@collab.net>:
> >> >>> Does a file replace differ in any way from a delete plus add of the 
> >> >>> new text?
> >> >>
> >> >> In Subversion, yes.  A replacement is, like an add or a delete, an 
> >> >> operation
> >> >> at the node level, not an operation on the contents of that node.  A 
> >> >> replace
> >> >> is an addition of a new object[1] -- with its own new line of version
> >> >> control history -- that is coincidental with the removal of some 
> >> >> previously
> >> >> existing object that occupied the same path.
> >> >
> >> > I still don't understand how this differs from a delete followed by an 
> >> > add.
> >> > Explain it to me like I'm reallllyyy stuuupid, please, so I can document 
> >> > it
> >> > and you never have to explain it again.
> >> >
> >> > When I add a file at a given path, it creates new object with a
> >> > history that is tracked.  When I delete that path, I destroy the
> >> > container as well as the content.  If I subsequently create a new
> >> > file at the same path, it's a new object with its own history.
> >> >
> >> > How is a replace different?
> >>
> >> Assume your "delete" and subsequent "add" happens in the same commit, it's
> >> not different at all.  In fact, the Subversion filesystem API doesn't even
> >> recognize a "replace" operation.  There's "delete (file or dir)", there's
> >> "make file" and "make dir", and there's "copy (file or dir)".  The 
> >> "replace"
> >> action found in the dumpfile is just a compacting of some delete operation
> >> and a subsequent add or copy into a single verb, and that only because it
> >> helps sequential processors of the dump stream avoid possibly notifying
> >> about multiple actions on the same path.  We favor the likes of:
> >>
> >>     R   /some/file.txt
> >>
> >> over:
> >>
> >>     D   /some/file.txt
> >>     A   /some/file.txt
> >>
> >> in output.
> >>
> >> (My prior response was the result of my misreading your phrase "delete plus
> >> add of the new text" as meaning "removing all the contents of the file, and
> >> then adding all new contents of the same file".  I see now that you were
> >> talking about "container" operations, not content ones.  Sorry about that.)
> >>
> >> >> [1] Most of the time.  A replacement can have a copyfrom source, in 
> >> >> which
> >> >> case its not strictly a new line of history for that object.
> >> >
> >> > I think I get this part.  When you replace with a copy source, you're
> >> > destroying the container that existed at this path, abd replacing it with
> >> > a new container that has history extending back through the copy source.
> >> > Is that correct?
> >>
> >> Yup!
> >>
> >> I was trying to think through the generalities here, too.  I believe they
> >> boil down to this:
> >>
> >>    "delete" stands alone.  It never has text.  Never has properties.
> >>    Never has copyfrom.
> >>
> >>    "add" and "replace" can have text if the added object is a file.  The
> >>    text is the contents of the added object as it appears in the committed
> >>    revision.  "add" and "replace" of directories can not have text.
> >>
> >>    "add and replace" can have properties -- the set of properties present
> >>    on the added file/directory in the committed revision.
> >>
> >>    "add and replace" can have copyfrom information, indicating that the
> >>    "added" object does not truly represent the creation of a new line of
> >>    history, but is instead a continuation of a pre-existing line of
> >>    history.  This is still an addition of sorts in that the object is newly
> >>    added to the set of its parent directory's list of children.
> >>
> >> But I haven't double-thunk that for complete accuracy.
> >>
> >> > So, everything except a delete can include properties and they all
> >> > work the same way. Correct?
> >>
> >> Yes.
> >>
> >> >>> If a file replace can have a copyfrom source, how does replace with a
> >> >>> copyfrom source differ from add with a copyfrom source?
> >> >>
> >> >> The differ only in the fact that a replace implies the simultaneous 
> >> >> deletion
> >> >> of some other object which previously lived at that path.
> >> >
> >> > Got it.  That case I understand, it's how they differ in the non-copyfrom
> >> > case that still confuses me.
> >>
> >> This is replace without copyfrom:
> >>
> >>    $ svn rm some/file.txt
> >>    $ touch some/file.txt
> >>    $ svn add some/file.txt
> >>    $ svn ci -m "Replace some/file.txt with a new file."
> >>
> >> This is replace with copyfrom:
> >>
> >>    $ svn rm some/file.txt
> >>    $ touch some/file.txt
> >>    $ svn copy someother/differentfile.txt some/file.txt
> >>    $ svn ci -m "Replace some/file.txt with a copy of a different file ."
> >
> > And:
> >
> >   $ svn rm some/file.txt
> >   $ touch some/file.txt
> >   $ svn copy some/file.txt@HEAD some/file.txt
> >   $ svn ci -m "Replace some/file.txt with a copy itself."
> 
> And even:
> 
>   $ svn mv some/file.txt some/otherfile.txt
>   $ svn mv some/otherfile.txt some/file.txt
>   $ svn ci -m "Replace some/file.txt with a copy of itself."
> 
> (pre-1.7 this would be a replace without copyfrom, breaking the line
> of history [1], but that is fixed as of 1.7)
> 

But the fix is client-side, right?  One can still do things like that by
driving an RA commit editor directly.

> [1] http://subversion.tigris.org/issues/show_bug.cgi?id=3429 - "svn mv
> A B; svn mv B A" generates replace without history
> 
> -- 
> Johan

Reply via email to