From: Junio C Hamano <hidden> Date: 2016-08-11 20:27:08
Carl Worth [off-list ref] writes:
On Mon, 27 Nov 2006 16:42:14 -0800, Junio C Hamano wrote:
quoted
I think you are teaching backwards. Couldn't you start like this?
"git commit" takes the list of paths you want to commit.
...
If the "commit the index" operation were moved to a non-default
command-line option of git-commit, then the commit command could be
explained without having to introduce the notion of the index at
all.
Read what I wrote again. You can explain it without talking
about index at all. I really do not think you need to break
"git commit" nor rename "update-index" to "resolve" to explain
things to new people.
The tutorial might be better reworked not to start talking about
-a but start building small project from a newly created
hello.c, git add it, and "git commit" (the first commit), then
edit hello.c and "git commit hello.c" (the second commit).
Perhaps.
Enough about "git commit -a" for tonight.
From: Carl Worth <hidden> Date: 2016-08-11 19:16:28
On Mon, 27 Nov 2006 22:59:52 -0800, Junio C Hamano wrote:
I've been playing with a "private edition" git to see how it
feels like to use "git commit" that defaults to the "-a"
behaviour, using myself as a guinea pig, for the rest of the
evening.
Thanks already for the documentation improvements and the patches. I
will immediately start using these and use myself as a guinea pig as
well.
Confession time. I've had a "purist me" deep inside, who always
thought that people who play contributor role (that is to say
"99.9% of people") should make no commits other than the "-a"
kind [*1*].
...
*1* The reason to favor "-a" commit is not about hiding the
index but about discipline.
I agree with your comments on discipline, (and honestly, I don't
really see why they wouldn't apply to anybody). It just plain makes
sense to commit code as it existed and as it has been tested.
And I think this is really the same motivation for the users whose
complaints I've been representing in this thread. I know people who
have read all of the "hide the index" debates on the git list and
still find the "staged commit" features of the index useless, (because
they already have the discipline of never committing a state that
didn't actually exist in their working tree).
Judging from my experience so far, although I really wanted to
like this, I am still hesitant to recommend this for inclusion.
I'm glad you were willing to try yourself out as a guinea pig on
this. That's definitely worthwhile. But I don't think your negative
experience here is good evidence against changing the default.
My proposal was not that old-time, index-loving git users should adapt
to a new default. I think that it should be made very straight-forward
for experienced users to drop in an alias or a configuration option
such that all the old defaults are preserved. With that, all of the
complaints you ran into, (which are all of the form "things act
differently than I'm used to"), go away.
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. Part of that is that some commands are inconsistent
with respect to updating the index or not. For example, the following
two operations:
git cherry-pick -n <something>
git am < something
are conceptually very similar, (apply some change without creating a
new commit), but the first updates the index and the second does
not. (This is something you already pointed out in your message and
said that perhaps "apply --index" should be the default. I'll come to
a different conclusion below.)
So things like "git diff" and others work very differently in the
above two situations, and the user has to stay well-aware of what's
happening in the index or not. So I do find myself having to "worry
about it all the time".
Another example is how to "undo" a modification of a file such that it
is restored to its state as in the last commit. I'd like to be able to
teach users a single, reliable command for operations like this. It
would be tempting to just say:
git checkout some/file
which will often work, but not in the case of an updated index,
(whether manual or due to something like "cherry-pick -n" or an
in-progress merge). In those cases various suggestions might be
offered such as:
git reset
git checkout some/file
or:
git cat-file -p HEAD:some/file > some/file
at which point we can send users screaming again. (I think there's yet
another option that was discussed on the list recently, but if I
recall correctly, it involved an even more obscure option to some git
command than any of the above).
So a simple operation like this "undo" requires the user to understand
the index and adapt the workflow based on its state. But there's no
advantage being offered to the user at all in a case like this. (And
whether the change being undone came through something like
"cherry-pick -n" or "git-am" is totally irrelevant to the work the
user is attempting to get (un)done).
All of the above is just to point out that there are times when the
notion of the index does get in the way. The user has to mentally
track what's happening in the index even when there's no advantage. My
goal is to reduce the set of operations where the user is forced to do
that.
If users want to take advantage of the index, then by all means, it's
there and can be taken advantage of. And when the index does its job
of taking care of things so the user doesn't have to think about it,
that's definitely a good thing.
The same thing can be said about "git merge" (or "git pull .").
The index is updated for cleanly merged paths so I do not have
to worry about the details -- the only thing I have to know is
that index keeps track of the state and cleanly merged paths are
taken care of for me automatically, so I do not have to worry
about them. "git diff" and "git ls-files -u" will give me
conflicting paths and I can only concentrate on them.
Sure. The behavior of "git diff" during a conflicted merge is actually
quite intuitive. And that's even intuitive to someone who has no idea
what the index is. So the index is doing a fine job here of taking
care of things so the user doesn't have to think about them. We should
have more of that.
The "git diff" behavior would really only be surprising to someone who
doesn't totally grok the index if the index got updated other than
during a commit or merge. So I think it would be great if that only
happened when the user passed the word "index" on the command line as
in "update-index" or "apply --index".
In fact that rule of them would argue for leaving "git apply" alone
and instead solving the inconsistency I pointed out above by making
"cherry-pick -n" not update the index, (unless passed a new "--index"
option).
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. I don't see why the correct next value
for the version is easier to compute at one time vs. another. Linus
argued that it helped him not forget to update the version, but I
would think this kind of thing would train users to leave uncommitted
stuff around which could lead to mistakes, (and the user _still_ has
to remember "Oh, this is that special commit where I _don't_ leave
that uncommitted stuff around anymore, but I actually commit it."). So
I don't personally see any gain to the trick.
Probably new people who are not used to the index do not have
this problem, but I suspect I am not alone among old time
gitters.
Sure, so put an alias or config option in place so you don't have to
change your ways at all.
I lost about half an hour after saying "git commit --amend",
without thinking, because I wanted to amend only the commit
message, and much later I noticed that it swallowed unrelated
changes I had in the working tree because it now implied the
"-a" behaviour, and I should have said "git commit -i --amend".
I definitely commiserate on that one. I myself often use "commit
--amend" to change just a commit message.
But at the same time, I also very often use "commit --amend" to fix up
the tree itself in the most recent commit. And I've also last the same
half hour by forgetting to do "commit -a" or "update-index" when doing
that more than once in the past.
I think the real fix for this particular issue is to add a little more
"stack" functionality to git itself rather than just the one-step-back
functionality of "--amend". For example, one simple thing that might
help would be a command to edit the commit message of any commit. That
would at least be easy to implement as it wouldn't introduce any
user-interface concerns about dealing with conflicts while replaying
history.
-Carl
From: Nicolas Pitre <hidden> Date: 2016-08-11 19:26:12
On Tue, 28 Nov 2006, Junio C Hamano wrote:
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.
This argument has its converse. What you should _not_ have to worry
about all the time is whether your index really includes all the changes
you want included in your next commit.
And whether wanting to leave local changes in the working directory
without commiting them actually happen more often than wanting to commit
every changes is arguable.
What should be pretty consensual though, is the fact that having
experienced GIT users add an alias for "commit" actually becoming "comit
-i" to preserve the current behavior is much easier than asking new GIT
users do the same but with "commit -a".
So in that context I think having commit without arguments meaning
commit -a is a pretty sensible default. And I don't think it has any
influence on the "learning about the index" issue.
From: Junio C Hamano <hidden> Date: 2016-08-11 19:29:05
Junio C Hamano [off-list ref] writes:
Enough about "git commit -a" for tonight.
I've been playing with a "private edition" git to see how it
feels like to use "git commit" that defaults to the "-a"
behaviour, using myself as a guinea pig, for the rest of the
evening.
Confession time. I've had a "purist me" deep inside, who always
thought that people who play contributor role (that is to say
"99.9% of people") should make no commits other than the "-a"
kind [*1*]. So this is not only trying out the issues in the
discussion I had with you, but what that "other me" wanted to do
for quite some time.
A pair of patches will follow this message and I encourage you
to try it out, work with it for a dozen or so commits, handful
of merges, a patch application or two to get part of changes
from different commits (not a "git format-patch | git am" to get
another commit wholesale, but "git apply" followed by your own
edits that eventually result in "git commit"), a few rebases and
resets. If you have a few new people you can sacrifice their
"git virginity" for experimenting this on, I am reasonably sure
they will like it, but I do not know how their learning curve
later will be affected by this change -- it would be interesting
to know. I do not think it would flatten the learning curve of
index much. I am somewhat fearful that it might make it harder,
but I lost my git virginity long time ago, so it is just an
unsubstantiated feeling.
Judging from my experience so far, although I really wanted to
like this, I am still hesitant to recommend this for inclusion.
It does not make any difference while I am doing the simplest
operation (it is just not having to say "-a"), so I do not
foresee problems either way for new people following a saner
version of tutorial, which does not exist yet, that does not
talk much about "git commit -a".
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.
For example, "git apply --index" will update the index for paths
that the patch I feed it talks about (and reminds me if I have
local changes to them by refusing to lose my changes) so after
it finishes successfully, I do not have to think about the index
at all [*2*]. After working on a few files, I can ask "git
diff" to see if the changes so far are reasonable, and mark them
with "git update-index" so that I do not have to worry about
them anymore and keep going to make matching changes to other
files. Once I tell something to git via index, I do not have to
worry about it, and this is a big relief.
The same thing can be said about "git merge" (or "git pull .").
The index is updated for cleanly merged paths so I do not have
to worry about the details -- the only thing I have to know is
that index keeps track of the state and cleanly merged paths are
taken care of for me automatically, so I do not have to worry
about them. "git diff" and "git ls-files -u" will give me
conflicting paths and I can only concentrate on them.
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.
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. In that sense, I do not have to think about
the index at all, because I know git is doing appropriate things
behind the scene for me.
Coming from this perspective, having to say "git commit -i" at
the time of making the commit just makes me feel uneasy, if not
counterintuitive. Making "git commit" default to "-a" rubs this
mental model quite the wrong way.
Probably new people who are not used to the index do not have
this problem, but I suspect I am not alone among old time
gitters.
I lost about half an hour after saying "git commit --amend",
without thinking, because I wanted to amend only the commit
message, and much later I noticed that it swallowed unrelated
changes I had in the working tree because it now implied the
"-a" behaviour, and I should have said "git commit -i --amend".
I needed to redo bunch of commits, which involved having to
re-test a handful revisions (this is not git.git project but my
day job one -- I do not work on it after work, but I was doing
the guinea pig). But this is something re-training can fix and
much a smaller problem than the mental model issue.
[Footnote]
*1* The reason to favor "-a" commit is not about hiding the
index but about discipline. For the "integrator" people to be
able to coast over the changes, they need to be able to trust
the work by contributors to some degree without worrying about
small details; the changes fed to the integrators must be well
tested when they leave the hand of a contributor, and making a
commit that never existed as a whole in the working tree goes
against this discipline.
*2* It might be a good idea to make "--index" the default for
"git apply" when we know we are in a git repository ("git apply"
must be usable outside a git repository so this needs to be
handled with care if somebody wants to do it). There is no
"--no-index" option to countermand it right now, which also
needs to be added.
From: Jakub Narebski <hidden> Date: 2016-08-11 19:48:53
Salikh Zakirov wrote:
Someone said, that default '-a' does not go well with 'git-commit --amend',
and I second that. It was somewhat suprising to see that 'git commit --amend'
is going to include all of the dirty state into the commit,
and since there is no easy way to abort a --amend commit (because the comment
buffer wasn't empty, and :q! does not work as it would on the regular commit),
I had to untwine the changes manually.
By the way, I think that git-commit should also watch the return code
from the editor, so you can ^C it to abort git-commit --amend.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
From: Jakub Narebski <hidden> Date: 2016-08-11 19:56:45
Junio C Hamano wrote:
At the same time, stop talking about "--only" option being the
default when given paths. It has been that way for quite some
time.
This change breaks t1400 which assumed the long tradition of not
modifying index when not told to touch it with an explicit -a
nor paths, so this commit includes adjustment for it as well.
Perhaps we should make it configuration option instead? I usually use
"git commit -a -s"; I add -s anyway, so adding -a is not that much more.
By the way, if I understand correctly git-resolve is meant as restricted
git-update-index, which can _only_ mark file as resolved (and probably
check for merge markers, unless --force'd).
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
From: Junio C Hamano <hidden> Date: 2016-08-11 19:57:38
This makes "git commit" accept "-i" without any parameter (we
used to barf on such a command line) to mean "commit what is in
the index as-is". There is nothing surprising about this new
behaviour. "git commit -i paths..." means "in addition to the
changes I accumulated in the index, also run update-index on
these paths and then make a commit" and this new behaviour is a
natural extension to that to the case where "paths..." is empty.
"git commit" without -i, -a, nor -o still behave the same way as
it has done for a long time, but it now warns that this will be
changed to default to the "-a" behaviour.
Signed-off-by: Junio C Hamano <redacted>
---
git-commit.sh | 30 ++++++++++++++++++------------
1 files changed, 18 insertions(+), 12 deletions(-)
@@ -287,11 +287,15 @@ esaccase"$#,$also,$only,$amend"in *,t,t,*)die"Only one of --include/--only can be used.";;-0,t,,*|0,,t,)-die"No paths with --include/--only does not make sense.";;+0,t,,*)+;;+0,,t,)+die"No paths with --only does not make sense.";;0,,t,t)only_include_assumed="# Clever... amending the last one with dirty index.";;0,,,*)+:all=t+only_include_assumed="# We will start assuming -a without -i; you have been warned.";; *,,,*)only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
@@ -304,8 +308,6 @@ t,t,*)die"Cannot use -a and -i at the same time.";; t,,[1-9]*)die"Paths with -a does not make sense.";;-,t,0)-die"No paths with -i does not make sense.";;esac################################################################
@@ -407,7 +409,7 @@ GIT_INDEX_FILE="$USE_INDEX" \# If the request is status, just show it and exit.case"$0"in-*status)+*status|*status.sh)run_statusexit$?esac
@@ -539,7 +541,11 @@ thenecho""echo"# Please enter the commit message for your changes."echo"# (Comment lines starting with '#' will not be included)"-test-z"$only_include_assumed"||echo"$only_include_assumed"+test-z"$only_include_assumed"||{+echo"#"+echo"$only_include_assumed"+echo"#"+}run_status}>>"$GIT_DIR"/COMMIT_EDITMSGelse
From: Jakub Narebski <hidden> Date: 2016-08-11 19:58:31
Josef Weidendorfer wrote:
On Tuesday 28 November 2006 07:59, Junio C Hamano wrote:
quoted
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
...
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.
I think the difference behavior between "git commit" and "git diff" is
a little bit confusing.
Currently, we have
* "git diff" shows what "git commit -a" would commit
* "git diff --cached" shows what "git commit" would commit
IMHO, "git diff" should show what's in the staging area,
and we should introduce "git diff -a" as a way to see the full
changes.
I see it in other way. "git diff" tells us if a tree has changed wrt. what
would be committed. It is not a preview of commit.
Also, as of now the version without additional option is a fastest one, both
for diff and for commit.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
From: Josef Weidendorfer <hidden> Date: 2016-08-11 20:04:44
On Tuesday 28 November 2006 07:59, Junio C Hamano wrote:
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
...
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.
I think the difference behavior between "git commit" and "git diff" is
a little bit confusing.
Currently, we have
* "git diff" shows what "git commit -a" would commit
* "git diff --cached" shows what "git commit" would commit
IMHO, "git diff" should show what's in the staging area,
and we should introduce "git diff -a" as a way to see the full
changes.
I've been playing with a "private edition" git to see how it
feels like to use "git commit" that defaults to the "-a"
behaviour, using myself as a guinea pig, for the rest of the
evening.
Thanks a lot for the patches, Junio!
I am using them for two days, and my experience is great!
Many times it saved me annoyances of forgetting to put '-a' to 'git commit'.
It should be noted, that I mostly used 'git-commit files...'
or 'git-commit -a' forms before.
Someone said, that default '-a' does not go well with 'git-commit --amend',
and I second that. It was somewhat suprising to see that 'git commit --amend'
is going to include all of the dirty state into the commit,
and since there is no easy way to abort a --amend commit (because the comment
buffer wasn't empty, and :q! does not work as it would on the regular commit),
I had to untwine the changes manually.
On Mon, Nov 27, 2006 at 06:18:54PM -0800, Junio C Hamano wrote:
Read what I wrote again. You can explain it without talking
about index at all. I really do not think you need to break
"git commit" nor rename "update-index" to "resolve" to explain
things to new people.
I think you're both right, and talking past each other to a certain
extent. Yes, pedagogically it would be better to talk about "git
commit Makefile hello.c ..."; and "git commit -a" as a short-cut to
not have to list all of the files explicitly.
The tutorial might be better reworked not to start talking about
-a but start building small project from a newly created
hello.c, git add it, and "git commit" (the first commit), then
edit hello.c and "git commit hello.c" (the second commit).
Perhaps.
Carl was saying that the totorial should be changed to do this. I
would change "perhaps" to "DEFINITELY".
I would go further and argue that the man page for git-commit should
be changed to list the:
git commit file ...
and
git -a
alternatives first, and then talk about the index in a subsequent
paragraph (perhaps with a note that the first two usages are best for
novice users) might also be a good idea. Yes, the man page is
supposed to be a reference, but some novice users do bother to try to
learn by reading the man page (shock! horror!), and it might be good
if they don't run screaming into the night.
But hey, there's room for many distributed SCM's, and we can always
let those users use Mercurial and be happy.... (Just know that
project leaders who are worried about keeping their developer base
broad might choose Mercurial because it has a gentler learning curve
--- and that perhaps a few simple documentation changes plus some
syntatic sugar might make git much more attractive to them and to
novice git users.)
From: Daniel Barkalow <hidden> Date: 2016-08-11 20:09:53
On Tue, 28 Nov 2006, Junio C Hamano wrote:
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.
Perhaps you'd be happier if the command to commit what "git diff --cached"
shows were "git commit --cached" rather than "git commit -i"? (Or if they
were both --index; how did we miss that last September?)
It seems logical to me that "git commit" would commit the changes shown by
"git diff" (in addition to changes in the index, of course, which are so
obvious as to need no mention). I personally check with "git diff" and
commit if everything there looks good; otherwise I tweak stuff until it
does. And if there are a lot of changes, and all of those in some files
look good, but those in other files need work, I can "git update-index"
the ones I know I like so I don't have to go through them each time I'm
checking on other stuff next time.
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.
That is not so clear to me. Maybe you're putting changes into the index to
reduce the noise in "git diff", by updating everything that's
unquestionable while you examine the other stuff. I think that everything
in the index is clearly in the next commit, but it's obviously not true
that everything in the next commit is in the index (because you might not
be done updating things yet).
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.
I personally think that --amend should default to retaining the same tree,
with options available for using the index or -a or paths. Using the index
by default is just as wrong as -a; you're just more careful about it by
experience. The index holds stuff to go in the *next* commit, but --amend
generates a new version of the *previous* commit, so the logical basis for
the new previous commit is the old previous commit's tree, leaving the
index alone.
-Daniel
From: Andy Whitcroft <hidden> Date: 2016-08-11 20:14:00
Junio C Hamano wrote:
Junio C Hamano [off-list ref] writes:
quoted
Enough about "git commit -a" for tonight.
I've been playing with a "private edition" git to see how it
feels like to use "git commit" that defaults to the "-a"
behaviour, using myself as a guinea pig, for the rest of the
evening.
I for one would find this change confusing. Yes like most virgins I
found the -a being needed all the time left me with a bit of "huh, why
not turn it on by default" feeling. But as time goes by and you use git
more and start to rebase and merge and start to get those conflicts then
the index comes into focus, you can see why that 'stupid layer' is there
and its power. I am now finding myself using the index more and more as
you described as a staging ground for the 'commit in progres'.
I think the new wording in the tutorial really is a much better way
round to teach it, and would have saved me some mental movement. But
the index really is there and useful when you get beyond the trivial. I
am using git almost exclusivly in a contributer role and find it so.
my $0.02.
From: Junio C Hamano <hidden> Date: 2016-08-11 20:35:19
At the same time, stop talking about "--only" option being the
default when given paths. It has been that way for quite some
time.
This change breaks t1400 which assumed the long tradition of not
modifying index when not told to touch it with an explicit -a
nor paths, so this commit includes adjustment for it as well.
Signed-off-by: Junio C Hamano <redacted>
---
git-commit.sh | 13 ++++++-------
t/t1400-update-ref.sh | 4 ++--
2 files changed, 8 insertions(+), 9 deletions(-)
@@ -292,13 +292,12 @@ case "$#,$also,$only,$amend" in0,,t,)die"No paths with --only does not make sense.";;0,,t,t)-only_include_assumed="# Clever... amending the last one with dirty index.";;+only_include_assumed="Clever... amending the last one with dirty index.";;0,,,*)-:all=t-only_include_assumed="# We will start assuming -a without -i; you have been warned."+all=t+only_include_assumed="No -o nor -i is given; committing --all";; *,,,*)-only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."also=;;esac
@@ -542,9 +541,9 @@ thenecho"# Please enter the commit message for your changes."echo"# (Comment lines starting with '#' will not be included)"test-z"$only_include_assumed"||{-echo"#"-echo"$only_include_assumed"-echo"#"+echo"################################################"+echo"# $only_include_assumed"+echo"################################################"}run_status}>>"$GIT_DIR"/COMMIT_EDITMSG
From: Andy Whitcroft <hidden> Date: 2016-08-11 20:43:12
Salikh Zakirov wrote:
Junio C Hamano wrote:
quoted
I've been playing with a "private edition" git to see how it
feels like to use "git commit" that defaults to the "-a"
behaviour, using myself as a guinea pig, for the rest of the
evening.
Thanks a lot for the patches, Junio!
I am using them for two days, and my experience is great!
Many times it saved me annoyances of forgetting to put '-a' to 'git commit'.
It should be noted, that I mostly used 'git-commit files...'
or 'git-commit -a' forms before.
Someone said, that default '-a' does not go well with 'git-commit --amend',
and I second that. It was somewhat suprising to see that 'git commit --amend'
is going to include all of the dirty state into the commit,
and since there is no easy way to abort a --amend commit (because the comment
buffer wasn't empty, and :q! does not work as it would on the regular commit),
I had to untwine the changes manually.
If you have no commit message the commit will be aborted. So just write
back a completly empty commit message. "dG:wq" in vi land.
apw@larry:~/git/linux-2.6$ git commit --amend
* no commit message? aborting commit.
apw@larry:~/git/linux-2.6$
From: Junio C Hamano <hidden> Date: 2016-08-11 20:46:07
Carl Worth [off-list ref] writes:
quoted
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.
quoted
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.