Re: Comments on "Understanding Version Control" by Eric S. Raymond

3 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: Comments on "Understanding Version Control" by Eric S. Raymond

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:46:06

Theodore Tso [off-list ref] writes:
Careful; that's actually an argument for recording the directory
rename.
I do not think so.  More precisely, I can see people could make that
argument, but I think that argument is weak.

Suppose the original project's implementor only knew about innodb
interface, so he had the "database interface" directory and innodb access
method file in the source tree, perhaps at <db/inno.c>.

I forked the project, and added gdbm support at <db/gdbm.c>.

You also forked the project without knowing what I was working on, and you
started working on refining the innodb support.

All the while, the development community started discussing how the source
tree should be organized to support multiple backends, and you learned
that the plan is to have one directory per larger backend, while keeping
single file ones in <db/*.c>.  Specifically, you learned that innodb
related code will be stored in <innodb/*.c>, and there may be other
<somedb/*.c> and <someotherdb/*.c> groups added, but you are not
interested in anything but enhancing innodb support.

You rename "scm mv db innodb" and then add <innodb/enhanced.c>, or perhaps
you may have done it the other way, i.e. added <db/enhanced.c> and then
renamed "scm mv db innodb".

Suppose you would want to merge my changes, but the upstream's plan hasn't
happened yet.  Neither of us merged from the upstream in the meantime.

Recording your "scm mv db innodb" as "the user's intention to rename
directory" does not help when you want to merge with me to handle the new
file <db/gdbm.c> I added.  You not only need to record the "intent to
rename db to innodb", but need to know that the validity of that "intent
to rename" is contingent on the absense of anything unrelated to innodb in
db/ directory, in order to merge the two branches correctly.  Otherwise
you will end up moving my <db/gdbm.c> to <innodb/gdbm.c>.  The correct
outcome in this case would probably be to leave it as it is.
In other cases, maybe the right thing *is* to drop the new file in the
original directory.  So as the Hg and Bzr apologists might say, if the
SCM actually records whether the user intention was a *directory*
rename, versus a series of *file* rename/moves, then it becomes
obvious what the right thing to do.
See how that argument is flawed?  The point of my example is that the line
between your example (1) and (2) in the previous message is blurry.

Re: Comments on "Understanding Version Control" by Eric S. Raymond

From: Theodore Tso <tytso@mit.edu>
Date: 2016-06-15 22:46:06

On Wed, Feb 04, 2009 at 10:24:57PM -0800, Junio C Hamano wrote:
All the while, the development community started discussing how the source
tree should be organized to support multiple backends, and you learned
that the plan is to have one directory per larger backend, while keeping
single file ones in <db/*.c>.  Specifically, you learned that innodb
related code will be stored in <innodb/*.c>, and there may be other
<somedb/*.c> and <someotherdb/*.c> groups added, but you are not
interested in anything but enhancing innodb support.

You rename "scm mv db innodb" and then add <innodb/enhanced.c>, or perhaps
you may have done it the other way, i.e. added <db/enhanced.c> and then
renamed "scm mv db innodb".
The argument would be that for SCM that properly tracked user
intentions, you did the wrong thing.  If the SCM properly understood
directory renames, there is a big differene between this:

	scm mvdir db innodb

and this

	scm mv db/* innodb

You see?  The first moves the *directory* db to innodb.  The second
moves all of the *files* that are in db to a new directory, innodb.
If, in your example, you had learned that the goal was to keep single
file ones in <db/*.c>, and larger backends in <innodb/*.c>, the
correct thing to tell the SCM is *not* to rename the directory db to
innodb, but rather, to move all of the files currently in <db/*.c>,
which implement innodb, into the innodb directory.  If an SCM properly
handles directory renames, it would distinguish between these two
cases and record them different, since it implies a different
intention about what should happen to new files created in <db/*.c> in
other branches when it comes time to merge them.

Of course, this distinction does not exist in git, because we track
content only.  And a number of other SCM's like Hg, which only track
file renames, wouldn't get this right either.  In order to get this
right, you need to treat directory renames as separate and distinct
operations from file renames, because they have different merge
implications.
See how that argument is flawed?  The point of my example is that the line
between your example (1) and (2) in the previous message is blurry.
It's blurry if you don't properly make the distinction between file
and directory renames, yes.  A SCM that only handles file renames
can't record the difference between "move all the files in directory
foo to bar" from "rename directory foo to bar".  Just as an SCM (like
git) that only handles content that tell the difference between "move
all of the lines of content from foo.c to bar.c" and "rename foo.c to
bar.c".

Our argument for git is that with sufficiently smart merge algorithms
it doesn't matter, since we can intuit the right thing at merge time.
However, your argument that it's not possible to determine whether the
new file should appear as db/gdbm.c or innodb/gdm.c is an argument
content-tracking alone isn't enough. 

Personally, I think the scenario I used of renaming plugins is more
likely that the sort of source reorganization which you've posited,
but I agree they are both possible scenarios.  The question for git
development is whether these sorts of issues ar ones that we should
try to handle or not?  After all, one possibility is just to tell
people that if they are folks who like to go wild with source tree
reorganizations all the time, they should go to some other SCM like
bzr or Hg; that in git's view, the costs of being able to handle
random file and directory renames isn't worth the benefits for what is
normally a rare occurrence (and if it's happening all the time, the
project is probably doing something else wrong....)

						- Ted

Re: Comments on "Understanding Version Control" by Eric S. Raymond

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:46:06

Theodore Tso [off-list ref] writes:
The argument would be that for SCM that properly tracked user
intentions, you did the wrong thing.  If the SCM properly understood
directory renames, there is a big differene between this:

	scm mvdir db innodb

and this

	scm mv db/* innodb

You see?  The first moves the *directory* db to innodb.  The second
Then please s/scm mv/scm mvdir/ before reading my example.  The
hypothetical "scm mv" command in my example just knew it was fed an
directory and interpreted it as an intention to move the directory, not
all its contents.
Of course, this distinction does not exist in git, because we track
content only.  And a number of other SCM's like Hg, which only track
file renames, wouldn't get this right either.  In order to get this
right, you need to treat directory renames as separate and distinct
operations from file renames, because they have different merge
implications.
...
quoted
See how that argument is flawed?  The point of my example is that the line
between your example (1) and (2) in the previous message is blurry.
It's blurry if you don't properly make the distinction between file
and directory renames, yes.
My point was even if you (in the example, who said "I want to move db
directory to innodb directory") had two different operations, it is not
enough, because you cannot capture that "I want to move db directory to
innodb directory" was contingent on "because I know everything in my db
directory should belong to innodb -- in fact in my history of db/, there
is nothing but innodb support".  The other person you will eventually be
merging with may not share that precondition, as the project started out
to hold anything databasey in db/ and between the two branches being
merged, only you changed the semantics of what each directory means.
However, your argument that it's not possible to determine whether the
new file should appear as db/gdbm.c or innodb/gdm.c is an argument
content-tracking alone isn't enough. 
Yes, but it is stronger than that. It is not just "content-tracking alone"
is not enough.  Even systems that have distinction between "scm mv" and
"scm mvdir" are not enough.  That is what I was trying to illustrate.

Your plug-in example differentiates two cases, one of which is that the
renaming branch would move the directory and the other is the branch moved
files under one directory to a new directory while keeping the original
directory, and two cases should produce different results.  If I
understand your argument correctly, it is that in the latter case the
outcome may be ambiguous, but in the former case, it is clear that the
intention of the remaning branch is to rename the directory itself and the
addition to the directory done in the other branch being merged should
automatically be done to the renamed directory while merging.  Most
importantly, the argument makes the assumption that the intention of the
non-renaming branch (iow, why he added the new files in the directory)
does not matter and does not affect the outcome.

The source tree restructuring example I brought in questions that
assumption.  It illustrates that the intention of the side that added the
new file matters.  Is it an innodb support enhancement?  Then it should
follow the renamer's intention to move rename db/ to innodb/.  Is it
adding something unrelated to the new meaning of "innodb" directory given
by the renaming side?  Then it is very likely that it should not go to the
renamed innodb/ directory, even though we may not be able to decide where
it *should* go automatically.  The point to consider is that recording the
renamer's intention to rename the directory and not just its contents is
not enough and does not help the merge.
Personally, I think the scenario I used of renaming plugins is more
likely that the sort of source reorganization which you've posited,
but I agree they are both possible scenarios.  The question for git
development is whether these sorts of issues ar ones that we should
try to handle or not?
That entirely depends on your definition of "handle", I think.

I personally think that it is better for the tool to make its best effort
but stop and let the human inspect the result if the validitly of the
result is not so cut-and-dried, than blindly saying "the user said move
the directory, so I'll move the directory and move any and all new files
to it" and produce a potentially wrong result.  My comment in the previous
message about <db/gdbm.c> was not that it is 100% correct to leave it
there, nor it is 100% correct to move it elsewhere.  The point was it is a
case you cannot say what is correct even with help from "scm mvdir", and
the tool should stop and ask for confirmation.

Boasting that "unlike git that does not record renames, we correctly
resolve this case automatically, because our superiour design records the
user's intention to rename directory" is simply embarrassing yourself.
You may be silently producing a wrong result, which is nothing to boast
about.

I think it is Ok to assume that most of the time it is correct to move the
new file if the other branch "renamed" the directory in the situation the
example depicts, and I do not mind if the "best effort" the tool makes is
to move it to make it easy for the user to say "Yup, that is the right
outcome" and conclude the merge, but I think a tool is broken if it does
not give the user an opportunity to examine the situation and say "Oh, no,
that is not correct in *this* case" and fix it up.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help