Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".

Previous thread: Re: git and bzr by Jakub Narebski on Wednesday, November 29, 2006 - 8:30 pm. (1 message)

Next thread: [PATCH] git-branch: let caller specify logmsg by Lars Hjemli on Wednesday, November 29, 2006 - 10:16 pm. (1 message)
To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, <git@...>
Date: Wednesday, November 29, 2006 - 9:03 pm

We seem to be agreeing (and Linus seems to, too, in a thread
next door) that it is a good thing that git keeps index clean
unless you explicitly ask it to.

We also seem to be agreeing that people with more involved needs
can deliberately make index different from HEAD, way before
issuing "git commit", and that they can commit even when "git
diff" gives nonempty differences, and these are good things.

Are we on the same page?

Now what does it mean to make "commit" silently update the index
with all the changes in the working tree without being told?

Unless you are introducing "working tree is the king" mode to
git to make everything ignore the index's "contents" part (in
other words, the index is used as the CVS/Entries file, nothing
more, under that mode of operation), I think you just introduced
an inconsistency at the place where the difference matters most.

I do not agree what you are asking is a "mild change" at all,
and I said it already that it goes against the mental model of
how git tools work.

Earlier, the world model was "you build it in the index and you
make a commit of what is in the index; there is a last-minute
index operation you can do by passing paths to commit and as a
short-hand there is -a as well [*1*]". Now you made the world
model "it does not matter what you have in the index before
issuing git-commit; if you want to preserve what you built in
the index, you have to do something non-default". That WOULD
solicit more newbie confusion. "If it does not matter at the
end unless you do something special, why bother doing it at
all?" would be the question you would face.

Earlier on the "UI warts" thread, people said that the users do
not form the mental model of how the toolset works by reading
the tool's documentation but by trying things out, and I think
that is a valid observation. We should not be sending a wrong
message by introducing inconsistencies like that.

The tool's UI should naturally reflect what world model it is
based on, an...

To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, <git@...>
Date: Wednesday, November 29, 2006 - 9:22 pm

Side note. I think the above "Until..." is an overstatement,
and maybe the readers of the tutorial can be taught a lot
earlier how the index can help them. Maybe the following
sequence can be added to an early part of the tutorial sequence?

$ edit hello.c
$ make test
$ git diff
$ git update-index hello.c; # ok, that is good so far.
$ edit hello.c; # hack more
$ make test; # oops, does not work
$ git diff; # ah, that overeager edit broken what was good
$ git checkout hello.c; # get the last good one back

-

To: Junio C Hamano <junkio@...>
Cc: Nicolas Pitre <nico@...>, Carl Worth <cworth@...>, <git@...>
Date: Wednesday, November 29, 2006 - 10:11 pm

Hi,

I like it. Sort of a "temporary commit" to check against.

Ciao,
Dscho

-

To: Johannes Schindelin <Johannes.Schindelin@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, <git@...>
Date: Wednesday, November 29, 2006 - 11:10 pm

I (very) occasionally do this for patches I get.

You can do

git-apply --index patch

and it will apply the patch and update the index for you. That's great for
committing the patch (because it means that it adds and removes your files
automatically for you), but most of the time when I get an email that I
want to apply, I just use "git-applymbox".

So where doing the "git apply --index" thing is great is when you see a
patch that has some obvious deficiency that makes you not want to commit
it directly, but add some fixup of your own.

That's when it's useful to use the index to your advantage - you can do
"git diff" (to see just the fixups you did on top of the patch), or you
can do "git diff HEAD" (to see the combined effect of both the patch _and_
your fixups).

That said, I have to admit that I usually (a) don't do this very often (ie
this is not part of my daily routine) and (b) I tend to do "git reset"
fairly soon afterwards (or alternatively, just "git commit -a") to get
back to the situation where the index will match the current HEAD 100%
again. So the "index doesn't match HEAD" situation is always just a
_temporary_ thing for me.

Linus
-

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, <git@...>
Date: Thursday, November 30, 2006 - 7:09 am

A staging area is per definition meant to keep temporary things before
they are committed to their designated place so there's nothing odd
about that.

--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
-

To: Andreas Ericsson <ae@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, <git@...>
Date: Thursday, November 30, 2006 - 11:58 am

Sure. It's just that some people seem to expect the index to be different
from HEAD, and are afraid of being "confused" by it.

The fear seems to be about "git diff" getting different results from "git
diff HEAD", and always having to _check_ the two.

So I wanted to make it clear that I never have that situation, because I
never leave the index "dirty". I agree that there is nothing odd about it,
but I think that people who don't actively use the index (or don't use git
at all, and just worry about it) see it as a kind of separate entity with
a life all its own.

I can see that if you think the index is likely to be out of kilter with
HEAD, you'd always worry about "ok, so maybe the diff I get from 'git
diff' isn't the _true_ diff, so now I have to do _both_ 'git diff' and
'git diff HEAD' to make sure I know what's up".

