threads / discuss / 29005

Proposal: create meaningful aliases for git reset's hard/soft/mixed

Subject: Proposal: create meaningful aliases for git reset's hard/soft/mixed

## tl;dr

22 messages between Nov 23, 2011 and Dec 18, 2012.

replies: 21people: 10as markdown or json

Philippe Vaucher· Nov 23, 2011, 08:28 UTC · lore
Hello,

A lot of time when I want to use reset for smth else than "--hard" I have to go and look the documentation. I think the modes could be improved by creating new aliases like this:

Optional: a new mode would be introduced for consistency:
--worktree (or maybe --tree): only updates the worktree but not the index

Then the existing mode could be aliased like this: --mixed would be aliased as --index --hard would be aliased as --all --soft could be aliased as --no-changes

Additionally: --merge could be removed in favor of an additional --preserve-staged flag --keep could be removed in favor of an additional --safe flag

So if I recap my ideas:

"I want to discard my changes" --> git reset --all HEAD^ "I want to discard the last commit" --> git reset --index HEAD^ "I want to discard the last commit, but let's be safe in case I forgot about a modified file" --> git reset --all --safe HEAD^ "I want to discard the last commit, keep my current staged changes" --> git reset --all --preserve-staged HEAD^

Philippe
Matthieu Moy· Nov 23, 2011, 08:49 UTC · re: Philippe Vaucher · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

Philippe Vaucher <philippe.vaucher@gmail.com> writes:
> A lot of time when I want to use reset for smth else than "--hard" I
> have to go and look the documentation.

I have to agree with this, I took a lot of time to understand/memorize the meaning of reset options.

> Optional: a new mode would be introduced for consistency:
> --worktree (or maybe --tree): only updates the worktree but not the index
That would be an alias for "git checkout <rev> -- path", right?

I don't really like this "there is more than one way to do it" in Git's command-line, I think we should think very carefully before introducing yet another instance of it.

> --keep could be removed in favor of an additional --safe flag

If you are to change the option names, then you should also make the behavior safe by default:

* "git reset --all" = "git reset --keep"
* "git reset --all --force" = "git reset --hard"

With the current terminology, --hard has the advantage that it makes it realatively clear how dangerous it is. Still, I've seen users losing data because they did a "git reset --hard" with uncommited changes. Git is safe by default most of the time, and "git reset --hard" is one unfortunate exception (because it was there before --keep, people are more used to it).

"git reset --all" would make it worse, because the option name is less scary, people would be less reluctant to use it, and would get more chance to lose data.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Philippe Vaucher· Nov 23, 2011, 11:32 UTC · re: Matthieu Moy · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

>> Optional: a new mode would be introduced for consistency:
>> --worktree (or maybe --tree): only updates the worktree but not the index
>
> That would be an alias for "git checkout <rev> -- path", right?

Hum... yeah probably, what motivated me was that there's a way to reset the index and not the worktree, but there's no way to reset the worktree but not the index. I guess it's "checkout" as you pointed out.

Show 7 quoted lines
>> --keep could be removed in favor of an additional --safe flag
>
> If you are to change the option names, then you should also make the
> behavior safe by default:
>
> * "git reset --all" = "git reset --keep"
> * "git reset --all --force" = "git reset --hard"
Yes that's actually much better. Let's change my proposal to that.
Philippe
Martin von Zweigbergk· Dec 18, 2012, 06:24 UTC · re: Matthieu Moy · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Wed, Nov 23, 2011 at 12:49 AM, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote:

Show 6 quoted lines
> Philippe Vaucher <philippe.vaucher@gmail.com> writes:
>
>> Optional: a new mode would be introduced for consistency:
>> --worktree (or maybe --tree): only updates the worktree but not the index
>
> That would be an alias for "git checkout <rev> -- path", right?

Not quite, in two ways, I think. First, it _would_ update the index, wouldn't it? Second, "git checkout <rev> -- path" doesn't delete files that are deleted in <rev> as compared to head.

I'm considering implementing support for an operation that would do what I expected "git checkout <rev> -- <path>" and "git reset --hard <rev> -- <path>" to do. I'm currently planning for it to be exactly "git reset --hard <rev> -- <path>" (which is currently simply not allowed), but perhaps it would be more natural as an option to checkout (--also-deleted or something)?

