diff options
Diffstat (limited to 'reflog-walk.c')
-rw-r--r-- | reflog-walk.c | 111 |
1 files changed, 84 insertions, 27 deletions
diff --git a/reflog-walk.c b/reflog-walk.c index 653ec956f0..caba4f743f 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -3,11 +3,12 @@ #include "refs.h" #include "diff.h" #include "revision.h" -#include "path-list.h" +#include "string-list.h" #include "reflog-walk.h" struct complete_reflogs { char *ref; + const char *short_ref; struct reflog_info { unsigned char osha1[20], nsha1[20]; char *email; @@ -127,7 +128,7 @@ struct commit_reflog { struct reflog_walk_info { struct commit_info_lifo reflogs; - struct path_list complete_reflogs; + struct string_list complete_reflogs; struct commit_reflog *last_commit_reflog; }; @@ -136,12 +137,12 @@ void init_reflog_walk(struct reflog_walk_info** info) *info = xcalloc(sizeof(struct reflog_walk_info), 1); } -void add_reflog_for_walk(struct reflog_walk_info *info, +int add_reflog_for_walk(struct reflog_walk_info *info, struct commit *commit, const char *name) { unsigned long timestamp = 0; int recno = -1; - struct path_list_item *item; + struct string_list_item *item; struct complete_reflogs *reflogs; char *branch, *at = strchr(name, '@'); struct commit_reflog *commit_reflog; @@ -161,7 +162,7 @@ void add_reflog_for_walk(struct reflog_walk_info *info, } else recno = 0; - item = path_list_lookup(branch, &info->complete_reflogs); + item = string_list_lookup(branch, &info->complete_reflogs); if (item) reflogs = item->util; else { @@ -174,9 +175,22 @@ void add_reflog_for_walk(struct reflog_walk_info *info, branch = xstrdup(head); } reflogs = read_complete_reflog(branch); + if (!reflogs || reflogs->nr == 0) { + unsigned char sha1[20]; + char *b; + if (dwim_log(branch, strlen(branch), sha1, &b) == 1) { + if (reflogs) { + free(reflogs->ref); + free(reflogs); + } + free(branch); + branch = b; + reflogs = read_complete_reflog(branch); + } + } if (!reflogs || reflogs->nr == 0) - die("No reflogs found for '%s'", branch); - path_list_insert(branch, &info->complete_reflogs)->util + return -1; + string_list_insert(branch, &info->complete_reflogs)->util = reflogs; } @@ -187,13 +201,14 @@ void add_reflog_for_walk(struct reflog_walk_info *info, if (commit_reflog->recno < 0) { free(branch); free(commit_reflog); - return; + return -1; } } else commit_reflog->recno = reflogs->nr - recno - 1; commit_reflog->reflogs = reflogs; add_commit_info(commit, commit_reflog, &info->reflogs); + return 0; } void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) @@ -227,32 +242,74 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) commit->object.flags &= ~(ADDED | SEEN | SHOWN); } -void show_reflog_message(struct reflog_walk_info* info, int oneline) +void get_reflog_selector(struct strbuf *sb, + struct reflog_walk_info *reflog_info, + enum date_mode dmode, + int shorten) +{ + struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; + struct reflog_info *info; + const char *printed_ref; + + if (!commit_reflog) + return; + + if (shorten) { + if (!commit_reflog->reflogs->short_ref) + commit_reflog->reflogs->short_ref + = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0); + printed_ref = commit_reflog->reflogs->short_ref; + } else { + printed_ref = commit_reflog->reflogs->ref; + } + + strbuf_addf(sb, "%s@{", printed_ref); + if (commit_reflog->flag || dmode) { + info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; + strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode)); + } else { + strbuf_addf(sb, "%d", commit_reflog->reflogs->nr + - 2 - commit_reflog->recno); + } + + strbuf_addch(sb, '}'); +} + +void get_reflog_message(struct strbuf *sb, + struct reflog_walk_info *reflog_info) { - if (info && info->last_commit_reflog) { - struct commit_reflog *commit_reflog = info->last_commit_reflog; + struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; + struct reflog_info *info; + size_t len; + + if (!commit_reflog) + return; + + info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; + len = strlen(info->message); + if (len > 0) + len--; /* strip away trailing newline */ + strbuf_add(sb, info->message, len); +} + +void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline, + enum date_mode dmode) +{ + if (reflog_info && reflog_info->last_commit_reflog) { + struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; struct reflog_info *info; + struct strbuf selector = STRBUF_INIT; info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; + get_reflog_selector(&selector, reflog_info, dmode, 0); if (oneline) { - printf("%s@{", commit_reflog->reflogs->ref); - if (commit_reflog->flag) - printf("%s", show_date(info->timestamp, 0, 1)); - else - printf("%d", commit_reflog->reflogs->nr - - 2 - commit_reflog->recno); - printf("}: %s", info->message); + printf("%s: %s", selector.buf, info->message); } else { - printf("Reflog: %s@{", commit_reflog->reflogs->ref); - if (commit_reflog->flag) - printf("%s", show_rfc2822_date(info->timestamp, - info->tz)); - else - printf("%d", commit_reflog->reflogs->nr - - 2 - commit_reflog->recno); - printf("} (%s)\nReflog message: %s", - info->email, info->message); + printf("Reflog: %s (%s)\nReflog message: %s", + selector.buf, info->email, info->message); } + + strbuf_release(&selector); } } |