Skip to content

Commit 8f1b063

Browse files
committed
Merge branch 'jc/checkout'
* 'jc/checkout': checkout: "best effort" checkout unpack_trees(): allow callers to differentiate worktree errors from merge errors checkout: consolidate reset_{to_new,clean_to_new}() checkout: make reset_clean_to_new() not die by itself
2 parents 6810053 + 291d823 commit 8f1b063

File tree

2 files changed

+43
-42
lines changed

2 files changed

+43
-42
lines changed

builtin-checkout.c

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -151,57 +151,50 @@ static void describe_detached_head(char *msg, struct commit *commit)
151151
strbuf_release(&sb);
152152
}
153153

154-
static int reset_to_new(struct tree *tree, int quiet)
155-
{
156-
struct unpack_trees_options opts;
157-
struct tree_desc tree_desc;
154+
struct checkout_opts {
155+
int quiet;
156+
int merge;
157+
int force;
158+
int writeout_error;
158159

159-
memset(&opts, 0, sizeof(opts));
160-
opts.head_idx = -1;
161-
opts.update = 1;
162-
opts.reset = 1;
163-
opts.merge = 1;
164-
opts.fn = oneway_merge;
165-
opts.verbose_update = !quiet;
166-
opts.src_index = &the_index;
167-
opts.dst_index = &the_index;
168-
parse_tree(tree);
169-
init_tree_desc(&tree_desc, tree->buffer, tree->size);
170-
if (unpack_trees(1, &tree_desc, &opts))
171-
return 128;
172-
return 0;
173-
}
160+
char *new_branch;
161+
int new_branch_log;
162+
enum branch_track track;
163+
};
174164

175-
static void reset_clean_to_new(struct tree *tree, int quiet)
165+
static int reset_tree(struct tree *tree, struct checkout_opts *o, int worktree)
176166
{
177167
struct unpack_trees_options opts;
178168
struct tree_desc tree_desc;
179169

180170
memset(&opts, 0, sizeof(opts));
181171
opts.head_idx = -1;
182-
opts.skip_unmerged = 1;
172+
opts.update = worktree;
173+
opts.skip_unmerged = !worktree;
183174
opts.reset = 1;
184175
opts.merge = 1;
185176
opts.fn = oneway_merge;
186-
opts.verbose_update = !quiet;
177+
opts.verbose_update = !o->quiet;
187178
opts.src_index = &the_index;
188179
opts.dst_index = &the_index;
189180
parse_tree(tree);
190181
init_tree_desc(&tree_desc, tree->buffer, tree->size);
191-
if (unpack_trees(1, &tree_desc, &opts))
192-
exit(128);
182+
switch (unpack_trees(1, &tree_desc, &opts)) {
183+
case -2:
184+
o->writeout_error = 1;
185+
/*
186+
* We return 0 nevertheless, as the index is all right
187+
* and more importantly we have made best efforts to
188+
* update paths in the work tree, and we cannot revert
189+
* them.
190+
*/
191+
case 0:
192+
return 0;
193+
default:
194+
return 128;
195+
}
193196
}
194197

195-
struct checkout_opts {
196-
int quiet;
197-
int merge;
198-
int force;
199-
200-
char *new_branch;
201-
int new_branch_log;
202-
enum branch_track track;
203-
};
204-
205198
struct branch_info {
206199
const char *name; /* The short name used */
207200
const char *path; /* The full name of a real branch */
@@ -226,7 +219,7 @@ static int merge_working_tree(struct checkout_opts *opts,
226219
read_cache();
227220

228221
if (opts->force) {
229-
ret = reset_to_new(new->commit->tree, opts->quiet);
222+
ret = reset_tree(new->commit->tree, opts, 1);
230223
if (ret)
231224
return ret;
232225
} else {
@@ -262,7 +255,8 @@ static int merge_working_tree(struct checkout_opts *opts,
262255
tree = parse_tree_indirect(new->commit->object.sha1);
263256
init_tree_desc(&trees[1], tree->buffer, tree->size);
264257

265-
if (unpack_trees(2, trees, &topts)) {
258+
ret = unpack_trees(2, trees, &topts);
259+
if (ret == -1) {
266260
/*
267261
* Unpack couldn't do a trivial merge; either
268262
* give up or do a real merge, depending on
@@ -290,12 +284,14 @@ static int merge_working_tree(struct checkout_opts *opts,
290284
add_files_to_cache(NULL, NULL, 0);
291285
work = write_tree_from_memory();
292286

293-
ret = reset_to_new(new->commit->tree, opts->quiet);
287+
ret = reset_tree(new->commit->tree, opts, 1);
294288
if (ret)
295289
return ret;
296290
merge_trees(new->commit->tree, work, old->commit->tree,
297291
new->name, "local", &result);
298-
reset_clean_to_new(new->commit->tree, opts->quiet);
292+
ret = reset_tree(new->commit->tree, opts, 0);
293+
if (ret)
294+
return ret;
299295
}
300296
}
301297

@@ -495,7 +491,8 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
495491

496492
update_refs_for_switch(opts, &old, new);
497493

498-
return post_checkout_hook(old.commit, new->commit, 1);
494+
ret = post_checkout_hook(old.commit, new->commit, 1);
495+
return ret || opts->writeout_error;
499496
}
500497

501498
int cmd_checkout(int argc, const char **argv, const char *prefix)

unpack-trees.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,13 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
358358
return -1;
359359
}
360360

361+
/*
362+
* N-way merge "len" trees. Returns 0 on success, -1 on failure to manipulate the
363+
* resulting index, -2 on failure to reflect the changes to the work tree.
364+
*/
361365
int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
362366
{
367+
int ret;
363368
static struct cache_entry *dfc;
364369

365370
if (len > MAX_UNPACK_TREES)
@@ -404,11 +409,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
404409
return unpack_failed(o, "Merge requires file-level merging");
405410

406411
o->src_index = NULL;
407-
if (check_updates(o))
408-
return -1;
412+
ret = check_updates(o) ? (-2) : 0;
409413
if (o->dst_index)
410414
*o->dst_index = o->result;
411-
return 0;
415+
return ret;
412416
}
413417

414418
/* Here come the merge functions */

0 commit comments

Comments
 (0)