git-svn: fix show-ignore when not connected to the repository root
[gitweb.git] / revision.c
index 1e3b29a429e99fd04da54a3af661d07ddb870688..f5b8ae4f031a059cff08328cf661515b9e68ccec 100644 (file)
@@ -7,6 +7,7 @@
 #include "refs.h"
 #include "revision.h"
 #include "grep.h"
+#include "reflog-walk.h"
 
 static char *path_name(struct name_path *path, const char *name)
 {
@@ -115,7 +116,12 @@ void mark_parents_uninteresting(struct commit *commit)
 
 void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
 {
+       if (revs->no_walk && (obj->flags & UNINTERESTING))
+               die("object ranges do not make sense when not walking revisions");
        add_object_array(obj, name, &revs->pending);
+       if (revs->reflog_info && obj->type == OBJ_COMMIT)
+               add_reflog_for_walk(revs->reflog_info,
+                               (struct commit *)obj, name);
 }
 
 static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
@@ -476,7 +482,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag,
        struct all_refs_cb *cb = cb_data;
        struct object *object = get_reference(cb->all_revs, path, sha1,
                                              cb->all_flags);
-       add_pending_object(cb->all_revs, object, "");
+       add_pending_object(cb->all_revs, object, path);
        return 0;
 }
 
@@ -528,7 +534,7 @@ static void handle_reflog(struct rev_info *revs, unsigned flags)
        struct all_refs_cb cb;
        cb.all_revs = revs;
        cb.all_flags = flags;
-       for_each_ref(handle_one_reflog, &cb);
+       for_each_reflog(handle_one_reflog, &cb);
 }
 
 static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