I just wanted to clarify that that is never the case for me, and I doubt
anybody else really does it either. For a very complicated merge, I could
possibly see somebody having a dirty index for a day or two and taking a
break with the index dirty, but

(a) I've certainly never seen that myself (and it would have to be
something very messy indeed - I remember multi-day merges with CVS,
but that was because CVS is so bad at merging, not because the merges
per se would have been all that messy)

(b) if you have a merge _that_ messy, I don't think you're likely to
forget about it, and rather than be confused about the difference
between 'git diff' and 'git diff HEAD', you'll be really really happy
that you have some way of seeing just the _remaining_ pieces, rather
than all the crud you already fixed up.

In other words, the fact that the index _normally_ matches the HEAD may be
obvious, but it's also important - it's important to allay fears from
non-index users about it being somehow scary and confusing. It's not.

Linus
-

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 12:40 pm

Well, sure, because the documentation *talks* about it as a separate
entity all its own. Just look at the man page for git-diff as a great
example of this, or the ascii art diagram of the index. It is all

But then why is the default for "git commit" to commit the index, if
the index is almost == HEAD? And why is git-update-index given such

If everyone agrees with this, I think it would be easier to make
changes to the documentation and maybe some UI tweaks about what the
default might be.

One suggestion is that perhaps a mode where warns users when index !=
HEAD for certain critical commands might not be a bad thing. That
might give users that are just graduating beyond novice git usage, and
just starting to become aware of the index, reassurance because if
they *don't* see the warning message, they can rest assured that they
don't have to do both "git diff" and "git diff HEAD", for example.

- Ted
-

To: Theodore Tso <tytso@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 1:13 pm

The default is: commit everything that you ask for to be committed.

If you haven't marked anything to be committed (which you can do with "git
add" too, or with simply being in the middle of a merge, or by having done
something like "git pull -n" or similar that does everything _but_
commit), then git commit will say "nothing to do".

It has NOTHING to do with the index per se.

I still don't understand why people are so hung up about the index.

So ignore the index entirely, and follow along with me:

"git commit" with no parameters simply DOES NOT DO ANYTHING YOU
HAVEN'T ALREADY ASKED YOU TO DO.

It's that simple. It's that logical. Ignore the index. Ignore everything
else. Just read that simple, straightforward, and logical sentence on its
own. It all makes sense.

Then, the trivial follow-up is:

If you want to commit _all_ dirty files, use "git commit -a".
Otherwise, name the files or subdirectories you want to commit
explicitly.

Again: THIS JUST MAKES SENSE.

Asking for "-a" to be the default behaviour is BAD.

