Git development
 help / color / mirror / Atom feed
* Re: git blame
From: Junio C Hamano @ 2006-11-30 22:38 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Joseph Wakeling, Carl Worth
In-Reply-To: <Pine.LNX.4.63.0611302314320.30004@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Thu, 30 Nov 2006, Carl Worth wrote:
>
>> Here's a crazy idea. How about a "git tutorial" builtin or "git example" 
>> or something that would create a repository into some useful state for 
>> demonstrating something.
>
> That sounds fine! Actually, it should be very simple to turn the tutorial 
> into such a script, displaying the command with an explanation, and 
> executing the command. It could even call gitk from time to time, so the 
> user can form a mental model of the ancestor graph.

Doesn't one of our existing t/ scripts do that?

^ permalink raw reply

* Re: [RFC] git-add update with all-0 object
From: Jakub Narebski @ 2006-11-30 22:41 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0611301733460.9647@xanadu.home>

Nicolas Pitre wrote:

> On Thu, 30 Nov 2006, Daniel Barkalow wrote:
> 
>> One thing that I think is non-intuitive to a lot of users (either novice 
>> or who just don't do it much) is that it matters where in the process you 
>> do "git add <path>" if you're also changing the file. Even if you 
>> understand the index, you may not realize (or may not have internalized 
>> the fact) that what git-add does is update the index with what's there 
>> now.
> 
> And actually I think this is a good thing.  This is what makes the index 
> worth it.  Better find a way to make it obvious to people what's 
> happening.

Still, perhaps (perhaps!) it would be useful to have "intent to add"
git-add.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: git and bzr
From: Johannes Schindelin @ 2006-11-30 22:45 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: jnareb, Alan Chandler, git
In-Reply-To: <7vbqmpjlsz.fsf@assigned-by-dhcp.cox.net>

Hi,

On Thu, 30 Nov 2006, Junio C Hamano wrote:

> Somehow we ended up introducing that twisted semantics and that was 
> where --only came from, which unfortunately later became the default 
> (and I already said that I realize this was a big mistake).

If you are talking about "git commit file1 file2" ignoring the current 
index, and building a new index just updating file1 and file2 from the 
working directory, I disagree that it was a big mistake.

Actually, I was very happy to get that change (IIRC it was me requesting 
it, so blame me), because I now can say: just specify exactly what you 
want to commit *1*.

If you want to commit just file2 (even if you added file1, but did not 
commit it yet) do "git commit file2". If you want to commit all changes, 
either pass the names of all modified files, or "-a". IMHO this satisfies 
the principle of least surprise.

Ciao,
Dscho

Footnote 1: Of course, you can use commit in more ways. But this is 
sufficient to get people started.

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Nicolas Pitre @ 2006-11-30 22:46 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Carl Worth, Linus Torvalds, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <7vac28h898.fsf@assigned-by-dhcp.cox.net>

On Thu, 30 Nov 2006, Junio C Hamano wrote:

> What this will "achieve" is:
> 
>  $ git add hello.c ;# index remembers the path
>  $ git diff ;# nothing -- it sees 0{40} and 0{40} on both sides
>  $ edit hello.c
>  $ git diff ;# still nothing
>  $ git commit ;# takes the content of 'hello.c' at this point
>  
> This is a non-trivial amount of work but not a rocket science.
> It is however of a negative value that helps the users stick to
> the "filename matters more than content" mindset.

And personally I think this bastardizes the index.

I think so far the index is not a problem.  the problem is in the UI and 
in the doc.  With a "git add" as I described it I don't think the user 
will ask for such thing.

And let's have a "git diff --commit" be a much meaningful alias for the 
appropriate diff argument (which argument I always forget about myself) 
needed to show what is going to be committed.



^ permalink raw reply

* Re: [RFC] git-add update with all-0 object
From: Linus Torvalds @ 2006-11-30 22:46 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: git, Junio C Hamano
In-Reply-To: <Pine.LNX.4.64.0611301634080.20138@iabervon.org>



On Thu, 30 Nov 2006, Daniel Barkalow wrote:
> 
> I think the more obvious behavior is to have it record the fact that you 
> want to have the path tracked, but require one of the usual updating 
> mechanisms to get a particular content into the index.

While this certainly matches the git model better than just automatically 
taking whatever state exist at commit time (you instead introduce it as a 
special "empty state" case), I don't think you really want it.

Why? 

Two reasons:

 - you're still left with all the same issues (ie you do need to use "git 
   commit -a" because that is simply fundamental, and if you don't, "git 
   commit" now causes an ERROR, which is just illogical - you just added 
   the data!)

   So it's simply better to just tell people "git add" adds the whole 
   state. Explain to them that git doesn't track "filenames", it tracks 
   state, and when you do a "git add", it really adds the _data_ and the 
   permissions too.

   Really, if you didn't come from years of broken SCM's, you'd think that 
   it's _natural_ that when you add a file for tracking, you add its 
   contents too. It's not that git is surprising or unnatural, it's that 
   CVS is.

 - you generally really don't want to see "git diff" show you the big diff 
   for a new creation. You only think you do, but trust me, you generally 
   don't. It's the same thing as with doing merges - keeping the 
   automerged state in the index is actually nice, because it means that 
   the default "git diff" can just shut the heck up about the things that 
   may be the _bulk_ of the change, but it's not the interesting part.

