tree-diff: remove special-case diff-emitting code for empty-tree cases
[gitweb.git] / line-log.c
index 38f827ba9a01b96316358bba43ffd74e5d3682fe..150010105806291180d9e6bdfcf1939fb242f2ac 100644 (file)
@@ -291,7 +291,6 @@ static void line_log_data_insert(struct line_log_data **list,
 
        if (p) {
                range_set_append_unsafe(&p->ranges, begin, end);
-               sort_and_merge_range_set(&p->ranges);
                free(path);
                return;
        }
@@ -299,7 +298,6 @@ static void line_log_data_insert(struct line_log_data **list,
        p = xcalloc(1, sizeof(struct line_log_data));
        p->path = path;
        range_set_append(&p->ranges, begin, end);
-       sort_and_merge_range_set(&p->ranges);
        if (ip) {
                p->next = ip->next;
                ip->next = p;
@@ -566,12 +564,14 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
        struct nth_line_cb cb_data;
        struct string_list_item *item;
        struct line_log_data *ranges = NULL;
+       struct line_log_data *p;
 
        for_each_string_list_item(item, args) {
                const char *name_part, *range_part;
                char *full_name;
                struct diff_filespec *spec;
                long begin = 0, end = 0;
+               long anchor;
 
                name_part = skip_range_arg(item->string);
                if (!name_part || *name_part != ':' || !name_part[1])
@@ -590,8 +590,14 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
                cb_data.lines = lines;
                cb_data.line_ends = ends;
 
+               p = search_line_log_data(ranges, full_name, NULL);
+               if (p && p->ranges.nr)
+                       anchor = p->ranges.ranges[p->ranges.nr - 1].end + 1;
+               else
+                       anchor = 1;
+
                if (parse_range_arg(range_part, nth_line, &cb_data,
-                                   lines, 1, &begin, &end,
+                                   lines, anchor, &begin, &end,
                                    full_name))
                        die("malformed -L argument '%s'", range_part);
                if (lines < end || ((lines || begin) && lines < begin))
@@ -608,6 +614,9 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
                ends = NULL;
        }
 
+       for (p = ranges; p; p = p->next)
+               sort_and_merge_range_set(&p->ranges);
+
        return ranges;
 }
 
@@ -751,21 +760,12 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list
                        r = r->next;
                }
                paths[count] = NULL;
-               init_pathspec(&rev->diffopt.pathspec, paths);
+               parse_pathspec(&rev->diffopt.pathspec, 0,
+                              PATHSPEC_PREFER_FULL, "", paths);
                free(paths);
        }
 }
 
-static void load_tree_desc(struct tree_desc *desc, void **tree,
-                          const unsigned char *sha1)
-{
-       unsigned long size;
-       *tree = read_object_with_reference(sha1, tree_type, &size, NULL);
-       if (!*tree)
-               die("Unable to read tree (%s)", sha1_to_hex(sha1));
-       init_tree_desc(desc, *tree, size);
-}
-
 static int count_parents(struct commit *commit)
 {
        struct commit_list *parents = commit->parents;
@@ -832,18 +832,11 @@ static void queue_diffs(struct line_log_data *range,
                        struct diff_queue_struct *queue,
                        struct commit *commit, struct commit *parent)
 {
-       void *tree1 = NULL, *tree2 = NULL;
-       struct tree_desc desc1, desc2;
-
        assert(commit);
-       load_tree_desc(&desc2, &tree2, commit->tree->object.sha1);
-       if (parent)
-               load_tree_desc(&desc1, &tree1, parent->tree->object.sha1);
-       else
-               init_tree_desc(&desc1, "", 0);
 
        DIFF_QUEUE_CLEAR(&diff_queued_diff);
-       diff_tree(&desc1, &desc2, "", opt);
+       diff_tree_sha1(parent ? parent->tree->object.sha1 : NULL,
+                       commit->tree->object.sha1, "", opt);
        if (opt->detect_rename) {
                filter_diffs_for_paths(range, 1);
                if (diff_might_be_rename())
@@ -851,11 +844,6 @@ static void queue_diffs(struct line_log_data *range,
                filter_diffs_for_paths(range, 0);
        }
        move_diff_queue(queue, &diff_queued_diff);
-
-       if (tree1)
-               free(tree1);
-       if (tree2)
-               free(tree2);
 }
 
 static char *get_nth_line(long line, unsigned long *ends, void *data)