Nguyen Thai Ngoc Duy· Nov 23, 2011, 12:02 UTC · re: Philippe Vaucher · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Wed, Nov 23, 2011 at 3:28 PM, Philippe Vaucher <philippe.vaucher@gmail.com> wrote:

> Hello,
>
> A lot of time when I want to use reset for smth else than "--hard" I
> have to go and look the documentation.
May be related: http://thread.gmane.org/gmane.comp.version-control.git/170266
-- 
Duy
Junio C Hamano· Nov 23, 2011, 18:51 UTC · re: Philippe Vaucher · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

Philippe Vaucher <philippe.vaucher@gmail.com> writes:
> So if I recap my ideas:
>
> "I want to discard my changes" --> git reset --all HEAD^
That is discarding your changes and also the last commit.
> "I want to discard the last commit" --> git reset --index HEAD^

I do not think this has a clear meaning. "discard the last commit but leave the contents in the working tree. I do not care a newly added files are forgotten by the index, I'll remember to re-add them if I need to" is what you are saying here, but the word "index" does not hint it. When used as an option name, "--index" means "this command usually works on or touches working tree but for this invocation please also affect the index"; "please look at or affect _only_ the index" is usually spelled "--cached".

In any case, I think your proposal makes it even worse than the current state, and you should aim higher. Some modes of "git reset" have historical reasoning behind their behaviour that cannot be dismissed easily by somebody who does not understand them, but at the same time some of them outlived their usefulness and we may want to start thinking about deprecating them. The first step might be to make them less prominent in the documentation.

I am guilty of introducing "git reset --soft HEAD^" before I invented "commit --amend" during v1.3.0 timeframe to solve the issue "soft" reset originally wanted to. Even though the whole point of the "reset" command is about "resetting the index", it is an unfortunate oddball that does not touch the index. It shouldn't have been part of the "reset" command, and if we were doing Git from scratch today, we probably wouldn't have it there. What it does is sometimes useful in interactive use and often useful in scripting, but scripts can use update-ref.

"git reset --hard HEAD" is an unambiguously descriptive good name for the option. It is a "hard reset" like power cycling a machinery to discard anything in progress and get back to a clean slate. I do not see anything confusing with this mode nor its name.

"git reset --keep" was introduced at 9bc454d (reset: add option "--keep" to "git reset", 2010-01-19) as a short-hand to run something like this.

    git checkout -B $current_branch $target_commit

If we made the above command line to work (it errors out saying you cannot update the current branch) instead of adding it a new mode to "reset", it would have been much easier to understand what the particular operation does. You are updating the tip of the branch that happens to be the current branch to a different commit while carrying the local change with you.

It also would have made number of options "reset" has smaller by one and reducing confusion. What it does is too similar to what "reset --merge" does, which only adds to the confusion.

Philippe Vaucher· Nov 23, 2011, 23:00 UTC · re: Junio C Hamano · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

>> "I want to discard my changes" --> git reset --all HEAD^
>
> That is discarding your changes and also the last commit.
Yes, of course.
Show 9 quoted lines
>> "I want to discard the last commit" --> git reset --index HEAD^
>
> I do not think this has a clear meaning. "discard the last commit but
> leave the contents in the working tree. I do not care a newly added files
> are forgotten by the index, I'll remember to re-add them if I need to" is
> what you are saying here, but the word "index" does not hint it.  When
> used as an option name, "--index" means "this command usually works on or
> touches working tree but for this invocation please also affect the index";
> "please look at or affect _only_ the index" is usually spelled "--cached".

Well, it's certainly a bit more descriptive and easy to remember than "--mixed". I understand it could confuse people because of the other commands, but maybe something like "--index-only"?

> In any case, I think your proposal makes it even worse than the current
> state, and you should aim higher.

Why worse? I'd understand if you said it's doesn't improve it enough for it to be worth the change tho. Anyway, my proposal was to get a discussion going, and I'm all for aiming higher if there's a way. What do you propose instead? You seemed to imply we'd remove --soft and --merge, and make --keep as an option for --hard but named differently, something like --keep-changes. Maybe I didn't fully understand.

Mathieu even suggested that it'd have the behavior of --keep by default, and that you have to add --force to get today's --hard behavior, which sounds like a good idea to me (avoid destructive behavior by default).

Philippe
Phil Hord· Dec 1, 2011, 21:23 UTC · re: Philippe Vaucher · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Wed, Nov 23, 2011 at 6:00 PM, Philippe Vaucher <philippe.vaucher@gmail.com> wrote:

Show 5 quoted lines
>> In any case, I think your proposal makes it even worse than the current
>> state, and you should aim higher.
>
> Why worse? I'd understand if you said it's doesn't improve it enough
> for it to be worth the change tho.
I think that's what "you should aim higher" means.
Show 5 quoted lines
> Anyway, my proposal was to get a discussion going, and I'm all for
> aiming higher if there's a way. What do you propose instead? You
> seemed to imply we'd remove --soft and --merge, and make --keep as an
> option for --hard but named differently, something like
> --keep-changes. Maybe I didn't fully understand.

I think there are too many scripts dependent on these switches to remove them. But I love the direction you're going in.

Aim higher.
> Mathieu even suggested that it'd have the behavior of --keep by
> default, and that you have to add --force to get today's --hard
> behavior, which sounds like a good idea to me (avoid destructive
> behavior by default).
Think outside the "reset" command.  Like this:
Show 5 quoted lines
>From the "most popular" comment on http://progit.org/2011/07/11/reset.html:
> I remember them as:
> --soft      -> git uncommit
> --mixed  -> git unadd
> --hard     -> git undo
I don't particular like these names, but conceptually they are helpful.

What other commands can we embellish or create to replace the overload git-reset functionality?

How about:
  --soft: git checkout -B <commit>
  --mixed: git reset -- <paths>
  --hard:  git checkout --clean
Phil
Thomas Rast· Dec 2, 2011, 07:26 UTC · re: Phil Hord · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

Phil Hord wrote:
Show 10 quoted lines
> 
> Think outside the "reset" command.  Like this:
> 
> From the "most popular" comment on http://progit.org/2011/07/11/reset.html:
> > I remember them as:
> > --soft      -> git uncommit
> > --mixed  -> git unadd
> > --hard     -> git undo
> 
> I don't particular like these names, but conceptually they are helpful.

I think all of these, but the last one in particular, are *very* dangerous oversimplifications. Doubly so if you then use "undo" with a revision argument.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch
Miles Bader· Dec 2, 2011, 07:45 UTC · re: Thomas Rast · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

Thomas Rast <trast@student.ethz.ch> writes:
Show 10 quoted lines
>> > I remember them as:
>> > --soft      -> git uncommit
>> > --mixed  -> git unadd
>> > --hard     -> git undo
>> 
>> I don't particular like these names, but conceptually they are helpful.
>
> I think all of these, but the last one in particular, are *very*
> dangerous oversimplifications.  Doubly so if you then use "undo" with
> a revision argument.

I agree. Not only is it completely wrong when used with a revision argument, but "undo" is so vague that it's probably useless for _any_ git command, much less one so dangerous as "reset --hard".

-miles
-- 
Friendship, n. A ship big enough to carry two in fair weather, but only one
in foul.
Phil Hord· Dec 2, 2011, 15:28 UTC · re: Thomas Rast · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Fri, Dec 2, 2011 at 2:26 AM, Thomas Rast <trast@student.ethz.ch> wrote:
Show 15 quoted lines
> Phil Hord wrote:
>>
>> Think outside the "reset" command.  Like this:
>>
>> From the "most popular" comment on http://progit.org/2011/07/11/reset.html:
>> > I remember them as:
>> > --soft      -> git uncommit
>> > --mixed  -> git unadd
>> > --hard     -> git undo
>>
>> I don't particular like these names, but conceptually they are helpful.
>
> I think all of these, but the last one in particular, are *very*
> dangerous oversimplifications.  Doubly so if you then use "undo" with
> a revision argument.
I agree.  That's why I also said this:
> How about:
>  --soft: git checkout -B <commit>
>  --mixed: git reset -- <paths>
>  --hard:  git checkout --clean

But maybe I wasn't clear enough. I'm not suggesting git-alias for these. I am proposing new commands to replace common usages of git-reset. These commands would need basic safeguards against foot-shooting, of course.

Phil
Philippe Vaucher· Dec 2, 2011, 14:27 UTC · re: Phil Hord · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

> > Why worse? I'd understand if you said it's doesn't improve it enough
> > for it to be worth the change tho.
>
> I think that's what "you should aim higher" means.

Yes, but my question was why was the proposal _worse_ in his mind. Anyway, it's not really important, probably something he typed in a hurry.

> How about:
>  --soft: git checkout -B <commit>
>  --mixed: git reset -- <paths>
>  --hard:  git checkout --clean
I like the idea... but as other pointed out those are not equivalent.
Maybe we'd start by listing the features we want to be able to do:
- Move git's HEAD to a particular commit without touching the files or the index
- Move git's HEAD to a particular commit and clear the index but
without touching the files
- Move git's HEAD to a particular commit and clear the index and have
all the files match that particular commit files
- Move git's HEAD to a particular commit and clear the index and have
all the files match that particular commit files and remove files that
are unknown to that commit

Is there a scenario I'm missing? Once we have the scenarios nailed down we can start thinking about how to express them.

Philippe
Phil Hord· Dec 2, 2011, 15:38 UTC · re: Philippe Vaucher · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Fri, Dec 2, 2011 at 9:27 AM, Philippe Vaucher <philippe.vaucher@gmail.com> wrote:

Show 13 quoted lines
> Maybe we'd start by listing the features we want to be able to do:
>
> - Move git's HEAD to a particular commit without touching the files or the index
> - Move git's HEAD to a particular commit and clear the index but
> without touching the files
> - Move git's HEAD to a particular commit and clear the index and have
> all the files match that particular commit files
> - Move git's HEAD to a particular commit and clear the index and have
> all the files match that particular commit files and remove files that
> are unknown to that commit
>
> Is there a scenario I'm missing? Once we have the scenarios nailed
> down we can start thinking about how to express them.
Aim higher.

Do not think about the git-reset command and all of its features. Moreover, do not limit yourself to git-reset's functionality.

Think about why you need to use git-reset. Why do new users need to use git-reset? What is it they are after?

For me, it was the three I mentioned before.
So, let's look at yours:
> - Move git's HEAD to a particular commit without touching the files or the index

I know what this is, but I don't know to describe it without saying "reset". It's like teleportation. "Move me to a new location in the tree". git teleport <commit>

> - Move git's HEAD to a particular commit and clear the index but
> without touching the files
git teleport --index <commit>
> - Move git's HEAD to a particular commit and clear the index and have
> all the files match that particular commit files
git checkout --clean <commit>
> - Move git's HEAD to a particular commit and clear the index and have
> all the files match that particular commit files and remove files that
> are unknown to that commit
git checkout --clean <commit> && git clean -fd  # maybe this needs a switch?
One you left out is this:
- Do NOT move git's HEAD; clear the index and workdir
git reset

I think the ability to move git's HEAD is what makes reset dangerous, especially in the hands of new users.

Phil
Philippe Vaucher· Dec 6, 2011, 07:34 UTC · re: Phil Hord · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

> Think about why you need to use git-reset.  Why do new users need to
> use git-reset?  What is it they are after?

Ok, so let's forget about git reset and let's focus on the features instead. If I got it right you suggested the features that people wants most often are uncommit, unadd/undelete and undo. Here's a new proposal (based on your input):

uncommit: git jump <commit> (currently "git reset --soft <commit>") unadd/undelete: git unstage file (currently "git reset --mixed file" (with "git checkout file" for deleted files) undo: git checkout --force --clean <commit> (currently "git reset --hard <commit> && git clean -fd")

So, let's try out some scenarios:
1) Newbie user clones/pulls a repository from somewhere. He hacks
around and then things go bad, and he decides to scratch away
everything he did to make sure things are like they're supposed to be.
He'd then type "git checkout --force --clean master". If he didn't
introduce new files, he would simply type "git checkout --force
master"
2) Newbie adds some file to the index, then realise he added one too
many. He wants to remove it from being added. He'd then type "git
unstage file".
3) Average user creates a commit and suddenly realise he actually
wanted to split that commit in two (he cannot use --amend, and he's
not a rebase -i guru yet). Or he did a "temp" commit because he don't
know about "git stash" yet and wants to discard it. He wants to simply
go back to the previous state while keeping his changes in the index
and the worktree. He'd then type "git jump HEAD^1".
Feel free to add more scenarios!
Philippe
Phil Hord· Oct 3, 2012, 16:23 UTC · re: Philippe Vaucher · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Tue, Dec 6, 2011 at 2:34 AM, Philippe Vaucher <philippe.vaucher@gmail.com> wrote:

Show 7 quoted lines
>> Think about why you need to use git-reset.  Why do new users need to
>> use git-reset?  What is it they are after?
>
> Ok, so let's forget about git reset and let's focus on the features
> instead. If I got it right you suggested the features that people
> wants most often are uncommit, unadd/undelete and undo. Here's a new
> proposal (based on your input):

I flagged this for followup in my MUA, but I failed to follow-up after the holidays. I apologize for that, and I really regret it because I liked where this was going. I only remembered it today when it came up again in another thread.

Show 14 quoted lines
> uncommit: git jump <commit> (currently "git reset --soft <commit>")
> unadd/undelete: git unstage file (currently "git reset --mixed file"
> (with "git checkout file" for deleted files)
> undo: git checkout --force --clean <commit> (currently "git reset
> --hard <commit> && git clean -fd")
>
> So, let's try out some scenarios:
>
> 1) Newbie user clones/pulls a repository from somewhere. He hacks
> around and then things go bad, and he decides to scratch away
> everything he did to make sure things are like they're supposed to be.
> He'd then type "git checkout --force --clean master". If he didn't
> introduce new files, he would simply type "git checkout --force
> master"

I like this just fine. I think we can explicitly say that HEAD is the implied default refspec, yes? "git checkout --force --clean"

> 2) Newbie adds some file to the index, then realise he added one too
> many. He wants to remove it from being added. He'd then type "git
> unstage file".

I'm afraid of the word "stage" because of previous discussions about its i18n abilities. How about "unadd" and "unrm"? Or maybe "git undo add", "git undo rm" and "git undo commit".

The fact that "git undo rm $FILE" works the same as "git checkout HEAD -- $FILE" and does not truly "undo" the delete operation may make this a non-starter. And I admit I have other qualms about using "undo" even though I keep on introducing it into the discussion. For example, this hypothetical sequence will do what I expect when I read it:

   cp bar foo
   git add foo
   echo "more info" >> foo
   git add foo
   git unstage foo   # now index:foo == HEAD:foo
But if I use "git undo add", it will not
   cp bar foo
   git add foo
   echo "more info" >> foo
   git add foo
   git undo add foo   # index:foo == HEAD:foo, not index:foo == bar
Dang.
Well, I personally am ok with 'unstage' but I expect others will not be.
Show 6 quoted lines
> 3) Average user creates a commit and suddenly realise he actually
> wanted to split that commit in two (he cannot use --amend, and he's
> not a rebase -i guru yet). Or he did a "temp" commit because he don't
> know about "git stash" yet and wants to discard it. He wants to simply
> go back to the previous state while keeping his changes in the index
> and the worktree. He'd then type "git jump HEAD^1".

I fear the HEAD^1 concept is too much for the newbie. What about "git uncommit [$REF]" instead? It would work like "git reset --soft $REF^", I think, but maybe it should fail if $REF has multiple parents.

If the user really wants to uncommit a merge commit, she may need to use "git unmerge".

Phil
Junio C Hamano· Oct 3, 2012, 18:41 UTC · re: Phil Hord · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

Phil Hord <phil.hord@gmail.com> writes:
> I flagged this for followup in my MUA, but I failed to follow-up after
> the holidays. I apologize for that, and I really regret it because I
> liked where this was going.
I really regret to see you remembered it, actually.
Show 9 quoted lines
>> 1) Newbie user clones/pulls a repository from somewhere. He hacks
>> around and then things go bad, and he decides to scratch away
>> everything he did to make sure things are like they're supposed to be.
>> He'd then type "git checkout --force --clean master". If he didn't
>> introduce new files, he would simply type "git checkout --force
>> master"
>
> I like this just fine.  I think we can explicitly say that HEAD is the
> implied default refspec, yes?  "git checkout --force --clean"

That depends on what the "hacks around" involved. Where is he now, what damage did he cause, and what can you depend on to take him to a "clean" state, where the definition of "clean" happens to match this hypothetical "Newbie user"? Did he do "git checkout" of another branch? Did he commit? Did he "reset" to other commit while on the 'master' branch? Is he still on "master" branch when he says "git checkout --force --clean <master>"? Can he say "git checkout --force --clean master~4" and what does that even mean? Is he trying to go into the detached HEAD state, or is he somehow trying to rewind master?

Junio C Hamano· Oct 3, 2012, 19:03 UTC · re: Junio C Hamano · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

Junio C Hamano <gitster@pobox.com> writes:
Show 7 quoted lines
> Phil Hord <phil.hord@gmail.com> writes:
>
>> I flagged this for followup in my MUA, but I failed to follow-up after
>> the holidays. I apologize for that, and I really regret it because I
>> liked where this was going.
>
> I really regret to see you remembered it, actually.

Having said that, I am glad that you brought the old discussion thread to our attention. In

    http://thread.gmane.org/gmane.comp.version-control.git/185825/focus=185863,

I said that "git reset --keep" started out as an ugly workaround for the lack of "git checkout -B $current_branch". Now we have it, so we can afford to make "reset --keep" less prominently advertised in our tool set. As I already said back then, "reset --soft" also has outlived its usefulness when "commit --amend" came, so that leaves only these modes of "reset":

        reset --hard [$commit]
	reset [$commit]
        reset --merge

I am not sure if it makes sense to give a commit different from HEAD to "reset --merge", and to a lessor degree, "reset --mixed" to flip the HEAD to another commit while retaining the working tree contents does not make much sense, either, in a common workflow.

It _might_ be possible to merge the --mixed and --merge if we think things through to reduce the often-used options even further, but I haven't done so, and I suspect nobody has (yet).

Jan Engelhardt· Dec 15, 2012, 18:57 UTC · re: Junio C Hamano · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Wednesday 2012-10-03 21:03, Junio C Hamano wrote:
Show 7 quoted lines
>
>I said that "git reset --keep" started out as an ugly workaround for
>the lack of "git checkout -B $current_branch".  Now we have it, so
>we can afford to make "reset --keep" less prominently advertised in
>our tool set.  As I already said back then, "reset --soft" also has
>outlived its usefulness when "commit --amend" came, so that leaves
>only these modes of "reset":

Soft is still useful, partway. Consider patch splitting (where easily possible):

 $ git add foo.c bar.c
 $ git commit -m foo,bar
 [other commits]
 $ git rebase -i FOOBARCOMMIT^
 [mark foo,bar for edit]
 $ git reset --soft HEAD^
 $ git reset bar.c
 $ git commit -m foo
 $ git add bar.c
 $ git commit -m bar
 $ git rebase --continue
Phil Hord· Dec 1, 2011, 21:02 UTC · re: Junio C Hamano · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Wed, Nov 23, 2011 at 1:51 PM, Junio C Hamano <gitster@pobox.com> wrote:
> "git reset --hard HEAD" is an unambiguously descriptive good name for the
> option. It is a "hard reset" like power cycling a machinery to discard
> anything in progress and get back to a clean slate. I do not see anything
> confusing with this mode nor its name.
As a git expert-user, I agree.

But, honestly, as a git new-user, I had a lot of trouble with this command. It is mysterious and powerful and new users do not understand it. Everyone learns "git reset --hard HEAD" as a single command. Only much later (if ever) do they learn about the other git-reset options. --hard is the only useful option for the new user, so it seems superfluous. HEAD is a foreign concept for the new-user and makes little sense when this command is first memorized. And at the early stages of the git learning curve, that's what it is: memorized. _The spelling is what counts; the meaning is mysterious._ (For all its flaws, though, at least "git reset --hard HEAD" serves to introduce the new-user to the concept of HEAD.)

So, as a git new-user, what I wanted was this:
  git clean-checkout [or "git checkout --clean"]
What I found instead was this:
  git reset --hard HEAD

What does this have to do with "checking out my files from the last commit" or "discarding my local, uncommitted edits"? To the new-user, nothing at all. reset? Meaningless. --hard? Whatever. HEAD? Shrug.

In the end it doesn't even do what I wanted.  What I really wanted was this:
  git reset --hard HEAD && git clean -fd

I think the git-reset modes should be relegated to plumbing. I can see how 'git reset --mixed' is useful for resetting changes out of the index, but reset is so mired in all sorts of extra mumbo-jumbo that this usage becomes a forgotten detail for me. I didn't even learn that usage until later, where it makes loads of sense on its own:

     FTH: This means that git reset <paths> is the opposite of git add <paths>.
That is beautiful, clean and useful.  If that's all it did, it would be perfect.
Problems with git-reset--hard:
 * It has no safety nets (except the reflog, another concept foreign
to new-users)
 * It requires extra switches/arguments to be useful
 * Surprisingly (at first), it can move your branch, but it's not
spelled 'branch' or 'commit' or 'move'
That last one is particularly troubling in light of the description of
'git reset --hard':
     Resets the index and working tree. Any changes to tracked
     files in the working tree since <commit> are discarded.

Maybe we should add "and by the way, your currently checked-out branch is moved to point to <commit>".

</rant>
Phil
Martin von Zweigbergk· Dec 18, 2012, 06:34 UTC · re: Junio C Hamano · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Wed, Nov 23, 2011 at 10:51 AM, Junio C Hamano <gitster@pobox.com> wrote:
>
> I am guilty of introducing "git reset --soft HEAD^" before I invented
> "commit --amend" during v1.3.0 timeframe to solve the issue "soft" reset
> originally wanted to.

I do use "commit --amend" a lot, but I still appreciate having "reset --soft". For example, to squash the last few commits:

git reset --soft HEAD^^^ && git commit --amend
or undo "commit --amend":
git reset --soft HEAD@{1} && git commit --amend
Maybe there's a better way of doing that?
Junio C Hamano· Dec 18, 2012, 15:22 UTC · re: Martin von Zweigbergk · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

Martin von Zweigbergk <martinvonz@gmail.com> writes:
Show 10 quoted lines
> On Wed, Nov 23, 2011 at 10:51 AM, Junio C Hamano <gitster@pobox.com> wrote:
>>
>> I am guilty of introducing "git reset --soft HEAD^" before I invented
>> "commit --amend" during v1.3.0 timeframe to solve the issue "soft" reset
>> originally wanted to.
>
> I do use "commit --amend" a lot, but I still appreciate having "reset
> --soft". For example, to squash the last few commits:
>
> git reset --soft HEAD^^^ && git commit --amend

Yeah, I do that sometimes myself, but the key word is "sometimes". These days, I think most users (not just mortals but experienced ones) use "rebase -i" to squash them altogether, either with "fixup", with which you lose the messages from the follow-up fixes, just like the soft reset to an old one with an amen,) or with "squash", with which you can pick pieces of messages from the follow-up fixes while updating the message from the original one.

Jeff King· Dec 18, 2012, 16:30 UTC · re: Martin von Zweigbergk · lore

Re: Proposal: create meaningful aliases for git reset's hard/soft/mixed

On Mon, Dec 17, 2012 at 10:34:07PM -0800, Martin von Zweigbergk wrote:
Show 10 quoted lines
> On Wed, Nov 23, 2011 at 10:51 AM, Junio C Hamano <gitster@pobox.com> wrote:
> >
> > I am guilty of introducing "git reset --soft HEAD^" before I invented
> > "commit --amend" during v1.3.0 timeframe to solve the issue "soft" reset
> > originally wanted to.
> 
> I do use "commit --amend" a lot, but I still appreciate having "reset
> --soft". For example, to squash the last few commits:
> 
> git reset --soft HEAD^^^ && git commit --amend
Me too. Another one I use is:
  $ hack hack hack
  $ git commit -m wip
  $ git checkout something-else
  ... time passes ...
  $ git checkout orig-branch
  $ git reset --soft HEAD^
  $ hack hack hack
  $ git diff
  $ git add -p
  $ git commit

which ends up with the same history as "commit --amend", but in between the reset and the commit, the bogus WIP commit is thrown away entirely. And things like "diff" and "add -p" do what you want, instead of showing your progress on top of the WIP.

-Peff

← back to recent threads