All of lore.kernel.org
 help / color / mirror / Atom feed
* Command-line interface thoughts
       [not found] <BANLkTikTWx7A64vN+hVZgL7cuiZ16Eobgg@mail.gmail.com>
@ 2011-06-04 16:17 ` Michael Nahas
  2011-06-04 21:49   ` Jakub Narebski
  2011-06-05 21:34   ` Paul Ebermann
  0 siblings, 2 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-04 16:17 UTC (permalink / raw)
  To: git

Quick list of recommendations:

1. Pick aliases for the next commit and the working tree that act like
commits on the command-line.
2. Adopt a (semi-)formal notation for describing what commands do.
3. Move the operations "checkout -- <file>" and "reset -- <file>" to
their own command names
4. Deemphasize the "branch" command for creating branches.

A "normal" (long) email follows.  At the end are examples of commands
in a not-quite-so-formal notation.

I AM NOT ON THE MAILING LIST - PLEASE CC ME ON REPLIES.


------------

I was the primary designer of the PAR2 open file format and write a
lot of big software (application-layer multicast, etc.).  I've been
using Git for 2 months.  I love it and I greatly admire the plumbing.
However, the default "porcelain" has at times been more confusing than
enlightening.

I had some ideas about the porcelain and decided they were worth
sending to the mailing list.  I ran the ideas by the two Git gurus who
answer my questions and they agreed with them.  I wish I had the time
to implement them but I did PAR2 when I had time off and I'm working
now.  I apologize if any of these are repeats or have already been
discussed to death.


My recommendations are:

1. Pick aliases for the next commit and the working tree that act like
commits on the command-line.

By "next commit", I mean "the commit that would be generated if the
"commit" command was run right now".  "Next commit" is not the same as
the index.  The index is a _file_ that serves multiple purposes.
(Think of it's state during a conflicted merge.)  But the index does
usually hold the files that change between HEAD and the next commit.

For the alias for the next commit and working tree, I suggest "NEXT"
and "WTREE".  Creating these aliases will make the interface more
regular. It will remove oddities like "diff --cached FOO" and replace
them with "diff NEXT FOO" and mean that "diff" and "diff FOO" can be
explained as "diff WTREE NEXT" and "diff WTREE FOO".


2. Adopt a notation for describing what commands do.

I am sure in developer discussions there are descriptions of the
"commit" command as something like:
   HEAD = new(HEAD + (NEXT-HEAD))
   NEXT = HEAD

Where "-" creates a patch between versions and + applys a patch.  Git
already has some operators like "^", which refers to the parent of a
commit. Those are useful for defining things like "commit --amend":
   HEAD = new(HEAD^ + (NEXT-HEAD^))
   NEXT = HEAD

Having this notation and using it in the man pages will make the exact
nature of the operation clear. (Right now, it takes a lot of reading
to figure out what happens to NEXT with the various command-line
options of "reset".)

Currently, to understand what commands do, I use "A Visual Git
Reference", which has been extremely valuable to me. Kuddos to Mark
Lodato for it.
http://marklodato.github.com/visual-git-guide/index-en.html

[I've included git commands in a not-formal-enough notation at the end
of this email.]


3. Move the operations "checkout -- <file>" and "reset -- <file>" to
their own command names

This is my biggest and most important suggestion.

"checkout -- foo.txt" copies foo.txt from NEXT to WTREE. Similarly,
"reset -- foo.txt" will copy foo.txt from HEAD to NEXT.

These are operations to designate/undesignate files in the next commit
and should be grouped with others like them: "add", "rm" and "mv". (In
fact, the man page for "reset -- <file>" even says that it is the
opposite of "add"!)

When these file-based operations are removed from "checkout" and
"reset", the purposes of those commands becomes clearer: "checkout"
changes HEAD to a new branch and "reset" moves the current branch
pointer to a different commit.  These operations may share code with
the operations "checkout -- <file>" and "reset -- <file>", but they
serve different purposes from the user's perspective and the user
should have different names to refer to them.

As for naming these new commands, the "yet-another-porcelain" renames
"reset -- <file>" to "unadd", which I like very much.  For the other,
my best suggestion is "head-to-next", but I'm sure someone can do
better.


4. Deemphasize the "branch" command for creating branches.

I assumed that the command "branch" was used for creating branches.
After all, that's how it is done in the "gittutorial(7)" man page.
However, after reviewing all the major commands, I find that it is the
_last_ way I want to create a branch. It creates a new branch, but it
doesn't switch HEAD to the new branch!

The commands that should be emphasized are "checkout -b <name>",
"commit -b <name>", and "stash branch".  These make sense in normal
git usage. The "branch" command has its uses but it is not usually the
way you want to create a branch.


These are my suggestions.  I wish i had time to implement them, but
I'm glad to help in the discussion of them.  I'm not on the mailing
list, so PLEASE CC ME WITH ANY REPLIES.

Michael Nahas


----

These are just some commands written in a not-quite-formal notation.
This notation doesn't handle a detached head, adding directories, the
state after a conflicted "stash pop", etc.  Still, as it is, I think
it's very informative to users for getting the gist of what command
does.

"add foo.txt"
   NEXT:foo.txt = WTREE:foo.txt
"rm foo.txt"
   delete(NEXT:foo.txt)
   delete(WTREE:foo.txt)
"rm --cached foo.txt"
   delete(NEXT:foo.txt)
"/bin/rm foo.txt"
   delete(WTREE:foo.txt)
"mv foo.txt bar.txt"
   WTREE:bar.txt = WTREE:foo.txt
   NEXT.bar.txt = WTREE:foo.txt
   delete(WTREE:foo.txt)
   delete(NEXT:foo.txt)
"checkout -- foo.txt"
   WTREE:foo.txt = NEXT:foo.txt
"reset -- foo.txt"
   NEXT:foo.txt = HEAD:foo.txt

"commit"
   HEAD = new(HEAD + (NEXT-HEAD))
   NEXT = HEAD
"commit --amend"
   HEAD = new(HEAD^ + (NEXT-HEAD^))
   NEXT = HEAD

"checkout FOO" (prequires WTREE==NEXT==HEAD)
   WTREE = FOO
   NEXT = FOO
   HEAD ::= FOO // changes the alias of HEAD to refer to FOO

"reset --soft FOO"
   HEAD = FOO // move branch; don't change alias
"reset --mixed FOO" (the default)
   NEXT = FOO
   HEAD = FOO // move branch; don't change alias
"reset --hard FOO"
   WTREE = FOO
   NEXT = FOO
   HEAD = FOO // move branch; don't change alias

"stash save"
   STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)
   NEXT = HEAD
   WTREE = HEAD
   push(STASH)
"stash pop"
   STASH = pop()
   WTREE = HEAD + (STASH-STASH^^)
   NEXT = HEAD + (STASH^-STASH^^)

"branch FOO"
   FOO = HEAD
"commit -b FOO"
   FOO = new(HEAD + (NEXT-HEAD))
   NEXT = FOO
   HEAD ::= FOO // change alias
"checkout -b FOO" (prequires WTREE==NEXT==HEAD)
   FOO = HEAD // create FOO and make it a copy of HEAD
   WTREE = FOO
   NEXT = FOO
   HEAD ::= FOO // change alias
"stash branch FOO"
   STASH = pop()
   FOO = STASH^^ // create FOO and make it a copy of STASH^^
   NEXT = STASH^
   WTREE = STASH
   HEAD ::= FOO // change alias

"merge FOO" (prequires NEXT=HEAD)
   [ANC is the nearest common ancestor]
   WTREE = ANC + (WTREE - ANC) + (FOO-ANC)
   NEXT = ANC + (HEAD - ANC) + (FOO-ANC)
   HEAD = new(HEAD + (NEXT-HEAD))
   NEXT = HEAD
"cherry-pick FOO" (prequires WTREE==NEXT==HEAD)
   HEAD = new(HEAD + (FOO - FOO^))
   NEXT = HEAD
   WTREE = HEAD
"rebase FOO" is basically a iterated application of "cherry-pick"

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-04 16:17 ` Command-line interface thoughts Michael Nahas
@ 2011-06-04 21:49   ` Jakub Narebski
  2011-06-05  1:00     ` Michael Nahas
  2011-06-05 21:34   ` Paul Ebermann
  1 sibling, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-04 21:49 UTC (permalink / raw)
  To: mike; +Cc: git, Michael Nahas

Michael Nahas <mike.nahas@gmail.com> writes:

> Quick list of recommendations:
> 
> 1. Pick aliases for the next commit and the working tree that act like
>    commits on the command-line.

No go.  This was asked for many times, and each time shot down.
Those "aliases" / pseudo-refs looks like commits but do not behave
exactly like commits.  This would increase connfusion.

See also gitcli(7) manpage for description of --index and --cached
options (and other git command line conventions).

> 2. Adopt a (semi-)formal notation for describing what commands do.

Whom it would help?  Not an ordinary user.

> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
>    their own command names

Proposed "git unadd <pathspec>..." doesn't cover all features of
"git reset <rev> -- <path>" nor "git checkout [<rev>] -- <path>".

> 4. Deemphasize the "branch" command for creating branches.

Or add "git branch --checkout <newbranch>".

> 
> A "normal" (long) email follows.  At the end are examples of commands
> in a not-quite-so-formal notation.
 
> ------------
> 
> I was the primary designer of the PAR2 open file format and write a
> lot of big software (application-layer multicast, etc.).  I've been
> using Git for 2 months.  I love it and I greatly admire the plumbing.
> However, the default "porcelain" has at times been more confusing than
> enlightening.

BTW. have you read gitcli(7) manpage?
 
> I had some ideas about the porcelain and decided they were worth
> sending to the mailing list.  I ran the ideas by the two Git gurus who
> answer my questions and they agreed with them.  I wish I had the time
> to implement them but I did PAR2 when I had time off and I'm working
> now.  I apologize if any of these are repeats or have already been
> discussed to death.
> 
> 
> My recommendations are:
> 
> 1. Pick aliases for the next commit and the working tree that act like
> commits on the command-line.
> 
> By "next commit", I mean "the commit that would be generated if the
> "commit" command was run right now".  "Next commit" is not the same as
> the index.  The index is a _file_ that serves multiple purposes.
> (Think of it's state during a conflicted merge.)  But the index does
> usually hold the files that change between HEAD and the next commit.
> 
> For the alias for the next commit and working tree, I suggest "NEXT"
> and "WTREE".  Creating these aliases will make the interface more
> regular. It will remove oddities like "diff --cached FOO" and replace
> them with "diff NEXT FOO" and mean that "diff" and "diff FOO" can be
> explained as "diff WTREE NEXT" and "diff WTREE FOO".
 
This idea ws proposed multiple time on git mailing list, and every
time it was rejected.

The problem is first, that you make INDEX / STAGE / NEXT and 
WORK / WTREE *look* like commits (like pseudo symbolic refs), while
they do not *behave* like commits.
 
"git show HEAD" looks differently from "git show NEXT" or "git show WTREE".
Neither the index now working tree have a parent, or author, or commit
message.  The index (staging area) can have stages, though you sidestep
this issue by handwaving it away.  Working area has notion of tracked,
untracked ignored and untracked not ignored (other) files.   Etc., etc.

BTW. both index and worktree have their own "aliases", namely ':0:'
for index (stage 0), and ':' or ':/' for top tree.


Second, it doesn't solve issue of needing --cached and/or --index
swiches completely.  Those pseudo-almost-refs hide them for "git diff",
"git grep", "git ls-files", perhaps "git submodule" where we *read*
from index, but not for "git apply", "git rm" or "git stash" where
those swicthes affect *writing*.

> 2. Adopt a notation for describing what commands do.
> 
> I am sure in developer discussions there are descriptions of the
> "commit" command as something like:
>    HEAD = new(HEAD + (NEXT-HEAD))
>    NEXT = HEAD

Basic algebra fail

  HEAD + (NEXT-HEAD) == NEXT

Besides "git commit" creates commit from state of index, no diffing or
patching is involved.

> Where "-" creates a patch between versions and + applies a patch.  Git
> already has some operators like "^", which refers to the parent of a
> commit. Those are useful for defining things like "commit --amend":
>    HEAD = new(HEAD^ + (NEXT-HEAD^))
>    NEXT = HEAD

Which is again not true.
 
> Having this notation and using it in the man pages will make the exact
> nature of the operation clear. (Right now, it takes a lot of reading
> to figure out what happens to NEXT with the various command-line
> options of "reset".)

It's not that difficult: only "git reset --soft [<rev>]" doesn't
affect index.

Hrmmm... how this notation would explain differences between 
"git reset --hard", "git reset --keep" and "git reset --merge"?

> 
> Currently, to understand what commands do, I use "A Visual Git
> Reference", which has been extremely valuable to me. Kuddos to Mark
> Lodato for it.
> http://marklodato.github.com/visual-git-guide/index-en.html

Unfortunately manpages cannot really include images.  Well, there is
some kind of obscure graph description language for manpages ('dot' or
something like that), supposedly, IIRC...

> 
> [I've included git commands in a not-formal-enough notation at the end
> of this email.]
 
NEVERTHELESS some kind of semi-formal notation might be useful.
 
> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
> their own command names
> 
> This is my biggest and most important suggestion.
> 
> "checkout -- foo.txt" copies foo.txt from NEXT to WTREE. Similarly,
> "reset -- foo.txt" will copy foo.txt from HEAD to NEXT.

  "checkout HEAD -- foo.txt" copies foo.txt from HEAD to NEXT and WTREE

  "checkout HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT and WTREE
  "reset HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT
 
> These are operations to designate/undesignate files in the next commit
> and should be grouped with others like them: "add", "rm" and "mv". (In
> fact, the man page for "reset -- <file>" even says that it is the
> opposite of "add"!)
> 
> When these file-based operations are removed from "checkout" and
> "reset", the purposes of those commands becomes clearer: "checkout"
> changes HEAD to a new branch and "reset" moves the current branch
> pointer to a different commit.  These operations may share code with
> the operations "checkout -- <file>" and "reset -- <file>", but they
> serve different purposes from the user's perspective and the user
> should have different names to refer to them.
> 
> As for naming these new commands, the "yet-another-porcelain" renames
> "reset -- <file>" to "unadd", which I like very much.

Well, that goes counter to reducing number of commands, but I quite
like this name.  Though "unadd <revision> -- <file>" looks a bit
strange...

> For the other, my best suggestion is "head-to-next", but I'm sure
> someone can do better.

I'd rather remember that "git checkout" is about checking out
something to a working area.
 
> 
> 4. Deemphasize the "branch" command for creating branches.
> 
> I assumed that the command "branch" was used for creating branches.
> After all, that's how it is done in the "gittutorial(7)" man page.

It _is_ used to create branches.  But perhaps we should update
gittutorial(7) (and check users manual)...

> However, after reviewing all the major commands, I find that it is the
> _last_ way I want to create a branch. It creates a new branch, but it
> doesn't switch HEAD to the new branch!

"checkout -b" is just shortcut for "branch" + "checkout".  Very
convenient one, that is...

> 
> The commands that should be emphasized are "checkout -b <name>",
> "commit -b <name>", and "stash branch".  These make sense in normal
> git usage. The "branch" command has its uses but it is not usually the
> way you want to create a branch.
[...]

> ----
> 
> These are just some commands written in a not-quite-formal notation.
> This notation doesn't handle a detached head, adding directories, the
> state after a conflicted "stash pop", etc.  Still, as it is, I think
> it's very informative to users for getting the gist of what command
> does.
> 
> "add foo.txt"
>    NEXT:foo.txt = WTREE:foo.txt

What about "add --intent-to-add foo.txt"?  What about "add <directory>"?
What about resolving merge conflicts?

> "rm foo.txt"
>    delete(NEXT:foo.txt)
>    delete(WTREE:foo.txt)
> "rm --cached foo.txt"
>    delete(NEXT:foo.txt)
> "/bin/rm foo.txt"
>    delete(WTREE:foo.txt)

O.K.  Note however that "git rm foo.txt" on conflicted entry would
clean up conflict.

> "mv foo.txt bar.txt"
>    WTREE:bar.txt = WTREE:foo.txt
>    NEXT.bar.txt = WTREE:foo.txt
>    delete(WTREE:foo.txt)
>    delete(NEXT:foo.txt)

O.K., but what is important are atomicity and safety checks.

> "checkout -- foo.txt"
>    WTREE:foo.txt = NEXT:foo.txt
> "reset -- foo.txt"
>    NEXT:foo.txt = HEAD:foo.txt

Those are not the only modes.

> "commit"
>    HEAD = new(HEAD + (NEXT-HEAD))
>    NEXT = HEAD

   HEAD + (NEXT-HEAD) == NEXT

"git commit" doesn't apply patches.

> "commit --amend"
>    HEAD = new(HEAD^ + (NEXT-HEAD^))
>    NEXT = HEAD

  HEAD^ + (NEXT-HEAD^) == NEXT

"git commit --amend" works correctly even if HEAD is a merge commit!

> 
> "checkout FOO" (prequires WTREE==NEXT==HEAD)

No such requirement.  It's all about which files differ between HEAD
and FOO.  If you start working on some file, and decide that you
should have made the change on different branch, "git checkout FOO"
allow to move to FOO branch... assuming that changed file has the same
contents in HEAD and in FOO.

End there is "checkout -f" and "checkout -m".

>    WTREE = FOO
>    NEXT = FOO
>    HEAD ::= FOO // changes the alias of HEAD to refer to FOO

And this is supposed to be easier to understand?


> "stash save"
>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)
>    NEXT = HEAD
>    WTREE = HEAD
>    push(STASH)
> "stash pop"
>    STASH = pop()
>    WTREE = HEAD + (STASH-STASH^^)
>    NEXT = HEAD + (STASH^-STASH^^)

???

[...] 
> "cherry-pick FOO" (prequires WTREE==NEXT==HEAD)
>    HEAD = new(HEAD + (FOO - FOO^))
>    NEXT = HEAD
>    WTREE = HEAD
> "rebase FOO" is basically a iterated application of "cherry-pick"

Ordinary rebase isn't.

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-04 21:49   ` Jakub Narebski
@ 2011-06-05  1:00     ` Michael Nahas
  2011-06-05 11:10       ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-05  1:00 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git

Thanks for your reply, Jakub.

On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:
> Michael Nahas <mike.nahas@gmail.com> writes:
>
>> Quick list of recommendations:
>>
>> 1. Pick aliases for the next commit and the working tree that act like
>>    commits on the command-line.
>
> No go.  This was asked for many times, and each time shot down.
> Those "aliases" / pseudo-refs looks like commits but do not behave
> exactly like commits.  This would increase connfusion.

I'm glad it was discussed.  I think users would know that those
commits were special (they are writeable after all), but I'm sure more
informed people than I made the same arguments.

> See also gitcli(7) manpage for description of --index and --cached
> options (and other git command line conventions).

Thanks for the pointer.  I've now read it.

>> 2. Adopt a (semi-)formal notation for describing what commands do.
>
> Whom it would help?  Not an ordinary user.

I think it would help experts in discussing exactly what happens.  For
ordinary users that are hitting an intricate case (or don't know
English very well), it would be good if there was something that would
tell them mathematically what occurs.

>> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
>>    their own command names
>
> Proposed "git unadd <pathspec>..." doesn't cover all features of
> "git reset <rev> -- <path>" nor "git checkout [<rev>] -- <path>".

I'm confused.  How can it not cover all the features?  I'm just
suggesting renaming the command.  From "git reset -- <path>" to "git
unadd [--] <path>".  (And renaming "git checkout -- <path>" to some
yet-to-be-named other command.)

>> 4. Deemphasize the "branch" command for creating branches.
>
> Or add "git branch --checkout <newbranch>".

Would that operation be the different from the existing "git checkout
-b <new branch>", or just another way to write it?

>> A "normal" (long) email follows.  At the end are examples of commands
>> in a not-quite-so-formal notation.
>
>> ------------
>>
>> I was the primary designer of the PAR2 open file format and write a
>> lot of big software (application-layer multicast, etc.).  I've been
>> using Git for 2 months.  I love it and I greatly admire the plumbing.
>> However, the default "porcelain" has at times been more confusing than
>> enlightening.
>
> BTW. have you read gitcli(7) manpage?

I have now.  I'd swear I've read close to 30 manpages but never
heard-of/noticed that one until you mentioned it.  Thanks for the
pointer; it's good to have --index and --cached clarified.

>> I had some ideas about the porcelain and decided they were worth
>> sending to the mailing list.  I ran the ideas by the two Git gurus who
>> answer my questions and they agreed with them.  I wish I had the time
>> to implement them but I did PAR2 when I had time off and I'm working
>> now.  I apologize if any of these are repeats or have already been
>> discussed to death.
>>
>>
>> My recommendations are:
>>
>> 1. Pick aliases for the next commit and the working tree that act like
>> commits on the command-line.
>>
>> By "next commit", I mean "the commit that would be generated if the
>> "commit" command was run right now".  "Next commit" is not the same as
>> the index.  The index is a _file_ that serves multiple purposes.
>> (Think of it's state during a conflicted merge.)  But the index does
>> usually hold the files that change between HEAD and the next commit.
>>
>> For the alias for the next commit and working tree, I suggest "NEXT"
>> and "WTREE".  Creating these aliases will make the interface more
>> regular. It will remove oddities like "diff --cached FOO" and replace
>> them with "diff NEXT FOO" and mean that "diff" and "diff FOO" can be
>> explained as "diff WTREE NEXT" and "diff WTREE FOO".
>
> This idea ws proposed multiple time on git mailing list, and every
> time it was rejected.
>
> The problem is first, that you make INDEX / STAGE / NEXT and
> WORK / WTREE *look* like commits (like pseudo symbolic refs), while
> they do not *behave* like commits.
>
> "git show HEAD" looks differently from "git show NEXT" or "git show WTREE".
> Neither the index now working tree have a parent, or author, or commit
> message.  The index (staging area) can have stages, though you sidestep
> this issue by handwaving it away.  Working area has notion of tracked,
> untracked ignored and untracked not ignored (other) files.   Etc., etc.

I knew of some of these issues and I agree that I was handwaving them
away.  I didn't have all the answers and certainly didn't want to
appear to be claiming to have them.  I assumed that if the idea had
merit that these issues could be worked out.

That this idea has been brought up multiple times says that it does
have some merit.  But apparently not enough merit.

> BTW. both index and worktree have their own "aliases", namely ':0:'
> for index (stage 0), and ':' or ':/' for top tree.

Really?  Where can these aliases be used?

> Second, it doesn't solve issue of needing --cached and/or --index
> swiches completely.  Those pseudo-almost-refs hide them for "git diff",
> "git grep", "git ls-files", perhaps "git submodule" where we *read*
> from index, but not for "git apply", "git rm" or "git stash" where
> those swicthes affect *writing*.

I agree with you that it would not get rid of all switches.  I never
expected it to.  My major aim was to simplify things like the "diff"
command, which I have trouble remembering the different variations of.

>> 2. Adopt a notation for describing what commands do.
>>
>> I am sure in developer discussions there are descriptions of the
>> "commit" command as something like:
>>    HEAD = new(HEAD + (NEXT-HEAD))
>>    NEXT = HEAD
>
> Basic algebra fail
>
>  HEAD + (NEXT-HEAD) == NEXT
>
> Besides "git commit" creates commit from state of index, no diffing or
> patching is involved.

I would claim that the "state of index" is an approximation of
(NEXT-HEAD).  Also, the new Tree and Blob objects that get written
during the commit are another approximation of (NEXT-HEAD).  Neither
of these is exactly a patch applied to HEAD, but that's the intent I
was going for with my algebraic identity.  (It's not a fail; it's an
unoptimization!)

>> Where "-" creates a patch between versions and + applies a patch.  Git
>> already has some operators like "^", which refers to the parent of a
>> commit. Those are useful for defining things like "commit --amend":
>>    HEAD = new(HEAD^ + (NEXT-HEAD^))
>>    NEXT = HEAD
>
> Which is again not true.

[Addressed below, where the "what if HEAD is a merge commit with
multiple predecessors" is mentioned.]

>> Having this notation and using it in the man pages will make the exact
>> nature of the operation clear. (Right now, it takes a lot of reading
>> to figure out what happens to NEXT with the various command-line
>> options of "reset".)
>
> It's not that difficult: only "git reset --soft [<rev>]" doesn't
> affect index.
>
> Hrmmm... how this notation would explain differences between
> "git reset --hard", "git reset --keep" and "git reset --merge"?

I don't understand what "git reset --keep" and "git reset --merge" do.
 I've read the manpage but am still confused.  One of my reasons for
suggesting a notation is so that there is a clear mathematical
representation of what the commands do.  Once I understand them, I can
make an attempt at a notation that can explain them.

>> Currently, to understand what commands do, I use "A Visual Git
>> Reference", which has been extremely valuable to me. Kuddos to Mark
>> Lodato for it.
>> http://marklodato.github.com/visual-git-guide/index-en.html
>
> Unfortunately manpages cannot really include images.  Well, there is
> some kind of obscure graph description language for manpages ('dot' or
> something like that), supposedly, IIRC...

The manpage for "git checkout" has some ASCII art of commit DAGs.
It's almost there...

>> [I've included git commands in a not-formal-enough notation at the end
>> of this email.]
>
> NEVERTHELESS some kind of semi-formal notation might be useful.

I'm glad you agree.  Do you think my not-formal-enough notation is a
good start or do you want to propose another notation to start from?

>> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
>> their own command names
>>
>> This is my biggest and most important suggestion.
>>
>> "checkout -- foo.txt" copies foo.txt from NEXT to WTREE. Similarly,
>> "reset -- foo.txt" will copy foo.txt from HEAD to NEXT.
>
>  "checkout HEAD -- foo.txt" copies foo.txt from HEAD to NEXT and WTREE
>
>  "checkout HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT and WTREE
>  "reset HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT
>
>> These are operations to designate/undesignate files in the next commit
>> and should be grouped with others like them: "add", "rm" and "mv". (In
>> fact, the man page for "reset -- <file>" even says that it is the
>> opposite of "add"!)
>>
>> When these file-based operations are removed from "checkout" and
>> "reset", the purposes of those commands becomes clearer: "checkout"
>> changes HEAD to a new branch and "reset" moves the current branch
>> pointer to a different commit.  These operations may share code with
>> the operations "checkout -- <file>" and "reset -- <file>", but they
>> serve different purposes from the user's perspective and the user
>> should have different names to refer to them.
>>
>> As for naming these new commands, the "yet-another-porcelain" renames
>> "reset -- <file>" to "unadd", which I like very much.
>
> Well, that goes counter to reducing number of commands, but I quite
> like this name.  Though "unadd <revision> -- <file>" looks a bit
> strange...

I agree, that does look strange.  I think it would be the far less
frequent usage, but still strange.

>> For the other, my best suggestion is "head-to-next", but I'm sure
>> someone can do better.
>
> I'd rather remember that "git checkout" is about checking out
> something to a working area.

Now that I've separated these two usages of "checkout" in my brain,
"git checkout <branch>" is all about changing to a different branch.
That files in the working tree change is just incidental to moving to
the new branch.

The manpage paragraph for "git checkout -- <file>" has in bold that
this usage "does not switch branches".  So, for me, it's a completely
different usage and should be a different command.

I wish I had a reasonable name to suggest for the new command.

>> 4. Deemphasize the "branch" command for creating branches.
>>
>> I assumed that the command "branch" was used for creating branches.
>> After all, that's how it is done in the "gittutorial(7)" man page.
>
> It _is_ used to create branches.  But perhaps we should update
> gittutorial(7) (and check users manual)...

Thank you.

>> However, after reviewing all the major commands, I find that it is the
>> _last_ way I want to create a branch. It creates a new branch, but it
>> doesn't switch HEAD to the new branch!
>
> "checkout -b" is just shortcut for "branch" + "checkout".  Very
> convenient one, that is...

Yes, it's my primary way of making a branch now.

>> The commands that should be emphasized are "checkout -b <name>",
>> "commit -b <name>", and "stash branch".  These make sense in normal
>> git usage. The "branch" command has its uses but it is not usually the
>> way you want to create a branch.
> [...]
>
>> ----
>>
>> These are just some commands written in a not-quite-formal notation.
>> This notation doesn't handle a detached head, adding directories, the
>> state after a conflicted "stash pop", etc.  Still, as it is, I think
>> it's very informative to users for getting the gist of what command
>> does.
>>
>> "add foo.txt"
>>    NEXT:foo.txt = WTREE:foo.txt
>
> What about "add --intent-to-add foo.txt"?  What about "add <directory>"?
> What about resolving merge conflicts?

Good points.  These are all interesting cases that a fully developed
formal notation should make sure to address.

>> "rm foo.txt"
>>    delete(NEXT:foo.txt)
>>    delete(WTREE:foo.txt)
>> "rm --cached foo.txt"
>>    delete(NEXT:foo.txt)
>> "/bin/rm foo.txt"
>>    delete(WTREE:foo.txt)
>
> O.K.  Note however that "git rm foo.txt" on conflicted entry would
> clean up conflict.

Yes.  "git add foo.txt" is also used to resolve conflicts.

>> "mv foo.txt bar.txt"
>>    WTREE:bar.txt = WTREE:foo.txt
>>    NEXT.bar.txt = WTREE:foo.txt
>>    delete(WTREE:foo.txt)
>>    delete(NEXT:foo.txt)
>
> O.K., but what is important are atomicity and safety checks.

I think it's best to assume every operation is done atomically.
(Right?)   I'm not sure how to denote safety checks or prerequisites.

>> "checkout -- foo.txt"
>>    WTREE:foo.txt = NEXT:foo.txt
>> "reset -- foo.txt"
>>    NEXT:foo.txt = HEAD:foo.txt
>
> Those are not the only modes.
>
>> "commit"
>>    HEAD = new(HEAD + (NEXT-HEAD))
>>    NEXT = HEAD
>
>   HEAD + (NEXT-HEAD) == NEXT
>
> "git commit" doesn't apply patches.

Agreed.  I addressed this above.

>> "commit --amend"
>>    HEAD = new(HEAD^ + (NEXT-HEAD^))
>>    NEXT = HEAD
>
>  HEAD^ + (NEXT-HEAD^) == NEXT
>
> "git commit --amend" works correctly even if HEAD is a merge commit!

Another good issue.  A formal notation will need to specify how to
deal with cases of a commit with more than one predecessor.

>> "checkout FOO" (prequires WTREE==NEXT==HEAD)
>
> No such requirement.  It's all about which files differ between HEAD
> and FOO.  If you start working on some file, and decide that you
> should have made the change on different branch, "git checkout FOO"
> allow to move to FOO branch... assuming that changed file has the same
> contents in HEAD and in FOO.

Okay.  I will have to think about how a formal notation can denote that...

> End there is "checkout -f" and "checkout -m".
>
>>    WTREE = FOO
>>    NEXT = FOO
>>    HEAD ::= FOO // changes the alias of HEAD to refer to FOO
>
> And this is supposed to be easier to understand?

"checkout" is a very simple command to describe in English, so the
mathematical description will be more convoluted.  I don't (yet)
understand some of the variants of "git reset" even though they are
written in English.  I'm hoping a formal notation will make them
easier to understand.

>> "stash save"
>>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)
>>    NEXT = HEAD
>>    WTREE = HEAD
>>    push(STASH)
>> "stash pop"
>>    STASH = pop()
>>    WTREE = HEAD + (STASH-STASH^^)
>>    NEXT = HEAD + (STASH^-STASH^^)
>
> ???

"stash save" makes two new consecutive commits: one equal to NEXT and
another equal to WTREE.  (This is "STASH" above, with my
unoptimizations.)  I don't know where the SHA of the final commit gets
stored, so I just created push() and pop() commands.

Rereading the man page, the commit containing WTREE has two parents.
This notation doesn't have a way to denote that.

> [...]
>> "cherry-pick FOO" (prequires WTREE==NEXT==HEAD)
>>    HEAD = new(HEAD + (FOO - FOO^))
>>    NEXT = HEAD
>>    WTREE = HEAD
>> "rebase FOO" is basically a iterated application of "cherry-pick"
>
> Ordinary rebase isn't.
>
> --
> Jakub Narebski
> Poland
> ShadeHawk on #git
>

Jakub, thanks again for taking the time to respond.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-05  1:00     ` Michael Nahas
@ 2011-06-05 11:10       ` Jakub Narebski
  2011-06-05 18:39         ` Scott Chacon
  2011-06-05 21:22         ` Paul Ebermann
  0 siblings, 2 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-05 11:10 UTC (permalink / raw)
  To: Michael Nahas; +Cc: git

On Sun, 5 Jun 2011, Michael Nahas wrote:
> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>> Michael Nahas <mike.nahas@gmail.com> writes:
>>
>>> Quick list of recommendations:
>>>
>>> 1. Pick aliases for the next commit and the working tree that act like
>>>    commits on the command-line.
>>
>> No go.  This was asked for many times, and each time shot down.
>> Those "aliases" / pseudo-refs looks like commits but do not behave
>> exactly like commits.  This would increase connfusion.
> 
> I'm glad it was discussed.  I think users would know that those
> commits were special (they are writeable after all), but I'm sure more
> informed people than I made the same arguments.

Perhaps we should add conclusion / summary of this discussion either
somewhere on git wiki (http://git.wiki.kernel.org), or e.g. on gitcli(7)
manpage, so that it won't get reiterated again and again.  It is sort
of frequently asked question^W request.
 
>> See also gitcli(7) manpage for description of --index and --cached
>> options (and other git command line conventions).
> 
> Thanks for the pointer.  I've now read it.
[...]
>> BTW. have you read gitcli(7) manpage?
> 
> I have now.  I'd swear I've read close to 30 manpages but never
> heard-of/noticed that one until you mentioned it.  Thanks for the
> pointer; it's good to have --index and --cached clarified.

Hmmm... gitcli(7) is linked only from git(1) and git-rev-parse(1)
manpages.  Perhaps link to it should be added to user-manual at
least, to make it easier to find?

>>> 2. Adopt a (semi-)formal notation for describing what commands do.
>>
>> Whom it would help?  Not an ordinary user.
> 
> I think it would help experts in discussing exactly what happens.  For
> ordinary users that are hitting an intricate case (or don't know
> English very well), it would be good if there was something that would
> tell them mathematically what occurs.

Well, semi-formal notation could help, but I am not sure if it would
really be easier to understand than textual description.

There is also kind of "meta" problem: people who do not understand
English well instead of not understanding textual description of git
behavior would now not understand explanation of said formal notation.

  Cargill's quandary: "any design problem can be solved by adding an
  additional level of indirection, except for too many levels of
  indirection."

;-)

>>> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
>>>    their own command names
>>
>> Proposed "git unadd <pathspec>..." doesn't cover all features of
>> "git reset <rev> -- <path>" nor "git checkout [<rev>] -- <path>".
> 
> I'm confused.  How can it not cover all the features?  I'm just
> suggesting renaming the command.  From "git reset -- <path>" to "git
> unadd [--] <path>".

What about (well, more rarely used) "git reset <commit> -- <path>"?
But I quite like "git unadd" alias, even if "git unadd <commit> <path>"
looks strange; we have precedent in the form of "git stage" command
(alias).

> (And renaming "git checkout -- <path>" to some 
> yet-to-be-named other command.)

I think this one could be left as is, at least until a really good name
for said replacement appears ("git revert" means something else, and
"git revert-file" is a bit long, and can be confused with currently
not existing but proposed and discussed "git revert <revision> <pathspec>".)
 
>>> 4. Deemphasize the "branch" command for creating branches.
>>
>> Or add "git branch --checkout <newbranch>".
> 
> Would that operation be the different from the existing "git checkout
> -b <new branch>", or just another way to write it?

No, it would be just another way to do it.


>>> My recommendations are:
>>>
>>> 1. Pick aliases for the next commit and the working tree that act like
>>> commits on the command-line.
[...]
>>> For the alias for the next commit and working tree, I suggest "NEXT"
>>> and "WTREE".  Creating these aliases will make the interface more
>>> regular. It will remove oddities like "diff --cached FOO" and replace
>>> them with "diff NEXT FOO" and mean that "diff" and "diff FOO" can be
>>> explained as "diff WTREE NEXT" and "diff WTREE FOO".
>>
>> This idea ws proposed multiple time on git mailing list, and every
>> time it was rejected.
[...]
> That this idea has been brought up multiple times says that it does
> have some merit.  But apparently not enough merit.

No, this only means that people *think* it has merit.  And perhaps
that they are poisoned by Subversion's pseudo-refs ;-P 
 
>> BTW. both index and worktree have their own "aliases", namely ':0:'
>> for index (stage 0), and ':' or ':/' for top tree.
> 
> Really?  Where can these aliases be used?

Well, actually they _currently_ cannot be used in many places.

You can view version of file as it is in the index with

  $ git show :0:path/to/file

You can add file from a top of project directory (given new enough git;
I think it isn't in any released git version yet) with

  $ git add :/path/to/file

independently on subdirectory you are in (i.e. --full-tree).


But the main point was meant to be that even if there was some merit
to the pseudo-tree-ish aliases, ':0:' or '::' or ':0' would be better
that NEXT / STAGE / INDEX that looks like symbolic refs and therefore
commits but ain't, and ':/' would be better that WORK / WTREE.

I'm sorry, I should have written it more clearly.
 
>> Second, it doesn't solve issue of needing --cached and/or --index
>> swiches completely.  Those pseudo-almost-refs hide them for "git diff",
>> "git grep", "git ls-files", perhaps "git submodule" where we *read*
>> from index, but not for "git apply", "git rm" or "git stash" where
>> those swicthes affect *writing*.
> 
> I agree with you that it would not get rid of all switches.  I never
> expected it to.  My major aim was to simplify things like the "diff"
> command, which I have trouble remembering the different variations of.

You miss the point of this.  The issue is that you have to learn about
'--cached' and '--index' *anyway* (because pseudo-almost-refs do not
solve everything), and for consistency and backward compatibility we
need to support '--cached' for "git diff" etc., so you proposal brings
nothing but new thing to learn (and not only syntax, but quirks as well).

So you only add to required knowledgebase, not reduce it.

>>> 2. Adopt a notation for describing what commands do.
>>>
>>> I am sure in developer discussions there are descriptions of the
>>> "commit" command as something like:
>>>    HEAD = new(HEAD + (NEXT-HEAD))
>>>    NEXT = HEAD
>>
>> Basic algebra fail
>>
>>  HEAD + (NEXT-HEAD) == NEXT
>>
>> Besides "git commit" creates commit from state of index, no diffing or
>> patching is involved.
> 
> I would claim that the "state of index" is an approximation of
> (NEXT-HEAD).  Also, the new Tree and Blob objects that get written
> during the commit are another approximation of (NEXT-HEAD).  Neither
> of these is exactly a patch applied to HEAD, but that's the intent I
> was going for with my algebraic identity.  (It's not a fail; it's an
> unoptimization!)

It's still fail.  Git is at its repository model _snapshot_ based, not
_changeset_ (delta) based.  "git commit" takes _exact_ state of index,
and does not care about HEAD version.  Nb. your case does not cover
creating root commit (including but not limited to initial commit).

If you want to describe what "git commit" does it would be:

  commit = new Commit
  commit^{tree} = :0:       # or NEXT
  commit^ = HEAD^{commit}   # i.e. HEAD, but be more explicit
  HEAD@ = commit            # or @{0}, i.e. branch pointed by HEAD
                            # or HEAD itself if it is detached (no branch)
 
The above does not cover commit message, author and committer info,
and in some cases 'encoding' header (for commit message).

>>> Where "-" creates a patch between versions and + applies a patch.  Git
>>> already has some operators like "^", which refers to the parent of a
>>> commit. Those are useful for defining things like "commit --amend":
>>>    HEAD = new(HEAD^ + (NEXT-HEAD^))
>>>    NEXT = HEAD
>>
>> Which is again not true.

Again, snapshot, not delta.
 
> [Addressed below, where the "what if HEAD is a merge commit with
> multiple predecessors" is mentioned.]
> 
>>> Having this notation and using it in the man pages will make the exact
>>> nature of the operation clear. (Right now, it takes a lot of reading
>>> to figure out what happens to NEXT with the various command-line
>>> options of "reset".)
>>
>> It's not that difficult: only "git reset --soft [<rev>]" doesn't
>> affect index.
>>
>> Hrmmm... how this notation would explain differences between
>> "git reset --hard", "git reset --keep" and "git reset --merge"?
> 
> I don't understand what "git reset --keep" and "git reset --merge" do.
> I've read the manpage but am still confused.  One of my reasons for
> suggesting a notation is so that there is a clear mathematical
> representation of what the commands do.  Once I understand them, I can
> make an attempt at a notation that can explain them.

What I meant here is that above notation wouldn't help explaining the
differences between --hard, --keep and --merge.  Perhaps a table could
help there.

But IMVHO is more important for documentation to tell *when* one would
use one or another, not how they work.
 
[...]
>>> [I've included git commands in a not-formal-enough notation at the end
>>> of this email.]
>>
>> NEVERTHELESS some kind of semi-formal notation might be useful.
> 
> I'm glad you agree.  Do you think my not-formal-enough notation is a
> good start or do you want to propose another notation to start from?

Well, I am not sure if it is good enough idea to waste time on it...
Hmmm... maybe revctrl.org guys would be interested?  Just a thought.

>>> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
>>> their own command names
>>>
>>> This is my biggest and most important suggestion.
>>>
>>> "checkout -- foo.txt" copies foo.txt from NEXT to WTREE. Similarly,
>>> "reset -- foo.txt" will copy foo.txt from HEAD to NEXT.
>>
>>  "checkout HEAD -- foo.txt" copies foo.txt from HEAD to NEXT and WTREE
>>
>>  "checkout HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT and WTREE
>>  "reset HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT
>>
>>> These are operations to designate/undesignate files in the next commit
>>> and should be grouped with others like them: "add", "rm" and "mv". (In
>>> fact, the man page for "reset -- <file>" even says that it is the
>>> opposite of "add"!)
[...]

>>> For the other, my best suggestion is "head-to-next", but I'm sure
>>> someone can do better.
>>
>> I'd rather remember that "git checkout" is about checking out
>> something to a working area.
> 
> Now that I've separated these two usages of "checkout" in my brain,
> "git checkout <branch>" is all about changing to a different branch.
> That files in the working tree change is just incidental to moving to
> the new branch.
> 
> The manpage paragraph for "git checkout -- <file>" has in bold that
> this usage "does not switch branches".  So, for me, it's a completely
> different usage and should be a different command.

For me it is about "checking out" two different entities: a branch
(or related case of non-branch ref, e.g. "git checkout v1.7.3", or
"git checkout HEAD~2"), or a pathspec (file or directory).  Checking
out branch means making it current branch, checking out file means
making this version of a file current.
 
> I wish I had a reasonable name to suggest for the new command.

Good name is a required prerequisite here, unfortunately...

[cut]

>>> "commit --amend"
>>>    HEAD = new(HEAD^ + (NEXT-HEAD^))
>>>    NEXT = HEAD
>>
>>  HEAD^ + (NEXT-HEAD^) == NEXT
>>
>> "git commit --amend" works correctly even if HEAD is a merge commit!
> 
> Another good issue.  A formal notation will need to specify how to
> deal with cases of a commit with more than one predecessor.

Perhaps, in extension notation proposed for describing what "git commit"
does perhaps

   commit^@ = HEAD^@

or just

   commit = copy(HEAD^{commit})
   commit^{tree} = :0:
 
Note however that "git commit" has more modes.  Not including exotic
ones there is "git commit -a", "git commit [--only] <file>", and
rarely used "git commit --include <file>".

>>> "checkout FOO" (prequires WTREE==NEXT==HEAD)
>>
>> No such requirement.  It's all about which files differ between HEAD
>> and FOO.  If you start working on some file, and decide that you
>> should have made the change on different branch, "git checkout FOO"
>> allow to move to FOO branch... assuming that changed file has the same
>> contents in HEAD and in FOO.
> 
> Okay.  I will have to think about how a formal notation can denote that...

I think that table with HEAD version, worktree version, switched to branch
version, and result for plain checkout, -f/--force and -m/--merge would
be a better solution than formal notation.

>>>    WTREE = FOO
>>>    NEXT = FOO
>>>    HEAD ::= FOO // changes the alias of HEAD to refer to FOO
>>
>> And this is supposed to be easier to understand?
> 
> "checkout" is a very simple command to describe in English, so the
> mathematical description will be more convoluted.  I don't (yet)
> understand some of the variants of "git reset" even though they are
> written in English.  I'm hoping a formal notation will make them
> easier to understand.

Hmmm...
 
>>> "stash save"
>>>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)
>>>    NEXT = HEAD
>>>    WTREE = HEAD
>>>    push(STASH)
>>> "stash pop"
>>>    STASH = pop()
>>>    WTREE = HEAD + (STASH-STASH^^)
>>>    NEXT = HEAD + (STASH^-STASH^^)
>>
>> ???
> 
> "stash save" makes two new consecutive commits: one equal to NEXT and
> another equal to WTREE.

No, "stash save" doesn't make two _consecutive_ commits.  It makes
a commit which has state of worktree as one parent, and state of index
as other parent (i.e. a merge commit).

> (This is "STASH" above, with my unoptimizations.)
> I don't know where the SHA of the final commit gets 
> stored, so I just created push() and pop() commands.

It is stored in 'refs/stash' and its reflog.
 
> Rereading the man page, the commit containing WTREE has two parents.
> This notation doesn't have a way to denote that.

Right.
 
-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-05 11:10       ` Jakub Narebski
@ 2011-06-05 18:39         ` Scott Chacon
  2011-06-05 23:37           ` Jakub Narebski
  2011-06-06  6:16           ` Junio C Hamano
  2011-06-05 21:22         ` Paul Ebermann
  1 sibling, 2 replies; 98+ messages in thread
