Git development
 help / color / mirror / Atom feed
* [PATCH] object name: introduce ':::<oneline prefix>' notation
@ 2007-02-23 18:32 Johannes Schindelin
  2007-02-23 22:48 ` Johannes Schindelin
  0 siblings, 1 reply; 15+ messages in thread
From: Johannes Schindelin @ 2007-02-23 18:32 UTC (permalink / raw)
  To: git, junkio


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

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

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

end of thread, other threads:[~2007-02-24  2:15 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-23 18:32 [PATCH] object name: introduce ':::<oneline prefix>' notation Johannes Schindelin
2007-02-23 22:48 ` Johannes Schindelin
2007-02-24  1:12   ` Jeff King
2007-02-24  1:21     ` Johannes Schindelin
2007-02-24  1:30       ` Jeff King
2007-02-24  1:49         ` Johannes Schindelin
2007-02-24  1:57           ` Jeff King
2007-02-24  2:14             ` Johannes Schindelin
2007-02-24  2:15               ` Jeff King
2007-02-24  1:53         ` Nicolas Pitre
2007-02-24  1:18   ` Junio C Hamano
2007-02-24  1:35     ` Johannes Schindelin
2007-02-24  1:46       ` Junio C Hamano
2007-02-24  1:56         ` Nicolas Pitre
2007-02-24  2:10           ` Johannes Schindelin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox