vendor/libgit2/src/checkout.c in rugged-0.23.0b1 vs vendor/libgit2/src/checkout.c in rugged-0.23.0b2

- old
+ new

@@ -407,10 +407,18 @@ git_submodule_free(sm); return rval; } +static bool checkout_is_empty_dir(checkout_data *data, const char *path) +{ + git_buf_truncate(&data->path, data->workdir_len); + if (git_buf_puts(&data->path, path) < 0) + return false; + return git_path_is_empty_dir(data->path.ptr); +} + static int checkout_action_with_wd( int *action, checkout_data *data, const git_diff_delta *delta, git_iterator *workdir, @@ -524,10 +532,11 @@ case GIT_DELTA_UNMODIFIED: /* case 19 or 24 (or 34 but not really) */ GITERR_CHECK_ERROR( checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL)); GITERR_CHECK_ERROR( checkout_notify(data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd)); + *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, NONE); break; case GIT_DELTA_ADDED:/* case 4 (and 7 for dir) */ case GIT_DELTA_MODIFIED: /* case 20 (or 37 but not really) */ if (delta->old_file.mode == GIT_FILEMODE_COMMIT) /* expected submodule (and maybe found one) */; @@ -548,12 +557,10 @@ * However, safely removing child files will remove the parent * directory if is it left empty, so we can defer removing the * dir and it will succeed if no children are left. */ *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE); - if (*action != CHECKOUT_ACTION__NONE) - *action |= CHECKOUT_ACTION__DEFER_REMOVE; } else if (delta->new_file.mode != GIT_FILEMODE_TREE) /* For typechange to dir, dir is already created so no action */ *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); break; @@ -562,10 +569,24 @@ } return checkout_action_common(action, data, delta, wd); } +static int checkout_action_with_wd_dir_empty( + int *action, + checkout_data *data, + const git_diff_delta *delta) +{ + int error = checkout_action_no_wd(action, data, delta); + + /* We can always safely remove an empty directory. */ + if (error == 0 && *action != CHECKOUT_ACTION__NONE) + *action |= CHECKOUT_ACTION__REMOVE; + + return error; +} + static int checkout_action( int *action, checkout_data *data, git_diff_delta *delta, git_iterator *workdir, @@ -651,11 +672,13 @@ advance = git_iterator_advance; goto done; } } - return checkout_action_with_wd_dir(action, data, delta, workdir, wd); + return checkout_is_empty_dir(data, wd->path) ? + checkout_action_with_wd_dir_empty(action, data, delta) : + checkout_action_with_wd_dir(action, data, delta, workdir, wd); } /* case 6 - wd is after delta */ return checkout_action_no_wd(action, data, delta); } @@ -1195,11 +1218,11 @@ } } if (action & ~CHECKOUT_ACTION__REMOVE) { if (!git_path_isvalid(repo, delta->new_file.path, flags)) { - giterr_set(GITERR_CHECKOUT, "Cannot checkout to invalid path '%s'", delta->old_file.path); + giterr_set(GITERR_CHECKOUT, "Cannot checkout to invalid path '%s'", delta->new_file.path); return -1; } } return 0; @@ -1455,11 +1478,11 @@ writer.base.free = checkout_stream_free; writer.path = path; writer.fd = fd; writer.open = 1; - error = git_filter_list_stream_blob(fl, blob, (git_writestream *)&writer); + error = git_filter_list_stream_blob(fl, blob, &writer.base); assert(writer.open == 0); git_filter_list_free(fl); @@ -2460,11 +2483,12 @@ GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_RECURSE_UNTRACKED_DIRS | /* needed to match baseline */ GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_TYPECHANGE | GIT_DIFF_INCLUDE_TYPECHANGE_TREES | - GIT_DIFF_SKIP_BINARY_CHECK; + GIT_DIFF_SKIP_BINARY_CHECK | + GIT_DIFF_INCLUDE_CASECHANGE; if (data.opts.checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) diff_opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH; if (data.opts.paths.count > 0) diff_opts.pathspec = data.opts.paths; @@ -2641,10 +2665,10 @@ } if ((error = git_repository_index(&index, repo)) < 0) return error; - if (!(error = git_iterator_for_tree(&tree_i, tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL))) + if (!(error = git_iterator_for_tree(&tree_i, tree, 0, NULL, NULL))) error = git_checkout_iterator(tree_i, index, opts); git_iterator_free(tree_i); git_index_free(index); git_tree_free(tree);