From: Scott Chacon @ 2011-06-05 18:39 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Michael Nahas, git

Hey,

On Sun, Jun 5, 2011 at 4:10 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> On Sun, 5 Jun 2011, Michael Nahas wrote:
>> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>>> Michael Nahas <mike.nahas@gmail.com> writes:
>>>
>>>> Quick list of recommendations:
>>>>
>>>> 1. Pick aliases for the next commit and the working tree that act like
>>>>    commits on the command-line.
>>>
>>> No go.  This was asked for many times, and each time shot down.
>>> Those "aliases" / pseudo-refs looks like commits but do not behave
>>> exactly like commits.  This would increase connfusion.
>>
>> I'm glad it was discussed.  I think users would know that those
>> commits were special (they are writeable after all), but I'm sure more
>> informed people than I made the same arguments.
>
> Perhaps we should add conclusion / summary of this discussion either
> somewhere on git wiki (http://git.wiki.kernel.org), or e.g. on gitcli(7)
> manpage, so that it won't get reiterated again and again.  It is sort
> of frequently asked question^W request.

Can you cite any of these threads please?  I also thought this was a
reasonable suggestion and don't remember these previous discussions.
Also, to be fair, I've been pretty active in this community for a long
time now and I honestly don't ever remember seeing the 'gitcli'
manpage, so don't feel too bad Michael.

>
>>>> 2. Adopt a (semi-)formal notation for describing what commands do.
>>>
>>> Whom it would help?  Not an ordinary user.
>>
>> I think it would help experts in discussing exactly what happens.  For
>> ordinary users that are hitting an intricate case (or don't know
>> English very well), it would be good if there was something that would
>> tell them mathematically what occurs.
>
> Well, semi-formal notation could help, but I am not sure if it would
> really be easier to understand than textual description.

I think some notational format like this would be way, way easier to
understand than, for instance, the current git-reset page, which is
almost impossible to follow.

> What about (well, more rarely used) "git reset <commit> -- <path>"?
> But I quite like "git unadd" alias, even if "git unadd <commit> <path>"
> looks strange; we have precedent in the form of "git stage" command
> (alias).
>

I actually sort of dislike the idea of an alias, even though I'm
probably mostly to blame for the introduction of the 'git stage' alias
in the first place.  I do feel, however, that 'reset' and 'checkout'
are horribly and confusingly overloaded and introducing a couple of
new porcelain commands to do a subset of their functionality in a
safer and more friendly manner would be hugely helpful.  I would
actually like to start treating 'reset' as more of a plumbing command,
since it is so incredibly confusing and does so many different things.
 I think it would be better to introduce things like 'unadd' or
'unstage', 'revert-file' to revert file contents in the work tree,
'uncommit' to do 'reset HEAD~', 'unmerge' to do a 'reset --hard' but
check that we are in a conflicted merge state, etc.

Not just aliases, but commands that run 'reset' or 'checkout' in the
background but have command specific options and help pages.  Knowing
that 'reset' is how you do all of these things is not intuitive.
Knowing that some options to 'reset' and 'checkout' are work tree
unsafe and others are safe is not intuitive in addition to scaring
people into not using or figuring out the other options because
they're scared of the unsafe invocations.

>> (And renaming "git checkout -- <path>" to some
>> yet-to-be-named other command.)
>
> I think this one could be left as is, at least until a really good name
> for said replacement appears ("git revert" means something else, and
> "git revert-file" is a bit long, and can be confused with currently
> not existing but proposed and discussed "git revert <revision> <pathspec>".)

I would really like to not introduce more ways of making one command
do totally different things depending on if it gets a file path
limiter or not.


>>>> My recommendations are:
>>>>
>>>> 1. Pick aliases for the next commit and the working tree that act like
>>>> commits on the command-line.
> [...]
>>>> For the alias for the next commit and working tree, I suggest "NEXT"
>>>> and "WTREE".  Creating these aliases will make the interface more
>>>> regular. It will remove oddities like "diff --cached FOO" and replace
>>>> them with "diff NEXT FOO" and mean that "diff" and "diff FOO" can be
>>>> explained as "diff WTREE NEXT" and "diff WTREE FOO".
>>>
>>> This idea ws proposed multiple time on git mailing list, and every
>>> time it was rejected.
> [...]
>> That this idea has been brought up multiple times says that it does
>> have some merit.  But apparently not enough merit.
>
> No, this only means that people *think* it has merit.  And perhaps
> that they are poisoned by Subversion's pseudo-refs ;-P

Just for the record, I've never used Subversion, have a pretty solid
understanding of Git internals and I thought this was a good idea.
For example, implementation details aside, I think having something
like WTREE and NEXT available would help users understand that there
are these 3 trees that are important and useful in Git and re-inforce
a very non-SVN style workflow in that manner.

Having people learn '--cached', which just makes no sense in most
contexts, is confusing.  It's great that it's there, but it's not
necessary to know the difference to use git in almost any
circumstances.  I never remember what the difference is, but I rarely,
if ever, run into a case where I need to use one where I haven't just
memorized the invocation I need. For example, 'rm --cached', and 'diff
--cached' are just commands I use because I know what they do, not
because I remember the semantics of --cached over --index (if --index
even is applicable in these cases, which I don't think it is).

>
>>> BTW. both index and worktree have their own "aliases", namely ':0:'
>>> for index (stage 0), and ':' or ':/' for top tree.
>>
>> Really?  Where can these aliases be used?
>
> Well, actually they _currently_ cannot be used in many places.
>
> You can view version of file as it is in the index with
>
>  $ git show :0:path/to/file
>
> You can add file from a top of project directory (given new enough git;
> I think it isn't in any released git version yet) with
>
>  $ git add :/path/to/file
>
> independently on subdirectory you are in (i.e. --full-tree).
>
>
> But the main point was meant to be that even if there was some merit
> to the pseudo-tree-ish aliases, ':0:' or '::' or ':0' would be better
> that NEXT / STAGE / INDEX that looks like symbolic refs and therefore
> commits but ain't, and ':/' would be better that WORK / WTREE.

Please be kidding.

I just don't understand how you can honestly suggest to someone that
"git show :0:/path/to/file.txt" makes more sense to anyone then "git
show NEXT:/path/to/file.txt" would.  I have no idea if ':0:' or '::'
work anywhere, but if they ever do, I guarantee they will be used by
practically nobody.

>>> Second, it doesn't solve issue of needing --cached and/or --index
>>> swiches completely.  Those pseudo-almost-refs hide them for "git diff",
>>> "git grep", "git ls-files", perhaps "git submodule" where we *read*
>>> from index, but not for "git apply", "git rm" or "git stash" where
>>> those swicthes affect *writing*.
>>
>> I agree with you that it would not get rid of all switches.  I never
>> expected it to.  My major aim was to simplify things like the "diff"
>> command, which I have trouble remembering the different variations of.

Nearly everybody does, which is why I also believe his argument has merit.

> You miss the point of this.  The issue is that you have to learn about
> '--cached' and '--index' *anyway* (because pseudo-almost-refs do not
> solve everything), and for consistency and backward compatibility we
> need to support '--cached' for "git diff" etc., so you proposal brings
> nothing but new thing to learn (and not only syntax, but quirks as well).
>
> So you only add to required knowledgebase, not reduce it.

Though I already argued against this, I would reiterate it.  You do
not have to learn about those switches to use Git.  You don't have to
be able to do everything in Git before you can do anything.  I do not
know of a single command I've ever used where I needed to know the
difference - it almost never comes up in daily use for nearly all Git
users.  Can you come up with an example other than 'apply' that takes
both options?  If a user doesn't use 'apply' (and I think the vast
majority doesn't), then a simpler alternative that is more universally
applicable would reduce the required knowledgebase for almost all Git
users.


>>> Hrmmm... how this notation would explain differences between
>>> "git reset --hard", "git reset --keep" and "git reset --merge"?
>>
>> I don't understand what "git reset --keep" and "git reset --merge" do.
>> I've read the manpage but am still confused.  One of my reasons for
>> suggesting a notation is so that there is a clear mathematical
>> representation of what the commands do.  Once I understand them, I can
>> make an attempt at a notation that can explain them.
>
> What I meant here is that above notation wouldn't help explaining the
> differences between --hard, --keep and --merge.  Perhaps a table could
> help there.
>
> But IMVHO is more important for documentation to tell *when* one would
> use one or another, not how they work.

Just to I also have no idea how to use --keep and --merge. I think it
would be useful to have both - I've read the one example of how to use
--keep, but I've never used it and if I ran into that specific
use-case, I'm sure I wouldn't even remember that something was there
to help.

>>>> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
>>>> their own command names
>>>>
>>>> This is my biggest and most important suggestion.
>>>>
>>>> "checkout -- foo.txt" copies foo.txt from NEXT to WTREE. Similarly,
>>>> "reset -- foo.txt" will copy foo.txt from HEAD to NEXT.
>>>
>>>  "checkout HEAD -- foo.txt" copies foo.txt from HEAD to NEXT and WTREE
>>>
>>>  "checkout HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT and WTREE
>>>  "reset HEAD^ -- foo.txt" copies foo.txt from HEAD^ to NEXT
>>>
>>>> These are operations to designate/undesignate files in the next commit
>>>> and should be grouped with others like them: "add", "rm" and "mv". (In
>>>> fact, the man page for "reset -- <file>" even says that it is the
>>>> opposite of "add"!)
> [...]
>
>>>> For the other, my best suggestion is "head-to-next", but I'm sure
>>>> someone can do better.
>>>
>>> I'd rather remember that "git checkout" is about checking out
>>> something to a working area.
>>
>> Now that I've separated these two usages of "checkout" in my brain,
>> "git checkout <branch>" is all about changing to a different branch.
>> That files in the working tree change is just incidental to moving to
>> the new branch.
>>
>> The manpage paragraph for "git checkout -- <file>" has in bold that
>> this usage "does not switch branches".  So, for me, it's a completely
>> different usage and should be a different command.
>
> For me it is about "checking out" two different entities: a branch
> (or related case of non-branch ref, e.g. "git checkout v1.7.3", or
> "git checkout HEAD~2"), or a pathspec (file or directory).  Checking
> out branch means making it current branch, checking out file means
> making this version of a file current.
>
>> I wish I had a reasonable name to suggest for the new command.
>
> Good name is a required prerequisite here, unfortunately...

Actually, I'm pretty sure even an amazing name wouldn't help here.
I'm a bit surprised that you would reference the previous WTREE/NEXT
discussions, but not the discussions we've had on this topic:

http://thread.gmane.org/gmane.comp.version-control.git/121206/focus=121317

I've brought up splitting checkout and simplifying some commands the
way EasyGit has done and none other than Linus himself shot it down
and that was nearly 2 years ago.  Sadly, the chances of getting any UI
improvements of this nature in seem quite remote, and have been for
some time.

I would like to thank Michael for taking so much time to propose a
thoughtful response to the UI issues that so many people struggle with
instead of just complaining, as most do.

I would love if we could compile suggestions like these and shoot for
a Git 2.0 with a much nicer UI and help system.  However, it seems
unlikely that Junio would go for this.  It seems somewhat more likely
that what would happen is that a simpler, cleaner libgit2 based cli
would emerge at some point with an 80% most-used functionality and
super nice UI mentality, but that wouldn't be for some time.

Scott

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-05 11:10       ` Jakub Narebski
  2011-06-05 18:39         ` Scott Chacon
@ 2011-06-05 21:22         ` Paul Ebermann
  1 sibling, 0 replies; 98+ messages in thread
From: Paul Ebermann @ 2011-06-05 21:22 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Michael Nahas, git

Jakub Narebski skribis:
> On Sun, 5 Jun 2011, Michael Nahas wrote:
>> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>>> Michael Nahas <mike.nahas@gmail.com> writes:
[...]
>>>> "stash save"
>>>>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)
>>>>    NEXT = HEAD
>>>>    WTREE = HEAD
>>>>    push(STASH)
>>>> "stash pop"
>>>>    STASH = pop()
>>>>    WTREE = HEAD + (STASH-STASH^^)
>>>>    NEXT = HEAD + (STASH^-STASH^^)
>>>
>>> ???
>>
>> "stash save" makes two new consecutive commits: one equal to NEXT and
>> another equal to WTREE.
> 
> No, "stash save" doesn't make two _consecutive_ commits.  It makes
> a commit which has state of worktree as one parent, and state of index
> as other parent (i.e. a merge commit).

Hmm, for me it always looked like one commit with the index state as
content and HEAD as parent, and second one with the Worktree as content,
and both HEAD and the mentioned index commit as parent.

This is technically a merge commit (as it has two parents), but not
really done as a merge.


Paul

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-04 16:17 ` Command-line interface thoughts Michael Nahas
  2011-06-04 21:49   ` Jakub Narebski
@ 2011-06-05 21:34   ` Paul Ebermann
  1 sibling, 0 replies; 98+ messages in thread
From: Paul Ebermann @ 2011-06-05 21:34 UTC (permalink / raw)
  To: git; +Cc: mike, Michael Nahas

Michael Nahas skribis:

> "commit"
>    HEAD = new(HEAD + (NEXT-HEAD))
>    NEXT = HEAD
> "commit --amend"
>    HEAD = new(HEAD^ + (NEXT-HEAD^))
>    NEXT = HEAD

A better notation for creating a new commit would be something that
takes both the contents and the parents as arguments.

"commit:"
  HEAD = new(NEXT, HEAD)
  NEXT = HEAD
"commit --amend"
  HEAD = new(NEXT, all-parents-of(HEAD))
  NEXT = HEAD

> "stash save"
>    STASH = new(new(HEAD+(NEXT-HEAD))+WTREE-NEXT)
>    NEXT = HEAD
>    WTREE = HEAD
>    push(STASH)

"stash save"
  STASH = new(WTREE, HEAD, new(NEXT, HEAD))
  NEXT = HEAD
  WTREE = HEAD
  push(STASH)

And similar.


Paul

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-05 18:39         ` Scott Chacon
@ 2011-06-05 23:37           ` Jakub Narebski
  2011-06-06  6:16           ` Junio C Hamano
  1 sibling, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-05 23:37 UTC (permalink / raw)
  To: Scott Chacon; +Cc: Michael Nahas, git

Hey,

On Sun, 5 Jun 2011, Scott Chacon wrote:
> On Sun, Jun 5, 2011 at 4:10 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>> On Sun, 5 Jun 2011, Michael Nahas wrote:
>>> On Sat, Jun 4, 2011 at 5:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>>>> Michael Nahas <mike.nahas@gmail.com> writes:
>>>>
>>>>> Quick list of recommendations:
>>>>>
>>>>> 1. Pick aliases for the next commit and the working tree that act like
>>>>>    commits on the command-line.
>>>>
>>>> No go.  This was asked for many times, and each time shot down.
>>>> Those "aliases" / pseudo-refs looks like commits but do not behave
>>>> exactly like commits.  This would increase connfusion.
>>>
>>> I'm glad it was discussed.  I think users would know that those
>>> commits were special (they are writeable after all), but I'm sure more
>>> informed people than I made the same arguments.
>>
>> Perhaps we should add conclusion / summary of this discussion either
>> somewhere on git wiki (http://git.wiki.kernel.org), or e.g. on gitcli(7)
>> manpage, so that it won't get reiterated again and again.  It is sort
>> of frequently asked question^W request.
> 
> Can you cite any of these threads please?  I also thought this was a
> reasonable suggestion and don't remember these previous discussions.

Somewhere in this thread:

  "[RFC/PATCH 0/2] New 'stage' command"
  http://thread.gmane.org/gmane.comp.version-control.git/115666/focus=115880
  (STAGE and WORKTREE pseudo-ref aliases)

And I think it was not the only one, but is the only one I have saved
(bookmarked).  Unfortunately searching for such thread needs case sensitive
search, and most searches ain't.

> Also, to be fair, I've been pretty active in this community for a long
> time now and I honestly don't ever remember seeing the 'gitcli'
> manpage, so don't feel too bad Michael.

Well, gitcli(7) is referenced only from git(1) and from git-rev-parse(1)
manpages, and was added in 2f7ee08 (parse-options: Add a gitcli(5) man
page., 2007-12-13) [v1.5.4-rc2~14], as I wrote.

It should really be referenced in git tutorials and in user's manual.

>>
>>>>> 2. Adopt a (semi-)formal notation for describing what commands do.
>>>>
>>>> Whom it would help?  Not an ordinary user.
>>>
>>> I think it would help experts in discussing exactly what happens.  For
>>> ordinary users that are hitting an intricate case (or don't know
>>> English very well), it would be good if there was something that would
>>> tell them mathematically what occurs.
>>
>> Well, semi-formal notation could help, but I am not sure if it would
>> really be easier to understand than textual description.
> 
> I think some notational format like this would be way, way easier to
> understand than, for instance, the current git-reset page, which is
> almost impossible to follow.

Not all can be solved by semi-formal, semi-mathematical notation, but it,
together with tables (a problem for manpages, though), and ABNF for 
technical documentation would help, sure.

It is unfortunate that to know what to write in manpage you need to be
a bit of expert, and when you are expert you usually loose sight on how
to write manpage readable for new / non-expert user ;-)  Maybe it would
be a good task for Google Code-In?

>> What about (well, more rarely used) "git reset <commit> -- <path>"?
>> But I quite like "git unadd" alias, even if "git unadd <commit> <path>"
>> looks strange; we have precedent in the form of "git stage" command
>> (alias).
> 
> I actually sort of dislike the idea of an alias, even though I'm
> probably mostly to blame for the introduction of the 'git stage' alias
> in the first place.

Well, because of backward compatibility we would need to keep supporting
"git checkout -- <path>", "git checkout <commit> -- <path>", and
"git reset -- <path>".  That's why I used 'alias' name.

> I do feel, however, that 'reset' and 'checkout' 
> are horribly and confusingly overloaded and introducing a couple of
> new porcelain commands to do a subset of their functionality in a
> safer and more friendly manner would be hugely helpful.

Well, AFAIK responsible for some of this overloading was "git is difficult
because it has too many commands" mantra... though I am not sure if putting
overloading commands really helps.

But the notion of checking out file, or reseting file is quite natural...
at least for native English speaker.  I think in most natural languages
there are words that have more than one meaning.


NOTE that information in "git status" output, and in template for commit
message is *extremely* helpful because it explains in exact detail what
you can do!

> I would 
> actually like to start treating 'reset' as more of a plumbing command,
> since it is so incredibly confusing and does so many different things.
>  I think it would be better to introduce things like 'unadd' or
> 'unstage', 

Would need both, most probably.  I don't know how widespread is using of
"stage" command, but I think old timers are used to "git add".

> 'revert-file' to revert file contents in the work tree, 

Bit longish, but quite all right.

> 'uncommit' to do 'reset HEAD~',

Not "git reset --soft HEAD"?

> 'unmerge' to do a 'reset --hard' but 
> check that we are in a conflicted merge state, etc.

I think you meant "git reset --merge" here.  Nevertheless it might be
a good addition because of safety check.  Like "git mv" which is wrapper
around "git rm" and "mv"/"cp" and "git add", but with safety check.

> Not just aliases, but commands that run 'reset' or 'checkout' in the
> background but have command specific options and help pages.

If proliferation of command is problem, it might be "git add --undo"
instead of "git unadd"... but then there is problem with 
"git unadd <commit> <file>".

> Knowing that 'reset' is how you do all of these things is not intuitive.

Thanks to "git status" output knowledge is not really necessary.  It is
written there in detail.

But it is true that guessing by ones own that forms of git-checkout and
git-reset is how you do it require good knowledge of "git model".

> Knowing that some options to 'reset' and 'checkout' are work tree
> unsafe and others are safe is not intuitive in addition to scaring
> people into not using or figuring out the other options because
> they're scared of the unsafe invocations.

Errr... "git checkout" in its branch switching version is always safe,
unless you use "--force".  The forms of "checkout" and "reset" that
are about checking out and reseting file are of course this file unsafe.
Duh.  Well, "git reset --hard" could get "--force" safety check... but
then it would be quite annoying and harder to use.

>>> (And renaming "git checkout -- <path>" to some
>>> yet-to-be-named other command.)
>>
>> I think this one could be left as is, at least until a really good name
>> for said replacement appears ("git revert" means something else, and
>> "git revert-file" is a bit long, and can be confused with currently
>> not existing but proposed and discussed "git revert <revision> <pathspec>".)
> 
> I would really like to not introduce more ways of making one command
> do totally different things depending on if it gets a file path
> limiter or not.

You probably don't like Perl with its context-dependency and TIMTOWTDI
("there is more than one way to do it")... ;-P

>>>>> My recommendations are:
>>>>>
>>>>> 1. Pick aliases for the next commit and the working tree that act like
>>>>> commits on the command-line.
>> [...]
>>>>> For the alias for the next commit and working tree, I suggest "NEXT"
>>>>> and "WTREE".  Creating these aliases will make the interface more
>>>>> regular. It will remove oddities like "diff --cached FOO" and replace
>>>>> them with "diff NEXT FOO" and mean that "diff" and "diff FOO" can be
>>>>> explained as "diff WTREE NEXT" and "diff WTREE FOO".
>>>>
>>>> This idea ws proposed multiple time on git mailing list, and every
>>>> time it was rejected.
>> [...]
>>> That this idea has been brought up multiple times says that it does
>>> have some merit.  But apparently not enough merit.
>>
>> No, this only means that people *think* it has merit.  And perhaps
>> that they are poisoned by Subversion's pseudo-refs ;-P
> 
> Just for the record, I've never used Subversion, have a pretty solid
> understanding of Git internals and I thought this was a good idea.
> For example, implementation details aside, I think having something
> like WTREE and NEXT available would help users understand that there
> are these 3 trees that are important and useful in Git and re-inforce
> a very non-SVN style workflow in that manner.

These are not quite tree-ish, because of index stages, and of ignored
and other (untracked not ignored) files in worktree.  And they are
not at all commit-ish/revision or symrefs, like name hints.
 
> Having people learn '--cached', which just makes no sense in most
> contexts, is confusing.  It's great that it's there, but it's not
> necessary to know the difference to use git in almost any
> circumstances.  I never remember what the difference is, but I rarely,
> if ever, run into a case where I need to use one where I haven't just
> memorized the invocation I need. For example, 'rm --cached', and 'diff
> --cached' are just commands I use because I know what they do, not
> because I remember the semantics of --cached over --index (if --index
> even is applicable in these cases, which I don't think it is).

Because --index is about affecting _also_ index, i.e. about affecting
index and working tree _together_, it is quite rare: only "git apply"
and "git stash" use it.

So --cached means proposed NEXT / STAGE.  It is used by "diff", "grep",
"ls-files", "rm", "submodule".  From those only in "git diff" there
might be trouble remembering, because diff is about 2 endpoints.

BTW. gitcli(7) manpage mentions http://marc.info/?l=git&m=116563135620359
(talking about --cached vs --index, and why both are necessary) and
http://marc.info/?l=git&m=119150393620273 (differences between --cached
and index, and about "git apply" that has three modes: "git apply", 
"git apply --cached" and "git apply --index").
 
>>>> BTW. both index and worktree have their own "aliases", namely ':0:'
>>>> for index (stage 0), and ':' or ':/' for top tree.
>>>
>>> Really?  Where can these aliases be used?
>>
>> Well, actually they _currently_ cannot be used in many places.
>>
>> You can view version of file as it is in the index with
>>
>>  $ git show :0:path/to/file
>>
>> You can add file from a top of project directory (given new enough git;
>> I think it isn't in any released git version yet) with
>>
>>  $ git add :/path/to/file
>>
>> independently on subdirectory you are in (i.e. --full-tree).
>>
>>
>> But the main point was meant to be that even if there was some merit
>> to the pseudo-tree-ish aliases, ':0:' or '::' or ':0' would be better
>> that NEXT / STAGE / INDEX that looks like symbolic refs and therefore
>> commits but ain't, and ':/' would be better that WORK / WTREE.
> 
> Please be kidding.
> 
> I just don't understand how you can honestly suggest to someone that
> "git show :0:/path/to/file.txt" makes more sense to anyone then "git
> show NEXT:/path/to/file.txt" would.  I have no idea if ':0:' or '::'
> work anywhere, but if they ever do, I guarantee they will be used by
> practically nobody.

Note that it is :0:, :1:, :2:, :3:, i.e. you can refer to individual
stages for unmerged file.  Though perhaps people use --base, --ours,
--theirs instead... though this is not very widely supported. :0:file
works anywhere, because it is revspec.

The problem wit HEAD-like NEXT / STAGE pseudo-ref is that it looks like
commit but does not behave like commit.  Even looking at it as tree-ish
is [slight] oversimplification.
 
>>>> Second, it doesn't solve issue of needing --cached and/or --index
>>>> swiches completely.  Those pseudo-almost-refs hide them for "git diff",
>>>> "git grep", "git ls-files", perhaps "git submodule" where we *read*
>>>> from index, but not for "git apply", "git rm" or "git stash" where
>>>> those swicthes affect *writing*.
>>>
>>> I agree with you that it would not get rid of all switches.  I never
>>> expected it to.  My major aim was to simplify things like the "diff"
>>> command, which I have trouble remembering the different variations of.
> 
> Nearly everybody does, which is why I also believe his argument has merit.

It's only "git diff" that have problems, because of peculiarity of it
that it comares 2 things.  What is second one, that can be confusing:
"git diff", "git diff --cached", "git diff HEAD":

                worktree
                  |   \
                  |    \  diff
                  |     v
       diff HEAD  |     index
                  |     /
                  |    /  diff --cached
                  v   v
                  HEAD   


I don't think anybody has problems understanding and remembering 
"git grep --cached" and "git rm --cached"... and while you could use
"git grep NEXT", "git rm NEXT" doesn't make sense -- "--cached" is
target designator, not source designator here.
 
>> You miss the point of this.  The issue is that you have to learn about
>> '--cached' and '--index' *anyway* (because pseudo-almost-refs do not
>> solve everything), and for consistency and backward compatibility we
>> need to support '--cached' for "git diff" etc., so you proposal brings
>> nothing but new thing to learn (and not only syntax, but quirks as well).
>>
>> So you only add to required knowledgebase, not reduce it.
> 
> Though I already argued against this, I would reiterate it.  You do
> not have to learn about those switches to use Git.  You don't have to
> be able to do everything in Git before you can do anything.  I do not
> know of a single command I've ever used where I needed to know the
> difference - it almost never comes up in daily use for nearly all Git
> users.  

In most cases you use "--cached".  Is it that much of a problem to
remember it (with possible exception of mentioned "git diff" complication)
compared to WHATEVER (NEXT or STAGE or INDEX)?

> Can you come up with an example other than 'apply' that takes 
> both options?  If a user doesn't use 'apply' (and I think the vast
> majority doesn't), then a simpler alternative that is more universally
> applicable would reduce the required knowledgebase for almost all Git
> users.

But you would need both of those options for "git apply", and pseudo-refs
does not really work here in either case - it is target designator, not
source designator. 
 
There is no other command that takes both, but there is --index for stash:
"git stash --index apply".

>>>> Hrmmm... how this notation would explain differences between
>>>> "git reset --hard", "git reset --keep" and "git reset --merge"?
>>>
>>> I don't understand what "git reset --keep" and "git reset --merge" do.
>>> I've read the manpage but am still confused.  One of my reasons for
>>> suggesting a notation is so that there is a clear mathematical
>>> representation of what the commands do.  Once I understand them, I can
>>> make an attempt at a notation that can explain them.
>>
>> What I meant here is that above notation wouldn't help explaining the
>> differences between --hard, --keep and --merge.  Perhaps a table could
>> help there.
>>
>> But IMVHO is more important for documentation to tell *when* one would
>> use one or another, not how they work.
> 
> Just to I also have no idea how to use --keep and --merge. I think it
> would be useful to have both - I've read the one example of how to use
> --keep, but I've never used it and if I ran into that specific
> use-case, I'm sure I wouldn't even remember that something was there
> to help.

"git reset --merge", as the name hints, is to be used to 'nuke' botched
merge.  "git reset --keep" is safe way of rewinding which won't nuke
your changes by accident... as far as I understand it.  The documentation
is suboptimal at best, I certainly agree.
 
>>>>> 3. Move the operations "checkout -- <file>" and "reset -- <file>" to
>>>>> their own command names
[...]
>>> The manpage paragraph for "git checkout -- <file>" has in bold that
>>> this usage "does not switch branches".  So, for me, it's a completely
>>> different usage and should be a different command.
>>
>> For me it is about "checking out" two different entities: a branch
>> (or related case of non-branch ref, e.g. "git checkout v1.7.3", or
>> "git checkout HEAD~2"), or a pathspec (file or directory).  Checking
>> out branch means making it current branch, checking out file means
>> making this version of a file current.
>>
>>> I wish I had a reasonable name to suggest for the new command.
>>
>> Good name is a required prerequisite here, unfortunately...
> 
> Actually, I'm pretty sure even an amazing name wouldn't help here.

"Required" prerequisite does not mean "sufficient" prerequisite.

> I'm a bit surprised that you would reference the previous WTREE/NEXT
> discussions, but not the discussions we've had on this topic:
> 
> http://thread.gmane.org/gmane.comp.version-control.git/121206/focus=121317
> 
> I've brought up splitting checkout and simplifying some commands the
> way EasyGit has done and none other than Linus himself shot it down
> and that was nearly 2 years ago.  Sadly, the chances of getting any UI
> improvements of this nature in seem quite remote, and have been for
> some time.

As I wrote above (independently), some like context-aware grammar
(c.f. Perl), some loathe it ;-PPP

Besides, now we have "git status" hints...
 
> I would like to thank Michael for taking so much time to propose a
> thoughtful response to the UI issues that so many people struggle with
> instead of just complaining, as most do.

Even if there would be no new commands like "git unadd", and there
wouldn't be NEXT / STAGE / INDEX nor WTREE / WORK / WORKTREE pseudo-symrefs,
perhaps it would lead to improved documentation; even if not pseudo-formal
specification, at least mentioning gitcli(7) in more places.
 
> I would love if we could compile suggestions like these and shoot for
> a Git 2.0 with a much nicer UI and help system.  However, it seems
> unlikely that Junio would go for this.  It seems somewhat more likely
> that what would happen is that a simpler, cleaner libgit2 based cli
> would emerge at some point with an 80% most-used functionality and
> super nice UI mentality, but that wouldn't be for some time.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-05 18:39         ` Scott Chacon
  2011-06-05 23:37           ` Jakub Narebski
@ 2011-06-06  6:16           ` Junio C Hamano
  2011-06-06  7:34             ` Michael J Gruber
  2011-06-09  9:06             ` Michael Haggerty
  1 sibling, 2 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-06  6:16 UTC (permalink / raw)
  To: Scott Chacon; +Cc: Jakub Narebski, Michael Nahas, git

Scott Chacon <schacon@gmail.com> writes:

> For example, implementation details aside, I think having something
> like WTREE and NEXT available would help users understand that there
> are these 3 trees that are important and useful in Git and re-inforce
> a very non-SVN style workflow in that manner.

That's a funny thing to say. Working tree may almost always (to put it
another way, "you could make it to") act like a tree, but the index does
not act like a tree at all in more important situations.

For example, how would you design the user experience of "git show NEXT"?
Try to write a transcript (i.e. "The user starts from this state, runs
these commands, and then says 'git show NEXT'. The user will see this."),
covering various corner cases exhaustively, including what would happen
before the first commit, and during a conflicted "pull" or "rebase -i".

It's not just the matter of "internally pretend to run write-tree with
'not committed yet' as a fake commit log message and show it as if it is
an existing commit.

I wouldn't demand "implement 'git show NEXT'" here, nor "implement it
efficiently" here; just designing the user experience is a good first step
to realize that the index does not act like a tree, and I do not think you
should spread such a misconception to the end users.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06  6:16           ` Junio C Hamano
@ 2011-06-06  7:34             ` Michael J Gruber
  2011-06-06 11:45               ` Michael Nahas
                                 ` (2 more replies)
  2011-06-09  9:06             ` Michael Haggerty
  1 sibling, 3 replies; 98+ messages in thread
From: Michael J Gruber @ 2011-06-06  7:34 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Scott Chacon, Jakub Narebski, Michael Nahas, git

Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:
> Scott Chacon <schacon@gmail.com> writes:
> 
>> For example, implementation details aside, I think having something
>> like WTREE and NEXT available would help users understand that there
>> are these 3 trees that are important and useful in Git and re-inforce
>> a very non-SVN style workflow in that manner.
> 
> That's a funny thing to say. Working tree may almost always (to put it
> another way, "you could make it to") act like a tree, but the index does
> not act like a tree at all in more important situations.
> 
> For example, how would you design the user experience of "git show NEXT"?
> Try to write a transcript (i.e. "The user starts from this state, runs
> these commands, and then says 'git show NEXT'. The user will see this."),
> covering various corner cases exhaustively, including what would happen
> before the first commit, and during a conflicted "pull" or "rebase -i".
> 
> It's not just the matter of "internally pretend to run write-tree with
> 'not committed yet' as a fake commit log message and show it as if it is
> an existing commit.
> 
> I wouldn't demand "implement 'git show NEXT'" here, nor "implement it
> efficiently" here; just designing the user experience is a good first step
> to realize that the index does not act like a tree, and I do not think you
> should spread such a misconception to the end users.

That is why the other Michael suggested "NEXT" as opposed to "INDEX":
The index has many aspects, only one of which is "the contents of the
next commit if I would issue 'git commit' right now". (I would even go
so far as using "STAGE".) Now, it's hard to argue that "the result of a
commit" is not tree-like, isn't it? And there's no question what "git
show NEXT" would do. Yes, if you repeat that command, you get a
different sha1 each time (because of the time field).

I don't think anyone is seriously suggesting to replace the index by a
pseudo commit; but the one aspect which people use most could be well
represented like that, and this might even help emphasizing the
different aspects of the index. Give the index an identity as an
"object" (no, no new type, not in the object db, but as a ui object),
not something mysterious behind the scenes!

As for WTREE: git diff against work tree does not look at non-tracked
ignored files, so why should WTREE?

Full disclosure: I love the index but hate the way we make it difficult
to use sometimes, and even have to lookup myself what command and option
to actually use if all I want to do is diff A against B, or take the
version of a file from A and write it to B, when A and B are a commit,
the index or the worktree (with a commit being the nonwritable, of course).

I mean, this is really crazy: We have 4 commands ("add", "rm
[--cached]", "checkout [<commit>] --", "reset [<commit>] --") which you
need to be aware of if all you want to do is moving file contents
(content at a path) between a commit, the index and the worktree! And
this is actually worse than having 6 for the 6 cases.

Michael

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06  7:34             ` Michael J Gruber
@ 2011-06-06 11:45               ` Michael Nahas
  2011-06-06 12:19               ` Jakub Narebski
  2011-06-06 14:00               ` Junio C Hamano
  2 siblings, 0 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-06 11:45 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: git

Thanks for all the interest!

Before getting into the contentious topics:

Is there general agreement on my item #4 that "git branch <name>"
should be replaced by "git checkout -b <name>" in the tutorial?

Concerning the semi-formal notation for describing commands, do people
thing it is useful?  Is this better covered at revctrl.org?


Okay, back to NEXT/WTREE:

I think Junio is right: The best way to think about NEXT and WTREE are
_not_ as commits.  They are "snapshots of the project".  A commit
object is a snaphot + parent commit SHAs + author + message + other
things.  Think of NEXT and WTREE as equivalent to the tree object
pointed to by a commit object.

[Perhaps "next commit" is a bad name for a snapshot]

These concepts of NEXT and WTREE are use by visual tools.  My favorite
Git documentation, Visual Git Reference, uses them.  Even "git stash
save" stores the "state of the index" and "state of the working tree"
in two commits.

My initial desire for NEXT/WTREE was to make "git diff" usage easier
for me to remember.  It ends up that this is _exactly_ the same usage
that inspired the previous emails that Jakub referenced.  I understand
that NEXT and WTREE may not have as many uses elsewhere, but I think
they have a lot of value for "git diff".

I don't think users will have trouble realizing that NEXT and WTREE
are _not_ commits.  They're writable.  Commits are not.  I do think
that NEXT has some value that users will realize that "git add
foo.txt" adds a particular version of foo.txt to the index and that
further edits to foo.txt will not make it into the next commit, unless
"git add foo.txt" is run again.

In reference as to how to report "git show NEXT", I would suggest that
the usual case would be to treat NEXT like a tree object.  I'm new to
Git and I know enough to know that I don't know all the states of the
index nor even all the commands that use it.  I will read up on the
format of the index and try to come up with some answers for the more
complex situations, but I'm also okay with saying the alias NEXT
doesn't work while in a merge conflict (where "git write-tree" would
return an error.)  Perhaps other alias do work then?
MERGE_HEAD/FETCH_HEAD come and go, right?

Mike


On Mon, Jun 6, 2011 at 3:34 AM, Michael J Gruber
<git@drmicha.warpmail.net> wrote:
> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:
>> Scott Chacon <schacon@gmail.com> writes:
>>
>>> For example, implementation details aside, I think having something
>>> like WTREE and NEXT available would help users understand that there
>>> are these 3 trees that are important and useful in Git and re-inforce
>>> a very non-SVN style workflow in that manner.
>>
>> That's a funny thing to say. Working tree may almost always (to put it
>> another way, "you could make it to") act like a tree, but the index does
>> not act like a tree at all in more important situations.
>>
>> For example, how would you design the user experience of "git show NEXT"?
>> Try to write a transcript (i.e. "The user starts from this state, runs
>> these commands, and then says 'git show NEXT'. The user will see this."),
>> covering various corner cases exhaustively, including what would happen
>> before the first commit, and during a conflicted "pull" or "rebase -i".
>>
>> It's not just the matter of "internally pretend to run write-tree with
>> 'not committed yet' as a fake commit log message and show it as if it is
>> an existing commit.
>>
>> I wouldn't demand "implement 'git show NEXT'" here, nor "implement it
>> efficiently" here; just designing the user experience is a good first step
>> to realize that the index does not act like a tree, and I do not think you
>> should spread such a misconception to the end users.
>
> That is why the other Michael suggested "NEXT" as opposed to "INDEX":
> The index has many aspects, only one of which is "the contents of the
> next commit if I would issue 'git commit' right now". (I would even go
> so far as using "STAGE".) Now, it's hard to argue that "the result of a
> commit" is not tree-like, isn't it? And there's no question what "git
> show NEXT" would do. Yes, if you repeat that command, you get a
> different sha1 each time (because of the time field).
>
> I don't think anyone is seriously suggesting to replace the index by a
> pseudo commit; but the one aspect which people use most could be well
> represented like that, and this might even help emphasizing the
> different aspects of the index. Give the index an identity as an
> "object" (no, no new type, not in the object db, but as a ui object),
> not something mysterious behind the scenes!
>
> As for WTREE: git diff against work tree does not look at non-tracked
> ignored files, so why should WTREE?
>
> Full disclosure: I love the index but hate the way we make it difficult
> to use sometimes, and even have to lookup myself what command and option
> to actually use if all I want to do is diff A against B, or take the
> version of a file from A and write it to B, when A and B are a commit,
> the index or the worktree (with a commit being the nonwritable, of course).
>
> I mean, this is really crazy: We have 4 commands ("add", "rm
> [--cached]", "checkout [<commit>] --", "reset [<commit>] --") which you
> need to be aware of if all you want to do is moving file contents
> (content at a path) between a commit, the index and the worktree! And
> this is actually worse than having 6 for the 6 cases.
>
> Michael
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06  7:34             ` Michael J Gruber
  2011-06-06 11:45               ` Michael Nahas
@ 2011-06-06 12:19               ` Jakub Narebski
  2011-06-06 13:20                 ` Michael J Gruber
  2011-06-06 16:23                 ` Junio C Hamano
  2011-06-06 14:00               ` Junio C Hamano
  2 siblings, 2 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-06 12:19 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Junio C Hamano, Scott Chacon, Michael Nahas, git

On Mon, 6 June 2011, Michael J Gruber wrote:
> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:
>> Scott Chacon <schacon@gmail.com> writes:
>> 
>>> For example, implementation details aside, I think having something
>>> like WTREE and NEXT available would help users understand that there
>>> are these 3 trees that are important and useful in Git and re-inforce
>>> a very non-SVN style workflow in that manner.
>> 
>> That's a funny thing to say. Working tree may almost always (to put it
>> another way, "you could make it to") act like a tree, but the index does
>> not act like a tree at all in more important situations.
>> 
>> For example, how would you design the user experience of "git show NEXT"?
>> Try to write a transcript (i.e. "The user starts from this state, runs
>> these commands, and then says 'git show NEXT'. The user will see this."),
>> covering various corner cases exhaustively, including what would happen
>> before the first commit, and during a conflicted "pull" or "rebase -i".
>> 
>> It's not just the matter of "internally pretend to run write-tree with
>> 'not committed yet' as a fake commit log message and show it as if it is
>> an existing commit.
>> 
>> I wouldn't demand "implement 'git show NEXT'" here, nor "implement it
>> efficiently" here; just designing the user experience is a good first step
>> to realize that the index does not act like a tree, and I do not think you
>> should spread such a misconception to the end users.
> 
> That is why the other Michael suggested "NEXT" as opposed to "INDEX":
> The index has many aspects, only one of which is "the contents of the
> next commit if I would issue 'git commit' right now". (I would even go
> so far as using "STAGE".) Now, it's hard to argue that "the result of a
> commit" is not tree-like, isn't it? And there's no question what "git
> show NEXT" would do. Yes, if you repeat that command, you get a
> different sha1 each time (because of the time field).
> 
> I don't think anyone is seriously suggesting to replace the index by a
> pseudo commit; but the one aspect which people use most could be well
> represented like that, and this might even help emphasizing the
> different aspects of the index. Give the index an identity as an
> "object" (no, no new type, not in the object db, but as a ui object),
> not something mysterious behind the scenes!

So what you suggest would make

  $ git diff NEXT WTREE

behave differently from

  $ git diff

and

  $ git diff HEAD NEXT

behave differently from

  $ git diff --cached

Do you really think that it is good idea?

> As for WTREE: git diff against work tree does not look at non-tracked
> ignored files, so why should WTREE?

So we tailor WTREE do diff behavior?


Well, actually, lets examine each command that takes --cached or --index
and see if NEXT and WTREE would apply at all, and if apply if it would
help.

The following commands support --cached:

  git diff-index      # plumbing
  git diff
  git grep
  git ls-files
  git rm
  git submodule

The following commands support --index

  git checkout-index  # plumbing
  git stash

The following command support both --cached and --index

  git apply

I would skip "git submodule" in this analysis because I don't know enough
about it, and let's skip for the time being purely plumbing commands.
 
Of those, NEXT is not applicable at all and wouldn't help "git rm" and
"git stash", nor "git apply" commands (3/7), isn't it?

In the case of "git grep" using NEXT isn't IMVHO more helpful than using
"--cached".  Note that presence of (slightly misnamed) "--no-index" and
backward compatibility make some problems in interpreting "WTREE" for
"git diff"; natural would for "git grep WTREE" to be current "git grep",
and new "git grep" be "git grep --no-index"... or should it be in reverse,
and "git grep WTREE" to mean "git grep --no-index"?  But then your
interpretation which takes into account only tracked files fails.

In the case of "git ls-files" the "--cached" option is the default;
NEXT could only hinder here IMVHO.

That makes "git grep" and "git ls-files" places where using NEXT is
possible, but doesn't help much. (2/7).


So we are left with "git diff", where we have the following diagram
(perhaps it should made it into "git diff" manpage?):


                worktree
                 |   \    diff
                 |    \   diff NEXT WTREE
                 |     \  [add]
 diff HEAD       |      v 
 diff HEAD WTREE |    index
 [commit -a]     |     /
                 |    /   diff --cached
                 |   /    diff HEAD NEXT  # not NEXT HEAD
                 v  v     [commit]
                 HEAD

Besides, isn't this exercise a bit academic?  New to git wouldn't use
index, and would use 'git commit -a' and 'git diff'... and that would
be enough... well, perhaps except 'git add' + 'git diff'...

> Full disclosure: I love the index but hate the way we make it difficult
> to use sometimes, and even have to lookup myself what command and option
> to actually use if all I want to do is diff A against B, or take the
> version of a file from A and write it to B, when A and B are a commit,
> the index or the worktree (with a commit being the nonwritable, of course).

Note that in case of saving to worktree you can always use

  $ git show HEAD:./foo  >foo
  $ git show :0:./foo    >foo     # or just :./foo
 
> I mean, this is really crazy: We have 4 commands ("add", "rm
> [--cached]", "checkout [<commit>] --", "reset [<commit>] --") which you
> need to be aware of if all you want to do is moving file contents
> (content at a path) between a commit, the index and the worktree! And
> this is actually worse than having 6 for the 6 cases.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 12:19               ` Jakub Narebski
@ 2011-06-06 13:20                 ` Michael J Gruber
  2011-06-08 13:10                   ` Jakub Narebski
  2011-06-06 16:23                 ` Junio C Hamano
  1 sibling, 1 reply; 98+ messages in thread
From: Michael J Gruber @ 2011-06-06 13:20 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Junio C Hamano, Scott Chacon, Michael Nahas, git

Jakub Narebski venit, vidit, dixit 06.06.2011 14:19:
> On Mon, 6 June 2011, Michael J Gruber wrote:
>> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:
>>> Scott Chacon <schacon@gmail.com> writes:
>>>
>>>> For example, implementation details aside, I think having something
>>>> like WTREE and NEXT available would help users understand that there
>>>> are these 3 trees that are important and useful in Git and re-inforce
>>>> a very non-SVN style workflow in that manner.
>>>
>>> That's a funny thing to say. Working tree may almost always (to put it
>>> another way, "you could make it to") act like a tree, but the index does
>>> not act like a tree at all in more important situations.
>>>
>>> For example, how would you design the user experience of "git show NEXT"?
>>> Try to write a transcript (i.e. "The user starts from this state, runs
>>> these commands, and then says 'git show NEXT'. The user will see this."),
>>> covering various corner cases exhaustively, including what would happen
>>> before the first commit, and during a conflicted "pull" or "rebase -i".
>>>
>>> It's not just the matter of "internally pretend to run write-tree with
>>> 'not committed yet' as a fake commit log message and show it as if it is
>>> an existing commit.
>>>
>>> I wouldn't demand "implement 'git show NEXT'" here, nor "implement it
>>> efficiently" here; just designing the user experience is a good first step
>>> to realize that the index does not act like a tree, and I do not think you
>>> should spread such a misconception to the end users.
>>
>> That is why the other Michael suggested "NEXT" as opposed to "INDEX":
>> The index has many aspects, only one of which is "the contents of the
>> next commit if I would issue 'git commit' right now". (I would even go
>> so far as using "STAGE".) Now, it's hard to argue that "the result of a
>> commit" is not tree-like, isn't it? And there's no question what "git
>> show NEXT" would do. Yes, if you repeat that command, you get a
>> different sha1 each time (because of the time field).
>>
>> I don't think anyone is seriously suggesting to replace the index by a
>> pseudo commit; but the one aspect which people use most could be well
>> represented like that, and this might even help emphasizing the
>> different aspects of the index. Give the index an identity as an
>> "object" (no, no new type, not in the object db, but as a ui object),
>> not something mysterious behind the scenes!
> 
> So what you suggest would make
> 
>   $ git diff NEXT WTREE
> 
> behave differently from
> 
>   $ git diff
> 
> and
> 
>   $ git diff HEAD NEXT
> 
> behave differently from
> 
>   $ git diff --cached
> 
> Do you really think that it is good idea?

I don't know where you're getting from that someone is suggesting to
make them different. (And even if, it's new UI, not changed.) Everyone's
been suggesting to make these more accessible.

>> As for WTREE: git diff against work tree does not look at non-tracked
>> ignored files, so why should WTREE?
> 
> So we tailor WTREE do diff behavior?

There is no WTREE and nothing to tailer. We create it so that it is most
useful and consistent, whatever that may be.

...

> Besides, isn't this exercise a bit academic?  New to git wouldn't use
> index, and would use 'git commit -a' and 'git diff'... and that would
> be enough... well, perhaps except 'git add' + 'git diff'...

But we want them to grasp and use the git concepts! That is why some of
us want to make them more accessible.

>> Full disclosure: I love the index but hate the way we make it difficult
>> to use sometimes, and even have to lookup myself what command and option
>> to actually use if all I want to do is diff A against B, or take the
>> version of a file from A and write it to B, when A and B are a commit,
>> the index or the worktree (with a commit being the nonwritable, of course).
> 
> Note that in case of saving to worktree you can always use
> 
>   $ git show HEAD:./foo  >foo
>   $ git show :0:./foo    >foo     # or just :./foo

Exactly, yet another command to add to the list below, and it's not even
all git (because of the shell redirection).

>> I mean, this is really crazy: We have 4 commands ("add", "rm
>> [--cached]", "checkout [<commit>] --", "reset [<commit>] --") which you
>> need to be aware of if all you want to do is moving file contents
>> (content at a path) between a commit, the index and the worktree! And
>> this is actually worse than having 6 for the 6 cases.

Add to this craziness the fact that "checkout -- <path>" reads from
index and writes to worktree, but "checkout <commit> -- path" does not
read from commit and write to worktree - it reads from commit and writes
to index+worktree.

Note that I'm not suggesting to change any of the beloved
reset/checkout/whatever variants.

But the more I look at the commit - index - worktree triangle and the
commands we have the more I realize how messed up the ui is, simply
because it is determined by the underlying mechanics (e.g.: checkout
writes the index to the worktree, possibly after updating the index from
a commit) rather than by the concepts.

And the bad thing is that even when you look at a single command like
reset or checkout, you can get confused easily because of the multiple
different functions they overload (e.g. checkout can change HEAD, the
index and/or the worktree), and also because of some different defaults
(HEAD vs. index). I think we lost consistency here because over time
"useful defaults" grew in the wild.

That is why I'm suggesting concept based variants (move this content
from A to B, show me the difference between A and B).

Michael

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06  7:34             ` Michael J Gruber
  2011-06-06 11:45               ` Michael Nahas
  2011-06-06 12:19               ` Jakub Narebski
@ 2011-06-06 14:00               ` Junio C Hamano
  2011-06-06 14:16                 ` Michael J Gruber
  2 siblings, 1 reply; 98+ messages in thread
From: Junio C Hamano @ 2011-06-06 14:00 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Scott Chacon, Jakub Narebski, Michael Nahas, git

Michael J Gruber <git@drmicha.warpmail.net> writes:

> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:
> ...
>> For example, how would you design the user experience of "git show NEXT"?
>> Try to write a transcript (i.e. "The user starts from this state, runs
>> these commands, and then says 'git show NEXT'. The user will see this."),
>> covering various corner cases exhaustively, including what would happen
>> before the first commit, and during a conflicted "pull" or "rebase -i".
>>  ...
> That is why the other Michael suggested "NEXT" as opposed to "INDEX":

That is why I asked what the user experience of "git show NEXT" as opposed
to "git show INDEX" should look like. So what should it look like during a
"pull" that did not finish?

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 14:00               ` Junio C Hamano
@ 2011-06-06 14:16                 ` Michael J Gruber
  2011-06-06 16:14                   ` Junio C Hamano
  0 siblings, 1 reply; 98+ messages in thread
From: Michael J Gruber @ 2011-06-06 14:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Scott Chacon, Jakub Narebski, Michael Nahas, git

Junio C Hamano venit, vidit, dixit 06.06.2011 16:00:
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
>> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:
>> ...
>>> For example, how would you design the user experience of "git show NEXT"?
>>> Try to write a transcript (i.e. "The user starts from this state, runs
>>> these commands, and then says 'git show NEXT'. The user will see this."),
>>> covering various corner cases exhaustively, including what would happen
>>> before the first commit, and during a conflicted "pull" or "rebase -i".
>>>  ...
>> That is why the other Michael suggested "NEXT" as opposed to "INDEX":
> 
> That is why I asked what the user experience of "git show NEXT" as opposed
> to "git show INDEX" should look like. So what should it look like during a
> "pull" that did not finish?

If NEXT is to mean the result of a commit in the current state, and the
current state would or should not allow a commit, then trying to access
that pseudo-commit should error out with a helpful message.

Another option is to make NEXT/INDEX mean a tree (:0:). I have not
thought this through (and have not made a suggestion, accordingly) but I
do see a problem in the UI. (I don't think we need to change the
existing ui in that respect but can amend and improve it.)

Anyway, it's rc phase :)

Michael

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 14:16                 ` Michael J Gruber
@ 2011-06-06 16:14                   ` Junio C Hamano
  2011-06-06 17:42                     ` Scott Chacon
  2011-06-07  6:11                     ` Michael J Gruber
  0 siblings, 2 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-06 16:14 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Scott Chacon, Jakub Narebski, Michael Nahas, git

Michael J Gruber <git@drmicha.warpmail.net> writes:

>> That is why I asked what the user experience of "git show NEXT" as opposed
>> to "git show INDEX" should look like. So what should it look like during a
>> "pull" that did not finish?
>
> If NEXT is to mean the result of a commit in the current state, and the
> current state would or should not allow a commit, then trying to access
> that pseudo-commit should error out with a helpful message.

What "helpful message"? I asked for the user experience, not handwaving.

Do you mean to say that the error message would teach the user that the
current state is not something you can create a commit? What message would
that give the end user?  I am hoping the following is not what will happen:

  Q. I tried "git show NEXT" because I wanted to see what the next commit
     would look like, but I got an error, saying NEXT is not known as I
     haven't resolved a conflict.

  A. Yes, the message is correct.

  Q. But then how can I see what the next commit would look like?

  A. You would say "git diff HEAD NEXT".

  Q. Ah, that is the same as I always do before making a commit to see what
     I have added so far look sane. Thanks.

     ...after 2 minutes...

  Q. Sorry, it does not work. I get the same error, that says NEXT is not
     known yet.

  A. Ok, you would say "git diff HEAD" the old fashioned way. The person
     who thought NEXT would be useful didn't think things through.

  Q. Now I am seeing a diff between the conflicted state and the previous
     commit, I think I can get to where I want to go from here. Thanks.


> Another option is to make NEXT/INDEX mean a tree (:0:). I have not
> thought this through (and have not made a suggestion, accordingly) but I
> do see a problem in the UI. (I don't think we need to change the
> existing ui in that respect but can amend and improve it.)
>
> Anyway, it's rc phase :)

Rc or not rc, just repeating a fuzzy and uncooked "idea" around phoney
ref-looking names that will end up confusing the users, and selling that
as if it is a logical conclusion to "we want to give an easier to
understand UI", without presenting a solid user experience design that is
convincing enough that the "idea" will reduce confusion will not get us
anywhere, especially when it is sprinkled with ad hominem attack at me.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 12:19               ` Jakub Narebski
  2011-06-06 13:20                 ` Michael J Gruber
@ 2011-06-06 16:23                 ` Junio C Hamano
  2011-06-06 16:40                   ` Drew Northup
  1 sibling, 1 reply; 98+ messages in thread
From: Junio C Hamano @ 2011-06-06 16:23 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Michael J Gruber, Scott Chacon, Michael Nahas, git

Jakub Narebski <jnareb@gmail.com> writes:

> On Mon, 6 June 2011, Michael J Gruber wrote:
>
> So what you suggest would make
>
>   $ git diff NEXT WTREE
>
> behave differently from
>
>   $ git diff
>
> and
>
>   $ git diff HEAD NEXT
>
> behave differently from
>
>   $ git diff --cached
>
> Do you really think that it is good idea?

I do not know if Michael is suggesting to make it different, but if the
difference is an improvement, it may be a good thing. Being different from
the current behaviour should not be a basis for automatic rejection ---
otherwise we won't make any progress.

I just don't know what the plans by advocates of this NEXT/WTREE are for
conflicted cases [*1*] to tell how they want to make the user experience, so I
cannot even tell if they want something different, let alone to judge if
the proposed difference is an improvement.

[Footnote]

*1* There may be other equally important corner cases, but let's tackle
one simple and obvious thing first to see where this goes.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 16:23                 ` Junio C Hamano
@ 2011-06-06 16:40                   ` Drew Northup
  0 siblings, 0 replies; 98+ messages in thread
From: Drew Northup @ 2011-06-06 16:40 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jakub Narebski, Michael J Gruber, Scott Chacon, Michael Nahas, git


On Mon, 2011-06-06 at 09:23 -0700, Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
> 
> > On Mon, 6 June 2011, Michael J Gruber wrote:
> >
> > So what you suggest would make
> >
> >   $ git diff NEXT WTREE
> >
> > behave differently from
> >
> >   $ git diff
> >
> > and
> >
> >   $ git diff HEAD NEXT
> >
> > behave differently from
> >
> >   $ git diff --cached
> >
> > Do you really think that it is good idea?
> 
> I do not know if Michael is suggesting to make it different, but if the
> difference is an improvement, it may be a good thing. Being different from
> the current behaviour should not be a basis for automatic rejection ---
> otherwise we won't make any progress.
> 
> I just don't know what the plans by advocates of this NEXT/WTREE are for
> conflicted cases [*1*] to tell how they want to make the user experience, so I
> cannot even tell if they want something different, let alone to judge if
> the proposed difference is an improvement.
> 
> [Footnote]
> 
> *1* There may be other equally important corner cases, but let's tackle
> one simple and obvious thing first to see where this goes.

Given the history of the thread including this:
http://article.gmane.org/gmane.comp.version-control.git/172220

I'd prefer not introducing any more global pseudo-refs....

-- 
-Drew Northup
________________________________________________
"As opposed to vegetable or mineral error?"
-John Pescatore, SANS NewsBites Vol. 12 Num. 59

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 16:14                   ` Junio C Hamano
@ 2011-06-06 17:42                     ` Scott Chacon
  2011-06-06 19:01                       ` Junio C Hamano
  2011-06-07  6:11                     ` Michael J Gruber
  1 sibling, 1 reply; 98+ messages in thread
From: Scott Chacon @ 2011-06-06 17:42 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michael J Gruber, Jakub Narebski, Michael Nahas, git

Hey,

On Mon, Jun 6, 2011 at 9:14 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Michael J Gruber <git@drmicha.warpmail.net> writes:
>
>>> That is why I asked what the user experience of "git show NEXT" as opposed
>>> to "git show INDEX" should look like. So what should it look like during a
>>> "pull" that did not finish?
>>
>> If NEXT is to mean the result of a commit in the current state, and the
>> current state would or should not allow a commit, then trying to access
>> that pseudo-commit should error out with a helpful message.
>
> What "helpful message"? I asked for the user experience, not handwaving.
>
> Do you mean to say that the error message would teach the user that the
> current state is not something you can create a commit? What message would
> that give the end user?  I am hoping the following is not what will happen:
>
>  Q. I tried "git show NEXT" because I wanted to see what the next commit
>     would look like, but I got an error, saying NEXT is not known as I
>     haven't resolved a conflict.
>
>  A. Yes, the message is correct.

I'm not sure why this wouldn't just list out the index tree, having
some message for entries that have more than one stage.  Like a
porcelain-ized version of 'git ls-files --stage', maybe in this case
with a warning at the bottom that a subsequent commit command will not
complete.  Even something similar to what would happen if you ran
'commit' right then:

  fatal: 'commit' will not be possible because you have unmerged files.

>  Q. But then how can I see what the next commit would look like?
>
>  A. You would say "git diff HEAD NEXT".
>
>  Q. Ah, that is the same as I always do before making a commit to see what
>     I have added so far look sane. Thanks.

Why would this look sane? I would think this would say "* Unmerged
path <file>" just like 'diff --cached would do.

>
>     ...after 2 minutes...
>
>  Q. Sorry, it does not work. I get the same error, that says NEXT is not
>     known yet.
>
>  A. Ok, you would say "git diff HEAD" the old fashioned way. The person
>     who thought NEXT would be useful didn't think things through.

I think the point would be that "git diff HEAD WTREE" would give you
this same output and if you had the basic concept of these three
important areas of Git that you could be explicit about what you
wanted to see or compare rather than having to look up the specific
special case that will show you what you want. Consider these very
common scenarios from a new user perspective: you want to see what is
changed in your working tree but not added yet, you want to see what
is added but not committed, you want to see the sum total of all
changes since your last commit and you want to see what the index
currently looks like.

Here are the commands currently:

a) diff
b) diff --cached
c) diff HEAD
d) ls-files --stage

Here would be the commands with the proposed pseudo-trees.

a) diff NEXT WTREE
b) diff HEAD NEXT
c) diff HEAD WTREE
d) show NEXT

It seems to me to be more guessable and straightforward for new users.
 But, yes, I assume there would be some difficulty in supporting it
everywhere.

>
>  Q. Now I am seeing a diff between the conflicted state and the previous
>     commit, I think I can get to where I want to go from here. Thanks.
>
>
>> Another option is to make NEXT/INDEX mean a tree (:0:). I have not
>> thought this through (and have not made a suggestion, accordingly) but I
>> do see a problem in the UI. (I don't think we need to change the
>> existing ui in that respect but can amend and improve it.)
>>
>> Anyway, it's rc phase :)
>
> Rc or not rc, just repeating a fuzzy and uncooked "idea" around phoney
> ref-looking names that will end up confusing the users, and selling that
> as if it is a logical conclusion to "we want to give an easier to
> understand UI", without presenting a solid user experience design that is
> convincing enough that the "idea" will reduce confusion will not get us
> anywhere, especially when it is sprinkled with ad hominem attack at me.

I think I'm the only one that mentioned your name so I apologize if
you saw that as an attack.  I was not saying you are unreasonable in
not changing the UI all the time, or that you are unreasonable for not
liking the NEXT/WTREE - there are certainly cases I'm not considering.
(For example, I'm more concerned about things like 'git commit-tree
NEXT' or 'git rev-parse NEXT' if the index is in a weird state - it
obviously has to be special-cased and I would assume only usable at
the porcelain level, possibly only by 'diff', 'show' and 'grep'. It's
the implementation I'm mainly worried about, I feel that the UI would
be pretty straightforward in all these cases.)

Re: the ad-hominim stuff, I was simply remarking that the
'reset'/'checkout' debate has been had several times and there is
precedent for it being a non-starter.  I also see and understand the
argument from you and Linus about that, I just happen to disagree with
it. It was not meant to be an attack.

Scott

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 17:42                     ` Scott Chacon
@ 2011-06-06 19:01                       ` Junio C Hamano
       [not found]                         ` <BANLkTi=yytzDrJLvVn_ZhJOiQs-rqvKi1w@mail.gmail.com>
  0 siblings, 1 reply; 98+ messages in thread
From: Junio C Hamano @ 2011-06-06 19:01 UTC (permalink / raw)
  To: Scott Chacon; +Cc: Michael J Gruber, Jakub Narebski, Michael Nahas, git

Scott Chacon <schacon@gmail.com> writes:

> On Mon, Jun 6, 2011 at 9:14 AM, Junio C Hamano <gitster@pobox.com> wrote:
> ...
>>>> That is why I asked what the user experience of "git show NEXT" as opposed
>>>> to "git show INDEX" should look like. So what should it look like during a
>>>> "pull" that did not finish?
>>>
>>> If NEXT is to mean the result of a commit in the current state, and the
>>> current state would or should not allow a commit, then trying to access
>>> that pseudo-commit should error out with a helpful message.
>>
>> What "helpful message"? I asked for the user experience, not handwaving.
>>
>> Do you mean to say that the error message would teach the user that the
>> current state is not something you can create a commit? What message would
>> that give the end user?  I am hoping the following is not what will happen:
>>
>>  Q. I tried "git show NEXT" because I wanted to see what the next commit
>>     would look like, but I got an error, saying NEXT is not known as I
>>     haven't resolved a conflict.
>>
>>  A. Yes, the message is correct.
>
> I'm not sure why this wouldn't just list out the index tree,...

You are not entitled to say "I'm not sure" ;-). I asked you to show a
design of the user experience of "git show NEXT", as an advocate for the
NEXT/WTREE notation.

I'd take it that you would "just list out the index tree" as the outline
of the user experience.

>>  A. You would say "git diff HEAD NEXT".
>>
>>  Q. Ah, that is the same as I always do before making a commit to see what
>>     I have added so far look sane. Thanks.
>
> Why would this look sane? I would think this would say "* Unmerged
> path <file>" just like 'diff --cached would do.

Either you read it too hastily or I didn't write this clear enough; "sane"
does not refer to the command. In this story, the novice is saying "Before
I make a commit, I check if my changes so far matches what I wanted to
achieve, in other words, I check the sanity of my changes. And 'git diff
HEAD NEXT' is the command I use when I am not in this weird 'conflicted'
state. I am happy that I can use the same command".

> But, yes, I assume there would be some difficulty in supporting it
> everywhere.

I don't care too much about "difficulty in uniformly implementing". I am
doubting that you can _design_ uniformly for these new tokens to make
enough sense to help the new people. That is why I've been asking for
concrete examples of user experience design, sample transcripts, that
covers known corner cases.

If NEXT/WTREE advocates cannot come up with one, or if that is just to
punt and say "NEXT is not defined in this case---use the traditional
command" in the error message, I don't see much point in discussing this
further. It will end up with the same whine-fest as previous rounds.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
       [not found]                         ` <BANLkTi=yytzDrJLvVn_ZhJOiQs-rqvKi1w@mail.gmail.com>
@ 2011-06-07  2:31                           ` Michael Nahas
  2011-06-07  4:03                             ` Junio C Hamano
  0 siblings, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-07  2:31 UTC (permalink / raw)
  To: git

I think NEXT and WTREE should be like tree objects, not commits, so I
would argue that "git show NEXT" should show what it shows for a tree.
 From the man page:

"For trees, it shows the names (equivalent to git ls-tree with --name-only)."


"git diff HEAD NEXT" during a merge conflict: During the merge
conflict there are two groups of changing files.  Some files have been
resolved and reside in "Stage0".  The others have not been resolved
and a copy resides in each of "Stage1", 2, and 3.  (Which I eagerly
want to name BASE, HEAD, and MERGE_HEAD.)

My thought is that NEXT should only represent those changing files
that have been resolved.  So, NEXT would be HEAD plus the files in
Stage0.  So, "git diff HEAD NEXT" would print out the changes in
Stage0.

The trickier question for me is what does this make "git diff WTREE
NEXT"?  Well, the resolved changes are the same in WTREE and NEXT.
The unresolved files in NEXT are the same as in HEAD.  So, "git diff
WTREE NEXT" would print out the unresolved changes between WTREE and
HEAD.

What I don't like about that is that at the point of conflict in each
file, "git merge" has written the changes from HEAD and MERGE_HEAD.
So, printing the changes between HEAD and WTREE will resulting in the
changes done by HEAD printed twice.  That, while understandable, isn't
so pretty.


I've engineered a conflicted merge and taken a look at what "git diff
--cached HEAD" and "git diff --cached" looks like.  Can someone
confirm that the current behavior is equivalent to what I described
above?


Junio asked: So what should it look like during a "pull" that did not finish?

Is this the same as a conflicted merge state?  (Except possibly with
FETCH_HEAD instead of MERGE_HEAD.)


Junio asked: "rebase -i"?

I know what this does (and love it!), but not how it works.  I
certainly don't know the state it leaves things in when it's
conflicted.  I'll let someone else go to bat here.


Teach a noob: What's "rc phase"?


Mike



On Mon, Jun 6, 2011 at 3:01 PM, Junio C Hamano <gitster@pobox.com> wrote:
>
> Scott Chacon <schacon@gmail.com> writes:
>
> > On Mon, Jun 6, 2011 at 9:14 AM, Junio C Hamano <gitster@pobox.com> wrote:
> > ...
> >>>> That is why I asked what the user experience of "git show NEXT" as opposed
> >>>> to "git show INDEX" should look like. So what should it look like during a
> >>>> "pull" that did not finish?
> >>>
> >>> If NEXT is to mean the result of a commit in the current state, and the
> >>> current state would or should not allow a commit, then trying to access
> >>> that pseudo-commit should error out with a helpful message.
> >>
> >> What "helpful message"? I asked for the user experience, not handwaving.
> >>
> >> Do you mean to say that the error message would teach the user that the
> >> current state is not something you can create a commit? What message would
> >> that give the end user?  I am hoping the following is not what will happen:
> >>
> >>  Q. I tried "git show NEXT" because I wanted to see what the next commit
> >>     would look like, but I got an error, saying NEXT is not known as I
> >>     haven't resolved a conflict.
> >>
> >>  A. Yes, the message is correct.
> >
> > I'm not sure why this wouldn't just list out the index tree,...
>
> You are not entitled to say "I'm not sure" ;-). I asked you to show a
> design of the user experience of "git show NEXT", as an advocate for the
> NEXT/WTREE notation.
>
> I'd take it that you would "just list out the index tree" as the outline
> of the user experience.
>
> >>  A. You would say "git diff HEAD NEXT".
> >>
> >>  Q. Ah, that is the same as I always do before making a commit to see what
> >>     I have added so far look sane. Thanks.
> >
> > Why would this look sane? I would think this would say "* Unmerged
> > path <file>" just like 'diff --cached would do.
>
> Either you read it too hastily or I didn't write this clear enough; "sane"
> does not refer to the command. In this story, the novice is saying "Before
> I make a commit, I check if my changes so far matches what I wanted to
> achieve, in other words, I check the sanity of my changes. And 'git diff
> HEAD NEXT' is the command I use when I am not in this weird 'conflicted'
> state. I am happy that I can use the same command".
>
> > But, yes, I assume there would be some difficulty in supporting it
> > everywhere.
>
> I don't care too much about "difficulty in uniformly implementing". I am
> doubting that you can _design_ uniformly for these new tokens to make
> enough sense to help the new people. That is why I've been asking for
> concrete examples of user experience design, sample transcripts, that
> covers known corner cases.
>
> If NEXT/WTREE advocates cannot come up with one, or if that is just to
> punt and say "NEXT is not defined in this case---use the traditional
> command" in the error message, I don't see much point in discussing this
> further. It will end up with the same whine-fest as previous rounds.
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07  2:31                           ` Michael Nahas
@ 2011-06-07  4:03                             ` Junio C Hamano
  2011-06-07 11:04                               ` Michael Nahas
  0 siblings, 1 reply; 98+ messages in thread
From: Junio C Hamano @ 2011-06-07  4:03 UTC (permalink / raw)
  To: mike; +Cc: git

Michael Nahas <mike.nahas@gmail.com> writes:

> I think NEXT and WTREE should be like tree objects, not commits, so I
> would argue that "git show NEXT" should show what it shows for a tree.

So what is the definition of such a "tree" during a conflicted merge?

The traditional definition is "such a state cannot be expressed as a
tree". You are free to define it the same way, or for NEXT to be more
useful than status quo, come up with a better definition.

> My thought is that NEXT should only represent those changing files
> that have been resolved.  So, NEXT would be HEAD plus the files in
> Stage0.  So, "git diff HEAD NEXT" would print out the changes in
> Stage0.

That would mean conflicted files will all be shown as removed, or
unchanged?  Either would be more confusing.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 16:14                   ` Junio C Hamano
  2011-06-06 17:42                     ` Scott Chacon
@ 2011-06-07  6:11                     ` Michael J Gruber
  2011-06-07 11:45                       ` Jonathan Nieder
  2011-06-08 11:12                       ` Command-line interface thoughts (ad-hominem attacks) Jakub Narebski
  1 sibling, 2 replies; 98+ messages in thread
From: Michael J Gruber @ 2011-06-07  6:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Scott Chacon, Jakub Narebski, Michael Nahas, git

Junio C Hamano venit, vidit, dixit 06.06.2011 18:14:
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
>>> That is why I asked what the user experience of "git show NEXT" as opposed
>>> to "git show INDEX" should look like. So what should it look like during a
>>> "pull" that did not finish?
>>
>> If NEXT is to mean the result of a commit in the current state, and the
>> current state would or should not allow a commit, then trying to access
>> that pseudo-commit should error out with a helpful message.
> 
> What "helpful message"? I asked for the user experience, not handwaving.

I specified the exit behaviour, that is no handwaving.

[...]
>> Another option is to make NEXT/INDEX mean a tree (:0:). I have not
>> thought this through (and have not made a suggestion, accordingly) but I
>> do see a problem in the UI. (I don't think we need to change the
>> existing ui in that respect but can amend and improve it.)
>>
>> Anyway, it's rc phase :)
> 
> Rc or not rc,

I spend my limited git time running builds and tests for master on
several systems these days (and following changed build environments
there which I can't control).

> just repeating a fuzzy and uncooked "idea" around phoney
> ref-looking names that will end up confusing the users, and selling that
> as if it is a logical conclusion to "we want to give an easier to
> understand UI", without presenting a solid user experience design that is
> convincing enough that the "idea" will reduce confusion will not get us
> anywhere, especially when it is sprinkled with ad hominem attack at me.

I've re-read all my posts in this thread and have no idea what you're
referring to here. If I were more sensitive I could spot attacks at
myself in the above, though. Just count your usage of terms like
"phoney", "fuzzy" etc. directed at other people's ideas and arguments.

I'm actually wondering whether there is any agreement on the sheer fact
that there is a problem in the ui, namely having too many different
commands or options (reset/commit/add/checkout resp. diff invocations;
I've described that already) for different aspects of a "similar"
concept (cp content version from A to B resp. diff it).

If we don't agree that there's a problem then there's no point
discussing solutions (or ideas/brainstorms thereof).

Michael

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07  4:03                             ` Junio C Hamano
@ 2011-06-07 11:04                               ` Michael Nahas
  0 siblings, 0 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-07 11:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Tue, Jun 7, 2011 at 12:03 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Michael Nahas <mike.nahas@gmail.com> writes:
>
>> I think NEXT and WTREE should be like tree objects, not commits, so I
>> would argue that "git show NEXT" should show what it shows for a tree.
>
> So what is the definition of such a "tree" during a conflicted merge?

Good question.  You've been asking it a lot.  I answered it later in the email.

> The traditional definition is "such a state cannot be expressed as a
> tree". You are free to define it the same way, or for NEXT to be more
> useful than status quo, come up with a better definition.
>
>> My thought is that NEXT should only represent those changing files
>> that have been resolved.  So, NEXT would be HEAD plus the files in
>> Stage0.  So, "git diff HEAD NEXT" would print out the changes in
>> Stage0.

(during a conflicted merge...)
"NEXT would be HEAD plus the files in Stage0".

That is the tree.  HEAD plus the resolved files.

> That would mean conflicted files will all be shown as removed, or
> unchanged?  Either would be more confusing.

Conflicted files would be shown as unchanged in NEXT.

"diff NEXT HEAD" == changes in resolved files
"diff WTREE NEXT" == changes in conflicted files
"diff WTREE HEAD" == all changes.

That makes a lot of sense to me.  Those are the three different
changesets I'd want to see and those are the logical commands using
NEXT and WTREE to see them.

I _believe_ but don't know for sure that that _is_ the current behavior for:

"diff --cached HEAD" and
"diff --cached"
"diff HEAD"

If it is the current behavior, I don't see how it could be more
confusing.  It's exactly the same amount of confusing ... with a more
regular syntax, IMHO.


Another way to think about this:  If you had a conflicted merge and
someone allowed you to create the next commit with a command "git
commit --force", what would you expect to be in the created commit?
Wouldn't it be only the resolved files?  The files in Stage0?  The
files in WTREE have the "<<<<</=====/>>>>>" blocks in them - would you
want to commit those?  No.  For those files, you'd prefer the versions
you already had in HEAD.

Mike

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07  6:11                     ` Michael J Gruber
@ 2011-06-07 11:45                       ` Jonathan Nieder
  2011-06-07 19:00                         ` Holger Hellmuth
  2011-06-07 19:34                         ` René Scharfe
  2011-06-08 11:12                       ` Command-line interface thoughts (ad-hominem attacks) Jakub Narebski
  1 sibling, 2 replies; 98+ messages in thread
From: Jonathan Nieder @ 2011-06-07 11:45 UTC (permalink / raw)
  To: Michael J Gruber
  Cc: Junio C Hamano, Scott Chacon, Jakub Narebski, Michael Nahas, git

Hi,

Michael J Gruber wrote:

> I'm actually wondering whether there is any agreement on the sheer fact
> that there is a problem in the ui, namely having too many different
> commands or options (reset/commit/add/checkout resp. diff invocations;
> I've described that already) for different aspects of a "similar"
> concept (cp content version from A to B resp. diff it).

I agree that there is a problem --- a difficult learning curve that
means for example it took a year or so before I was used to the "git
diff describes the changes you are preparing" mnemonic for the various
0- and 1-tree git diff forms --- but I do not agree with your specific
characterization of it.  If there are too many ways to spell
operations of a certain class then we should be looking to deprecate
some of them, and that is a direction I do not think would be very
fruitful.

So I'd prefer to focus on actual UI bugs, of the form, "A reasonable
person tried this command, expecting this effect, and got some other
effect instead" or "A reasonable person was searching for a command
with this effect and the only solutions she came up with were
convoluted".

Example:

Long ago, I remember wanting to see what unstaged changes were in
the worktree --- that is, I wanted to compare the content of the
index to the worktree.  So, tell "git diff" to look at the index:

	git diff --cached

No, I should have used "git diff" and the model of "git diff" I had
was completely wrong.  How can we avoid this confusion?

One answer would be to adapt "git diff" to match a familiar model,
that of the ordinary "diff" command.  "diff" takes two arguments,
preimage and postimage, so that would be:

	git diff INDEX WORKTREE

If there were an unmerged path in the index, this would do a
three-way diff, just like "git diff" currently does.

That all sounds great, but I do not find it completely satisfactory.
One problem is that if this is the mental model people have of
"git diff", the three-way diff for a multiple stages, behavior of
"git diff <paths>", and so on, however they are spelled, will look
completely mystifying.  From the point of view of "this command
explains the changes in the worktree" they make sense, while from the
point of view of "compare A to B" they don't make much sense at all.
So this change just defers the learning process.

I think part of the problem in the current UI is that the
documentation never spells out the idea of what plain "git diff" is
for.  Worse, "--cached means to look to the index in place of the
worktree" doesn't seem to be spelled out anywhere except gitcli(7).  I
am not sure it is worth the headache of spelling the latter out
instead of changing the UI to be easier to explain.

Something like "git diff --index-only" would at least set people
thinking in the right direction --- "index only as opposed to what?".

With an INDEX pseudo-tree,

	git diff INDEX

is a synonym for "git diff", and to do "git diff --cached" one would
have to write

	git diff HEAD INDEX

I like the "rename --cached to --index-only" proposal more but am
not too satisfied with it, either.  In a way it is tempting to teach
people

	git diff-files -p;	# compare worktree to index
	git diff-index -p HEAD;	# compare worktree to HEAD
	git diff-index -p --cached HEAD;	# compare index to HEAD
	git diff-tree -p HEAD HEAD^;	# compare HEAD^ to HEAD

I wish there were some other alternative that can be learned more
gracefully.

Sorry for the longwinded, meandering message.  Still, I hope it
clarifies a little.

Jonathan

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07 11:45                       ` Jonathan Nieder
@ 2011-06-07 19:00                         ` Holger Hellmuth
  2011-06-07 19:11                           ` Jonathan Nieder
  2011-06-07 19:34                         ` René Scharfe
  1 sibling, 1 reply; 98+ messages in thread
From: Holger Hellmuth @ 2011-06-07 19:00 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Michael J Gruber, Junio C Hamano, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

On 07.06.2011 13:45, Jonathan Nieder wrote:
[...]
> If there were an unmerged path in the index, this would do a
> three-way diff, just like "git diff" currently does.
>
> That all sounds great, but I do not find it completely satisfactory.
> One problem is that if this is the mental model people have of
> "git diff", the three-way diff for a multiple stages, behavior of
> "git diff<paths>", and so on, however they are spelled, will look
> completely mystifying.  From the point of view of "this command
> explains the changes in the worktree" they make sense, while from the
> point of view of "compare A to B" they don't make much sense at all.
> So this change just defers the learning process.

If someone finds the three-way diff completely mystifiying, how do you 
expect him to resolve a merge conflict at all? Or recognize that there 
is one? Or find the command to use after editing out the conflict markers?

A novice user will have no real mental model anyway. He will be looking 
for simple (and easy to remember) commands for (mostly) simple needs.

> I think part of the problem in the current UI is that the
> documentation never spells out the idea of what plain "git diff" is
> for.  Worse, "--cached means to look to the index in place of the
> worktree" doesn't seem to be spelled out anywhere except gitcli(7).  I
> am not sure it is worth the headache of spelling the latter out
> instead of changing the UI to be easier to explain.
>
> Something like "git diff --index-only" would at least set people
> thinking in the right direction --- "index only as opposed to what?".
>
> With an INDEX pseudo-tree,
>
> 	git diff INDEX
>
> is a synonym for "git diff", and to do "git diff --cached" one would
> have to write
>
> 	git diff HEAD INDEX
>
> I like the "rename --cached to --index-only" proposal more but am
> not too satisfied with it, either.  In a way it is tempting to teach
> people
>
> 	git diff-files -p;	# compare worktree to index
> 	git diff-index -p HEAD;	# compare worktree to HEAD
> 	git diff-index -p --cached HEAD;	# compare index to HEAD
> 	git diff-tree -p HEAD HEAD^;	# compare HEAD^ to HEAD

if you look at the comments you put behind the commands, they look very 
much like the proposed diff command. How much time would a novice (and 
everyone else) need to remember your comments compared to your commands? 
A lot less.

Holger.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07 19:00                         ` Holger Hellmuth
@ 2011-06-07 19:11                           ` Jonathan Nieder
  2011-06-07 20:33                             ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Jonathan Nieder @ 2011-06-07 19:11 UTC (permalink / raw)
  To: Holger Hellmuth
  Cc: Michael J Gruber, Junio C Hamano, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

Holger Hellmuth wrote:

> If someone finds the three-way diff completely mystifiying, how do
> you expect him to resolve a merge conflict at all? Or recognize that
> there is one? Or find the command to use after editing out the
> conflict markers?
>
> A novice user will have no real mental model anyway.

Yes, I think you're getting closer to the point I was trying to make.
A novice will have a naive mental model, and a good user interface
needs to be close to it but not too close.  Close because the UI must
be intuitive on its own.  Not too close because a good UI will help in
leading such a person to productive ways of thinking and working, by
making common tasks convenient.

So much for generalities.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07 11:45                       ` Jonathan Nieder
  2011-06-07 19:00                         ` Holger Hellmuth
@ 2011-06-07 19:34                         ` René Scharfe
  2011-06-07 19:38                           ` Jakub Narebski
  1 sibling, 1 reply; 98+ messages in thread
From: René Scharfe @ 2011-06-07 19:34 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Michael J Gruber, Junio C Hamano, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

Am 07.06.2011 13:45, schrieb Jonathan Nieder:
> Example:
> 
> Long ago, I remember wanting to see what unstaged changes were in
> the worktree --- that is, I wanted to compare the content of the
> index to the worktree.  So, tell "git diff" to look at the index:
> 
> 	git diff --cached
> 
> No, I should have used "git diff" and the model of "git diff" I had
> was completely wrong.  How can we avoid this confusion?

Would it help if a header was shown in this case, describing the
following diff, e.g. something like this:

	$ cd /tmp && mkdir repo && cd repo && git init
	Initialized empty Git repository in /tmp/repo/.git/
	$ echo a >a && git add a && git commit -m.
	[master (root-commit) faeefb5] .
	 1 files changed, 1 insertions(+), 0 deletions(-)
	 create mode 100644 a
	$ echo b >a
	$ git diff
	Let's get rrready to diiiiff!!
	In corner a: the INDEX!  And in corner b: the WORKTREE!

	diff --git a/a b/a
	index 7898192..6178079 100644
	--- a/a
	+++ b/a
	@@ -1 +1 @@
	-a
	+b

Such a prefix would be ignored by patch etc..  You would still get it
wrong at the first try but now you'd get immediate feedback on what you
actually compared, without having to read the manpage.

René

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07 19:34                         ` René Scharfe
@ 2011-06-07 19:38                           ` Jakub Narebski
  0 siblings, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-07 19:38 UTC (permalink / raw)
  To: René Scharfe
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

René Scharfe wrote:

> Would it help if a header was shown in this case, describing the
> following diff, e.g. something like this:
> 
> 	$ cd /tmp && mkdir repo && cd repo && git init
> 	Initialized empty Git repository in /tmp/repo/.git/
> 	$ echo a >a && git add a && git commit -m.
> 	[master (root-commit) faeefb5] .
> 	 1 files changed, 1 insertions(+), 0 deletions(-)
> 	 create mode 100644 a
> 	$ echo b >a
> 	$ git diff
> 	Let's get rrready to diiiiff!!
> 	In corner a: the INDEX!  And in corner b: the WORKTREE!
> 
> 	diff --git a/a b/a
> 	index 7898192..6178079 100644
> 	--- a/a
> 	+++ b/a
> 	@@ -1 +1 @@
> 	-a
> 	+b
> 
> Such a prefix would be ignored by patch etc..  You would still get it
> wrong at the first try but now you'd get immediate feedback on what you
> actually compared, without having to read the manpage.

We have `diff.mnemonicprefix`, though it is not header... and is not set
by default ;-)

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07 19:11                           ` Jonathan Nieder
@ 2011-06-07 20:33                             ` Jakub Narebski
  2011-06-08 13:04                               ` Holger Hellmuth
  0 siblings, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-07 20:33 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Holger Hellmuth, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

On Tue, 7 June 2011, Jonathan Nieder wrote:
> Holger Hellmuth wrote:
> 
> > If someone finds the three-way diff completely mystifiying, how do
> > you expect him to resolve a merge conflict at all? Or recognize that
> > there is one? Or find the command to use after editing out the
> > conflict markers?
> >
> > A novice user will have no real mental model anyway.
> 
> Yes, I think you're getting closer to the point I was trying to make.
> A novice will have a naive mental model, and a good user interface
> needs to be close to it but not too close.  Close because the UI must
> be intuitive on its own.  Not too close because a good UI will help in
> leading such a person to productive ways of thinking and working, by
> making common tasks convenient.
> 
> So much for generalities.

To reiterate; perhaps it is not stated clearly in documentation:

1. "git diff" is about examining _your_ changes.  This short form is the
   same in every SCM.

   Because of explicit index (cache, staging area) one needs to know if
   it is working area against index, or working area against HEAD. 
   Thinking about merge conflict case helps to remember; in such case
   you want your changes against partially resolved merge.

   Also advanced users can use index to hide fully cooked changes from
   having to browse during review.

   Novice users which do not use index (and use "git commit -a") would
   never notice the difference, if not for the complication of newly
   added files: in other SCM you would see on "<scm> diff" creation
   diff (well, there is "git add -N").  Same with removal if one uses
   "git rm" and not simply "rm".

2. "git diff --cached" is about cached (staged) changes, therefore
   it is index against HEAD.

3. "git diff <commit>" in general, and "git diff HEAD" in particular,
   is about your changes (worktree), compared to given commit.

At in no place I _have_ to explain what is compared with what to explain 
when and what for to use "git diff", "git diff --cached" and "git diff 
HEAD".

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-07  6:11                     ` Michael J Gruber
  2011-06-07 11:45                       ` Jonathan Nieder
@ 2011-06-08 11:12                       ` Jakub Narebski
  2011-06-08 11:39                         ` Michael Nahas
  1 sibling, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-08 11:12 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Junio C Hamano, Scott Chacon, Michael Nahas, git

On Tue, 7 June 2011, Michael J Gruber wrote:
> Junio C Hamano venit, vidit, dixit 06.06.2011 18:14:
 
> > just repeating a fuzzy and uncooked "idea" around phoney
> > ref-looking names that will end up confusing the users, and selling that
> > as if it is a logical conclusion to "we want to give an easier to
> > understand UI", without presenting a solid user experience design that is
> > convincing enough that the "idea" will reduce confusion will not get us
> > anywhere, especially when it is sprinkled with ad hominem attack at me.
> 
> I've re-read all my posts in this thread and have no idea what you're
> referring to here.

I think one can see __ad hominem__ attack in *implication* that the idea
got shot down because of Junio (and Linus) _personal_ resistance to
fresh ideas.  And that is Junio stubborness than stand in the way of
new ideas.  Certainly somebody more sensitive might read it as such.

> If I were more sensitive I could spot attacks at 
> myself in the above, though. Just count your usage of terms like
> "phoney", "fuzzy" etc. directed at other people's ideas and arguments.

Those "attacks" are at ideas and arguments, not at people.

> I'm actually wondering whether there is any agreement on the sheer fact
> that there is a problem in the ui, namely having too many different
> commands or options (reset/commit/add/checkout resp. diff invocations;
> I've described that already) for different aspects of a "similar"
> concept (cp content version from A to B resp. diff it).
> 
> If we don't agree that there's a problem then there's no point
> discussing solutions (or ideas/brainstorms thereof).

Well, some of current overloading might be leftover result of "git is too
complicated, see how many commands it have [in $PATH]" criticism of git
and comparison with other (D)VCS... and in reducing number of commands
the pendulum perhaps went too far in opposite direction.

I don't quite think that we need "git diff NEXT WTREE"; the short
and sweet "git diff" is short for a reason, see my other response in this
thread:

  http://thread.gmane.org/gmane.comp.version-control.git/175061/focus=175265

and that the pseudo-almost-ref notation it would require for each such
pseudo-ref considering many corner cases:

  git diff <pseudo-ref-A> <pseudo-ref-B>
  git diff <commit or tree> <pseudo-ref>
  git diff <pseudo-ref>
  git show <pseudo-ref>

in normal and in conflicted case.


I am also not sure if replacing "context-sensitive" git-checkout behavior
by "git revert-file" (or rather "git revert-path", as you can use pathspec,
c.f. "git checkout ."), is something to consider without rock-solid UI
design and a very good name.  True, context dependent grammars are harder
than context-free grammars, but people do understand context, don't they?

Anyway, if one does not remember "git checkout -- <file>", one can always
use obvious alternative, namely "git show :./<file> > <file>"...


BUT I quite like "git unadd" (and/or "git unstage") idea.  

It is not obvious that "git reset" can be used for files, and it requires
bit of analysis that it resets index from HEAD: 
1. "git reset [<options>]" always resets from commit (defaults to HEAD),
2. "git reset" == "git reset --mixed" modifies current branch and index
   (HEAD -> index -> worktree progression of --soft -> --mixed -> --hard
   et al.),
3. modifying branch tip doesn't make sense for checking out file, so
4. "git reset -- <file>" must set index version of file from HEAD.

Truth to be told I really just follow what "git status" tells me ;-)

Though I am always wondering why there isn't "git reset --hard <file>"
to mean the same as "git checkout HEAD <file>".

So +1 from me for "git unadd [<commit>] [--] <path>..." (and "git unstage")
to do _exactly the same_ as "git reset [<commit>] [--] <path>...".

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-08 11:12                       ` Command-line interface thoughts (ad-hominem attacks) Jakub Narebski
@ 2011-06-08 11:39                         ` Michael Nahas
  2011-06-08 12:42                           ` Jakub Narebski
  2011-06-08 15:05                           ` Jeff King
  0 siblings, 2 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-08 11:39 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> I don't quite think that we need "git diff NEXT WTREE"; the short
> and sweet "git diff" is short for a reason,

To be clear, I'm not advocating and have never advocated getting rid
of zero-argument "git diff".  I've advocated that every (whole
project) diff command should be expressible by a "git diff TREE1
TREE2".  I'm fine with defaults if one or zero trees are specified.
So "git diff" would default to "git diff NEXT WTREE".


> It is not obvious that "git reset" can be used for files, and it requires
> bit of analysis that it resets index from HEAD:
...
> 4. "git reset -- <file>" must set index version of file from HEAD.
>
> Truth to be told I really just follow what "git status" tells me ;-)

I love those messages but if a user is relying on just copying a
warning message, then they are learning anything.  They're parroting.
I believe a user interface should have concepts and commands that make
sense, so that user will learn them and be able to apply them in other
areas.

> --
> Jakub Narebski
> Poland
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-08 11:39                         ` Michael Nahas
@ 2011-06-08 12:42                           ` Jakub Narebski
  2011-06-08 14:15                             ` Michael Nahas
  2011-06-08 15:05                           ` Jeff King
  1 sibling, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-08 12:42 UTC (permalink / raw)
  To: mike; +Cc: Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Wed, Jun 8, 2011, Michael Nahas wrote:
> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:

> > I don't quite think that we need "git diff NEXT WTREE"; the short
> > and sweet "git diff" is short for a reason,
> 
> To be clear, I'm not advocating and have never advocated getting rid
> of zero-argument "git diff".  I've advocated that every (whole
> project) diff command should be expressible by a "git diff TREE1
> TREE2".  I'm fine with defaults if one or zero trees are specified.

Those pseudo-almost-refs (almost-tree-ish) are to help new users, isn't it?
But shouldn't new user learn that he/she should use "git diff" to review
his changes, rather than use "git diff NEXT WTREE" to compare staged
contents with working area?

> So "git diff" would default to "git diff NEXT WTREE".

You mean that "git diff NEXT WTREE" output be the same as "git diff",
except for corner cases (merge conflict), isn't it?

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-07 20:33                             ` Jakub Narebski
@ 2011-06-08 13:04                               ` Holger Hellmuth
  2011-06-08 18:56                                 ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Holger Hellmuth @ 2011-06-08 13:04 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

On 07.06.2011 22:33, Jakub Narebski wrote:
> To reiterate; perhaps it is not stated clearly in documentation:
 >
> 1. "git diff" is about examining _your_ changes.  This short form is the
>     same in every SCM.

you are right, more explicit mention in the docs would help about this.

But other SCMs don't have the additional target 'index'. Much easier to 
reason there. Also, wouldn't Joe User then conclude that 'git diff' must 
be comparing working area against HEAD ?

>     Because of explicit index (cache, staging area) one needs to know if
>     it is working area against index, or working area against HEAD.
>     Thinking about merge conflict case helps to remember; in such case
>     you want your changes against partially resolved merge.

This is far from a straightforward reasoning that would pop up in 
anyones mind. In truth, I can't follow that reasoning even now. In case 
of a merge conflict the working area doesn't concern me at all, I would 
want a diff between 'ours' and 'theirs'

Since perl has been brought up as example of this DWIM philosophy: In 
perl commands have their defaults, but you always can specify exactly 
what you want if you are not sure or want to make it explicit. You can 
use 'chomp' or you can use 'chomp $_'. But I can't make it explicit 
which two targets I want to compare with 'git diff'.

>     Also advanced users can use index to hide fully cooked changes from
>     having to browse during review.
>
>     Novice users which do not use index (and use "git commit -a") would
>     never notice the difference, if not for the complication of newly
>     added files: in other SCM you would see on "<scm>  diff" creation
>     diff (well, there is "git add -N").  Same with removal if one uses
>     "git rm" and not simply "rm".

> 2. "git diff --cached" is about cached (staged) changes, therefore
>     it is index against HEAD.

We use three words to talk about the index: cache, stage, index. So 
apart from having an additional target for diff that target also is 
diffused by three words. Sure, index is the real designation and cached 
and staged are used as verbs, but that is just one more confusing bit. 
Also 'cache' in computer science is a transparent buffer to access data 
faster (wikipedia definition). Not what I would think of the index.

Probably there are good reasons to not use "git diff --index" and 
probably they have been discussed a few times, but it doesn't make using 
diff easier. But that's a side issue.

If someone sees 'git diff --cached' he might know one target, the index. 
But how does he get the other? By reasoning that 'git diff' alone is 
already index against working area? But for that he would have first to 
conclude that 'git diff' is not working area against HEAD (as it is in 
other SCMs), see above.

> 3. "git diff<commit>" in general, and "git diff HEAD" in particular,
>     is about your changes (worktree), compared to given commit.
>
> At in no place I _have_ to explain what is compared with what to explain
> when and what for to use "git diff", "git diff --cached" and "git diff
> HEAD".
>

I'm sure every part of the user interface of gimp can be rationalized in 
the same way by someone deeply involved in the concepts and the 
structure of gimp, but still it is perceived as difficult by nearly 
everyone else. You look at it from inside and it looks logical. Others 
just don't have all the pieces to make that reasoning really work.

Holger.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06 13:20                 ` Michael J Gruber
@ 2011-06-08 13:10                   ` Jakub Narebski
  0 siblings, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-08 13:10 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Junio C Hamano, Scott Chacon, Michael Nahas, git

On Mon, 6 Jun 2011, Michael J Gruber wrote:
> Jakub Narebski venit, vidit, dixit 06.06.2011 14:19:
>> On Mon, 6 June 2011, Michael J Gruber wrote:
>>> Junio C Hamano venit, vidit, dixit 06.06.2011 08:16:
>>>> Scott Chacon <schacon@gmail.com> writes:

[...]
>>> That is why the other Michael suggested "NEXT" as opposed to "INDEX":
>>> The index has many aspects, only one of which is "the contents of the
>>> next commit if I would issue 'git commit' right now". (I would even go
>>> so far as using "STAGE".) Now, it's hard to argue that "the result of a
>>> commit" is not tree-like, isn't it? And there's no question what "git
>>> show NEXT" would do. Yes, if you repeat that command, you get a
>>> different sha1 each time (because of the time field).
>>>
>>> I don't think anyone is seriously suggesting to replace the index by a
>>> pseudo commit; but the one aspect which people use most could be well
>>> represented like that, and this might even help emphasizing the
>>> different aspects of the index. Give the index an identity as an
>>> "object" (no, no new type, not in the object db, but as a ui object),
>>> not something mysterious behind the scenes!
>> 
>> So what you suggest would make
>> 
>>   $ git diff NEXT WTREE
>> 
>> behave differently from
>> 
>>   $ git diff
>> 
>> and
>> 
>>   $ git diff HEAD NEXT
>> 
>> behave differently from
>> 
>>   $ git diff --cached
>> 
>> Do you really think that it is good idea?
> 
> I don't know where you're getting from that someone is suggesting to
> make them different. (And even if, it's new UI, not changed.) Everyone's
> been suggesting to make these more accessible.

Here:

  That is why the other Michael suggested "NEXT" as opposed to "INDEX":

It was in response to question how "git diff NEXT WTREE" etc. and
"git show NEXT" would look like _in presence of merge conflicts_, as
compared to "git diff" etc. and "git ls-files" / "git ls-files --stage".

>>> As for WTREE: git diff against work tree does not look at non-tracked
>>> ignored files, so why should WTREE?
>> 
>> So we tailor WTREE do diff behavior?
> 
> There is no WTREE and nothing to tailer. We create it so that it is most
> useful and consistent, whatever that may be.

But what if "most useful" contradicts "consistent" (and "user friendly")
and vice versa?  That is the problem with designing this UI.

>> Besides, isn't this exercise a bit academic?  New to git wouldn't use
>> index, and would use 'git commit -a' and 'git diff'... and that would
>> be enough... well, perhaps except 'git add' + 'git diff'...
> 
> But we want them to grasp and use the git concepts! That is why some of
> us want to make them more accessible.

I don't think that making stage/index and working area look like tree-ish
(which they ain't), or using tree-ish like keyword for some ways of 
accessing/addressing index and worktree would make them grasp git concepts.
 
All the corner cases of proposed UI must be addressed in detail, and
examined to tell if it would make git [concepts] more accessible, or if
it would just move difficulty in other place.

>>> Full disclosure: I love the index but hate the way we make it difficult
>>> to use sometimes, and even have to lookup myself what command and option
>>> to actually use if all I want to do is diff A against B, or take the
>>> version of a file from A and write it to B, when A and B are a commit,
>>> the index or the worktree (with a commit being the nonwritable, of course).
>> 
>> Note that in case of saving to worktree you can always use
>> 
>>   $ git show HEAD:./foo>foo
>>   $ git show :0:./foo  >foo     # or just :./foo
> 
> Exactly, yet another command to add to the list below, and it's not even
> all git (because of the shell redirection).

Orthogonality is good in theory, but having more than one way to do
something (like Perl's TIMTOWTDI) is a good thing, especially for UI.
 
>>> I mean, this is really crazy: We have 4 commands ("add", "rm
>>> [--cached]", "checkout [<commit>] --", "reset [<commit>] --") which you
>>> need to be aware of if all you want to do is moving file contents
>>> (content at a path) between a commit, the index and the worktree! And
>>> this is actually worse than having 6 for the 6 cases.
> 
> Add to this craziness the fact that "checkout -- <path>" reads from
> index and writes to worktree, but "checkout <commit> -- path" does not
> read from commit and write to worktree - it reads from commit and writes
> to index+worktree.
> 
> Note that I'm not suggesting to change any of the beloved
> reset/checkout/whatever variants.
> 
> But the more I look at the commit - index - worktree triangle and the
> commands we have the more I realize how messed up the ui is, simply
> because it is determined by the underlying mechanics (e.g.: checkout
> writes the index to the worktree, possibly after updating the index from
> a commit) rather than by the concepts.

Actually it is not determined by underlying mechanics, but by requiring
sane behavior.  Updating worktree from HEAD without updating index is
usually something that you do not want, generating unexpected result.

Also, IMVHO the concepts are simple to understand / remember.  All
checkout variants check out to working area; all reset variants reset
from HEAD / commit:

                 checkout    reset
                  /--^--\   /--^--\

  HEAD              |         ||v
                    |         ||
  index             ||        |v
                    ||        |
  working area      vv        v

And all those update intermediate stages.

> And the bad thing is that even when you look at a single command like
> reset or checkout, you can get confused easily because of the multiple
> different functions they overload (e.g. checkout can change HEAD, the
> index and/or the worktree), and also because of some different defaults
> (HEAD vs. index). I think we lost consistency here because over time
> "useful defaults" grew in the wild.
> 
> That is why I'm suggesting concept based variants (move this content
> from A to B, show me the difference between A and B).

Like "git put" proposal by Jeff King (Peff)?

  [RFC/PATCH] git put: an alternative to add/reset/checkout
  http://thread.gmane.org/gmane.comp.version-control.git/175262

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-08 12:42                           ` Jakub Narebski
@ 2011-06-08 14:15                             ` Michael Nahas
  0 siblings, 0 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-08 14:15 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Wed, Jun 8, 2011 at 8:42 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> On Wed, Jun 8, 2011, Michael Nahas wrote:
>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>
>> > I don't quite think that we need "git diff NEXT WTREE"; the short
>> > and sweet "git diff" is short for a reason,
>>
>> To be clear, I'm not advocating and have never advocated getting rid
>> of zero-argument "git diff".  I've advocated that every (whole
>> project) diff command should be expressible by a "git diff TREE1
>> TREE2".  I'm fine with defaults if one or zero trees are specified.
>
> Those pseudo-almost-refs (almost-tree-ish) are to help new users, isn't it?
> But shouldn't new user learn that he/she should use "git diff" to review
> his changes, rather than use "git diff NEXT WTREE" to compare staged
> contents with working area?

I think we need a new term that refers to NEXT, WTREE, and commits.
It could be "snapshots", but that is closely associated with commit
and has a feeling of being read-only.  Maybe "root-tree"?

I think most users - new or ortherwise - should use "git diff".  It's
the shorter command.  I think a man page saying "git diff" is
equivalent to "git diff NEXT WTREE" is (1) very specific as to what
the command does and (2) illuminates new users to the concepts, so
that when they see "git diff HEAD NEXT" or "git diff HEAD WTREE", they
can imagine what is going on.

>> So "git diff" would default to "git diff NEXT WTREE".
>
> You mean that "git diff NEXT WTREE" output be the same as "git diff",
> except for corner cases (merge conflict), isn't it?

I've addressed the conflict case already.  NEXT should contain HEAD
plus all the resolved files.

As far as I can tell, with that definition, "git diff NEXT WTREE" "git
diff HEAD NEXT" and "git diff HEAD WTREE" would produce the same
results as the current implementation of "git diff", "git diff
--cached" and "git diff HEAD" --- even in a conflicted state.

I've only been able to check that by experimentation; I asked if
someone who knew the code could confirm it.

>
> --
> Jakub Narebski
> Poland
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-08 11:39                         ` Michael Nahas
  2011-06-08 12:42                           ` Jakub Narebski
@ 2011-06-08 15:05                           ` Jeff King
  2011-06-08 18:57                             ` Michael Nahas
  1 sibling, 1 reply; 98+ messages in thread
From: Jeff King @ 2011-06-08 15:05 UTC (permalink / raw)
  To: mike; +Cc: Jakub Narebski, Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:

> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> > I don't quite think that we need "git diff NEXT WTREE"; the short
> > and sweet "git diff" is short for a reason,
> 
> To be clear, I'm not advocating and have never advocated getting rid
> of zero-argument "git diff".  I've advocated that every (whole
> project) diff command should be expressible by a "git diff TREE1
> TREE2".  I'm fine with defaults if one or zero trees are specified.

I agree with this, but...

> So "git diff" would default to "git diff NEXT WTREE".

Isn't this going to be behavior change, since your NEXT is not quite the
same as the index? How do I now get an n-way combined diff of the
unmerged files in the index?

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-08 13:04                               ` Holger Hellmuth
@ 2011-06-08 18:56                                 ` Jakub Narebski
  2011-06-09 11:55                                   ` Holger Hellmuth
  0 siblings, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-08 18:56 UTC (permalink / raw)
  To: Holger Hellmuth
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

On Wed, 8 Jun 2011, Holger Hellmuth wrote:
> On 07.06.2011 22:33, Jakub Narebski wrote:

> > To reiterate; perhaps it is not stated clearly in documentation:
> >
> > 1. "git diff" is about examining _your_ changes.  This short form is the
> >     same in every SCM.
> 
> you are right, more explicit mention in the docs would help about this.
> 
> But other SCMs don't have the additional target 'index'. Much easier to 
> reason there. Also, wouldn't Joe User then conclude that 'git diff' must 
> be comparing working area against HEAD ?

Well, actually it should be that "git diff" is about examining _your_
*remaining* changes.

If Joe User doesn't use index, then "git diff" and "git diff HEAD" shows
the same contents (modulo "git add" / "git add -N" trouble).  So Joe
doesn't need to worry if it is worktree versus index, or versus HEAD;
it is enought to know when it is used.
 
> >     Because of explicit index (cache, staging area) one needs to know if
> >     it is working area against index, or working area against HEAD.
> >     Thinking about merge conflict case helps to remember; in such case
> >     you want your changes against partially resolved merge.
> 
> This is far from a straightforward reasoning that would pop up in 
> anyones mind. In truth, I can't follow that reasoning even now. In case 
> of a merge conflict the working area doesn't concern me at all, I would 
> want a diff between 'ours' and 'theirs'.

What you want is irrelevant ;-)  Because in the case of merge conflict
entries in index is populated automatically, *your* changes are changes
agains index.  So there.

And what "git diff" would show in that case is --cc diff of file with
merge markers against stages '1' and '2' in index, which is quite useful.
Which is 3-way diff between 'ours' and 'theirs'.


Nb. I don't know how to get _remaining_ diff between 'ours' and 'theirs',
but the NEXT proposal doesn't address it either...

> 
> Since perl has been brought up as example of this DWIM philosophy: In 
> perl commands have their defaults, but you always can specify exactly 
> what you want if you are not sure or want to make it explicit. You can 
> use 'chomp' or you can use 'chomp $_'.

By TIMTOWTDI I rather meant here that you can write

  if (...) {
     ...
  }

or

  ... if (...);

or

  ... or ...;


I wasn't saying anything about DWIM-mery, just TIMTOWTDI and context...

> But I can't make it explicit which two targets I want to compare with
> 'git diff'. 

For me it looks XY problem; instead of wanting to compare two explicit
targets, you should specify what you want to see ;-).
 
> >     Also advanced users can use index to hide fully cooked changes from
> >     having to browse during review.

What is where "remaining" in 'examining your remaining changes' come
from.  Advanced users can "git add <file>" (or "git add -p" even) when
some change is fully cooked and ready to be included, to reduce size of
diff when reviewing remaining changes.

> >     Novice users which do not use index (and use "git commit -a") would
> >     never notice the difference, if not for the complication of newly
> >     added files: in other SCM you would see on "<scm>  diff" creation
> >     diff (well, there is "git add -N").  Same with removal if one uses
> >     "git rm" and not simply "rm".
> 
> > 2. "git diff --cached" is about cached (staged) changes, therefore
> >     it is index against HEAD.
> 
> We use three words to talk about the index: cache, stage, index. So 
> apart from having an additional target for diff that target also is 
> diffused by three words. Sure, index is the real designation and cached 
> and staged are used as verbs, but that is just one more confusing bit. 
> Also 'cache' in computer science is a transparent buffer to access data 
> faster (wikipedia definition). Not what I would think of the index.

At the very beginning it was named 'dircache'... ;-)))

There was an attempt to introduce 'to stage', 'staged contents' and
'staging area', and you can use "git diff --staged" instead... but
support might be incomplete.


The area is called 'the index', but you examine 'cached' contents,
not 'indexed' contents.  One of resons for the index is making git
faster, so it is the cache as well (keeps e.g. cached stats info to
make it possible for git to swiftly find which files changed).
 
> Probably there are good reasons to not use "git diff --index" and 
> probably they have been discussed a few times, but it doesn't make using 
> diff easier. But that's a side issue.

The issue is with "git apply" and "git stash", where --index means
'use staging area in addition to working directory' and not like
--cached for "git apply" 'use staging area _instead_ of working
directory" (though _instead_ is not very precise here).
 
> If someone sees 'git diff --cached' he might know one target, the index. 
> But how does he get the other? By reasoning that 'git diff' alone is 
> already index against working area? But for that he would have first to 
> conclude that 'git diff' is not working area against HEAD (as it is in 
> other SCMs), see above.

"git diff --cached" / "git diff --staged" is about 'what changes are
in index' (are 'staged'), i.e. what you "git add"-ed / "git stage"-d.
Because changes always go working directory -> staging area -> repository
(commit) it is abvious that those are "staging area -> repository"
changes.
 
> > 3. "git diff<commit>" in general, and "git diff HEAD" in particular,
> >     is about your changes (worktree), compared to given commit.
> >
> > At in no place I _have_ to explain what is compared with what to explain
> > when and what for to use "git diff", "git diff --cached" and "git diff
> > HEAD".
> 
> I'm sure every part of the user interface of gimp can be rationalized in 
> the same way by someone deeply involved in the concepts and the 
> structure of gimp, but still it is perceived as difficult by nearly 
> everyone else. You look at it from inside and it looks logical. Others 
> just don't have all the pieces to make that reasoning really work.

