threads / patch / 6930

patchobject name: introduce ':::<oneline prefix>' notation

Subject: [PATCH] object name: introduce ':::<oneline prefix>' notation

## tl;dr

15 messages between Feb 23, 2007 and Feb 24, 2007. Diffs are folded; open one to read it.

replies: 14people: 4as markdown or json

Johannes Schindelin· Feb 23, 2007, 18:32 UTC · lore
To name a commit, you can now say
	git rev-parse ':::Initial revision of "git"'

and it will return the hash of the first youngest commit whose commit message (the oneline) begins with the given prefix.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
	I often do "git log --grep=bla" to find a certain commit, then 
	grab my mouse, mark the commit hash, and paste it into the command 
	line I really want to run on that commit.
	This allows me to throw away my mouse.
 sha1_name.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)
Show changes to sha1_name.c +50 −0
diff --git a/sha1_name.c b/sha1_name.c
index 2793de9..004c4e3 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -578,6 +578,54 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
 	return get_short_sha1(name, len, sha1, 0);
 }
 
+static int handle_one_ref(const char *path,
+		const unsigned char *sha1, int flag, void *cb_data)
+{
+	struct commit_list **list = cb_data;
+	struct object *object = parse_object(sha1);
+	if (!object)
+		return 0;
+	if (object->type == OBJ_TAG)
+		object = deref_tag(object, path, strlen(path));
+	if (object->type != OBJ_COMMIT)
+		return 0;
+	insert_by_date((struct commit *)object, list);
+	return 0;
+}
+
+/*
+ * This interprets names like ':::Initial revision of "git"' by searching
+ * through history and returning the first commit whose message starts
+ * with the given string.
+ */
+
+#define ONELINE_SEEN (1u<<20)
+int get_sha1_oneline(const char *prefix, unsigned char *sha1)
+{
+	struct commit_list *list = NULL, *backup = NULL, *l;
+	struct commit *commit;
+
+	if (!save_commit_buffer)
+		return error("Could not expand oneline-name.");
+	for_each_ref(handle_one_ref, &list);
+	for (l = list; l; l = l->next)
+		commit_list_insert(l->item, &backup);
+	while ((commit = pop_most_recent_commit(&list, ONELINE_SEEN))) {
+		char *p;
+		parse_object(commit->object.sha1);
+		if (!commit->buffer || !(p = strstr(commit->buffer, "\n\n")))
+			continue;
+		if (!prefixcmp(p + 2, prefix)) {
+			hashcpy(sha1, commit->object.sha1);
+			break;
+		}
+	}
+	free_commit_list(list);
+	for (l = backup; l; l = l->next)
+		clear_commit_marks(l->item, ONELINE_SEEN);
+	return commit == NULL;
+}
+
 /*
  * This is like "get_sha1_basic()", except it allows "sha1 expressions",
  * notably "xyz^" for "parent of xyz"
@@ -601,6 +649,8 @@ int get_sha1(const char *name, unsigned char *sha1)
 		int stage = 0;
 		struct cache_entry *ce = NULL;
 		int pos;
+		if (namelen > 3 && !prefixcmp(name + 1, "::"))
+			return get_sha1_oneline(name + 3, sha1);
 		if (namelen < 3 ||
 		    name[2] != ':' ||
 		    name[1] < '0' || '3' < name[1])
-- 
1.5.0.1.2246.geaab8-dirty
Johannes Schindelin· Feb 23, 2007, 22:48 UTC · re: Johannes Schindelin · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Hi,
On Fri, 23 Feb 2007, Johannes Schindelin wrote:
> To name a commit, you can now say
> 
> 	git rev-parse ':::Initial revision of "git"'

Alex Riesen and Shawn Pearce suggested ":/" instead of ":::", to reflect the searching nature ("/" is the key to search in "less" output).

Comments?

Ciao, Dscho

Jeff King· Feb 24, 2007, 01:12 UTC · re: Johannes Schindelin · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

On Fri, Feb 23, 2007 at 11:48:38PM +0100, Johannes Schindelin wrote:
Show 6 quoted lines
> > To name a commit, you can now say
> > 
> > 	git rev-parse ':::Initial revision of "git"'
> 
> Alex Riesen and Shawn Pearce suggested ":/" instead of ":::", to reflect 
> the searching nature ("/" is the key to search in "less" output).

Is there a particular argument for using a special syntax in the commit argument? Why not just add a '--grep' or similar option to indicate that we will be grepping the commits logs?

-Peff
Johannes Schindelin· Feb 24, 2007, 01:21 UTC · re: Jeff King · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Hi,
On Fri, 23 Feb 2007, Jeff King wrote:
Show 13 quoted lines
> On Fri, Feb 23, 2007 at 11:48:38PM +0100, Johannes Schindelin wrote:
> 
> > > To name a commit, you can now say
> > > 
> > > 	git rev-parse ':::Initial revision of "git"'
> > 
> > Alex Riesen and Shawn Pearce suggested ":/" instead of ":::", to 
> > reflect the searching nature ("/" is the key to search in "less" 
> > output).
> 
> Is there a particular argument for using a special syntax in the commit 
> argument? Why not just add a '--grep' or similar option to indicate that 
> we will be grepping the commits logs?

--grep works with git-log, but not with rev-parse, rev-list, show, diff, etc.

Ciao, Dscho

Jeff King· Feb 24, 2007, 01:30 UTC · re: Johannes Schindelin · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

I said:
> > > Alex Riesen and Shawn Pearce suggested ":/" instead of ":::", to 
> > argument? Why not just add a '--grep' or similar option to indicate that 

Hmm, I completely misread your patch comments in the first place, so forget my suggestion; it obviously needs to be a per-committish indicator, not a per-command flag.

I think :/ is slightly easier on the eyes than :::. Plus it opens the door for :? to find the oldest such match (though I'm not sure if it would be by topology or date).

Of course it's starting to look a bit like line noise...maybe we just need :-/ and :-).

-Peff
Johannes Schindelin· Feb 24, 2007, 01:49 UTC · re: Jeff King · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Hi,
On Fri, 23 Feb 2007, Jeff King wrote:
> I think :/ is slightly easier on the eyes than :::. Plus it opens the 
> door for :? to find the oldest such match (though I'm not sure if it 
> would be by topology or date).
By topology makes no sense with more than one root.
> Of course it's starting to look a bit like line noise...maybe we just 
> need :-/ and :-).
That was also a suggestion in IRC :-)

Ciao, Dscho

Jeff King· Feb 24, 2007, 01:57 UTC · re: Johannes Schindelin · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

On Sat, Feb 24, 2007 at 02:49:31AM +0100, Johannes Schindelin wrote:
> > door for :? to find the oldest such match (though I'm not sure if it 
> > would be by topology or date).
> By topology makes no sense with more than one root.

Agreed, but by date might not make sense if you have clock skew. I had assumed your patch for "youngest" was by distance to ref, but I suppose that doesn't make sense if you are looking over a set of possibly unconnected refs. So I think trusting the clock may be the only sensible thing.

-Peff
Johannes Schindelin· Feb 24, 2007, 02:14 UTC · re: Jeff King · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Hi,
On Fri, 23 Feb 2007, Jeff King wrote:
Show 12 quoted lines
> On Sat, Feb 24, 2007 at 02:49:31AM +0100, Johannes Schindelin wrote:
> 
> > > door for :? to find the oldest such match (though I'm not sure if it 
> > > would be by topology or date).
> >
> > By topology makes no sense with more than one root.
> 
> Agreed, but by date might not make sense if you have clock skew. I had 
> assumed your patch for "youngest" was by distance to ref, but I suppose 
> that doesn't make sense if you are looking over a set of possibly 
> unconnected refs. So I think trusting the clock may be the only sensible 
> thing.

Given that most commits _will_ have a unique oneline, I think it does not matter that much. After all, the principal use case I see for it is finding a commit, given a shortlog, or a mail subject, or even a sentence muttered over the phone.

Ciao, Dscho

Jeff King· Feb 24, 2007, 02:15 UTC · re: Johannes Schindelin · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

On Sat, Feb 24, 2007 at 03:14:11AM +0100, Johannes Schindelin wrote:
> Given that most commits _will_ have a unique oneline, I think it does not 
> matter that much. After all, the principal use case I see for it is 
> finding a commit, given a shortlog, or a mail subject, or even a sentence 
> muttered over the phone.

Fair enough. If you have something ambiguous, looking through 'git log' output is probably more sane anyway. Color me convinced.

-Peff
Nicolas Pitre· Feb 24, 2007, 01:53 UTC · re: Jeff King · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

On Fri, 23 Feb 2007, Jeff King wrote:
Show 6 quoted lines
> I think :/ is slightly easier on the eyes than :::. Plus it opens the
> door for :? to find the oldest such match (though I'm not sure if it
> would be by topology or date).
> 
> Of course it's starting to look a bit like line noise...maybe we just
> need :-/ and :-).
LOL!  ;-D

I was looking at that :/!!P=(blah) and my yuck-o-meter was going up quickly. But I'd use :-) anytime!

Nicolas
Junio C Hamano· Feb 24, 2007, 01:18 UTC · re: Johannes Schindelin · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Show 10 quoted lines
> On Fri, 23 Feb 2007, Johannes Schindelin wrote:
>
>> To name a commit, you can now say
>> 
>> 	git rev-parse ':::Initial revision of "git"'
>
> Alex Riesen and Shawn Pearce suggested ":/" instead of ":::", to reflect 
> the searching nature ("/" is the key to search in "less" output).
>
> Comments?

Sounds good. "git show :/path" does not currently mean "find /path in the index", so I do not see offhand it would interfere with anything.

However, it would be worthwhile to plant an escape hatch for future extension. Using short-and-sweet ":/" for the most common case such as exact prefix match would be fine, but we might want to say:

	':/!' syntax is reserved for future extension and does
	not look for a string that begins with "!".
	one extension "do not do anything special" is defined
	and is spelled as "!!" - so if you want to look for a
	commit that begins with "!something", please spell it
	as ':/!!something'
or something like that.
Obvious extension possibilities include:
	":/!(r=regexp)"
        ":/!(a=author)"
	":/!(d=2001-09-17)"
	":/!(p=Documentation/)"
or various combination of them e.g.
	":!(p=Documentation/)!(a=Johannes)Update command list"

to look for a commit by Johannes that touches Documentation/ area and oneline begins with "Update command list".

By the way, where do you start digging from?  From all refs?
Johannes Schindelin· Feb 24, 2007, 01:35 UTC · re: Junio C Hamano · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Hi,
On Fri, 23 Feb 2007, Junio C Hamano wrote:
Show 15 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > On Fri, 23 Feb 2007, Johannes Schindelin wrote:
> >
> >> To name a commit, you can now say
> >> 
> >> 	git rev-parse ':::Initial revision of "git"'
> >
> > Alex Riesen and Shawn Pearce suggested ":/" instead of ":::", to reflect 
> > the searching nature ("/" is the key to search in "less" output).
> >
> > Comments?
> 
> Sounds good.  "git show :/path" does not currently mean "find /path in 
> the index", so I do not see offhand it would interfere with anything.
That's also what Shawn said.
Show 6 quoted lines
> However, it would be worthwhile to plant an escape hatch for future 
> extension.  Using short-and-sweet ":/" for the most common case such as 
> exact prefix match would be fine, but we might want to say:
> 
> 	':/!' syntax is reserved for future extension and does
> 	not look for a string that begins with "!".
Okay. Will rework.
Show 10 quoted lines
> Obvious extension possibilities include:
> 
> 	":/!(r=regexp)"
>         ":/!(a=author)"
> 	":/!(d=2001-09-17)"
> 	":/!(p=Documentation/)"
> 
> or various combination of them e.g.
> 
> 	":!(p=Documentation/)!(a=Johannes)Update command list"
They are much harder to implement. So I'll leave that to others :-)
> By the way, where do you start digging from?  From all refs?
Yes, all refs. In order of the date.

Ciao, Dscho

Junio C Hamano· Feb 24, 2007, 01:46 UTC · re: Johannes Schindelin · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> By the way, where do you start digging from?  From all refs?
>
> Yes, all refs. In order of the date.

Then, another possibly useful extension is "start from this ref" (you can give multiple and if no such refs are given keep the current "from all refs" behaviour).

Nicolas Pitre· Feb 24, 2007, 01:56 UTC · re: Junio C Hamano · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

On Fri, 23 Feb 2007, Junio C Hamano wrote:
Show 9 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> >> By the way, where do you start digging from?  From all refs?
> >
> > Yes, all refs. In order of the date.
> 
> Then, another possibly useful extension is "start from this ref"
> (you can give multiple and if no such refs are given keep the
> current "from all refs" behaviour).
Can we generalize the syntax a bit more instead?
What about HEAD:/blah ?
Nicolas
Johannes Schindelin· Feb 24, 2007, 02:10 UTC · re: Nicolas Pitre · lore

Re: [PATCH] object name: introduce ':::<oneline prefix>' notation

Hi,
On Fri, 23 Feb 2007, Nicolas Pitre wrote:
Show 15 quoted lines
> On Fri, 23 Feb 2007, Junio C Hamano wrote:
> 
> > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> > 
> > >> By the way, where do you start digging from?  From all refs?
> > >
> > > Yes, all refs. In order of the date.
> > 
> > Then, another possibly useful extension is "start from this ref"
> > (you can give multiple and if no such refs are given keep the
> > current "from all refs" behaviour).
> 
> Can we generalize the syntax a bit more instead?
> 
> What about HEAD:/blah ?
I'd expect this to do the same as HEAD:blah

Ciao, Dscho

← back to recent threads