For example, in "git commit --amend", it's _important_ that "-a" not be
the default, because you may well want to just amend the commit _message_.
No files updated AT ALL. You may have other state that is still dirty
(because you didn't ask it to be committed last time), and they should NOT
be committed, because the simple rule is:

"git commit" with no parameters simply DOES NOT DO ANYTHING YOU
HAVEN'T ALREADY ASKED YOU TO DO.

Repeat the above sentence again. IT JUST MAKES SENSE.

So maybe the documentation shouldn't mention the "index" at all, because
it apparently scares and confuses people. But the fact is, the
documentation started out as _technical_ documentation, that explains the
_technical_ side of git. We don't have lots of "end-user" docs.

But the lack of such end-user documentation should not cause idiotic
threads like this, where people blame "the index".

Yeah, so the docs are too scary. But none of th...

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 2:09 pm

OK. I'll try to not mention the "index" any more in any postings
here.

And can we agree that any time git spits out a message directing the

I think the response that would come from the people that are confused
is:

"But I told git I wanted to track this file when I said 'git
add' long ago. Why is it making me tell it again."

As you mentioned, all systems have _some_ mechanism for keeping track
of the files to be committed, (and git's is only unique in having a
name and providing more functionality for direct manipulation and lots
of extra information in the case of a merge conflict).

But I think most every system out there _except_ git default to a
state of committing every file it "knows" about as it exists in the
working tree, and then allowing the user to restrict that behavior to
some subset of the files.

Git allows the same subsetting, and has behavior that is very similar
to these other systems when the user provides a list of files.

Git also provides a unique mode in that users can "stage" file state
to be committed later in spite of subsequent different changes being
made to the same files in the working tree that won't be
committed. Some git users love this functionality. But mentioning it
to new users does scare them off to some extent, ("Why would I _want_
to do that?", "What if that happens accidentally?").

And I think one thing that happens is that the current defaults
naturally lead users to hear about this "scary" functionality, even if
the presenter, (whether a human or printed documentation), isn't
trying to go that direction:

Presenter: So use "git commit -a" here.

New user: Why -a?

Presenter: To tell git that you want to commit all files rather
than having to list them all on the command line.

New user: Why not just "git commit" for that then?

Presenter: Because that's something else.

New user: What's that?

Presenter: It lets you stage things---stuff you think is ready to
commit, but when you want to delay that commit unt...

To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 2:33 pm

If so, you should make it a special case.

I refuse to believe in the "people who know what the hell they are doing
should work more at it" philosophy.

The "git commit -a" behaviour as it is now is better than the
alternatives, exactly because it's more flexible. It _allows_ you to not
commit anything at all (and as already mentioned, there are cases where
that is exactly what you want).

If you want to have a "-a by default", then that you require _you_ to do
more work, and no, it's NOT an excuse to say "I'm a clueless newbie, and I
don't know how to set a config option, so I think it's the smart and
beautiful people who should suffer for my shortcomings".

You can even do it by doing an alias like

[alias]
ci = commit -a

and then you can revel in your CVS-induced mudpit all you want. Just
don't try to convince people who have gotten over that braindamage to live
in the same muck with you.

Problem solved. For all I care, we can make that alias a default one, so
people who just can't get their mind out of the gutter that is CVS can
continue with their evil ways.

Linus
-

To: Linus Torvalds <torvalds@...>
Cc: Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 1:37 pm

Might it be a good idea to have "git-add" do the same as
"git-update-index" on already tracked files? That could be easily
taught as "you must explicitly _add_ files to your next commit" and
whether the file is already tracked or not wouldn't matter. This would
help newbies actually getting used the index without mentioning the
dreaded word "index" at all.

Right now git-add on an already tracked file does nothing, not even a
message to say it did nothing.

Nicolas
-

To: Nicolas Pitre <nico@...>
Cc: Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Thursday, November 30, 2006 - 2:38 pm

I think this is worth doing, but it doesn't solve the problem.

It would be nice if this worked, because then it would be natural to
teach users to "git add" their changes, and then when the obvious
complaint about that being annoying to type all the time, then respond
by teaching "git commit -a" as a shortcut. That would be very natural.

But this doesn't quite work. Here's a major "index is confusing"
scenario that I first hit on my first exposure to git, (it was so long
ago that I completely forgot about it when when Linus asked what the
big deal is about the index).

It's all about the fine details of what "git add" does that can be
_extremely_ surprising to new users. Here's a simple scenario:

$ git init-db
defaulting to local storage area
$ echo "hello wurld" > hello
$ git add hello

# Oops! Look at that typo.

$ echo "hello world" > hello
$ git commit -m "add hello"
Committing initial tree 0267c1bf2956b3df47851e0163f2ea86c002379d
$ git diff
diff --git a/hello b/hello
index b1df5e6..3b18e51 100644
--- a/hello
+++ b/hello
@@ -1 +1 @@
-hello wurld
+hello world

And here the new user reaction is "What?! I fixed that before I
made the commit! What kind of broken system is this."

The above example is not at all surprising to someone who understands
the index. And it's that "why should that behavior be confusing"
disconnect that I'm trying to bridge here. Can you see why the above
confuses new users?

In most other systems I've used, 'add' means "I want the system to
'know' about this file" while 'commit' means "Please commit the
current state of all files you 'know' about (or the ones I mention
here on the command line)".

The current semantics do nothing to avoid this "interaction bug" and
there is no way to explain it to the user without going through an
"explanation of the index" and the user is left to decide that the
index is just there to help make broken commits.

So, I'd love for "git add" to be a shorter way to type "update-in...

To: Nicolas Pitre <nico@...>
Cc: Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Thursday, November 30, 2006 - 2:51 pm

By the way, I think I've said all I can in this thread.

If the "create file; git add; edit file; git commit" confusion isn't
blisteringly obvious to the git maintainers then I think I have to
give up here.

And this isn't just CVS-induced brain damage. It's the user being
required to mentally juggle 3 states for the file, (the last
"committed" state, the current "working tree" state, and this
"something else" state). The sequence above, (which is very natural),
exposes this "something else" state that to a new user.

If we imagine a new user as coming, not from cvs, but coming from
no revision control system, then it's less confusing to add one single
new state, (the "last committed" state), in addition to the "working
tree" state the user is familiar with.

Forcing the user to learn two instead of one is just plain harder,
(which is completely separate from git _allowing_ this extra state
once you learn it).

So if git is determined to just be harder to learn this way, then I
don't know what more I can do to help here.

I love git, and I think everyone should use it. I would just like to
help make it a bit easier for people to do that.

-Carl

To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Thursday, November 30, 2006 - 5:33 pm

Exactly. We had a tutorial for the project I contribute to (admittedly
the initial users were all used to how CVS worked) and while a number of
people got the concept of the index and were fairly happy with it, it
did add to the confusion of the tutorial, so now it doesn't mention the
index at all.

The tutorial introduced it as a staging area for commits, but the
trouble is that once you work like this you have to remember that
"git-diff" won't show you what will be committed, so you have to use
"git-diff-index" as well. If you get them mixed up then you end up
committing the wrong thing.

Here's a selected list of the commands introduced in the tutorial,
without mentioning the index:
git diff
git commit -a
git commit <changed-files>
git reset HEAD^
git cherry-pick

Here would be the same entries, but introducing the index too:
git-update-index
git diff
git diff-index
git commit
git commit -a
git commit <changed-files>
git reset HEAD^
git reset --soft HEAD^
git cherry-pick
git cherry-pick -n

Having the index exposed for even simple operations means that the user
has to initially learn three states instead of two. The worst thing
about the index is that it is a limbo state. The committed content is in
the history and can be viewed by gitk (and other tools that the user
will be introduced to later) and the working tree is exactly what the
user sees in their editor. Having a hidden state isn't very good from an
HCI point of view.

Once you understand the concept of the index, it is very useful.
However, new users should be shielded from it if at all possible.

I'm not advocating making "git-commit" equal to "git-commit -a" as I've
been frustrated by command's semantics changing in git before. I can
understand long-time git users would automatically try to use
"git-commit" to just commit their index and get annoyed if it did
something unexpected. Therefore, I would advocate there being no default
behaviour for "git-commit" except f...

To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 3:55 pm

I'm sorry, but you are wrong.

It really _is_ CVS-induced brain damage, and I'm trying to teach you. You
can give up, but that's really "refuse to see the damage that systems like
RCS and CVS has done to the world"

The fundamental brain damage that CVS (and RCS, and SVN, and just about
anything else) has had is thinking that "filenames" (and sometimes this is
"fixed" to be "file ID's") are somehow special, and a totally separate
thing from "file contents".

Really. It's a BUG. It's a deficiency in CVS and friends. And it's a
deficiency that you have gotten so used to that you don't even see that
it's simply obviously NOT TRUE.

You _cannot_ have a filename without the contents of that filename. That
whole concept doesn't make sense, except in the twisted AND WRONG mental
model of "files have identities even without content".

The whole point of git is that it is about "project state" and the history
that binds those states together. People have kind of come to accept that,
and a lot of people realize what it means, but I don't think you've really
accepted what it means for something as simple as a "git add" command.

Again, totally ignore the index. Imagine that it doesn't exist. Imagine
that you never actually learnt about it, and that none of the
documentation ever mentions it, and just ask yourself:

"What does 'adding a file' really mean?"

I mean _really_. It cannot be about the "filename", because a filename
simply doesn't have any meaning alone. Remember what git is all about.

No, when you do a "git add", YOU DO NOT TALK ABOUT FILENAMES AT ALL.

NOT EVEN CLOSE!

No. Git is, and has always been, all about tracking project content. The
fact that CVS is crap, and thinks that "filenames" are special (and this
causes major problems when you do renames), and the fact that SVN is crap,
and things that "file identities" are special (and this causes major
problems when you split a file or when two files join) is very much about
THEIR F*CKING ID...

To: Linus Torvalds <torvalds@...>
Cc: Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 4:47 pm

Great. But let me repeat my last question:

Would it make sense for "git add" to do the same as "git update-index"
on already tracked files? Given the explanation above this would make
100% sense to me.

Even for newbies this might help them understand the power of the index
with only one command. "You _add_ your changes together before you may
commit." That's simple to understand even for newbies. And then
they'll start using the power of the index even without realizing it.

But right now, doing "git add" on an already tracked file simply does
nothing. This is even worse than erroring out.

Nicolas
-

To: Nicolas Pitre <nico@...>
Cc: Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Thursday, November 30, 2006 - 5:19 pm

I think this makes sense and what we did in the original "git
add".

-

To: Junio C Hamano <junkio@...>
Cc: Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Thursday, November 30, 2006 - 6:21 pm

Wonderful! We might be converging to something then.

Because, conceptually, it then becomes much easier to tell newbies about
the index as follows (this could be pasted in a tutorial somewhere):

Contrary to other SCMs, with GIT you have to explicitly "add" all
the changes you want to commit together. This can be done in a few
different ways:

1) By using "git add <file_spec...>"

This can be performed multiple times before a commit. Note that
this is not only for adding new files. Even modified files must be
added to the set of changes about to be committed. The "git
status" command gives you a summary of what is included so far for
the commit. When done you should use the "git commit" command to
make it real.

Note: don't forget to "add" a file again if you modified it after
the first "add" and before "commit". Otherwise only the previous
"added" state of that file will be committed.

2) By using "git commit -a" directly

