Hi, On Tue, 27 Jun 2006, Alex Riesen wrote: > I finally got pis^Witched enough by my platform at work and decided > to start the effort of converting Fredriks git-merge-recursive to C. Darn. I was working on the same thing since a few days. A few remarks: - have you considered using run-command() instead of system()? - in setup_index(), you set GIT_INDEX_FILE, but I do not think that the rest of git picks up on it. environment.cc:get_index_file() checks if the variable was set already, but not if it changed. - You work with linked lists all the time. This is slow, especially for the checks, if a file/directory is already there. Sorted lists would be way faster there. Since you encapsulated that, it is no problem to change that later (before inclusion). - is not "struct commit_list" more appropriate than "struct graph"? - I always wondered why merge-recursive did not call merge-base, but did its own thing. Hmm? > It still uses some calls to git programs (git-update-index, > git-hash-object, git-diff-tree and git-write-tree), and merge(1) has > the labels (-L) missing - I was unsure how to tackle this on windows - > it has only argv[1]. See above. > And it needs to be cleaned up a bit (a lot) - Python is not exactly > what you'd call "C-conversion-friendly-language", and I am not an > expert (as in "git-merge-recursive.py is my first Python experience"). No problem. Since I already worked on it, that should be easy. > To my deep disappointment, it didn't work out as good as I hoped: one > program I see most often and for longest time in the process list > (git-diff-tree) is a too complex thing to be put directly into > merge-recursive.c, so any help in this direction will be greatly > appreciated. Maybe something like this (ripped from my fragment of merge-recursive.c): static struct container *get_renames(struct tree *tree, struct tree *o, struct tree *a, struct tree *b, struct container *cache_entries) { /* * Get information of all renames which occured between 'oTree' and * 'tree'. We need the three trees in the merge ('oTree', 'aTree' and * 'bTree') to be able to associate the correct cache entries with the * rename information. 'tree' is always equal to either aTree or bTree. */ int i; struct diff_options diff_opts; struct container *result = xcalloc(1, sizeof(struct container)); diff_setup(&diff_opts); diff_opts.recursive = 1; diff_opts.detect_rename = DIFF_DETECT_RENAME; if (diff_setup_done(&diff_opts) < 0) die("diff_setup_done failed"); diff_tree_sha1(o->object.sha1, tree->object.sha1, "", &diff_opts); diffcore_std(&diff_opts); for (i = 0; i < diff_queued_diff.nr; i++) { struct diff_filepair *p = diff_queued_diff.queue[i]; if (p->status == 'R') { struct entry *entry = get_rename(result, p->one->path); struct rename *rename = entry->priv; rename->src.mode = p->one->mode; rename->src.sha1 = p->one->sha1; rename->src.data = get_cache_entry(cache_entries, p->one->path)->priv; fake_stage_data(rename->src.data, o, a, b); rename->dest.path = p->two->path; rename->dest.mode = p->two->mode; rename->dest.sha1 = p->two->sha1; rename->dest.data = get_cache_entry(cache_entries, p->two->path)->priv; fake_stage_data(rename->dest.data, o, a, b); rename->score = p->score; } } return result; } It is not tested, evidently, since I did not get the merge-base code integrated yet. But it should give you an idea. Ciao, Dscho - : send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html