{"thread":{"id":"44921","subject":"[PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","startedAt":"2017-01-20T10:31:22Z","lastAt":"2017-02-05T22:46:02Z","messageCount":12,"participants":["Nguyễn Thái Ngọc Duy","Johannes Schindelin","Duy Nguyen","Jeff King","Junio C Hamano","Jacob Keller"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"309814","messageId":"20170120102249.15572-1-pclouds@gmail.com","threadId":"44921","inReplyTo":null,"subject":"[PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-20T10:22:49Z","receivedAt":"2017-01-20T10:31:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"OK This patch is horrible. Though the idea is cool and I've found it\nvery useful. So here it is. Perhaps the idea may be revised a bit\nthat's more suitable for more than one user.\n\nThe problem is old, SHA-1 name is not keyboard-friendly, even in\nabbreviated form. And recent change has made abbrev form longer,\nharder to type. Most of the time I just go with copy/paste with the\nmouse, which I don't like. name-rev helps a bit, but it's still long\nto type (especially with all the ^ and ~ that requires holding shift\ndown).\n\nSo, this patch adds an option --mark-commits to git-log. Whenever a\ncommit SHA-1 is printed on screen, it gets a new shortcut in form of\n<at-sign><one-letter><number> e.g. @h2. The number keeps increasing\nduring one git-log, so you'll get @h1, @h2, @h3 and so on. Typing @h3\ngets you back to the associated SHA-1.\n\nDifferent git-log runs will change the <one-letter> part. So the\nsecond git-log run may give you @j1, @j2, @j3... This is useful\nbecause sometimes you want to run more than one command, then\nreference back to commits from the first command.\n\nThere's a limited number of letters to be used here. I limit it to the\nletters on the home row to avoid moving fingers too much. Which means\nafter like 9 runs, @h is recycled for something new. Not great if you\nhave \"git blah blah @h2\" in bash history and keep recalling it from\ntime to time.\n\nSo, whenever you use a shortcut, the shortcut is kept in a \"database\"\nand will not be recycled for quite some time. When @h is recycled,\nyou'll get @h1, then @h3 and so on if @h2 has just been used recently.\nThis makes sure recently used shortcuts live on.\n\nThat's it. I have to say typing 3-4 characters is really nice. I kinda\nwant to reduce the number of keystokes further down, but it's been good\nenough that I'm not so pissed to spend time tuning it further.\n\nThis shortcut format violates the extended sha1 syntax, I think. In\norder have any chance of entering git, we'll have to deal with that\nfirst.\n\n---\n Makefile            |   1 +\n commit.h            |   1 +\n log-tree.c          |   7 +++\n pretty.c            |   5 ++\n rev-counter.c (new) | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n rev-counter.h (new) |  10 ++++\n revision.c          |   4 ++\n revision.h          |   1 +\n sha1_name.c         |   8 +++\n 9 files changed, 203 insertions(+)\n create mode 100644 rev-counter.c\n create mode 100644 rev-counter.h\n\ndiff --git a/Makefile b/Makefile\nindex de5a030256..28948bd9eb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -788,6 +788,7 @@ LIB_OBJS += replace_object.o\n LIB_OBJS += rerere.o\n LIB_OBJS += resolve-undo.o\n LIB_OBJS += revision.o\n+LIB_OBJS += rev-counter.o\n LIB_OBJS += run-command.o\n LIB_OBJS += send-pack.o\n LIB_OBJS += sequencer.o\ndiff --git a/commit.h b/commit.h\nindex b06db4d5d9..8f67687208 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -155,6 +155,7 @@ struct pretty_print_context {\n \tstruct string_list *mailmap;\n \tint color;\n \tstruct ident_split *from_ident;\n+\tint mark_commits;\n \n \t/*\n \t * Fields below here are manipulated internally by pp_* functions and\ndiff --git a/log-tree.c b/log-tree.c\nindex 78a5381d0e..f49366b376 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -11,6 +11,7 @@\n #include \"gpg-interface.h\"\n #include \"sequencer.h\"\n #include \"line-log.h\"\n+#include \"rev-counter.h\"\n \n static struct decoration name_decoration = { \"object names\" };\n static int decoration_loaded;\n@@ -593,6 +594,9 @@ void show_log(struct rev_info *opt)\n \t}\n \topt->shown_one = 1;\n \n+\tif (opt->mark_commits)\n+\t\tmark_commit(&commit->object.oid);\n+\n \t/*\n \t * If the history graph was requested,\n \t * print the graph, up to this commit's line\n@@ -615,6 +619,8 @@ void show_log(struct rev_info *opt)\n \t\t\tput_revision_mark(opt, commit);\n \t\tfputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit),\n \t\t      stdout);\n+\t\tif (opt->mark_commits)\n+\t\t\tprintf(\" @%s\", oid_to_commit_mark(&commit->object.oid));\n \t\tif (opt->print_parents)\n \t\t\tshow_parents(commit, abbrev_commit);\n \t\tif (opt->children.name)\n@@ -687,6 +693,7 @@ void show_log(struct rev_info *opt)\n \tctx.output_encoding = get_log_output_encoding();\n \tif (opt->from_ident.mail_begin && opt->from_ident.name_begin)\n \t\tctx.from_ident = &opt->from_ident;\n+\tctx.mark_commits = opt->mark_commits;\n \tpretty_print_commit(&ctx, commit, &msgbuf);\n \n \tif (opt->add_signoff)\ndiff --git a/pretty.c b/pretty.c\nindex c3ec430220..14e0022085 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -10,6 +10,7 @@\n #include \"color.h\"\n #include \"reflog-walk.h\"\n #include \"gpg-interface.h\"\n+#include \"rev-counter.h\"\n \n static char *user_format;\n static struct cmt_fmt_map {\n@@ -1127,6 +1128,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */\n \tcase 'H':\t\t/* commit hash */\n \t\tstrbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));\n \t\tstrbuf_addstr(sb, oid_to_hex(&commit->object.oid));\n+\t\tif (c->pretty_ctx->mark_commits)\n+\t\t\tstrbuf_addf(sb, \" @%s\", oid_to_commit_mark(&commit->object.oid));\n \t\tstrbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));\n \t\treturn 1;\n \tcase 'h':\t\t/* abbreviated commit hash */\n@@ -1137,6 +1140,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */\n \t\t}\n \t\tstrbuf_addstr(sb, find_unique_abbrev(commit->object.oid.hash,\n \t\t\t\t\t\t     c->pretty_ctx->abbrev));\n+\t\tif (c->pretty_ctx->mark_commits)\n+\t\t\tstrbuf_addf(sb, \" @%s\", oid_to_commit_mark(&commit->object.oid));\n \t\tstrbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));\n \t\tc->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;\n \t\treturn 1;\ndiff --git a/rev-counter.c b/rev-counter.c\nnew file mode 100644\nindex 0000000000..60ab991fe1\n--- /dev/null\n+++ b/rev-counter.c\n@@ -0,0 +1,166 @@\n+#include \"cache.h\"\n+#include \"strbuf.h\"\n+#include \"commit.h\"\n+#include \"commit-slab.h\"\n+\n+define_commit_slab(counter, char *);\n+struct counter counter = COMMIT_SLAB_INIT(1, counter);\n+\n+static unsigned commit_counter;\n+static int run_counter;\n+int latest_fd = -1;\n+struct strbuf recent = STRBUF_INIT;\n+\n+/* home row, except 'l' which looks too much like '1' */\n+const char *starter = \"asdfghjk\";\n+\n+static void start_marking(void)\n+{\n+\tchar buf[64];\n+\tssize_t len;\n+\n+\tlen = readlink(git_path(\"rev-counter/latest\"), buf, sizeof(buf));\n+\tif (len == -1) {\n+\t\tif (errno != ENOENT)\n+\t\t\tdie_errno(\"failed to open rev-counter/latest\");\n+\t} else {\n+\t\tchar ch, *p;\n+\t\tsscanf(buf, \"%c\", &ch);\n+\t\tp = strchrnul(starter, ch);\n+\t\trun_counter = ((p - starter) + 1) % strlen(starter);\n+\t}\n+\n+\tif (!is_directory(git_path(\"rev-counter\")))\n+\t\tmkdir(git_path(\"rev-counter\"), 0755);\n+\tlatest_fd = open(git_path(\"rev-counter/%c\", starter[run_counter]),\n+\t\t\t O_RDWR | O_CREAT | O_TRUNC, 0644);\n+\tif (latest_fd == -1)\n+\t\tdie_errno(\"failed to create new rev-counter\");\n+\n+\tsprintf(buf, \"%c\", starter[run_counter]);\n+\t(void)unlink(git_path(\"rev-counter/latest\"));\n+\tif (symlink(buf, git_path(\"rev-counter/latest\")))\n+\t\tdie_errno(\"failed to update rev-counter/latest\");\n+}\n+\n+static int strbuf_find_commit_mark(const struct strbuf *sb,\n+\t\t\t\t   const char *mark,\n+\t\t\t\t   struct object_id *oid)\n+{\n+\tconst char *p, *end;\n+\tint ret = -1;\n+\n+\tend = sb->buf + sb->len;\n+\tp = sb->buf;\n+\twhile (p < end && ret < 0) {\n+\t\tconst char *next = strchrnul(p, '\\n');\n+\n+\t\tif (next - p > 41 &&\n+\t\t    p[40] == ' ' &&\n+\t\t    p + 41 + strlen(mark) == next &&\n+\t\t    !strncmp(p + 41, mark, strlen(mark)) &&\n+\t\t    !get_oid_hex(p, oid))\n+\t\t\tret = 0;\n+\n+\t\tp = next;\n+\t\tif (*p == '\\n')\n+\t\t\tp++;\n+\t}\n+\treturn ret;\n+}\n+\n+void update_commit_counter(void)\n+{\n+\tstatic int read_recent;\n+\tstruct object_id oid;\n+\tchar buf[16];\n+\n+\tif (!read_recent) {\n+\t\tstrbuf_read_file(&recent, git_path(\"rev-counter/recent\"), 0);\n+\t\tread_recent = 1;\n+\n+\t\tif (recent.len > 1000 * 45) { /* prune time? */\n+\t\t\tint fd;\n+\t\t\tconst char *p = strchr(recent.buf + 1000 * 45, '\\n');\n+\t\t\tstrbuf_remove(&recent, 0, p + 1 - recent.buf);\n+\t\t\tif (!is_directory(git_path(\"rev-counter\")))\n+\t\t\t\tmkdir(git_path(\"rev-counter\"), 0755);\n+\t\t\tfd = open(git_path(\"rev-counter/recent\"),\n+\t\t\t\t  O_CREAT | O_TRUNC | O_RDWR, 0644);\n+\t\t\twrite_or_die(fd, recent.buf, recent.len);\n+\t\t\tclose(fd);\n+\t\t}\n+\t}\n+\n+\tdo {\n+\t\tcommit_counter++;\n+\t\tsprintf(buf, \"%c%u\", starter[run_counter], commit_counter);\n+\t} while (!strbuf_find_commit_mark(&recent, buf, &oid));\n+}\n+\n+void mark_commit(const struct object_id *oid)\n+{\n+\tstruct commit *c;\n+\tchar buf[64];\n+\tchar **val;\n+\n+\tif (latest_fd < 0)\n+\t\tstart_marking();\n+\n+\tif (!(c = lookup_commit(oid->hash)))\n+\t\treturn;\n+\n+\tupdate_commit_counter();\n+\tsprintf(buf, \"%s %u\\n\", oid_to_hex(oid), commit_counter);\n+\twrite_or_die(latest_fd, buf, strlen(buf));\n+\n+\tsprintf(buf, \"%c%u\", starter[run_counter], commit_counter);\n+\tval = counter_at(&counter, c);\n+\t*val = xstrdup(buf);\n+}\n+\n+const char *oid_to_commit_mark(const struct object_id *oid)\n+{\n+\tstruct commit *c;\n+\tchar **val;\n+\n+\tif (!(c = lookup_commit(oid->hash)) ||\n+\t    !(val = counter_peek(&counter, c)))\n+\t\treturn NULL;\n+\n+\treturn *val;\n+}\n+\n+int commit_mark_to_oid(const char *mark, struct object_id *oid)\n+{\n+\tchar buf[16];\n+\tint ret, c;\n+\tchar r_ch;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\n+\tif (sscanf(mark, \"%c%u\", &r_ch, &c) != 2 ||\n+\t    !strchr(starter, r_ch) ||\n+\t    strbuf_read_file(&sb, git_path(\"rev-counter/%c\", r_ch), 0) < 0)\n+\t\treturn -1;\n+\n+\tsprintf(buf, \"%u\", c);\n+\tret = strbuf_find_commit_mark(&sb, buf, oid);\n+\tstrbuf_release(&sb);\n+\n+\tif (!ret) {\n+\t\tchar line[80];\n+\t\tstatic int fd;\n+\n+\t\tif (!fd) {\n+\t\t\tif (!is_directory(git_path(\"rev-counter\")))\n+\t\t\t\tmkdir(git_path(\"rev-counter\"), 0755);\n+\t\t\tfd = open(git_path(\"rev-counter/recent\"),\n+\t\t\t\t  O_CREAT | O_RDWR | O_APPEND, 0644);\n+\t\t\tif (fd == -1)\n+\t\t\t\tdie(\"failed to open rev-counter/recent\");\n+\t\t}\n+\t\tsprintf(line, \"%s %s\\n\", oid_to_hex(oid), mark);\n+\t\twrite_or_die(fd, line, strlen(line));\n+\t}\n+\treturn ret;\n+}\ndiff --git a/rev-counter.h b/rev-counter.h\nnew file mode 100644\nindex 0000000000..ab2e8d8803\n--- /dev/null\n+++ b/rev-counter.h\n@@ -0,0 +1,10 @@\n+#ifndef __REV_COUNTER_H__\n+#define __REV_COUNTER_H__\n+\n+struct object_id;\n+\n+void mark_commit(const struct object_id *oid);\n+const char *oid_to_commit_mark(const struct object_id *oid);\n+int commit_mark_to_oid(const char *mark, struct object_id *oid);\n+\n+#endif\ndiff --git a/revision.c b/revision.c\nindex 2f60062876..1e32e91b9f 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1998,6 +1998,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg\n \t\trevs->limited = 1;\n \t} else if (!strcmp(arg, \"--ignore-missing\")) {\n \t\trevs->ignore_missing = 1;\n+\t} else if (!strcmp(arg, \"--mark-commits\")) {\n+\t\trevs->mark_commits = 1;\n+\t} else if (!strcmp(arg, \"--no-mark-commits\")) {\n+\t\trevs->mark_commits = 0;\n \t} else {\n \t\tint opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix);\n \t\tif (!opts)\ndiff --git a/revision.h b/revision.h\nindex 9fac1a607d..94e5b70ff5 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -146,6 +146,7 @@ struct rev_info {\n \tunsigned int\ttrack_linear:1,\n \t\t\ttrack_first_time:1,\n \t\t\tlinear:1;\n+\tunsigned int\tmark_commits:1;\n \n \tstruct date_mode date_mode;\n \tint\t\texpand_tabs_in_log; /* unset if negative */\ndiff --git a/sha1_name.c b/sha1_name.c\nindex ca7ddd6f2c..d3e1ff3921 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -7,6 +7,7 @@\n #include \"refs.h\"\n #include \"remote.h\"\n #include \"dir.h\"\n+#include \"rev-counter.h\"\n \n static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);\n \n@@ -485,6 +486,13 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1,\n \t\t}\n \t\treturn 0;\n \t}\n+\tif (len > 2 && str[0] == '@' && isalpha(str[1]) && isdigit(str[2])) {\n+\t\tstruct object_id oid;\n+\t\tif (!commit_mark_to_oid(str + 1, &oid)) {\n+\t\t\thashcpy(sha1, oid.hash);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n \n \t/* basic@{time or number or -number} format to query ref-log */\n \treflog_len = at = 0;\n-- \n2.11.0.157.gd943d85\n\n"},{"id":"309816","messageId":"alpine.DEB.2.20.1701201138520.3469@virtualbox","threadId":"44921","inReplyTo":"20170120102249.15572-1-pclouds@gmail.com","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-01-20T10:46:17Z","receivedAt":"2017-01-20T10:46:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Duy,\n\nOn Fri, 20 Jan 2017, Nguyễn Thái Ngọc Duy wrote:\n\n> OK This patch is horrible.\n\nYeah ;-)\n\n> Though the idea is cool and I've found it very useful. So here it is.\n> Perhaps the idea may be revised a bit that's more suitable for more than\n> one user.\n\nWhy not introduce a flag to \"git log\" that shows a keyboard-friendly name\nsimilar to what `git name-rev` would have said, except that the name would\nbe generated using the name(s) specified on the command-line?\n\nExample:\n\n\tgit log 8923d2d0 upstream/pu\n\n\tcommit 8923d2d00192ceb1107078484cccf537cb51c1b5 (8923d2d0)\n\t...\n\tcommit 9f500d6cf5eaa49391d6deca85fc864e5bd23415 (8923d2d0^)\n\t...\n\tcommit f79c24a291a58845b08cfec7573e22cc153693e1 (8923d2d0~2)\n\t...\n\tcommit c921c5bb63baaa16dc760de9549da55c8c89dc9c (upstream/pu)\n\t...\n\tcommit 16793ba6b6333ba0cdee1adb53d979c3fbdb17bc (upstream/pu^)\n\t...\n\nGranted, this is still a little more cumbersome to type than @h1, but\nthen, you can skip those round-robin games as well as the possibly\nbackwards-incompatible extension of the rev syntax.\n\nCiao,\nJohannes"},{"id":"309819","messageId":"CACsJy8C0SFsTNTB=R8zLLvnqkPofP0VQWPUR9pguT-n2Y+Tp1w@mail.gmail.com","threadId":"44921","inReplyTo":"alpine.DEB.2.20.1701201138520.3469@virtualbox","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-20T11:01:43Z","receivedAt":"2017-01-20T11:02:35Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 20, 2017 at 5:46 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Why not introduce a flag to \"git log\" that shows a keyboard-friendly name\n> similar to what `git name-rev` would have said, except that the name would\n> be generated using the name(s) specified on the command-line?\n>\n> Example:\n>\n>         git log 8923d2d0 upstream/pu\n>\n>         commit 8923d2d00192ceb1107078484cccf537cb51c1b5 (8923d2d0)\n>         ...\n>         commit 9f500d6cf5eaa49391d6deca85fc864e5bd23415 (8923d2d0^)\n>         ...\n>         commit f79c24a291a58845b08cfec7573e22cc153693e1 (8923d2d0~2)\n>         ...\n>         commit c921c5bb63baaa16dc760de9549da55c8c89dc9c (upstream/pu)\n>         ...\n>         commit 16793ba6b6333ba0cdee1adb53d979c3fbdb17bc (upstream/pu^)\n>         ...\n>\n> Granted, this is still a little more cumbersome to type than @h1, but\n> then, you can skip those round-robin games as well as the possibly\n> backwards-incompatible extension of the rev syntax.\n\nI mentioned name-rev a few paragraphs down. No, I want the sweet and\nshort @h1 (or something like that). name-rev does not qualify. I don't\nfeel comfortable typing 8923d2d0 without looking at the keyboard, and\nthat's a lot of movement on the keyboard.  upstream/pu is a bit\nbetter, but still very long (at least for me). Yes TAB-ing does help,\nbut not enough. Then you'll get the dreadful \"^2~1^3\" dance.\n-- \nDuy\n"},{"id":"309836","messageId":"alpine.DEB.2.20.1701201501190.3469@virtualbox","threadId":"44921","inReplyTo":"CACsJy8C0SFsTNTB=R8zLLvnqkPofP0VQWPUR9pguT-n2Y+Tp1w@mail.gmail.com","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-01-20T15:21:01Z","receivedAt":"2017-01-20T15:21:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Duy,\n\nOn Fri, 20 Jan 2017, Duy Nguyen wrote:\n\n> On Fri, Jan 20, 2017 at 5:46 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> > Why not introduce a flag to \"git log\" that shows a keyboard-friendly name\n> > similar to what `git name-rev` would have said, except that the name would\n> > be generated using the name(s) specified on the command-line?\n> >\n> > Example:\n> >\n> >         git log 8923d2d0 upstream/pu\n> >\n> >         commit 8923d2d00192ceb1107078484cccf537cb51c1b5 (8923d2d0)\n> >         ...\n> >         commit 9f500d6cf5eaa49391d6deca85fc864e5bd23415 (8923d2d0^)\n> >         ...\n> >         commit f79c24a291a58845b08cfec7573e22cc153693e1 (8923d2d0~2)\n> >         ...\n> >         commit c921c5bb63baaa16dc760de9549da55c8c89dc9c (upstream/pu)\n> >         ...\n> >         commit 16793ba6b6333ba0cdee1adb53d979c3fbdb17bc (upstream/pu^)\n> >         ...\n> >\n> > Granted, this is still a little more cumbersome to type than @h1, but\n> > then, you can skip those round-robin games as well as the possibly\n> > backwards-incompatible extension of the rev syntax.\n> \n> I mentioned name-rev a few paragraphs down.\n\nOkay, then.\n\n> No, I want the sweet and short @h1 (or something like that). name-rev\n> does not qualify.\n\nI am afraid that you have to go back to the drawing board, then, to come\nup with a backwards-compatible syntax that is as equally short and sweet\nas @h1.\n\nAnd you will probably also have to come up with a strategy for\nimplementing \"transient refs\", because that is exactly what you are doing\nhere. After all, you need to ensure that @h1 still works correctly (i.e.\nwithout scary warnings) when the corresponding ref has been removed and an\naggressive garbage collection was completed.\n\nAnd there are other concerns to be considered, not only the\nbackwards-compatibility. Certainly the current design will need to be\noverhauled.\n\nJust from a cursory brain-storming on my side (I even left out the\nhand-waving concerns):\n\n- this feature requires write-access. From a user's point of view, this\n  should be read-only, or at least also work without write access\n\n- the term \"commit mark\" is already used for something very different in\n  fast-import\n\n- the idea that running \"git log --mark-commits master\" twice will\n  generate *different* marks is surprising (and not in a good way)\n\n- introducing a feature to save keyboard strokes, and then requiring the\n  user to type ` --mark-commits`, i.e. 15 key presses, is, uhm, funny\n\n- the fact that these marks are per-worktree makes it a lot less useful\n  than if they were per-repository\n\n- related: there is no way to re-use these marks in different\n  repositories, e.g. when helping other developers, say, in a chat room\n\n- the fact that the first mark in every repository will be @a1 opens the\n  door very wide for using that mark accidentally in the wrong repository.\n  At least if I write 8923d in the git-gui repository, it will tell me\n  that there is no such revision. Using @a1, it would succeed, and it\n  would take me a *long* time to even realize that I am in the wrong\n  directory!\n\nAnd then there are the implementation issues:\n\n- it uses symlinks. I cannot let you do that, Dave.\n\n- using sscanf() to get the value of the first byte of a buffer? What's\n  wrong with `*buf*`?\n\n- \"asdfghjk\"? That is *very* limiting. The opposite of diverse. Just ask\n  the French, for starters\n\n- latest_fd is never closed, nor flushed\n\nIt sure complicates the implementation side as well as the overall design\na heck of a lot to insist on not using existing rev syntax.\n\n> I don't feel comfortable typing 8923d2d0 without looking at the\n> keyboard, and that's a lot of movement on the keyboard.\n\nI mentioned 8923d2d0 only as an example to illustrate the difference to\nname-rev.\n\nAnd when you talk about movement on the keyboard, you *must* realize that\nyou impose your favorite keyboard layout here. On the German keyboard, for\nexample, the `@` sign is typed via AltGr+q. That is very cumbersome right\nthere.\n\nAnd when you talk about speed advantages of keyboard vs mouse, it seems\nthat there are studies that show that keyboard is faster than mouse. For\nkeyboard shortcuts. Not for typing. I actually found no study comparing\nthe speed of typing with the speed of copy/paste, although I am sure that\nthey exist, and that they show pretty clearly that copy/paste is faster,\nand more accurate, than typing.\n\nBut back to minimizing movement on the keyboard.\n\nYou would usually type `git log upstream/pu`, tab-completing\n`upstream/pu`, right? And then you would want to refer to one particular\nentry in that output, say, `upstream/pu~50^2`, right?\n\nRight:\n\n> upstream/pu is a bit better, but still very long (at least for me). Yes\n> TAB-ing does help, but not enough. Then you'll get the dreadful \"^2~1^3\"\n> dance.\n\nYes, exactly. You would use tab-completion there, too, most of the way.\nAlthough I do not find that \"^2^^3\" [*1*] dreadful, I can see that some\nusers find it cumbersome. And then it is a little bit over the top to try\nto optimize away that \"^2^^3\".\n\nHowever, I am starting to feel like you try to use the wrong approach,\nbending Git's user interface out of shape just to be able force a workflow\nthat avoids copy-paste or GUIs, or for that matter, advanced ref notation\nsuch as \"upstream/pu^{/worktree.remove}\".\n\nDon't get me wrong, I would love to have faster method to go between log\nand prompt. But to be honest, what costs me much more of my time is\nfiguring out which commit and branch any given mail talks about when\nreviewing, or addressing reviews. Or for that matter, finding the mail\nthread discussing the patch series that the \"What's cooking\" mail talks\nabout. I guess I'd spend more time on accelerating that than on avoiding\ncopy/paste from `git log`'s output.\n\nCiao,\nJohannes\n\nFootnote *1*: Do we really have octopus merges in Git? I do not think so.\n*clicketyclick*. Urgh. You are correct. I found a whopping 45 in my\nrepository, and I certainly did not introduce any. On a sunny note, the\nlast Octopus seems to be v1.7.10-rc0~9^2~9(Merge branches\nzj/decimal-width, zj/term-columns and jc/diff-stat-scaler, 2012-02-24),\ni.e. a couple of years old.\n"},{"id":"309839","messageId":"20170120160942.srqf4y5w5r6feidw@sigill.intra.peff.net","threadId":"44921","inReplyTo":"20170120102249.15572-1-pclouds@gmail.com","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-01-20T16:09:43Z","receivedAt":"2017-01-20T16:10:01Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jan 20, 2017 at 05:22:49PM +0700, Nguyễn Thái Ngọc Duy wrote:\n\n> OK This patch is horrible. Though the idea is cool and I've found it\n> very useful. So here it is. Perhaps the idea may be revised a bit\n> that's more suitable for more than one user.\n> \n> The problem is old, SHA-1 name is not keyboard-friendly, even in\n> abbreviated form. And recent change has made abbrev form longer,\n> harder to type. Most of the time I just go with copy/paste with the\n> mouse, which I don't like. name-rev helps a bit, but it's still long\n> to type (especially with all the ^ and ~ that requires holding shift\n> down).\n\nNot really a comment on your patch itself, but I think a lot of people\nsolve this at a higher level, either in their terminal or via a tool\nlike tmux.\n\nI recently taught urxvt to recognize sha1s and grab them via keyboard\nhints, and I'm finding it quite useful. Here's what it looks like if\nyou're interested:\n\n  http://peff.net/git-hints.gif\n\nThe hints technique is taken from pentadactyl (which I also use), but\nthe urxvt port is mine. I'm happy to share the code.\n\nWhich isn't to say solving it inside Git is wrong, but I've found it\nreally convenient for two reasons:\n\n  1. It works whenever you see a sha1, not just in git commands (so\n     emails, inside commit messages, etc).\n\n  2. It doesn't take any screen space until you're ready to select.\n\nThe big downside is that it's scraping the screen, so you're guessing at\nwhat is a sha1. False positives are a little annoying, but usually not\nthat big a deal because you're already looking at what you want to\nselect, and the hint pops up right there.\n\n-Peff\n"},{"id":"309846","messageId":"xmqqh94ty4b5.fsf@gitster.mtv.corp.google.com","threadId":"44921","inReplyTo":"20170120160942.srqf4y5w5r6feidw@sigill.intra.peff.net","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-01-20T18:27:58Z","receivedAt":"2017-01-20T18:32:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Not really a comment on your patch itself, but I think a lot of people\n> solve this at a higher level, either in their terminal or via a tool\n> like tmux.\n>\n> I recently taught urxvt to recognize sha1s and grab them via keyboard\n> hints, and I'm finding it quite useful. Here's what it looks like if\n> you're interested:\n>\n>   http://peff.net/git-hints.gif\n\nNice.  I would have called the \"give me the string that is already\non the screen\" solution solving at a lower level, not higher, but I\nthink I agree with the general direction.  I always work in \"screen\"\nand grab a string I see displayed by going into its \"copy\" mode,\nwhich lets me jump to where the string appears by searching, and I\nthink that is a solution in the same class.\n\n>   2. It doesn't take any screen space until you're ready to select.\n\nYup, personally I find this quite important (as I am often on a box\nwith a smaller screen).\n\nI dream an integration with the command line completion we have.  I\ndo not offhand see what the mecanism to tell what object names were\nshown on the display recently to the completion mechanism should be,\nbut if we can solve that small detail, the result would be wonderful\n;-)\n\n"},{"id":"309848","messageId":"CA+P7+xoMTX5n_h+5MytZwVqKjqa0wdNKCeDtH29A_+WSfr6gTQ@mail.gmail.com","threadId":"44921","inReplyTo":"20170120160942.srqf4y5w5r6feidw@sigill.intra.peff.net","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2017-01-20T19:16:15Z","receivedAt":"2017-01-20T19:16:42Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Fri, Jan 20, 2017 at 8:09 AM, Jeff King <peff@peff.net> wrote:\n> On Fri, Jan 20, 2017 at 05:22:49PM +0700, Nguyễn Thái Ngọc Duy wrote:\n>\n>> OK This patch is horrible. Though the idea is cool and I've found it\n>> very useful. So here it is. Perhaps the idea may be revised a bit\n>> that's more suitable for more than one user.\n>>\n>> The problem is old, SHA-1 name is not keyboard-friendly, even in\n>> abbreviated form. And recent change has made abbrev form longer,\n>> harder to type. Most of the time I just go with copy/paste with the\n>> mouse, which I don't like. name-rev helps a bit, but it's still long\n>> to type (especially with all the ^ and ~ that requires holding shift\n>> down).\n>\n> Not really a comment on your patch itself, but I think a lot of people\n> solve this at a higher level, either in their terminal or via a tool\n> like tmux.\n>\n> I recently taught urxvt to recognize sha1s and grab them via keyboard\n> hints, and I'm finding it quite useful. Here's what it looks like if\n> you're interested:\n>\n>   http://peff.net/git-hints.gif\n>\n> The hints technique is taken from pentadactyl (which I also use), but\n> the urxvt port is mine. I'm happy to share the code.\n>\n> Which isn't to say solving it inside Git is wrong, but I've found it\n> really convenient for two reasons:\n>\n>   1. It works whenever you see a sha1, not just in git commands (so\n>      emails, inside commit messages, etc).\n>\n>   2. It doesn't take any screen space until you're ready to select.\n>\n> The big downside is that it's scraping the screen, so you're guessing at\n> what is a sha1. False positives are a little annoying, but usually not\n> that big a deal because you're already looking at what you want to\n> select, and the hint pops up right there.\n>\n> -Peff\n\nI would be interested in the code for this.. I'm curious if I can\nadapt it to my use of tmux.\n\nThanks,\nJake\n"},{"id":"309850","messageId":"20170120192539.7jts6xqzx46unn7y@sigill.intra.peff.net","threadId":"44921","inReplyTo":"CA+P7+xoMTX5n_h+5MytZwVqKjqa0wdNKCeDtH29A_+WSfr6gTQ@mail.gmail.com","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-01-20T19:25:39Z","receivedAt":"2017-01-20T19:25:47Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jan 20, 2017 at 11:16:15AM -0800, Jacob Keller wrote:\n\n> > I recently taught urxvt to recognize sha1s and grab them via keyboard\n> > hints, and I'm finding it quite useful. Here's what it looks like if\n> > you're interested:\n> >\n> >   http://peff.net/git-hints.gif\n> >\n> > The hints technique is taken from pentadactyl (which I also use), but\n> > the urxvt port is mine. I'm happy to share the code.\n> [...]\n> \n> I would be interested in the code for this.. I'm curious if I can\n> adapt it to my use of tmux.\n\nSee below. You can drop it into ~/.urxvt/ext/urlmatch and put something\nlike this into your Xresources:\n\n  URxvt.keysym.C-b: urlmatch:list\n  URxvt.keysym.C-semicolon: urlmatch:hint\n\nI think the interesting bits if you're adapting it to another system\nwill be the regexes in find_commits(), and the key-at-a-time state\nmachine in handle_select_key().\n\nNote that there's a sort-of bug in find_commits(). If you have:\n\n  1234abcd..5678abcd\n\nit finds three matches: one for each sha1, and one for the whole range.\nBut the range hint is covered up by the first sha1's hint.\n\nAnd probably other bugs, too. I've only been using it for about a week,\nand I did a bunch of cleanups this morning (after foolishly offering to\nlet other people see it ;) ).\n\n-- >8 --\n#!/usr/bin/perl\n\nuse warnings qw(all FATAL);\nuse strict;\n\nsub on_action {\n\tmy ($self, $action) = @_;\n\t($action, my @args) = split /:/, $action;\n\tif ($action eq 'list') {\n\t\t$self->matchlist(@args);\n\t} elsif ($action eq 'hint') {\n\t\t$self->open_hints(@args);\n\t}\n\t();\n}\n\nsub d { print STDERR \"debug: \" . join(' ', @_) . \"\\n\"; }\n\nsub handle_select_key {\n\tmy ($self, $event, $keysym, $octets) = @_;\n\n\tmy $input = $self->{input};\n\n\tmy $escape;\n\tif (48 <= $keysym && $keysym <= 57) {\n\t\t$input->{number} .= ($keysym - 48);\n\t} elsif (97 <= $keysym && $keysym <= 122) {\n\t\t$input->{text} .= chr($keysym);\n\t} elsif ($self->XKeysymToString($keysym) eq 'Return') {\n\t\t$input->{number} .= '$';\n\t} elsif ($keysym == 59) {\n\t\t$input->{action} = 'yank';\n\t\treturn 1;\n\t} else {\n\t\t$escape = 1;\n\t}\n\n\tif (!$escape) {\n\t\tmy $min = 0;\n\t\tmy $max = scalar(@{$input->{array}});\n\n\t\tmy $nr_re = qr/^$input->{number}/;\n\t\tmy $text_re = qr/$input->{text}/;\n\t\tmy @matches;\n\t\tfor (my $i = $min; $i < $max; $i++) {\n\t\t\tmy $item = $input->{array}->[$i];\n\t\t\tif ($i =~ /$nr_re/ && $item->{text} =~ /$text_re/) {\n\t\t\t\tpush @matches, $i;\n\t\t\t} elsif ($input->{unmatch}) {\n\t\t\t\tmy $item = $input->{array}->[$i];\n\t\t\t\t$input->{unmatch}->($self, $item);\n\t\t\t}\n\t\t}\n\t\tif (@matches > 1) {\n\t\t\t# not enough data yet\n\t\t\treturn 1;\n\t\t}\n\t\tif (@matches == 1) {\n\t\t\tmy $item = $input->{array}->[$matches[0]];\n\t\t\tmy $action = $input->{action} ||\n\t\t\t             $item->{action} ||\n\t\t\t\t     'activate';\n\t\t\tif ($action eq 'activate') {\n\t\t\t\t$self->exec_async(qw(webview), $item->{text});\n\t\t\t} elsif ($action eq 'yank') {\n\t\t\t\t$self->selection($item->{text});\n\t\t\t\t$self->selection_grab(urxvt::CurrentTime);\n\t\t\t}\n\t\t}\n\t}\n\n\tdelete $self->{input};\n\t$self->disable('key_press');\n\t1;\n}\n\nsub enable_select {\n\tmy $self = shift;\n\t$self->{input} = {text => '', number => '', @_};\n\t$self->enable(key_press => \\&handle_select_key);\n}\n\nsub matchlist {\n\tmy $self = shift;\n\n\tmy @items = $self->find_matches(@_)\n\t\tor return;\n\n\tmy $max_width = 0;\n\tfor (my $i = 0; $i < @items; $i++) {\n\t\tmy $item = $items[$i];\n\n\t\t$item->{number} = $i;\n\t\t$item->{menu} = \"$i. $item->{text}\";\n\n\t\tmy $width = $self->strwidth($item->{menu});\n\t\t$max_width = $width if $width > $max_width;\n\t}\n\n\tmy $rend = urxvt::SET_COLOR(urxvt::OVERLAY_RSTYLE, 0, 3);\n\n\tmy $o = $self->overlay(0, 0, $max_width, scalar(@items), $rend, 0);\n\tfor (my $i = 0; $i < @items; $i++) {\n\t\t$o->set(0, $i, $items[$i]->{menu});\n\t}\n\t$self->enable_select(\n\t\tarray => \\@items,\n\t\toverlay => $o,\n\t\tunmatch => sub {\n\t\t\tmy ($self, $item) = @_;\n\t\t\tmy $o = $self->{input}->{overlay};\n\t\t\t$o->set(0, $item->{number}, ' ' x length($item->{menu}));\n\t\t},\n\t);\n}\n\nsub open_hints {\n\tmy $self = shift;\n\n\tmy @items = $self->find_matches(@_)\n\t\tor return;\n\n\tfor (my $i = 0; $i < @items; $i++) {\n\t\tmy $item = $items[$i];\n\n\t\t$item->{overlay} = $self->overlay($item->{col}, $item->{row},\n\t\t\t\t\t\t  length($i), 1,\n\t\t\t\t\t\t  urxvt::OVERLAY_RSTYLE, 0);\n\t\t$item->{overlay}->set(0, 0, $i);\n\t}\n\n\t$self->enable_select(\n\t\tarray => \\@items,\n\t\tunmatch => sub {\n\t\t\tmy ($self, $item) = @_;\n\t\t\t$item->{overlay} = undef;\n\t\t},\n\t);\n}\n\nmy $URLCHAR = qr![-a-zA-Z:0-9./\\#%+~_?=&()@;,]!;\nmy $URLEND = qr![a-zA-Z0-9/]!;\n#my $URLLINE = qr!$URLCHAR{60,}$URLEND\\n|$URLCHAR*$URLEND!;\nmy $URL = qr!$URLCHAR*$URLEND!;\n\nsub find_urls {\n\tlocal $_ = shift;\n\tmy @urls;\n\n\twhile (m!(http|https|ftp|file)://$URL!g) {\n\t\tpush @urls, [$-[0], $&];\n\t}\n\twhile (m!^ *([a-zA-Z0-9]$URL\\.(?:com|net|org)/$URL)!mg) {\n\t\tpush @urls, [$-[0], \"http://$&\"];\n\t}\n\twhile (m!(?:^|(?<=\\s))(www|ftp)\\.$URL!g) {\n\t\tpush @urls, [$-[0], ($1 eq 'www' ? 'http://' : 'ftp://') . $&];\n\t}\n\n\treturn map { {\n\t\toffset => $_->[0],\n\t\ttext => $_->[1],\n\t} } @urls;\n}\n\nsub find_commits {\n\tlocal $_ = shift;\n\n\tmy @items;\n\twhile (m/(?:^|[^0-9a-f])\n\t\t ([0-9a-f]{7,40})\n\t\t (?![0-9a-f])/gx) {\n\t\tpush @items, { offset => $-[1], text => $1, action => 'yank' };\n\t}\n\twhile (m/(?:^|\\s)\n\t\t ([0-9a-f]{7,} \\.{2,3} [0-9a-f]{7,})\n\t\t (?:$|\\s)/gx) {\n\t\tpush @items, { offset => $-[1], text => $1, action => 'yank' };\n\t}\n\treturn @items;\n}\n\nsub find_matches {\n\tmy $self = shift;\n\n\tmy @ret;\n\tmy $row = 0;\n\twhile ($row < $self->nrow) {\n\t\tmy $line = $self->line($row);\n\t\tfor my $item (find_line_matches($line->t)) {\n\t\t\t@$item{qw(row col)} = $line->coord_of($item->{offset});\n\t\t\tpush @ret, $item;\n\t\t}\n\t\t$row = 1 + $line->end;\n\t}\n\treturn @ret;\n}\n\nsub find_line_matches {\n\tmy $buf = shift;\n\treturn map {\n\t\tif ($_ eq 'url') { find_urls($buf) }\n\t\telsif ($_ eq 'commit') { find_commits($buf) }\n\t\telse { d(\"unknown type: $_\"); () }\n\t} @_ ? @_ : qw(url commit);\n}\n"},{"id":"309886","messageId":"CACsJy8DxCPCXUeEoR1pQBCNqYOHjpgfLy_vgqsK1H=C0Mf=L8g@mail.gmail.com","threadId":"44921","inReplyTo":"20170120192539.7jts6xqzx46unn7y@sigill.intra.peff.net","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-21T12:44:05Z","receivedAt":"2017-01-21T12:44:42Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jan 21, 2017 at 2:25 AM, Jeff King <peff@peff.net> wrote:\n> On Fri, Jan 20, 2017 at 11:16:15AM -0800, Jacob Keller wrote:\n>\n>> > I recently taught urxvt to recognize sha1s and grab them via keyboard\n>> > hints, and I'm finding it quite useful. Here's what it looks like if\n>> > you're interested:\n>> >\n>> >   http://peff.net/git-hints.gif\n>> >\n>> > The hints technique is taken from pentadactyl (which I also use), but\n>> > the urxvt port is mine. I'm happy to share the code.\n\nYou just gave me a reason to rebuild urxvt with perl support. It\nsolves my problem with SHA-1 nicely (and fixes another problem with\nvery large counter in my approach, when you scroll git-log further\ndown, because I can't know what's on screen or already scrolled past).\n\nDo you think it should be in contrib for better discoverability (than\nburying it in the mail archive)? A separate git repo is also ok, but I\nguess that's just more burden.\n\n>> I would be interested in the code for this.. I'm curious if I can\n>> adapt it to my use of tmux.\n\nYeah. Let me know if it works out. Would be nice to have this run on\nbasically any terminal, as long as I run tmux on top.\n-- \nDuy\n"},{"id":"309892","messageId":"20170121140325.uicd2nxtuhn3i5vy@sigill.intra.peff.net","threadId":"44921","inReplyTo":"CACsJy8DxCPCXUeEoR1pQBCNqYOHjpgfLy_vgqsK1H=C0Mf=L8g@mail.gmail.com","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-01-21T14:03:25Z","receivedAt":"2017-01-21T14:03:31Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jan 21, 2017 at 07:44:05PM +0700, Duy Nguyen wrote:\n\n> You just gave me a reason to rebuild urxvt with perl support. It\n> solves my problem with SHA-1 nicely (and fixes another problem with\n> very large counter in my approach, when you scroll git-log further\n> down, because I can't know what's on screen or already scrolled past).\n\nNote that even without my module, you can probably use the \"matcher\"\nextension which is included with urxvt to do something similar (it can\nhandle arbitrary numbers of matching regexps).\n\nThe things I like about my module (and why I bothered to write it) are:\n\n  - it does nothing at all until you trigger it, so you don't have to\n    worry about the cost of your regexes, or how ugly false positives\n    will look when underlined\n\n  - I think the hint mode is much better for keyboard navigation.\n    The matcher extension does have a \"list\" mode where you get an\n    overlay with the whole list and select by number. That's what I\n    started with in mine, but I found it's really hard to use when there\n    are a lot of matches. Especially with sha1s.\n\n> Do you think it should be in contrib for better discoverability (than\n> burying it in the mail archive)? A separate git repo is also ok, but I\n> guess that's just more burden.\n\nI'm not sure it makes sense in git's contrib. It's really more about\nurxvt than it is about git.\n\n-Peff\n"},{"id":"310870","messageId":"CACsJy8CTRcDuRiNeutG82iAj8qQFp+z2nadFfdkkHQGk6GKppA@mail.gmail.com","threadId":"44921","inReplyTo":"CA+P7+xoMTX5n_h+5MytZwVqKjqa0wdNKCeDtH29A_+WSfr6gTQ@mail.gmail.com","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-02-05T10:39:12Z","receivedAt":"2017-02-05T10:39:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Jan 21, 2017 at 2:16 AM, Jacob Keller <jacob.keller@gmail.com> wrote:\n> I would be interested in the code for this.. I'm curious if I can\n> adapt it to my use of tmux.\n\nI stumbled upon this which does mention about git SHA-1. Maybe you'll\nfind it useful. Haven't tried it out though.\n\nhttps://github.com/morantron/tmux-fingers\n\n-- \nDuy\n"},{"id":"310889","messageId":"CA+P7+xr3e4ER_p-Y8+A+3zE9-cgWEBBi1N9fsHRXKxNz+vd6=w@mail.gmail.com","threadId":"44921","inReplyTo":"CACsJy8CTRcDuRiNeutG82iAj8qQFp+z2nadFfdkkHQGk6GKppA@mail.gmail.com","subject":"Re: [PATCH/TOY] Shortcuts to quickly refer to a commit name with keyboard","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2017-02-05T22:45:33Z","receivedAt":"2017-02-05T22:46:02Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Sun, Feb 5, 2017 at 2:39 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, Jan 21, 2017 at 2:16 AM, Jacob Keller <jacob.keller@gmail.com> wrote:\n>> I would be interested in the code for this.. I'm curious if I can\n>> adapt it to my use of tmux.\n>\n> I stumbled upon this which does mention about git SHA-1. Maybe you'll\n> find it useful. Haven't tried it out though.\n>\n> https://github.com/morantron/tmux-fingers\n>\n> --\n> Duy\n\nThis sounds almost exactly like what I want! :)\n\nThanks,\nJake\n"}]}