This is a quick way to automatically "add" all modified files to
the set of changes and perform the actual commit without having to
separately "add" them. This will not "add" new files -- those
files still have to be added explicitly before performing a commit.

Here's a twist. If you do "git commit <file1> <file2> ..." then
only the changes belonging to those explicitly specified files will
be committed, entirely bypassing the current "added" changes. Those
"added" changes will still remain available for a subsequent commit.

There is a twist about that twist: if you do "git commit -i <file>..."
then the commit will consider changes to those specified files
_including_ all "added" changes so far.

But for instance it is best to only remember "git add" + "git
commit" and/or "git commit -a".

Doesn't it sounds nice? The index is being introduced up front without
even mentioning it, and I think the above should ...

To: Nicolas Pitre <nico@...>
Cc: Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Friday, December 1, 2006 - 4:59 am

"This is because git tracks content, so what you're really 'add'ing to
the commit is the *content* of the file in the state it is in when you

me likes

--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
-

To: <git@...>
Date: Friday, December 1, 2006 - 7:36 pm

me too
--
Alan Chandler
http://www.chandlerfamily.org.uk
-

To: Nicolas Pitre <nico@...>
Cc: Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Thursday, November 30, 2006 - 7:02 pm

Yup. And it appears that we even agree that "intent to add" is

