Skip to content

Commit

Permalink
Merge branch 'lt/unpack-trees'
Browse files Browse the repository at this point in the history
* lt/unpack-trees:
  unpack_trees(): fix diff-index regression.
  traverse_trees_recursive(): propagate merge errors up
  unpack_trees(): minor memory leak fix in unused destination index
  Make 'unpack_trees()' have a separate source and destination index
  Make 'unpack_trees()' take the index to work on as an argument
  Add 'const' where appropriate to index handling functions
  Fix tree-walking compare_entry() in the presense of --prefix
  Move 'unpack_trees()' over to 'traverse_trees()' interface
  Make 'traverse_trees()' traverse conflicting DF entries in parallel
  Add return value to 'traverse_tree()' callback
  Make 'traverse_tree()' use linked structure rather than 'const char *base'
  Add 'df_name_compare()' helper function
  • Loading branch information
Junio C Hamano committed Mar 12, 2008
2 parents b81a7b5 + 20a16eb commit b85997d
Show file tree
Hide file tree
Showing 15 changed files with 503 additions and 452 deletions.
9 changes: 9 additions & 0 deletions builtin-checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,16 @@ static int reset_to_new(struct tree *tree, int quiet)
{
struct unpack_trees_options opts;
struct tree_desc tree_desc;

memset(&opts, 0, sizeof(opts));
opts.head_idx = -1;
opts.update = 1;
opts.reset = 1;
opts.merge = 1;
opts.fn = oneway_merge;
opts.verbose_update = !quiet;
opts.src_index = &the_index;
opts.dst_index = &the_index;
parse_tree(tree);
init_tree_desc(&tree_desc, tree->buffer, tree->size);
if (unpack_trees(1, &tree_desc, &opts))
Expand All @@ -170,13 +173,16 @@ static void reset_clean_to_new(struct tree *tree, int quiet)
{
struct unpack_trees_options opts;
struct tree_desc tree_desc;

memset(&opts, 0, sizeof(opts));
opts.head_idx = -1;
opts.skip_unmerged = 1;
opts.reset = 1;
opts.merge = 1;
opts.fn = oneway_merge;
opts.verbose_update = !quiet;
opts.src_index = &the_index;
opts.dst_index = &the_index;
parse_tree(tree);
init_tree_desc(&tree_desc, tree->buffer, tree->size);
if (unpack_trees(1, &tree_desc, &opts))
Expand Down Expand Up @@ -224,8 +230,11 @@ static int merge_working_tree(struct checkout_opts *opts,
struct tree_desc trees[2];
struct tree *tree;
struct unpack_trees_options topts;

memset(&topts, 0, sizeof(topts));
topts.head_idx = -1;
topts.src_index = &the_index;
topts.dst_index = &the_index;

refresh_cache(REFRESH_QUIET);

Expand Down
2 changes: 2 additions & 0 deletions builtin-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ static void create_base_index(void)
opts.head_idx = 1;
opts.index_only = 1;
opts.merge = 1;
opts.src_index = &the_index;
opts.dst_index = &the_index;

opts.fn = oneway_merge;
tree = parse_tree_indirect(head_sha1);
Expand Down
2 changes: 2 additions & 0 deletions builtin-merge-recursive.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ static int git_merge_trees(int index_only,
opts.merge = 1;
opts.head_idx = 2;
opts.fn = threeway_merge;
opts.src_index = &the_index;
opts.dst_index = &the_index;

init_tree_desc_from_tree(t+0, common);
init_tree_desc_from_tree(t+1, head);
Expand Down
23 changes: 2 additions & 21 deletions builtin-read-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)

memset(&opts, 0, sizeof(opts));
opts.head_idx = -1;
opts.src_index = &the_index;
opts.dst_index = &the_index;

git_config(git_default_config);

Expand Down Expand Up @@ -220,27 +222,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
if ((opts.dir && !opts.update))
die("--exclude-per-directory is meaningless unless -u");

if (opts.prefix) {
int pfxlen = strlen(opts.prefix);
int pos;
if (opts.prefix[pfxlen-1] != '/')
die("prefix must end with /");
if (stage != 2)
die("binding merge takes only one tree");
pos = cache_name_pos(opts.prefix, pfxlen);
if (0 <= pos)
die("corrupt index file");
pos = -pos-1;
if (pos < active_nr &&
!strncmp(active_cache[pos]->name, opts.prefix, pfxlen))
die("subdirectory '%s' already exists.", opts.prefix);
pos = cache_name_pos(opts.prefix, pfxlen-1);
if (0 <= pos)
die("file '%.*s' already exists.",
pfxlen-1, opts.prefix);
opts.pos = -1 - pos;
}

if (opts.merge) {
if (stage < 2)
die("just how do you expect me to merge %d trees?", stage-1);
Expand Down
11 changes: 6 additions & 5 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,12 +346,12 @@ extern void verify_non_filename(const char *prefix, const char *name);
/* Initialize and use the cache information */
extern int read_index(struct index_state *);
extern int read_index_from(struct index_state *, const char *path);
extern int write_index(struct index_state *, int newfd);
extern int write_index(const struct index_state *, int newfd);
extern int discard_index(struct index_state *);
extern int unmerged_index(struct index_state *);
extern int unmerged_index(const struct index_state *);
extern int verify_path(const char *path);
extern int index_name_exists(struct index_state *istate, const char *name, int namelen);
extern int index_name_pos(struct index_state *, const char *name, int namelen);
extern int index_name_pos(const struct index_state *, const char *name, int namelen);
#define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
#define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */
#define ADD_CACHE_SKIP_DFCHECK 4 /* Ok to skip DF conflict checks */
Expand All @@ -368,8 +368,8 @@ extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
#define CE_MATCH_IGNORE_VALID 01
/* do not check the contents but report dirty on racily-clean entries */
#define CE_MATCH_RACY_IS_DIRTY 02
extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);

extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
Expand Down Expand Up @@ -536,6 +536,7 @@ extern int create_symref(const char *ref, const char *refs_heads_master, const c
extern int validate_headref(const char *ref);

extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
extern int df_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);

extern void *read_object_with_reference(const unsigned char *sha1,
Expand Down
55 changes: 21 additions & 34 deletions diff-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,8 +600,7 @@ static void mark_merge_entries(void)
*/
static void do_oneway_diff(struct unpack_trees_options *o,
struct cache_entry *idx,
struct cache_entry *tree,
int idx_pos, int idx_nr)
struct cache_entry *tree)
{
struct rev_info *revs = o->unpack_data;
int match_missing, cached;
Expand Down Expand Up @@ -642,32 +641,19 @@ static void do_oneway_diff(struct unpack_trees_options *o,
show_modified(revs, tree, idx, 1, cached, match_missing);
}

/*
* Count how many index entries go with the first one
*/
static inline int count_skip(const struct cache_entry *src, int pos)
static inline void skip_same_name(struct cache_entry *ce, struct unpack_trees_options *o)
{
int skip = 1;

/* We can only have multiple entries if the first one is not stage-0 */
if (ce_stage(src)) {
struct cache_entry **p = active_cache + pos;
int namelen = ce_namelen(src);

for (;;) {
const struct cache_entry *ce;
pos++;
if (pos >= active_nr)
break;
ce = *++p;
if (ce_namelen(ce) != namelen)
break;
if (memcmp(ce->name, src->name, namelen))
break;
skip++;
}
int len = ce_namelen(ce);
const struct index_state *index = o->src_index;

while (o->pos < index->cache_nr) {
struct cache_entry *next = index->cache[o->pos];
if (len != ce_namelen(next))
break;
if (memcmp(ce->name, next->name, len))
break;
o->pos++;
}
return skip;
}

/*
Expand All @@ -685,17 +671,14 @@ static inline int count_skip(const struct cache_entry *src, int pos)
* the fairly complex unpack_trees() semantic requirements, including
* the skipping, the path matching, the type conflict cases etc.
*/
static int oneway_diff(struct cache_entry **src,
struct unpack_trees_options *o,
int index_pos)
static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
{
int skip = 0;
struct cache_entry *idx = src[0];
struct cache_entry *tree = src[1];
struct rev_info *revs = o->unpack_data;

if (index_pos >= 0)
skip = count_skip(idx, index_pos);
if (idx && ce_stage(idx))
skip_same_name(idx, o);

/*
* Unpack-trees generates a DF/conflict entry if
Expand All @@ -707,9 +690,9 @@ static int oneway_diff(struct cache_entry **src,
tree = NULL;

if (ce_path_match(idx ? idx : tree, revs->prune_data))
do_oneway_diff(o, idx, tree, index_pos, skip);
do_oneway_diff(o, idx, tree);

return skip;
return 0;
}

int run_diff_index(struct rev_info *revs, int cached)
Expand All @@ -734,6 +717,8 @@ int run_diff_index(struct rev_info *revs, int cached)
opts.merge = 1;
opts.fn = oneway_diff;
opts.unpack_data = revs;
opts.src_index = &the_index;
opts.dst_index = NULL;

init_tree_desc(&t, tree->buffer, tree->size);
if (unpack_trees(1, &t, &opts))
Expand Down Expand Up @@ -787,6 +772,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
opts.merge = 1;
opts.fn = oneway_diff;
opts.unpack_data = &revs;
opts.src_index = &the_index;
opts.dst_index = &the_index;

init_tree_desc(&t, tree->buffer, tree->size);
if (unpack_trees(1, &t, &opts))
Expand Down
6 changes: 3 additions & 3 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* the existing entry, or the empty slot if none existed. The caller
* can then look at the (*ptr) to see whether it existed or not.
*/
static struct hash_table_entry *lookup_hash_entry(unsigned int hash, struct hash_table *table)
static struct hash_table_entry *lookup_hash_entry(unsigned int hash, const struct hash_table *table)
{
unsigned int size = table->size, nr = hash % size;
struct hash_table_entry *array = table->array;
Expand Down Expand Up @@ -66,7 +66,7 @@ static void grow_hash_table(struct hash_table *table)
free(old_array);
}

void *lookup_hash(unsigned int hash, struct hash_table *table)
void *lookup_hash(unsigned int hash, const struct hash_table *table)
{
if (!table->array)
return NULL;
Expand All @@ -81,7 +81,7 @@ void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table)
return insert_hash_entry(hash, ptr, table);
}

int for_each_hash(struct hash_table *table, int (*fn)(void *))
int for_each_hash(const struct hash_table *table, int (*fn)(void *))
{
int sum = 0;
unsigned int i;
Expand Down
4 changes: 2 additions & 2 deletions hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ struct hash_table {
struct hash_table_entry *array;
};

extern void *lookup_hash(unsigned int hash, struct hash_table *table);
extern void *lookup_hash(unsigned int hash, const struct hash_table *table);
extern void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table);
extern int for_each_hash(struct hash_table *table, int (*fn)(void *));
extern int for_each_hash(const struct hash_table *table, int (*fn)(void *));
extern void free_hash(struct hash_table *table);

static inline void init_hash(struct hash_table *table)
Expand Down
Loading

0 comments on commit b85997d

Please sign in to comment.