* [PATCH/RFC] get_sha1: allow users to extend ..^{%..} syntax
@ 2010-12-22 15:33 Nguyễn Thái Ngọc Duy
0 siblings, 0 replies; only message in thread
From: Nguyễn Thái Ngọc Duy @ 2010-12-22 15:33 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This allows users to add abitrary sth^{%foo} syntax that translates
from an SHA-1 to another SHA-1, where "foo" refers to an alias
"sha1-foo" or "foo". If either is found, %sha1% in the alias will be
replaced with SHA-1 of "sth". The alias command is supposed to print
translated SHA-1 to stdout.
Another syntax is sth^{%foo:args} where %arg% in the alias will be
replaced with "args" from the syntax. This gives users much more
flexibilty in extending SHA-1 syntax. I'm not sure if I should support
multiple arguments though.
My mind is still with the :/ syntax. So as an example,
git config alias.sha1-topic 'rev-list --merges --grep=%arg% --max-count=1 %sha1%'
git rev-parse origin/pu^{%topic:nd/struct-pathspec}
would give me sha-1 of my topic. This is supposed to be faster than
standard :/ syntax because it only searches merges. I can also make it
more accurate to my liking by adjust --grep= freely. Unfortunately
git-rev-list takes ~1 sec to run. Maybe I can detect rev-list command
and run it internally without run_command().
The intention is that a similar syntax can be used for branch
translation too, i.e ref@{%...}.
One of the rising issues is that every time this syntax is evaluated,
external process will be run again. Some cache might help. I should
also take alias code out of git.c for reuse here.
So comments? (This patch looks bad, I know)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
sha1_name.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/sha1_name.c b/sha1_name.c
index c5c59ce..6b40cec 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -6,6 +6,7 @@
#include "tree-walk.h"
#include "refs.h"
#include "remote.h"
+#include "run-command.h"
static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);
@@ -529,6 +530,86 @@ struct object *peel_to_type(const char *name, int namelen,
}
}
+static int peel_alias_onion(const char *name, int len, const char *sp,
+ unsigned char *sha1)
+{
+ int alias_len;
+ struct strbuf sb = STRBUF_INIT;
+ struct strbuf cmd = STRBUF_INIT;
+ struct child_process cp;
+ const char **argv;
+ int count, hex_len;
+ char *s, *arg;
+ char hex[40];
+
+ len--; /* remove the last '}' */
+ arg = strchr(sp, ':');
+ if (arg)
+ alias_len = arg - sp;
+ else
+ alias_len = len - (sp - name);
+ strbuf_add(&sb, "sha1-", 5);
+ strbuf_add(&sb, sp, alias_len);
+ s = alias_lookup(sb.buf);
+ if (!s) {
+ strbuf_reset(&sb);
+ strbuf_add(&sb, sp, alias_len);
+ s = alias_lookup(sb.buf);
+ }
+ strbuf_release(&sb);
+ if (!s)
+ return error("unable to find alias for %s", name);
+
+ strbuf_attach(&cmd, s, strlen(s), strlen(s)+1);
+ s = strstr(cmd.buf, "%sha1%");
+ if (!s) {
+ error("%%sha1%% not found, not an sha1 alias:\n%s", cmd.buf);
+ strbuf_release(&cmd);
+ return -1;
+ }
+ strbuf_splice(&cmd, s - cmd.buf, 6, sha1_to_hex(sha1), 40);
+ if (arg) {
+ int arg_len = len - (++arg - name);
+ s = strstr(cmd.buf, "%arg%");
+ if (!s) {
+ error("%%arg%% not found, not an sha1 alias:\n%s", cmd.buf);
+ strbuf_release(&cmd);
+ return -1;
+ }
+ strbuf_splice(&cmd, s - cmd.buf, 5, arg, arg_len);
+ }
+
+ count = split_cmdline(cmd.buf, &argv);
+ if (count < 0) {
+ error("Bad alias.%s string: %s", cmd.buf, split_cmdline_strerror(count));
+ strbuf_release(&cmd);
+ return -1;
+ }
+
+ memset(&cp, 0, sizeof(cp));
+ cp.git_cmd = 1;
+ cp.in = 0;
+ cp.out = -1;
+ cp.argv = argv;
+ trace_argv_printf(argv, "trace: sha1 alias expansion: %s =>", cmd.buf);
+ if (start_command(&cp)) {
+ error("Failed to run %s", cmd.buf);
+ strbuf_release(&cmd);
+ return -1;
+ }
+ hex_len = xread(cp.out, hex, 40);
+ close(cp.out);
+ if (finish_command(&cp)) {
+ error("Failed to finish %s", cmd.buf);
+ strbuf_release(&cmd);
+ return -1;
+ }
+ strbuf_release(&cmd);
+ if (hex_len != 40 || get_sha1_hex(hex, sha1))
+ return error("failed to get result SHA-1 from ...%s", sp-3);
+ return 0;
+}
+
static int peel_onion(const char *name, int len, unsigned char *sha1)
{
unsigned char outer[20];
@@ -566,6 +647,12 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
expected_type = OBJ_NONE;
else if (sp[0] == '/')
expected_type = OBJ_COMMIT;
+ else if (sp[0] == '%') {
+ if (get_sha1_1(name, sp - name - 2, outer))
+ return -1;
+ hashcpy(sha1, outer);
+ return peel_alias_onion(name, len, sp + 1, sha1);
+ }
else
return -1;
--
1.7.3.3.476.g10a82
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2010-12-22 15:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-22 15:33 [PATCH/RFC] get_sha1: allow users to extend ..^{%..} syntax Nguyễn Thái Ngọc Duy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).