/src/git/builtin/read-tree.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * GIT - The information manager from hell |
3 | | * |
4 | | * Copyright (C) Linus Torvalds, 2005 |
5 | | */ |
6 | | |
7 | | #include "builtin.h" |
8 | | #include "config.h" |
9 | | #include "gettext.h" |
10 | | #include "hex.h" |
11 | | #include "lockfile.h" |
12 | | #include "object.h" |
13 | | #include "object-name.h" |
14 | | #include "tree.h" |
15 | | #include "tree-walk.h" |
16 | | #include "cache-tree.h" |
17 | | #include "unpack-trees.h" |
18 | | #include "parse-options.h" |
19 | | #include "repository.h" |
20 | | #include "resolve-undo.h" |
21 | | #include "setup.h" |
22 | | #include "sparse-index.h" |
23 | | #include "submodule.h" |
24 | | |
25 | | static int nr_trees; |
26 | | static int read_empty; |
27 | | static struct tree *trees[MAX_UNPACK_TREES]; |
28 | | |
29 | | static int list_tree(struct object_id *oid) |
30 | 0 | { |
31 | 0 | struct tree *tree; |
32 | |
|
33 | 0 | if (nr_trees >= MAX_UNPACK_TREES) |
34 | 0 | die("I cannot read more than %d trees", MAX_UNPACK_TREES); |
35 | 0 | tree = parse_tree_indirect(oid); |
36 | 0 | if (!tree) |
37 | 0 | return -1; |
38 | 0 | trees[nr_trees++] = tree; |
39 | 0 | return 0; |
40 | 0 | } |
41 | | |
42 | | static const char * const read_tree_usage[] = { |
43 | | N_("git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>)\n" |
44 | | " [-u | -i]] [--index-output=<file>] [--no-sparse-checkout]\n" |
45 | | " (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"), |
46 | | NULL |
47 | | }; |
48 | | |
49 | | static int index_output_cb(const struct option *opt UNUSED, const char *arg, |
50 | | int unset) |
51 | 0 | { |
52 | 0 | BUG_ON_OPT_NEG(unset); |
53 | 0 | set_alternate_index_output(arg); |
54 | 0 | return 0; |
55 | 0 | } |
56 | | |
57 | | static int exclude_per_directory_cb(const struct option *opt, const char *arg, |
58 | | int unset) |
59 | 0 | { |
60 | 0 | struct unpack_trees_options *opts; |
61 | |
|
62 | 0 | BUG_ON_OPT_NEG(unset); |
63 | | |
64 | 0 | opts = (struct unpack_trees_options *)opt->value; |
65 | |
|
66 | 0 | if (!opts->update) |
67 | 0 | die("--exclude-per-directory is meaningless unless -u"); |
68 | 0 | if (strcmp(arg, ".gitignore")) |
69 | 0 | die("--exclude-per-directory argument must be .gitignore"); |
70 | 0 | return 0; |
71 | 0 | } |
72 | | |
73 | | static void debug_stage(const char *label, const struct cache_entry *ce, |
74 | | struct unpack_trees_options *o) |
75 | 0 | { |
76 | 0 | printf("%s ", label); |
77 | 0 | if (!ce) |
78 | 0 | printf("(missing)\n"); |
79 | 0 | else if (ce == o->df_conflict_entry) |
80 | 0 | printf("(conflict)\n"); |
81 | 0 | else |
82 | 0 | printf("%06o #%d %s %.8s\n", |
83 | 0 | ce->ce_mode, ce_stage(ce), ce->name, |
84 | 0 | oid_to_hex(&ce->oid)); |
85 | 0 | } |
86 | | |
87 | | static int debug_merge(const struct cache_entry * const *stages, |
88 | | struct unpack_trees_options *o) |
89 | 0 | { |
90 | 0 | int i; |
91 | |
|
92 | 0 | printf("* %d-way merge\n", o->internal.merge_size); |
93 | 0 | debug_stage("index", stages[0], o); |
94 | 0 | for (i = 1; i <= o->internal.merge_size; i++) { |
95 | 0 | char buf[24]; |
96 | 0 | xsnprintf(buf, sizeof(buf), "ent#%d", i); |
97 | 0 | debug_stage(buf, stages[i], o); |
98 | 0 | } |
99 | 0 | return 0; |
100 | 0 | } |
101 | | |
102 | | static int git_read_tree_config(const char *var, const char *value, |
103 | | const struct config_context *ctx, void *cb) |
104 | 0 | { |
105 | 0 | if (!strcmp(var, "submodule.recurse")) |
106 | 0 | return git_default_submodule_config(var, value, cb); |
107 | | |
108 | 0 | return git_default_config(var, value, ctx, cb); |
109 | 0 | } |
110 | | |
111 | | int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) |
112 | 0 | { |
113 | 0 | int i, stage = 0; |
114 | 0 | struct object_id oid; |
115 | 0 | struct tree_desc t[MAX_UNPACK_TREES]; |
116 | 0 | struct unpack_trees_options opts; |
117 | 0 | int prefix_set = 0; |
118 | 0 | struct lock_file lock_file = LOCK_INIT; |
119 | 0 | const struct option read_tree_options[] = { |
120 | 0 | OPT__SUPER_PREFIX(&opts.super_prefix), |
121 | 0 | OPT_CALLBACK_F(0, "index-output", NULL, N_("file"), |
122 | 0 | N_("write resulting index to <file>"), |
123 | 0 | PARSE_OPT_NONEG, index_output_cb), |
124 | 0 | OPT_BOOL(0, "empty", &read_empty, |
125 | 0 | N_("only empty the index")), |
126 | 0 | OPT__VERBOSE(&opts.verbose_update, N_("be verbose")), |
127 | 0 | OPT_GROUP(N_("Merging")), |
128 | 0 | OPT_BOOL('m', NULL, &opts.merge, |
129 | 0 | N_("perform a merge in addition to a read")), |
130 | 0 | OPT_BOOL(0, "trivial", &opts.trivial_merges_only, |
131 | 0 | N_("3-way merge if no file level merging required")), |
132 | 0 | OPT_BOOL(0, "aggressive", &opts.aggressive, |
133 | 0 | N_("3-way merge in presence of adds and removes")), |
134 | 0 | OPT_BOOL(0, "reset", &opts.reset, |
135 | 0 | N_("same as -m, but discard unmerged entries")), |
136 | 0 | { OPTION_STRING, 0, "prefix", &opts.prefix, N_("<subdirectory>/"), |
137 | 0 | N_("read the tree into the index under <subdirectory>/"), |
138 | 0 | PARSE_OPT_NONEG }, |
139 | 0 | OPT_BOOL('u', NULL, &opts.update, |
140 | 0 | N_("update working tree with merge result")), |
141 | 0 | OPT_CALLBACK_F(0, "exclude-per-directory", &opts, |
142 | 0 | N_("gitignore"), |
143 | 0 | N_("allow explicitly ignored files to be overwritten"), |
144 | 0 | PARSE_OPT_NONEG, exclude_per_directory_cb), |
145 | 0 | OPT_BOOL('i', NULL, &opts.index_only, |
146 | 0 | N_("don't check the working tree after merging")), |
147 | 0 | OPT__DRY_RUN(&opts.dry_run, N_("don't update the index or the work tree")), |
148 | 0 | OPT_BOOL(0, "no-sparse-checkout", &opts.skip_sparse_checkout, |
149 | 0 | N_("skip applying sparse checkout filter")), |
150 | 0 | OPT_BOOL(0, "debug-unpack", &opts.internal.debug_unpack, |
151 | 0 | N_("debug unpack-trees")), |
152 | 0 | OPT_CALLBACK_F(0, "recurse-submodules", NULL, |
153 | 0 | "checkout", "control recursive updating of submodules", |
154 | 0 | PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater), |
155 | 0 | OPT__QUIET(&opts.quiet, N_("suppress feedback messages")), |
156 | 0 | OPT_END() |
157 | 0 | }; |
158 | |
|
159 | 0 | memset(&opts, 0, sizeof(opts)); |
160 | 0 | opts.head_idx = -1; |
161 | 0 | opts.src_index = the_repository->index; |
162 | 0 | opts.dst_index = the_repository->index; |
163 | |
|
164 | 0 | git_config(git_read_tree_config, NULL); |
165 | |
|
166 | 0 | argc = parse_options(argc, argv, cmd_prefix, read_tree_options, |
167 | 0 | read_tree_usage, 0); |
168 | |
|
169 | 0 | prefix_set = opts.prefix ? 1 : 0; |
170 | 0 | if (1 < opts.merge + opts.reset + prefix_set) |
171 | 0 | die("Which one? -m, --reset, or --prefix?"); |
172 | | |
173 | | /* Prefix should not start with a directory separator */ |
174 | 0 | if (opts.prefix && opts.prefix[0] == '/') |
175 | 0 | die("Invalid prefix, prefix cannot start with '/'"); |
176 | | |
177 | 0 | if (opts.reset) |
178 | 0 | opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED; |
179 | |
|
180 | 0 | prepare_repo_settings(the_repository); |
181 | 0 | the_repository->settings.command_requires_full_index = 0; |
182 | |
|
183 | 0 | repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR); |
184 | | |
185 | | /* |
186 | | * NEEDSWORK |
187 | | * |
188 | | * The old index should be read anyway even if we're going to |
189 | | * destroy all index entries because we still need to preserve |
190 | | * certain information such as index version or split-index |
191 | | * mode. |
192 | | */ |
193 | |
|
194 | 0 | if (opts.reset || opts.merge || opts.prefix) { |
195 | 0 | if (repo_read_index_unmerged(the_repository) && (opts.prefix || opts.merge)) |
196 | 0 | die(_("You need to resolve your current index first")); |
197 | 0 | stage = opts.merge = 1; |
198 | 0 | } |
199 | 0 | resolve_undo_clear_index(the_repository->index); |
200 | |
|
201 | 0 | for (i = 0; i < argc; i++) { |
202 | 0 | const char *arg = argv[i]; |
203 | |
|
204 | 0 | if (repo_get_oid(the_repository, arg, &oid)) |
205 | 0 | die("Not a valid object name %s", arg); |
206 | 0 | if (list_tree(&oid) < 0) |
207 | 0 | die("failed to unpack tree object %s", arg); |
208 | 0 | stage++; |
209 | 0 | } |
210 | 0 | if (!nr_trees && !read_empty && !opts.merge) |
211 | 0 | warning("read-tree: emptying the index with no arguments is deprecated; use --empty"); |
212 | 0 | else if (nr_trees > 0 && read_empty) |
213 | 0 | die("passing trees as arguments contradicts --empty"); |
214 | | |
215 | 0 | if (1 < opts.index_only + opts.update) |
216 | 0 | die("-u and -i at the same time makes no sense"); |
217 | 0 | if ((opts.update || opts.index_only) && !opts.merge) |
218 | 0 | die("%s is meaningless without -m, --reset, or --prefix", |
219 | 0 | opts.update ? "-u" : "-i"); |
220 | 0 | if (opts.update && !opts.reset) |
221 | 0 | opts.preserve_ignored = 0; |
222 | | /* otherwise, opts.preserve_ignored is irrelevant */ |
223 | 0 | if (opts.merge && !opts.index_only) |
224 | 0 | setup_work_tree(); |
225 | |
|
226 | 0 | if (opts.skip_sparse_checkout) |
227 | 0 | ensure_full_index(the_repository->index); |
228 | |
|
229 | 0 | if (opts.merge) { |
230 | 0 | switch (stage - 1) { |
231 | 0 | case 0: |
232 | 0 | die("you must specify at least one tree to merge"); |
233 | 0 | break; |
234 | 0 | case 1: |
235 | 0 | opts.fn = opts.prefix ? bind_merge : oneway_merge; |
236 | 0 | break; |
237 | 0 | case 2: |
238 | 0 | opts.fn = twoway_merge; |
239 | 0 | opts.initial_checkout = is_index_unborn(the_repository->index); |
240 | 0 | break; |
241 | 0 | case 3: |
242 | 0 | default: |
243 | 0 | opts.fn = threeway_merge; |
244 | 0 | break; |
245 | 0 | } |
246 | | |
247 | 0 | if (stage - 1 >= 3) |
248 | 0 | opts.head_idx = stage - 2; |
249 | 0 | else |
250 | 0 | opts.head_idx = 1; |
251 | 0 | } |
252 | | |
253 | 0 | if (opts.internal.debug_unpack) |
254 | 0 | opts.fn = debug_merge; |
255 | | |
256 | | /* If we're going to prime_cache_tree later, skip cache tree update */ |
257 | 0 | if (nr_trees == 1 && !opts.prefix) |
258 | 0 | opts.skip_cache_tree_update = 1; |
259 | |
|
260 | 0 | cache_tree_free(&the_repository->index->cache_tree); |
261 | 0 | for (i = 0; i < nr_trees; i++) { |
262 | 0 | struct tree *tree = trees[i]; |
263 | 0 | if (parse_tree(tree) < 0) |
264 | 0 | return 128; |
265 | 0 | init_tree_desc(t+i, &tree->object.oid, tree->buffer, tree->size); |
266 | 0 | } |
267 | 0 | if (unpack_trees(nr_trees, t, &opts)) |
268 | 0 | return 128; |
269 | | |
270 | 0 | if (opts.internal.debug_unpack || opts.dry_run) |
271 | 0 | return 0; /* do not write the index out */ |
272 | | |
273 | | /* |
274 | | * When reading only one tree (either the most basic form, |
275 | | * "-m ent" or "--reset ent" form), we can obtain a fully |
276 | | * valid cache-tree because the index must match exactly |
277 | | * what came from the tree. |
278 | | */ |
279 | 0 | if (nr_trees == 1 && !opts.prefix) |
280 | 0 | prime_cache_tree(the_repository, |
281 | 0 | the_repository->index, |
282 | 0 | trees[0]); |
283 | |
|
284 | 0 | if (write_locked_index(the_repository->index, &lock_file, COMMIT_LOCK)) |
285 | 0 | die("unable to write new index file"); |
286 | 0 | return 0; |
287 | 0 | } |