You are viewing gitster

February 25th, 2009


Previous Entry Add to Memories Share Next Entry
09:49 am - Fun with keeping local changes around
In an earlier entry, I covered how to complete a merge that failed with conflicts, but as an introduction to the entry, briefly mentioned that there are cases merge refuses to even start in order to protect your local changes.

This entry is about such safety.

Linus often performs patch applications and merges in a dirty work tree with a clean index.

A dirty work tree is where you have changes that are not added to the index.
A work tree that is not dirty is a clean work tree.

A dirty index is where you have changes already added to it (in other words, "git diff --cached" will report some changes).
A clean index matches the HEAD.

The changes typically are to the Makefile where he already has incremented the version number for the next release (lest he forget) and to the source files he recently sent out "How about doing it this way" feeler patches for (to eat his own dog food).

When you try to run "git pull" to merge with others, or to run "git am" to apply patches from others, they both first check if your index is clean, and will error out if it is not.  You will see something like this:

$ git pull
error: Entry 'hello.c' would be overwritten by merge. Cannot merge.
fatal: merging of trees 32b97a7... and da65a11... failed

Or this (for "git am")

Dirty index: cannot apply patches (dirty: hello.c)

After such a failure, git did not do anything to your work tree nor to the index.  You were simply not ready to do a merge or a patch application.

So you can first finish what you were doing.  Perhaps you were just randomly hacking and do not need any of the changes, in which case you can "git reset --hard" them away, or perhaps you wanted to commit the changes you added so far but forgot, in which case you conclude it with "git commit".  The simplest thing for those who cannot decide may be to stash the changes away for later.

$ git stash save "Random changes that are not ready"

And then redo "git pull" or "git am".  "git stash" is the ultimate tool for people who are afraid of commitment.

One caution.  After seeing that "git am" stops this way, you would need "rm -fr .git/rebase-apply".  Unfortunately "git am --abort" is broken and does not deal with this situation correctly.

After redoing "git pull" or "git am", you can replay the local changes you stashed away:

$ git stash pop

These commands also detect if the operation they perform need to touch paths that you have local modifications in.  If Linus has a change to his Makefile he has not added, but a patch he is about to apply does not touch the Makefile, there is no reason for "git am" to refuse operating (or "git pull" to create a merge).

But if a patch (or a merge) is about improving the Makefile, these commands will stop, again without touching your index nor the work tree.  You will see:

$ git pull
error: Entry 'hello.c' would be overwritten by merge. Cannot merge.
fatal: merging of trees 32b97a7... and da65a11... failed

You can deal with your local changes the same way as in the previous case.

Or (for "git am"):

$ git am 0001-patch.txt
Applying: Some change to hello.c
error: hello.c: does not match index
Patch failed at 0001 Some change to hello.c

At this point, you can save away your changes temporarily and resume the operation.

$ git stash save "Random changes that are not ready"
$ git am
$ git stash pop

Tags:

(4 comments | Leave a comment)

Comments:


From:Jakub Narębski [openid.pl]
Date:February 27th, 2009 01:49 am (UTC)

git am --abort with dirty index

(Link)
Do I remember correctly that "git am --abort" would do the right thing(TM) in the presence of dirty index?
[User Picture]
From:gitster
Date:February 27th, 2009 09:08 am (UTC)

Re: git am --abort with dirty index

(Link)
Didn't I say

Unfortunately "git am --abort" is broken and does not deal with this situation correctly.

in the entry?

From:Jakub Narębski [openid.pl]
Date:February 27th, 2009 09:46 am (UTC)

Re: git am --abort with dirty index

(Link)
I'm sorry, I didn't make myself clear: I meant that if I remember correctly this bug would be corrected in the future git releases, so workaround would be not necessary. Isn't it?
[User Picture]
From:petdance
Date:September 3rd, 2009 07:31 pm (UTC)
(Link)
Thanks very much for posting this. I'm still getting used to git, and this solved my problem.
gitster's journal - Fun with keeping local changes around

> Recent Entries
> Archive
> Friends
> User Info

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

> Go to Top
LiveJournal.com