vendor/libgit2/src/checkout.c in rugged-1.3.2.3 vs vendor/libgit2/src/checkout.c in rugged-1.4.2
- old
+ new
@@ -25,14 +25,15 @@
#include "blob.h"
#include "diff.h"
#include "diff_generate.h"
#include "pathspec.h"
#include "diff_xdiff.h"
-#include "path.h"
+#include "fs_path.h"
#include "attr.h"
#include "pool.h"
#include "strmap.h"
+#include "path.h"
/* See docs/checkout-internals.md for more information */
enum {
CHECKOUT_ACTION__NONE = 0,
@@ -42,11 +43,11 @@
CHECKOUT_ACTION__CONFLICT = 8,
CHECKOUT_ACTION__REMOVE_CONFLICT = 16,
CHECKOUT_ACTION__UPDATE_CONFLICT = 32,
CHECKOUT_ACTION__MAX = 32,
CHECKOUT_ACTION__REMOVE_AND_UPDATE =
- (CHECKOUT_ACTION__UPDATE_BLOB | CHECKOUT_ACTION__REMOVE),
+ (CHECKOUT_ACTION__UPDATE_BLOB | CHECKOUT_ACTION__REMOVE)
};
typedef struct {
git_repository *repo;
git_iterator *target;
@@ -59,13 +60,13 @@
git_vector removes;
git_vector remove_conflicts;
git_vector update_conflicts;
git_vector *update_reuc;
git_vector *update_names;
- git_buf target_path;
+ git_str target_path;
size_t target_len;
- git_buf tmp;
+ git_str tmp;
unsigned int strategy;
int can_symlink;
int respect_filemode;
bool reload_submodules;
size_t total_steps;
@@ -78,15 +79,15 @@
typedef struct {
const git_index_entry *ancestor;
const git_index_entry *ours;
const git_index_entry *theirs;
- int name_collision:1,
- directoryfile:1,
- one_to_two:1,
- binary:1,
- submodule:1;
+ unsigned int name_collision:1,
+ directoryfile:1,
+ one_to_two:1,
+ binary:1,
+ submodule:1;
} checkout_conflictdata;
static int checkout_notify(
checkout_data *data,
git_checkout_notify_t why,
@@ -319,37 +320,37 @@
return checkout_action_common(action, data, delta, NULL);
}
static int checkout_target_fullpath(
- git_buf **out, checkout_data *data, const char *path)
+ git_str **out, checkout_data *data, const char *path)
{
- git_buf_truncate(&data->target_path, data->target_len);
+ git_str_truncate(&data->target_path, data->target_len);
- if (path && git_buf_puts(&data->target_path, path) < 0)
+ if (path && git_str_puts(&data->target_path, path) < 0)
return -1;
- if (git_path_validate_workdir_buf(data->repo, &data->target_path) < 0)
+ if (git_path_validate_str_length(data->repo, &data->target_path) < 0)
return -1;
*out = &data->target_path;
return 0;
}
static bool wd_item_is_removable(
checkout_data *data, const git_index_entry *wd)
{
- git_buf *full;
+ git_str *full;
if (wd->mode != GIT_FILEMODE_TREE)
return true;
if (checkout_target_fullpath(&full, data, wd->path) < 0)
return false;
- return !full || !git_path_contains(full, DOT_GIT);
+ return !full || !git_fs_path_contains(full, DOT_GIT);
}
static int checkout_queue_remove(checkout_data *data, const char *path)
{
char *copy = git_pool_strdup(&data->pool, path);
@@ -421,11 +422,11 @@
bool over = false, removable = wd_item_is_removable(data, wd);
git_iterator_status_t untracked_state;
/* copy the entry for issuing notification callback later */
git_index_entry saved_wd = *wd;
- git_buf_sets(&data->tmp, wd->path);
+ git_str_sets(&data->tmp, wd->path);
saved_wd.path = data->tmp.ptr;
error = git_iterator_advance_over(
wditem, &untracked_state, workdir);
if (error == GIT_ITEROVER)
@@ -474,16 +475,16 @@
return rval;
}
static bool checkout_is_empty_dir(checkout_data *data, const char *path)
{
- git_buf *fullpath;
+ git_str *fullpath;
if (checkout_target_fullpath(&fullpath, data, path) < 0)
return false;
- return git_path_is_empty_dir(fullpath->ptr);
+ return git_fs_path_is_empty_dir(fullpath->ptr);
}
static int checkout_action_with_wd(
int *action,
checkout_data *data,
@@ -960,11 +961,11 @@
static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, git_vector *pathspec)
{
git_index *index;
- /* Only write conficts from sources that have them: indexes. */
+ /* Only write conflicts from sources that have them: indexes. */
if ((index = git_iterator_index(data->target)) == NULL)
return 0;
data->update_conflicts._cmp = checkout_conflictdata_cmp;
@@ -1199,16 +1200,16 @@
"index inconsistency, truncated index while loading expected conflict '%s'", path);
error = -1;
goto done;
}
- prefixed = git_path_equal_or_prefixed(path, entry->path, NULL);
+ prefixed = git_fs_path_equal_or_prefixed(path, entry->path, NULL);
- if (prefixed == GIT_PATH_EQUAL)
+ if (prefixed == GIT_FS_PATH_EQUAL)
continue;
- if (prefixed == GIT_PATH_PREFIX)
+ if (prefixed == GIT_FS_PATH_PREFIX)
conflict->directoryfile = 1;
break;
}
}
@@ -1278,18 +1279,18 @@
git_diff_delta *delta)
{
unsigned int flags = GIT_PATH_REJECT_WORKDIR_DEFAULTS;
if (action & CHECKOUT_ACTION__REMOVE) {
- if (!git_path_validate(repo, delta->old_file.path, delta->old_file.mode, flags)) {
+ if (!git_path_is_valid(repo, delta->old_file.path, delta->old_file.mode, flags)) {
git_error_set(GIT_ERROR_CHECKOUT, "cannot remove invalid path '%s'", delta->old_file.path);
return -1;
}
}
if (action & ~CHECKOUT_ACTION__REMOVE) {
- if (!git_path_validate(repo, delta->new_file.path, delta->new_file.mode, flags)) {
+ if (!git_path_is_valid(repo, delta->new_file.path, delta->new_file.mode, flags)) {
git_error_set(GIT_ERROR_CHECKOUT, "cannot checkout to invalid path '%s'", delta->new_file.path);
return -1;
}
}
@@ -1582,24 +1583,24 @@
checkout_data *data,
struct stat *st,
git_blob *blob,
const char *path)
{
- git_buf linktarget = GIT_BUF_INIT;
+ git_str linktarget = GIT_STR_INIT;
int error;
if ((error = mkpath2file(data, path, data->opts.dir_mode)) < 0)
return error;
if ((error = git_blob__getbuf(&linktarget, blob)) < 0)
return error;
if (data->can_symlink) {
- if ((error = p_symlink(git_buf_cstr(&linktarget), path)) < 0)
+ if ((error = p_symlink(git_str_cstr(&linktarget), path)) < 0)
git_error_set(GIT_ERROR_OS, "could not create symlink %s", path);
} else {
- error = git_futils_fake_symlink(git_buf_cstr(&linktarget), path);
+ error = git_futils_fake_symlink(git_str_cstr(&linktarget), path);
}
if (!error) {
data->perfdata.stat_calls++;
@@ -1607,11 +1608,11 @@
git_error_set(GIT_ERROR_CHECKOUT, "could not stat symlink %s", path);
st->st_mode = GIT_FILEMODE_LINK;
}
- git_buf_dispose(&linktarget);
+ git_str_dispose(&linktarget);
return error;
}
static int checkout_update_index(
@@ -1634,11 +1635,11 @@
static int checkout_submodule_update_index(
checkout_data *data,
const git_diff_file *file)
{
- git_buf *fullpath;
+ git_str *fullpath;
struct stat st;
/* update the index unless prevented */
if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) != 0)
return 0;
@@ -1770,11 +1771,11 @@
static int checkout_blob(
checkout_data *data,
const git_diff_file *file)
{
- git_buf *fullpath;
+ git_str *fullpath;
struct stat st;
int error = 0;
if (checkout_target_fullpath(&fullpath, data, file->path) < 0)
return -1;
@@ -1807,11 +1808,11 @@
{
int error = 0;
git_diff_delta *delta;
const char *str;
size_t i;
- git_buf *fullpath;
+ git_str *fullpath;
uint32_t flg = GIT_RMDIR_EMPTY_PARENTS |
GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS;
if (data->opts.checkout_strategy & GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES)
flg |= GIT_RMDIR_SKIP_NONEMPTY;
@@ -1925,44 +1926,44 @@
return error;
}
static int conflict_entry_name(
- git_buf *out,
+ git_str *out,
const char *side_name,
const char *filename)
{
- if (git_buf_puts(out, side_name) < 0 ||
- git_buf_putc(out, ':') < 0 ||
- git_buf_puts(out, filename) < 0)
+ if (git_str_puts(out, side_name) < 0 ||
+ git_str_putc(out, ':') < 0 ||
+ git_str_puts(out, filename) < 0)
return -1;
return 0;
}
-static int checkout_path_suffixed(git_buf *path, const char *suffix)
+static int checkout_path_suffixed(git_str *path, const char *suffix)
{
size_t path_len;
int i = 0, error = 0;
- if ((error = git_buf_putc(path, '~')) < 0 || (error = git_buf_puts(path, suffix)) < 0)
+ if ((error = git_str_putc(path, '~')) < 0 || (error = git_str_puts(path, suffix)) < 0)
return -1;
- path_len = git_buf_len(path);
+ path_len = git_str_len(path);
- while (git_path_exists(git_buf_cstr(path)) && i < INT_MAX) {
- git_buf_truncate(path, path_len);
+ while (git_fs_path_exists(git_str_cstr(path)) && i < INT_MAX) {
+ git_str_truncate(path, path_len);
- if ((error = git_buf_putc(path, '_')) < 0 ||
- (error = git_buf_printf(path, "%d", i)) < 0)
+ if ((error = git_str_putc(path, '_')) < 0 ||
+ (error = git_str_printf(path, "%d", i)) < 0)
return error;
i++;
}
if (i == INT_MAX) {
- git_buf_truncate(path, path_len);
+ git_str_truncate(path, path_len);
git_error_set(GIT_ERROR_CHECKOUT, "could not write '%s': working directory file exists", path->ptr);
return GIT_EEXISTS;
}
@@ -1972,12 +1973,12 @@
static int checkout_write_entry(
checkout_data *data,
checkout_conflictdata *conflict,
const git_index_entry *side)
{
- const char *hint_path, *suffix;
- git_buf *fullpath;
+ const char *hint_path = NULL, *suffix;
+ git_str *fullpath;
struct stat st;
int error;
GIT_ASSERT(side == conflict->ours || side == conflict->theirs);
@@ -2023,20 +2024,20 @@
return error;
}
static int checkout_merge_path(
- git_buf *out,
+ git_str *out,
checkout_data *data,
checkout_conflictdata *conflict,
git_merge_file_result *result)
{
const char *our_label_raw, *their_label_raw, *suffix;
int error = 0;
- if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0 ||
- (error = git_path_validate_workdir_buf(data->repo, out)) < 0)
+ if ((error = git_str_joinpath(out, data->opts.target_directory, result->path)) < 0 ||
+ (error = git_path_validate_str_length(data->repo, out)) < 0)
return error;
/* Most conflicts simply use the filename in the index */
if (!conflict->name_collision)
return 0;
@@ -2054,23 +2055,26 @@
static int checkout_write_merge(
checkout_data *data,
checkout_conflictdata *conflict)
{
- git_buf our_label = GIT_BUF_INIT, their_label = GIT_BUF_INIT,
- path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT,
- in_data = GIT_BUF_INIT, out_data = GIT_BUF_INIT;
+ git_str our_label = GIT_STR_INIT, their_label = GIT_STR_INIT,
+ path_suffixed = GIT_STR_INIT, path_workdir = GIT_STR_INIT,
+ in_data = GIT_STR_INIT, out_data = GIT_STR_INIT;
git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
git_merge_file_result result = {0};
git_filebuf output = GIT_FILEBUF_INIT;
git_filter_list *fl = NULL;
git_filter_session filter_session = GIT_FILTER_SESSION_INIT;
int error = 0;
if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3)
opts.flags |= GIT_MERGE_FILE_STYLE_DIFF3;
+ if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3)
+ opts.flags |= GIT_MERGE_FILE_STYLE_ZDIFF3;
+
opts.ancestor_label = data->opts.ancestor_label ?
data->opts.ancestor_label : "ancestor";
opts.our_label = data->opts.our_label ?
data->opts.our_label : "ours";
opts.their_label = data->opts.their_label ?
@@ -2086,12 +2090,12 @@
&our_label, opts.our_label, conflict->ours->path)) < 0 ||
(error = conflict_entry_name(
&their_label, opts.their_label, conflict->theirs->path)) < 0)
goto done;
- opts.our_label = git_buf_cstr(&our_label);
- opts.their_label = git_buf_cstr(&their_label);
+ opts.our_label = git_str_cstr(&our_label);
+ opts.their_label = git_str_cstr(&their_label);
}
if ((error = git_merge_file_from_index(&result, data->repo,
conflict->ancestor, conflict->ours, conflict->theirs, &opts)) < 0)
goto done;
@@ -2104,11 +2108,11 @@
if ((error = checkout_merge_path(&path_workdir, data, conflict, &result)) < 0)
goto done;
if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0 &&
- (error = checkout_safe_for_update_only(data, git_buf_cstr(&path_workdir), result.mode)) <= 0)
+ (error = checkout_safe_for_update_only(data, git_str_cstr(&path_workdir), result.mode)) <= 0)
goto done;
if (!data->opts.disable_filters) {
in_data.ptr = (char *)result.ptr;
in_data.size = result.len;
@@ -2125,25 +2129,25 @@
out_data.ptr = (char *)result.ptr;
out_data.size = result.len;
}
if ((error = mkpath2file(data, path_workdir.ptr, data->opts.dir_mode)) < 0 ||
- (error = git_filebuf_open(&output, git_buf_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
+ (error = git_filebuf_open(&output, git_str_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
(error = git_filebuf_write(&output, out_data.ptr, out_data.size)) < 0 ||
(error = git_filebuf_commit(&output)) < 0)
goto done;
done:
git_filter_list_free(fl);
- git_buf_dispose(&out_data);
- git_buf_dispose(&our_label);
- git_buf_dispose(&their_label);
+ git_str_dispose(&out_data);
+ git_str_dispose(&our_label);
+ git_str_dispose(&their_label);
git_merge_file_result_free(&result);
- git_buf_dispose(&path_workdir);
- git_buf_dispose(&path_suffixed);
+ git_str_dispose(&path_workdir);
+ git_str_dispose(&path_suffixed);
return error;
}
static int checkout_conflict_add(
@@ -2319,12 +2323,12 @@
git_vector_free_deep(&data->update_conflicts);
git__free(data->pfx);
data->pfx = NULL;
- git_buf_dispose(&data->target_path);
- git_buf_dispose(&data->tmp);
+ git_str_dispose(&data->target_path);
+ git_str_dispose(&data->tmp);
git_index_free(data->index);
data->index = NULL;
git_strmap_free(data->mkdir_map);
@@ -2335,14 +2339,14 @@
static int validate_target_directory(checkout_data *data)
{
int error;
- if ((error = git_path_validate_workdir(data->repo, data->opts.target_directory)) < 0)
+ if ((error = git_path_validate_length(data->repo, data->opts.target_directory)) < 0)
return error;
- if (git_path_isdir(data->opts.target_directory))
+ if (git_fs_path_isdir(data->opts.target_directory))
return 0;
error = checkout_mkdir(data, data->opts.target_directory, NULL,
GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR);
@@ -2490,10 +2494,12 @@
goto cleanup;
else if (strcmp(conflict_style->value, "merge") == 0)
data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_MERGE;
else if (strcmp(conflict_style->value, "diff3") == 0)
data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_DIFF3;
+ else if (strcmp(conflict_style->value, "zdiff3") == 0)
+ data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3;
else {
git_error_set(GIT_ERROR_CHECKOUT, "unknown style '%s' given for 'merge.conflictstyle'",
conflict_style->value);
error = -1;
git_config_entry_free(conflict_style);
@@ -2504,16 +2510,16 @@
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_str_puts(&data->target_path, data->opts.target_directory)) < 0 ||
+ (error = git_fs_path_to_dir(&data->target_path)) < 0 ||
(error = git_strmap_new(&data->mkdir_map)) < 0)
goto cleanup;
- data->target_len = git_buf_len(&data->target_path);
+ data->target_len = git_str_len(&data->target_path);
git_attr_session__init(&data->attr_session, data->repo);
cleanup:
if (error < 0)
@@ -2621,10 +2627,10 @@
if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0)
goto cleanup;
if (data.strategy & GIT_CHECKOUT_DRY_RUN)
goto cleanup;
-
+
data.total_steps = counts[CHECKOUT_ACTION__REMOVE] +
counts[CHECKOUT_ACTION__REMOVE_CONFLICT] +
counts[CHECKOUT_ACTION__UPDATE_BLOB] +
counts[CHECKOUT_ACTION__UPDATE_SUBMODULE] +
counts[CHECKOUT_ACTION__UPDATE_CONFLICT];