* Piers Cawley <pdcaw...@bofh.org.uk> [2011-02-08 17:10]:
> On Mon, Feb 7, 2011 at 12:48 PM, Aristotle Pagaltzis <pagalt...@gmx.de> wrote:
> >* Philippe Bruhat (BooK) <b...@cpan.org> [2011-02-07 09:50]:
> >>> You probably want this instead:
> >>>
> >>>     git stash
> >>>     git reset --hard HEAD^
> >>>     git stash pop
> >>>
> >>> THIS is a git undo button.
> >>
> >>  --mixed
> >>
> >>      Resets the index but not the working tree (i.e., the
> >>      changed files are preserved but not marked for commit)
> >>      and reports what has not been updated. This is the
> >>      default action.
> >
> >Yeah, but I *don't* want all changed files preserved. I want
> >only the changes preserved that were made *on top* of the
> >commit, but not any changes that came from the commit itself.
>
> Err... that's what it does. Stash saves a changeset, not whole
> files. You roll back to HEAD^ and then reapply the changes.

What is what what does? OK, it looks like someone or other got
royally confused. Time for a few pictures.


Initial situation:

    HEAD^:foo.txt | HEAD:foo.txt | index:foo.txt | ./foo.txt
                  |              |               |
    foo           | foo          | foo           | foo
                  |              |               |
    bar           | bar          | bar           | bar
                  |              |               |
                  | quux         | quux          | baz
                  |              |               |
                  |              |               | quux

The current commit adds a line over the previous one, the index
reflects the current commit, and the working copy has some extra
changes on top of that. Now I want to get rid of the current
commit.


After `git reset --hard HEAD^`:

    HEAD:foo.txt | index:foo.txt | ./foo.txt
                 |               |
    foo          | foo           | foo
                 |               |
    bar          | bar           | bar

The extra change that was in the working copy is lost.



If I do `git reset --mixed HEAD^` instead:

    HEAD:foo.txt | index:foo.txt | ./foo.txt
                 |               |
    foo          | foo           | foo
                 |               |
    bar          | bar           | bar
                 |               |
                 |               | baz
                 |               |
                 |               | quux

The working copy still has the `quux` line, but it *also* has
the `baz` line that was added by the commit I wanted to throw
away. If I commit now, the spirit of the thrown-away commit will
live on.


But with `git stash ; git reset --hard HEAD^ ; git stash pop`:

    HEAD:foo.txt | index:foo.txt | ./foo.txt
                 |               |
    foo          | foo           | foo
                 |               |
    bar          | bar           | bar
                 |               |
                 |               | baz

The stuff that was originally *only* in the working copy is still
there afterwards, yet the stuff that was in the commit I threw
away is now gone from everywhere – working copy and index too.


Hopefully that clears up why I described this as a proper undo
button and why `git reset` alone is insufficient, `--mixed` or
not.

Regards,
-- 
Aristotle Pagaltzis // <http://plasmasturm.org/>

Reply via email to