So I would suggest that if people are irritated with "git diff" for 
example not showing newly added files AT ALL, then the solution to that 
isn't that they should be added as "empty" or "all zeroes". We do have 
other state bits in the index already (we need them for marking things as 
being unmerged etc), and if the problem is that you want to see that you 
have a pending add, it's easy enough to have "git add" always set a bit 
saying "this file is new".

A normal "read tree object" would populate index entries with that bit 
cleared, and so it would be possible to have

	git add file.c
	git diff

show something like

	diff --git a/file.c b/file.c
	added file <mode> <sha1>

rather than show the whole big diff (which I _really_ don't think you want 
to see, and which is actually against the whole point, which is that you 
add _content_ to the index, and "git diff" will always show you the stuff 
that is _not_ added to the index yet).

(Of course, if you _also_ had changed it between the "git add" and the 
"git diff", you'd get both the "added file <mode> <sha1>" _and_ the diff 
that is the diff between the thing you added, and the status it has now).

So showing a real diff after "git add" would really be wrong. The index 
really is important. But if it's _only_ an issue of worrying about seeing 
added files at all, we can add a "people comfort" bit to do that.

(Quite frankly, I don't think it's worthwhile. I really think this is a 
documentation issue. Make people understand that "git add" adds the 
contents too, and that git never tracks filenames on their own at all).

So it is always going to be true that

	git add file
	echo New line >> file
	git commit

must commit the old contents of the file. That really _does_ follow from 
the whole "track contents" model. Anything that doesn't do this is 
fundamnetally broken, and has broken the notion of what "git add" means.


^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Junio C Hamano @ 2006-11-30 22:47 UTC (permalink / raw)
  To: Carl Worth
  Cc: git, Jakub Narebski, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin
In-Reply-To: <878xhsty3t.wl%cworth@cworth.org>

Carl Worth <cworth@cworth.org> writes:

> I'm happy with the direction of having several commands that take the
> place of update-index, each with its own name oriented toward what the
> user wants to do.
>
> Obviously, "add", "mv", and "rm" have obvious places where the user
> wants to use them.
>
> There's the merge case where "resolve" and "resolved" have both been
> floated as possible names.
>
> It might even make sense to invent one more name for the case where
> the user wants to inform git that a file has been edited and that git
> should accept the new contents. It's the sort of "note that file is
> edited" operation that could be recommended to the user with "add; fix
> typo; commit" confusion.
>
> Sure, "add" could be used again, and "update-index" clearly _works_
> but it's a rather ugly name, (and already has "plumbing" functionality
> like --add and --remove that we don't want here).

