Daniel Barkalow [off-list ref] writes:
I sort of suspect that "git commit some_other_file" should really read
HEAD into a temporary index, update "some_other_file" in that (and the
main index), and commit it.
...
The surprising thing is that "git commit path ..." means
"everything I've already mentioned, plus path..." not just
"path ...", and it's particularly surprising because people
only tend to specify paths when they've done something they
don't want to commit.
Interesting idea, and a good point.
Not that I particularly would like to encourage people to make
partial commits by making it easier, but as long as we allow our
users to say "commit path...", your proposal would reduce the
confusion.
I wonder which is faster, to check if index differs from HEAD
and do the temporary index only when they differ, or always use
a temporary without checking? The former needs one diff-index
--cached, zero or one read-tree, one write-tree and one
commit-tree. The latter always needs one read-tree, one
write-tree and one commit-tree.
Wait. We already do diff-index --cached during git-commit
anyway (it is in git-status). Maybe with a bit of code
restructuring we can do the temporary index part optional.
On Tue, 31 Jan 2006, Junio C Hamano wrote:
Daniel Barkalow [off-list ref] writes:
quoted
I sort of suspect that "git commit some_other_file" should really read
HEAD into a temporary index, update "some_other_file" in that (and the
main index), and commit it.
...
The surprising thing is that "git commit path ..." means
"everything I've already mentioned, plus path..." not just
"path ...", and it's particularly surprising because people
only tend to specify paths when they've done something they
don't want to commit.
Interesting idea, and a good point.
One thing to be careful about is merges.
This actually happens to me:
git pull ....
.. uhhuh, trivial conflict in one file ..
.. edit the/file/that/conflicted ..
git commit the/file/that/conflicted
and there is no way that it would ever be correct to then just commit that
one file. The fact that it's a merge means that the rest of the index -
which is all from the merge, and correct - absolutely _must_ be committed
too.
And yes, I could use "git commit -a" (and I often do), but the thing is, I
surprisingly often have edits in unrelated files (stuff that the merge
never touched), and doing "git commit -a" would do the wrong thing.
So the current "git commit filename" behaviour is actually the only
possible correct one for a merge. Nothing else makes any sense
what-so-ever.
Now, I can hear people arguing that "ok, merges are special, and for
merges we always do it in the current index", but that makes "git commit
pathname" act very _differently_ for a merge than for a normal commit.
That just smells wrong to me.
So if you do this change (which may be the right one) then please make
sure that "git commit <filename>" doesn't work _at_all_ when a merge is in
progress (ie MERGE_HEAD exists), because it would do the wrong thing.
And yes, then I'll just have to force my fingers to do a simple
git-update-index filename
git commit
instead. I can do that.
Oh, one final suggestion: if you give a filename to "git commit", and you
do the new semantics which means something _different_ than "do a
git-update-index on that file and commit", then I'd really suggest that
the _old_ index for that filename should match the parent exactly.
Otherwise, you may have done a
git diff filename
and you _thought_ you were committing just a two-line thing (because you
didn't understand about the index), but another, earlier, action caused
the index to be different from the file you had in HEAD, and in reality
you're actually committing a much bigger diff.
In other words: if you want "git commit <filename>" to _not_ care about
the current index, then it should make sure that the index at least
_matches_ the current HEAD in the files mentioned.
Ie "git-diff-index --cached HEAD <filespec>" should return empty. Or
something like that.
Linus
On Tue, 31 Jan 2006, Linus Torvalds wrote:
So if you do this change (which may be the right one) then please make
sure that "git commit <filename>" doesn't work _at_all_ when a merge is in
progress (ie MERGE_HEAD exists), because it would do the wrong thing.
Agreed. I suppose it could accept doing a commit of only a few files which
weren't touched by the merge, but I don't think even you multitask enough
to want to do that; anyway, the user can just ditch the merge, commit
their stuff, and try the merge again. (I bet this is a case where new
users would be really surprised by the behavior of "git commit filename",
except that they wouldn't think it would do anything other than give an
error.)
And yes, then I'll just have to force my fingers to do a simple
git-update-index filename
git commit
instead. I can do that.
Oh, one final suggestion: if you give a filename to "git commit", and you
do the new semantics which means something _different_ than "do a
git-update-index on that file and commit", then I'd really suggest that
the _old_ index for that filename should match the parent exactly.
Otherwise, you may have done a
git diff filename
and you _thought_ you were committing just a two-line thing (because you
didn't understand about the index), but another, earlier, action caused
the index to be different from the file you had in HEAD, and in reality
you're actually committing a much bigger diff.
In other words: if you want "git commit <filename>" to _not_ care about
the current index, then it should make sure that the index at least
_matches_ the current HEAD in the files mentioned.
Ie "git-diff-index --cached HEAD <filespec>" should return empty. Or
something like that.
Agreed here, too.
-Daniel
*This .sig left intentionally blank*