I sense that you are inviting me to argue for reverting the
other "git commit" braindead which is spelled "--only" (and

Other than these "twists", I think it makes sense, and that is
what I think.

But making sense to me does not necessarily validate that a
tutorial document is great for its intended audience, since I
lost git virginity long time ago. I can only endorse that the
description is technically accurate.

-

To: Junio C Hamano <junkio@...>
Cc: Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, Linus Torvalds <torvalds@...>, <git@...>
Date: Thursday, November 30, 2006 - 9:20 pm

No no no !

I argued for that at the time and I still stands behind that change !

Nicolas
-

To: Junio C Hamano <junkio@...>
Cc: Nicolas Pitre <nico@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 7:40 pm

I actually really like the current defaults for "git commit".

And I say that despite the fact that the defaults are _different_ from the
original ones.

I like the fact that when you do "git commit filename", it really will
commit _only_ that file, not the other files you added. It's logical.

So you can do

echo a > file-a
echo b > file-b
git add file-a file-b

git commit file-a

and it will only commit one of them. Now, admittedly, the status message
that you get is slightly misleading (it says that "file-b" is untracked,
which is not strictly true or at least somewhat confusing - it's untracked
only within the context of that one commit), but this is all logically
consistent.

And it's wonderful for noticing "Oh, sh*t, I forgot to commit that
previous change, let's commit that other file first!". You can do things
like this _despite_ the fact that you've added other files to the list of
files to be committed.

The current semantics for "git commit" are really powerful, and really
flexible. Yes, there are different "cases", but they all have their place:

- "git commit" on its own:

This is for things where you prepared things earlier: notably a merge,
for example. But it might be the "--amend" case too, where you simply
don't want to change any of the working tree, just the commit message.

The fact that it has a nice fallback for the "nothing to commit" case
which basically just prints out the same thing as "git status" is just
gravy.

- "git commit explicit/file anotherfile"

This is great (and I use it) exactly for when you have random other
additions in your tree that are brewing, and you just want to commit a
particular fix that takes precedence. You may be in the middle of
something else, but you found a critical bug that needs to be fixed,
and while you _could_ do it on another branch, it's just a lot more
convenient to specify exactly what you want to commit.

- "git commit -a"...

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 8:24 pm

Hmmm. I did not make my judgement based on what the command did
in the ancient _original_ version. The --only behaviour being
totally different from others (from "index is the only thing
that matters" point of view) was what bothered me. It did not
feel logical.

that makes tons of sense.

What's "logical" largely depends on how things ought to behave
in the mental model, and the mental model you would form largely
depends on how things are explained to you.

-

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 8:13 pm

But, wait a second. What if I do my typo fix to file-a in between that
"git add" and the "git commit". Why should "git commit" insist so
vehemently on committing the _old_ state of file-a while "git commit
file-a" so happily commits the _new_ state?

I'm really not seeing conceptual consistency to what "commit <files>"
does compared to "commit".

The "commit <files>" case is a special-case of "commit -a" while
"commit" is just plain different. See?

I do like the direction Nico is going with "git add" and his little
tutorial. I think the first part of that, (without the twists), could
make a very nice introduction to git.

The "twists" part though is quite a nightmare, and "twists on twists"
is something that should be left to B-grade screenwriters, not
technical writers, (nothing against Nico there---the stuff is really
confusing).

But dropping back to the old default for "git commit explicit/file"

For "notably a merge", how often is this not equivalent to "commit -a"

Personally, I think I use --amend to change the tree of the last
commit as often as I change just the message. Regardless of the
relative frequency, I definitely use it often for both of those modes,

As I mention above, this usage is exactly "commit -a" but restricted
to just a few paths. Why isn't it just as brain-damaged to take
contents from the working tree instead of the index here as in the

If we all agree it's the most common, then why isn't it the default?!
It's the right thing for after resolving a conflicted merge, (since
the working tree is where the user _first_ resolves things, before the
changes make it to the index), the command is consistent with the
behavior of "git commit explicit/file", and the existing "git commit"
behavior would still be available in the rare cases it's desired, (and
then, how painful would it be to type the few extra characters to ask
for that?).

I know, I know. I said I'd give up and yet I keep harping on this
stuff. I'm hopeless.

-Carl

To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 8:21 pm

Because that's what "git commit filename" means.

Exactly what the command says. "git commit" says "commit everything I've
told you to commit". While "git commit filename" says "commit the changes
that I've made to this file".

