summaryrefslogtreecommitdiff
path: root/diff-lib.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-01-30 01:11:08 -0800
committerJunio C Hamano <junkio@cox.net>2007-02-05 14:55:11 -0800
commit1cfe77333f274c9ba9879c2eb61057a790eb050f (patch)
tree5ef650c0f61f51fd5fe58997425b44684df2df94 /diff-lib.c
parent28389d45fb2161d4dcdc1bbfabbcc2fb135914c6 (diff)
downloadgit-1cfe77333f274c9ba9879c2eb61057a790eb050f.tar.gz
git-blame: no rev means start from the working tree file.
Warning: this changes the semantics. This makes "git blame" without any positive rev to start digging from the working tree copy, which is made into a fake commit whose sole parent is the HEAD. It also adds --contents <file> option to pretend as if the working tree copy has the contents of the named file. You can use '-' to make the command read from the standard input. If you want the command to start annotating from the HEAD commit, you need to explicitly give HEAD parameter. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'diff-lib.c')
-rw-r--r--diff-lib.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/diff-lib.c b/diff-lib.c
index 2c9be60ed9..91cd87742f 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -7,6 +7,7 @@
#include "diff.h"
#include "diffcore.h"
#include "revision.h"
+#include "cache-tree.h"
/*
* diff-files
@@ -271,7 +272,7 @@ static int diff_cache(struct rev_info *revs,
break;
}
/* Show difference between old and new */
- show_modified(revs,ac[1], ce, 1,
+ show_modified(revs, ac[1], ce, 1,
cached, match_missing);
break;
case 1:
@@ -372,3 +373,44 @@ int run_diff_index(struct rev_info *revs, int cached)
diff_flush(&revs->diffopt);
return ret;
}
+
+int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
+{
+ struct tree *tree;
+ struct rev_info revs;
+ int i;
+ struct cache_entry **dst;
+ struct cache_entry *last = NULL;
+
+ /*
+ * This is used by git-blame to run diff-cache internally;
+ * it potentially needs to repeatedly run this, so we will
+ * start by removing the higher order entries the last round
+ * left behind.
+ */
+ dst = active_cache;
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce = active_cache[i];
+ if (ce_stage(ce)) {
+ if (last && !strcmp(ce->name, last->name))
+ continue;
+ cache_tree_invalidate_path(active_cache_tree,
+ ce->name);
+ last = ce;
+ ce->ce_mode = 0;
+ ce->ce_flags &= ~htons(CE_STAGEMASK);
+ }
+ *dst++ = ce;
+ }
+ active_nr = dst - active_cache;
+
+ init_revisions(&revs, NULL);
+ revs.prune_data = opt->paths;
+ tree = parse_tree_indirect(tree_sha1);
+ if (!tree)
+ die("bad tree object %s", sha1_to_hex(tree_sha1));
+ if (read_tree(tree, 1, opt->paths))
+ return error("unable to read tree %s", sha1_to_hex(tree_sha1));
+ return diff_cache(&revs, active_cache, active_nr, revs.prune_data,
+ 1, 0);
+}