Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2005 Junio C Hamano |
| 3 | */ |
| 4 | |
| 5 | #include "cache.h" |
| 6 | #include "diff.h" |
| 7 | |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 8 | static struct diff_options diff_options; |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 9 | |
Petr Baudis | 4d1f119 | 2005-07-29 11:01:26 +0200 | [diff] [blame] | 10 | static const char diff_stages_usage[] = |
Junio C Hamano | dda2d79 | 2005-07-13 12:52:35 -0700 | [diff] [blame] | 11 | "git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]" |
| 12 | COMMON_DIFF_OPTIONS_HELP; |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 13 | |
Junio C Hamano | 77882f6 | 2006-04-10 15:57:24 -0700 | [diff] [blame] | 14 | static void diff_stages(int stage1, int stage2, const char **pathspec) |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 15 | { |
| 16 | int i = 0; |
| 17 | while (i < active_nr) { |
| 18 | struct cache_entry *ce, *stages[4] = { NULL, }; |
| 19 | struct cache_entry *one, *two; |
| 20 | const char *name; |
Junio C Hamano | 77882f6 | 2006-04-10 15:57:24 -0700 | [diff] [blame] | 21 | int len, skip; |
| 22 | |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 23 | ce = active_cache[i]; |
Junio C Hamano | 77882f6 | 2006-04-10 15:57:24 -0700 | [diff] [blame] | 24 | skip = !ce_path_match(ce, pathspec); |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 25 | len = ce_namelen(ce); |
| 26 | name = ce->name; |
| 27 | for (;;) { |
| 28 | int stage = ce_stage(ce); |
| 29 | stages[stage] = ce; |
| 30 | if (active_nr <= ++i) |
| 31 | break; |
| 32 | ce = active_cache[i]; |
| 33 | if (ce_namelen(ce) != len || |
| 34 | memcmp(name, ce->name, len)) |
| 35 | break; |
| 36 | } |
| 37 | one = stages[stage1]; |
| 38 | two = stages[stage2]; |
Junio C Hamano | 77882f6 | 2006-04-10 15:57:24 -0700 | [diff] [blame] | 39 | |
| 40 | if (skip || (!one && !two)) |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 41 | continue; |
| 42 | if (!one) |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 43 | diff_addremove(&diff_options, '+', ntohl(two->ce_mode), |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 44 | two->sha1, name, NULL); |
| 45 | else if (!two) |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 46 | diff_addremove(&diff_options, '-', ntohl(one->ce_mode), |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 47 | one->sha1, name, NULL); |
| 48 | else if (memcmp(one->sha1, two->sha1, 20) || |
Junio C Hamano | 4727f64 | 2005-06-19 13:14:05 -0700 | [diff] [blame] | 49 | (one->ce_mode != two->ce_mode) || |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 50 | diff_options.find_copies_harder) |
| 51 | diff_change(&diff_options, |
| 52 | ntohl(one->ce_mode), ntohl(two->ce_mode), |
Junio C Hamano | 4727f64 | 2005-06-19 13:14:05 -0700 | [diff] [blame] | 53 | one->sha1, two->sha1, name, NULL); |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 54 | } |
| 55 | } |
| 56 | |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 57 | int main(int ac, const char **av) |
| 58 | { |
Junio C Hamano | 9939664 | 2005-06-10 18:44:36 -0700 | [diff] [blame] | 59 | int stage1, stage2; |
Junio C Hamano | 77882f6 | 2006-04-10 15:57:24 -0700 | [diff] [blame] | 60 | const char *prefix = setup_git_directory(); |
| 61 | const char **pathspec = NULL; |
Junio C Hamano | 9ce392f | 2005-11-21 22:52:37 -0800 | [diff] [blame] | 62 | |
| 63 | git_config(git_diff_config); |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 64 | read_cache(); |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 65 | diff_setup(&diff_options); |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 66 | while (1 < ac && av[1][0] == '-') { |
| 67 | const char *arg = av[1]; |
| 68 | if (!strcmp(arg, "-r")) |
| 69 | ; /* as usual */ |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 70 | else { |
| 71 | int diff_opt_cnt; |
| 72 | diff_opt_cnt = diff_opt_parse(&diff_options, |
| 73 | av+1, ac-1); |
| 74 | if (diff_opt_cnt < 0) |
| 75 | usage(diff_stages_usage); |
| 76 | else if (diff_opt_cnt) { |
| 77 | av += diff_opt_cnt; |
| 78 | ac -= diff_opt_cnt; |
| 79 | continue; |
| 80 | } |
| 81 | else |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 82 | usage(diff_stages_usage); |
| 83 | } |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 84 | ac--; av++; |
| 85 | } |
| 86 | |
| 87 | if (ac < 3 || |
| 88 | sscanf(av[1], "%d", &stage1) != 1 || |
| 89 | ! (0 <= stage1 && stage1 <= 3) || |
| 90 | sscanf(av[2], "%d", &stage2) != 1 || |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 91 | ! (0 <= stage2 && stage2 <= 3)) |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 92 | usage(diff_stages_usage); |
| 93 | |
| 94 | av += 3; /* The rest from av[0] are for paths restriction. */ |
Junio C Hamano | 77882f6 | 2006-04-10 15:57:24 -0700 | [diff] [blame] | 95 | pathspec = get_pathspec(prefix, av); |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 96 | |
| 97 | if (diff_setup_done(&diff_options) < 0) |
| 98 | usage(diff_stages_usage); |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 99 | |
Junio C Hamano | 77882f6 | 2006-04-10 15:57:24 -0700 | [diff] [blame] | 100 | diff_stages(stage1, stage2, pathspec); |
Junio C Hamano | 6b5ee13 | 2005-09-21 00:00:47 -0700 | [diff] [blame] | 101 | diffcore_std(&diff_options); |
| 102 | diff_flush(&diff_options); |
Junio C Hamano | 22f77b7 | 2005-06-09 15:13:13 -0700 | [diff] [blame] | 103 | return 0; |
| 104 | } |