threads / patch / 43062

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

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

## tl;dr

25 messages between Nov 27, 2006 and Nov 30, 2006. Diffs are folded; open one to read it.

replies: 24people: 11as markdown or json

Nicolas Pitre· Nov 27, 2006, 21:31 UTC · lore

[PATCH/RFC] "init-db" can really be just "init"

This should make first GIT impression a little less intimidating.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---

Maybe that could be a good rule of thumb to have all porcelainish commands not have any hyphen in their name, like "diff", "commit", "add", etc. ?

Show changes to 9 files +10 −6

Documentation/everyday.txt, Documentation/git-init-db.txt, Documentation/git-init.txt, Documentation/git.txt, Documentation/tutorial-2.txt, Documentation/tutorial.txt, Makefile, builtin-init-db.c, git.c

diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt
index 9677671..ee9ddee 100644
--- a/Documentation/everyday.txt
+++ b/Documentation/everyday.txt
@@ -25,7 +25,7 @@ Basic Repository[[Basic Repository]]
 
 Everybody uses these commands to maintain git repositories.
 
-  * gitlink:git-init-db[1] or gitlink:git-clone[1] to create a
+  * gitlink:git-init[1] or gitlink:git-clone[1] to create a
     new repository.
 
   * gitlink:git-fsck-objects[1] to check the repository for errors.
@@ -106,7 +106,7 @@ Use a tarball as a starting point for a new repository:
 ------------
 $ tar zxf frotz.tar.gz
 $ cd frotz
-$ git-init-db
+$ git-init
 $ git add . <1>
 $ git commit -m 'import of frotz source tree.'
 $ git tag v2.43 <2>
diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt
index ca7d09d..bc3ba14 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -74,6 +74,7 @@ Running `git-init-db` in an existing repository is safe. It will not overwrite
 things that are already there. The primary reason for rerunning `git-init-db`
 is to pick up newly added templates.
 
+Note that `git-init` is the same as `git-init-db`.
 
 
 EXAMPLES
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
new file mode 100644
index 0000000..36838c7
--- /dev/null
+++ b/Documentation/git-init.txt
@@ -0,0 +1 @@
+include::git-init-db.txt[]
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 619d656..5501ae0 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -347,6 +347,7 @@ gitlink:git-hash-object[1]::
 gitlink:git-index-pack[1]::
 	Build pack idx file for an existing packed archive.
 
+gitlink:git-init[1]::
 gitlink:git-init-db[1]::
 	Creates an empty git object database, or reinitialize an
 	existing one.
diff --git a/Documentation/tutorial-2.txt b/Documentation/tutorial-2.txt
index 6389de5..13a1878 100644
--- a/Documentation/tutorial-2.txt
+++ b/Documentation/tutorial-2.txt
@@ -17,7 +17,7 @@ Let's start a new project and create a small amount of history:
 ------------------------------------------------
 $ mkdir test-project
 $ cd test-project
-$ git init-db
+$ git init
 defaulting to local storage area
 $ echo 'hello world' > file.txt
 $ git add .
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index 35af81a..978d4bd 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -20,7 +20,7 @@ can place it under git revision control as follows.
 ------------------------------------------------
 $ tar xzf project.tar.gz
 $ cd project
-$ git init-db
+$ git init
 ------------------------------------------------
 
 Git will reply
diff --git a/Makefile b/Makefile
index e547e2a..c307324 100644
--- a/Makefile
+++ b/Makefile
@@ -203,7 +203,7 @@ EXTRA_PROGRAMS =
 
 BUILT_INS = \
 	git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
-	git-get-tar-commit-id$X \
+	git-get-tar-commit-id$X git-init$X \
 	$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
 
 # what 'all' will build and 'install' will install, in gitexecdir
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 235a0ee..408b51a 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -242,7 +242,7 @@ static void create_default_files(const char *git_dir, const char *template_path)
 }
 
 static const char init_db_usage[] =
