Re: Command-line interface thoughts

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

Re: Command-line interface thoughts

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:51:27

Michael Haggerty [off-list ref] 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.

Re: Command-line interface thoughts

From: Michael Haggerty <hidden>
Date: 2016-06-15 22:51:27

On 06/09/2011 08:38 PM, Junio C Hamano wrote:
Michael Haggerty [off-list ref] writes:
quoted
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/

Re: Command-line interface thoughts

From: Jeff King <hidden>
Date: 2016-06-15 22:51:27

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

Re: Command-line interface thoughts

From: Michael Haggerty <hidden>
Date: 2016-06-15 22:51:27

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/

Re: Command-line interface thoughts

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:51:27

On Thu, 9 Jan 2011, Michael Haggerty wrote:
On 06/09/2011 10:04 PM, Jeff King wrote:
quoted
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".
quoted
  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

Re: Command-line interface thoughts

From: Jeff King <hidden>
Date: 2016-06-15 22:51:27

On Thu, Jun 09, 2011 at 11:37:04PM +0200, Michael Haggerty wrote:
On 06/09/2011 10:04 PM, Jeff King wrote:
quoted
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

Re: Command-line interface thoughts

From: Michael Nahas <hidden>
Date: 2016-06-15 22:51:27

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 [off-list ref] wrote:
On 06/09/2011 10:04 PM, Jeff King wrote:
quoted
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
quoted
  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/

Re: Command-line interface thoughts

From: Jeff King <hidden>
Date: 2016-06-15 22:51:27

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

Re: Command-line interface thoughts

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:51:27

On Fri, 10 Jun 2011, Jeff King wrote:
On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:
quoted
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.
 
quoted
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.
quoted
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

Re: Command-line interface thoughts

From: Michael Haggerty <hidden>
Date: 2016-06-15 22:51:27

On 06/10/2011 12:04 AM, Jakub Narebski wrote:
On Thu, 9 Jan 2011, Michael Haggerty wrote:
quoted
On 06/09/2011 10:04 PM, Jeff King wrote:
quoted
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/

Re: Command-line interface thoughts

From: Michael Nahas <hidden>
Date: 2016-06-15 22:51:27

On Thu, Jun 9, 2011 at 6:38 PM, Jeff King [off-list ref] wrote:
On Thu, Jun 09, 2011 at 06:27:11PM -0400, Michael Nahas wrote:
quoted
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.

quoted
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.
quoted
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

Re: Command-line interface thoughts

From: Jeff King <hidden>
Date: 2016-06-15 22:51:27

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

Re: Command-line interface thoughts

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:51:27

On Fri, 10 Jun 2011, Michael Haggerty wrote:
On 06/10/2011 12:04 AM, Jakub Narebski wrote:
quoted
On Thu, 9 Jan 2011, Michael Haggerty wrote:
quoted
On 06/09/2011 10:04 PM, Jeff King wrote:
quoted
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
               ^^^^^^^^^^^^^^^^ -- ???
[...]
quoted
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...
 
quoted
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

Re: Command-line interface thoughts

From: Michael Nahas <hidden>
Date: 2016-06-15 22:51:27

'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.

Re: Command-line interface thoughts

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:51:27

On Fri, 10 Jul 2011, Michael Nahas wrote:
Jakub Narebski wrote:
quoted
'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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help