What I wanted to say here that instead of teaching / trying to teach
new people something like the following:

  There is working area, index and current commit (HEAD).  To compare
  workdir with index use this, to compare index with HEAD use that, to
  compare workdir with HEAD use this one.

we better do explaining higher level concepts

  To examine your remaining changes, i.e. what you can "git stage",
  use "git diff".  To examine staged changes, i.e. what you 
  "git stage"-d, use "git diff --staged"; that is what "git commit"
  will create.  To compare working version with given older version,
  use "git diff <revision>", in particular to compare with last version
  use "git diff HEAD"; that is what "git commit --all" would create.


The "git diff NEXT WTREE" looks like training wheels to me.  And like
training wheels they could become obstacles and not help to learning
git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-08 15:05                           ` Jeff King
@ 2011-06-08 18:57                             ` Michael Nahas
  2011-06-09  0:43                               ` Jeff King
  2011-06-09  9:48                               ` Command-line interface thoughts Jakub Narebski
  0 siblings, 2 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-08 18:57 UTC (permalink / raw)
  To: Jeff King
  Cc: Jakub Narebski, Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:
> On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:
>
>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>> > I don't quite think that we need "git diff NEXT WTREE"; the short
>> > and sweet "git diff" is short for a reason,
>>
>> To be clear, I'm not advocating and have never advocated getting rid
>> of zero-argument "git diff".  I've advocated that every (whole
>> project) diff command should be expressible by a "git diff TREE1
>> TREE2".  I'm fine with defaults if one or zero trees are specified.
>
> I agree with this, but...
>
>> So "git diff" would default to "git diff NEXT WTREE".
>
> Isn't this going to be behavior change, since your NEXT is not quite the
> same as the index? How do I now get an n-way combined diff of the
> unmerged files in the index?
>
> -Peff