Yes, they are two totally different cases, but nobody sane can claim that
it is strange. Exactly _because_ you explicitly list the filename, that
also means that you want the file content AT THAT TIME. If you don't list
the filename, you obviously must be talking about committing something you
did earlier.

Linus
-

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 9:10 pm

Call me insane.

I think it is very strange that the following command sequences commit
different content for myfile:

echo old > myfile
git add myfile
echo new > myfile
git commit

compared to:

echo old > myfile
git add myfile
echo new > myfile
git commit myfile

The difference there is very subtle and really does prevent a
reasonable, "just ignore the index and you can use git comfortably".

Now, the behavior above can be explained. You and I both understand it
just fine. And Nico's proposed tutorial document even explains it,
(twists and all).

But it is strange, and I cannot see how the first case is at all useful.

The point is that by-and-large I don't ever want to commit anything
that is not present in my working tree at the time I type
"commit". That's precisely why I'm typing "commit" at that time.

If I do ever want to commit content that is not currently in my
working tree, then I should have to do something
exceptional. Otherwise, git will always have user-interface traps that
will trip people up.

You might point at my first example and say that the timing of my "git
add" command is the exceptional thing I did to trigger the old commit.
But the second command above destroys that explanation. In the second,
the timing of "git add" doesn't trigger any exceptional behavior at

You're explaining the behavior, but not providing any justification
for this being the right thing based on what a user actually wants to
do.

-Carl

To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 9:32 pm

If you want to ignore the index, you'd always use "git commit -a".

The old argument by incredulity. The fact that you cannot see it doesnt'
change the fact that I use it all the time. Usually not for the same file,
but committing something that is different in the index and in the working
tree is my normal behaviour - it's how any number of things work (like
merging while you have dirty state, or applying patches while you have
changes).

So, let me condense the argument:

- your argument is that cannot understand how anybody would ever want to
use this.

That's really what it all boils down to. That's your ONLY argument. You
didn't actually answer any of me explaining _why_ it's how it works, and
why it _has_ to be why it works. Your argument just boils down to "I can't
believe it's useful to be consistent".

My argument is:

- the current behaviour is actually very powerful, and I've given
examples of when I actually do use it (and whether you know it or not,
they are also things you've probably done - the "pull from somebody
else with dirty files" is actually exactly the same thing, you just
never realized it just because it happened to be the same thing on two
different files)

- the "git add file ; change file ; git commit" behaviour is absolutely
REQUIRED once you get the whole "git tracks content" logic. Doing
anything but committing the old version (the one you added) would be
illogical and wrong, because it's strictly against the whole POINT of
tracking content.

So. That's what it boils down to. Your personal incredulity against
fundamental concepts and real usage.

The reason I like UNIX is that it has "fundamental concepts". And
surprise, surprise, a lot of the same issues are at play in "git" too.
Pretty much _all_ the behaviour (apart from actual _naming_ issues) really
come from fundamental concepts, and _not_ doing special cases.

I guarantee you, in the end you're better off building a world-...

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 10:08 pm

I'm sorry, Linus. I'm really failing to communicate with you somehow
here.

I _do_ use this all the time too. I don't need you to explain it to me
again. I get it, I like it, I use it. That's not at all what I'm

Nope. I get it and I use it. Most commonly I do things like
"update-index;commit" to separate independent changes, (I could use
"git commit explicit/files" instead but I *gasp* actually enjoy being
able to manually stage things in the index first).

What I'm trying to say is that the _defaults_ are not well geared

I do understand how git works. I understand your points about
filenames and content. I understand that.

One thing you never really answered was my conversation with a new
user that left the user with the impression of "git is bizarre". How
can I fix that conversation?

The idea I have for improving this is to do nothing more than change
the default semantics for one command to the semantics of that same
command with a single-letter option. You keep saying that my idea is
brain-damaged, (that carrying the filename from "git add" to "git
commit" without the old contents would violate something fundamental).
But "commit -a" already exists and does _exactly_ what I'm asking for
here. People use that without destroying git's model. Why would it
necessarily be so evil to do that by default?

By the way, none of the "confusion" arguments are coming from me
directly. They're coming through me by proxy, (on behalf of people
I've seen deciding against using git). Personally, I love git and plan
to continue using it forever. I'm very happy with it. I'm even
comfortable with all of the aspects of its interface that I'm arguing
against changing here, (which really are not big fundamental
things). I just think its harder for new people to get to that point

Here's another question based on that example. You say above that
committing the old version is the only logical thing to
do. Separately, you say that after adding file-a and file-b it's often
convenient to be a...

To: Carl Worth <cworth@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 10:44 pm

I really think we're better off just telling people how things work (with
practical examples, and _not_ by trying to explain things at too high a
conceptual level).

I don't think people generally are all that stupid, and I think it's
actually counter-productive to try to basically lie about how things work.

I really _think_ that a lot of that is in the documentation being overly
technically oriented and talking often about the technical side of how
things work in the index, rather than the purely user side of what that
_results_ in.

