Subject: Re: [PATCH] Document what the stage numbers in the :$n:path syntax mean.

From: Jeff King <[email-masked]>
Date: Mon, 20 Aug 2007 01:52:21 -0400

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(-)

diff --git a/sha1_name.c b/sha1_name.c
index 2d727d5..eaa6bd7 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -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 -> 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
 	 */
 	if (name[0] == ':') {
 		int stage = 0;
@@ -671,14 +672,36 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
 		int pos;
 		if (namelen > 2 && name[1] == '/')
 			return get_sha1_oneline(name + 2, sha1);
-		if (namelen < 3 ||
-		    name[2] != ':' ||
-		    name[1] < '0' || '3' < name[1])
-			cp = name + 1;
-		else {
-			stage = name[1] - '0';
+		if (!strncmp(name+1, "0:", 2)) {
+			stage = 0;
+			cp = name + 3;
+		}
+		else if (!strncmp(name+1, "1:", 2)) {
+			stage = 1;
+			cp = name + 3;
+		}
+		else if (!strncmp(name+1, "base:", 5)) {
+			stage = 1;
+			cp = name + 6;
+		}
+		else if (!strncmp(name+1, "2:", 2)) {
+			stage = 2;
 			cp = name + 3;
 		}
+		else if (!strncmp(name+1, "ours:", 5)) {
+			stage = 2;
+			cp = name + 6;
+		}
+		else if (!strncmp(name+1, "3:", 2)) {
+			stage = 3;
+			cp = name + 3;
+		}
+		else if (!strncmp(name+1, "theirs:", 7)) {
+			stage = 3;
+			cp = name + 8;
+		}
+		else
+			cp = name + 1;
 		namelen = namelen - (cp - name);
 		if (!active_cache)
 			read_cache();