The index is a file in .git/ that serves many purposes.  NEXT is an
image of the whole project.  NEXT can be computed from the index and
HEAD.

During a conflicted merge, stage 0 of the index holds the resolved
files.  WTREE holds all merge files: the resolved and the unresolved
(which have <<<< ==== >>>> blocks in them).  I propose that during a
conflicted merge, that NEXT be computed as HEAD plus the resolved
files, that is, the files in stage 0 of the index.

"git diff HEAD NEXT" would print the resolved changes.
"git diff NEXT WTREE" would print the unresolved changes
"git diff HEAD WTREE" would print all changes.

I believe that is the same behaviour as "git diff", "git diff
--cached" and "git diff HEAD" during a conflicted merge.

I do not know how "n-way" merge works.  I saw somewhere that indicated
that it was a series of N-1 two-way merges.


Mike

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-08 18:57                             ` Michael Nahas
@ 2011-06-09  0:43                               ` Jeff King
  2011-06-09  1:56                                 ` Michael Nahas
  2011-06-09  9:48                               ` Command-line interface thoughts Jakub Narebski
  1 sibling, 1 reply; 98+ messages in thread
From: Jeff King @ 2011-06-09  0:43 UTC (permalink / raw)
  To: mike; +Cc: Jakub Narebski, Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Wed, Jun 08, 2011 at 02:57:09PM -0400, Michael Nahas wrote:

> > Isn't this going to be behavior change, since your NEXT is not quite the
> > same as the index? How do I now get an n-way combined diff of the
> > unmerged files in the index?
> 
> The index is a file in .git/ that serves many purposes.  NEXT is an
> image of the whole project.  NEXT can be computed from the index and
> HEAD.
> 
> During a conflicted merge, stage 0 of the index holds the resolved
> files.  WTREE holds all merge files: the resolved and the unresolved
> (which have <<<< ==== >>>> blocks in them).  I propose that during a
> conflicted merge, that NEXT be computed as HEAD plus the resolved
> files, that is, the files in stage 0 of the index.

OK. So NEXT actually has less information than the whole index, because
it doesn't contain information on what was on either side of the merge
originally (or in the merge base).

> "git diff HEAD NEXT" would print the resolved changes.
> "git diff NEXT WTREE" would print the unresolved changes
> "git diff HEAD WTREE" would print all changes.
> 
> I believe that is the same behaviour as "git diff", "git diff
> --cached" and "git diff HEAD" during a conflicted merge.

I assume you don't mean respectively here, but rather:

  git diff          => git diff NEXT WTREE
  git diff --cached => git diff HEAD NEXT
  git diff HEAD     => git diff HEAD WTREE

But even still, I don't think "git diff" is the same. Try this:

  git init repo && cd repo
  echo one >file && git add file && git commit -m one &&
  echo two >file && git add file && git commit -m two &&
  git checkout -b other HEAD^ &&
  echo three >file && git add file && git commit -m three &&
  ! git merge master &&
  git diff

I get:

  diff --cc file
  index 2bdf67a,f719efd..0000000
  --- a/file
  +++ b/file
  @@@ -1,1 -1,1 +1,5 @@@
  ++<<<<<<< HEAD
   +three
  ++=======
  + two
  ++>>>>>>> master

Note that this is _not_ a diff between NEXT and the working tree.  It is a
3-way "combined" diff of what's in the working tree compared to each side of
the merge.

If NEXT is a tree that contains HEAD plus stage 0 files, then we would
see a 2-way diff of the HEAD version of "file" and the working tree
version. I.e., the same as "git diff HEAD -- file":

  diff --git a/file b/file
  index 2bdf67a..087e97e 100644
  --- a/file
  +++ b/file
  @@ -1 +1,5 @@
  +<<<<<<< HEAD
   three
  +=======
  +two
  +>>>>>>> master

which looks similar, because we haven't started resolving anything yet.
But try resolving it like this:

  cat >file <<'EOF'
  three
  and
  two
  EOF

Now try "git diff" again. You should get:

  diff --cc file
  index 2bdf67a,f719efd..0000000
  --- a/file
  +++ b/file
  @@@ -1,1 -1,1 +1,3 @@@
   +three
  ++and
  + two

This shows us that "three" came from one side of the merge, "two" from
the other, and that "and" was found in neither side.

Compare to the 2-way that shows:

  diff --git a/file b/file
  index 2bdf67a..1ecff7e 100644
  --- a/file
  +++ b/file
  @@ -1 +1,3 @@
   three
  +and
  +two

There's nothing to distinguish added code pulled from the other side of
the merge versus changes that were made as part of the resolution.

I think this is what Junio was talking about when he said that the index
is more than a tree. There may be times when you want to treat the items
in stage 0 as a tree, but diffing against the index is more than just
diffing against that tree.

> I do not know how "n-way" merge works.  I saw somewhere that indicated
> that it was a series of N-1 two-way merges.

Git history can represent a merge of any number of branches (an "octopus
merge"), because the commits store only the final state and a list of
parent commits. The combined diff format is capable of handling an
arbitrary number of parents.

I should have just said "3-way", though, because it's not relevant here.
The index only has 2 stage bits, so we can only represent four stages
("resolved", "base", "ours", and "theirs"). So you can't represent an
n-way merge in the index.

So "git merge" just punts on an octopus merge if there are actual merge
conflicts that would need to go in the index. So in practice, people
just tend to do N-1 pair-wise merges.

You can see some example octopus merges (and their combined diff) if you
have a recent git (that supports --min-parents) with:

  git log --min-parents=3 -p --cc

in both git.git and linux-2.6.git.

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-09  0:43                               ` Jeff King
@ 2011-06-09  1:56                                 ` Michael Nahas
  2011-06-10 15:29                                   ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-09  1:56 UTC (permalink / raw)
  To: Jeff King
  Cc: Jakub Narebski, Michael J Gruber, Junio C Hamano, Scott Chacon, git

Hi Peff,

First, thanks for correcting my diff-without-NEXT-and-WTREE to
diff-with-NEXT-and-WTREE pairing.

Second, I agree that the index is more than just NEXT.  There were
good reasons behind calling it "NEXT" and not "INDEX".

Third, I didn't know for sure that "git diff" during a merge conflict
would produce a three-way-diff result, but I suspected it would.  (You
really didn't have to produce all that code - I would have accepted
your word as an expert.  But thanks!)  So, yes, the two-way merge
result of "git diff NEXT WTREE" would be different.

I could argue that git should allow a 4-way diff where "git diff NEXT
WTREE OURS THEIR" prints all the unresolved changes as coming from
OURS or THEIR or neither.  But I think that's silly.

I will say that "git diff NEXT WTREE" will tell you what's left
unresolved and most of it is in <<<<====>>>>> blocks that tell you
whether it came from OURS or THEIRS.  If the user has any discipline,
they won't introduce unnecessary changes that were not necessary for
the merge.  If they don't have discipline, we really can't help them.

I'm not saying there is no use for a 3-way merge.  In fact, I'd guess
it's a requirement so that Alice can check Bob's merge before Bob
commits.  But I'm fine with making it "git diff --3-way" or the silly
"git diff NEXT WTREE OURS THEIRS" because I think its "git diff NEXT
WTREE" will be good enough 99% of the time.



On Wed, Jun 8, 2011 at 8:43 PM, Jeff King <peff@peff.net> wrote:
> On Wed, Jun 08, 2011 at 02:57:09PM -0400, Michael Nahas wrote:
>
>> > Isn't this going to be behavior change, since your NEXT is not quite the
>> > same as the index? How do I now get an n-way combined diff of the
>> > unmerged files in the index?
>>
>> The index is a file in .git/ that serves many purposes.  NEXT is an
>> image of the whole project.  NEXT can be computed from the index and
>> HEAD.
>>
>> During a conflicted merge, stage 0 of the index holds the resolved
>> files.  WTREE holds all merge files: the resolved and the unresolved
>> (which have <<<< ==== >>>> blocks in them).  I propose that during a
>> conflicted merge, that NEXT be computed as HEAD plus the resolved
>> files, that is, the files in stage 0 of the index.
>
> OK. So NEXT actually has less information than the whole index, because
> it doesn't contain information on what was on either side of the merge
> originally (or in the merge base).
>
>> "git diff HEAD NEXT" would print the resolved changes.
>> "git diff NEXT WTREE" would print the unresolved changes
>> "git diff HEAD WTREE" would print all changes.
>>
>> I believe that is the same behaviour as "git diff", "git diff
>> --cached" and "git diff HEAD" during a conflicted merge.
>
> I assume you don't mean respectively here, but rather:
>
>  git diff          => git diff NEXT WTREE
>  git diff --cached => git diff HEAD NEXT
>  git diff HEAD     => git diff HEAD WTREE
>
> But even still, I don't think "git diff" is the same. Try this:
>
>  git init repo && cd repo
>  echo one >file && git add file && git commit -m one &&
>  echo two >file && git add file && git commit -m two &&
>  git checkout -b other HEAD^ &&
>  echo three >file && git add file && git commit -m three &&
>  ! git merge master &&
>  git diff
>
> I get:
>
>  diff --cc file
>  index 2bdf67a,f719efd..0000000
>  --- a/file
>  +++ b/file
>  @@@ -1,1 -1,1 +1,5 @@@
>  ++<<<<<<< HEAD
>   +three
>  ++=======
>  + two
>  ++>>>>>>> master
>
> Note that this is _not_ a diff between NEXT and the working tree.  It is a
> 3-way "combined" diff of what's in the working tree compared to each side of
> the merge.
>
> If NEXT is a tree that contains HEAD plus stage 0 files, then we would
> see a 2-way diff of the HEAD version of "file" and the working tree
> version. I.e., the same as "git diff HEAD -- file":
>
>  diff --git a/file b/file
>  index 2bdf67a..087e97e 100644
>  --- a/file
>  +++ b/file
>  @@ -1 +1,5 @@
>  +<<<<<<< HEAD
>   three
>  +=======
>  +two
>  +>>>>>>> master
>
> which looks similar, because we haven't started resolving anything yet.
> But try resolving it like this:
>
>  cat >file <<'EOF'
>  three
>  and
>  two
>  EOF
>
> Now try "git diff" again. You should get:
>
>  diff --cc file
>  index 2bdf67a,f719efd..0000000
>  --- a/file
>  +++ b/file
>  @@@ -1,1 -1,1 +1,3 @@@
>   +three
>  ++and
>  + two
>
> This shows us that "three" came from one side of the merge, "two" from
> the other, and that "and" was found in neither side.
>
> Compare to the 2-way that shows:
>
>  diff --git a/file b/file
>  index 2bdf67a..1ecff7e 100644
>  --- a/file
>  +++ b/file
>  @@ -1 +1,3 @@
>   three
>  +and
>  +two
>
> There's nothing to distinguish added code pulled from the other side of
> the merge versus changes that were made as part of the resolution.
>
> I think this is what Junio was talking about when he said that the index
> is more than a tree. There may be times when you want to treat the items
> in stage 0 as a tree, but diffing against the index is more than just
> diffing against that tree.
>
>> I do not know how "n-way" merge works.  I saw somewhere that indicated
>> that it was a series of N-1 two-way merges.
>
> Git history can represent a merge of any number of branches (an "octopus
> merge"), because the commits store only the final state and a list of
> parent commits. The combined diff format is capable of handling an
> arbitrary number of parents.
>
> I should have just said "3-way", though, because it's not relevant here.
> The index only has 2 stage bits, so we can only represent four stages
> ("resolved", "base", "ours", and "theirs"). So you can't represent an
> n-way merge in the index.
>
> So "git merge" just punts on an octopus merge if there are actual merge
> conflicts that would need to go in the index. So in practice, people
> just tend to do N-1 pair-wise merges.
>
> You can see some example octopus merges (and their combined diff) if you
> have a recent git (that supports --min-parents) with:
>
>  git log --min-parents=3 -p --cc
>
> in both git.git and linux-2.6.git.
>
> -Peff
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-06  6:16           ` Junio C Hamano
  2011-06-06  7:34             ` Michael J Gruber
@ 2011-06-09  9:06             ` Michael Haggerty
  2011-06-09 10:02               ` Andreas Ericsson
  2011-06-09 16:18               ` Jeff King
  1 sibling, 2 replies; 98+ messages in thread
From: Michael Haggerty @ 2011-06-09  9:06 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Scott Chacon, Jakub Narebski, Michael Nahas, git

On 06/06/2011 08:16 AM, Junio C Hamano wrote:
> Scott Chacon <schacon@gmail.com> writes:
>> For example, implementation details aside, I think having something
>> like WTREE and NEXT available would help users understand that there
>> are these 3 trees that are important and useful in Git and re-inforce
>> a very non-SVN style workflow in that manner.
> 
> That's a funny thing to say. Working tree may almost always (to put it
> another way, "you could make it to") act like a tree, but the index does
> not act like a tree at all in more important situations.

My naive understanding is that in the case of a merge commit, the index
contains information equivalent to *multiple* trees:

NEXT -- HEAD plus the files that have been resolved
BASE -- the contents of the common ancestor
OURS -- equivalent to the tree from HEAD
THEIRS -- equivalent to the tree from MERGE_HEAD

If my understanding is correct, then it would be logical to allow *any*
of these pseudo-trees to participate in a "git diff" during a conflicted
merge.

If I'm incorrect, then I expect a learning-experience-by-flame :-)

FWIW, when I was learning git, I struggled with exactly the problems
that Michael is trying to address.  My most frustrating moments always
involved trying to get my working tree and index from some existing
state to some desired state, because operations that seemed (in my
mental model) to be similar typically required using entirely different
git commands and/or command options.  Having a uniform nomenclature for
these concepts would be a big improvement (if the resulting abstraction
does not leak too badly).  I also think that the proposal for "git put"
would be a great help and would work nicely with the proposed changes to
"git diff".

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-08 18:57                             ` Michael Nahas
  2011-06-09  0:43                               ` Jeff King
@ 2011-06-09  9:48                               ` Jakub Narebski
  2011-06-09 11:44                                 ` Michael Nahas
  1 sibling, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-09  9:48 UTC (permalink / raw)
  To: mike; +Cc: Jeff King, Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Wed, 8 June 2011, Michael Nahas wrote:
> On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:
>> On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:
>>
>>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>>>> I don't quite think that we need "git diff NEXT WTREE"; the short
>>>> and sweet "git diff" is short for a reason,
>>>
>>> To be clear, I'm not advocating and have never advocated getting rid
>>> of zero-argument "git diff".  I've advocated that every (whole
>>> project) diff command should be expressible by a "git diff TREE1
>>> TREE2".  I'm fine with defaults if one or zero trees are specified.
>>
>> I agree with this, but...
>>
>>> So "git diff" would default to "git diff NEXT WTREE".
>>
>> Isn't this going to be behavior change, since your NEXT is not quite the
>> same as the index? How do I now get an n-way combined diff of the
>> unmerged files in the index?
> 
> The index is a file in .git/ that serves many purposes.  NEXT is an
> image of the whole project.  NEXT can be computed from the index and
> HEAD.
> 
> During a conflicted merge, stage 0 of the index holds the resolved
> files.

It is simply not true.  During a conflicted merge, for conflicted files
there is _no_ stage 0!!!  Conflicted files have stage 1 == base, 2 == ours
and 3 == theirs, where those stages have all conflicts that can be resolved
automatically resolved, and places where there is conflict replaced by
merge-base ('base'), current branch into which we merge ('ours') and
merged branch ('theirs').

> WTREE holds all merge files: the resolved and the unresolved 
> (which have <<<< ==== >>>> blocks in them).

Worktree version has files with conflict merge markers added in place
where there is conflict.


> I propose that during a 
> conflicted merge, that NEXT be computed as HEAD plus the resolved 
> files, that is, the files in stage 0 of the index.

Why _HEAD_?
 
> "git diff HEAD NEXT" would print the resolved changes.
> "git diff NEXT WTREE" would print the unresolved changes
> "git diff HEAD WTREE" would print all changes.
> 
> I believe that is the same behaviour as "git diff", "git diff
> --cached" and "git diff HEAD" during a conflicted merge.

"git diff NEXT WTREE" would not behave (with your proposal) like
"git diff", but like "git diff --ours".

"git diff HEAD NEXT" would not behave like "git diff --cached"
(which shows only '*Unmerged path foo').

"git diff HEAD WTREE" would be the same as "git diff HEAD" (just
longer to write), only because it doesn't involve index at all.
 

> I do not know how "n-way" merge works.  I saw somewhere that indicated
> that it was a series of N-1 two-way merges.

Where this "n-way merge" came from?  Peff wrote about "n-way combined
diff", which is something different.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09  9:06             ` Michael Haggerty
@ 2011-06-09 10:02               ` Andreas Ericsson
  2011-06-09 13:30                 ` Thomas Rast
  2011-06-09 16:18               ` Jeff King
  1 sibling, 1 reply; 98+ messages in thread
From: Andreas Ericsson @ 2011-06-09 10:02 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Junio C Hamano, Scott Chacon, Jakub Narebski, Michael Nahas, git

On 06/09/2011 11:06 AM, Michael Haggerty wrote:
> On 06/06/2011 08:16 AM, Junio C Hamano wrote:
>> Scott Chacon<schacon@gmail.com>  writes:
>>> For example, implementation details aside, I think having something
>>> like WTREE and NEXT available would help users understand that there
>>> are these 3 trees that are important and useful in Git and re-inforce
>>> a very non-SVN style workflow in that manner.
>>
>> That's a funny thing to say. Working tree may almost always (to put it
>> another way, "you could make it to") act like a tree, but the index does
>> not act like a tree at all in more important situations.
> 
> My naive understanding is that in the case of a merge commit, the index
> contains information equivalent to *multiple* trees:
> 
> NEXT -- HEAD plus the files that have been resolved
> BASE -- the contents of the common ancestor
> OURS -- equivalent to the tree from HEAD
> THEIRS -- equivalent to the tree from MERGE_HEAD
> 

Except there might be any number of THEIRS in the case of an octopus
merge. The most common case is just one though.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09  9:48                               ` Command-line interface thoughts Jakub Narebski
@ 2011-06-09 11:44                                 ` Michael Nahas
  2011-06-09 12:45                                   ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-09 11:44 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jeff King, Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Thu, Jun 9, 2011 at 5:48 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> On Wed, 8 June 2011, Michael Nahas wrote:
>> On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:
>>> On Wed, Jun 08, 2011 at 07:39:16AM -0400, Michael Nahas wrote:
>>>
>>>> On Wed, Jun 8, 2011 at 7:12 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>>>>> I don't quite think that we need "git diff NEXT WTREE"; the short
>>>>> and sweet "git diff" is short for a reason,
>>>>
>>>> To be clear, I'm not advocating and have never advocated getting rid
>>>> of zero-argument "git diff".  I've advocated that every (whole
>>>> project) diff command should be expressible by a "git diff TREE1
>>>> TREE2".  I'm fine with defaults if one or zero trees are specified.
>>>
>>> I agree with this, but...
>>>
>>>> So "git diff" would default to "git diff NEXT WTREE".
>>>
>>> Isn't this going to be behavior change, since your NEXT is not quite the
>>> same as the index? How do I now get an n-way combined diff of the
>>> unmerged files in the index?
>>
>> The index is a file in .git/ that serves many purposes.  NEXT is an
>> image of the whole project.  NEXT can be computed from the index and
>> HEAD.
>>
>> During a conflicted merge, stage 0 of the index holds the resolved
>> files.
>
> It is simply not true.  During a conflicted merge, for conflicted files
> there is _no_ stage 0!!!  Conflicted files have stage 1 == base, 2 == ours
> and 3 == theirs, where those stages have all conflicts that can be resolved
> automatically resolved, and places where there is conflict replaced by
> merge-base ('base'), current branch into which we merge ('ours') and
> merged branch ('theirs').

"resolved files" means "NOT conflicted files".  The merge conflicts if
any one file conflicts, but there may be other files that resolve
immediately.  And any conflicted files can be resolved by the user
running "git add" or "git rm"

If a file is resolved - either immediately or by user action - it
exists only in stage 0.

>> WTREE holds all merge files: the resolved and the unresolved
>> (which have <<<< ==== >>>> blocks in them).
>
> Worktree version has files with conflict merge markers added in place
> where there is conflict.

I assumed most people knew what I meant by <<<<====>>>> blocks.  But,
yes, I meant that the working tree has both versions present at
locations of conflicts.

>> I propose that during a
>> conflicted merge, that NEXT be computed as HEAD plus the resolved
>> files, that is, the files in stage 0 of the index.
>
> Why _HEAD_?

Because we merged changed from another branch into HEAD.
Or we pull changes from a remote branch into HEAD.

When a commit is written, it will be part of the branch referenced by HEAD.

>> "git diff HEAD NEXT" would print the resolved changes.
>> "git diff NEXT WTREE" would print the unresolved changes
>> "git diff HEAD WTREE" would print all changes.
>>
>> I believe that is the same behaviour as "git diff", "git diff
>> --cached" and "git diff HEAD" during a conflicted merge.
>
> "git diff NEXT WTREE" would not behave (with your proposal) like
> "git diff", but like "git diff --ours".

OURS and HEAD are the same thing, so I doubt a command that does not
involve "HEAD" would behave like "--ours"

> "git diff HEAD NEXT" would not behave like "git diff --cached"
> (which shows only '*Unmerged path foo').
>
> "git diff HEAD WTREE" would be the same as "git diff HEAD" (just
> longer to write), only because it doesn't involve index at all.

I refer you to any of my previous emails to which I kindly replied.
YES, "git diff HEAD" and "git diff HEAD WTREE" would be equivalent.
I, myself, would probably use "git diff HEAD" most of the time.
Nonetheless, saying "git diff" ALWAYS takes two arguments and saying
that if an argument is unspecified that there is a default is much
clearer and more regular interface than special casing everything and
using command-line options to say what you want, which is what we have
now.


>> I do not know how "n-way" merge works.  I saw somewhere that indicated
>> that it was a series of N-1 two-way merges.
>
> Where this "n-way merge" came from?  Peff wrote about "n-way combined
> diff", which is something different.

N-way merge exists.  It would be bad to say that I was answering a
question about conflicted merges if I didn't produce an answer for
N-way merges.  Unfortunately, I don't have enough information about
N-way merges to answer the question so I decided it was best to
acknowledge my ignorance and that I was giving an incomplete answer.



> --
> Jakub Narebski
> Poland
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-08 18:56                                 ` Jakub Narebski
@ 2011-06-09 11:55                                   ` Holger Hellmuth
  2011-06-10 16:44                                     ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Holger Hellmuth @ 2011-06-09 11:55 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

On 08.06.2011 20:56, Jakub Narebski wrote:
[...]
>>>      Because of explicit index (cache, staging area) one needs to know if
>>>      it is working area against index, or working area against HEAD.
>>>      Thinking about merge conflict case helps to remember; in such case
>>>      you want your changes against partially resolved merge.
          --------
>>
>> This is far from a straightforward reasoning that would pop up in
>> anyones mind. In truth, I can't follow that reasoning even now. In case
>> of a merge conflict the working area doesn't concern me at all, I would
>> want a diff between 'ours' and 'theirs'.
>
> What you want is irrelevant ;-)

No, because you used my wants in your reasoning above. Makes them highly 
relevant ;-)

> Because in the case of merge conflict
> entries in index is populated automatically, *your* changes are changes
> agains index.  So there.
>
> And what "git diff" would show in that case is --cc diff of file with
> merge markers against stages '1' and '2' in index, which is quite useful.
> Which is 3-way diff between 'ours' and 'theirs'.

Ah okay. This detail about the merge process never really registered 
with me. Which shows that your logic deduction what 'git diff' does is 
often not possible for the casual user

[...]
>> But I can't make it explicit which two targets I want to compare with
>> 'git diff'.
>
> For me it looks XY problem; instead of wanting to compare two explicit
> targets, you should specify what you want to see ;-).

Then don't call the command 'diff' (... I proclaim in the knowledge that 
that isn't possible). 'diff' is the short form of 'difference' which 
means literally a comparison between *two* things. If someone wants to 
see something he would pick the words 'show' or 'list'. So user 
expectation is different from what you want diff to be.

Also there are no good words for what someone wants to see in this case. 
At least I would assume the git project would have found them if they 
existed. '--cached' is definitely not one of them. But we have fitting 
and widely known names for the targets, i.e 'working tree', 'index' and 
'head'.

[...]
>>> At in no place I _have_ to explain what is compared with what to explain
>>> when and what for to use "git diff", "git diff --cached" and "git diff
>>> HEAD".
>>
>> I'm sure every part of the user interface of gimp can be rationalized in
>> the same way by someone deeply involved in the concepts and the
>> structure of gimp, but still it is perceived as difficult by nearly
>> everyone else. You look at it from inside and it looks logical. Others
>> just don't have all the pieces to make that reasoning really work.
>
> What I wanted to say here that instead of teaching / trying to teach
> new people something like the following:
>
>    There is working area, index and current commit (HEAD).  To compare
>    workdir with index use this, to compare index with HEAD use that, to
>    compare workdir with HEAD use this one.

If they know working area, index and head, you don't have to tell them 
three times how to compare this with that, they just have to know they 
can compare any which way they want. In fact, the situation *now* is 
exactly what you describe, you have to tell everyone for any of the 3 
combinations the command to use because it is not obvious.

> we better do explaining higher level concepts
>
>    To examine your remaining changes, i.e. what you can "git stage",
>    use "git diff".  To examine staged changes, i.e. what you
>    "git stage"-d, use "git diff --staged"; that is what "git commit"
>    will create.  To compare working version with given older version,
>    use "git diff<revision>", in particular to compare with last version
>    use "git diff HEAD"; that is what "git commit --all" would create.

Do you realize that you are just enumerating all the possible 
combinations again, exactly what you wanted to avoid? Ok, unfair 
argument, you want to just make it clear how to remember the commands. 
But if I already need 3 emails from you to see the concept behind these 
commands (and lets assume my slow-wittedness is par for the course) many 
others will probably have the same problems. It may be a nice concept, 
but the relation to the user interface is only detectable by close 
examination.

Teaching concepts is good. But if git is only usable after having 
learned all those concepts, the entry barrier is much too big. With 
commands like 'git put' and an improved diff people can use git first, 
then learn the concepts while using git. Which is what most people have 
to do anyway if they encounter git at the work place for example.

> The "git diff NEXT WTREE" looks like training wheels to me.  And like
> training wheels they could become obstacles and not help to learning
> git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))
>

If your goal is that anyone who uses git is a git expert, they may be a 
hindrance (as are all the porcelain commands really). If you also want 
to make git friendly to people who will never get past intermediate or 
beginner stage or will only use a small part of git or use git seldomly, 
training wheels are good.

Holger.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 11:44                                 ` Michael Nahas
@ 2011-06-09 12:45                                   ` Jakub Narebski
  2011-06-09 13:06                                     ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-09 12:45 UTC (permalink / raw)
  To: mike; +Cc: Jeff King, Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Thu, Jun 9, 2011, Michael Nahas wrote:
> On Thu, Jun 9, 2011 at 5:48 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>> On Wed, 8 June 2011, Michael Nahas wrote:
>>> On Wed, Jun 8, 2011 at 11:05 AM, Jeff King <peff@peff.net> wrote:

>>>> Isn't this going to be behavior change, since your NEXT is not quite the
>>>> same as the index?

[...]
>>> I propose that during a
>>> conflicted merge, that NEXT be computed as HEAD plus the resolved
>>> files, that is, the files in stage 0 of the index.
>>
>> Why _HEAD_?
> 
> Because we merged changed from another branch into HEAD.
> Or we pull changes from a remote branch into HEAD.
> 
> When a commit is written, it will be part of the branch referenced
> by HEAD. 

And by selecting HEAD for diff's NEXT you would have problems with rebase,
where you also can have conflicts, where 'ours' and 'theirs' are switched
around (at least from one point of view).
 
>>> "git diff HEAD NEXT" would print the resolved changes.
>>> "git diff NEXT WTREE" would print the unresolved changes
>>> "git diff HEAD WTREE" would print all changes.
>>>
>>> I believe that is the same behaviour as "git diff", "git diff
>>> --cached" and "git diff HEAD" during a conflicted merge.
>>
>> "git diff NEXT WTREE" would not behave (with your proposal) like
>> "git diff", but like "git diff --ours".
> 
> OURS and HEAD are the same thing, so I doubt a command that does not
> involve "HEAD" would behave like "--ours"

OURS and HEAD are not the same thing.  In OURS you have _conflicted_
chunks replaced with HEAD ('ours') version, but chunks that can be
resolved sutomatically are resolved; sometimes to 'theirs' version.

"git diff" in case of conflict prints 3-way combined diff between
'ours', 'theirs' and working area version.  As "git diff NEXT WTREE"
doesn't print 3-way combined diff, it would be different for conflicts
from "git diff".

"git diff --ours" for nonconflicted entry (stage 0 in index) would
print ordinary diff between index and working area, just like
"git diff NEXT WTREE".  What I just realized that at least from what
you wrote (corner case!) in case of conflicts it would be different
from "git diff NEXT WTREE", as ours != HEAD.

[...]
>>> I do not know how "n-way" merge works.  I saw somewhere that indicated
>>> that it was a series of N-1 two-way merges.
>>
>> Where this "n-way merge" came from?  Peff wrote about "n-way combined
>> diff", which is something different.
> 
> N-way merge exists.  It would be bad to say that I was answering a
> question about conflicted merges if I didn't produce an answer for
> N-way merges.  Unfortunately, I don't have enough information about
> N-way merges to answer the question so I decided it was best to
> acknowledge my ignorance and that I was giving an incomplete answer.

Actually while git can do n-way merge (so called "octopus" merge), it
either resolves it cleanly, or refuses merge; it does not try to resolve
conflict and present conflicts in the index.  So it is always "3-way
combined diff".

But you didn't answer about _combined diff_...

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 12:45                                   ` Jakub Narebski
@ 2011-06-09 13:06                                     ` Jakub Narebski
  0 siblings, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-09 13:06 UTC (permalink / raw)
  To: mike; +Cc: Jeff King, Michael J Gruber, Junio C Hamano, Scott Chacon, git

Jakub Narebski wrote:
> On Thu, Jun 9, 2011, Michael Nahas wrote:
>> On Thu, Jun 9, 2011 at 5:48 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>>> On Wed, 8 June 2011, Michael Nahas wrote:

[...]
>>>> "git diff HEAD NEXT" would print the resolved changes.
>>>> "git diff NEXT WTREE" would print the unresolved changes
>>>> "git diff HEAD WTREE" would print all changes.
>>>>
>>>> I believe that is the same behaviour as "git diff", "git diff
>>>> --cached" and "git diff HEAD" during a conflicted merge.
>>>
>>> "git diff NEXT WTREE" would not behave (with your proposal) like
>>> "git diff", but like "git diff --ours".
>> 
>> OURS and HEAD are the same thing, so I doubt a command that does not
>> involve "HEAD" would behave like "--ours"
> 
> OURS and HEAD are not the same thing.  In OURS you have _conflicted_
> chunks replaced with HEAD ('ours') version, but chunks that can be
> resolved sutomatically are resolved; sometimes to 'theirs' version.

I'm very sorry, my mistake.  I have actually checked and OURS is the
same as HEAD version.

You wrote that NEXT contains either stage 0 for resolved files, or
OURS (HEAD) version for files with conflicts.  But that is exactly
what "git diff --ours" show.

> "git diff" in case of conflict prints 3-way combined diff between
> 'ours', 'theirs' and working area version.  As "git diff NEXT WTREE"
> doesn't print 3-way combined diff, it would be different for conflicts
> from "git diff".
> 
> "git diff --ours" for nonconflicted entry (stage 0 in index) would
> print ordinary diff between index and working area, just like
> "git diff NEXT WTREE". [...]

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 10:02               ` Andreas Ericsson
@ 2011-06-09 13:30                 ` Thomas Rast
  0 siblings, 0 replies; 98+ messages in thread
From: Thomas Rast @ 2011-06-09 13:30 UTC (permalink / raw)
  To: Andreas Ericsson
  Cc: Michael Haggerty, Junio C Hamano, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

Andreas Ericsson wrote:
> On 06/09/2011 11:06 AM, Michael Haggerty wrote:
> > THEIRS -- equivalent to the tree from MERGE_HEAD
> 
> Except there might be any number of THEIRS in the case of an octopus
> merge. The most common case is just one though.

Not really, the current implementation bails out and tells you not to
use an octopus:

  Trying simple merge with t/man-unquote-apos-3
  Simple merge did not work, trying automatic merge.
  Auto-merging Documentation/Makefile
  ERROR: content conflict in Documentation/Makefile
  Auto-merging Makefile
  fatal: merge program failed
  Automated merge did not work.
  Should not be doing an Octopus.
  Merge with strategy octopus failed.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09  9:06             ` Michael Haggerty
  2011-06-09 10:02               ` Andreas Ericsson
@ 2011-06-09 16:18               ` Jeff King
  2011-06-09 17:15                 ` Jay Soffian
  2011-06-09 18:03                 ` Michael Haggerty
  1 sibling, 2 replies; 98+ messages in thread
From: Jeff King @ 2011-06-09 16:18 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Junio C Hamano, Scott Chacon, Jakub Narebski, Michael Nahas, git

On Thu, Jun 09, 2011 at 11:06:56AM +0200, Michael Haggerty wrote:

> My naive understanding is that in the case of a merge commit, the index
> contains information equivalent to *multiple* trees:
> 
> NEXT -- HEAD plus the files that have been resolved
> BASE -- the contents of the common ancestor
> OURS -- equivalent to the tree from HEAD
> THEIRS -- equivalent to the tree from MERGE_HEAD

Almost. Remember that as part of the merge resolution process,
higher-level stages will collapse down to 0. So the "theirs" stage of
the index is equivalent to MERGE_HEAD only if you have a conflict in
every file and have resolved nothing. Otherwise, any resolved entries
will not have a "theirs" entry at all.

So when I do "git diff", we will see for resolved entries that the
working tree matches stage 0 in the index, and show nothing. Whereas
unresolved entries will have their diff shown. But with "git diff
MERGE_HEAD", we will see differences from the other branch, even if
those differences are simply resolutions or even changes made on the
"ours" branch.

So the index is not quite simply a set of four trees. The presence of
various stages for each entry tells us the progress of resolution.

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 16:18               ` Jeff King
@ 2011-06-09 17:15                 ` Jay Soffian
  2011-06-09 17:20                   ` Jeff King
  2011-06-09 17:36                   ` Junio C Hamano
  2011-06-09 18:03                 ` Michael Haggerty
  1 sibling, 2 replies; 98+ messages in thread
From: Jay Soffian @ 2011-06-09 17:15 UTC (permalink / raw)
  To: Jeff King
  Cc: Michael Haggerty, Junio C Hamano, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

On Thu, Jun 9, 2011 at 12:18 PM, Jeff King <peff@peff.net> wrote:
> On Thu, Jun 09, 2011 at 11:06:56AM +0200, Michael Haggerty wrote:
>
>> My naive understanding is that in the case of a merge commit, the index
>> contains information equivalent to *multiple* trees:
>>
>> NEXT -- HEAD plus the files that have been resolved
>> BASE -- the contents of the common ancestor
>> OURS -- equivalent to the tree from HEAD
>> THEIRS -- equivalent to the tree from MERGE_HEAD
>
> Almost. Remember that as part of the merge resolution process,
> higher-level stages will collapse down to 0. So the "theirs" stage of
> the index is equivalent to MERGE_HEAD only if you have a conflict in
> every file and have resolved nothing. Otherwise, any resolved entries
> will not have a "theirs" entry at all.
>
> So when I do "git diff", we will see for resolved entries that the
> working tree matches stage 0 in the index, and show nothing. Whereas
> unresolved entries will have their diff shown. But with "git diff
> MERGE_HEAD", we will see differences from the other branch, even if
> those differences are simply resolutions or even changes made on the
> "ours" branch.
>
> So the index is not quite simply a set of four trees. The presence of
> various stages for each entry tells us the progress of resolution.

However, it would be useful I think to expose it as four separate
trees. During conflict resolution, I often want to look at the
conflicted files in these various states, and end up using various
incantations that are somewhat baroque.

e.g.:

  $ git diff ...MERGE_HEAD -- /path/to/file

is probably less clear than:

  $ git diff BASE THEIRS -- /path/to/file

In fact, my first step after a conflicted merge is:

  $ git tag -f ours HEAD
  $ git tag -f theirs MERGE_HEAD
  $ git tag -f base $(git merge-base HEAD MERGE_HEAD)

j.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 17:15                 ` Jay Soffian
@ 2011-06-09 17:20                   ` Jeff King
  2011-06-09 17:36                   ` Junio C Hamano
  1 sibling, 0 replies; 98+ messages in thread
From: Jeff King @ 2011-06-09 17:20 UTC (permalink / raw)
  To: Jay Soffian
  Cc: Michael Haggerty, Junio C Hamano, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

On Thu, Jun 09, 2011 at 01:15:38PM -0400, Jay Soffian wrote:

> > So the index is not quite simply a set of four trees. The presence of
> > various stages for each entry tells us the progress of resolution.
> 
> However, it would be useful I think to expose it as four separate
> trees. During conflict resolution, I often want to look at the
> conflicted files in these various states, and end up using various
> incantations that are somewhat baroque.

Oh, I do agree that giving easier access to those things when you want
them is reasonable. I just think that it can't _replace_ diffing with
the index, which is able to look at all of the trees at once and present
you with a useful subset.

> In fact, my first step after a conflicted merge is:
> 
>   $ git tag -f ours HEAD
>   $ git tag -f theirs MERGE_HEAD
>   $ git tag -f base $(git merge-base HEAD MERGE_HEAD)

Do note that this last one is only almost true. There may be multiple
bases, and what merge-recursive does with them may mean that what ends
up in the "base" index stage for a file may not match what is in the
first first merge-base (e.g., if a recursive virtual merge creates a new
base).

But most of the time, it is right. :)

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 17:15                 ` Jay Soffian
  2011-06-09 17:20                   ` Jeff King
@ 2011-06-09 17:36                   ` Junio C Hamano
  2011-06-09 18:20                     ` Jay Soffian
  1 sibling, 1 reply; 98+ messages in thread
From: Junio C Hamano @ 2011-06-09 17:36 UTC (permalink / raw)
  To: Jay Soffian
  Cc: Jeff King, Michael Haggerty, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

Jay Soffian <jaysoffian@gmail.com> writes:

> In fact, my first step after a conflicted merge is:
>
>   $ git tag -f ours HEAD
>   $ git tag -f theirs MERGE_HEAD
>   $ git tag -f base $(git merge-base HEAD MERGE_HEAD)

That looks like quite a convoluted set-up, I would think, than
necessary. You only need to remember these:

 # what does the result look if I said "commit -a" now?
 $ git diff HEAD	  

 # I want to also see comparison with the original
 $ git checkout --conflict=diff3 <conflicted paths>...
 $ git diff

 # What did they do since they forked from my history?
 $ git diff ...MERGE_HEAD

 # What did I do since I forked from them?
 $ git diff MERGE_HEAD...

 # I want step-by-step explanation of how these paths were touched
 $ git log -p --left-right --merge [<conflicted paths>...]

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 16:18               ` Jeff King
  2011-06-09 17:15                 ` Jay Soffian
@ 2011-06-09 18:03                 ` Michael Haggerty
  2011-06-09 18:38                   ` Junio C Hamano
  2011-06-09 19:41                   ` Jeff King
  1 sibling, 2 replies; 98+ messages in thread
From: Michael Haggerty @ 2011-06-09 18:03 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Scott Chacon, Jakub Narebski, Michael Nahas, git

On 06/09/2011 06:18 PM, Jeff King wrote:
> On Thu, Jun 09, 2011 at 11:06:56AM +0200, Michael Haggerty wrote:
> 
>> My naive understanding is that in the case of a merge commit, the index
>> contains information equivalent to *multiple* trees:
>>
>> NEXT -- HEAD plus the files that have been resolved
>> BASE -- the contents of the common ancestor
>> OURS -- equivalent to the tree from HEAD
>> THEIRS -- equivalent to the tree from MERGE_HEAD
> 
> Almost. Remember that as part of the merge resolution process,
> higher-level stages will collapse down to 0. So the "theirs" stage of
> the index is equivalent to MERGE_HEAD only if you have a conflict in
> every file and have resolved nothing. Otherwise, any resolved entries
> will not have a "theirs" entry at all.

Thanks for the correction.  So one interesting pseudo-tree would be

OURS -- The NEXT version of any file that has been resolved; and the
stage 2 version of any file that has not yet been resolved.  The name
seems consistent with what is meant by, e.g., "git checkout --ours".

Another interesting pseudo-tree would be

THEIRS -- The NEXT version of any file that has been resolved; and the
stage 3 version of any file that has not yet been resolved.  The name
seems consistent with "git checkout --theirs".

The other trees HEAD and MERGE_HEAD are already accessible under those
names, and so there is no need to make a special provision to access them.

BASE should presumably be something like the NEXT version of any file
that has been resolved and the stage 1 version of any file that has not
been resolved.

> So the index is not quite simply a set of four trees. The presence of
> various stages for each entry tells us the progress of resolution.

Wouldn't the four trees described above contain information equivalent
to the contents of the index?  For example, the resolution work that
remains to be done that can be inquired using old-fashioned "git diff"
(3-way diff) could also be accessed via

    git diff NEXT OURS
    git diff NEXT THEIRS

or even

    git diff NEXT WTREE

if you want to see the remaining conflicts in <<<<<======>>>>>> format.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 17:36                   ` Junio C Hamano
@ 2011-06-09 18:20                     ` Jay Soffian
  2011-06-09 19:40                       ` Junio C Hamano
  0 siblings, 1 reply; 98+ messages in thread
From: Jay Soffian @ 2011-06-09 18:20 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Michael Haggerty, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

On Thu, Jun 9, 2011 at 1:36 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jay Soffian <jaysoffian@gmail.com> writes:
>
>> In fact, my first step after a conflicted merge is:
>>
>>   $ git tag -f ours HEAD
>>   $ git tag -f theirs MERGE_HEAD
>>   $ git tag -f base $(git merge-base HEAD MERGE_HEAD)
>
> That looks like quite a convoluted set-up, I would think, than
> necessary. You only need to remember these:

My merges are fairly complex, involving a code base of 20k+ files with
merges bringing several hundred commits at a time. So, they require
lots of amending after conflict resolution to get into shape, where I
often have to look at either side of the merge. I prefer to tag at the
time of the merge so that I can use ours, theirs, and before and after
the merge (otherwise it's HEAD MERGE_HEAD vs HEAD^ and HEAD^2).

>  # what does the result look if I said "commit -a" now?
>  $ git diff HEAD

I never use commit -a.

>  # I want to also see comparison with the original
>  $ git checkout --conflict=diff3 <conflicted paths>...
>  $ git diff

I have merge.conflictstyle diff3 in my .gitconfig.

>  # What did they do since they forked from my history?
>  $ git diff ...MERGE_HEAD
>
>  # What did I do since I forked from them?
>  $ git diff MERGE_HEAD...

Sure, I already suggested that, but if I want to do the same after the
merge I can use the tags I've already set up.

>  # I want step-by-step explanation of how these paths were touched
>  $ git log -p --left-right --merge [<conflicted paths>...]

Now that's one I haven't used before. I usually use log ..MERGE_HEAD
and log MERGE_HEAD.. on the paths.

j.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 18:03                 ` Michael Haggerty
@ 2011-06-09 18:38                   ` Junio C Hamano
  2011-06-09 19:17                     ` Michael Haggerty
  2011-06-09 20:04                     ` Jeff King
  2011-06-09 19:41                   ` Jeff King
  1 sibling, 2 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-09 18:38 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Jeff King, Scott Chacon, Jakub Narebski, Michael Nahas, git

Michael Haggerty <mhagger@alum.mit.edu> writes:

> Wouldn't the four trees described above contain information equivalent
> to the contents of the index?

In the same sense that you can re-create the state in the index by running
the merge again between HEAD and MERGE_HEAD, yes, they probably do, but is
that a useful question to ask?

I think this mega-thread served its purpose. It started to explore "will
it make it easier to understand and explain if we use these tokens to name
trees that do not exist in reality?" which is a worthy thing to do.  The
conclusion appears to be "well we do not even know what exactly these
tokens mean in certain situations." but at least people tried, and along
the way a few new people seem to have become more aware of the index, so
overall we didn't lose that much.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 18:38                   ` Junio C Hamano
@ 2011-06-09 19:17                     ` Michael Haggerty
  2011-06-09 20:04                     ` Jeff King
  1 sibling, 0 replies; 98+ messages in thread
From: Michael Haggerty @ 2011-06-09 19:17 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Scott Chacon, Jakub Narebski, Michael Nahas, git

On 06/09/2011 08:38 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>> Wouldn't the four trees described above contain information equivalent
>> to the contents of the index?
> 
> In the same sense that you can re-create the state in the index by running
> the merge again between HEAD and MERGE_HEAD, yes, they probably do, but is
> that a useful question to ask?

The questions is obviously not useful if the only answer is the one that
you give.

But it seems to me that the four pseudo-trees NEXT, OURS, THEIRS, and
BASE are a complete and self-consistent alternative representation of
the information contained in the index.  If this is true, then I claim
that this representation would be much easier to understand and remember
than the index stages (with its highly mnemonic names 0, 1, 2, and 3!)
and the irregular myriad of commands and options currently needed to
access it.

> I think this mega-thread served its purpose. It started to explore "will
> it make it easier to understand and explain if we use these tokens to name
> trees that do not exist in reality?" which is a worthy thing to do.  The
> conclusion appears to be "well we do not even know what exactly these
> tokens mean in certain situations."

Why do you reach that conclusion?  Are you claiming that the proposed
definitions of the four pseudo-trees upthread are incorrect or
insufficiently defined?

We are about to introduce git at my company, and this is one of the
points that makes me cringe when I think of explaining it to developers
(let alone non-developers).  Even here on the git mailing list, where
most people are numbed to the git UI, there has been a lot of confusion
about how to get needed information from the index.  And I truly believe
that the commands currently needed to access the information in the
index are so nonuniform that half of the participants in this discussion
will have to look them up *again* the next time they need them.

Please throw us struggling users a bone :-)

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 18:20                     ` Jay Soffian
@ 2011-06-09 19:40                       ` Junio C Hamano
  0 siblings, 0 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-09 19:40 UTC (permalink / raw)
  To: Jay Soffian
  Cc: Jeff King, Michael Haggerty, Scott Chacon, Jakub Narebski,
	Michael Nahas, git

Jay Soffian <jaysoffian@gmail.com> writes:

>>  # what does the result look if I said "commit -a" now?
>>  $ git diff HEAD
>
> I never use commit -a.

Well I said 'commit -a' only so that any newbie can understand what I
meant, and certainly didn't mean to suggest you to use 'commit -a'.  You
can rephrase it as: "Now I _think_ I have good state in my working tree;
what is the change since HEAD, i.e. the result of the merge?".


>>  # I want to also see comparison with the original
>>  $ git checkout --conflict=diff3 <conflicted paths>...
>>  $ git diff
>
> I have merge.conflictstyle diff3 in my .gitconfig.

Good for you.

> ...
> Now that's one I haven't used before.

Surely there is room for everybody to learn something every day ;-).

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 18:03                 ` Michael Haggerty
  2011-06-09 18:38                   ` Junio C Hamano
