diff options
author | Junio C Hamano <junkio@cox.net> | 2007-01-30 01:11:08 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-02-05 14:55:11 -0800 |
commit | 1cfe77333f274c9ba9879c2eb61057a790eb050f (patch) | |
tree | 5ef650c0f61f51fd5fe58997425b44684df2df94 /diff-lib.c | |
parent | 28389d45fb2161d4dcdc1bbfabbcc2fb135914c6 (diff) | |
download | git-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.c | 44 |
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); +} |