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

4 messages, 3 authors, 2016-06-15 · open the first message on its own page

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

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:48:23

Junio C Hamano [off-list ref] writes:
    $ 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.
Nah, what was I thinking.  If I rephrase your side note <2> and <3> a
little bit, everything makes sense.  Perhaps like so:

    <2> In the ideal world, you could have realized that the earlier
    commit did not belong to the new topic when you created and switched
    to branch2 (i.e. "git checkout -b branch2 start"), but nobody is
    perfect.

    <3> But you can use "reset --keep" to remove the unwanted commit after
    you switched to "branch2".

And it becomes very clear that "reset --keep" is a sensible way to recover
from this mistake.  No need to do "read-tree -m -u" followed by "reset"
anymore.

Do you think I finally understood what "reset --keep" is about?

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

From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:48:23

Junio C Hamano wrote:
Do you think I finally understood what "reset --keep" is about?
Probably. :)  Let me take the opportunity to give some examples of what
I am hoping to use it for, to see if I am crazy.
Nah, what was I thinking.  If I rephrase your side note <2> and <3> a
little bit, everything makes sense.  Perhaps like so:

    <2> In the ideal world, you could have realized that the earlier
    commit did not belong to the new topic when you created and switched
    to branch2 (i.e. "git checkout -b branch2 start"), but nobody is
    perfect.

    <3> But you can use "reset --keep" to remove the unwanted commit after
    you switched to "branch2".

And it becomes very clear that "reset --keep" is a sensible way to recover
from this mistake.  No need to do "read-tree -m -u" followed by "reset"
anymore.
Yes, this (recovery from a wrong choice of starting commit for a new
branch) makes sense.  Here are some other planned uses:

1. Helping people new to git.

A person not very familiar with git comes to me asking how to undo
the last couple of commits.  After a quick conversation, it becomes
clear that the commits in question were not pushed out to any public
repository and that this person does not feel it would be useful to
publish the problem commits.

Currently, I would have to advise such a person to use

	git reset --hard HEAD^^

I would prefer to recommend

	git reset --keep HEAD^^

because if there are uncommitted changes then it will give a "needs
update" message (right?) and I can help the person to deal with it.

2. Splitting up a huge patch.

Suppose I have a huge patch consisting of several unrelated changes
applied to the work tree but not commited.  I want to split it into
logical changes, commiting each one, and when I am done I will use a
loop reading from git rev-list to test all the resulting commits
automatically.  A workflow for this looks something like the
following:

 git checkout -b series1
 git add -p
 git commit
 git add -p
 git commit
 git checkout -b series2 appropriate-base
 git add -p
 git commit
 ...

Having 'git reset --keep' available would add some flexibility:

 * As you mentioned, reset --keep would let me recover from 'git
   checkout -b' to the wrong commit.
 * As in example 1, if some part of the patch turns out to be a
   bad idea after all, I can try to discard it.

A 'git stash' might be worth avoiding in some cases because it touches
unrelated files, which means wasted time rebuilding everything.

3. Keeping unrelated extra changes around.

Suppose I am Linus, and I keep on forgetting to update the version
number in a file named version.h or something.  So I update it in
advance as soon as I remember, but I do not commit the change or
register it in the index because it is not time yet.

Then in almost every instance when I would have normally used
'reset --hard', I should use 'reset --keep' instead.  The only
exception is when I am mean “screw it all, reset to a completely
known state”; in that case, I will have to update version.h by hand
again.

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

From: Christian Couder <hidden>
Date: 2016-06-15 22:48:23

On Friday 05 March 2010 01:49:21 Junio C Hamano wrote:
Junio C Hamano [off-list ref] writes:
quoted
    $ 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.
Nah, what was I thinking.  If I rephrase your side note <2> and <3> a
little bit, everything makes sense.  Perhaps like so:

    <2> In the ideal world, you could have realized that the earlier
    commit did not belong to the new topic when you created and switched
    to branch2 (i.e. "git checkout -b branch2 start"), but nobody is
    perfect.

    <3> But you can use "reset --keep" to remove the unwanted commit after
    you switched to "branch2".

And it becomes very clear that "reset --keep" is a sensible way to recover
from this mistake.  No need to do "read-tree -m -u" followed by "reset"
anymore.

Do you think I finally understood what "reset --keep" is about?
Yes I think so. Thanks for that.

I will rework the documentation patch according to your remarks and perhaps 
Jonathan Nieder's remarks too.

Thanks both,
Christian.

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

From: Christian Couder <hidden>
Date: 2016-06-15 22:48:23

On Friday 05 March 2010 17:25:21 Jonathan Nieder wrote:
1. Helping people new to git.

A person not very familiar with git comes to me asking how to undo
the last couple of commits.  After a quick conversation, it becomes
clear that the commits in question were not pushed out to any public
repository and that this person does not feel it would be useful to
publish the problem commits.

Currently, I would have to advise such a person to use

	git reset --hard HEAD^^

I would prefer to recommend

	git reset --keep HEAD^^

because if there are uncommitted changes then it will give a "needs
update" message (right?) and I can help the person to deal with it.
If the uncommited changes are in files that are not touched by the discarded 
commits then it will silently work and will keep your uncommited changes.
If the uncommited changes are in files touched by the discarded commits then it 
will fail with an error message like this:

error: Entry 'foo' not uptodate. Cannot merge.
fatal: Could not reset index file to revision 'HEAD^^'.

Best regards,
Christian.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help