@ 2011-06-09 19:41                   ` Jeff King
  1 sibling, 0 replies; 98+ messages in thread
From: Jeff King @ 2011-06-09 19:41 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Junio C Hamano, Scott Chacon, Jakub Narebski, Michael Nahas, git

On Thu, Jun 09, 2011 at 08:03:06PM +0200, Michael Haggerty wrote:

> Thanks for the correction.  So one interesting pseudo-tree would be
> 
> OURS -- The NEXT version of any file that has been resolved; and the
> stage 2 version of any file that has not yet been resolved.  The name
> seems consistent with what is meant by, e.g., "git checkout --ours".

Yeah, that makes sense to me as a definition.

> > So the index is not quite simply a set of four trees. The presence of
> > various stages for each entry tells us the progress of resolution.
> 
> Wouldn't the four trees described above contain information equivalent
> to the contents of the index?

Taken together, yes, I think you could represent the whole index. But
each taken alone is missing some information that might be useful in a
diff.

For example, if I do "git diff THEIRS WTREE" during a merge conflict,
that is a 2-way diff that is going to show things in THEIRS going away,
and both things brought by OURS and things that are part of a resolution
being added. That's less information than "git diff INDEX WTREE" (i.e.,
what is currently spelled as "git diff") provides, because when looking
at the whole index we can do a combined diff showing which part came
from which parent.

> For example, the resolution work that remains to be done that can be
> inquired using old-fashioned "git diff" (3-way diff) could also be
> accessed via
> 
>     git diff NEXT OURS
>     git diff NEXT THEIRS

But you don't get to see it together. You have to do two separate diffs,
which means you will see conflicted regions twice. Try:

  git log --merges -p --cc

on a repo of your choice, and compare with:

  git log --merges -p -m

The former is what "git diff" would show just before marking paths as
resolved, and the latter is what your two diffs above would show.

> or even
> 
>     git diff NEXT WTREE
> 
> if you want to see the remaining conflicts in <<<<<======>>>>>> format.

As I mentioned in an earlier email, this doesn't show which parts are
part of the resolution process (including conflict markers), and which
came from either side of the merge.

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 18:38                   ` Junio C Hamano
  2011-06-09 19:17                     ` Michael Haggerty
@ 2011-06-09 20:04                     ` Jeff King
  2011-06-09 21:37                       ` Michael Haggerty
  2011-06-10 21:48                       ` Junio C Hamano
  1 sibling, 2 replies; 98+ messages in thread
From: Jeff King @ 2011-06-09 20:04 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Michael Haggerty, Scott Chacon, Jakub Narebski, Michael Nahas, git

On Thu, Jun 09, 2011 at 11:38:21AM -0700, Junio C Hamano wrote:

> I think this mega-thread served its purpose. It started to explore "will
> it make it easier to understand and explain if we use these tokens to name
> trees that do not exist in reality?" which is a worthy thing to do.  The
> conclusion appears to be "well we do not even know what exactly these
> tokens mean in certain situations." but at least people tried, and along
> the way a few new people seem to have become more aware of the index, so
> overall we didn't lose that much.

I think there are actually two questions here:

  1. Will it be easier for people to understand "git diff" if we use
     tokens to describe non-treeish sources and destinations?

  2. Are there better tokens to use to break down parts of the index?

I don't have a big problem with (1). Allowing things like:

  git diff INDEX WTREE

allows one to explain what is going on with the diff syntax in a very
clear and verbose manner. I wouldn't want to type that every day, but
that's OK; "git diff" will always mean the same thing as it always has,
but can now be explained to people who have trouble seeing it in terms
of "git diff INDEX WTREE".

There's still a bit of magic in that INDEX is _not_ a tree, but I think
that's a good thing. When there are no merge conflicts, it will behave
identically to the proposed NEXT tree. And when there are conflicts, it
will show you something even more useful.

It does have the potential to confuse in that "INDEX" is not actually a
tree, and so we can't expect to use it as a tree-ish everywhere. So now
diff feels a little inconsistent with other parts of git. One idea,
which I think is probably too crazy, would be to let INDEX be used as a
tree-ish everywhere, but only if all entries are at stage 0. Otherwise,
it will die with an error. That would make it more or less a more
verbose version of ":" (e.g., I can do "git show :Makefile", but it will
die with an error if Makefile exists only at higher stages).


I'm less sure about these new tokens, for a few reasons:

  1. You get less useful answers in some situations by treating each
     stage as a separate tree (e.g., lack of combined diff). So why
     would I want to use them?

  2. Their answers are different than what diffing against the INDEX
     could give. So in theory they could be more useful in different
     situations than a diff against the index. But I haven't seen a good
     example of what such a situation would be.

  3. They're supposed to introduce consistency in explaining diff
     behavior. But we're not going to change what "git diff" does to not
     use the whole index. So "git diff" isn't actually expressible using
     these tokens.

  4. They're supposed to be simpler to understand than index stages. But
     are they? The latest definitions seem to be:

       OURS is a tree of each path in the index, either from stage 2 if
       it exists, or from NEXT otherwise.

       NEXT is a tree of each path in the index, either from stage 0 if
       it exists, or from HEAD otherwise.

     But that doesn't seem any simpler to me than just saying "the index
     has numbered stages, and they correspond to resolved, base, ours,
     and theirs".

I agree that ":2:Makefile" is not exactly an intuitive way to ask for
"ours". Didn't we have a patch at one point a year or two ago to allow
using names instead of numbered stages? If we allowed "INDEX" as a
verbose noise-word in front of ":", then you could say:

  git show INDEX:OURS:Makefile

which is identical to what I wrote above, but is perhaps easier to
explain.

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 20:04                     ` Jeff King
@ 2011-06-09 21:37                       ` Michael Haggerty
  2011-06-09 22:04                         ` Jakub Narebski
                                           ` (2 more replies)
  2011-06-10 21:48                       ` Junio C Hamano
  1 sibling, 3 replies; 98+ messages in thread
From: Michael Haggerty @ 2011-06-09 21:37 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Scott Chacon, Jakub Narebski, Michael Nahas, git

On 06/09/2011 10:04 PM, Jeff King wrote:
> I'm less sure about these new tokens, for a few reasons:
> 
>   1. You get less useful answers in some situations by treating each
>      stage as a separate tree (e.g., lack of combined diff). So why
>      would I want to use them?

Wouldn't it be nice to be able to do a combined diff between *any* two
trees?  Then the nonuniform merge behavior of "git diff" would be a
special case of a general concept:

    git diff3 OURS NEXT THEIRS

>   4. They're supposed to be simpler to understand than index stages. But
>      are they? The latest definitions seem to be:
> 
>        OURS is a tree of each path in the index, either from stage 2 if
>        it exists, or from NEXT otherwise.
> 
>        NEXT is a tree of each path in the index, either from stage 0 if
>        it exists, or from HEAD otherwise.
> 
>      But that doesn't seem any simpler to me than just saying "the index
>      has numbered stages, and they correspond to resolved, base, ours,
>      and theirs".

There is no need to explain the pseudotrees in terms of the index
stages; the pseudotrees are easier to understand and should therefore
become the primary way to describe the index.  Let me give it a try, at
tutorial level.  Assume that the concepts HEAD and WTREE have already
been introduced:

  The "index" is a special area that can hold one or more temporary
  snapshots of your version-controlled content.  Each snapshot is
  called a "tree" because it is analogous to a filesystem tree such
  as the working tree [1].

  Usually the index holds a single tree called "NEXT".  NEXT is a
  snapshot of the state of the working tree that is ready to be
  committed.  This usually consists of the contents from the commit
  that was last checked out (HEAD), plus any changes that have been
  staged for commit using "git stage".

  It is possible to use "git diff" to view the difference between any
  two trees, whether they be trees in the index, trees in commits, or
  the working tree.  For example, to see the difference between the
  last commit and the working tree, use

      git diff HEAD WTREE

  If you would like to see the changes that are ready to be committed,
  type

      git diff HEAD NEXT

  To see the changes in your working tree that have not yet been staged
  for commit, use

      git diff NEXT WTREE

  (The previous command can be abbreviated to "git diff".)

  However, things become more complicated during a merge, when the
  index is used to keep track of the merge's progress.  During a
  merge, the index contains four trees: "NEXT", "OURS", "THEIRS", and
  "BASE".  These four trees are modified as merge conflicts are
  resolved.

  NEXT, as usual, contains the contents that are ready to be committed.
  Specifically, NEXT contains:

    * the original contents of the branch being merged into
    * plus the merged versions of any files that merged cleanly
    * plus any changes that have been staged for commit using
      "git stage"; for example, files whose conflicts have been
      resolved manually.

  OURS contains all of the resolved merges from NEXT, with any
  remaining conflicts resolved by using the version from the branch
  being merged *into*.

  THEIRS contains all of the resolved merges from NEXT, with any
  remaining conflicts resolved by using the content from the branch
  being merged *from*.

  BASE contains all of the resolved merges from NEXT, with any
  remaining conflicts resolved by using the content from the most
  recent ancestor of the two branches being merged.

  As before, "git diff" can be used to view the differences between
  these various trees.  For example, the following command displays the
  conflicts that still have to be resolved:

      git diff NEXT WTREE

  To see how the resolved version differs from the contents of each of
  the original branches, use

      git diff HEAD NEXT
      git diff MERGE_HEAD NEXT

  The "git diff3" command can be used to compare three trees at once:

      git diff3 OURS NEXT THEIRS

  The previous command can be abbreviated to "git diff3".

  [1] The trees that are stored in the index are in an internal format
      that is optimized for efficiency.  They are not stored as
      individual files like in your working copy.

Thoughts?

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 21:37                       ` Michael Haggerty
@ 2011-06-09 22:04                         ` Jakub Narebski
  2011-06-09 23:02                           ` Michael Haggerty
  2011-06-09 22:21                         ` Jeff King
  2011-06-09 22:27                         ` Michael Nahas
  2 siblings, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-09 22:04 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Jeff King, Junio C Hamano, Scott Chacon, Michael Nahas, git

On Thu, 9 Jan 2011, Michael Haggerty wrote:
> On 06/09/2011 10:04 PM, Jeff King wrote:
> > I'm less sure about these new tokens, for a few reasons:
> > 
> >   1. You get less useful answers in some situations by treating each
> >      stage as a separate tree (e.g., lack of combined diff). So why
> >      would I want to use them?
> 
> Wouldn't it be nice to be able to do a combined diff between *any* two
> trees?  Then the nonuniform merge behavior of "git diff" would be a
> special case of a general concept:
> 
>     git diff3 OURS NEXT THEIRS
                ^^^^^^^^^^^^^^^^ -- ???

First, it is unnecessary power, unnecessary complication.  WTF. you are
doing comparing _abitrary_ trees?

Second, for files with merge conflicts "git diff" is the same as
"git diff3 OURS THEIRS WTREE", not "git diff3 OURS NEXT THEIRS".
As you can see it is very easy to construct wrong options to git-diff,
and end up with nonsense!

Third, "git diff" is not "git diff3 OURS THEIRS WTREE" in general,
because for resolved files it is "git diff NEXT WTREE", which is
very useful.  

I could agree with STAGE being possibly multi-stage thingy, so that
"git diff STAGE WTREE" in case of merge conflict is _exactly the same_
as "git diff".

> >   4. They're supposed to be simpler to understand than index stages. But
> >      are they? The latest definitions seem to be:
> > 
> >        OURS is a tree of each path in the index, either from stage 2 if
> >        it exists, or from NEXT otherwise.
> > 
> >        NEXT is a tree of each path in the index, either from stage 0 if
> >        it exists, or from HEAD otherwise.
> > 
> >      But that doesn't seem any simpler to me than just saying "the index
> >      has numbered stages, and they correspond to resolved, base, ours,
> >      and theirs".
> 
> There is no need to explain the pseudotrees in terms of the index
> stages; the pseudotrees are easier to understand and should therefore
> become the primary way to describe the index.  Let me give it a try, at
> tutorial level.  Assume that the concepts HEAD and WTREE have already
> been introduced:
> 
>   The "index" is a special area that can hold one or more temporary
>   snapshots of your version-controlled content.  Each snapshot is
>   called a "tree" because it is analogous to a filesystem tree such
>   as the working tree [1].
> 
>   Usually the index holds a single tree called "NEXT".  NEXT is a
>   snapshot of the state of the working tree that is ready to be
>   committed.  This usually consists of the contents from the commit
>   that was last checked out (HEAD), plus any changes that have been
>   staged for commit using "git stage".
> 
>   It is possible to use "git diff" to view the difference between any
>   two trees, whether they be trees in the index, trees in commits, or
>   the working tree.  For example, to see the difference between the
>   last commit and the working tree, use
> 
>       git diff HEAD WTREE

[cut very long explanation]
 
I won't repear the THIRD time simple and around *three times shorter*
explanation on _when_ to use which form: "git diff" for your own remaining
changes that can be "git add"-ef, "git diff --staged" for which changes
are staged i.e. what you have "git add"-ed, and "git diff HEAD" to compare
current with last.

Those pseudo-trees might be useful if you know what you want to compare,
but are not useful if you know what you want to see (you have to remember
what to compare with which).  Never mind they are longer to write...

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 21:37                       ` Michael Haggerty
  2011-06-09 22:04                         ` Jakub Narebski
@ 2011-06-09 22:21                         ` Jeff King
  2011-06-09 22:27                         ` Michael Nahas
  2 siblings, 0 replies; 98+ messages in thread
From: Jeff King @ 2011-06-09 22:21 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Junio C Hamano, Scott Chacon, Jakub Narebski, Michael Nahas, git

On Thu, Jun 09, 2011 at 11:37:04PM +0200, Michael Haggerty wrote:

> On 06/09/2011 10:04 PM, Jeff King wrote:
> > I'm less sure about these new tokens, for a few reasons:
> > 
> >   1. You get less useful answers in some situations by treating each
> >      stage as a separate tree (e.g., lack of combined diff). So why
> >      would I want to use them?
> 
> Wouldn't it be nice to be able to do a combined diff between *any* two
> trees?  Then the nonuniform merge behavior of "git diff" would be a
> special case of a general concept:
> 
>     git diff3 OURS NEXT THEIRS

You can almost already do that with "git diff". For example:

  merge=456a4c08b8d8ddefda939014c15877ace3e3f499
  git diff $merge $merge^1 $merge^2

which should show the same diff as "git show $merge".

To do that in the index case, I think you would want:

  git diff WTREE HEAD MERGE_HEAD

except that you can't say "WTREE" yet.

You might want:

  git diff NEXT HEAD MERGE_HEAD

but I'm not sure it is going to be useful. For resolved paths, it makes
sense: show the combined diff that would happen if I committed this
right now. But for unmerged paths, NEXT is going to default to HEAD, so
it's going to be the combined diff as if you threw out all of the
changes from both branches. Which is probably not helpful.

I'm not sure about OURS and THEIRS versus HEAD and MERGE_HEAD. They also
default to HEAD, so I guess that:

  git diff NEXT OURS THEIRS

would omit unresolved paths and give you only the "what would happen if
I committed this". Which is not something I have ever heard of somebody
wanting, but is at least something you can't calculate with current git.

I'd be curious to see more concrete examples of situations where these
tokens could help.

> There is no need to explain the pseudotrees in terms of the index
> stages; the pseudotrees are easier to understand and should therefore
> become the primary way to describe the index.  Let me give it a try, at
> tutorial level.  Assume that the concepts HEAD and WTREE have already
> been introduced:
> [...]

Not too bad. It's long, but I don't think any single concept in it is
hard. Of course I already understand the index, so maybe I'm not a good
judge.

I would be most worried about the following spots in terms of confusing
users:

>   The "index" is a special area that can hold one or more temporary
>   snapshots of your version-controlled content.  Each snapshot is
>   called a "tree" because it is analogous to a filesystem tree such
>   as the working tree [1].

This is giving the user a different mental model than what is actually
in the index. I haven't yet convinced myself whether that mental model
is completely isomorphic to what is actually being stored or not. If it
isn't, then what are the cases where the abstraction is going to leak,
and what problems is it going to cause?

IOW, I am worried about the moment where somebody does a diff with one
of these trees, and it _doesn't_ do what they expect, and the
explanation for what did happen involves explaining how the index is
actually stored.

>   NEXT, as usual, contains the contents that are ready to be committed.
>   Specifically, NEXT contains:
> 
>     * the original contents of the branch being merged into
>     * plus the merged versions of any files that merged cleanly
>     * plus any changes that have been staged for commit using
>       "git stage"; for example, files whose conflicts have been
>       resolved manually.
> 
>   OURS contains all of the resolved merges from NEXT, with any
>   remaining conflicts resolved by using the version from the branch
>   being merged *into*.
> 
>   THEIRS contains all of the resolved merges from NEXT, with any
>   remaining conflicts resolved by using the content from the branch
>   being merged *from*.
> 
>   BASE contains all of the resolved merges from NEXT, with any
>   remaining conflicts resolved by using the content from the most
>   recent ancestor of the two branches being merged.

So now we have primitive definitions, which is good. They're clear,
unambiguous, and easy to understand. But what worries me is whether
people will be able to extrapolate that those definitions mean to the
various diffs.

It's nice that you give examples of how to ask for some common things,
but I wonder if we are creating the same situation of "here's the magic
incantation to show you what you want" without actually creating more
understanding in the average user. That is, will "git diff NEXT OURS
THEIRS" be any less magical to most users than "git diff"? Understanding
_why_ they work seems as difficult to me as understanding the index in
the first place.

>   As before, "git diff" can be used to view the differences between
>   these various trees.  For example, the following command displays the
>   conflicts that still have to be resolved:
> 
>       git diff NEXT WTREE

I wouldn't recommend this; the 3-way diff contains more information. I
know why you introduced this one first. It fits the path of your
narrative better. But it seems like it is also being recommended as the
right way to get this information.

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 21:37                       ` Michael Haggerty
  2011-06-09 22:04                         ` Jakub Narebski
  2011-06-09 22:21                         ` Jeff King
@ 2011-06-09 22:27                         ` Michael Nahas
  2011-06-09 22:38                           ` Jeff King
  2 siblings, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-09 22:27 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Jeff King, Junio C Hamano, Scott Chacon, Jakub Narebski, git

I dunno Michael, your idea sounds dangerous.

You're saying that the user interface should be defined with concepts
that have nothing to do with the plumbing.  That's crazy talk!  Next
you'll be arguing that users don't need to know that the Index file
has 4 stages!

;)


Jakub: "it is unnecessary power"
Yeah, like that an argument that anyone here will listen to.  "I can't
let you have diff3.  It's too much power for you.  You might trash the
repository with ... uh... diff3."

Peff: "... use tokens to describe non-treeish sources and destinations"
What defines "tree-ish"ness?
What is non-treeish about NEXT/WTREE/etc.?
Do you know of anything in the INDEX file that would not be visible
from NEXT/WTREE/OURS/THEIRS?

Mike


On Thu, Jun 9, 2011 at 5:37 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> On 06/09/2011 10:04 PM, Jeff King wrote:
>> I'm less sure about these new tokens, for a few reasons:
>>
>>   1. You get less useful answers in some situations by treating each
>>      stage as a separate tree (e.g., lack of combined diff). So why
>>      would I want to use them?
>
> Wouldn't it be nice to be able to do a combined diff between *any* two
> trees?  Then the nonuniform merge behavior of "git diff" would be a
> special case of a general concept:
>
>    git diff3 OURS NEXT THEIRS
>
>>   4. They're supposed to be simpler to understand than index stages. But
>>      are they? The latest definitions seem to be:
>>
>>        OURS is a tree of each path in the index, either from stage 2 if
>>        it exists, or from NEXT otherwise.
>>
>>        NEXT is a tree of each path in the index, either from stage 0 if
>>        it exists, or from HEAD otherwise.
>>
>>      But that doesn't seem any simpler to me than just saying "the index
>>      has numbered stages, and they correspond to resolved, base, ours,
>>      and theirs".
>
> There is no need to explain the pseudotrees in terms of the index
> stages; the pseudotrees are easier to understand and should therefore
> become the primary way to describe the index.  Let me give it a try, at
> tutorial level.  Assume that the concepts HEAD and WTREE have already
> been introduced:
>
>  The "index" is a special area that can hold one or more temporary
>  snapshots of your version-controlled content.  Each snapshot is
>  called a "tree" because it is analogous to a filesystem tree such
>  as the working tree [1].
>
>  Usually the index holds a single tree called "NEXT".  NEXT is a
>  snapshot of the state of the working tree that is ready to be
>  committed.  This usually consists of the contents from the commit
>  that was last checked out (HEAD), plus any changes that have been
>  staged for commit using "git stage".
>
>  It is possible to use "git diff" to view the difference between any
>  two trees, whether they be trees in the index, trees in commits, or
>  the working tree.  For example, to see the difference between the
>  last commit and the working tree, use
>
>      git diff HEAD WTREE
>
>  If you would like to see the changes that are ready to be committed,
>  type
>
>      git diff HEAD NEXT
>
>  To see the changes in your working tree that have not yet been staged
>  for commit, use
>
>      git diff NEXT WTREE
>
>  (The previous command can be abbreviated to "git diff".)
>
>  However, things become more complicated during a merge, when the
>  index is used to keep track of the merge's progress.  During a
>  merge, the index contains four trees: "NEXT", "OURS", "THEIRS", and
>  "BASE".  These four trees are modified as merge conflicts are
>  resolved.
>
>  NEXT, as usual, contains the contents that are ready to be committed.
>  Specifically, NEXT contains:
>
>    * the original contents of the branch being merged into
>    * plus the merged versions of any files that merged cleanly
>    * plus any changes that have been staged for commit using
>      "git stage"; for example, files whose conflicts have been
>      resolved manually.
>
>  OURS contains all of the resolved merges from NEXT, with any
>  remaining conflicts resolved by using the version from the branch
>  being merged *into*.
>
>  THEIRS contains all of the resolved merges from NEXT, with any
>  remaining conflicts resolved by using the content from the branch
>  being merged *from*.
>
>  BASE contains all of the resolved merges from NEXT, with any
>  remaining conflicts resolved by using the content from the most
>  recent ancestor of the two branches being merged.
>
>  As before, "git diff" can be used to view the differences between
>  these various trees.  For example, the following command displays the
>  conflicts that still have to be resolved:
>
>      git diff NEXT WTREE
>
>  To see how the resolved version differs from the contents of each of
>  the original branches, use
>
>      git diff HEAD NEXT
>      git diff MERGE_HEAD NEXT
>
>  The "git diff3" command can be used to compare three trees at once:
>
>      git diff3 OURS NEXT THEIRS
>
>  The previous command can be abbreviated to "git diff3".
>
>  [1] The trees that are stored in the index are in an internal format
>      that is optimized for efficiency.  They are not stored as
>      individual files like in your working copy.
>
> Thoughts?
>
> Michael
>
> --
> Michael Haggerty
> mhagger@alum.mit.edu
> http://softwareswirl.blogspot.com/
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 22:27                         ` Michael Nahas
@ 2011-06-09 22:38                           ` Jeff King
  2011-06-09 22:55                             ` Jakub Narebski
  2011-06-10  0:00                             ` Michael Nahas
  0 siblings, 2 replies; 98+ messages in thread
From: Jeff King @ 2011-06-09 22:38 UTC (permalink / raw)
  To: mike; +Cc: Michael Haggerty, Junio C Hamano, Scott Chacon, Jakub Narebski, git

On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:

> I dunno Michael, your idea sounds dangerous.
> 
> You're saying that the user interface should be defined with concepts
> that have nothing to do with the plumbing.  That's crazy talk!  Next
> you'll be arguing that users don't need to know that the Index file
> has 4 stages!
> 
> ;)

I know you are being sarcastic, but it _is_ a dangerous thing. One of
the great things about git is that it exposes the details of its data
structures. So you rarely run into corner cases where the UI has given
you an inaccurate mental model, and you have to reconcile what is
actually happening with your mental model. The tradeoff, of course, is
that you get exposed to the full complexity of what is happening.

And note that I'm not saying it's impossible, or it's something we
definitely shouldn't do. Only that we should be aware of what
inaccuracies we might be feeding to the user, and asking questions about
how that might bite is. Like: how likely is the user to run into a
corner case where git does something unexpected? If it does happen, how
much worse will explaining the behavior be than simply having exposed
them to lower-level constructs in the first place?

Also note that I'm not even sure that this token proposal is in fact
introducing inaccuracies, and is not simply an alternate but equivalent
mental model. But these are the types of things I think people should be
thinking about in a proposal like this.

> Jakub: "it is unnecessary power"
> Yeah, like that an argument that anyone here will listen to.  "I can't
> let you have diff3.  It's too much power for you.  You might trash the
> repository with ... uh... diff3."

It's also wrong. Diff already does combined diff on arbitrary trees. So
unnecessary, perhaps, but already there.

> Peff: "... use tokens to describe non-treeish sources and destinations"
> What defines "tree-ish"ness?

I was using tree-ish there in the sense that it is used in the git
documentation, which is: a reference that can resolve to a git
tree object. So a tree sha1, a commit sha1 (which would resolve to its
tree), a tag that points to a tree or commit, a ref that points to any
of the above, and so on.

I think it is actually dying out from git documentation, though.  I was
writing to Junio there, who I know understands that term, but I should
have been more mindful that other readers of the thread wouldn't.

> What is non-treeish about NEXT/WTREE/etc.?

They don't resolve to git tree objects. :)

> Do you know of anything in the INDEX file that would not be visible
> from NEXT/WTREE/OURS/THEIRS?

The stat information, but that is usually ignored in porcelain, anyway
(we refresh the state information at the beginning of most porcelain
commands, so you can just assume everything is up to date with the
working tree and will be shown as such).

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 22:38                           ` Jeff King
@ 2011-06-09 22:55                             ` Jakub Narebski
  2011-06-10  0:00                             ` Michael Nahas
  1 sibling, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-09 22:55 UTC (permalink / raw)
  To: Jeff King; +Cc: mike, Michael Haggerty, Junio C Hamano, Scott Chacon, git

On Fri, 10 Jun 2011, Jeff King wrote:
> On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:

> > Jakub: "it is unnecessary power"
> > Yeah, like that an argument that anyone here will listen to.  "I can't
> > let you have diff3.  It's too much power for you.  You might trash the
> > repository with ... uh... diff3."
> 
> It's also wrong. Diff already does combined diff on arbitrary trees. So
> unnecessary, perhaps, but already there.

BTW. I should have written "too much flexibility", not "too much power".
What I had in mind is _convention_-based branching model in Subversion,
and its svn:mergeinfo property... which allow things like recording
cherry-picking, partial merges (of subtree), comitting on a tag or
commits over more than one branch... but which things are usually user's
error, not prevented by a tool.
 
> > Peff: "... use tokens to describe non-treeish sources and destinations"
> > What defines "tree-ish"ness?
> 
> I was using tree-ish there in the sense that it is used in the git
> documentation, which is: a reference that can resolve to a git
> tree object. So a tree sha1, a commit sha1 (which would resolve to its
> tree), a tag that points to a tree or commit, a ref that points to any
> of the above, and so on.
> 
> I think it is actually dying out from git documentation, though.  I was
> writing to Junio there, who I know understands that term, but I should
> have been more mindful that other readers of the thread wouldn't.

Historical note: "tree-ish" (now just "tree") were once called "ents" :-)
c.f. 3f0073a (Axe the last ent, 2006-08-21)

    Axe the last ent
    
    In the name of Standardization, this cleanses the last usage string of
    mystical creatures.  But they still dwell deep within the source and in
    some debug messages, it is said.

> > Do you know of anything in the INDEX file that would not be visible
> > from NEXT/WTREE/OURS/THEIRS?
> 
> The stat information, but that is usually ignored in porcelain, anyway
> (we refresh the state information at the beginning of most porcelain
> commands, so you can just assume everything is up to date with the
> working tree and will be shown as such).

Hmmm... there is additional complication that I haven't thought about,
namely assume-unchanged bit, and partial checkouts.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 22:04                         ` Jakub Narebski
@ 2011-06-09 23:02                           ` Michael Haggerty
  2011-06-10 10:19                             ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Michael Haggerty @ 2011-06-09 23:02 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jeff King, Junio C Hamano, Scott Chacon, Michael Nahas, git

On 06/10/2011 12:04 AM, Jakub Narebski wrote:
> On Thu, 9 Jan 2011, Michael Haggerty wrote:
>> On 06/09/2011 10:04 PM, Jeff King wrote:
>>> I'm less sure about these new tokens, for a few reasons:
>>>
>>>   1. You get less useful answers in some situations by treating each
>>>      stage as a separate tree (e.g., lack of combined diff). So why
>>>      would I want to use them?
>>
>> Wouldn't it be nice to be able to do a combined diff between *any* two
>> trees?  Then the nonuniform merge behavior of "git diff" would be a
>> special case of a general concept:
>>
>>     git diff3 OURS NEXT THEIRS
>                 ^^^^^^^^^^^^^^^^ -- ???
> 
> First, it is unnecessary power, unnecessary complication.  WTF. you are
> doing comparing _abitrary_ trees?
> 
> Second, for files with merge conflicts "git diff" is the same as
> "git diff3 OURS THEIRS WTREE", not "git diff3 OURS NEXT THEIRS".
> As you can see it is very easy to construct wrong options to git-diff,
> and end up with nonsense!

Since there is currently no "git diff3" command, I decided to orient the
hypothetical "git diff3" command based on diff3(1), which uses

    diff3 [OPTION]... MYFILE OLDFILE YOURFILE

By using a new command (diff3) that is somewhat familiar to some users,
we could reduce the amount of overloading of "git diff".  I, for one,
was surprised and confused the first few times I typed "git diff" during
a merge and got a three-way diff rather than what I expected, namely the
two-way diff that is called "git diff NEXT WTREE" in the proposed notation.

> I won't repear the THIRD time simple and around *three times shorter*
> explanation on _when_ to use which form: "git diff" for your own remaining
> changes that can be "git add"-ef, "git diff --staged" for which changes
> are staged i.e. what you have "git add"-ed, and "git diff HEAD" to compare
> current with last.

You don't need to repeat for my benefit the existing version of the
commands; I knew them long before this discussion started.  And
repeating them does not make them more obvious.