checkin.

You check things into index with "git checkin" and later commit
the index with "git commit".


^ permalink raw reply

* Re: [RFC] git-add update with all-0 object
From: Nicolas Pitre @ 2006-11-30 22:49 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <eknmju$9ok$1@sea.gmane.org>

On Thu, 30 Nov 2006, Jakub Narebski wrote:

> Nicolas Pitre wrote:
> 
> > On Thu, 30 Nov 2006, Daniel Barkalow wrote:
> > 
> >> One thing that I think is non-intuitive to a lot of users (either novice 
> >> or who just don't do it much) is that it matters where in the process you 
> >> do "git add <path>" if you're also changing the file. Even if you 
> >> understand the index, you may not realize (or may not have internalized 
> >> the fact) that what git-add does is update the index with what's there 
> >> now.
> > 
> > And actually I think this is a good thing.  This is what makes the index 
> > worth it.  Better find a way to make it obvious to people what's 
> > happening.
> 
> Still, perhaps (perhaps!) it would be useful to have "intent to add"
> git-add.

Well, sure.  It could be an argument to git-add.  But surely not the 
default?

git-add --latest maybe?



^ permalink raw reply

* Re: git blame
From: Johannes Schindelin @ 2006-11-30 22:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Joseph Wakeling, Carl Worth
In-Reply-To: <7v64cwh86r.fsf@assigned-by-dhcp.cox.net>

Hi,

On Thu, 30 Nov 2006, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > On Thu, 30 Nov 2006, Carl Worth wrote:
> >
> >> Here's a crazy idea. How about a "git tutorial" builtin or "git example" 
> >> or something that would create a repository into some useful state for 
> >> demonstrating something.
> >
> > That sounds fine! Actually, it should be very simple to turn the tutorial 
> > into such a script, displaying the command with an explanation, and 
> > executing the command. It could even call gitk from time to time, so the 
> > user can form a mental model of the ancestor graph.
> 
> Doesn't one of our existing t/ scripts do that?

;-) I did not forget... t1200-tutorial.sh

But it serves a different purpose: it makes sure that we did not break the 
commands in the tutorial. (I fear that the script and the tutorial have 
diverged a little bit, though).

git-tutorial should not test that, rather it should show the user what is 
possible, and encourage playing with git.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Johannes Schindelin @ 2006-11-30 22:55 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Carl Worth, Linus Torvalds, Nicolas Pitre, Theodore Tso,
	Andreas Ericsson, git
In-Reply-To: <7vac28h898.fsf@assigned-by-dhcp.cox.net>

Hi,

On Thu, 30 Nov 2006, Junio C Hamano wrote:

> Linus Torvalds <torvalds@osdl.org> writes:
> 
> > ...
> > So yes, you very much ARE talking about CVS braindamage. The reason why
> >
> > 	git add file.c
> > 	echo New line >> file.c
> > 	git commit
> >
> > commits the _old_ content, is very much because git is ALL ABOUT THE 
> > CONTENT. It has _never_ been about filenames. And it _shouldn't_ be about 
> > filenames, because that would be BUGGY AND BROKEN.
> 
> I think this pretty much sums up and closes the current topic,
> by declaring "expecting to give behaviour consistent to the
> 'filename is what the user tells the SCM to track' mental model
> CVS instilled is a lost cause".

I think this is so important, that I vote for including this email as 
Documentation/howto/explain-why-git-is-better-than-cvs.txt

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Junio C Hamano @ 2006-11-30 23:02 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Linus Torvalds, Carl Worth, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <Pine.LNX.4.64.0611301624430.9647@xanadu.home>

Nicolas Pitre <nico@cam.org> writes:

> Wonderful! We might be converging to something then.

Yup.  And it appears that we even agree that "intent to add" is
a bad idea ;-).

>   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.

I sense that you are inviting me to argue for reverting the
other "git commit" braindead which is spelled "--only" (and
worse yet, it is the default).  I am very tempted.

