builtin/show-branch: rewrite functions to work with object_id
[gitweb.git] / diff-lib.c
index 044872935c30d84affb1955a7ae03c0986c90bda..0d8c5358e4236bf1d0c2ceb214d6a4fa09b2d2de 100644 (file)
@@ -97,11 +97,11 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                diff_unmerged_stage = 2;
        entries = active_nr;
        for (i = 0; i < entries; i++) {
-               struct stat st;
                unsigned int oldmode, newmode;
                struct cache_entry *ce = active_cache[i];
                int changed;
                unsigned dirty_submodule = 0;
+               const unsigned char *old_sha1, *new_sha1;
 
                if (diff_can_quit_early(&revs->diffopt))
                        break;
@@ -115,6 +115,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                        unsigned int wt_mode = 0;
                        int num_compare_stages = 0;
                        size_t path_len;
+                       struct stat st;
 
                        path_len = ce_namelen(ce);
 
@@ -124,7 +125,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                        dpath->next = NULL;
                        memcpy(dpath->path, ce->name, path_len);
                        dpath->path[path_len] = '\0';
-                       hashclr(dpath->sha1);
+                       oidclr(&dpath->oid);
                        memset(&(dpath->parent[0]), 0,
                               sizeof(struct combine_diff_parent)*5);
 
@@ -154,7 +155,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                                if (2 <= stage) {
                                        int mode = nce->ce_mode;
                                        num_compare_stages++;
-                                       hashcpy(dpath->parent[stage-2].sha1, nce->sha1);
+                                       hashcpy(dpath->parent[stage-2].oid.hash, nce->sha1);
                                        dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode);
                                        dpath->parent[stage-2].status =
                                                DIFF_STATUS_MODIFIED;
@@ -195,29 +196,46 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                        continue;
 
                /* If CE_VALID is set, don't look at workdir for file removal */
-               changed = (ce->ce_flags & CE_VALID) ? 0 : check_removed(ce, &st);
-               if (changed) {
-                       if (changed < 0) {
-                               perror(ce->name);
+               if (ce->ce_flags & CE_VALID) {
+                       changed = 0;
+                       newmode = ce->ce_mode;
+               } else {
+                       struct stat st;
+
+                       changed = check_removed(ce, &st);
+                       if (changed) {
+                               if (changed < 0) {
+                                       perror(ce->name);
+                                       continue;
+                               }
+                               diff_addremove(&revs->diffopt, '-', ce->ce_mode,
+                                              ce->sha1, !is_null_sha1(ce->sha1),
+                                              ce->name, 0);
+                               continue;
+                       } else if (ce->ce_flags & CE_INTENT_TO_ADD) {
+                               diff_addremove(&revs->diffopt, '+', ce->ce_mode,
+                                              EMPTY_BLOB_SHA1_BIN, 0,
+                                              ce->name, 0);
                                continue;
                        }
-                       diff_addremove(&revs->diffopt, '-', ce->ce_mode,
-                                      ce->sha1, !is_null_sha1(ce->sha1),
-                                      ce->name, 0);
-                       continue;
+
+                       changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
+                                                           ce_option, &dirty_submodule);
+                       newmode = ce_mode_from_stat(ce, st.st_mode);
                }
-               changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
-                                                   ce_option, &dirty_submodule);
+
                if (!changed && !dirty_submodule) {
                        ce_mark_uptodate(ce);
                        if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
                                continue;
                }
                oldmode = ce->ce_mode;
-               newmode = ce_mode_from_stat(ce, st.st_mode);
+               old_sha1 = ce->sha1;
+               new_sha1 = changed ? null_sha1 : ce->sha1;
                diff_change(&revs->diffopt, oldmode, newmode,
-                           ce->sha1, (changed ? null_sha1 : ce->sha1),
-                           !is_null_sha1(ce->sha1), (changed ? 0 : !is_null_sha1(ce->sha1)),
+                           old_sha1, new_sha1,
+                           !is_null_sha1(old_sha1),
+                           !is_null_sha1(new_sha1),
                            ce->name, 0, dirty_submodule);
 
        }
@@ -326,14 +344,14 @@ static int show_modified(struct rev_info *revs,
                memcpy(p->path, new->name, pathlen);
                p->path[pathlen] = 0;
                p->mode = mode;
-               hashclr(p->sha1);
+               oidclr(&p->oid);
                memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));
                p->parent[0].status = DIFF_STATUS_MODIFIED;
                p->parent[0].mode = new->ce_mode;
-               hashcpy(p->parent[0].sha1, new->sha1);
+               hashcpy(p->parent[0].oid.hash, new->sha1);
                p->parent[1].status = DIFF_STATUS_MODIFIED;
                p->parent[1].mode = old->ce_mode;
-               hashcpy(p->parent[1].sha1, old->sha1);
+               hashcpy(p->parent[1].oid.hash, old->sha1);
                show_combined_diff(p, 2, revs->dense_combined_merges, revs);
                free(p);
                return 0;
@@ -363,6 +381,13 @@ static void do_oneway_diff(struct unpack_trees_options *o,
        struct rev_info *revs = o->unpack_data;
        int match_missing, cached;
 
+       /* i-t-a entries do not actually exist in the index */
+       if (idx && (idx->ce_flags & CE_INTENT_TO_ADD)) {
+               idx = NULL;
+               if (!tree)
+                       return; /* nothing to diff.. */
+       }
+
        /* if the entry is not checked out, don't examine work tree */
        cached = o->index_only ||
                (idx && ((idx->ce_flags & CE_VALID) || ce_skip_worktree(idx)));