For a beginner, the main goal is not brevity.  It is discoverability and
memorability.  Obviously our priorities and tastes differ and we will
not come to agreement.  I would be very interested what people with a
fresh memory of struggling to learn the git CLI think would have been
easier to learn.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 22:38                           ` Jeff King
  2011-06-09 22:55                             ` Jakub Narebski
@ 2011-06-10  0:00                             ` Michael Nahas
  2011-06-10  0:08                               ` Jeff King
  1 sibling, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-10  0:00 UTC (permalink / raw)
  To: Jeff King
  Cc: Michael Haggerty, Junio C Hamano, Scott Chacon, Jakub Narebski, git

On Thu, Jun 9, 2011 at 6:38 PM, Jeff King <peff@peff.net> wrote:
> On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:
>
>> I dunno Michael, your idea sounds dangerous.
>>
>> You're saying that the user interface should be defined with concepts
>> that have nothing to do with the plumbing.  That's crazy talk!  Next
>> you'll be arguing that users don't need to know that the Index file
>> has 4 stages!
>>
>> ;)
>
> I know you are being sarcastic, but it _is_ a dangerous thing. One of
> the great things about git is that it exposes the details of its data
> structures. So you rarely run into corner cases where the UI has given
> you an inaccurate mental model, and you have to reconcile what is
> actually happening with your mental model. The tradeoff, of course, is
> that you get exposed to the full complexity of what is happening.
>
> And note that I'm not saying it's impossible, or it's something we
> definitely shouldn't do. Only that we should be aware of what
> inaccuracies we might be feeding to the user, and asking questions about
> how that might bite is. Like: how likely is the user to run into a
> corner case where git does something unexpected? If it does happen, how
> much worse will explaining the behavior be than simply having exposed
> them to lower-level constructs in the first place?
>
> Also note that I'm not even sure that this token proposal is in fact
> introducing inaccuracies, and is not simply an alternate but equivalent
> mental model. But these are the types of things I think people should be
> thinking about in a proposal like this.

The beauty of building a level of abstraction is that you don't need
to know about the lower level.  Git's plumbing is built on files, and
directories, and communication libraries, but, in general, we don't
talk about manipulating the plumbing in those terms.  We talk in the
concepts of the higher level: commits, trees, branches, pushes, and
pulls.

I don't know what are the right concepts are for the porcelain.  I
have a feeling that a lot of the concepts will map 1-to-1 will
concepts in the plumbing, which is what makes the two hard to
separate.  At the moment, the NEXT and HEAD concepts "feel" right.
But I also think they're just part of the solution.

A partial step towards the right idea is not always a good thing.  It
could leave users confused or give them the power to create a mess but
not fix it.  We should be careful, but not fearful.


>> Peff: "... use tokens to describe non-treeish sources and destinations"
>> What is non-treeish about NEXT/WTREE/etc.?
>
> They don't resolve to git tree objects. :)

Touchee'.
Actually, nice succinct definition.

Tree objects have SHAs and are long lasting.  Good differences to keep in mind.

>> Do you know of anything in the INDEX file that would not be visible
>> from NEXT/WTREE/OURS/THEIRS?
>
> The stat information, but that is usually ignored in porcelain, anyway
> (we refresh the state information at the beginning of most porcelain
> commands, so you can just assume everything is up to date with the
> working tree and will be shown as such).

I took a quick look at some documentation.  The index has almost all
the stats about a file that are directly available from a file in the
working tree.  It also looks like the index has far more stats than
can be stored in a tree object entry.  Is that right?

Mike

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10  0:00                             ` Michael Nahas
@ 2011-06-10  0:08                               ` Jeff King
  0 siblings, 0 replies; 98+ messages in thread
From: Jeff King @ 2011-06-10  0:08 UTC (permalink / raw)
  To: mike; +Cc: Michael Haggerty, Junio C Hamano, Scott Chacon, Jakub Narebski, git

On Thu, Jun 09, 2011 at 08:00:12PM -0400, Michael Nahas wrote:

> A partial step towards the right idea is not always a good thing.  It
> could leave users confused or give them the power to create a mess but
> not fix it.  We should be careful, but not fearful.

Yeah, that was what I was trying get at. We do need to be careful not to
make things worse.

> I took a quick look at some documentation.  The index has almost all
> the stats about a file that are directly available from a file in the
> working tree.  It also looks like the index has far more stats than
> can be stored in a tree object entry.  Is that right?

Yeah. The index does double duty by holding both the sha1 of what is at
each stage, but also the stat cache for files in the worktree. That's
what lets us avoid even opening unchanged files during a diff (we lstat
them and check the size, modification time, etc).

In general, that particular duty probably doesn't have a place in the UI
for porcelain. Most commands will transparently go through the cache,
find any stat-dirty entries, and actually open and check what's in the
file.

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 23:02                           ` Michael Haggerty
@ 2011-06-10 10:19                             ` Jakub Narebski
  2011-06-10 11:06                               ` Michael Nahas
  0 siblings, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-10 10:19 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Jeff King, Junio C Hamano, Scott Chacon, Michael Nahas, git

On Fri, 10 Jun 2011, Michael Haggerty wrote:
> On 06/10/2011 12:04 AM, Jakub Narebski wrote:
>> On Thu, 9 Jan 2011, Michael Haggerty wrote:
>>> On 06/09/2011 10:04 PM, Jeff King wrote:
>>>> I'm less sure about these new tokens, for a few reasons:
>>>>
>>>>   1. You get less useful answers in some situations by treating each
>>>>      stage as a separate tree (e.g., lack of combined diff). So why
>>>>      would I want to use them?
>>>
>>> Wouldn't it be nice to be able to do a combined diff between *any* two
>>> trees?  Then the nonuniform merge behavior of "git diff" would be a
>>> special case of a general concept:
>>>
>>>     git diff3 OURS NEXT THEIRS
>>                ^^^^^^^^^^^^^^^^ -- ???
[...]

>> Second, for files with merge conflicts "git diff" is the same as
>> "git diff3 OURS THEIRS WTREE", not "git diff3 OURS NEXT THEIRS".
>> As you can see it is very easy to construct wrong options to git-diff,
>> and end up with nonsense!
> 
> Since there is currently no "git diff3" command, I decided to orient the
> hypothetical "git diff3" command based on diff3(1), which uses
> 
>     diff3 [OPTION]... MYFILE OLDFILE YOURFILE
> 
> By using a new command (diff3) that is somewhat familiar to some users,
> we could reduce the amount of overloading of "git diff".

But here, by using "git diff3" which does not work at all like diff3, and
which output is very different from "git diff --cc" combined diff format,
you increase confusion, not decrease it.  By using somewhat familiar name
that behaves differently from said familiar tool, you make user's life
unnecessary harder.

Let me explain how "git diff --cc" is diferent from "diff3".

First, "git diff --cc" works differently than "diff3";

 * "git diff --cc" can do combined diff of arbitrary number of 3 things
   or more; "diff3" is limited to 3.

 * "git diff --cc" is about comparing merge results with its sources
   (parents) and the like; "diff3" is about comparing two divergent
   versions with their ancestor (merge base) -- opposite direction of
   following parent links.

 * therefore natural ordering for "git diff --cc" is 'PARENT^1 PARENT^2
   MERGE' (like 'FROM TO'), while "diff3" uses arbitrary ordering of
   'MYFILE OLDFILE YOURFILE'... which I always have to check in docs.

Second, "diff3" output is different from "git diff --cc" output... and
as you see above rightly so.

Third, it was still a mistake to write

  git diff3 OURS NEXT THEIRS

In result of combined diff that "git diff" shows in case of merge conflict
differences between OURS, THEIRS, and WTREE version; NEXT isn't there,
and you didn't mention WTREE though it is here.  But see also the next point.

Fourth, with "git diff3 OURS NEXT THEIRS" / "git diff3 OURS THEIRS WTREE"
you either introduce interface inefficiency, or UI inconsistency, or UI
complication.

In the case of conflict "git diff" shows 3-way combined diff for files
with conflict (OURS, THEIRS, WTREE), but it shows ordinary diff from
stage '0' (NEXT, WTREE) for files which resolved cleanly; the fact that
file resolved cleanly doesn't necessarily mean that it resolved correctly...

So you either make "git diff3 OURS NEXT THEIRS" show only 3-way combined
diff part, consistent with 'diff3' name, but making for an *inefficient*
user interface -- now you have to use two commands for single piece of
information.

Or you make "git diff3 OURS NEXT THEIRS" behave like current "git diff",
i.e. show the whole diff from index, be it conflict or a fixup, which is
efficient but *inconsistent*.

Or you make "git diff3 OURS NEXT THEIRS" compare stage 0 (NEXT?) with
worktree if there is no conflict, and stages 'ours' and 'theirs' with
worktree if there is conflict... which is *weird*, especially that you
defined OURS as "'ours' or stage 0" (union of stage 'ours' and stage 0),
covering all resolved and unresolved files.

> I, for one, 
> was surprised and confused the first few times I typed "git diff" during
> a merge and got a three-way diff rather than what I expected, namely the
> two-way diff that is called "git diff NEXT WTREE" in the proposed notation.

This three way diff is more useful...
 
>> I won't repear the THIRD time simple and around *three times shorter*
>> explanation on _when_ to use which form: "git diff" for your own remaining
>> changes that can be "git add"-ef, "git diff --staged" for which changes
>> are staged i.e. what you have "git add"-ed, and "git diff HEAD" to compare
>> current with last.
> 
> You don't need to repeat for my benefit the existing version of the
> commands; I knew them long before this discussion started.  And
> repeating them does not make them more obvious.
> 
> For a beginner, the main goal is not brevity.  It is discoverability and
> memorability.  Obviously our priorities and tastes differ and we will
> not come to agreement.  I would be very interested what people with a
> fresh memory of struggling to learn the git CLI think would have been
> easier to learn.

You say that user would think something like that:

  "I need to compare staged contents and working area.  To do that I use
   'git diff NEXT WTREE' / have to look up documentation to find that it
   is 'git diff'".

I say that I guess user would think something like that:

  "I want to check if and what remaining changes are.  To do that I use
   'git diff' / have to look up documentation which stages I have to
   compare to find that it is 'git diff NEXT WTREE'".

'git diff' / 'git diff --cached' / 'git diff HEAD' is about use cases
(or "user stories").  'git diff NEXT WTREE' / 'git diff HEAD NEXT' /
/ 'git diff HEAD WTREE' are about mechanism.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 10:19                             ` Jakub Narebski
@ 2011-06-10 11:06                               ` Michael Nahas
  2011-06-10 12:20                                 ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-10 11:06 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Michael Haggerty, Jeff King, Junio C Hamano, Scott Chacon, git

> 'git diff' / 'git diff --cached' / 'git diff HEAD' is about use cases
> (or "user stories").  'git diff NEXT WTREE' / 'git diff HEAD NEXT' /
> / 'git diff HEAD WTREE' are about mechanism.

Would you say that the UNIX commands "find", "grep", and "xargs" are
about use cases?  I rarely use them by themselves.  They clearly
manipulate concepts: files and lines.  So, it's easy for me to think
what this does:

find . | grep "\.h" | xargs grep MyClass | grep public

I'm trying to find concepts the concepts that git manipulates and I
think NEXT and WTREE are part of those concepts.

It is my opinion that if we focus on concepts, we'll be able to create
general commands and that the user will be able to combine the
commands in new and interesting ways, like I combined the UNIX
commands above.

I believe in "common" use cases.  The common case should be fast.  I
have always recommended still allowing "git diff" by itself.


BUT if we focus only on use cases, we'll create tools that are
specific to ONE thing and are NOT general.  They will be harder for
users to conceptualize and harder to combine in new and interesting
ways.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 11:06                               ` Michael Nahas
@ 2011-06-10 12:20                                 ` Jakub Narebski
  0 siblings, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-10 12:20 UTC (permalink / raw)
  To: mike; +Cc: Michael Haggerty, Jeff King, Junio C Hamano, Scott Chacon, git

On Fri, 10 Jul 2011, Michael Nahas wrote:
> Jakub Narebski wrote:

> > 'git diff' / 'git diff --cached' / 'git diff HEAD' is about use cases
> > (or "user stories").  'git diff NEXT WTREE' / 'git diff HEAD NEXT' /
> > / 'git diff HEAD WTREE' are about mechanism.
> 
> Would you say that the UNIX commands "find", "grep", and "xargs" are
> about use cases?  I rarely use them by themselves.  They clearly
> manipulate concepts: files and lines.  So, it's easy for me to think
> what this does:
> 
> find . | grep "\.h" | xargs grep MyClass | grep public

You do know that this is way suboptimal, even if you don't have 'ack'
installed, and don't use "git grep --no-index"?

> 
> I'm trying to find concepts the concepts that git manipulates and I
> think NEXT and WTREE are part of those concepts.
> 
> It is my opinion that if we focus on concepts, we'll be able to create
> general commands and that the user will be able to combine the
> commands in new and interesting ways, like I combined the UNIX
> commands above.
> 
> I believe in "common" use cases.  The common case should be fast.  I
> have always recommended still allowing "git diff" by itself.
> 
> 
> BUT if we focus only on use cases, we'll create tools that are
> specific to ONE thing and are NOT general.  They will be harder for
> users to conceptualize and harder to combine in new and interesting
> ways.

But if it is the angle you want to play, then don't advertise it as
a feature meant for _new users_!  But if you go that route (e.g. as a way
to compare BASE with THEIRS, for whatever reason), then you probably
would need to invent some notation that is obvious that these are not
refs, like HEAD, ORIG_HEAD, MERGE_HEAD and FETCH_HEAD are.  Something
that is easy to remember, won't go in the way of either git or shell;
see e.g.

  http://thread.gmane.org/gmane.comp.version-control.git/175262/focus=175407

in "[RFC/PATCH] git put: an alternative to add/reset/checkout" thread.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts (ad-hominem attacks)
  2011-06-09  1:56                                 ` Michael Nahas
@ 2011-06-10 15:29                                   ` Jakub Narebski
  0 siblings, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-10 15:29 UTC (permalink / raw)
  To: mike; +Cc: Jeff King, Michael J Gruber, Junio C Hamano, Scott Chacon, git

On Thu, 9 Jun 2011, Michael Nahas wrote:

> Hi Peff,
> 
> First, thanks for correcting my diff-without-NEXT-and-WTREE to
> diff-with-NEXT-and-WTREE pairing.
> 
> Second, I agree that the index is more than just NEXT.  There were
> good reasons behind calling it "NEXT" and not "INDEX".

NEXT has to be _well defined_ (is it tree-ish or a multi-tree in some 
cases), and definition examined if it is _useful_ (e.g. if you can get
results of "git diff" with "git diff NEXT <sth>..." both for conflicted 
and resolved cleanly entries).
 
This thread served to specify original handwavy definition of NEXT...

> Third, I didn't know for sure that "git diff" during a merge conflict
> would produce a three-way-diff result, but I suspected it would.  (You
> really didn't have to produce all that code - I would have accepted
> your word as an expert.  But thanks!)  So, yes, the two-way merge
> result of "git diff NEXT WTREE" would be different.
> 
> I could argue that git should allow a 4-way diff where "git diff NEXT
> WTREE OURS THEIR" prints all the unresolved changes as coming from
> OURS or THEIR or neither.  But I think that's silly.

It would be "git diff NEXT OURS THEIRS WTREE" or "git diff BASE OURS 
THEIRS WTREE" -- the putative merge results should be last; the 
convention of combined diff format is like for ordinary diff: first 
source(s), then destination.

> 
> I will say that "git diff NEXT WTREE" will tell you what's left
> unresolved and most of it is in <<<<====>>>>> blocks that tell you
> whether it came from OURS or THEIRS.  If the user has any discipline,
> they won't introduce unnecessary changes that were not necessary for
> the merge.  If they don't have discipline, we really can't help them.

What if he/she removed conflict markers, test compiled... and realized
that it was mismerge, then fixed?  Then to examine current fixed 
contents he/she doesn't have help of <<<< ==== >>>> blocks...

> 
> I'm not saying there is no use for a 3-way merge.  In fact, I'd guess
> it's a requirement so that Alice can check Bob's merge before Bob
> commits.  But I'm fine with making it "git diff --3-way" or the silly
> "git diff NEXT WTREE OURS THEIRS" because I think its "git diff NEXT
> WTREE" will be good enough 99% of the time.

"git diff --cc".  But I think with having to say explicitly 
"git diff --3way" / "git diff --cc" Alice wouldn't know that it has such 
useful tool...


P.S. Could you not quote text in bulk, if you are not answering to it 
block by block?  It is unnecessary download, and burden of scrolling 
down to check if there is anything added at bottom.
-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 11:55                                   ` Holger Hellmuth
@ 2011-06-10 16:44                                     ` Jakub Narebski
  2011-06-10 18:07                                       ` Holger Hellmuth
  0 siblings, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-10 16:44 UTC (permalink / raw)
  To: Holger Hellmuth
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

On Thu, 9 Jun 2011, Holger Hellmuth wrote:
> On 08.06.2011 20:56, Jakub Narebski wrote:

[...]
> >> But I can't make it explicit which two targets I want to compare with
> >> 'git diff'.
> >
> > For me it looks XY problem; instead of wanting to compare two explicit
> > targets, you should specify what you want to see ;-).
> 
> Then don't call the command 'diff' (... I proclaim in the knowledge that 
> that isn't possible). 'diff' is the short form of 'difference' which 
> means literally a comparison between *two* things.

Blame CVS (I think) on that.  It introduced no arguments "cvs diff" to
get current changes, and other version control systems picked this
convention up, including Git.
 
"diff" is 'are there any differences', or 'are there any changes'.
Implicit rules (targets) are very useful.

> If someone wants to 
> see something he would pick the words 'show' or 'list'. So user 
> expectation is different from what you want diff to be.

There is always "git status"...

> Also there are no good words for what someone wants to see in this case. 
> At least I would assume the git project would have found them if they 
> existed. '--cached' is definitely not one of them. But we have fitting 
> and widely known names for the targets, i.e 'working tree', 'index' and 
> 'head'.

"I want to see if there are any remiaining changes", "I want to see what
'git commit' would bring", "I want to see what 'git commit -a' would bring".
Neither of those is about targets for diff.

[...]
> > The "git diff NEXT WTREE" looks like training wheels to me.  And like
> > training wheels they could become obstacles and not help to learning
> > git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))
> 
> If your goal is that anyone who uses git is a git expert, they may be a 
> hindrance (as are all the porcelain commands really). If you also want 
> to make git friendly to people who will never get past intermediate or 
> beginner stage or will only use a small part of git or use git seldomly, 
> training wheels are good.

Those "training wheels" are useless for beginner, and might be not very
useful to middle expert user either, depending on corner cases.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 16:44                                     ` Jakub Narebski
@ 2011-06-10 18:07                                       ` Holger Hellmuth
  2011-06-10 18:35                                         ` Jakub Narebski
  0 siblings, 1 reply; 98+ messages in thread
From: Holger Hellmuth @ 2011-06-10 18:07 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

On 10.06.2011 18:44, Jakub Narebski wrote:
> On Thu, 9 Jun 2011, Holger Hellmuth wrote:
>> Also there are no good words for what someone wants to see in this case.
>> At least I would assume the git project would have found them if they
>> existed. '--cached' is definitely not one of them. But we have fitting
>> and widely known names for the targets, i.e 'working tree', 'index' and
>> 'head'.
>
> "I want to see if there are any remiaining changes", "I want to see what
> 'git commit' would bring", "I want to see what 'git commit -a' would bring".
> Neither of those is about targets for diff.

Are you proposing a command "git 
--I-want-to-see-if-there-are-any-remaining-changes" ? ;-). I was looking 
for short command or parameter names that are easy to remember, not for 
definitions of the output of cryptic commands.

But lets see. If I didn't know much git, where would I look for the 
right command for your three needs? Where would I expect the solution? 
(note I'm not proposing any of these commands)

"I want to see if there are any remiaining changes"?
git status
git status --full
git status --detailed

"I want to see what 'git commit' would bring"
git commit --dry-run

"I want to see what 'git commit -a' would bring"
git commit -a --dry-run

Now I'll add a question I would want to ask:
"I want to see the changes between what I have in my working tree and 
what I already added to the index"
git diff WTREE INDEX


Btw. even the 'git diff' man page emphasizes that diff is about a 
comparision between two things. Citation: "Show changes *between* two 
trees, a tree and the working tree, a tree and the index file,...".


> [...]
>>> The "git diff NEXT WTREE" looks like training wheels to me.  And like
>>> training wheels they could become obstacles and not help to learning
>>> git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))
>>
>> If your goal is that anyone who uses git is a git expert, they may be a
>> hindrance (as are all the porcelain commands really). If you also want
>> to make git friendly to people who will never get past intermediate or
>> beginner stage or will only use a small part of git or use git seldomly,
>> training wheels are good.
>
> Those "training wheels" are useless for beginner, and might be not very
> useful to middle expert user either, depending on corner cases.

"useless for beginner". No reasoning, just a fat road block for my opinion?
As git expert you are so far removed from any beginner status. Are you 
sure you still know how a beginner thinks?

Holger.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 18:07                                       ` Holger Hellmuth
@ 2011-06-10 18:35                                         ` Jakub Narebski
  2011-06-10 22:45                                           ` Holger Hellmuth
  0 siblings, 1 reply; 98+ messages in thread
From: Jakub Narebski @ 2011-06-10 18:35 UTC (permalink / raw)
  To: Holger Hellmuth
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

Dnia piątek 10. czerwca 2011 20:07, Holger Hellmuth napisał:
> On 10.06.2011 18:44, Jakub Narebski wrote:
> > On Thu, 9 Jun 2011, Holger Hellmuth wrote:
> >> Also there are no good words for what someone wants to see in this case.
> >> At least I would assume the git project would have found them if they
> >> existed. '--cached' is definitely not one of them. But we have fitting
> >> and widely known names for the targets, i.e 'working tree', 'index' and
> >> 'head'.
> >
> > "I want to see if there are any remiaining changes", "I want to see what
> > 'git commit' would bring", "I want to see what 'git commit -a' would bring".
> > Neither of those is about targets for diff.
> 
> Are you proposing a command "git 
> --I-want-to-see-if-there-are-any-remaining-changes" ? ;-). I was looking 
> for short command or parameter names that are easy to remember, not for 
> definitions of the output of cryptic commands.
> 
> But lets see. If I didn't know much git, where would I look for the 
> right command for your three needs? Where would I expect the solution? 
> (note I'm not proposing any of these commands)
> 
> "I want to see if there are any remaining changes"?
> git status
> git status --full
> git status --detailed

"Any differences"?

git diff


"I want to see what I staged"

git diff --staged


Isn't it simpler than "I want to see the changes between what I already
staged, which is put in place called index, but must refer to it by NEXT,
and the changes I didn't staged, in my working area, which I refer to by
WORK... no, it is TREE... oh, wait, it is WTREE" :-)  I am exaggerating
much here, but I think you can see what I want to point out.

> Now I'll add a question I would want to ask:
> "I want to see the changes between what I have in my working tree and 
> what I already added to the index"

That's not a beginner question.

> git diff WTREE INDEX
           ^^^^^^^^^^^ --- reverse to "git diff"

In this direction it is surely suprising... you see, how again and again
having to explicitely state what to compare with which leads to mistakes
such like this one, and the one in few mails earlier.
 
> 
> Btw. even the 'git diff' man page emphasizes that diff is about a 
> comparision between two things. Citation: "Show changes *between* two 
> trees, a tree and the working tree, a tree and the index file,...".
 
That's more about explaining result of command.  Besides manpages are
reference documentation; new users should start with user's manual, or
tutorial (or "Pro Git"), not manpages.
 
> > [...]
> >>> The "git diff NEXT WTREE" looks like training wheels to me.  And like
> >>> training wheels they could become obstacles and not help to learning
> >>> git.  Neverthemind they can snag on sharp corners^W corner-cases. ;-)))
> >>
> >> If your goal is that anyone who uses git is a git expert, they may be a
> >> hindrance (as are all the porcelain commands really). If you also want
> >> to make git friendly to people who will never get past intermediate or
> >> beginner stage or will only use a small part of git or use git seldomly,
> >> training wheels are good.
> >
> > Those "training wheels" are useless for beginner, and might be not very
> > useful to middle expert user either, depending on corner cases.
> 
> "useless for beginner". No reasoning, just a fat road block for my opinion?
> As git expert you are so far removed from any beginner status. Are you 
> sure you still know how a beginner thinks?

Well, that depends by what you mean by beginner.  Beginner to git, but
not beginner to version control knows about "<scm> diff" form to check
for one's changes, for example.

But I don't think that beginner knows that there is such thing like the
index, and know that he/she has to compare the index to the working area.
When he/she starts to use the index, probably he/she isn't a beginner
anymore.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-09 20:04                     ` Jeff King
  2011-06-09 21:37                       ` Michael Haggerty
@ 2011-06-10 21:48                       ` Junio C Hamano
  2011-06-10 22:08                         ` Junio C Hamano
                                           ` (4 more replies)
  1 sibling, 5 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-10 21:48 UTC (permalink / raw)
  To: Jeff King
  Cc: Michael Haggerty, Scott Chacon, Jakub Narebski, Michael Nahas, git

Jeff King <peff@peff.net> writes:

> I think there are actually two questions here:
>
>   1. Will it be easier for people to understand "git diff" if we use
>      tokens to describe non-treeish sources and destinations?
>
>   2. Are there better tokens to use to break down parts of the index?
>
> I don't have a big problem with (1). Allowing things like:
>
>   git diff INDEX WTREE
>
> allows one to explain what is going on with the diff syntax in a very
> clear and verbose manner. I wouldn't want to type that every day, but
> that's OK; "git diff" will always mean the same thing as it always has,
> but can now be explained to people who have trouble seeing it in terms
> of "git diff INDEX WTREE".
>
> There's still a bit of magic in that INDEX is _not_ a tree, but I think
> that's a good thing. When there are no merge conflicts, it will behave
> identically to the proposed NEXT tree. And when there are conflicts, it
> will show you something even more useful.

Thanks. This is exactly why I love to have people like you on the list,
who can say what I wanted to say in a matter that is a lot easier to
understand.

In short, the proposed "NEXT" does not help in a situation with conflicts,
and makes the user experience worse. In order to get the current power of
"git diff" with various options that are specifically designed to help
users to make progress (either working on their own changes, rebasing them
on top of others, or merging other's work in), people _COULD_ introduce
BASE/OURS/THEIRS in addition to "NEXT", throw the existing HEAD and
MERGE_HEAD to the mix, derive the same information by spending mental
effort to choose between which pairs of two entities among these six
possibilities and take pairwise diffs among those pairs, and combine the
results of these diffs (the message I responded to with "is that a useful
question" was an example of that---"Could we pile more kludge on top of
NEXT to have expressiveness equivalent to what the current index-based
system offers?"). Yes, that may be possible, but is there a point in
making users go through that kind of mental contortion by introducing
these new tokens? I find it highly doubtful that it would help new people
understand the situation during conflicted merges.

>   git show INDEX:OURS:Makefile
>
> which is identical to what I wrote above, but is perhaps easier to
> explain.

Why does anybody even want to say :2:Makefile to begin with?

Presumably, you are dealing with a merge conflict at that path and trying
to see how pre-merge version of Makefile looked like, and then the next
thing you may want to do is how pre-merge version of their Makefile looked
like.

Wouldn't it be far more natural to ask for these instead?

    git show HEAD:Makefile
    git show MERGE_HEAD:Makefile

I do not think whoever brought that "you can look at individual stages
with :$n:$path" to this discussion was thinking straight. Yes, it is
something you _could_ do, I've never found that particularly _useful_
unless I was debugging git itself.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 21:48                       ` Junio C Hamano
@ 2011-06-10 22:08                         ` Junio C Hamano
  2011-06-10 23:05                         ` Jakub Narebski
                                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-10 22:08 UTC (permalink / raw)
  To: Jeff King
  Cc: Michael Haggerty, Scott Chacon, Jakub Narebski, Michael Nahas, git

Junio C Hamano <gitster@pobox.com> writes:

> Thanks. This is exactly why I love to have people like you on the list,
> who can say what I wanted to say in a matter that is a lot easier to
> understand.

s/matter/manner/; of course.  Sorry for a silly typo and noise.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 18:35                                         ` Jakub Narebski
@ 2011-06-10 22:45                                           ` Holger Hellmuth
  2011-06-13  3:43                                             ` git diff --added (Re: Command-line interface thoughts) Jonathan Nieder
  2011-06-13 10:15                                             ` Command-line interface thoughts Jakub Narebski
  0 siblings, 2 replies; 98+ messages in thread
From: Holger Hellmuth @ 2011-06-10 22:45 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

Am 10.06.2011 20:35, schrieb Jakub Narebski:
> Dnia piątek 10. czerwca 2011 20:07, Holger Hellmuth napisał:
>> On 10.06.2011 18:44, Jakub Narebski wrote:
>>> On Thu, 9 Jun 2011, Holger Hellmuth wrote:
>>>> Also there are no good words for what someone wants to see in this case.
>>>> At least I would assume the git project would have found them if they
>>>> existed. '--cached' is definitely not one of them. But we have fitting
>>>> and widely known names for the targets, i.e 'working tree', 'index' and
>>>> 'head'.
>>>
>>> "I want to see if there are any remiaining changes", "I want to see what
>>> 'git commit' would bring", "I want to see what 'git commit -a' would bring".
>>> Neither of those is about targets for diff.
>>
>> Are you proposing a command "git 
>> --I-want-to-see-if-there-are-any-remaining-changes" ? ;-). I was looking 
>> for short command or parameter names that are easy to remember, not for 
>> definitions of the output of cryptic commands.
>>
>> But lets see. If I didn't know much git, where would I look for the 
>> right command for your three needs? Where would I expect the solution? 
>> (note I'm not proposing any of these commands)
>>
>> "I want to see if there are any remaining changes"?
>> git status
>> git status --full
>> git status --detailed
> 
> "Any differences"?
> 
> git diff

But difference to what --> User checks man page, again.

> 
> 
> "I want to see what I staged"
> 
> git diff --staged
> 

User never heard of 'staged'. He asks instead "I want to see what I
added" --> git diff --added --> Error Message --> User checks man page,
again

> 
> Isn't it simpler than "I want to see the changes between what I already
> staged, which is put in place called index, but must refer to it by NEXT,
> and the changes I didn't staged, in my working area, which I refer to by
> WORK... no, it is TREE... oh, wait, it is WTREE" :-)  I am exaggerating
> much here, but I think you can see what I want to point out.

Sure. I'm not a fan of 'NEXT' either. I would use INDEX. Or even index
if that doesn't clash with anything. WTREE as well is not optimal but it
is something you can get at as soon as you remember the term 'working
tree'. And you know what you will get without consulting the manuals if
you are unsure.

>> Now I'll add a question I would want to ask:
>> "I want to see the changes between what I have in my working tree and 
>> what I already added to the index"
> 
> That's not a beginner question.

Ok, I had a different definition of beginner, especially since I and all
the git-user I know at my work place used the index from the beginning.
The index is a wonderful idea but it isn't that hard to understand. If
you look at the gittutorial man page (and any of the other 3 top
tutorials in google) 3 of those 4 tutorials talk about the index and git
add, only one uses 'git commit -a' instead.

Only one mentions 'git diff --cached' by the way, seems to be an
advanced topic ;-)


>> git diff WTREE INDEX
>            ^^^^^^^^^^^ --- reverse to "git diff"
> 
> In this direction it is surely suprising... you see, how again and again
> having to explicitely state what to compare with which leads to mistakes
> such like this one, and the one in few mails earlier.

I'm a sloopy person as you have noticed. Also very forgetful. I usually
don't bother with the order of 'diff' parameters when I can get the
direction from the diff output.

>>
>> Btw. even the 'git diff' man page emphasizes that diff is about a 
>> comparision between two things. Citation: "Show changes *between* two 
>> trees, a tree and the working tree, a tree and the index file,...".
>  
> That's more about explaining result of command.  Besides manpages are
> reference documentation; new users should start with user's manual, or
> tutorial (or "Pro Git"), not manpages.

Ok, so lets look at 'Pro Git'. Besides using your description it is also
talking about comparision between working area and staging area and
comparing staged changes to last commit.

> Well, that depends by what you mean by beginner.  Beginner to git, but
> not beginner to version control knows about "<scm> diff" form to check
> for one's changes, for example.
> 
> But I don't think that beginner knows that there is such thing like the
> index, and know that he/she has to compare the index to the working area.
> When he/she starts to use the index, probably he/she isn't a beginner
> anymore.

Learning git is not a role playing game where you have to master level 1
before you can use all the tricks of level 2 ;-). But any which way we
call them there are a lot of users using git with index and all, but who
have to search in the docs whenever they want to do something like
unadding something from the index.

Small things like 'git unadd', Jeff Kings 'git put' and git diff with
targets probably would help this casual/intermediate/advanced user (take
your pick).

Holger.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 21:48                       ` Junio C Hamano
  2011-06-10 22:08                         ` Junio C Hamano
@ 2011-06-10 23:05                         ` Jakub Narebski
  2011-06-12  6:06                         ` Michael Haggerty
                                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-10 23:05 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Michael Haggerty, Scott Chacon, Michael Nahas, git

On Fri, 10 Jun 2011, Junio C Hamano wrote:

I'll be there advocatus diaboli for some things.

> Jeff King <peff@peff.net> writes:
> 
> > I think there are actually two questions here:
> >
> >   1. Will it be easier for people to understand "git diff" if we use
> >      tokens to describe non-treeish sources and destinations?
> >
> >   2. Are there better tokens to use to break down parts of the index?
> >
> > I don't have a big problem with (1). Allowing things like:
> >
> >   git diff INDEX WTREE
> >
> > allows one to explain what is going on with the diff syntax in a very
> > clear and verbose manner. I wouldn't want to type that every day, but
> > that's OK; "git diff" will always mean the same thing as it always has,
> > but can now be explained to people who have trouble seeing it in terms
> > of "git diff INDEX WTREE".
> >
> > There's still a bit of magic in that INDEX is _not_ a tree, but I think
> > that's a good thing. When there are no merge conflicts, it will behave
> > identically to the proposed NEXT tree. And when there are conflicts, it
> > will show you something even more useful.
> 
> Thanks. This is exactly why I love to have people like you on the list,
> who can say what I wanted to say in a manner that is a lot easier to
> understand.
> 
> In short, the proposed "NEXT" does not help in a situation with conflicts,
> and makes the user experience worse.

Which proposed NEXT?  I'm asking because there were many proposals from
many people, some contradictory.

One proposal was, if I understand it correctly, to have NEXT actually be
STAGE, i.e. be multi-tree like current index is in the case of merge
conflicts.  This means that NEXT = \Sum stage_0 + (stage_ours + stage_theirs
+ stage_base). 

