Code

Rename path_list to string_list
[git.git] / reflog-walk.c
index d4b49c7354a4b4cade997a98cb9f097e3d2b2369..f751fdc8d832cae54647c1a70d888e979d324fd8 100644 (file)
@@ -3,7 +3,8 @@
 #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;
@@ -70,7 +71,7 @@ static int get_reflog_recno_by_time(struct complete_reflogs *array,
        unsigned long timestamp)
 {
        int i;
-       for (i = array->nr - 1; i >= 0; i++)
+       for (i = array->nr - 1; i >= 0; i--)
                if (timestamp >= array->items[i].timestamp)
                        return i;
        return -1;
@@ -126,7 +127,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;
 };
 
@@ -135,16 +136,19 @@ 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;
 
+       if (commit->object.flags & UNINTERESTING)
+               die ("Cannot walk reflogs for %s", name);
+
        branch = xstrdup(name);
        if (at && at[1] == '{') {
                char *ep;
@@ -157,14 +161,35 @@ 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 {
+               if (*branch == '\0') {
+                       unsigned char sha1[20];
+                       const char *head = resolve_ref("HEAD", sha1, 0, NULL);
+                       if (!head)
+                               die ("No current branch");
+                       free(branch);
+                       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;
        }
 
@@ -175,13 +200,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)
@@ -215,21 +241,34 @@ 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)
+void show_reflog_message(struct reflog_walk_info* info, int oneline,
+       int relative_date)
 {
        if (info && info->last_commit_reflog) {
                struct commit_reflog *commit_reflog = info->last_commit_reflog;
                struct reflog_info *info;
 
-               printf("Reflog: %s@{", commit_reflog->reflogs->ref);
-               info = &commit_reflog->reflogs->items[commit_reflog->recno + 1];
-               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);
+               info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+               if (oneline) {
+                       printf("%s@{", commit_reflog->reflogs->ref);
+                       if (commit_reflog->flag || relative_date)
+                               printf("%s", show_date(info->timestamp, 0, 1));
+                       else
+                               printf("%d", commit_reflog->reflogs->nr
+                                      - 2 - commit_reflog->recno);
+                       printf("}: %s", info->message);
+               }
+               else {
+                       printf("Reflog: %s@{", commit_reflog->reflogs->ref);
+                       if (commit_reflog->flag || relative_date)
+                               printf("%s", show_date(info->timestamp,
+                                                       info->tz,
+                                                       relative_date));
+                       else
+                               printf("%d", commit_reflog->reflogs->nr
+                                      - 2 - commit_reflog->recno);
+                       printf("} (%s)\nReflog message: %s",
+                              info->email, info->message);
+               }
        }
 }