I really believe that people can understand the concept of "git add"
squirrelling away the whole state of the file at add-time, and suddenly
it's not all that complicated. Also, it's not even something that people
really need to worry about, and I think we should make that more clear.

In other words, the documentation could _literally_ give the example of

git add file.c
.. change file.c ..
git commit
git diff file.c

and talk about this issue up-front, but then just say outright to people
that "if you don't want to know about these details, you can always just
use 'git commit -a', and you'll never really even notice".

There really isn't all that much to "hide". I think we've sometimes done a
horrible job on _presentation_, but I also think that it's better to give
examples of thigns like this, and then tell people not to worry, because
they'll never need to care unless they actually start doing something
fancy.

So all your examples of "badness" aren't really all that bad. Newbies
should be told:

- use "git commit -a" normally (with pointers on fancier usage)

- and yes, we obviously should change the message to say "git commit -a"
instead of "git update-index"

- do NOT use the "-m" flag, and look at what git tells you in the
commit message!

This is actually important, because even for non-newbie users, the git
commit message for a conflicting merge contains useful information,
and ...

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 11:52 pm

I think Linus is right that the semantics of "git commit" and "git
add" are not broken and do not need fixing. But Carl and others are
right that they are not self-explanatory to most people, whether or
not they have been tainted by CVS and its ilk. Maybe this is a job
for a little contextual documentation (aka hand-holding) to accompany
the tutorial and reference docs.

How about we add a set of "expert" flags in the config, gating access
to non-intuitive behavior and to idioms that should be discouraged in
casual use. For instance, with an empty config, "git commit -m" fails
with a message to the effect of:
"As a general rule, you shouldn't use the -m flag unless you're
scripting git for automation purposes. If this is what you are doing,
or if you insist on committing without feedback about the state of
your tree, you need to set the 'expert-commit-message' flag".

Likewise, when your working copy does not match HEAD, "git commit"
with neither -a nor an explicit list of files fails, saying:
"'git commit' on a dirty working copy does the Right Thing! But
some people find the Right Thing counter-intuitive at first. Either
stick to 'git commit -a' or read the docs and set the
'expert-commit-dirty' flag."

And "git add" still does the right thing, but warns:
"Remember, git is not CVS. 'git add' has taken a snapshot of the
current _contents_ of the newly added files, not just their names.
From now on, you will need to 'git mark' edits to them if you want
them to be part of the next commit, just like edits to files that have
already been committed. This warning can be suppressed by setting the
'expert-add-content' flag."

Note that 'expert-commit', etc. should NOT change the semantics of any
command that doesn't error out. They should just enable idioms that a
novice user is likely to try and get unexpected results. They should
be overridable from the environment, of course, either one by one
(export GIT_EXPERT_COMMIT_MESSAGE=y) or wholesale (export
GIT_I_GRO...

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 11:40 pm

Sure. There's no need to lie to about how things work. And I agree
that would cause later problems. As far as getting the message out, we
have several different ways to do that:

1. In-person presentations, demos, tutorials

2. Written tutorials

3. Reference documentation

4. Output from git commands

5. The default behavior of git commands

And that list is roughly sorted from most to least "information
bandwidth". The limited bandwidth at the bottom-most levels in my
list, (together with the fact that people often start trying the tool
at only those levels), means we have to be even that much more careful
about the messaging there.

In my experience, I think we succeed quite well at level 1. In person,
we get immediate feedback from the user and it's easy to catch and
cut-off any user confusion up-front. "Oh, you don't even need to run
that command...use this instead", etc.

Yes, this is a big problem at level 3. Things like the "man git-diff"

One trick with saying "we just need to document this better" to avoid
the confusion is that approach assumes that the users are actually
_reading_ the right documentation. Now, we're currently making this
harder than it should be at level 4 by doing things like sending users
to the documentation for update-index. But still, if we can make
things less surprising in some cases _without_ needing the

Yes, adding lots of good examples to the written documentation will

So here you're arguing for documenting the heck out of "commit -a" at
all of levels 1-4. If we're going to do that, why not just go the next
tiny step and make it work as "git commit" by default, (which people
_will_ try). If we can say, "come from hg or bzr and things will just
work", people can try that, be satisfied that git isn't bizarre, and

Interesting. I do use -m almost exclusively. I do that for speed I
think, (but I do do multi-line commit messages). The only drawback I
was aware of was that I'm doing manual word wrapping, but I might
start...

To: Nicolas Pitre <nico@...>
Cc: Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, Johannes Schindelin <Johannes.Schindelin@...>, Theodore Tso <tytso@...>, Andreas Ericsson <ae@...>, <git@...>
Date: Thursday, November 30, 2006 - 5:03 pm

Yeah, I think it would probably make sense. I also think it would make
sense to rename "update-index" entirely, or at least offer other names for
it (ie the "git resolved" suggestion).

In short - I agree that it's all just facets of the same thing: telling
git that some part of the working tree is now in a state ready to be
committed. Whether it's because we want to "add" content, or just mark it

Yeah, that's arguably a stupid thing to do ("you already added it, what do
you want me to do?") but the choice we use is probably the worst of the
three straightforward possibilities (ignore, update or error).

The _original_ "git add" was literally just this one-liner:

#!/bin/sh
git-update-index --add -- "$@"

which actually was better in this respect (it updated the content), but
that didn't do sub-directories, so this is arguable a bug introduced by
commit 37539fbd:

[PATCH] Improved "git add"

This fixes everybodys favourite complaint about "git add", namely that it
doesn't take directories.

which started using

git-ls-files --others -z -- "$@"

together with the exclude files to generate the list of files to add. At
that point, we lost files that already existed (since "--others" specifies
just files we don't know about).

Linus
-

To: <git@...>
Date: Friday, December 1, 2006 - 4:34 am

How about this:

git-update-index becomes plumbing only - never expect a user to run it.

Hence,

git-add becomes git-prepare and does
a) update-index --add
when the file being "prepared" is not tracked
b) update-index
when the file is already tracked

