Re: CFT: merge-recursive in C

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]