>   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 be fairly palatable to 
> newbies as well.  Would only lack some enhancements to the commit 
> template and the "nothing to commit" message so the user is cued about 
> the fact that "current changeset is empty -- don't forget to 'git add' 
> modified files, or use 'git commit -a'".
>
> What do you think?

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.

^ permalink raw reply

* Re: git blame
From: Jakub Narebski @ 2006-11-30 23:08 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.63.0611302350510.30004@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin wrote:

> On Thu, 30 Nov 2006, Junio C Hamano wrote:
> 
>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> 
>>> On Thu, 30 Nov 2006, Carl Worth wrote:
>>>
>>>> Here's a crazy idea. How about a "git tutorial" builtin or "git example" 
>>>> or something that would create a repository into some useful state for 
>>>> demonstrating something.
>>>
>>> That sounds fine! Actually, it should be very simple to turn the tutorial 
>>> into such a script, displaying the command with an explanation, and 
>>> executing the command. It could even call gitk from time to time, so the 
>>> user can form a mental model of the ancestor graph.
>> 
>> Doesn't one of our existing t/ scripts do that?
> 
> ;-) I did not forget... t1200-tutorial.sh
> 
> But it serves a different purpose: it makes sure that we did not break the 
> commands in the tutorial. (I fear that the script and the tutorial have 
> diverged a little bit, though).
> 
> git-tutorial should not test that, rather it should show the user what is 
> possible, and encourage playing with git.

Something like Cogito tutorial-script?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: git and bzr
From: Junio C Hamano @ 2006-11-30 23:36 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: jnareb, Alan Chandler, git
In-Reply-To: <Pine.LNX.4.63.0611302338190.30004@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Thu, 30 Nov 2006, Junio C Hamano wrote:
>
>> Somehow we ended up introducing that twisted semantics and that was 
>> where --only came from, which unfortunately later became the default 
>> (and I already said that I realize this was a big mistake).
>
> If you are talking about "git commit file1 file2" ignoring the current 
> index, and building a new index just updating file1 and file2 from the 
> working directory, I disagree that it was a big mistake.

When I wrote that paragraph, I said:

        Much later, people from CVS background wanted to say "edit foo
        bar; git update-index bar; git commit foo" to mean "I might have
        done something to the index, but I do not want to care about it
        now -- please make a commit that includes only the changes to
        bar and I do not want the changes to foo included in the
        commit".  Somehow we ended up introducing that twisted semantics
        and that was where --only came from, which unfortunately later
        became the default (and I already said that I realize this was a
        big mistake).

But ignoring the index was not because of that command sequence,
as you reminded me in your message I am replying to.  It was to
allow this sequence, which is natural with CVS:

	$ git-checkout  ;# existing project that did not have Makefile
	$ edit hello.c  ;# to fix wording of the message
        $ edit Makefile ;# anybody who is self respecting should have one
	$ git-add Makefile ;# do not forget to add it
        $ git-commit hello.c ;# the fix is important independent of Makefile
	... then maybe the next commit is to add Makefile ...

If you view this sequence with CVS mindset, there is nothing
surprising about the commit _not_ committing Makefile in this
example.

But if you come from the school that "git-add" is about adding
"the contents (and the path, but only because content cannot be
added without the path)", and if you already understood that
"git-commit" without parameters nor options is a way to make a
commit out of the index, it certainly is counterintuitive.  

Granted, parameters and options are ways to affect what the
command does, but usually it does so by modifying and enhancing
what the command does without breaking the basic premise.  What
the --only does is quite different -- it bypasses the index
completely.

In fact, what it does is _so_ counterintuitive that I did not
even remember what the real motivation behind it was, and sent
my message with a much more implausible sequence which had an
explicit update-index (no sane person would do that).  That
should tell you something.

