vendor/libgit2/src/checkout.c in rugged-1.0.1 vs vendor/libgit2/src/checkout.c in rugged-1.1.0
- old
+ new
@@ -42,11 +42,10 @@
CHECKOUT_ACTION__UPDATE_SUBMODULE = 4,
CHECKOUT_ACTION__CONFLICT = 8,
CHECKOUT_ACTION__REMOVE_CONFLICT = 16,
CHECKOUT_ACTION__UPDATE_CONFLICT = 32,
CHECKOUT_ACTION__MAX = 32,
- CHECKOUT_ACTION__DEFER_REMOVE = 64,
CHECKOUT_ACTION__REMOVE_AND_UPDATE =
(CHECKOUT_ACTION__UPDATE_BLOB | CHECKOUT_ACTION__REMOVE),
};
typedef struct {
@@ -194,11 +193,11 @@
git_error_clear();
return true;
}
if (git_submodule_status(&sm_status, data->repo, wditem->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED) < 0 ||
- GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
+ GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
rval = true;
else if ((sm_oid = git_submodule_wd_id(sm)) == NULL)
rval = false;
else
rval = (git_oid__cmp(&baseitem->id, sm_oid) != 0);
@@ -215,13 +214,14 @@
* us to avoid touching the disk.
*/
ie = git_index_get_bypath(data->index, wditem->path, 0);
if (ie != NULL &&
- git_index_time_eq(&wditem->mtime, &ie->mtime) &&
- wditem->file_size == ie->file_size &&
- !is_filemode_changed(wditem->mode, ie->mode, data->respect_filemode)) {
+ !git_index_entry_newer_than_index(ie, data->index) &&
+ git_index_time_eq(&wditem->mtime, &ie->mtime) &&
+ wditem->file_size == ie->file_size &&
+ !is_filemode_changed(wditem->mode, ie->mode, data->respect_filemode)) {
/* The workdir is modified iff the index entry is modified */
return !is_workdir_base_or_new(&ie->id, baseitem, newitem) ||
is_filemode_changed(baseitem->mode, ie->mode, data->respect_filemode);
}
@@ -271,13 +271,12 @@
if (delta->new_file.mode == GIT_FILEMODE_LINK && wd != NULL)
*action |= CHECKOUT_ACTION__REMOVE;
/* if the file is on disk and doesn't match our mode, force update */
if (wd &&
- GIT_PERMS_IS_EXEC(wd->mode) !=
- GIT_PERMS_IS_EXEC(delta->new_file.mode))
- *action |= CHECKOUT_ACTION__REMOVE;
+ GIT_PERMS_IS_EXEC(wd->mode) != GIT_PERMS_IS_EXEC(delta->new_file.mode))
+ *action |= CHECKOUT_ACTION__REMOVE;
notify = GIT_CHECKOUT_NOTIFY_UPDATED;
}
if ((*action & CHECKOUT_ACTION__CONFLICT) != 0)
@@ -369,13 +368,18 @@
const git_index_entry *wd = *wditem;
if (!git_pathspec__match(
pathspec, wd->path,
(data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
- git_iterator_ignore_case(workdir), NULL, NULL))
- return git_iterator_advance(wditem, workdir);
+ git_iterator_ignore_case(workdir), NULL, NULL)) {
+ if (wd->mode == GIT_FILEMODE_TREE)
+ return git_iterator_advance_into(wditem, workdir);
+ else
+ return git_iterator_advance(wditem, workdir);
+ }
+
/* check if item is tracked in the index but not in the checkout diff */
if (data->index != NULL) {
size_t pos;
error = git_index__find_pos(
@@ -792,17 +796,17 @@
const checkout_conflictdata *ca = a;
const checkout_conflictdata *cb = b;
int diff;
if ((diff = checkout_idxentry_cmp(ca->ancestor, cb->ancestor)) == 0 &&
- (diff = checkout_idxentry_cmp(ca->ours, cb->theirs)) == 0)
+ (diff = checkout_idxentry_cmp(ca->ours, cb->theirs)) == 0)
diff = checkout_idxentry_cmp(ca->theirs, cb->theirs);
return diff;
}
-int checkout_conflictdata_empty(
+static int checkout_conflictdata_empty(
const git_vector *conflicts, size_t idx, void *payload)
{
checkout_conflictdata *conflict;
GIT_UNUSED(payload);
@@ -1171,11 +1175,11 @@
len = git_index_entrycount(index);
/* Find d/f conflicts */
git_vector_foreach(&data->update_conflicts, i, conflict) {
if ((conflict->ours && conflict->theirs) ||
- (!conflict->ours && !conflict->theirs))
+ (!conflict->ours && !conflict->theirs))
continue;
path = conflict->ours ?
conflict->ours->path : conflict->theirs->path;
@@ -1220,12 +1224,12 @@
if (data->strategy & GIT_CHECKOUT_SKIP_UNMERGED)
return 0;
if ((error = checkout_conflicts_load(data, workdir, pathspec)) < 0 ||
- (error = checkout_conflicts_coalesce_renames(data)) < 0 ||
- (error = checkout_conflicts_mark_directoryfile(data)) < 0)
+ (error = checkout_conflicts_coalesce_renames(data)) < 0 ||
+ (error = checkout_conflicts_mark_directoryfile(data)) < 0)
goto done;
done:
return error;
}
@@ -1302,18 +1306,19 @@
git_pool pathpool;
git_diff_delta *delta;
size_t i, *counts = NULL;
uint32_t *actions = NULL;
- git_pool_init(&pathpool, 1);
+ if (git_pool_init(&pathpool, 1) < 0)
+ return -1;
if (data->opts.paths.count > 0 &&
- git_pathspec__vinit(&pathspec, &data->opts.paths, &pathpool) < 0)
+ git_pathspec__vinit(&pathspec, &data->opts.paths, &pathpool) < 0)
return -1;
if ((error = git_iterator_current(&wditem, workdir)) < 0 &&
- error != GIT_ITEROVER)
+ error != GIT_ITEROVER)
goto fail;
deltas = &data->diff->deltas;
*counts_ptr = counts = git__calloc(CHECKOUT_ACTION__MAX+1, sizeof(size_t));
@@ -1348,23 +1353,22 @@
goto fail;
counts[CHECKOUT_ACTION__REMOVE] += data->removes.length;
if (counts[CHECKOUT_ACTION__CONFLICT] > 0 &&
- (data->strategy & GIT_CHECKOUT_ALLOW_CONFLICTS) == 0)
- {
+ (data->strategy & GIT_CHECKOUT_ALLOW_CONFLICTS) == 0) {
git_error_set(GIT_ERROR_CHECKOUT, "%"PRIuZ" %s checkout",
counts[CHECKOUT_ACTION__CONFLICT],
counts[CHECKOUT_ACTION__CONFLICT] == 1 ?
"conflict prevents" : "conflicts prevent");
error = GIT_ECONFLICT;
goto fail;
}
if ((error = checkout_get_remove_conflicts(data, workdir, &pathspec)) < 0 ||
- (error = checkout_get_update_conflicts(data, workdir, &pathspec)) < 0)
+ (error = checkout_get_update_conflicts(data, workdir, &pathspec)) < 0)
goto fail;
counts[CHECKOUT_ACTION__REMOVE_CONFLICT] = git_vector_length(&data->remove_conflicts);
counts[CHECKOUT_ACTION__UPDATE_CONFLICT] = git_vector_length(&data->update_conflicts);
@@ -1851,48 +1855,19 @@
}
return 0;
}
-static int checkout_deferred_remove(git_repository *repo, const char *path)
-{
-#if 0
- int error = git_futils_rmdir_r(
- path, data->opts.target_directory, GIT_RMDIR_EMPTY_PARENTS);
-
- if (error == GIT_ENOTFOUND) {
- error = 0;
- git_error_clear();
- }
-
- return error;
-#else
- GIT_UNUSED(repo);
- GIT_UNUSED(path);
- assert(false);
- return 0;
-#endif
-}
-
static int checkout_create_the_new(
unsigned int *actions,
checkout_data *data)
{
int error = 0;
git_diff_delta *delta;
size_t i;
git_vector_foreach(&data->diff->deltas, i, delta) {
- if (actions[i] & CHECKOUT_ACTION__DEFER_REMOVE) {
- /* this had a blocker directory that should only be removed iff
- * all of the contents of the directory were safely removed
- */
- if ((error = checkout_deferred_remove(
- data->repo, delta->old_file.path)) < 0)
- return error;
- }
-
if (actions[i] & CHECKOUT_ACTION__UPDATE_BLOB && !S_ISLNK(delta->new_file.mode)) {
if ((error = checkout_blob(data, &delta->new_file)) < 0)
return error;
data->completed_steps++;
report_progress(data, delta->new_file.path);
@@ -1913,24 +1888,14 @@
static int checkout_create_submodules(
unsigned int *actions,
checkout_data *data)
{
- int error = 0;
git_diff_delta *delta;
size_t i;
git_vector_foreach(&data->diff->deltas, i, delta) {
- if (actions[i] & CHECKOUT_ACTION__DEFER_REMOVE) {
- /* this has a blocker directory that should only be removed iff
- * all of the contents of the directory were safely removed
- */
- if ((error = checkout_deferred_remove(
- data->repo, delta->old_file.path)) < 0)
- return error;
- }
-
if (actions[i] & CHECKOUT_ACTION__UPDATE_SUBMODULE) {
int error = checkout_submodule(data, &delta->new_file);
if (error < 0)
return error;
@@ -2518,13 +2483,12 @@
goto cleanup;
}
git_config_entry_free(conflict_style);
}
- git_pool_init(&data->pool, 1);
-
- if ((error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 ||
+ if ((error = git_pool_init(&data->pool, 1)) < 0 ||
+ (error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 ||
(error = git_vector_init(&data->remove_conflicts, 0, NULL)) < 0 ||
(error = git_vector_init(&data->update_conflicts, 0, NULL)) < 0 ||
(error = git_buf_puts(&data->target_path, data->opts.target_directory)) < 0 ||
(error = git_path_to_dir(&data->target_path)) < 0 ||
(error = git_strmap_new(&data->mkdir_map)) < 0)
@@ -2542,10 +2506,21 @@
}
#define CHECKOUT_INDEX_DONT_WRITE_MASK \
(GIT_CHECKOUT_DONT_UPDATE_INDEX | GIT_CHECKOUT_DONT_WRITE_INDEX)
+GIT_INLINE(void) setup_pathspecs(
+ git_iterator_options *iter_opts,
+ const git_checkout_options *checkout_opts)
+{
+ if (checkout_opts &&
+ (checkout_opts->checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)) {
+ iter_opts->pathlist.count = checkout_opts->paths.count;
+ iter_opts->pathlist.strings = checkout_opts->paths.strings;
+ }
+}
+
int git_checkout_iterator(
git_iterator *target,
git_index *index,
const git_checkout_options *opts)
{
@@ -2584,25 +2559,25 @@
GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
workdir_opts.flags |= GIT_ITERATOR_DONT_AUTOEXPAND;
workdir_opts.start = data.pfx;
workdir_opts.end = data.pfx;
+ setup_pathspecs(&workdir_opts, opts);
+
if ((error = git_iterator_reset_range(target, data.pfx, data.pfx)) < 0 ||
(error = git_iterator_for_workdir_ext(
&workdir, data.repo, data.opts.target_directory, index, NULL,
&workdir_opts)) < 0)
goto cleanup;
baseline_opts.flags = git_iterator_ignore_case(target) ?
GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
baseline_opts.start = data.pfx;
baseline_opts.end = data.pfx;
- if (opts && (opts->checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)) {
- baseline_opts.pathlist.count = opts->paths.count;
- baseline_opts.pathlist.strings = opts->paths.strings;
- }
+ setup_pathspecs(&baseline_opts, opts);
+
if (data.opts.baseline_index) {
if ((error = git_iterator_for_index(
&baseline, git_index_owner(data.opts.baseline_index),
data.opts.baseline_index, &baseline_opts)) < 0)
goto cleanup;
@@ -2687,10 +2662,11 @@
int git_checkout_index(
git_repository *repo,
git_index *index,
const git_checkout_options *opts)
{
+ git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
int error, owned = 0;
git_iterator *index_i;
if (!index && !repo) {
git_error_set(GIT_ERROR_CHECKOUT,
@@ -2714,11 +2690,13 @@
if (!index && (error = git_repository_index__weakptr(&index, repo)) < 0)
return error;
GIT_REFCOUNT_INC(index);
- if (!(error = git_iterator_for_index(&index_i, repo, index, NULL)))
+ setup_pathspecs(&iter_opts, opts);
+
+ if (!(error = git_iterator_for_index(&index_i, repo, index, &iter_opts)))
error = git_checkout_iterator(index_i, index, opts);
if (owned)
GIT_REFCOUNT_OWN(index, NULL);
@@ -2771,14 +2749,11 @@
}
if ((error = git_repository_index(&index, repo)) < 0)
return error;
- if (opts && (opts->checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)) {
- iter_opts.pathlist.count = opts->paths.count;
- iter_opts.pathlist.strings = opts->paths.strings;
- }
+ setup_pathspecs(&iter_opts, opts);
if (!(error = git_iterator_for_tree(&tree_i, tree, &iter_opts)))
error = git_checkout_iterator(tree_i, index, opts);
git_iterator_free(tree_i);
@@ -2801,9 +2776,11 @@
GIT_INIT_STRUCTURE_FROM_TEMPLATE(
opts, version, git_checkout_options, GIT_CHECKOUT_OPTIONS_INIT);
return 0;
}
+#ifndef GIT_DEPRECATE_HARD
int git_checkout_init_options(git_checkout_options *opts, unsigned int version)
{
return git_checkout_options_init(opts, version);
}
+#endif