@@ -809,11 +815,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                const char *arg = argv[i];
                if (*arg == '-') {
                        int opts;
-                       if (!strncmp(arg, "--max-count=", 12)) {
+                       if (!prefixcmp(arg, "--max-count=")) {
                                revs->max_count = atoi(arg + 12);
                                continue;
                        }
-                       if (!strncmp(arg, "--skip=", 7)) {
+                       if (!prefixcmp(arg, "--skip=")) {
                                revs->skip_count = atoi(arg + 7);
                                continue;
                        }
@@ -828,31 +834,31 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                revs->max_count = atoi(argv[++i]);
                                continue;
                        }
-                       if (!strncmp(arg,"-n",2)) {
+                       if (!prefixcmp(arg, "-n")) {
                                revs->max_count = atoi(arg + 2);
                                continue;
                        }
-                       if (!strncmp(arg, "--max-age=", 10)) {
+                       if (!prefixcmp(arg, "--max-age=")) {
                                revs->max_age = atoi(arg + 10);
                                continue;
                        }
-                       if (!strncmp(arg, "--since=", 8)) {
+                       if (!prefixcmp(arg, "--since=")) {
                                revs->max_age = approxidate(arg + 8);
                                continue;
                        }
-                       if (!strncmp(arg, "--after=", 8)) {
+                       if (!prefixcmp(arg, "--after=")) {
                                revs->max_age = approxidate(arg + 8);
                                continue;
                        }
-                       if (!strncmp(arg, "--min-age=", 10)) {
+                       if (!prefixcmp(arg, "--min-age=")) {
                                revs->min_age = atoi(arg + 10);
                                continue;
                        }
-                       if (!strncmp(arg, "--before=", 9)) {
+                       if (!prefixcmp(arg, "--before=")) {
                                revs->min_age = approxidate(arg + 9);
                                continue;
                        }
-                       if (!strncmp(arg, "--until=", 8)) {
+                       if (!prefixcmp(arg, "--until=")) {
                                revs->min_age = approxidate(arg + 8);
                                continue;
                        }
@@ -864,6 +870,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                handle_reflog(revs, flags);
                                continue;
                        }
+                       if (!strcmp(arg, "-g") ||
+                                       !strcmp(arg, "--walk-reflogs")) {
+                               init_reflog_walk(&revs->reflog_info);
+                               continue;
+                       }
                        if (!strcmp(arg, "--not")) {
                                flags ^= UNINTERESTING;
                                continue;
@@ -935,7 +946,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                revs->num_ignore_packed = 0;
                                continue;
                        }
-                       if (!strncmp(arg, "--unpacked=", 11)) {
+                       if (!prefixcmp(arg, "--unpacked=")) {
                                revs->unpacked = 1;
                                add_ignore_packed(revs, arg+11);
                                continue;
@@ -971,7 +982,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                revs->verbose_header = 1;
                                continue;
                        }
-                       if (!strncmp(arg, "--pretty", 8)) {
+                       if (!prefixcmp(arg, "--pretty")) {
                                revs->verbose_header = 1;
                                revs->commit_format = get_commit_format(arg+8);
                                continue;
@@ -996,7 +1007,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                revs->abbrev = DEFAULT_ABBREV;
                                continue;
                        }
-                       if (!strncmp(arg, "--abbrev=", 9)) {
+                       if (!prefixcmp(arg, "--abbrev=")) {
                                revs->abbrev = strtoul(arg + 9, NULL, 10);
                                if (revs->abbrev < MINIMUM_ABBREV)
                                        revs->abbrev = MINIMUM_ABBREV;
@@ -1025,15 +1036,15 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                        /*
                         * Grepping the commit log
                         */
-                       if (!strncmp(arg, "--author=", 9)) {
+                       if (!prefixcmp(arg, "--author=")) {
                                add_header_grep(revs, "author", arg+9);
                                continue;
                        }
-                       if (!strncmp(arg, "--committer=", 12)) {
+                       if (!prefixcmp(arg, "--committer=")) {
                                add_header_grep(revs, "committer", arg+12);
                                continue;
                        }
-                       if (!strncmp(arg, "--grep=", 7)) {
+                       if (!prefixcmp(arg, "--grep=")) {
                                add_message_grep(revs, arg+7);
                                continue;
                        }
@@ -1041,7 +1052,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                all_match = 1;
                                continue;
                        }
-                       if (!strncmp(arg, "--encoding=", 11)) {
+                       if (!prefixcmp(arg, "--encoding=")) {
                                arg += 11;
                                if (strcmp(arg, "none"))
                                        git_log_output_encoding = strdup(arg);
@@ -1049,6 +1060,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                        git_log_output_encoding = "";
                                continue;
                        }
+                       if (!strcmp(arg, "--reverse")) {
+                               revs->reverse ^= 1;
+                               continue;
+                       }
 
                        opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
                        if (opts > 0) {
@@ -1121,21 +1136,23 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 void prepare_revision_walk(struct rev_info *revs)
 {
        int nr = revs->pending.nr;
-       struct object_array_entry *list = revs->pending.objects;
+       struct object_array_entry *e, *list;
 
+       e = list = revs->pending.objects;
        revs->pending.nr = 0;
        revs->pending.alloc = 0;
        revs->pending.objects = NULL;
        while (--nr >= 0) {
-               struct commit *commit = handle_commit(revs, list->item, list->name);
+               struct commit *commit = handle_commit(revs, e->item, e->name);
                if (commit) {
                        if (!(commit->object.flags & SEEN)) {
                                commit->object.flags |= SEEN;
                                insert_by_date(commit, &revs->commits);
                        }
                }
-               list++;
+               e++;
        }
+       free(list);
 
        if (revs->no_walk)
                return;
@@ -1208,6 +1225,9 @@ static struct commit *get_revision_1(struct rev_info *revs)
                revs->commits = entry->next;
                free(entry);
 
+               if (revs->reflog_info)
+                       fake_reflog_parent(revs->reflog_info, commit);
+
                /*
                 * If we haven't done the list limiting, we need to look at
                 * the parents here. We also need to do the date-based limiting
@@ -1215,9 +1235,15 @@ static struct commit *get_revision_1(struct rev_info *revs)
                 */
                if (!revs->limited) {
                        if (revs->max_age != -1 &&
-                           (commit->date < revs->max_age))
-                               continue;
-                       add_parents_to_list(revs, commit, &revs->commits);
+                           (commit->date < revs->max_age)) {
+                               if (revs->boundary)
+                                       commit->object.flags |=
+                                               BOUNDARY_SHOW | BOUNDARY;
+                               else
+                                       continue;
+                       } else
+                               add_parents_to_list(revs, commit,
+                                               &revs->commits);
                }
                if (commit->object.flags & SHOWN)
                        continue;
@@ -1272,6 +1298,40 @@ struct commit *get_revision(struct rev_info *revs)
 {
        struct commit *c = NULL;
 
+       if (revs->reverse) {
+               struct commit_list *list;
+
+               /*
+                * rev_info.reverse is used to note the fact that we
+                * want to output the list of revisions in reverse
+                * order.  To accomplish this goal, reverse can have
+                * different values:
+                *
+                *  0  do nothing
+                *  1  reverse the list
+                *  2  internal use:  we have already obtained and
+                *     reversed the list, now we only need to yield
+                *     its items.
+                */
+
+               if (revs->reverse == 1) {
+                       revs->reverse = 0;
+                       list = NULL;
+                       while ((c = get_revision(revs)))
+                               commit_list_insert(c, &list);
+                       revs->commits = list;
+                       revs->reverse = 2;
+               }
+
+               if (!revs->commits)
+                       return NULL;
+               c = revs->commits->item;
+               list = revs->commits->next;
+               free(revs->commits);
+               revs->commits = list;
+               return c;
+       }
+
        if (0 < revs->skip_count) {
                while ((c = get_revision_1(revs)) != NULL) {
                        if (revs->skip_count-- <= 0)
@@ -1284,7 +1344,18 @@ struct commit *get_revision(struct rev_info *revs)
        case -1:
                break;
        case 0:
-               return NULL;
+               if (revs->boundary) {
+                       struct commit_list *list = revs->commits;
+                       while (list) {
+                               list->item->object.flags |=
+                                       BOUNDARY_SHOW | BOUNDARY;
+                               list = list->next;
+                       }
+                       /* all remaining commits are boundary commits */
+                       revs->max_count = -1;
+                       revs->limited = 1;
+               } else
+                       return NULL;
        default:
                revs->max_count--;
        }