Remember, new peole will not stay "newbies" forever.  The
original "inclusive" semantics is a lot easier to explain once
you get what index does.  The way to introduce "index" to people
Nico proposed would not have to talk about "Ah, but there are
these two twists" if we did not make the --only the default
semantics.  What I find a big mistake is not the --only option;
the mistake is that it is the default.

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Linus Torvalds @ 2006-11-30 23:40 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Nicolas Pitre, Carl Worth, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <7vlklsfsgz.fsf@assigned-by-dhcp.cox.net>



On Thu, 30 Nov 2006, Junio C Hamano wrote:
> 
> I sense that you are inviting me to argue for reverting the
> other "git commit" braindead which is spelled "--only" (and
> worse yet, it is the default).  I am very tempted.

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"

   Sure, this is the common case, but just how painful is it to type those 
   extra few characters? And not defaulting to this is just sensible, 
   considering that "-a" really is not _that_ special, and the above two 
   cases simply aren't that unusual either. And it's just good to make 
   people have to _think_ about the fact that it commits everything that 
   have dirty.

At least for me, it turns out that the only mode I _never_ use personally 
is the "git commit -i" thing, which was actually the original behaviour, 
and which you'd think that I would encourage for that reason. But no. Of 
all the modes of "git commit", that's the one I think is the least 
important, and least interesting.

Of course, during a merge, you do need "-i" if you list files, but I think 
"-a" subsumes almost all cases (you _can_ use "-i file-list" or totally 
manually decide to have some extra edits you did that you don't want to 
commit together with the merge, but that's such a special case that I 
doubt anybody does it, so I don't think it's a big deal).

Anyway, we have "-i", and we don't force anybody to use it, so the fact 
that it's a bit odd and not that useful doesn't really matter. It 
certainly "fits" in the git commit family as another case, it's just not 
one of the important cases.


^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Andy Parkins @ 2006-12-01  0:01 UTC (permalink / raw)
  To: git
In-Reply-To: <20061130163304.GN12463MdfPADPa@greensroom.kotnet.org>

On Thursday 2006, November 30 16:33, Sven Verdoolaege wrote:
> > Well, I know what the commit is /that/ was all that was stored.  So I
>
> Then I have no idea what you are talking about.
> A commit _contains_ all the history that lead up to that commit,
> so if you have the commit, then you also have the history.

It's not so much an actual commit, as a reference to a commit in another 
repository.

Andy

-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Jakub Narebski @ 2006-12-01  0:06 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4. 64.0611301520370.3513@woody.osdl.org>

Linus Torvalds wrote:

> At least for me, it turns out that the only mode I _never_ use personally 
> is the "git commit -i" thing, which was actually the original behaviour, 
> and which you'd think that I would encourage for that reason. But no. Of 
> all the modes of "git commit", that's the one I think is the least 
> important, and least interesting.
> 
> Of course, during a merge, you do need "-i" if you list files, but I think 
> "-a" subsumes almost all cases (you _can_ use "-i file-list" or totally 
> manually decide to have some extra edits you did that you don't want to 
> commit together with the merge, but that's such a special case that I 
> doubt anybody does it, so I don't think it's a big deal).
> 
> Anyway, we have "-i", and we don't force anybody to use it, so the fact 
> that it's a bit odd and not that useful doesn't really matter. It 
> certainly "fits" in the git commit family as another case, it's just not 
> one of the important cases.

So, in short, -i is easier to explain, but is also least used. Perhaps
also because one can simply update index with <files> before git commit
instead of doing "git commit -i <files>".
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Jakub Narebski @ 2006-12-01  0:11 UTC (permalink / raw)
  To: git
In-Reply-To: <200612010001.57111.andyparkins@gmail.com>

Andy Parkins wrote:

> On Thursday 2006, November 30 16:33, Sven Verdoolaege wrote:
>>>
>>> Well, I know what the commit is /that/ was all that was stored.  So I
>>
>> Then I have no idea what you are talking about.
>> A commit _contains_ all the history that lead up to that commit,
>> so if you have the commit, then you also have the history.
> 
> It's not so much an actual commit, as a reference to a commit in another 
> repository.

Hmmm... I thought the idea was that submodule commit is available in the
object repository, be it via alternates mechanism pointing to the submodule
repository for alternate storage, or submodule being in "unrelated"
branch/tracking branch.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: [RFC] git-add update with all-0 object
From: Daniel Barkalow @ 2006-12-01  0:12 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git, Junio C Hamano
In-Reply-To: <Pine.LNX.4.64.0611301431420.3513@woody.osdl.org>

On Thu, 30 Nov 2006, Linus Torvalds wrote:

> A normal "read tree object" would populate index entries with that bit 
> cleared, and so it would be possible to have
> 
> 	git add file.c
> 	git diff
> 
> show something like
> 
> 	diff --git a/file.c b/file.c
> 	added file <mode> <sha1>
> 
> rather than show the whole big diff (which I _really_ don't think you want 
> to see, and which is actually against the whole point, which is that you 
> add _content_ to the index, and "git diff" will always show you the stuff 
> that is _not_ added to the index yet).

I'm not sure I want to see the whole added file more when diffing two 
trees, or when I do "git diff --cached" after "git update-index --add", 
than when I do "git diff" after "git add", but I'll concede that viewing 
the content of a new file as a diff is no fun. (Maybe diff-against-nothing 
for display needs work in general? It's solve the whole root commit thing, 
too.)

> (Of course, if you _also_ had changed it between the "git add" and the 
> "git diff", you'd get both the "added file <mode> <sha1>" _and_ the diff 
> that is the diff between the thing you added, and the status it has now).
> 
> So showing a real diff after "git add" would really be wrong. The index 
> really is important. But if it's _only_ an issue of worrying about seeing 
> added files at all, we can add a "people comfort" bit to do that.

This is where I think "git add" is really broken. For every other git 
command, if the command causes the index to not match HEAD, the command 
contains "index" either in the name of the command or in an option.

So, if you understand the index, and you understand git's model, but you 
don't know this one weird corner case, you will come to the conclusion 
that "git add <path>" leaves <path> such that the index matches HEAD.

Now *you* know that "git add" really is "git update-index --add", because 
you were typing the latter (well, "git update-cache --add", anyway) before 
"git add" existed at all. But for new users, and anyone who wasn't adding 
a lot of files back then, it's a surprising exception that has to be 
learned and internalized.

"git checkout" leaves the index matching HEAD or its original state.
"git commit" leaves the index matching HEAD (the new HEAD) or its original 
state.
"git reset" (all options) leaves the index matching HEAD or its original 
state.
"git pull/merge" does disrupt the index, but it also starts to prepare a 
commit based on multiple *HEAD files, and it leaves every stage of the 
index matching some *HEAD or its original state. And new users still seem 
to wonder where the merge happens, because it doesn't say "in the index".
"git apply" leaves the index alone.

"git update-index" says it works on the index.
"git apply --index" says it works on the index.

Am I missing any violations of the rule? I guess "git rm", but that's just 
for the CVS-damaged, unnecessary anyway, and it still doesn't care about 
the state of the working directory at any particular point in time. And I 
still prefer "git update-index --force-remove" as a command for that 
operation.

So it's obvious that the "add" functionality is properly called "git add 
--index", because whatever "git add" would, it would have to leave the 
index matching HEAD or its original state.

(Well, okay, '"git commit -i path" ^C', violates the rule. But I forgot 
until recently that -i stands for --include, not --index, which would make 
a reasonable expansion, too)

> (Quite frankly, I don't think it's worthwhile. I really think this is a 
> documentation issue. Make people understand that "git add" adds the 
> contents too, and that git never tracks filenames on their own at all).

I think people's model is likely to be closer to "touch" for the index, 
especially since it has no effect if the file is already in the index.

> So it is always going to be true that
> 
> 	git add file
> 	echo New line >> file
> 	git commit
> 
> must commit the old contents of the file. That really _does_ follow from 
> the whole "track contents" model. Anything that doesn't do this is 
> fundamnetally broken, and has broken the notion of what "git add" means.

