Re: What's cooking in git.git (Mar 2010, #01; Wed, 03)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Junio C Hamano <gitster@xxxxxxxxx> writes:

> * cc/reset-keep (2010-01-19) 5 commits
>  - reset: disallow using --keep when there are unmerged entries
>  - reset: disallow "reset --keep" outside a work tree
>  - Documentation: reset: describe new "--keep" option
>  - reset: add test cases for "--keep" option
>  - reset: add option "--keep" to "git reset"
>
> I am not sure if this series is useful, and even less sure if the
> usefulness of it outweighs the confusion factor.

Regarding this, I've been thinking about how I would explain this new
feature to end users (both new ones and old timers) as a good addition.  I
still haven't reached a satisfactory explanation, but here is my "WIP" try
to describe a scenario.

I understand that in essense, "reset --keep" does exactly a "checkout
<commit>" does but without detaching the HEAD.  I often deliberately stay
on detached HEAD because I find it highly useful that I can jump around
freely with "checkout <commit>" once the head is detached (I would stay in
a detached HEAD state and keep local changes around).  I think there must
be a similar usefulness I can gain by "reset --keep".

But I am not really succeeding to explain that to potential users.

    I have built commits A, B and C on my 'topic' branch, and the contents
    in the working tree is a checkout of C (which is at the tip of the
    branch).  I can make a small improvement, and start hacking.  And then
    I realize that the change I just did, which I haven't committed nor
    even added, is an improvement to commit A.

    I could do:

        $ git checkout topic~2              ;# to detach at A
        $ git commit --amend -a             ;# to improve on A
        $ git rebase --onto HEAD @{1} topic ;# rebase the rest and come back

    to fix up A and rebuild B and C on top of it.  With "reset --keep",
    I could do this instead:

        $ last=$(git rev-parse HEAD)
        $ git reset --keep topic~2
        $ git commit --amend -a
        $ git rebase --onto HEAD @{1} @{2}  ;# rebase the reset
        $ git branch -f topic               ;# and come
        $ git checkout topic                ;# back

The above however is clearly not an improvement.

So far, the _only_ use case I can think of that "reset --keep" may be
superiour than anything existing is this:

    I have built commits A, B and C on my 'topic' branch, and the contents
    in the working tree is a checkout of C (which is at the tip of the
    branch).  I can make a small improvement, and start hacking.  And then
    I realize that the change I just did, which I haven't committed nor
    even added, is an improvement to commit A.  Also I realize that B and
    C are completely bogus, and I want to get rid of them.

    I could do:

        $ git checkout topic~2		;# to detach at A
        $ git commit --amend -a         ;# fix it
        $ git branch -f topic           ;# the rest I do not need
        $ git checkout topic	        ;# and now on the branch

    but it would be far easier if I can do this:

        $ git reset --keep topic~2
        $ git commit --amend -a

You have some addition in Documentation/git-reset.txt in this topic, and
the last example (starting at around line 350) may be describing this
situation, but it was not very clear to me.

    Keep changes in working tree while discarding some previous commits::

    Suppose you are working on something and you commit it, and then you
    continue working a bit more, but now you think that what you have in
    your working tree should be in another branch that has nothing to do
    with what you commited previously. You can start a new branch and
    reset it while keeping the changes in your work tree.

    ------------
    $ git tag start
    $ git branch branch1

I take it that this is supposed to be "checkout -b branch1".

    $ edit
    $ git commit ...                            <1>
    $ edit
    $ git branch branch2                        <2>

I take it that this is supposed to be "checkout -b branch2".

    $ git reset --keep start                    <3>
    ------------

    <1> This commits your first edits in branch1.
    <2> This creates branch2, but unfortunately it contains the previous
    commit that you don't want in this branch.
    <3> This removes the unwanted previous commit, but this keeps the
    changes in your working tree.

The above sequence is not very convincing.  After you edited the second
time, you create branch2 and that is presumably because you realized that
the change in the work tree belongs to a separate topic.  It would be a
lot more natural to do this:

    $ git tag start ;# we do not have to tag, but just to make the
                       remainder of the illustration easier to read...
    $ git checkout -b branch1
    $ edit	    ;# do the work for the first topic
    $ git commit    ;# and commit
    $ edit          ;# start working more and then realize that the
    		       change belongs to a separate topic, and the previous
                       commit is unrelated to that new topic
    $ git checkout -b branch2 start 
    $ edit          ;# continue working
    $ git commit    ;# and conclude it

so the example makes the use of "reset --keep" look artificial.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]