git-rm takes on "git-update-index --remove" (and --force-remove) with
appropriate switches.

git-mv does what it does - it's already pretty perfect

git-cp gets added; even though it's simply "cp a b; git-prepare b"

Obviously with all the details that I've left out filled in.

Andy
--
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com
-

To: <git@...>
Date: Friday, December 1, 2006 - 7:33 pm

Why can't it stay as git-add

It means "add the current state of the content to the index"

It has the useful property that git-commit -a can be seen as a short cut for
add all the files in the working try and commit.

--
Alan Chandler
http://www.chandlerfamily.org.uk
-

To: Linus Torvalds <torvalds@...>
Cc: Nicolas Pitre <nico@...>, Junio C Hamano <junkio@...>, Carl Worth <cworth@...>, <git@...>
Date: Thursday, November 30, 2006 - 6:27 am

Hi,

An obvious deficiency would also be the presence of hundreds of debug
quirks I had to introduce to find the bug which I finally fixed. But I do
not want to commit, because it is such a mess. So: into the index, ye
files.

Now I can clean up everything I introduced to find the bug. If the result
does not work as expected? "git diff"!

But now that I cleaned up the mess, I find that there is a more elegant
way to solve the problem. Into the index, ye files! Clicketyclick, if I
mess up, I always have the state in the index!

Ciao,
Dscho

-

To: Junio C Hamano <junkio@...>
Cc: <git@...>
Date: Wednesday, November 29, 2006 - 9:58 pm

That actually points out one of the things I think isn't so hot about
using update-index for checkpointing your work. Here's a longer
development session:

$ edit hello.c
$ make test
$ git update-index hello.c; # so far so good
$ edit hello.c
$ make test
$ git update-index hello.c; # looks good too
$ edit hello.c
$ make test
$ git update-index hello.c; # sure, seems okay
$ edit hello.c
$ make test; # oops! design flaw in the second edit uncovered!
$ ???; # how do I back out the last three edits but not the first?

If you know for certain that you will only ever want to back out the
most recent edit during your development, or back out all the way to
HEAD, then update-index is fine, but if (like me) you want to checkpoint
your work frequently so you can step back in a very fine-grained
fashion, then it's less than ideal to have only one checkpoint that
keeps getting overwritten.

For frequent checkpointing, as far as I can tell I pretty much need to
commit (to a development branch, of course) every time. I do that
because I never know beforehand whether I'll need to go back by more
than one step later on; 99% of the time I don't have to, of course, but
the remaining 1% is pretty painful if I can't.

Am I missing some magic index command that would support multi-level
backing out? Obviously StGIT is an option as well, but that seems like
overkill when all I want is to checkpoint my work. The above is why,
even though (I think) I know enough about the index to use it as you
describe, I often don't bother and just run "commit -a" during
development instead. When I merge, I usually fold all my checkpoint
commits together and merge the change as a logical unit.

But I'm still a relative n00b and would appreciate knowing if I'm just
missing some big obvious technique.

-Steve
-

To: Steven Grimm <koreth@...>
Cc: <git@...>
Date: Wednesday, November 29, 2006 - 10:12 pm

You are doing just fine. Using commits to do snapshot is
another workflow people often use. These people tend to do so
in a work branch and cherry-pick the resulting series of commits
onto more permanent branch while reorganizing and tidying up the
development history to be published to the outside world.

-

To: Steven Grimm <koreth@...>
Cc: Junio C Hamano <junkio@...>, <git@...>
Date: Wednesday, November 29, 2006 - 10:04 pm

Try `git commit --amend'.

Sam.
-

Previous thread: Re: git and bzr by Jakub Narebski on Wednesday, November 29, 2006 - 8:30 pm. (1 message)

Next thread: [PATCH] git-branch: let caller specify logmsg by Lars Hjemli on Wednesday, November 29, 2006 - 10:16 pm. (1 message)