]>
Commit | Line | Data |
---|---|---|
22f77b77 JH |
1 | /* |
2 | * Copyright (c) 2005 Junio C Hamano | |
3 | */ | |
4 | ||
5 | #include "cache.h" | |
6 | #include "diff.h" | |
e8cc9cd9 | 7 | #include "builtin.h" |
22f77b77 | 8 | |
6b5ee137 | 9 | static struct diff_options diff_options; |
22f77b77 | 10 | |
4d1f1190 | 11 | static const char diff_stages_usage[] = |
dda2d79a JH |
12 | "git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]" |
13 | COMMON_DIFF_OPTIONS_HELP; | |
22f77b77 | 14 | |
77882f60 | 15 | static void diff_stages(int stage1, int stage2, const char **pathspec) |
9939664a JH |
16 | { |
17 | int i = 0; | |
18 | while (i < active_nr) { | |
19 | struct cache_entry *ce, *stages[4] = { NULL, }; | |
20 | struct cache_entry *one, *two; | |
21 | const char *name; | |
77882f60 JH |
22 | int len, skip; |
23 | ||
9939664a | 24 | ce = active_cache[i]; |
77882f60 | 25 | skip = !ce_path_match(ce, pathspec); |
9939664a JH |
26 | len = ce_namelen(ce); |
27 | name = ce->name; | |
28 | for (;;) { | |
29 | int stage = ce_stage(ce); | |
30 | stages[stage] = ce; | |
31 | if (active_nr <= ++i) | |
32 | break; | |
33 | ce = active_cache[i]; | |
34 | if (ce_namelen(ce) != len || | |
35 | memcmp(name, ce->name, len)) | |
36 | break; | |
37 | } | |
38 | one = stages[stage1]; | |
39 | two = stages[stage2]; | |
77882f60 JH |
40 | |
41 | if (skip || (!one && !two)) | |
9939664a JH |
42 | continue; |
43 | if (!one) | |
6b5ee137 | 44 | diff_addremove(&diff_options, '+', ntohl(two->ce_mode), |
9939664a JH |
45 | two->sha1, name, NULL); |
46 | else if (!two) | |
6b5ee137 | 47 | diff_addremove(&diff_options, '-', ntohl(one->ce_mode), |
9939664a | 48 | one->sha1, name, NULL); |
a89fccd2 | 49 | else if (hashcmp(one->sha1, two->sha1) || |
4727f640 | 50 | (one->ce_mode != two->ce_mode) || |
6b5ee137 JH |
51 | diff_options.find_copies_harder) |
52 | diff_change(&diff_options, | |
53 | ntohl(one->ce_mode), ntohl(two->ce_mode), | |
4727f640 | 54 | one->sha1, two->sha1, name, NULL); |
9939664a JH |
55 | } |
56 | } | |
57 | ||
a633fca0 | 58 | int cmd_diff_stages(int ac, const char **av, const char *prefix) |
22f77b77 | 59 | { |
9939664a | 60 | int stage1, stage2; |
77882f60 | 61 | const char **pathspec = NULL; |
9ce392f4 | 62 | |
83ad63cf | 63 | git_config(git_default_config); /* no "diff" UI options */ |
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 | ||
c9b5ef99 TH |
87 | if (!diff_options.output_format) |
88 | diff_options.output_format = DIFF_FORMAT_RAW; | |
89 | ||
22f77b77 JH |
90 | if (ac < 3 || |
91 | sscanf(av[1], "%d", &stage1) != 1 || | |
92 | ! (0 <= stage1 && stage1 <= 3) || | |
93 | sscanf(av[2], "%d", &stage2) != 1 || | |
6b5ee137 | 94 | ! (0 <= stage2 && stage2 <= 3)) |
22f77b77 JH |
95 | usage(diff_stages_usage); |
96 | ||
97 | av += 3; /* The rest from av[0] are for paths restriction. */ | |
77882f60 | 98 | pathspec = get_pathspec(prefix, av); |
22f77b77 | 99 | |
6b5ee137 JH |
100 | if (diff_setup_done(&diff_options) < 0) |
101 | usage(diff_stages_usage); | |
22f77b77 | 102 | |
77882f60 | 103 | diff_stages(stage1, stage2, pathspec); |
6b5ee137 JH |
104 | diffcore_std(&diff_options); |
105 | diff_flush(&diff_options); | |
22f77b77 JH |
106 | return 0; |
107 | } |