"git add" doesn't *say* it changes the index, and nothing else there 
*says* it changes the index, so "git commit" there should say "nothing to 
commit", because you never did "git update-index file", either before or 
after the change, and you didn't do "git commit file" or "git commit -a". 

Just tossing the words in commands around, it's obvious that what 
"git add file" should do is mean that you can now do
"git update-index file" instead of
"git update-index --add file". Saying you shouldn't need "update-index" 
after adding a file is like saying you shouldn't need "update-index" after 
modifying a file.

But it shouldn't change my index any more than "git apply" should, because 
it doesn't say it updates the index. (Of course, it would be good to have 
"git add --index file", matching "git apply --index patch", which does 
what "git add" does now.)

Now, in order to interact correctly with reseting, checking out a 
different branch, etc, it wants to have the information in the index 
file, so there isn't a separate file with a list to lose stuff from. And 
it patterns naturally as an adjunct to the index for some things (like 
ls-files, which doesn't care at all what the content associated with 
filenames is). But that's fundamentally an implementation detail, not an 
aspect of the model.

	-Daniel

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Carl Worth @ 2006-12-01  0:13 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Junio C Hamano, Nicolas Pitre, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <Pine.LNX.4.64.0611301520370.3513@woody.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 3059 bytes --]

On Thu, 30 Nov 2006 15:40:58 -0800 (PST), Linus Torvalds wrote:
> 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

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"
really would only make things worse.

>  - "git commit" on its own:
>
>     This is for things where you prepared things earlier: notably a merge,
>     for example.

For "notably a merge", how often is this not equivalent to "commit -a"
in your view?

>     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.

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,
so both should be supported.

>  - "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.

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
case of my "add; fix typo; commit" example?

>  - "git commit -a"
>
>    Sure, this is the common case, but just how painful is it to type those
>    extra few characters?

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

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Linus Torvalds @ 2006-12-01  0:21 UTC (permalink / raw)
  To: Carl Worth
  Cc: Junio C Hamano, Nicolas Pitre, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <873b80tqvv.wl%cworth@cworth.org>



On Thu, 30 Nov 2006, Carl Worth wrote:
> >
> > So you can do
> >
> > 	echo a > file-a
> > 	echo b > file-b
> > 	git add file-a file-b
> >
> > 	git commit file-a
> 
> 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?

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

It means "commit the changes to this file".

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

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.


^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Junio C Hamano @ 2006-12-01  0:24 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Nicolas Pitre, Carl Worth, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <Pine.LNX.4.64.0611301520370.3513@woody.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> On Thu, 30 Nov 2006, Junio C Hamano wrote:
>> 
>> I sense that you are inviting me to argue for reverting the
>> other "git commit" braindead which is spelled "--only" (and
>> worse yet, it is the default).  I am very tempted.
>
> I actually really like the current defaults for "git commit".

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.

However, if you put it this way:

> 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.

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.



^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Carl Worth @ 2006-12-01  1:10 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Junio C Hamano, Nicolas Pitre, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <Pine.LNX.4.64.0611301618490.3513@woody.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 2090 bytes --]

On Thu, 30 Nov 2006 16:21:56 -0800 (PST), Linus Torvalds wrote:
> 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.

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
all. The new content of the file is still committed.

> 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.

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

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Nicolas Pitre @ 2006-12-01  1:20 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Linus Torvalds, Carl Worth, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <7vlklsfsgz.fsf@assigned-by-dhcp.cox.net>

On Thu, 30 Nov 2006, Junio C Hamano wrote:

> I sense that you are inviting me to argue for reverting the
> other "git commit" braindead which is spelled "--only" (and
> worse yet, it is the default).  I am very tempted.

No no no !

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



^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Linus Torvalds @ 2006-12-01  1:32 UTC (permalink / raw)
  To: Carl Worth
  Cc: Junio C Hamano, Nicolas Pitre, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <871wnkh142.wl%cworth@cworth.org>



On Thu, 30 Nov 2006, Carl Worth wrote:
> 
> The difference there is very subtle and really does prevent a
> reasonable, "just ignore the index and you can use git comfortably".

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

So what's your point?

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

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-view on a 
coherent guiding logic, than on "personal incredulity" or "I can't believe 
that anybody would actually ever want to do that".

As an X developer, don't you get tired of hearing people saying "I can't 
believe anybody would ever want to use a network transparent protocol and 
do graphics from another machine"? The non-X people (and every single 
"let's replace X with something more efficient" discussion) always tend to 
take that approach. 

Same thing. It really doesn't matter what you think is "normal". What 
matters a lot more in the end is that you keep a coherent set of concepts, 
so that once you really learn the concepts, it all makes sense.

And in git, the over-arching concept for just about _anything_ is "git 
tracks contents, and filenames don't matter". The behaviour of "git add" 
and "git commit" is just a small detail in that whole picture.


^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Carl Worth @ 2006-12-01  2:08 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Junio C Hamano, Nicolas Pitre, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <Pine.LNX.4.64.0611301720240.3513@woody.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 4100 bytes --]

On Thu, 30 Nov 2006 17:32:22 -0800 (PST), Linus Torvalds wrote:
>
> The old argument by incredulity. The fact that you cannot see it doesnt'
> change the fact that I use it all the time.

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
trying to discuss here.

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

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
toward helping new users do what they want to with git.

> 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".

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
than it should be.

>  - 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.

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 able to commit file-a without file-b.

So, given the following:

	echo a > file-a
	echo b > file-b
	git add file-a file-b
	echo a-not-ready-yet > file-a

How could I do both of these at once? That is, how can I commit the
_old_ version of file-a, (the only logical choice), but not commit
file-b? There's no commit command that does that is there? (I don't
think that's a fault in git since I think this would be a fairly
exceptional thing to do).

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

[I'll snip the rest, because I really do think I understand, agree
with, and accept the fundamental concepts of git.]

But as for "real usage", by far, the thing I want to do most often is
to commit the state of my files as the exist in my working tree at the
time of commit. Any time I do anything else, I'm well aware of it, and
I'm quite happy to do "special" index-manipulating commands, (taking
advantage of the fundamental, content-tracking nature of git to do
it).

I think the defaults for git-commit should reflect that aspect of real
usage. That's all.

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Linus Torvalds @ 2006-12-01  2:44 UTC (permalink / raw)
  To: Carl Worth
  Cc: Junio C Hamano, Nicolas Pitre, Theodore Tso, Andreas Ericsson,
	Johannes Schindelin, git
In-Reply-To: <87y7psfjvk.wl%cworth@cworth.org>



On Thu, 30 Nov 2006, Carl Worth wrote:
> 
> What I'm trying to say is that the _defaults_ are not well geared
> toward helping new users do what they want to with git.

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. 
It will just make it harder for people later.

> 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?

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 people should read it. It lists the conflicting filenames for a 
   reason, namely so that you can talk about what the conflicts in 
   question _were_.

[ Btw, I can't stress that last point enough. Using the "-m" flag should 
  really really REALLY be discouraged. It is almost always a horrible 
  mistake, not just because it means that you miss what git will tell you 
  about which files are getting checked in, but because it invariably 
  leads to bad single-line commit messages.

  In my personal opinion, the "-m" flag is really only good for scripts 
  and sending example git sequences to each other, ie it's there for 
  automated "do this" kind of scripting, and using it for real work should 
  be a castration offence, so that you don't perpetuate your genes.

  (I've seen _way_ too many projects where there's a lot of "update 
  version" one-liner commit messages. Damn, I can understand that in CVS, 
  where the logs are useless _anyway_, but in git it shouldn't be 
  allowed!). ]

Ok, with that rant out of the way, my _point_ is that we're actually much 
better off educating users about _why_ git is different, than trying to 
lie to them and say "it's just like CVS by default, but when you're a real 
man, we'll show you how you can rock your world".


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox