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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Carl Worth <cworth@xxxxxxxxxx> writes:

>> The problem I have with the new behaviour is that it goes
>> against the mental model when I start doing anything nontrivial
>> (I would not use words as strong as "totally breaks the mental
>> model", but it comes close).  I am not sure how well I can
>> express this, but the short of it is that "grokking index" is
>> not about understanding how the index works, but about trusting
>> that git does the right thing to the index and you do not have
>> to worry about it all the time.
>
> Frankly, I do not currently trust git to always do the right thing
> with the index.

This clearly shows that I did not express myself well.  You are
correct that there are commands that ignore the index by default
(a notable example "git apply" has been given by both of us),
and you do have to know about what the commands you use do to
the index.

What I meant by "do not have to worry about" is not about the
index operations each command invocation involves.  Of course
you need to know (unless you will do a "commit -a" at the end)
that git apply without --index will leave the index out of sync
relative to your working tree, for example.

What you do _not_ have to worry about all the time is the local
changes you do not want to go in your next commit but still want
to keep in your working tree.  Although it probably is not
kosher from the purist point of view, it is very convenient to
be able to keep truly local changes (say, my GIT-VERSION-GEN,
everybody's change to Makefile to set "prefix=/usr/local", or
"#define DEBUG 1" in one of the C files you are currently
mucking with) that you have no intention of committing, while
you want to record the changes to the paths you worked on so far
with patch application, merging and edit + update-index in your
next commit.  You record the latter in the index using git tools
to build what you want to have in your next commit in the index
in each step (again, each step you may have to be aware what you
are doing).  After you update the index, you can forget about
them -- because the index remembers them for you.  They are in
the state you tentatively decided is good for the next commit.
You do not have to worry about the local changes you still have
that you do not want to have in the commit because you do not
run update-index on them, and you can trust that git does not
automatically do so either, so they stay local.

>> Once I am done, I can ask "git diff" and expect it to show my
>> local changes I have no intention of committing for now
>> (e.g. GIT-VERSION-GEN in the working tree has v1.4.5-rc1.GIT
>> long before I plan to start the rc1 cycle to constantly remind
>> me what the next version will be, which is a trick I picked up
>> from Linus), and "git diff --cached" would show exactly what I
>> will commit.
>
> I understand the trick, and I'm not proposing anything that would
> preclude it. But I really don't find it a compelling argument for the
> default behavior of git-commit.

The above paragraph is not the important part of my message.
What was much more important is what immediately followed it,
which you did not quote:

    And at that point, I trust "git commit" to do the right thing --
    the damn thing I just checked with "git diff --cached" _is_ what
    will be committed.

Like it or not, git was designed by and for people who use the
index to work in a dirty worktree.  The "-a" option to "git
commit" is politely explained as the "--all" option, but its
true pronunciation is "screw the index -- I rightfully haven't
been paying attention to the index (my workflow did not require
me to) because I know all the changes in my worktree are what I
want in the next commit" option.

The "screw the index" attitude is not a wrong thing per-se.  It
is perfectly a good habit to always work in a worktree that
exactly matches HEAD after each commit, and the only index
manipulation you would (unfortunately) need to do between your
own two commits are "git add" (for this use pattern, "git rm" is
an unnecessary thing to do -- just saying "rm" is enough).  Then
"git diff" (without --cached but perhaps with paths) would serve
as a preview for your next commit because you are going to do
the "screw the index" commit (except that unfortunate "git add"
thing, which we _could_ fix with "intent to add" entries in the
index) and you would be happy with the similarity to CVS.

Once you use "I care about the index" workflow, however, you
will see more areas where git's index shine.  For example, "git
diff" starts to take a more useful role.  "I care about the
index" attitude means you let the index be the incremental
staging area for your next commit, and when you reach a good
"snapshot" point you update the index with various means
provided by git.  "git diff" will show "what could further be
added to the next commit" without talking about what you already
decided are good earlier and updated the index with.  As we
already discussed, "git merge" will update the index for cleanly
merged paths to let you concentrate on more interesting cases
(i.e. merge conflicts).  To people who care about the index, the
next commit preview is "git diff --cached", not "git diff HEAD".
What git promises to them is not to update-index the local
changes they have without being told and without their knowing.

This is where "git commit" that does "-a" by default goes quite
against the underlying mental model of git.  You staged what
should appear in the next commit in the index because you did
not want to worry about the local changes you still want to keep
in your working tree.  Doing the "screw the index" commit by
default to these people is slap in the face.  You do not want to
get your index suddenly screwed at the final moment of making
the commit, which happened to me when I did "commit --amend"
with the version with those two patches applied.

Don't get me wrong.  I know there are cases that it is useful to
always commit with "-a", but that really has to be opt-in.  When
I work in my alternate "trivial fixes only" repository, I use
the "screw the index" workflow myself.  When I run git apply and
the patch does not apply, I use "git apply --reject" and fix the
mess by hand, and at that point I do not care if that operation
updates the index for the paths involved or not (although I do
check if the patch tries to add new paths -- they need to be
told to git even whey you take the "screw the index" attitude),
and I do not bother running update-index on them either.  But
that is possible only because I know I am going to commit the
final result with "screw the index" option.

"grokking the index" is not about knowing how the index could be
used in your workflow.  It is about actually using the index to
stage your next commit.  Somebody a bit smarter than me once
said that if you deny the index you are denying git.  Although I
would not say it that strongly, because "screw the index" is
also a valid workflow to use (arguably part of) git, "screw the
index" at the commit time _has_ _to_ be a conscious act.


-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]