read-tree: teach 1 and 2 way merges about cache-tree.
This teaches one-way and two-way "read-tree -m" (and its special form, "read-tree --reset" as well) not to discard cache-tree but invalidate only the changed parts of the tree. When switching between related branches, this helps the eventual commit (i.e. write-tree) by keeping cache-tree valid as much as possible. This does not prime cache-tree yet, but we ought to be able to do that for no-merge (i.e. reading from a tree object) case and, and also perhaps 1 way merge case. With this patch applied, switching between the tip of Linux 2.6 kernel tree and a branch that touches one path (fs/ext3/Makefile) from it invalidates only 3 paths out of 1201 cache-tree entries in the index, and subsequent write-tree takes about a half as much time as before. Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
17
read-tree.c
17
read-tree.c
@ -422,6 +422,12 @@ static void verify_uptodate(struct cache_entry *ce)
|
|||||||
die("Entry '%s' not uptodate. Cannot merge.", ce->name);
|
die("Entry '%s' not uptodate. Cannot merge.", ce->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void invalidate_ce_path(struct cache_entry *ce)
|
||||||
|
{
|
||||||
|
if (ce)
|
||||||
|
cache_tree_invalidate_path(active_cache_tree, ce->name);
|
||||||
|
}
|
||||||
|
|
||||||
static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
|
static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
|
||||||
{
|
{
|
||||||
merge->ce_flags |= htons(CE_UPDATE);
|
merge->ce_flags |= htons(CE_UPDATE);
|
||||||
@ -437,6 +443,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
|
|||||||
*merge = *old;
|
*merge = *old;
|
||||||
} else {
|
} else {
|
||||||
verify_uptodate(old);
|
verify_uptodate(old);
|
||||||
|
invalidate_ce_path(old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
merge->ce_flags &= ~htons(CE_STAGEMASK);
|
merge->ce_flags &= ~htons(CE_STAGEMASK);
|
||||||
@ -450,6 +457,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old)
|
|||||||
verify_uptodate(old);
|
verify_uptodate(old);
|
||||||
ce->ce_mode = 0;
|
ce->ce_mode = 0;
|
||||||
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD);
|
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD);
|
||||||
|
invalidate_ce_path(ce);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,8 +692,10 @@ static int oneway_merge(struct cache_entry **src)
|
|||||||
return error("Cannot do a oneway merge of %d trees",
|
return error("Cannot do a oneway merge of %d trees",
|
||||||
merge_size);
|
merge_size);
|
||||||
|
|
||||||
if (!a)
|
if (!a) {
|
||||||
|
invalidate_ce_path(old);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (old && same(old, a)) {
|
if (old && same(old, a)) {
|
||||||
return keep_entry(old);
|
return keep_entry(old);
|
||||||
}
|
}
|
||||||
@ -704,6 +714,7 @@ static int read_cache_unmerged(void)
|
|||||||
struct cache_entry *ce = active_cache[i];
|
struct cache_entry *ce = active_cache[i];
|
||||||
if (ce_stage(ce)) {
|
if (ce_stage(ce)) {
|
||||||
deleted++;
|
deleted++;
|
||||||
|
invalidate_ce_path(ce);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (deleted)
|
if (deleted)
|
||||||
@ -815,10 +826,9 @@ int main(int argc, char **argv)
|
|||||||
fn = twoway_merge;
|
fn = twoway_merge;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
fn = threeway_merge;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
fn = threeway_merge;
|
fn = threeway_merge;
|
||||||
|
cache_tree_free(&active_cache_tree);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,7 +839,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unpack_trees(fn);
|
unpack_trees(fn);
|
||||||
cache_tree_free(&active_cache_tree);
|
|
||||||
if (write_cache(newfd, active_cache, active_nr) ||
|
if (write_cache(newfd, active_cache, active_nr) ||
|
||||||
commit_index_file(&cache_file))
|
commit_index_file(&cache_file))
|
||||||
die("unable to write new index file");
|
die("unable to write new index file");
|
||||||
|
Reference in New Issue
Block a user