]>
Commit | Line | Data |
---|---|---|
22f77b77 JH |
1 | /* |
2 | * Copyright (c) 2005 Junio C Hamano | |
3 | */ | |
4 | ||
5 | #include "cache.h" | |
6 | #include "diff.h" | |
7 | ||
6b5ee137 | 8 | static struct diff_options diff_options; |
22f77b77 | 9 | |
4d1f1190 | 10 | static const char diff_stages_usage[] = |
dda2d79a JH |
11 | "git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]" |
12 | COMMON_DIFF_OPTIONS_HELP; | |
22f77b77 | 13 | |
77882f60 | 14 | static void diff_stages(int stage1, int stage2, const char **pathspec) |
9939664a JH |
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; | |
77882f60 JH |
21 | int len, skip; |
22 | ||
9939664a | 23 | ce = active_cache[i]; |
77882f60 | 24 | skip = !ce_path_match(ce, pathspec); |
9939664a JH |
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]; | |
77882f60 JH |
39 | |
40 | if (skip || (!one && !two)) | |
9939664a JH |
41 | continue; |
42 | if (!one) | |
6b5ee137 | 43 | diff_addremove(&diff_options, '+', ntohl(two->ce_mode), |
9939664a JH |
44 | two->sha1, name, NULL); |
45 | else if (!two) | |
6b5ee137 | 46 | diff_addremove(&diff_options, '-', ntohl(one->ce_mode), |
9939664a JH |
47 | one->sha1, name, NULL); |
48 | else if (memcmp(one->sha1, two->sha1, 20) || | |
4727f640 | 49 | (one->ce_mode != two->ce_mode) || |
6b5ee137 JH |
50 | diff_options.find_copies_harder) |
51 | diff_change(&diff_options, | |
52 | ntohl(one->ce_mode), ntohl(two->ce_mode), | |
4727f640 | 53 | one->sha1, two->sha1, name, NULL); |
9939664a JH |
54 | } |
55 | } | |
56 | ||
22f77b77 JH |
57 | int main(int ac, const char **av) |
58 | { | |
9939664a | 59 | int stage1, stage2; |
77882f60 JH |
60 | const char *prefix = setup_git_directory(); |
61 | const char **pathspec = NULL; | |
9ce392f4 JH |
62 | |
63 | git_config(git_diff_config); | |
22f77b77 | 64 | read_cache(); |
6b5ee137 | 65 | diff_setup(&diff_options); |
22f77b77 JH |
66 | while (1 < ac && av[1][0] == '-') { |
67 | const char *arg = av[1]; | |
68 | if (!strcmp(arg, "-r")) | |
69 | ; /* as usual */ | |
6b5ee137 JH |
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) | |
22f77b77 | 75 | usage(diff_stages_usage); |
6b5ee137 JH |
76 | else if (diff_opt_cnt) { |
77 | av += diff_opt_cnt; | |
78 | ac -= diff_opt_cnt; | |
79 | continue; | |
80 | } | |
81 | else | |
22f77b77 JH |
82 | usage(diff_stages_usage); |
83 | } | |
22f77b77 JH |
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 || | |
6b5ee137 | 91 | ! (0 <= stage2 && stage2 <= 3)) |
22f77b77 JH |
92 | usage(diff_stages_usage); |
93 | ||
94 | av += 3; /* The rest from av[0] are for paths restriction. */ | |
77882f60 | 95 | pathspec = get_pathspec(prefix, av); |
22f77b77 | 96 | |
6b5ee137 JH |
97 | if (diff_setup_done(&diff_options) < 0) |
98 | usage(diff_stages_usage); | |
22f77b77 | 99 | |
77882f60 | 100 | diff_stages(stage1, stage2, pathspec); |
6b5ee137 JH |
101 | diffcore_std(&diff_options); |
102 | diff_flush(&diff_options); | |
22f77b77 JH |
103 | return 0; |
104 | } |