@matheusbsbs / matheus-bagliano / commits / 5a56da5806
Fork 0

read-tree: migrate to parse-options

Cleanup the documentation to explicitly state that --exclude-directory is only meaningful when used with -u. Also make the documentation more consistent with the usage message printed with read-tree --help-all. The -m, --prefix, --reset options are performing similar actions (setting some flags, read_cache_unmerged(), checking for illegal option combinations). Instead of performing these actions when the options are parsed, we delay performing them until after parse-opts has finished. The bit fields in struct unpack_trees_options have been promoted to full unsigned ints. This is necessary to avoid "foo ? 1 : 0" constructs to set these fields. Signed-off-by: Stephen Boyd <bebarino@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stephen Boyd committed Jun 25, 2009 at 22:14 UTC 5a56da58060e50980fab0f4c38203a25440d1530
3 files changed +90 -109
Documentation/git-read-tree.txt
+4 -1
@@ -8,7 +8,10 @@ git-read-tree - Reads tree information into the index
8
9 SYNOPSIS
10 --------
11 -'git read-tree' (<tree-ish> | [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
11 +'git read-tree' [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>]
12 + [-u [--exclude-per-directory=<gitignore>] | -i]]
13 + [--index-output=<file>]
14 + <tree-ish1> [<tree-ish2> [<tree-ish3>]]
15
16
17 DESCRIPTION
builtin-read-tree.c
+74 -96
@@ -12,6 +12,7 @@
12 #include "unpack-trees.h"
13 #include "dir.h"
14 #include "builtin.h"
15 +#include "parse-options.h"
16
17 static int nr_trees;
18 static struct tree *trees[MAX_UNPACK_TREES];
@@ -29,7 +30,39 @@ static int list_tree(unsigned char *sha1)
30 return 0;
31 }
32
32 -static const char read_tree_usage[] = "git read-tree (<sha> | [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])";
33 +static const char * const read_tree_usage[] = {
34 + "git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u [--exclude-per-directory=<gitignore>] | -i]] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]]",
35 + NULL
36 +};
37 +
38 +static int index_output_cb(const struct option *opt, const char *arg,
39 + int unset)
40 +{
41 + set_alternate_index_output(arg);
42 + return 0;
43 +}
44 +
45 +static int exclude_per_directory_cb(const struct option *opt, const char *arg,
46 + int unset)
47 +{
48 + struct dir_struct *dir;
49 + struct unpack_trees_options *opts;
50 +
51 + opts = (struct unpack_trees_options *)opt->value;
52 +
53 + if (opts->dir)
54 + die("more than one --exclude-per-directory given.");
55 +
56 + dir = xcalloc(1, sizeof(*opts->dir));
57 + dir->flags |= DIR_SHOW_IGNORED;
58 + dir->exclude_per_dir = arg;
59 + opts->dir = dir;
60 + /* We do not need to nor want to do read-directory
61 + * here; we are merely interested in reusing the
62 + * per directory ignore stack mechanism.
63 + */
64 + return 0;
65 +}
66
67 static struct lock_file lock_file;
68
@@ -39,6 +72,34 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
72 unsigned char sha1[20];
73 struct tree_desc t[MAX_UNPACK_TREES];
74 struct unpack_trees_options opts;
75 + int prefix_set = 0;
76 + const struct option read_tree_options[] = {
77 + { OPTION_CALLBACK, 0, "index-output", NULL, "FILE",
78 + "write resulting index to <FILE>",
79 + PARSE_OPT_NONEG, index_output_cb },
80 + OPT__VERBOSE(&opts.verbose_update),
81 + OPT_GROUP("Merging"),
82 + OPT_SET_INT('m', NULL, &opts.merge,
83 + "perform a merge in addition to a read", 1),
84 + OPT_SET_INT(0, "trivial", &opts.trivial_merges_only,
85 + "3-way merge if no file level merging required", 1),
86 + OPT_SET_INT(0, "aggressive", &opts.aggressive,
87 + "3-way merge in presence of adds and removes", 1),
88 + OPT_SET_INT(0, "reset", &opts.reset,
89 + "same as -m, but discard unmerged entries", 1),
90 + { OPTION_STRING, 0, "prefix", &opts.prefix, "<subdirectory>/",
91 + "read the tree into the index under <subdirectory>/",
92 + PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP },
93 + OPT_SET_INT('u', NULL, &opts.update,
94 + "update working tree with merge result", 1),
95 + { OPTION_CALLBACK, 0, "exclude-per-directory", &opts,
96 + "gitignore",
97 + "allow explicitly ignored files to be overwritten",
98 + PARSE_OPT_NONEG, exclude_per_directory_cb },
99 + OPT_SET_INT('i', NULL, &opts.index_only,
100 + "don't check the working tree after merging", 1),
101 + OPT_END()
102 + };
103
104 memset(&opts, 0, sizeof(opts));
105 opts.head_idx = -1;
@@ -49,104 +110,19 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
110
111 newfd = hold_locked_index(&lock_file, 1);
112
52 - for (i = 1; i < argc; i++) {
53 - const char *arg = argv[i];
54 -
55 - /* "-u" means "update", meaning that a merge will update
56 - * the working tree.
57 - */
58 - if (!strcmp(arg, "-u")) {
59 - opts.update = 1;
60 - continue;
61 - }
62 -
63 - if (!strcmp(arg, "-v")) {
64 - opts.verbose_update = 1;
65 - continue;
66 - }
67 -
68 - /* "-i" means "index only", meaning that a merge will
69 - * not even look at the working tree.
70 - */
71 - if (!strcmp(arg, "-i")) {
72 - opts.index_only = 1;
73 - continue;
74 - }
75 -
76 - if (!prefixcmp(arg, "--index-output=")) {
77 - set_alternate_index_output(arg + 15);
78 - continue;
79 - }
80 -
81 - /* "--prefix=<subdirectory>/" means keep the current index
82 - * entries and put the entries from the tree under the
83 - * given subdirectory.
84 - */
85 - if (!prefixcmp(arg, "--prefix=")) {
86 - if (stage || opts.merge || opts.prefix)
87 - usage(read_tree_usage);
88 - opts.prefix = arg + 9;
89 - opts.merge = 1;
90 - stage = 1;
91 - if (read_cache_unmerged())
92 - die("you need to resolve your current index first");
93 - continue;
94 - }
95 -
96 - /* This differs from "-m" in that we'll silently ignore
97 - * unmerged entries and overwrite working tree files that
98 - * correspond to them.
99 - */
100 - if (!strcmp(arg, "--reset")) {
101 - if (stage || opts.merge || opts.prefix)
102 - usage(read_tree_usage);
103 - opts.reset = 1;
104 - opts.merge = 1;
105 - stage = 1;
106 - read_cache_unmerged();
107 - continue;
108 - }
109 -
110 - if (!strcmp(arg, "--trivial")) {
111 - opts.trivial_merges_only = 1;
112 - continue;
113 - }
114 -
115 - if (!strcmp(arg, "--aggressive")) {
116 - opts.aggressive = 1;
117 - continue;
118 - }
113 + argc = parse_options(argc, argv, unused_prefix, read_tree_options,
114 + read_tree_usage, 0);
115
120 - /* "-m" stands for "merge", meaning we start in stage 1 */
121 - if (!strcmp(arg, "-m")) {
122 - if (stage || opts.merge || opts.prefix)
123 - usage(read_tree_usage);
124 - if (read_cache_unmerged())
125 - die("you need to resolve your current index first");
126 - stage = 1;
127 - opts.merge = 1;
128 - continue;
129 - }
116 + if (read_cache_unmerged() && (opts.prefix || opts.merge))
117 + die("You need to resolve your current index first");
118
131 - if (!prefixcmp(arg, "--exclude-per-directory=")) {
132 - struct dir_struct *dir;
133 -
134 - if (opts.dir)
135 - die("more than one --exclude-per-directory are given.");
136 -
137 - dir = xcalloc(1, sizeof(*opts.dir));
138 - dir->flags |= DIR_SHOW_IGNORED;
139 - dir->exclude_per_dir = arg + 24;
140 - opts.dir = dir;
141 - /* We do not need to nor want to do read-directory
142 - * here; we are merely interested in reusing the
143 - * per directory ignore stack mechanism.
144 - */
145 - continue;
146 - }
119 + prefix_set = opts.prefix ? 1 : 0;
120 + if (1 < opts.merge + opts.reset + prefix_set)
121 + die("Which one? -m, --reset, or --prefix?");
122 + stage = opts.merge = (opts.reset || opts.merge || prefix_set);
123
148 - if (1 < opts.index_only + opts.update)
149 - die("-u and -i at the same time makes no sense");
124 + for (i = 0; i < argc; i++) {
125 + const char *arg = argv[i];
126
127 if (get_sha1(arg, sha1))
128 die("Not a valid object name %s", arg);
@@ -154,6 +130,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
130 die("failed to unpack tree object %s", arg);
131 stage++;
132 }
133 + if (1 < opts.index_only + opts.update)
134 + die("-u and -i at the same time makes no sense");
135 if ((opts.update||opts.index_only) && !opts.merge)
136 die("%s is meaningless without -m, --reset, or --prefix",
137 opts.update ? "-u" : "-i");
unpack-trees.h
+12 -12
@@ -17,18 +17,18 @@ struct unpack_trees_error_msgs {
17 };
18
19 struct unpack_trees_options {
20 - unsigned int reset:1,
21 - merge:1,
22 - update:1,
23 - index_only:1,
24 - nontrivial_merge:1,
25 - trivial_merges_only:1,
26 - verbose_update:1,
27 - aggressive:1,
28 - skip_unmerged:1,
29 - initial_checkout:1,
30 - diff_index_cached:1,
31 - gently:1;
20 + unsigned int reset,
21 + merge,
22 + update,
23 + index_only,
24 + nontrivial_merge,
25 + trivial_merges_only,
26 + verbose_update,
27 + aggressive,
28 + skip_unmerged,
29 + initial_checkout,
30 + diff_index_cached,
31 + gently;
32 const char *prefix;
33 int pos;
34 struct dir_struct *dir;