Staging
v0.5.1
Revision 1ed91937e5cd59fdbdfa5f15f6fac132d2b21ce0 authored by Junio C Hamano on 15 December 2005, 01:30:03 UTC, committed by Junio C Hamano on 15 December 2005, 01:30:03 UTC
Oh, I hate to do this but I ended up merging big usage string
cleanups from Fredrik, git-am enhancements that made a lot of
sense for non mbox users from HPA, and rebase changes (done
independently by me and Lukas) among other things, so git is
still in perpetual state of 1.0rc.  1.0 will probably be next
Wednesday, but who knows.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2 parent s a957207 + 294c695
Raw File
diff-stages.c
/*
 * Copyright (c) 2005 Junio C Hamano
 */

#include "cache.h"
#include "diff.h"

static struct diff_options diff_options;

static const char diff_stages_usage[] =
"git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]"
COMMON_DIFF_OPTIONS_HELP;

static void diff_stages(int stage1, int stage2)
{
	int i = 0;
	while (i < active_nr) {
		struct cache_entry *ce, *stages[4] = { NULL, };
		struct cache_entry *one, *two;
		const char *name;
		int len;
		ce = active_cache[i];
		len = ce_namelen(ce);
		name = ce->name;
		for (;;) {
			int stage = ce_stage(ce);
			stages[stage] = ce;
			if (active_nr <= ++i)
				break;
			ce = active_cache[i];
			if (ce_namelen(ce) != len ||
			    memcmp(name, ce->name, len))
				break;
		}
		one = stages[stage1];
		two = stages[stage2];
		if (!one && !two)
			continue;
		if (!one)
			diff_addremove(&diff_options, '+', ntohl(two->ce_mode),
				       two->sha1, name, NULL);
		else if (!two)
			diff_addremove(&diff_options, '-', ntohl(one->ce_mode),
				       one->sha1, name, NULL);
		else if (memcmp(one->sha1, two->sha1, 20) ||
			 (one->ce_mode != two->ce_mode) ||
			 diff_options.find_copies_harder)
			diff_change(&diff_options,
				    ntohl(one->ce_mode), ntohl(two->ce_mode),
				    one->sha1, two->sha1, name, NULL);
	}
}

int main(int ac, const char **av)
{
	int stage1, stage2;

	setup_git_directory();

	git_config(git_diff_config);
	read_cache();
	diff_setup(&diff_options);
	while (1 < ac && av[1][0] == '-') {
		const char *arg = av[1];
		if (!strcmp(arg, "-r"))
			; /* as usual */
		else {
			int diff_opt_cnt;
			diff_opt_cnt = diff_opt_parse(&diff_options,
						      av+1, ac-1);
			if (diff_opt_cnt < 0)
				usage(diff_stages_usage);
			else if (diff_opt_cnt) {
				av += diff_opt_cnt;
				ac -= diff_opt_cnt;
				continue;
			}
			else
				usage(diff_stages_usage);
		}
		ac--; av++;
	}

	if (ac < 3 ||
	    sscanf(av[1], "%d", &stage1) != 1 ||
	    ! (0 <= stage1 && stage1 <= 3) ||
	    sscanf(av[2], "%d", &stage2) != 1 ||
	    ! (0 <= stage2 && stage2 <= 3))
		usage(diff_stages_usage);

	av += 3; /* The rest from av[0] are for paths restriction. */
	diff_options.paths = av;

	if (diff_setup_done(&diff_options) < 0)
		usage(diff_stages_usage);

	diff_stages(stage1, stage2);
	diffcore_std(&diff_options);
	diff_flush(&diff_options);
	return 0;
}
back to top