[Python-Dev] PEP: Collecting information about git

Stephen J. Turnbull stephen at xemacs.org
Thu Sep 17 04:57:19 CEST 2015


Nikolaus Rath writes:
 > On Sep 17 2015, "Stephen J. Turnbull" <stephen at xemacs.org> wrote:
 > > Nikolaus Rath writes:
 > >
 > >  > Hmm, that's odd. As far as I know, the difference between the hg and git
 > >  > DAG model can be summarized like this:
 > >  > 
 > >  >  * In git, leaves of the DAG must be assigned a name. If they don't have
 > >  >    a name, they will be garbage collected.
 > >
 > > You can turn off automatic garbage collection.  I usually do: it's
 > > very unusual that I create millions of objects, or even megabytes
 > > worth of objects, that I'm creating.
 > 
 > Okay... (I don't quite see why this matters here).

Because it's very possible to have unnamed heads in git, although
naive usage in git doesn't create them.  The most common case used to
be after a rebase, but now the reflog provides a name and prevents
deletion for quite a while.  Now you have to do something weird like
delete a ref and change your mind, or commit to a detached HEAD and
then checkout something else.

Turning off GC is a very specialized taste, though.  I'm a packrat and
I'm also interested in workflow management (my day job is teaching
economics in a management school).  Spelunking in the detritus of my
work has made me more conscious of *how* I do various activities (not
limited to programming!), which helps in teaching others either to do
the same or to adapt my preferred workflows to their needs.

 > > >    If they have a name, they are called a branch.
 > >
 > > Tags are also refs, the difference being that committing child of the
 > > tip of the current branch advances the branch pointer, while that
 > > won't happen with a tag.
 > 
 > Yeah, it's like that both in hg and git, so I'm not quite sure what
 > you're trying to say...

Well, first of all tags in hg are *commits*, not refs.  That bugs git
people.

Second, "explicit is better than implicit".  In git, there's one
implicit object: the "cache", "index", or "staging area".  This
confuses a lot of people.  For example, "git diff" does NOT give a
diff against HEAD, it gives a diff against the staging area -- which
for my usual workflow which commits files by name is the same thing
because the staging area *equals* HEAD in that scenario.  But in cases
where I do use "git add", that's no longer true, and at first I was
surprised by the resulting diffs.[1]  In hg, there may be several
implicit objects, namely the unnamed heads.

I'm not going to insist on the importance of the *number* of implicit
objects (among other things, it's not obvious how many objects the
index should be counted as).  But what is implicit in git and hg is
*different*.  In git, heads are always explicitly named (even detached
heads have the name HEAD) when you want to operate on them.  In hg,
the most commonly used heads (the default branch and merge heads) are
not.  In hg, you don't have to worry about the difference between the
index (there is one: that's what things like "hg add" affect) and tip,
because the index isn't used implicitly by any commands (except
status, but that's a special case that isn't going to bother anybody).



Footnotes: [1] Now I find this useful, as I almost never make a
mistake with "git add <file>", and the diff against the index filters
out all the files I haven't decided about yet, as well as notifying me
that I've made changes -- often unintended -- to previously added
files.  But for me this was definitely an acquired taste, it wasn't
natural at first.



More information about the Python-Dev mailing list