> In order to get the current power of 
> "git diff" with various options that are specifically designed to help
> users to make progress (either working on their own changes, rebasing them
> on top of others, or merging other's work in), people _COULD_ introduce
> BASE/OURS/THEIRS in addition to "NEXT", throw the existing HEAD and
> MERGE_HEAD to the mix, derive the same information by spending mental
> effort to choose between which pairs of two entities among these six
> possibilities and take pairwise diffs among those pairs,

And find which direction makes more sense "diff A B" or "diff B A".
"git diff" / "git diff --staged" / "git diff HEAD" use direction that
makes most sense.

> and combine the 
> results of these diffs (the message I responded to with "is that a useful
> question" was an example of that---"Could we pile more kludge on top of
> NEXT to have expressiveness equivalent to what the current index-based
> system offers?"). Yes, that may be possible, but is there a point in
> making users go through that kind of mental contortion by introducing
> these new tokens? I find it highly doubtful that it would help new people
> understand the situation during conflicted merges.
> 
> >   git show INDEX:OURS:Makefile
> >
> > which is identical to what I wrote above, but is perhaps easier to
> > explain.
> 
> Why does anybody even want to say :2:Makefile to begin with?
> 
> Presumably, you are dealing with a merge conflict at that path and trying
> to see how pre-merge version of Makefile looked like, and then the next
> thing you may want to do is how pre-merge version of their Makefile looked
> like.
> 
> Wouldn't it be far more natural to ask for these instead?
> 
>     git show HEAD:Makefile
>     git show MERGE_HEAD:Makefile
> 
> I do not think whoever brought that "you can look at individual stages
> with :$n:$path" to this discussion was thinking straight. Yes, it is
> something you _could_ do, I've never found that particularly _useful_
> unless I was debugging git itself.

Actually there are cases when you don't have MERGE_HEAD, namely:

 * "git merge --squash"
 * "git rebase" and "git rebase --interactive", and "git cherry-pick"
 * "git am --3way"

Note that OURS/THEIRS/BASE/WTREE has more power: currently there is no way
as far as I know to compare stages 2 and 3 directly ("git diff :2: :3:"
didn't work, though this might be fiexed in newer git), or stage and base.

Though I am not sure if anybody would want this.
-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 21:48                       ` Junio C Hamano
  2011-06-10 22:08                         ` Junio C Hamano
  2011-06-10 23:05                         ` Jakub Narebski
@ 2011-06-12  6:06                         ` Michael Haggerty
  2011-06-12 21:12                           ` Junio C Hamano
  2011-06-12 13:30                         ` Michael Nahas
  2011-06-13 18:50                         ` Jeff King
  4 siblings, 1 reply; 98+ messages in thread
From: Michael Haggerty @ 2011-06-12  6:06 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Scott Chacon, Jakub Narebski, Michael Nahas, git

On 06/10/2011 11:48 PM, Junio C Hamano wrote:
> In short, the proposed "NEXT" does not help in a situation with conflicts,
> and makes the user experience worse.

The idea of "NEXT" and its friends would indeed be marginal if it only
applied to "git diff".  The real gain in learnability comes from using
the same idioms in other commands where they make sense; for example,

    # More consistent alternative to the special "--ours" option:
    git checkout OURS -- Makefile

    # This would add more completeness to the
    # "git checkout <tree-ish> -- PATH" command, and would remain the
    # default if no <tree-ish> is specified:
    git checkout NEXT -- Makefile

    # I had to look up the current way to spell this
    # ("git show :Makefile"), but this variant would be obvious
    # by analogy with the other uses of NEXT:
    git show NEXT:Makefile

and of course also in the proposed "git put" command.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 21:48                       ` Junio C Hamano
                                           ` (2 preceding siblings ...)
  2011-06-12  6:06                         ` Michael Haggerty
@ 2011-06-12 13:30                         ` Michael Nahas
  2011-06-12 21:29                           ` Junio C Hamano
  2011-06-13 18:50                         ` Jeff King
  4 siblings, 1 reply; 98+ messages in thread
From: Michael Nahas @ 2011-06-12 13:30 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Michael Haggerty, Scott Chacon, Jakub Narebski, git

I'm going to accept Junio's reply at a sign to withdraw.

It is clear that implementing NEXT/WTREE will worsen the performance
of some commands ("git diff" under merge conflict).  I can accept that
the community does not want to give up performance to include an
incomplete idea that offers no quantifiable improvement.


I agree with Haggerty that the value of NEXT and WTREE to the user
will be seen when they are used in multiple commands.  That is, when
they are part of a collection of porcelain-level concepts that the
user can work with.

I'm going to start a discussion on those porcelain-level concepts.  I
don't think this mailing list is the right forum for it.  If you wish
to be a part of the discussion, please email me.

If the discussion produces something of value, I look forward to
returning and presenting it to the mailing list.

Mike


On Fri, Jun 10, 2011 at 5:48 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jeff King <peff@peff.net> writes:
>
>> I think there are actually two questions here:
>>
>>   1. Will it be easier for people to understand "git diff" if we use
>>      tokens to describe non-treeish sources and destinations?
>>
>>   2. Are there better tokens to use to break down parts of the index?
>>
>> I don't have a big problem with (1). Allowing things like:
>>
>>   git diff INDEX WTREE
>>
>> allows one to explain what is going on with the diff syntax in a very
>> clear and verbose manner. I wouldn't want to type that every day, but
>> that's OK; "git diff" will always mean the same thing as it always has,
>> but can now be explained to people who have trouble seeing it in terms
>> of "git diff INDEX WTREE".
>>
>> There's still a bit of magic in that INDEX is _not_ a tree, but I think
>> that's a good thing. When there are no merge conflicts, it will behave
>> identically to the proposed NEXT tree. And when there are conflicts, it
>> will show you something even more useful.
>
> Thanks. This is exactly why I love to have people like you on the list,
> who can say what I wanted to say in a matter that is a lot easier to
> understand.
>
> In short, the proposed "NEXT" does not help in a situation with conflicts,
> and makes the user experience worse. In order to get the current power of
> "git diff" with various options that are specifically designed to help
> users to make progress (either working on their own changes, rebasing them
> on top of others, or merging other's work in), people _COULD_ introduce
> BASE/OURS/THEIRS in addition to "NEXT", throw the existing HEAD and
> MERGE_HEAD to the mix, derive the same information by spending mental
> effort to choose between which pairs of two entities among these six
> possibilities and take pairwise diffs among those pairs, and combine the
> results of these diffs (the message I responded to with "is that a useful
> question" was an example of that---"Could we pile more kludge on top of
> NEXT to have expressiveness equivalent to what the current index-based
> system offers?"). Yes, that may be possible, but is there a point in
> making users go through that kind of mental contortion by introducing
> these new tokens? I find it highly doubtful that it would help new people
> understand the situation during conflicted merges.
>
>>   git show INDEX:OURS:Makefile
>>
>> which is identical to what I wrote above, but is perhaps easier to
>> explain.
>
> Why does anybody even want to say :2:Makefile to begin with?
>
> Presumably, you are dealing with a merge conflict at that path and trying
> to see how pre-merge version of Makefile looked like, and then the next
> thing you may want to do is how pre-merge version of their Makefile looked
> like.
>
> Wouldn't it be far more natural to ask for these instead?
>
>    git show HEAD:Makefile
>    git show MERGE_HEAD:Makefile
>
> I do not think whoever brought that "you can look at individual stages
> with :$n:$path" to this discussion was thinking straight. Yes, it is
> something you _could_ do, I've never found that particularly _useful_
> unless I was debugging git itself.
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-12  6:06                         ` Michael Haggerty
@ 2011-06-12 21:12                           ` Junio C Hamano
  0 siblings, 0 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-12 21:12 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Jeff King, Scott Chacon, Jakub Narebski, Michael Nahas, git

Michael Haggerty <mhagger@alum.mit.edu> writes:

> On 06/10/2011 11:48 PM, Junio C Hamano wrote:
>> In short, the proposed "NEXT" does not help in a situation with conflicts,
>> and makes the user experience worse.
>
> The idea of "NEXT" and its friends would indeed be marginal if it only
> applied to "git diff".  The real gain in learnability comes from using
> the same idioms in other commands where they make sense; for example,
>
>     # More consistent alternative to the special "--ours" option:
>     git checkout OURS -- Makefile

I do not see much improvement over --ours here.

>     # This would add more completeness to the
>     # "git checkout <tree-ish> -- PATH" command, and would remain the
>     # default if no <tree-ish> is specified:
>     git checkout NEXT -- Makefile
>     git show NEXT:Makefile

Now, during conflict, you admitted that NEXT would not be helpful for
"diff", but these are even more dubious during conflict.

The point of index that can keep conflicted state (in fact, contrary to
some misperception, index is where the real merge happens, and updating
the working tree is merely to _help_ users to help the index resolve the
conflicts, not the other way around) is that until you resolve conflicts,
"the state for the NEXT commit" is not defined.

How would it improve the support we give to users when you give NEXT to
them, compared with the current system, if you have to say "NEXT" works
most of the time to represent what you would commit next?  You have to
also tell them that in some circumstances there cannot be "NEXT" until
they resolve conflicts, and then they need to learn how to do so with the
index. They need to learn the real thing at that point, unlearning fuzzily
defined "NEXT" illusion.

I certainly do not have any objection against making system easier to
understand, and I do not think implementation complexity nor performance
should trump the usability (I also do not think various conflicting
semantics of proposed "NEXT" are hard to implement efficiently).

I however doubt "NEXT" would help to give users any better understanding,
and that is the biggest problem I have with this topic.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-12 13:30                         ` Michael Nahas
@ 2011-06-12 21:29                           ` Junio C Hamano
  2011-06-13  2:14                             ` Michael Nahas
  0 siblings, 1 reply; 98+ messages in thread
From: Junio C Hamano @ 2011-06-12 21:29 UTC (permalink / raw)
  To: mike; +Cc: Jeff King, Michael Haggerty, Scott Chacon, Jakub Narebski, git

Michael Nahas <mike.nahas@gmail.com> writes:

> It is clear that implementing NEXT/WTREE will worsen the performance
> of some commands ("git diff" under merge conflict).

It is not clear to me at all. I generally do not to base my first
objection on performance. When I have problems with proposals at the
design and concept level, I do not have a chance to even bother about
performance aspect, before questioning the proposal.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-12 21:29                           ` Junio C Hamano
@ 2011-06-13  2:14                             ` Michael Nahas
  0 siblings, 0 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-13  2:14 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Michael Haggerty, Scott Chacon, Jakub Narebski, git

On Sun, Jun 12, 2011 at 5:29 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Michael Nahas <mike.nahas@gmail.com> writes:
>
>> It is clear that implementing NEXT/WTREE will worsen the performance
>> of some commands ("git diff" under merge conflict).
>
> It is not clear to me at all. I generally do not to base my first
> objection on performance. When I have problems with proposals at the
> design and concept level, I do not have a chance to even bother about
> performance aspect, before questioning the proposal.

My apologies.  "Performance" was an ambiguous word.

I meant that "git diff" under a merge conflict would be less
informative if forced it to be equivalent to some notation with
NEXT/WTREE.  Even if we allowed diff3 and defined BASE, OURS, THEIRS.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* git diff --added (Re: Command-line interface thoughts)
  2011-06-10 22:45                                           ` Holger Hellmuth
@ 2011-06-13  3:43                                             ` Jonathan Nieder
  2011-06-13  4:11                                               ` Miles Bader
  2011-06-13 10:15                                             ` Command-line interface thoughts Jakub Narebski
  1 sibling, 1 reply; 98+ messages in thread
From: Jonathan Nieder @ 2011-06-13  3:43 UTC (permalink / raw)
  To: Holger Hellmuth
  Cc: Jakub Narebski, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

Holger Hellmuth wrote:

> User never heard of 'staged'. He asks instead "I want to see what I
> added" --> git diff --added --> Error Message --> User checks man page,
> again

Do you think it would be valuable to introduce --added as a synonym
for --cached and slowly steer documentation to encourage the latter
in place of the former?

Examples, to see how it could work in practice:

	# Instead of searching tracked files in the working tree,
	# search blobs registered in the index file (i.e., accepted
	# with "git add" instead of the iffy hacks that are up in
	# the air).  The main advantage of this over plain "git grep"
	# is speed.
	git grep --added -e foo

	# Remove foo.c from the next commit, without touching the
	# worktree.
	git rm --added foo.c

	# Apply patch to the index, leaving the worktree alone.
	git apply --added some-change.patch

	# List changes that I marked with "git add" for inclusion in
	# the next commit.
	git diff --added

I like it a lot more than "staged". ;-)  Though --index-only still
seems a little clearer to me.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: git diff --added (Re: Command-line interface thoughts)
  2011-06-13  3:43                                             ` git diff --added (Re: Command-line interface thoughts) Jonathan Nieder
@ 2011-06-13  4:11                                               ` Miles Bader
  2011-06-13  4:46                                                 ` Miles Bader
                                                                   ` (2 more replies)
  0 siblings, 3 replies; 98+ messages in thread
From: Miles Bader @ 2011-06-13  4:11 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Holger Hellmuth, Jakub Narebski, Michael J Gruber,
	Junio C Hamano, Scott Chacon, Michael Nahas, git

Jonathan Nieder <jrnieder@gmail.com> writes:
> Do you think it would be valuable to introduce --added as a synonym
> for --cached and slowly steer documentation to encourage the latter
> in place of the former?

"--added" sounds very awkward though; "--staged" is much more natural.

-miles

-- 
Idiot, n. A member of a large and powerful tribe whose influence in human
affairs has always been dominant and controlling.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: git diff --added (Re: Command-line interface thoughts)
  2011-06-13  4:11                                               ` Miles Bader
@ 2011-06-13  4:46                                                 ` Miles Bader
  2011-06-13  8:06                                                 ` Jonathan Nieder
  2011-06-13 12:28                                                 ` Junio C Hamano
  2 siblings, 0 replies; 98+ messages in thread
From: Miles Bader @ 2011-06-13  4:46 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Holger Hellmuth, Jakub Narebski, Michael J Gruber,
	Junio C Hamano, Scott Chacon, Michael Nahas, git

On Mon, Jun 13, 2011 at 4:11 AM, Miles Bader <miles@gnu.org> wrote:
>> Do you think it would be valuable to introduce --added as a synonym
>> for --cached and slowly steer documentation to encourage the latter
>> in place of the former?
>
> "--added" sounds very awkward though; "--staged" is much more natural.

I should note _why_ this is so:

The main problem is well-known -- that "git add" is a bit overloaded
and slightly awkward in some case (e.g., to remove a file, you need to
add it...).  But whatever, it works well enough, because people are
used to it.

However in the case of git diff, if one sees "git diff --added", it
sounds like it means "show me a diff of added files" -- but the term
"added files" is ambiguous; and the fact that "git add" is in fact,
overloaded with multiple meanings doesn't really help, the basic
ambiguity makes "git diff --added" awkward and unclear.

A far better way would be to (1) make "git diff --staged" an alias for
"git-diff --cached" (2) start promoting "git stage" in documentation,
instead of "git add".

-Miles

-- 
Cat is power.  Cat is peace.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: git diff --added (Re: Command-line interface thoughts)
  2011-06-13  4:11                                               ` Miles Bader
  2011-06-13  4:46                                                 ` Miles Bader
@ 2011-06-13  8:06                                                 ` Jonathan Nieder
  2011-06-13 12:55                                                   ` Junio C Hamano
  2011-06-13 12:28                                                 ` Junio C Hamano
  2 siblings, 1 reply; 98+ messages in thread
From: Jonathan Nieder @ 2011-06-13  8:06 UTC (permalink / raw)
  To: Miles Bader
  Cc: Holger Hellmuth, Jakub Narebski, Michael J Gruber,
	Junio C Hamano, Scott Chacon, Michael Nahas, git

Miles Bader wrote:

> "--added" sounds very awkward though; "--staged" is much more natural.

You make a strong case.  How about something like this?

-- >8 --
Subject: Documentation: explain diff --cached in terms of non --cached form

"git diff" is a somewhat odd command, since it has two fairly
different roles:

 - on one hand, it is the command to explain the worktree or index in
   terms of something else;
 - on the other hand, it is the command to compare two blobs, trees,
   or on-disk files.

To a new user, that second role might seem to be the most basic and
most natural, since it is most closely analagous to the ordinary
non-git "diff" command, but in practice the first one is the one that
gets used most often and it is somewhat different.  Avoid surprises
by treating this first role separately in the introductory paragraph
and calling it "primary".

The motivation is that it is hard enough to remember the various 0-
and 1-tree forms of "git diff"; hopefully fending off the distraction
of a false analogy with 2-tree "git diff" will help with that.  This
patch also tries to clarify those mnemonics (especially: "--cached"
mean to use the index in place of the worktree) by rearranging the
material slightly.  The most obvious mechanical changes involved are
listing 0- and 1-tree "git diff" separately in the synopsis and
reordering the text to put "git diff HEAD" before "git diff --cached
HEAD".

Some small wording improvements snuck in while at it, including
mentioning the --staged synonym for --cached a little more often.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 Documentation/git-diff.txt |   61 +++++++++++++++++++++++--------------------
 1 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index f8d0819..7a66017 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -9,59 +9,64 @@ git-diff - Show changes between commits, commit and working tree, etc
 SYNOPSIS
 --------
 [verse]
-'git diff' [options] [<commit>] [--] [<path>...]
+'git diff' [options] [--] [<path>...]
+'git diff' [options] <commit> [--] [<path>...]
 'git diff' [options] --cached [<commit>] [--] [<path>...]
 'git diff' [options] <commit> <commit> [--] [<path>...]
 'git diff' [options] [--no-index] [--] <path> <path>
 
 DESCRIPTION
 -----------
-Show changes between the working tree and the index or a tree, changes
-between the index and a tree, changes between two trees, or changes
-between two files on disk.
+The primary purpose of 'git diff' is to compare files in the working
+tree to stored versions in the repository.  It can also be used to
+show changes between the index and a tree, changes between two trees,
+or changes between two files on disk.
 
-'git diff' [--options] [--] [<path>...]::
+'git diff' [options] [--] [<path>...]::
 
 	This form is to view the changes you made relative to
-	the index (staging area for the next commit).  In other
-	words, the differences are what you _could_ tell git to
-	further add to the index but you still haven't.  You can
-	stage these changes by using linkgit:git-add[1].
+	the index (staging area for the next commit).  It is
+	the most common use of 'git diff'; the differences are
+	what you _could_ tell git to further add to the index
+	but you still haven't.  You can stage these changes by
+	using linkgit:git-add[1] (aka linkgit:git-stage[1]).
 +
-If exactly two paths are given and at least one points outside
-the current repository, 'git diff' will compare the two files /
-directories. This behavior can be forced by --no-index.
+If exactly two paths are given and one points outside the current
+repository, 'git diff' will compare the two files or directories.
+This behavior can be forced with the `--no-index` option.
 
-'git diff' [--options] --cached [<commit>] [--] [<path>...]::
-
-	This form is to view the changes you staged for the next
-	commit relative to the named <commit>.  Typically you
-	would want comparison with the latest commit, so if you
-	do not give <commit>, it defaults to HEAD.
-	If HEAD does not exist (e.g. unborned branches) and
-	<commit> is not given, it shows all staged changes.
-	--staged is a synonym of --cached.
-
-'git diff' [--options] <commit> [--] [<path>...]::
+'git diff' [options] <commit> [--] [<path>...]::
 
 	This form is to view the changes you have in your
 	working tree relative to the named <commit>.  You can
-	use HEAD to compare it with the latest commit, or a
+	use HEAD to compare with the latest commit, or a
 	branch name to compare with the tip of a different
 	branch.
 
-'git diff' [--options] <commit> <commit> [--] [<path>...]::
+'git diff' [options] --cached [<commit>] [--] [<path>...]::
+'git diff' [options] --staged [<commit>] [--] [<path>...]::
+
+	If passed --cached or its synonym --staged,
+	'git diff' will view the changes you have staged for
+	the next commit instead of examining the working tree.
+	Typically you would want a comparison with the latest
+	commit, so if you do not give <commit>, it defaults
+	to HEAD.
+	If HEAD does not exist (e.g. unborn branches) and
+	<commit> is not given, it shows all staged changes.
+
+'git diff' [options] <commit> <commit> [--] [<path>...]::
 
 	This is to view the changes between two arbitrary
-	<commit>.
+	commits.
 
-'git diff' [--options] <commit>..<commit> [--] [<path>...]::
+'git diff' [options] <commit>..<commit> [--] [<path>...]::
 
 	This is synonymous to the previous form.  If <commit> on
 	one side is omitted, it will have the same effect as
 	using HEAD instead.
 
-'git diff' [--options] <commit>\...<commit> [--] [<path>...]::
+'git diff' [options] <commit>\...<commit> [--] [<path>...]::
 
 	This form is to view the changes on the branch containing
 	and up to the second <commit>, starting at a common ancestor
-- 
1.7.6.rc1

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 22:45                                           ` Holger Hellmuth
  2011-06-13  3:43                                             ` git diff --added (Re: Command-line interface thoughts) Jonathan Nieder
@ 2011-06-13 10:15                                             ` Jakub Narebski
  2011-06-13 22:33                                               ` Holger Hellmuth
  2011-06-14  4:21                                               ` Michael Haggerty
  1 sibling, 2 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-13 10:15 UTC (permalink / raw)
  To: Holger Hellmuth
  Cc: Jonathan Nieder, Michael J Gruber, Junio C Hamano, Scott Chacon,
	Michael Nahas, git

On Sat, 11 June 2011, Holger Hellmuth wrote:
> Am 10.06.2011 20:35, schrieb Jakub Narebski:
>> Dnia piątek 10. czerwca 2011 20:07, Holger Hellmuth napisał:
>>> On 10.06.2011 18:44, Jakub Narebski wrote:
>>>> On Thu, 9 Jun 2011, Holger Hellmuth wrote:

>>>>> Also there are no good words for what someone wants to see in this case.
>>>>> At least I would assume the git project would have found them if they
>>>>> existed. '--cached' is definitely not one of them. But we have fitting
>>>>> and widely known names for the targets, i.e 'working tree', 'index' and
>>>>> 'head'.
>>>>
>>>> "I want to see if there are any remaining changes", "I want to see what
>>>> 'git commit' would bring", "I want to see what 'git commit -a' would bring".
>>>> Neither of those is about targets for diff.
>>>
>>> Are you proposing a command "git 
>>> --I-want-to-see-if-there-are-any-remaining-changes" ? ;-). I was looking 
>>> for short command or parameter names that are easy to remember, not for 
>>> definitions of the output of cryptic commands.
>>>
>>> But lets see. If I didn't know much git, where would I look for the 
>>> right command for your three needs? Where would I expect the solution? 
>>> (note I'm not proposing any of these commands)
>>>
>>> "I want to see if there are any remaining changes"?
>>> git status
>>> git status --full
>>> git status --detailed
>> 
>> "Any differences"?
>> 
>> git diff
> 
> But difference to what --> User checks man page, again.

User's changes.  User doesn't need to know what are those two places
called.
 
>> 
>> 
>> "I want to see what I staged"
>> 
>> git diff --staged
>> 
> 
> User never heard of 'staged'. He asks instead "I want to see what I
> added" --> git diff --added --> Error Message --> User checks man page,
> again

User uses "git stage <file>", so he/she uses "git diff --staged".
 
[...]
>>> git diff WTREE INDEX
>>           ^^^^^^^^^^^ --- reverse to "git diff"
>> 
>> In this direction it is surely suprising... you see, how again and again
>> having to explicitely state what to compare with which leads to mistakes
>> such like this one, and the one in few mails earlier.
> 
> I'm a sloopy person as you have noticed. Also very forgetful. I usually
> don't bother with the order of 'diff' parameters when I can get the
> direction from the diff output.

For other people getting the reverse of changes can be certainly
suprising (I though I added this, not deleted...).  When you specify
endpoints manually, there is a chance to get them in wrong direction.
Especially that there is NEXT WTREE but HEAD NEXT.

> Small things like 'git unadd', Jeff Kings 'git put' and git diff with
> targets probably would help this casual/intermediate/advanced user (take
> your pick).

I agree with 'git unadd'.  Jeff Kings 'git put' and git diff targets have
the problems that need to be fully solved before considering for inclusion.

BTW. there is code for 'git put'.  Where is code for git diff targets?

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: git diff --added (Re: Command-line interface thoughts)
  2011-06-13  4:11                                               ` Miles Bader
  2011-06-13  4:46                                                 ` Miles Bader
  2011-06-13  8:06                                                 ` Jonathan Nieder
@ 2011-06-13 12:28                                                 ` Junio C Hamano
  2011-06-13 19:47                                                   ` Holger Hellmuth
  2 siblings, 1 reply; 98+ messages in thread
From: Junio C Hamano @ 2011-06-13 12:28 UTC (permalink / raw)
  To: Miles Bader
  Cc: Jonathan Nieder, Holger Hellmuth, Jakub Narebski,
	Michael J Gruber, Scott Chacon, Michael Nahas, git

Miles Bader <miles@gnu.org> writes:

> Jonathan Nieder <jrnieder@gmail.com> writes:
>> Do you think it would be valuable to introduce --added as a synonym
>> for --cached and slowly steer documentation to encourage the latter
>> in place of the former?
>
> "--added" sounds very awkward though; "--staged" is much more natural.

Actually I think _both_ are equally wrong.

I have to thank you and Jonathan for making me realize the real reason why
"staged" didn't sit well in my ears. The word used as adjective nauseated
me forever but I couldn't clearly explain why even to myself, but now I
have the explanation.

The index has data registered for paths. "add" (and "stage") are verbs
used to describe the act of taking data different from what is currently
registered in the index and replacing it. The phrase "added contents" thus
can be (mis)interpreted to refer to only the subset of the data that is
different from what you used to have in the index, typically meaning the
ones that are different from HEAD, i.e. you would see the change in the
output of "git diff HEAD". This is especially true because many people
think in terms of "recording difference from the previous version" when
they think about SCMs, and "--added" or "--staged" rhyme well with that
mindset.

This potential misinterpretation does not cause problems in some contenxt,
and one such context is the hidden synonym "git diff --staged", which _is_
all about the subset of the paths that are different from HEAD.

But as Jonathan in his message and you in your response brilliantly
illustrated, misinterpreted "added" and "staged" break down badly in other
contexts. When running "git grep" and "git rm" against the data sitting in
the index, you do _not_ want to limit your request to the subset of paths
in the index that are different from HEAD. "git rm --added" is not a
command that chooses paths that are added to the index, and remove these
paths from both the index and the working tree, but "added" would invite
such a misinterpretation from new people.

The adjective "cached" refers to the _state_ of the data for various paths
in the index as they exist, regardless of when or how these contents were
placed there. For the majority of the paths the "cached" data may have
come from the HEAD, and for other paths, "cached" data may be something
you have "added", but because "cached" is a state as it exists in the
index, there is no distinction between the two.

Because "cache" nor "index" are never used as verbs that mean the _act_ of
putting updated things in the index, we do not risk --cached nor --index
to get misinterpreted as limiting to the subset of the paths that are
different from HEAD. At least that is how these four words (added, staged,
cached and index) sound to my ears, and that is why I said the first two
are equally wrong in the beginning of this message.

It is an entirely different issue that "cached" is _not_ the best way to
spell "index-only", though.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: git diff --added (Re: Command-line interface thoughts)
  2011-06-13  8:06                                                 ` Jonathan Nieder
@ 2011-06-13 12:55                                                   ` Junio C Hamano
  0 siblings, 0 replies; 98+ messages in thread
From: Junio C Hamano @ 2011-06-13 12:55 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Miles Bader, Holger Hellmuth, Jakub Narebski, Michael J Gruber,
	Scott Chacon, Michael Nahas, git

Jonathan Nieder <jrnieder@gmail.com> writes:

> -Show changes between the working tree and the index or a tree, changes
> -between the index and a tree, changes between two trees, or changes
> -between two files on disk.
> +The primary purpose of 'git diff' is to compare files in the working
> +tree to stored versions in the repository.  It can also be used to
> +show changes between the index and a tree, changes between two trees,
> +or changes between two files on disk.

I agree that it is a good idea to clarify whatever likely misunderstanding
new people might have, and I further agree that to some people the command
line syntax of diff to compare a tree with the index or with the working
tree may look like a different "modes" from the syntax to compare two
tree-ish.

I however am not sure it is a good idea to declare "comparing the index
with the working tree" is the "primary". People who are just starting out,
just downloading and sightseeing, are likely to use "git clone" followed
by "git diff v2.6.39 v3.0", I suspect, and to them, the primary use would
be to compare two revisions, no?

Instead of making them sound as if they are different "modes", I think it
may make more sense to teach them upfront that in addition to the two
"modes" they may be familiar with from their past experiences with other
SCMs, namely, comparing two revisions and comparing a revision with the
working tree, there are two extra pairs they could be comparing in git,
namely, comparing the index (the data you prepared for your next commit)
with the working tree, and comparing the index with a revision.

	Side note: note that even in the context of other SCMs, the choice
	the user makes when using "diff" is not about what two things to
	compare, i.e. "scm diff REV1 WTREE" vs "scm diff REV1 REV2". They
	choose two "modes" and then fill in the parameter(s) the chosen
	mode requires. When comparing two revs, you need two revs; when
	comparing a rev with the working tree, you need one rev, and
	worktree does not have to be specified. That way, you do not
	explicitly specify which "mode" you are using, as that can be
	inferred from the command line.

	But if we do not call these two "modes", I do not see a reason for
	us to call two extra pairs git gives them "modes" either.

Then if you feel "comparing the index with the working tree" the most
important combination, start your description from that "mode".

For the reason I stated in the other message, I think it was a wise
decision not to advertise "diff --staged" synonym when we introduced it at
2baf185 (git-diff: Add --staged as a synonym for --cached., 2008-10-29),
by the way.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-10 21:48                       ` Junio C Hamano
                                           ` (3 preceding siblings ...)
  2011-06-12 13:30                         ` Michael Nahas
@ 2011-06-13 18:50                         ` Jeff King
  4 siblings, 0 replies; 98+ messages in thread
From: Jeff King @ 2011-06-13 18:50 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Michael Haggerty, Scott Chacon, Jakub Narebski, Michael Nahas, git

On Fri, Jun 10, 2011 at 02:48:56PM -0700, Junio C Hamano wrote:

> >   git show INDEX:OURS:Makefile
> >
> > which is identical to what I wrote above, but is perhaps easier to
> > explain.
> 
> Why does anybody even want to say :2:Makefile to begin with?
> [...]
> I do not think whoever brought that "you can look at individual stages
> with :$n:$path" to this discussion was thinking straight. Yes, it is
> something you _could_ do, I've never found that particularly _useful_
> unless I was debugging git itself.

I think it may have been me, and I was bringing it up for completeness
in discussion of the new tokens. I don't actually use that concept very
often at all, so it can just be dropped from this discussion.

-Peff

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: git diff --added (Re: Command-line interface thoughts)
  2011-06-13 12:28                                                 ` Junio C Hamano
@ 2011-06-13 19:47                                                   ` Holger Hellmuth
  2011-06-13 20:31                                                     ` Michael Nahas
  0 siblings, 1 reply; 98+ messages in thread
From: Holger Hellmuth @ 2011-06-13 19:47 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Miles Bader, Jonathan Nieder, Jakub Narebski, Michael J Gruber,
	Scott Chacon, Michael Nahas, git

Am 13.06.2011 14:28, schrieb Junio C Hamano:
>> Jonathan Nieder <jrnieder@gmail.com> writes:
>>> Do you think it would be valuable to introduce --added as a synonym
>>> for --cached and slowly steer documentation to encourage the latter
>>> in place of the former?

No. Apart from Junios reason more options won't help that much because
git is already loaded with options (git diff for example has 49). Don't
misinterpret this as a suggestion to remove options, just that an option
in this sea of options must be very obvious to help the casual user.
And "git diff --added" is not telling with what it compares the "added"
files, which means you either know the concept or you have to read the
man page whenever you need to use it. Until you fix it in your memory,
which may be never because you don't use it often enough.

> It is an entirely different issue that "cached" is _not_ the best way to
> spell "index-only", though.

Yes, and the one and only word that would be right here (apart from
spelling it out with index-only) is "index", while "index" as used in
git stash and git apply should have been something like 'with-index'. At
least to me '--something' suggests 'something-only' much more than
'something-too'

Since this is not possible anymore, we are stuck with 'cache' and
essentially a diff-command that will never be user-friendly. That is why
I still think that an alternate usage with 'git diff wtree index' would
be beneficial, especially with a corresponding 'git put'.

Holger.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: git diff --added (Re: Command-line interface thoughts)
  2011-06-13 19:47                                                   ` Holger Hellmuth
@ 2011-06-13 20:31                                                     ` Michael Nahas
  0 siblings, 0 replies; 98+ messages in thread
From: Michael Nahas @ 2011-06-13 20:31 UTC (permalink / raw)
  To: Holger Hellmuth
  Cc: Junio C Hamano, Miles Bader, Jonathan Nieder, Jakub Narebski,
	Michael J Gruber, Scott Chacon, git

index is a file with multiple uses.
E.g., during a conflict it may have 4 "stages".

I prefer either index0 or NEXT.

On Mon, Jun 13, 2011 at 3:47 PM, Holger Hellmuth <hellmuth@ira.uka.de> wrote:
> Am 13.06.2011 14:28, schrieb Junio C Hamano:
>>> Jonathan Nieder <jrnieder@gmail.com> writes:
>>>> Do you think it would be valuable to introduce --added as a synonym
>>>> for --cached and slowly steer documentation to encourage the latter
>>>> in place of the former?
>
> No. Apart from Junios reason more options won't help that much because
> git is already loaded with options (git diff for example has 49). Don't
> misinterpret this as a suggestion to remove options, just that an option
> in this sea of options must be very obvious to help the casual user.
> And "git diff --added" is not telling with what it compares the "added"
> files, which means you either know the concept or you have to read the
> man page whenever you need to use it. Until you fix it in your memory,
> which may be never because you don't use it often enough.
>
>> It is an entirely different issue that "cached" is _not_ the best way to
>> spell "index-only", though.
>
> Yes, and the one and only word that would be right here (apart from
> spelling it out with index-only) is "index", while "index" as used in
> git stash and git apply should have been something like 'with-index'. At
> least to me '--something' suggests 'something-only' much more than
> 'something-too'
>
> Since this is not possible anymore, we are stuck with 'cache' and
> essentially a diff-command that will never be user-friendly. That is why
> I still think that an alternate usage with 'git diff wtree index' would
> be beneficial, especially with a corresponding 'git put'.
>
> Holger.
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-13 10:15                                             ` Command-line interface thoughts Jakub Narebski
@ 2011-06-13 22:33                                               ` Holger Hellmuth
  2011-06-14  4:21                                               ` Michael Haggerty
  1 sibling, 0 replies; 98+ messages in thread
From: Holger Hellmuth @ 2011-06-13 22:33 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Holger Hellmuth, Jonathan Nieder, Michael J Gruber,
	Junio C Hamano, Scott Chacon, Michael Nahas, git

Am 13.06.2011 12:15, schrieb Jakub Narebski:
> For other people getting the reverse of changes can be certainly
> suprising (I though I added this, not deleted...).  When you specify
> endpoints manually, there is a chance to get them in wrong direction.
> Especially that there is NEXT WTREE but HEAD NEXT.

Other people have that problem anyway when they use 'git diff <commit>
<othercommit>'. Or when they use linux diff, where the man page doesn't
even specify which direction it compares. Obviously someone thought that
"--- a.txt,  +++ b.txt" or the direction of '>' and '<' give enough hints.

[...]
> BTW. there is code for 'git put'.  Where is code for git diff targets?

Do you accept perl code? ;-) I've never seriously coded in C

Holger.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-13 10:15                                             ` Command-line interface thoughts Jakub Narebski
  2011-06-13 22:33                                               ` Holger Hellmuth
@ 2011-06-14  4:21                                               ` Michael Haggerty
  2011-06-14  7:51                                                 ` Jakub Narebski
  1 sibling, 1 reply; 98+ messages in thread
From: Michael Haggerty @ 2011-06-14  4:21 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Holger Hellmuth, Jonathan Nieder, Michael J Gruber,
	Junio C Hamano, Scott Chacon, Michael Nahas, git

On 06/13/2011 12:15 PM, Jakub Narebski wrote:
> BTW. there is code for 'git put'.  Where is code for git diff targets?

Is this just a rhetorical question, or would code be useful?  From the
tone of the conversation, I got the impression that the change has no
chance of being accepted.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: Command-line interface thoughts
  2011-06-14  4:21                                               ` Michael Haggerty
@ 2011-06-14  7:51                                                 ` Jakub Narebski
  0 siblings, 0 replies; 98+ messages in thread
From: Jakub Narebski @ 2011-06-14  7:51 UTC (permalink / raw)
  To: Michael Haggerty, Scott Chacon
  Cc: Holger Hellmuth, Jonathan Nieder, Michael J Gruber,
	Junio C Hamano, Michael Nahas, git

On Thu, 14 Jun 2011, Michael Haggerty wrote:
> On 06/13/2011 12:15 PM, Jakub Narebski wrote:

> > BTW. there is code for 'git put'.  Where is code for git diff targets?
> 
> Is this just a rhetorical question, or would code be useful?  From the
> tone of the conversation, I got the impression that the change has no
> chance of being accepted.

It was not entirely rhetorical question.

First, code speak louder than words. A feature for which there exist
implementation (and documentation, and tests) has much more chance being
accepted / merged in, than purely theoretical discussion on user
interface. Though the latter is needed too, of course.

Second, writing proof of concept implementation, or at least trying
to write documentation and/or test for new feature or new behavior
help to flesh out ideas, to give them definite shape.


But I know that not everybody is a programmer, and from those not all
are proficient in C (at least for this case), Perl, Python or shell
scripting, and with Git API to implement new feature.

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2011-06-14  7:52 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <BANLkTikTWx7A64vN+hVZgL7cuiZ16Eobgg@mail.gmail.com>
2011-06-04 16:17 ` Command-line interface thoughts Michael Nahas
2011-06-04 21:49   ` Jakub Narebski
2011-06-05  1:00     ` Michael Nahas
2011-06-05 11:10       ` Jakub Narebski
2011-06-05 18:39         ` Scott Chacon
2011-06-05 23:37           ` Jakub Narebski
2011-06-06  6:16           ` Junio C Hamano
2011-06-06  7:34             ` Michael J Gruber
2011-06-06 11:45               ` Michael Nahas
2011-06-06 12:19               ` Jakub Narebski
2011-06-06 13:20                 ` Michael J Gruber
2011-06-08 13:10                   ` Jakub Narebski
2011-06-06 16:23                 ` Junio C Hamano
2011-06-06 16:40                   ` Drew Northup
2011-06-06 14:00               ` Junio C Hamano
2011-06-06 14:16                 ` Michael J Gruber
2011-06-06 16:14                   ` Junio C Hamano
2011-06-06 17:42                     ` Scott Chacon
2011-06-06 19:01                       ` Junio C Hamano
     [not found]                         ` <BANLkTi=yytzDrJLvVn_ZhJOiQs-rqvKi1w@mail.gmail.com>
2011-06-07  2:31                           ` Michael Nahas
2011-06-07  4:03                             ` Junio C Hamano
2011-06-07 11:04                               ` Michael Nahas
2011-06-07  6:11                     ` Michael J Gruber
2011-06-07 11:45                       ` Jonathan Nieder
2011-06-07 19:00                         ` Holger Hellmuth
2011-06-07 19:11                           ` Jonathan Nieder
2011-06-07 20:33                             ` Jakub Narebski
2011-06-08 13:04                               ` Holger Hellmuth
2011-06-08 18:56                                 ` Jakub Narebski
2011-06-09 11:55                                   ` Holger Hellmuth
2011-06-10 16:44                                     ` Jakub Narebski
2011-06-10 18:07                                       ` Holger Hellmuth
2011-06-10 18:35                                         ` Jakub Narebski
2011-06-10 22:45                                           ` Holger Hellmuth
2011-06-13  3:43                                             ` git diff --added (Re: Command-line interface thoughts) Jonathan Nieder
2011-06-13  4:11                                               ` Miles Bader
2011-06-13  4:46                                                 ` Miles Bader
2011-06-13  8:06                                                 ` Jonathan Nieder
2011-06-13 12:55                                                   ` Junio C Hamano
2011-06-13 12:28                                                 ` Junio C Hamano
2011-06-13 19:47                                                   ` Holger Hellmuth
2011-06-13 20:31                                                     ` Michael Nahas
2011-06-13 10:15                                             ` Command-line interface thoughts Jakub Narebski
2011-06-13 22:33                                               ` Holger Hellmuth
2011-06-14  4:21                                               ` Michael Haggerty
2011-06-14  7:51                                                 ` Jakub Narebski
2011-06-07 19:34                         ` René Scharfe
2011-06-07 19:38                           ` Jakub Narebski
2011-06-08 11:12                       ` Command-line interface thoughts (ad-hominem attacks) Jakub Narebski
2011-06-08 11:39                         ` Michael Nahas
2011-06-08 12:42                           ` Jakub Narebski
2011-06-08 14:15                             ` Michael Nahas
2011-06-08 15:05                           ` Jeff King
2011-06-08 18:57                             ` Michael Nahas
2011-06-09  0:43                               ` Jeff King
2011-06-09  1:56                                 ` Michael Nahas
2011-06-10 15:29                                   ` Jakub Narebski
2011-06-09  9:48                               ` Command-line interface thoughts Jakub Narebski
2011-06-09 11:44                                 ` Michael Nahas
2011-06-09 12:45                                   ` Jakub Narebski
2011-06-09 13:06                                     ` Jakub Narebski
2011-06-09  9:06             ` Michael Haggerty
2011-06-09 10:02               ` Andreas Ericsson
2011-06-09 13:30                 ` Thomas Rast
2011-06-09 16:18               ` Jeff King
2011-06-09 17:15                 ` Jay Soffian
2011-06-09 17:20                   ` Jeff King
2011-06-09 17:36                   ` Junio C Hamano
2011-06-09 18:20                     ` Jay Soffian
2011-06-09 19:40                       ` Junio C Hamano
2011-06-09 18:03                 ` Michael Haggerty
2011-06-09 18:38                   ` Junio C Hamano
2011-06-09 19:17                     ` Michael Haggerty
2011-06-09 20:04                     ` Jeff King
2011-06-09 21:37                       ` Michael Haggerty
2011-06-09 22:04                         ` Jakub Narebski
2011-06-09 23:02                           ` Michael Haggerty
2011-06-10 10:19                             ` Jakub Narebski
2011-06-10 11:06                               ` Michael Nahas
2011-06-10 12:20                                 ` Jakub Narebski
2011-06-09 22:21                         ` Jeff King
2011-06-09 22:27                         ` Michael Nahas
2011-06-09 22:38                           ` Jeff King
2011-06-09 22:55                             ` Jakub Narebski
2011-06-10  0:00                             ` Michael Nahas
2011-06-10  0:08                               ` Jeff King
2011-06-10 21:48                       ` Junio C Hamano
2011-06-10 22:08                         ` Junio C Hamano
2011-06-10 23:05                         ` Jakub Narebski
2011-06-12  6:06                         ` Michael Haggerty
2011-06-12 21:12                           ` Junio C Hamano
2011-06-12 13:30                         ` Michael Nahas
2011-06-12 21:29                           ` Junio C Hamano
2011-06-13  2:14                             ` Michael Nahas
2011-06-13 18:50                         ` Jeff King
2011-06-09 19:41                   ` Jeff King
2011-06-05 21:22         ` Paul Ebermann
2011-06-05 21:34   ` Paul Ebermann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.