?

Log in

January 12th, 2011


Previous Entry Share Next Entry
11:05 pm - Fun with telling stories

Somebody wrote an end-user documentation that describes this command:
$ git reset HEAD^ -- file2
and said:

This brings us into a funny state. The command does not reset HEAD, and the contents for the file2 recorded in that commit is also in the working tree, but the index records contents from an older commit. Because the copy in the working tree and the contents in the HEAD are the same, "git commit -a" will not commit any change. Worse, "git diff" will report changes to the file. In order to commit from this state, you have to "git add" the file you just reset and then run "git commit".

There is no lie in what is said in the above, but it makes me sad that new users will be taught by people who would say things like this. They may know "Doing A causes effect B", but they do not teach "For X, you want to see B" in the first place. Without knowing why you want B, a new user would not understand why being able to do A to cause B is a good thing to begin with.

By setting the stage in a more appropriate way, you can turn the "funny state" misconception into a more positive experience. For example, here is how I would tell the same story:
 
You have been working on two files, file1 and file2, and made a commit to record changes to them. But you realized that the change is better done as two commits, first commit that updates file1 with a new infrastructure, and then the second commit that records the change to use the new infrastructure in file2 on top of that. Also, you are not entirely satisfied with what you wrote in file2 yet.

For the purpose of fixing the commit you just made, i.e. step 1, you would want to amend it in such a way that it does not have any change to file2. After amending, you would want to perfect the changes you started making to file2 in your working tree, and then make another commit on top of the amended commit to record that change, which would be your step 2.

How would you perform the first step of amending the current commit, without disrupting the unfinished work you have in file2 in your working tree, so that you don't have to re-type anything to file2 while working in your step 2?

"git reset HEAD^ -- file2" is the answer. It will prepare your index so that it has the same contents as the commit you just made, except for file2, whose contents you just took from the commit before that with this "reset" command. From that state, all you have to do is to "git commit --amend" without -a option. Before amending the commit, you will see nothing in "git diff HEAD^ file2" (because you do not want the HEAD to be rewritten to have any change to that file). By running "git diff file2", you can check the progress of your unfinished change to file2 that you are not going to include in your amended, first, commit.

After amending the commit, you will further work on file2, and then "git commit -a" or "git commit file2" to conclude the second step.
 
With such an understanding of what the command is for (i.e. "why you would want to see B?  Because you want to do X"), you would never write things like "git diff still shows the changes" or "committing from this state requires you to 'git add' the file again", as if they are problems to be worked around. These remarks are true but entirely miss the point, as you would actively want "diff" to show the changes and you would never "commit -a" that state, if you know what you are doing.

Perhaps the person who wrote the above passage does not understand what "reset HEAD^ -- path" is about. But then why is he teaching new people?

And that is the saddest part. The author of the above passage is supposed to be an expert who teaches other people, and I am sure there are plenty of other similar "experts" in the field.

When it comes to teaching people, WHY and WHAT FOR is much more important part of understanding than merely knowing HOW.

At least that is what I think, and that is why my Git book (the publisher said it is now at the fourth reprint) is full of descriptions on WHY and WHAT FOR.

Current Mood: annoyedannoyed
Tags:

(3 comments | Leave a comment)

Comments:


From:(Anonymous)
Date:January 17th, 2011 07:58 am (UTC)
(Link)
I've discovered something similar in a pretty well-known git book. I actually meant to provide some technical corrections for its chapter on remote branches (which is quite buggy), but completely lost my motivation to do so when I read the section on deleting remote branches in which the author had nothing better to say than that the syntax is obtuse and that one might want to dog-ear the page.

Guess who won't recommend that book anymore (and who really should have read more of it before recommending it, instead of relying on opinions of people that were still learning git...)
[User Picture]
From:gitster
Date:January 17th, 2011 05:48 pm (UTC)

"git push there <nothing>:to-be-deleted"?

(Link)
If it is a pretty well received book, I'd ask you to reconsider and give them corrections by all means.

You'd be appreciated not just by the authors of the said book, but by the countless new people whose learning experience would otherwise be harmed by wrong information.

Among the three English books I know of, there indeed is one that has "dog-ear" in the section. Assuming that is the book you are talking about, I think that one is the easiest to get correction into. Just suggest removing the whole sentence because doing so would only improve the readability of the remaining paragraph without losing any useful information.
From:(Anonymous)
Date:April 5th, 2011 11:28 am (UTC)

Git book

(Link)
Hello,

when is your book available in english?
Thank you for your great work!

Arthur
Fun with telling stories - gitster's journal

> Recent Entries
> Archive
> Friends
> Profile

Links
Pages at the k.org
Gifts
貢ぎ物
The latest blog by Gitster

> Go to Top
LiveJournal.com