summaryrefslogtreecommitdiff
path: root/sha1_name.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-10-06 06:16:15 (GMT)
committerJunio C Hamano <junkio@cox.net>2006-10-06 06:17:11 (GMT)
commitab2a1a32ffa5a39aaf4204bd717562bce49e0a36 (patch)
tree21b6b7f63d6e74f023df5d338282b0a75df55c35 /sha1_name.c
parent422b4a0e03658d0933a7abc149f175735ea9c4b5 (diff)
downloadgit-ab2a1a32ffa5a39aaf4204bd717562bce49e0a36.zip
git-ab2a1a32ffa5a39aaf4204bd717562bce49e0a36.tar.gz
git-ab2a1a32ffa5a39aaf4204bd717562bce49e0a36.tar.bz2
ref-log: allow ref@{count} syntax.
Often I find myself wanting to say 'tip of "next" before I merged the last three topics'. Now I can say that with: git log next@{3}..next Since small integers alone are invalid input strings to approxidate, there is no fear of confusion. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'sha1_name.c')
-rw-r--r--sha1_name.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/sha1_name.c b/sha1_name.c
index ed711f2..e517033 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -249,24 +249,23 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
static const char *warning = "warning: refname '%.*s' is ambiguous.\n";
const char **p, *ref;
char *real_ref = NULL;
- int refs_found = 0, am;
- unsigned long at_time = (unsigned long)-1;
+ int refs_found = 0;
+ int at, reflog_len;
unsigned char *this_result;
unsigned char sha1_from_ref[20];
if (len == 40 && !get_sha1_hex(str, sha1))
return 0;
- /* At a given period of time? "@{2 hours ago}" */
- for (am = 1; am < len - 1; am++) {
- if (str[am] == '@' && str[am+1] == '{' && str[len-1] == '}') {
- int date_len = len - am - 3;
- char *date_spec = xmalloc(date_len + 1);
- strlcpy(date_spec, str + am + 2, date_len + 1);
- at_time = approxidate(date_spec);
- free(date_spec);
- len = am;
- break;
+ /* basic@{time or number} format to query ref-log */
+ reflog_len = 0;
+ if (str[len-1] == '}') {
+ for (at = 1; at < len - 1; at++) {
+ if (str[at] == '@' && str[at+1] == '{') {
+ reflog_len = (len-1) - (at+2);
+ len = at;
+ break;
+ }
}
}
@@ -291,11 +290,22 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
if (warn_ambiguous_refs && refs_found > 1)
fprintf(stderr, warning, len, str);
- if (at_time != (unsigned long)-1) {
- read_ref_at(
- real_ref,
- at_time,
- sha1);
+ if (reflog_len) {
+ /* Is it asking for N-th entry, or approxidate? */
+ int nth, i;
+ unsigned long at_time;
+ for (i = nth = 0; 0 <= nth && i < reflog_len; i++) {
+ char ch = str[at+2+i];
+ if ('0' <= ch && ch <= '9')
+ nth = nth * 10 + ch - '0';
+ else
+ nth = -1;
+ }
+ if (0 <= nth)
+ at_time = 0;
+ else
+ at_time = approxidate(str + at + 2);
+ read_ref_at(real_ref, at_time, nth, sha1);
}
free(real_ref);