-"git-init-db [--template=<template-directory>] [--shared]";
+"git-init [--template=<template-directory>] [--shared]";
 
 /*
  * If you want to, you can share the DB area with any number of branches.
diff --git a/git.c b/git.c
index f97de60..5ae5afc 100644
--- a/git.c
+++ b/git.c
@@ -241,6 +241,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
 		{ "get-tar-commit-id", cmd_get_tar_commit_id },
 		{ "grep", cmd_grep, RUN_SETUP },
 		{ "help", cmd_help },
+		{ "init", cmd_init_db },
 		{ "init-db", cmd_init_db },
 		{ "log", cmd_log, RUN_SETUP | USE_PAGER },
Junio C Hamano· Nov 27, 2006, 22:05 UTC · re: Nicolas Pitre · lore

Re: [PATCH/RFC] "init-db" can really be just "init"

Nicolas Pitre <nico@cam.org> writes:
> This should make first GIT impression a little less intimidating.
>
> Signed-off-by: Nicolas Pitre <nico@cam.org>

I was not sure about this for quite some time, thinking that it might make sense to default the behaviour of init-db for bare repositories and give init as a user-level wrapper to drive init-db to add customization suitable for repositories with working trees. List?

> Maybe that could be a good rule of thumb to have all porcelainish 
> commands not have any hyphen in their name, like "diff", "commit", 
> "add", etc. ?

I was also hoping that would become the case except verify-tag, cherry-pick, and format-patch. Also I was wondering if it would make sense to give two dashes to the back-end ones that never get invoked by the end users directly (e.g. merge--recursive, upload--pack) but thought it was too ugly.

Carl Worth· Nov 27, 2006, 22:40 UTC · re: Junio C Hamano · lore

Hyphens and hiding core commands (was: "init-db" can really be just "init")

On Mon, 27 Nov 2006 14:05:27 -0800, Junio C Hamano wrote:
> > Maybe that could be a good rule of thumb to have all porcelainish
> > commands not have any hyphen in their name, like "diff", "commit",
> > "add", etc. ?

I like the proposed rule-of-thumb very much. (Particularly if "update-index" could be included on the list of things to eliminate, in favor of a new "git resolve" for resolving merges.)

There's another rule-of-thumb I would like to propose that's a bit harder to state, but I think is just as important (if not more):

	For introductory documentation it should never make sense to
	introduce a command with specific command-line options before
	the same command without options.

As examples, both "commit -a" and "cat-file -p" fail that test and both appear in the git tutorial here:

	http://www.kernel.org/pub/software/scm/git/docs/tutorial.html
My proposals to fix those two are:
commit -a
   Change "commit" to commit the working tree. The current "commit
   index" option would be made available with a new "-i" or "--index"
   option, which could easily be made the default in a config file for
   any users that always want it. For merging, commit would also use
   the working tree, but would balk at any unmerged paths in the
   index, (which would have to be fixed with "git resolve" first).
cat-file -p
   Add new "cat" command with the functionality of "cat-file -p",
   (also succeeds in removing a hyphenated command from the
   tutorial).
> I was also hoping that would become the case except verify-tag,
> cherry-pick, and format-patch.
Here are some none-too-considered options for even cleaning up those:
verify-tag
   A new "git verify" which would accept any object specifier and do a
   restricted fsck on it, or a tag verification. Of course, the output
   should clearly indicate whether a signed-tag had been verified or
   just a tree object. [Perhaps the semantic mixing of signature
   verification and object integrity verification makes this a bad
   idea. I don't know.]
cherry-pick
   The name "cherry" is promising, but problematic in that it's
   already used for another command, (which is definitely at a
   lower-level in functionality, so would violate the rule-of-thumb
   being considered here).
format-patch
   I mentioned before that I'd like to see "export" and "import" as
   commands to replace the functionality of "format-patch" and
   "am". [These new names suggest something slightly different than
   formatting a patch for mailing and applying an email message, and
   perhaps even that difference should be taken advantage of.]
>                       Also I was wondering if it would
> make sense to give two dashes to the back-end ones that never
> get invoked by the end users directly (e.g. merge--recursive,
> upload--pack) but thought it was too ugly.

If you're willing to consider breaking backwards compatibility for these, why not hide them even further? An idea I just had that would hide them quite well would be to tuck them away as sub-commands of a new "core" command. That is:

	git core merge-recursive
	git core http-fetch
	etc.

That would bury these away from tab-completion of "git-" and even "git " with the completion scripts. It would still leave them available with "git core " with the completion scripts of course.

It would also make things much more clear if these commands ever slipped into an introductory tutorial, etc.

-Carl
Junio C Hamano· Nov 27, 2006, 23:59 UTC · re: Carl Worth · lore

Re: Hyphens and hiding core commands

Carl Worth <cworth@cworth.org> writes:
Show 6 quoted lines
> There's another rule-of-thumb I would like to propose that's a bit
> harder to state, but I think is just as important (if not more):
>
> 	For introductory documentation it should never make sense to
> 	introduce a command with specific command-line options before
> 	the same command without options.

I tend to disagree. "This is the easiest way to use, even for beginners" and "this way should be the default for all levels of users" are quite different.

Show 6 quoted lines
> As examples, both "commit -a" and "cat-file -p" fail that test and
> both appear in the git tutorial here:
>
> 	http://www.kernel.org/pub/software/scm/git/docs/tutorial.html
>
> My proposals to fix those two are:

Creating a "git cat" and promote that in the Tutorial makes a lot of sense, but then that can easily be done with aliases ;-). cat-file is plumbing. We did not even have '-p' and you needed to _know_ the type of stuff you are feeding and we had '-t' to help you do so. '-p' was done as a quick hack because showing the representation of any object in semi human readable way was not all that important but occasionally people found it useful, and it just was an easy thing to do inside cat-file. Nobody bothered to do a real Porcelain called "git cat" for that purpose, so far, but that is probably what should have been. On the other hand, if "cat-file -p" needs to be used often, I think there is something ELSE that is wrong.

I do not think defaulting to "commit -a" is a fix; rather, it feels exactly what Linus was talking about when he said about "second system syndrome".

I would not mind if you created "commit-easy" (just like curl library has curl_x_easy), but the current way the command works is more useful once you grok the index. Being able to work in a slightly dirty tree and commit only the necessary things, and being able to do so even for a merge commit, is damn convenient.

Because there is a learning curve involved, an easier way to use git without worrying about the index was added in the form of '-a' for beginners. People who use index regularly should not be forced to spend extra keystrokes for the rest of their lives only because you want to lose '-a' from the tutorial document. The tool should be designed for regular users, not for the first few pages of the tutorial.

Carl Worth· Nov 28, 2006, 00:23 UTC · re: Junio C Hamano · lore

Re: Hyphens and hiding core commands

On Mon, 27 Nov 2006 15:59:17 -0800, Junio C Hamano wrote:
>
> I tend to disagree.  "This is the easiest way to use, even for
> beginners" and "this way should be the default for all levels of
> users" are quite different.

I'll gladly agree that different defaults make sense for different users. Fortunately, we have a config file syntax that allows advanced users to select the defaults they prefer. But, what should be obvious is that the config file is not an option available for reducing the learning curve of git.

> Creating a "git cat" and promote that in the Tutorial makes a
> lot of sense, but then that can easily be done with aliases ;-).
...
> On the other hand, if "cat-file -p" needs to be used often, I think
> there is something ELSE that is wrong.

Sure. I don't think "cat-file -p" is any big problem. I only mention it because it _is_ mentioned in the git tutorial. So, let's add "git cat" or else find some other way to address what the tutorial is trying to demonstrate there.

> I would not mind if you created "commit-easy" (just like curl
> library has curl_x_easy),
Are you really serious about that? I think that's an awful idea.

Interfaces that give longer names to the simpler functionality are really broken. There are plenty of examples of this kind of thing, (XCreateWindow and XCreateSimpleWindow), but their existence in no way justifies this as a good thing.

The git commit syntax already suffers from this, ("commit -a" being a longer name than its conceptually more complex cousin, "commit"), so "commit-easy" would only make that problem worse.

>                           but the current way the command works
> is more useful once you grok the index.  Being able to work in a
> slightly dirty tree and commit only the necessary things, and
> being able to do so even for a merge commit, is damn convenient.

Sure. You don't need to convert me to that idea. I use that mode regularly, (though probably not more often than when committing an index that happens to match my working tree). But my proposal doesn't remove this functionality at all.

> Because there is a learning curve involved, an easier way to use
> git without worrying about the index was added in the form of
> '-a' for beginners.

Yes, there is a learning curve. There's the "once you grok the index" stuff you just mentioned. And it's really backwards to have to teach people that the "basic" way to do something is with a command line that looks more complex, ("commit -a"), and that "once you learn more you'll understand what that -a is all about and you'll know when not to use it".

I've taught lots of people how to use git like that, and it's really awkward. It would be much easier if learning new concepts and learning new command-line options were correlated. That would allow whole concepts to be dropped from the most basic introductions to git.

>                      People who use index regularly should not
> be forced to spend extra keystrokes for the rest of their lives
> only because you want to lose '-a' from the tutorial document.

You said yourself in the "cat-file -p" case, that can be done with aliases. No extra keystrokes are needed.

And many potential users who are evaluating git compared to other systems _do_ currently see something that will cost them extra keystrokes for the rest of their lives. And that is being used as part of the argument against git in some cases.

Now, maybe that's not the real reason people are rejecting git, but it sure would be a nice excuse to remove from the potential list of objections.

> The tool should be designed for regular users, not for the first
> few pages of the tutorial.

I'm not proposing eliminating the index or anything here. I really don't see how the default of this one command has any impact at all on the design of git. It's all still there.

-Carl
Junio C Hamano· Nov 28, 2006, 00:42 UTC · re: Carl Worth · lore

Re: Hyphens and hiding core commands

Carl Worth <cworth@cworth.org> writes:
Show 6 quoted lines
> Yes, there is a learning curve. There's the "once you grok the index"
> stuff you just mentioned. And it's really backwards to have to teach
> people that the "basic" way to do something is with a command line
> that looks more complex, ("commit -a"), and that "once you learn more
> you'll understand what that -a is all about and you'll know when not
> to use it".
I think you are teaching backwards.  Couldn't you start like this?
	"git commit" takes the list of paths you want to commit.
	Editing hello.c and saying "git commit hello.c" would
	commit your changes to hello.c.  It is cumbersome to
	list everything when your edit is all over the place,
	and in such a case you can say "git commit -a" to mean
	"everything I changed".

Later you can enhance that experience by teaching them index, saying:

	You might want to tell git that your change to this file
	is more or less complete, even when you are not ready to
	commit the whole thing.  You could use update-index to
	mark them and then later say "git commit" will make a
	commit from the state you used update-index on, without
	having you list them on the command line.  When you do
	this, the commit template would list three classes of
	files and here are what they mean...
Carl Worth· Nov 28, 2006, 01:35 UTC · re: Junio C Hamano · lore

Re: Hyphens and hiding core commands

On Mon, 27 Nov 2006 16:42:14 -0800, Junio C Hamano wrote:
> I think you are teaching backwards.  Couldn't you start like this?
>
> 	"git commit" takes the list of paths you want to commit.
I've always started teaching with:
	git init-db
	git add file
	git commit -m "Initial commit"
	# edit file
	git commit -a -m "edit file"

And at that point I've either apologized about "-a" or been asked a question about it. Every time.

But it's the tutorial we were talking about:
	http://www.kernel.org/pub/software/scm/git/docs/tutorial.html

That has 6 examples of commit being used, and all of them are with "commit -a". What "git commit" does without -a must certainly be a question in the mind of any reader, (the tutorial doesn't mention anything).

And unlike when I'm teaching in person, when the reader reads the tutorial, there's no person to explain the situation. The reader might just remain confused, or they might consult the documentation for git-commit and find a first sentence that says:

       Updates the index file for given paths, or all modified files
       if -a is specified, and makes a commit object.

And then we're back to the question of "what the heck is an index, and why do I care?".

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. This would be a good thing. I don't think we have any introductory documentation that introduces the index until the "core tutorial" and my goal here is to allow an introduction to using git that doesn't require that level of detail.

One of the arguments I got here on the git mailing list when I first brought up these kinds of "hide the index" proposals, (back in February or so), was that the index is essential to understand for merging anyway, and that I should just teach it early on.

I've tried the "teach it early" approach in the months since and found it to be largely a failure. Most new users react by deciding that git is more complicated than other systems, or that it's more specialized or not targeted at someone with their needs.

As for merging, I'd rather introduce the new "git resolve" syntax so that merging could be explained in terms of the working tree without having to fully understand the index either.

If we could fix "git commit" and add "git resolve" I think we would most of the confusion/complaints that I've encountered in 8 months of teaching git. There would still be some aspects of "git diff" that are potentially confusing without understanding the index, but that's been much less of a problem than "commit -a" in my experience.

-Carl
Junio C Hamano· Nov 28, 2006, 02:18 UTC · re: Carl Worth · lore

Re: Hyphens and hiding core commands

Carl Worth <cworth@cworth.org> writes:
Show 5 quoted lines
> On Mon, 27 Nov 2006 16:42:14 -0800, Junio C Hamano wrote:
>> 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.
Junio C Hamano· Nov 28, 2006, 06:59 UTC · re: Junio C Hamano · lore

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

Junio C Hamano <junkio@cox.net> 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.

Andy Whitcroft· Nov 28, 2006, 10:26 UTC · re: Junio C Hamano · lore
Junio C Hamano wrote:
Show 8 quoted lines
> Junio C Hamano <junkio@cox.net> 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.

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.
Josef Weidendorfer· Nov 28, 2006, 13:00 UTC · re: Junio C Hamano · lore
On Tuesday 28 November 2006 07:59, Junio C Hamano wrote:
Show 7 quoted lines
> 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.

Jakub Narebski· Nov 28, 2006, 13:23 UTC · re: Josef Weidendorfer · lore
Josef Weidendorfer wrote:
Show 19 quoted lines
> 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 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
Carl Worth· Nov 28, 2006, 18:18 UTC · re: Junio C Hamano · lore
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.

Show 8 quoted lines
> 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.

Show 7 quoted lines
> 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).

Show 7 quoted lines
> 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.

Show 5 quoted lines
> 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
Salikh Zakirov· Nov 30, 2006, 12:23 UTC · re: Junio C Hamano · lore
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 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.

Jakub Narebski· Nov 30, 2006, 13:16 UTC · re: Salikh Zakirov · lore
Salikh Zakirov wrote:
Show 6 quoted lines
> 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
Seth Falcon· Nov 30, 2006, 15:15 UTC · re: Jakub Narebski · lore
Jakub Narebski <jnareb@gmail.com> writes:
Show 11 quoted lines
> 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.

For those using emacsclient, I don't think ^C will work. Is there another way to undu an ammend commit? If not, is there any sense in

Nguyen Thai Ngoc Duy· Nov 30, 2006, 15:50 UTC · re: Seth Falcon · lore
On 11/30/06, Seth Falcon <sethfalcon@gmail.com> wrote:
>
> For those using emacsclient, I don't think ^C will work.  Is there
> another way to undu an ammend commit?  If not, is there any sense in
> detecting a magic comment to abort the ammend commit?
Uncomment to abort commit would be more intuitive.
Seth Falcon· Nov 30, 2006, 16:03 UTC · re: Nguyen Thai Ngoc Duy · lore
"Nguyen Thai Ngoc Duy" <pclouds@gmail.com> writes:
Show 7 quoted lines
> On 11/30/06, Seth Falcon <sethfalcon@gmail.com> wrote:
>>
>> For those using emacsclient, I don't think ^C will work.  Is there
>> another way to undu an ammend commit?  If not, is there any sense in
>> detecting a magic comment to abort the ammend commit?
>
> Uncomment to abort commit would be more intuitive.
Jakub Narebski· Nov 30, 2006, 16:05 UTC · re: Seth Falcon · lore
Seth Falcon wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
Show 6 quoted lines
>> 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.
> 
> For those using emacsclient, I don't think ^C will work.  Is there
> another way to undo an amended commit?  If not, is there any sense in
> detecting a magic comment to abort the ammend commit?
You can ^C the git-commit invocation.

And I guess ORIG_HEAD would help, and reflog certainly would help reverting (undoing) amend of a commit.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Andy Whitcroft· Nov 30, 2006, 17:13 UTC · re: Salikh Zakirov · lore
Salikh Zakirov wrote:
Show 20 quoted lines
> 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 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$
Junio C Hamano· Nov 28, 2006, 07:00 UTC · re: Junio C Hamano · lore

[PATCH 1/2] git-commit: prepare to make '-a' behaviour the default.

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 <junkio@cox.net>
---
 git-commit.sh |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)
Show changes to git-commit.sh +18 −12
diff --git a/git-commit.sh b/git-commit.sh
index 81c3a0c..6c95817 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -11,10 +11,10 @@ git-rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
 branch=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD)
 
 case "$0" in
-*status)
+*status|*status.sh)
 	status_only=t
 	unmerged_ok_if_status=--unmerged ;;
-*commit)
+*commit|*commit.sh)
 	status_only=
 	unmerged_ok_if_status= ;;
 esac
@@ -287,11 +287,15 @@ esac
 case "$#,$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
 
 ################################################################
@@ -317,8 +319,8 @@ then
 	TOP=./
 fi
 
-case "$all,$also" in
-t,)
+case "$all,$also,$#" in
+t,,*)
 	save_index &&
 	(
 		cd "$TOP"
@@ -328,7 +330,7 @@ t,)
 		git-update-index --remove -z --stdin
 	)
 	;;
-,t)
+,t,[1-9]*)
 	save_index &&
 	git-ls-files --error-unmatch -- "$@" >/dev/null || exit
 
@@ -340,7 +342,7 @@ t,)
 		git-update-index --remove -z --stdin
 	)
 	;;
-,)
+,,* | ,t,0)
 	case "$#" in
 	0)
 		;; # commit as-is
@@ -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_status
 	exit $?
 esac
@@ -539,7 +541,11 @@ then
 		echo ""
 		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_EDITMSG
 else
-- 
1.4.4.1.gcee8-dirty
Junio C Hamano· Nov 28, 2006, 07:00 UTC · re: Junio C Hamano · lore

[PATCH 2/2] git-commit: make '-a' the default.

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 <junkio@cox.net>
---
 git-commit.sh         |   13 ++++++-------
 t/t1400-update-ref.sh |    4 ++--
 2 files changed, 8 insertions(+), 9 deletions(-)
Show changes to 2 files +8 −9

git-commit.sh, t/t1400-update-ref.sh

diff --git a/git-commit.sh b/git-commit.sh
index 6c95817..655340c 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -292,13 +292,12 @@ case "$#,$also,$only,$amend" in
 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." ;;
+	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 @@ then
 		echo "# 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
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 6a917f2..1580224 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -200,13 +200,13 @@ test_expect_success \
 	 h_OTHER=$(git-rev-parse --verify HEAD) &&
 	 echo FIXED >F &&
 	 GIT_AUTHOR_DATE="2005-05-26 23:44" \
-	 GIT_COMMITTER_DATE="2005-05-26 23:44" git-commit --amend &&
+	 GIT_COMMITTER_DATE="2005-05-26 23:44" git-commit --amend -i &&
 	 h_FIXED=$(git-rev-parse --verify HEAD) &&
 	 echo TEST+FIXED >F &&
 	 echo Merged initial commit and a later commit. >M &&
 	 echo $h_TEST >.git/MERGE_HEAD &&
 	 GIT_AUTHOR_DATE="2005-05-26 23:45" \
-	 GIT_COMMITTER_DATE="2005-05-26 23:45" git-commit -F M &&
+	 GIT_COMMITTER_DATE="2005-05-26 23:45" git-commit -F M -i &&
 	 h_MERGED=$(git-rev-parse --verify HEAD)
 	 rm -f M'
 
-- 
1.4.4.1.gcee8-dirty
Jakub Narebski· Nov 28, 2006, 09:09 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/2] git-commit: make '-a' the default.

Junio C Hamano wrote:
Show 7 quoted lines
> 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
Johannes Schindelin· Nov 27, 2006, 23:36 UTC · re: Junio C Hamano · lore

Re: [PATCH/RFC] "init-db" can really be just "init"

Hi,
On Mon, 27 Nov 2006, Junio C Hamano wrote:
Show 8 quoted lines
> Nicolas Pitre <nico@cam.org> writes:
> 
> > Maybe that could be a good rule of thumb to have all porcelainish 
> > commands not have any hyphen in their name, like "diff", "commit", 
> > "add", etc. ?
> 
> I was also hoping that would become the case except verify-tag,
> cherry-pick, and format-patch.

I agree it might make a good rule-of-thumb, but let's not be overzealous. I have yet to see any better names for those three either, let alone better names without a hyphen.

> Also I was wondering if it would make sense to give two dashes to the 
> back-end ones that never get invoked by the end users directly (e.g. 
> merge--recursive, upload--pack) but thought it was too ugly.
I think it would appeal mostly to our friends, the monotone users...

Ciao, Dscho

Han-Wen Nienhuys· Nov 28, 2006, 10:45 UTC · re: Junio C Hamano · lore

Re: [PATCH/RFC] "init-db" can really be just "init"

Junio C Hamano escreveu:
Show 5 quoted lines
> I was not sure about this for quite some time, thinking that it
> might make sense to default the behaviour of init-db for bare
> repositories and give init as a user-level wrapper to drive
> init-db to add customization suitable for repositories with
> working trees.  List?
wouldn't using --bare be more consistent for bare repos?
Show 6 quoted lines
>> Maybe that could be a good rule of thumb to have all porcelainish 
>> commands not have any hyphen in their name, like "diff", "commit", 
>> "add", etc. ?
> 
> I was also hoping that would become the case except verify-tag,
> cherry-pick, and format-patch.  
why not shorten them to "pick" and "verify"?

← back to recent threads