Subject: Re: RFC: git status --amend

From: David Aguilar <[email-masked]>
Date: Wed, 1 Apr 2015 01:43:24 -0700

On Tue, Mar 31, 2015 at 11:35:17AM -0700, Junio C Hamano wrote:
> Jeff King <[email-masked]> writes:
> 
> > On Tue, Mar 31, 2015 at 04:59:27PM +0200, Sven Strickroth wrote:
> >
> >> for frontends or scripts it would be helpful to be able to use "git
> >> status" for getting the repository status compared to HEAD~1 instead of
> >> only HEAD (as provided by "git commit --amend" in the pre-filled commit
> >> message).
> >> 
> >> Thus, I'm suggesting to add a "--amend" parameter (or a parameter with a
> >> better naming) to "git status".
> >> 
> >> What do you think of this idea?
> >
> > Once upon a time "git status" really was just "git commit --dry-run".
> > These days it has diverged a bit. But I think you could get what you
> > want with:
> >
> >   git commit --dry-run --amend
> >
> > It even supports alternate styles like --short.
> 
> I think everything you said is correct, but your "diverged a bit"
> may hide one difference that could be crucial depending on the use
> case: pathspec.
> 
> What "git commit --dry-run [--other-options] <pathspec>" does, and
> what "git status [--other-options] <pathspec>" does, are different.
> 
> With or without --dry-run, to "git commit", <pathspec> tells the
> command to update the index at the paths specified by it from the
> working tree contents before proceeding (the contents recorded for
> the other paths depend on the use of -o or -i option).  But ever
> since "git status" departed from being "git commit -n", a pathspec
> given to the command means completely different thing.
> 
> After working on various parts of the tree, planning to conclude the
> current work with "commit", "git status directory/" is a good way to
> see what you did in that directory without seeing what you did
> outside (which will be included in the commit, too).
> 
> But what you get from "git commit --no-edit --dry-run directory/"
> would be different; it would show all the changes in the working
> tree inside directory/, including the ones that you deliberately
> left out of the index, as paths to be committed.
> 
> Having said all that, I am a bit torn on this topic.  Just like "git
> status" is a way to ask "I've worked so far, planning to conclude
> this with 'git commit'; tell me what I have achieved so far that are
> in the index and in the working tree, possibly limiting to these
> paths?", I think it is a reasonable thing to ask the same question
> with "s/git commit/git commit --amend/".
> 
> One workaround might be to
> 
>     git reset --soft HEAD^
>     git status [<pathspec>]
>     ...
>     git commit -c @{1}
> 
> but that is simply too error prone and ugly.  I would say it would
> be better if "status" knows how to answer that "I am planning to
> conclude with 'git commit --amend'" question.
> 
> The reason why I am torn is because I do not think "status --amend"
> is a sensible name for that option.  "status" is not about amending
> anything.
> 
> If the normal "status" is "give me status for the next commit", this
> new mode would be "give me status for the 'commit --amend'".  Naming
> it "git status --for-amend" crossed my mind, but it does not sound
> great to me, either.
> 
> So...

I think I can understand some of the "feeling torn" aspects.

I know exactly the problem that "status --amend" is trying to
solve, as it is non-trivial to get the status bits correct
for "what it looks like when amending a commit".

git-gui and git-cola both do some clever things to make their
amend modes work smoothly for the user, and having something
like "status --amend" could have made the implementation
simpler.

But "status --amend" still makes me torn too because it's too
special-purpose.  Taking a step back, "status" gives you a lot
of information, and all of it is relative to HEAD.

"status --amend" is really asking to make it all relative to
HEAD^ instead.

So I wonder, would the syntax not be more gittish if it were,

	git status HEAD
	git status HEAD^
	git status <ref> -- <pathspec>

and it'll compare your repo's status relative to any ref.

I like the above because it's general and not hard-wired into
the concept of amending a commit, but it enables that use case
as well.

The ultimate convenience for script writers would be if this
command gracefully handled the edge cases.  I have a separate
code path for this one, and eliminating it would be awesome.

"git init" time, where no commit exists (and thus "git status
HEAD|HEAD^" makes no sense) is an inconvenience to script
around. The most convenient behavior for the user would be to
treat that situation as being equivalent to comparing against an
empty tree.

That could extend to post-"git init" when a single commit exists
and the user asks for "git status HEAD^" for amending purposes.
It'd be great if the tool was dwim enough to also treat that as
an empty tree comparison.

I don't know if that's going too far, because normally git
would just yell, "HEAD^ makes no sense!" and tell the user to
bugger off, but I can definitely see the utility in a dwimmy
soft-edges status tool that papers over some of these edge
cases.

Would generalizing "status" to have a more gittish syntax make
you feel less torn?
-- 
David