People should learn this command. Really.
$ git cat-file -p :$n:path
where $n == 2 is ours, $n == 1 is common ancestor, and $n == 3
is theirs.
A question related to this: as a user, how can I tell if a command
is something I'm expected to use, or if thinking I need it is a
sign that I'm doing something wrong?
Git has many commands, and telling the business-as-usual apart from
the deviant ones is not always easy. It may be that it's just a question
of knowing what is plumbing and what is a porcelain, but I'm not sure.
Cheers,
-- Nikodemus
From: Steven Grimm <hidden> Date: 2016-06-15 22:43:29
Junio C Hamano wrote:
> People should learn this command. Really.
>
> $ git cat-file -p :$n:path
>
> where $n == 2 is ours, $n == 1 is common ancestor, and $n == 3
> is theirs.
The git-rev-parse manpage talks about the :$n:path notation (buried deep in
a list of other syntax) but it just says $n is a "stage number" -- someone
who is not familiar with the internals of git's merge implementation is
never going to be able to figure out that "1", "2", and "3" mean what Junio
said.
---
Not sure if this is correct for octopus merges -- corrections welcome.
Documentation/git-rev-parse.txt | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-rev-parse.txt
b/Documentation/git-rev-parse.txt
index 4b4d229..4758c33 100644
@@ -215,7 +215,10 @@ blobs contained in a commit. * A colon, optionally followed by a stage number (0 to 3) and a colon, followed by a path; this names a blob object in the index at the given path. Missing stage number (and the colon- that follows it) names an stage 0 entry.+ that follows it) names an stage 0 entry. During a merge, stage+ 1 is the common ancestor, stage 2 is the target branch's version+ (typically the current branch), and stage 3 is the version from+ the branch being merged. Here is an illustration, by Jon Loeliger. Both node B and C are a commit parents of commit node A. Parent commits are ordered
From: Jeff King <hidden> Date: 2016-06-15 22:43:29
On Mon, Aug 20, 2007 at 11:36:38AM +0800, Steven Grimm wrote:
The git-rev-parse manpage talks about the :$n:path notation (buried deep in
a list of other syntax) but it just says $n is a "stage number" -- someone
who is not familiar with the internals of git's merge implementation is
never going to be able to figure out that "1", "2", and "3" mean what Junio
said.
I often forget which number corresponds to which source. I seem to
recall somebody proposing :ours:$path a while ago, but I couldn't find
any reference in the archive, so perhaps I just dreamed it.
Am I the only one who messes this up? If not, patch is below.
-- >8 --
sha1_name: allow human-readable stage aliases
This adds the alias ":ours:$path" to mean the same thing as ":2:$path",
as well as "base" (for 1) and "theirs" (for 2), for those of us who
merge infrequently and forget which is which.
The parsing is as strict as possible in order to minimize impact on
filenames with colons. However, for some (presumably unlikely)
filenames, the behavior is changed. Previously, you could look at stage
0 of any file beginning with the string "ours:" as simply "git-show
:ours:foo". Now, because of the parsing conflict, you must use "git-show
:0:ours:foo".
---
sha1_name.c | 35 +++++++++++++++++++++++++++++------
1 files changed, 29 insertions(+), 6 deletions(-)
@@ -664,6 +664,7 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)/* sha1:path --> object name of path in ent sha1*:path->objectnameofpathinindex*:[0-3]:path->objectnameofpathinindexatstage+*:base|ours|theirs:path->sameas:[1-3]:path*/if(name[0]==':'){intstage=0;
From: Shawn O. Pearce <hidden> Date: 2016-06-15 22:43:29
Jeff King [off-list ref] wrote:
On Mon, Aug 20, 2007 at 11:36:38AM +0800, Steven Grimm wrote:
quoted
The git-rev-parse manpage talks about the :$n:path notation (buried deep in
a list of other syntax) but it just says $n is a "stage number" -- someone
who is not familiar with the internals of git's merge implementation is
never going to be able to figure out that "1", "2", and "3" mean what Junio
said.
I often forget which number corresponds to which source. I seem to
recall somebody proposing :ours:$path a while ago, but I couldn't find
any reference in the archive, so perhaps I just dreamed it.
Am I the only one who messes this up? If not, patch is below.
Maybe. ;-)
I've memorized it long long ago. But my coworkers haven't and always
get it wrong, and look at me funny when I tell them "trust me, your
data is in stage 2 and theirs is in stage 3... because that's the
convention all of the tools you are using follows".
Keywords in that last part: "convention" and "tools you are using".
Someone could redefine what the stages mean and load content into
them using `update index --index-info`. You might even be able to
load the stages in odd ways yourself from Porcelain.
Oh, like say git-rebase. During a rebase "theirs" (stage 3) is
your file and "ours" (stage 2) is the upstream. Confusing now,
ain't it? Mine is theirs and ours is theirs? Huh? Yeeaaaah.
This is why I've never liked most merge tools. They get hung up on
what is theirs and what is mine and then at some point they wind up
confusing the stages and getting them inverted. And this is exactly
why git-merge.sh/git-rebase.sh/git-am.sh try to setup GITHEAD_* for
git-merge-recursive, and why they set it up using branch names and
patch subject lines, because it makes the conflict markers easier
to understand.
/* sha1:path --> object name of path in ent sha1
* :path -> object name of path in index
* :[0-3]:path -> object name of path in index at stage
+ * :base|ours|theirs:path -> same as :[1-3]:path
*/
At least document the new syntax in git-rev-parse documentation?
--
Shawn.
From: Shawn O. Pearce <hidden> Date: 2016-06-15 22:43:29
"Shawn O. Pearce" [off-list ref] wrote:
Jeff King [off-list ref] wrote:
quoted
On Mon, Aug 20, 2007 at 11:36:38AM +0800, Steven Grimm wrote:
quoted
The git-rev-parse manpage talks about the :$n:path notation (buried deep in
a list of other syntax) but it just says $n is a "stage number" -- someone
who is not familiar with the internals of git's merge implementation is
never going to be able to figure out that "1", "2", and "3" mean what Junio
said.
I often forget which number corresponds to which source. I seem to
recall somebody proposing :ours:$path a while ago, but I couldn't find
any reference in the archive, so perhaps I just dreamed it.
Am I the only one who messes this up? If not, patch is below.
Maybe. ;-)
I've memorized it long long ago. But my coworkers haven't and always
get it wrong, and look at me funny when I tell them "trust me, your
data is in stage 2 and theirs is in stage 3... because that's the
convention all of the tools you are using follows".
Actually, what's wrong with the following:
git show HEAD:foo.c
git show MERGE_HEAD:foo.c
?
That gives you yours (HEAD) and theirs (MERGE_HEAD). And it doesn't
abuse sha1_file.c. Granted it only works during a true merge and
doesn't work during a rebase, but remember I just pointed out life
is backwards anyway during a rebase, so uh, yea...
--
Shawn.
From: Jeff King <hidden> Date: 2016-06-15 22:43:29
On Mon, Aug 20, 2007 at 02:05:22AM -0400, Shawn O. Pearce wrote:
Oh, like say git-rebase. During a rebase "theirs" (stage 3) is
your file and "ours" (stage 2) is the upstream. Confusing now,
ain't it? Mine is theirs and ours is theirs? Huh? Yeeaaaah.
Ugh, I hadn't even thought of that. git-diff _does_ respect "--base",
"--ours", and "--theirs" to mean the same thing, but I am now wondering
if that is a bit of a mistake.
However, as the intent of my patch was to _increase_ usability, I think
a gotcha like that is probably counterproductive. OTOH, users of
git-rebase already have to make the switch mentally.
confusing the stages and getting them inverted. And this is exactly
why git-merge.sh/git-rebase.sh/git-am.sh try to setup GITHEAD_* for
Yes, I agree that the GITHEAD markers are much more sensible.
Unfortunately, I'm not sure of the best way to translate them into
stage names. The MERGE_HEAD/HEAD suggestion you made is a nice way of
avoiding the whole issue, though it doesn't easily provide the "base"
version.
At least document the new syntax in git-rev-parse documentation?
I was about to, but your message has convinced me that this is perhaps
not a very good idea.
-Peff