Commit 99b68a2a by Carlos Martín Nieto

Merge pull request #2908 from ethomson/safe_create

Allow checkout to handle newly cloned repositories, remove `GIT_CHECKOUT_SAFE_CREATE`
parents 31bc6c04 496b76d4
......@@ -8,6 +8,9 @@ v0.22 + 1
* Rename and copy detection is enabled for small files.
* Checkout can now handle an initial checkout of a repository, making
`GIT_CHECKOUT_SAFE_CREATE` unnecessary for users of clone.
### API additions
* Parsing and retrieving a configuration value as a path is exposed
......@@ -18,6 +21,11 @@ v0.22 + 1
### Breaking API changes
* `GIT_CHECKOUT_SAFE_CREATE` has been removed. Most users will generally
be able to switch to `GIT_CHECKOUT_SAFE`, but if you require missing
file handling during checkout, you may now use `GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING`.
v0.22
------
......
......@@ -82,7 +82,7 @@ int do_clone(git_repository *repo, int argc, char **argv)
}
// Set up options
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
checkout_opts.progress_cb = checkout_progress;
checkout_opts.progress_payload = &pd;
clone_opts.checkout_opts = checkout_opts;
......
......@@ -31,7 +31,7 @@ GIT_BEGIN_DECL
* check out, the "baseline" tree of what was checked out previously, the
* working directory for actual files, and the index for staged changes.
*
* You give checkout one of four strategies for update:
* You give checkout one of three strategies for update:
*
* - `GIT_CHECKOUT_NONE` is a dry-run strategy that checks for conflicts,
* etc., but doesn't make any actual changes.
......@@ -40,8 +40,8 @@ GIT_BEGIN_DECL
* make the working directory match the target (including potentially
* discarding modified files).
*
* In between those are `GIT_CHECKOUT_SAFE` and `GIT_CHECKOUT_SAFE_CREATE`
* both of which only make modifications that will not lose changes.
* - `GIT_CHECKOUT_SAFE` is between these two options, it will only make
* modifications that will not lose changes.
*
* | target == baseline | target != baseline |
* ---------------------|-----------------------|----------------------|
......@@ -51,28 +51,21 @@ GIT_BEGIN_DECL
* workdir exists and | no action | conflict (notify |
* is != baseline | notify dirty MODIFIED | and cancel checkout) |
* ---------------------|-----------------------|----------------------|
* workdir missing, | create if SAFE_CREATE | create file |
* baseline present | notify dirty DELETED | |
* workdir missing, | notify dirty DELETED | create file |
* baseline present | | |
* ---------------------|-----------------------|----------------------|
*
* The only difference between SAFE and SAFE_CREATE is that SAFE_CREATE
* will cause a file to be checked out if it is missing from the working
* directory even if it is not modified between the target and baseline.
*
*
* To emulate `git checkout`, use `GIT_CHECKOUT_SAFE` with a checkout
* notification callback (see below) that displays information about dirty
* files. The default behavior will cancel checkout on conflicts.
*
* To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE_CREATE` with a
* To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE` with a
* notification callback that cancels the operation if a dirty-but-existing
* file is found in the working directory. This core git command isn't
* quite "force" but is sensitive about some types of changes.
*
* To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`.
*
* To emulate `git clone` use `GIT_CHECKOUT_SAFE_CREATE` in the options.
*
*
* There are some additional flags to modified the behavior of checkout:
*
......@@ -116,12 +109,12 @@ typedef enum {
/** Allow safe updates that cannot overwrite uncommitted data */
GIT_CHECKOUT_SAFE = (1u << 0),
/** Allow safe updates plus creation of missing files */
GIT_CHECKOUT_SAFE_CREATE = (1u << 1),
/** Allow all updates to force working directory to look like index */
GIT_CHECKOUT_FORCE = (1u << 2),
GIT_CHECKOUT_FORCE = (1u << 1),
/** Allow checkout to recreate missing files */
GIT_CHECKOUT_RECREATE_MISSING = (1u << 2),
/** Allow checkout to make safe updates even if conflicts are found */
GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4),
......
......@@ -106,9 +106,7 @@ typedef struct git_clone_options {
/**
* These options are passed to the checkout step. To disable
* checkout, set the `checkout_strategy` to
* `GIT_CHECKOUT_NONE`. Generally you will want the use
* GIT_CHECKOUT_SAFE_CREATE to create all files in the working
* directory for the newly cloned repository.
* `GIT_CHECKOUT_NONE`.
*/
git_checkout_options checkout_opts;
......@@ -173,7 +171,9 @@ typedef struct git_clone_options {
} git_clone_options;
#define GIT_CLONE_OPTIONS_VERSION 1
#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE_CREATE}, GIT_REMOTE_CALLBACKS_INIT}
#define GIT_CLONE_OPTIONS_INIT { GIT_CLONE_OPTIONS_VERSION, \
{ GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \
GIT_REMOTE_CALLBACKS_INIT }
/**
* Initializes a `git_clone_options` with default values. Equivalent to
......
......@@ -137,7 +137,7 @@ typedef struct git_submodule_update_options {
/**
* The checkout strategy to use when the sub repository needs to
* be cloned. Use GIT_CHECKOUT_SAFE_CREATE to create all files
* be cloned. Use GIT_CHECKOUT_SAFE to create all files
* in the working directory for the newly cloned repository.
*/
unsigned int clone_checkout_strategy;
......@@ -152,8 +152,8 @@ typedef struct git_submodule_update_options {
#define GIT_SUBMODULE_UPDATE_OPTIONS_VERSION 1
#define GIT_SUBMODULE_UPDATE_OPTIONS_INIT \
{ GIT_CHECKOUT_OPTIONS_VERSION, \
{ GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE}, \
GIT_REMOTE_CALLBACKS_INIT, GIT_CHECKOUT_SAFE_CREATE }
{ GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \
GIT_REMOTE_CALLBACKS_INIT, GIT_CHECKOUT_SAFE }
/**
* Initializes a `git_submodule_update_options` with default values.
......
......@@ -255,13 +255,13 @@ static int checkout_action_no_wd(
error = checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL);
if (error)
return error;
*action = CHECKOUT_ACTION_IF(SAFE_CREATE, UPDATE_BLOB, NONE);
*action = CHECKOUT_ACTION_IF(RECREATE_MISSING, UPDATE_BLOB, NONE);
break;
case GIT_DELTA_ADDED: /* case 2 or 28 (and 5 but not really) */
*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
break;
case GIT_DELTA_MODIFIED: /* case 13 (and 35 but not really) */
*action = CHECKOUT_ACTION_IF(SAFE_CREATE, UPDATE_BLOB, CONFLICT);
*action = CHECKOUT_ACTION_IF(RECREATE_MISSING, UPDATE_BLOB, CONFLICT);
break;
case GIT_DELTA_TYPECHANGE: /* case 21 (B->T) and 28 (T->B)*/
if (delta->new_file.mode == GIT_FILEMODE_TREE)
......@@ -2346,11 +2346,17 @@ static int checkout_data_init(
}
}
/* if you are forcing, definitely allow safe updates */
/* if you are forcing, allow all safe updates, plus recreate missing */
if ((data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) != 0)
data->opts.checkout_strategy |= GIT_CHECKOUT_SAFE_CREATE;
if ((data->opts.checkout_strategy & GIT_CHECKOUT_SAFE_CREATE) != 0)
data->opts.checkout_strategy |= GIT_CHECKOUT_SAFE;
data->opts.checkout_strategy |= GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING;
/* if the repository does not actually have an index file, then this
* is an initial checkout (perhaps from clone), so we allow safe updates
*/
if (!data->index->on_disk &&
(data->opts.checkout_strategy & GIT_CHECKOUT_SAFE) != 0)
data->opts.checkout_strategy |= GIT_CHECKOUT_RECREATE_MISSING;
data->strategy = data->opts.checkout_strategy;
......
......@@ -72,7 +72,7 @@ static int cherrypick_normalize_opts(
const char *their_label)
{
int error = 0;
unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE_CREATE |
unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_ALLOW_CONFLICTS;
GIT_UNUSED(repo);
......
......@@ -73,7 +73,7 @@ static int revert_normalize_opts(
const char *their_label)
{
int error = 0;
unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE_CREATE |
unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_ALLOW_CONFLICTS;
GIT_UNUSED(repo);
......
......@@ -21,7 +21,7 @@ void test_checkout_crlf__cleanup(void)
void test_checkout_crlf__detect_crlf_autocrlf_false(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", false);
......@@ -36,7 +36,7 @@ void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void)
git_index *index;
const git_index_entry *entry;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", false);
......@@ -56,7 +56,7 @@ void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void)
void test_checkout_crlf__detect_crlf_autocrlf_true(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", true);
......@@ -73,7 +73,7 @@ void test_checkout_crlf__detect_crlf_autocrlf_true(void)
void test_checkout_crlf__more_lf_autocrlf_true(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", true);
......@@ -85,7 +85,7 @@ void test_checkout_crlf__more_lf_autocrlf_true(void)
void test_checkout_crlf__more_crlf_autocrlf_true(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", true);
......@@ -97,7 +97,7 @@ void test_checkout_crlf__more_crlf_autocrlf_true(void)
void test_checkout_crlf__all_crlf_autocrlf_true(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", true);
......@@ -109,7 +109,7 @@ void test_checkout_crlf__all_crlf_autocrlf_true(void)
void test_checkout_crlf__detect_crlf_autocrlf_true_utf8(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", true);
......@@ -136,7 +136,7 @@ void test_checkout_crlf__autocrlf_true_index_size_is_filtered_size(void)
git_index *index;
const git_index_entry *entry;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", true);
......@@ -162,7 +162,7 @@ void test_checkout_crlf__with_ident(void)
git_index *index;
git_blob *blob;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_mkfile("crlf/.gitattributes",
"*.txt text\n*.bin binary\n"
......@@ -252,7 +252,7 @@ void test_checkout_crlf__with_ident(void)
void test_checkout_crlf__autocrlf_false_no_attrs(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", false);
......@@ -265,7 +265,7 @@ void test_checkout_crlf__autocrlf_false_no_attrs(void)
void test_checkout_crlf__autocrlf_true_no_attrs(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_bool(g_repo, "core.autocrlf", true);
......@@ -283,7 +283,7 @@ void test_checkout_crlf__autocrlf_true_no_attrs(void)
void test_checkout_crlf__autocrlf_input_no_attrs(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_repo_set_string(g_repo, "core.autocrlf", "input");
......@@ -296,7 +296,7 @@ void test_checkout_crlf__autocrlf_input_no_attrs(void)
void test_checkout_crlf__autocrlf_false_text_auto_attr(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
......@@ -316,7 +316,7 @@ void test_checkout_crlf__autocrlf_false_text_auto_attr(void)
void test_checkout_crlf__autocrlf_true_text_auto_attr(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
......@@ -336,7 +336,7 @@ void test_checkout_crlf__autocrlf_true_text_auto_attr(void)
void test_checkout_crlf__autocrlf_input_text_auto_attr(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
......
......@@ -49,7 +49,7 @@ void test_checkout_index__can_create_missing_files(void)
cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -69,7 +69,9 @@ void test_checkout_index__can_remove_untracked_files(void)
cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir"));
opts.checkout_strategy =
GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_REMOVE_UNTRACKED;
GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING |
GIT_CHECKOUT_REMOVE_UNTRACKED;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -88,7 +90,7 @@ void test_checkout_index__honor_the_specified_pathspecs(void)
cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -107,7 +109,7 @@ void test_checkout_index__honor_the_gitattributes_directives(void)
cl_git_mkfile("./testrepo/.gitattributes", attributes);
cl_repo_set_bool(g_repo, "core.autocrlf", false);
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -125,7 +127,7 @@ void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void)
cl_git_pass(p_unlink("./testrepo/.gitattributes"));
cl_repo_set_bool(g_repo, "core.autocrlf", true);
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -139,7 +141,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void)
cl_repo_set_bool(g_repo, "core.symlinks", true);
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -165,7 +167,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_false(void)
cl_repo_set_bool(g_repo, "core.symlinks", false);
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -207,7 +209,7 @@ void test_checkout_index__options_disable_filters(void)
cl_git_mkfile("./testrepo/.gitattributes", "*.txt text eol=crlf\n");
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
opts.disable_filters = false;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -238,7 +240,7 @@ void test_checkout_index__options_dir_modes(void)
reset_index_to_treeish((git_object *)commit);
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
opts.dir_mode = 0701;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -264,7 +266,7 @@ void test_checkout_index__options_override_file_modes(void)
if (!cl_is_chmod_supported())
return;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
opts.file_mode = 0700;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -329,8 +331,9 @@ void test_checkout_index__can_notify_of_skipped_files(void)
data.file = "new.txt";
data.sha = "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd";
opts.checkout_strategy =
GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_ALLOW_CONFLICTS;
opts.checkout_strategy = GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING |
GIT_CHECKOUT_ALLOW_CONFLICTS;
opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
opts.notify_cb = test_checkout_notify_cb;
opts.notify_payload = &data;
......@@ -368,7 +371,9 @@ void test_checkout_index__wont_notify_of_expected_line_ending_changes(void)
cl_git_mkfile("./testrepo/new.txt", "my new file\r\n");
opts.checkout_strategy =
GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_ALLOW_CONFLICTS;
GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING |
GIT_CHECKOUT_ALLOW_CONFLICTS;
opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
opts.notify_cb = dont_notify_cb;
opts.notify_payload = NULL;
......@@ -388,7 +393,7 @@ void test_checkout_index__calls_progress_callback(void)
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
int calls = 0;
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
opts.progress_cb = checkout_progress_counter;
opts.progress_payload = &calls;
......@@ -423,7 +428,9 @@ void test_checkout_index__can_overcome_name_clashes(void)
cl_assert(git_path_isfile("./testrepo/path0/file0"));
opts.checkout_strategy =
GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_ALLOW_CONFLICTS;
GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING |
GIT_CHECKOUT_ALLOW_CONFLICTS;
cl_git_pass(git_checkout_index(g_repo, index, &opts));
cl_assert(git_path_isfile("./testrepo/path1"));
......@@ -473,7 +480,9 @@ void test_checkout_index__can_update_prefixed_files(void)
cl_git_pass(p_mkdir("./testrepo/branch_file.txt.after", 0777));
opts.checkout_strategy =
GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_REMOVE_UNTRACKED;
GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING |
GIT_CHECKOUT_REMOVE_UNTRACKED;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
......@@ -523,7 +532,8 @@ void test_checkout_index__target_directory(void)
checkout_counts cts;
memset(&cts, 0, sizeof(cts));
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING;
opts.target_directory = "alternative";
cl_assert(!git_path_isdir("alternative"));
......@@ -568,7 +578,8 @@ void test_checkout_index__target_directory_from_bare(void)
cl_git_pass(git_index_write(index));
git_index_free(index);
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING;
opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
opts.notify_cb = checkout_count_callback;
......@@ -606,7 +617,7 @@ void test_checkout_index__can_get_repo_from_index(void)
cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_repository_index(&index, g_repo));
......
......@@ -15,7 +15,7 @@ void test_checkout_tree__initialize(void)
g_repo = cl_git_sandbox_init("testrepo");
GIT_INIT_STRUCTURE(&g_opts, GIT_CHECKOUT_OPTIONS_VERSION);
g_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
g_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
}
void test_checkout_tree__cleanup(void)
......@@ -408,7 +408,7 @@ void test_checkout_tree__can_checkout_with_pattern(void)
/* now to a narrow patterned checkout */
g_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
g_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
g_opts.paths.strings = entries;
g_opts.paths.count = 1;
......@@ -445,7 +445,8 @@ void test_checkout_tree__can_disable_pattern_match(void)
/* now to a narrow patterned checkout, but disable pattern */
g_opts.checkout_strategy =
GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
g_opts.paths.strings = entries;
g_opts.paths.count = 1;
......@@ -457,7 +458,7 @@ void test_checkout_tree__can_disable_pattern_match(void)
/* let's try that again, but allow the pattern match */
g_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
g_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
......@@ -824,7 +825,8 @@ void test_checkout_tree__target_directory_from_bare(void)
g_repo = cl_git_sandbox_init("testrepo.git");
cl_assert(git_repository_is_bare(g_repo));
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING;
opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
opts.notify_cb = checkout_count_callback;
......@@ -1264,3 +1266,39 @@ void test_checkout_tree__can_update_but_not_write_index(void)
git_object_free(head);
git_index_free(index);
}
/* Emulate checking out in a repo created by clone --no-checkout,
* which would not have written an index. */
void test_checkout_tree__safe_proceeds_if_no_index(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_oid oid;
git_object *obj = NULL;
assert_on_branch(g_repo, "master");
cl_must_pass(p_unlink("testrepo/.git/index"));
/* do second checkout safe because we should be clean after first */
opts.checkout_strategy = GIT_CHECKOUT_SAFE;
cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/subtrees"));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees", NULL, NULL));
cl_assert(git_path_isfile("testrepo/README"));
cl_assert(git_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_path_isfile("testrepo/new.txt"));
cl_assert(git_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_path_isfile("testrepo/ab/c/3.txt"));
cl_assert(git_path_isfile("testrepo/ab/de/2.txt"));
cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt"));
cl_assert(!git_path_isdir("testrepo/a"));
assert_on_branch(g_repo, "subtrees");
git_object_free(obj);
}
......@@ -212,7 +212,7 @@ void test_checkout_typechange__checkout_with_conflicts(void)
p_mkdir("typechanges/d", 0777); /* intentionally empty dir */
force_create_file("typechanges/untracked");
opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
opts.checkout_strategy = GIT_CHECKOUT_SAFE;
memset(&cts, 0, sizeof(cts));
cl_git_fail(git_checkout_tree(g_repo, obj, &opts));
......
......@@ -22,7 +22,7 @@ void test_clone_nonetwork__initialize(void)
memset(&g_options, 0, sizeof(git_clone_options));
g_options.version = GIT_CLONE_OPTIONS_VERSION;
g_options.checkout_opts = dummy_opts;
g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
g_options.remote_callbacks = dummy_callbacks;
cl_git_pass(git_signature_now(&g_options.signature, "Me", "foo@example.com"));
}
......
......@@ -104,7 +104,7 @@ void test_online_clone__can_checkout_a_cloned_repo(void)
bool checkout_progress_cb_was_called = false,
fetch_progress_cb_was_called = false;
g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
g_options.checkout_opts.progress_cb = &checkout_progress;
g_options.checkout_opts.progress_payload = &checkout_progress_cb_was_called;
g_options.remote_callbacks.transfer_progress = &fetch_progress;
......
......@@ -26,7 +26,7 @@ void perf__do_merge(const char *fixture,
perf__timer__start(&t_total);
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
clone_opts.checkout_opts = checkout_opts;
cl_git_pass(git_signature_now(&clone_opts.signature, "Me", "foo@example.com"));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment