diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-03-03 13:47:13 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-03-03 13:47:13 +0100 |
commit | 99b68a2aecfaa24f252f265d61b230b8e2576dd2 (patch) | |
tree | e54ed236c68b3d3cab3882634a0e6fb54f988617 | |
parent | 31bc6c044091c4d65f3a6fd7078beb260c210137 (diff) | |
parent | 496b76d415b080712d7648fc6f1ff2e55d27a6a5 (diff) | |
download | libgit2-99b68a2aecfaa24f252f265d61b230b8e2576dd2.tar.gz |
Merge pull request #2908 from ethomson/safe_create
Allow checkout to handle newly cloned repositories, remove `GIT_CHECKOUT_SAFE_CREATE`
-rw-r--r-- | CHANGELOG.md | 8 | ||||
-rw-r--r-- | examples/network/clone.c | 2 | ||||
-rw-r--r-- | include/git2/checkout.h | 27 | ||||
-rw-r--r-- | include/git2/clone.h | 8 | ||||
-rw-r--r-- | include/git2/submodule.h | 6 | ||||
-rw-r--r-- | src/.checkout.c.swp | bin | 0 -> 94208 bytes | |||
-rw-r--r-- | src/checkout.c | 18 | ||||
-rw-r--r-- | src/cherrypick.c | 2 | ||||
-rw-r--r-- | src/revert.c | 2 | ||||
-rw-r--r-- | tests/checkout/.icase.c.swp | bin | 0 -> 12288 bytes | |||
-rw-r--r-- | tests/checkout/crlf.c | 30 | ||||
-rw-r--r-- | tests/checkout/index.c | 49 | ||||
-rw-r--r-- | tests/checkout/tree.c | 48 | ||||
-rw-r--r-- | tests/checkout/typechange.c | 2 | ||||
-rw-r--r-- | tests/clone/nonetwork.c | 2 | ||||
-rw-r--r-- | tests/online/clone.c | 2 | ||||
-rw-r--r-- | tests/perf/helper__perf__do_merge.c | 2 |
17 files changed, 132 insertions, 76 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index bffcb2561..6a81a2026 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 ------ diff --git a/examples/network/clone.c b/examples/network/clone.c index 6144e217e..270bb68be 100644 --- a/examples/network/clone.c +++ b/examples/network/clone.c @@ -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; diff --git a/include/git2/checkout.h b/include/git2/checkout.h index 4fe1340b9..ed39bd3cb 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -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), diff --git a/include/git2/clone.h b/include/git2/clone.h index 464408534..1cee516a1 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -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 diff --git a/include/git2/submodule.h b/include/git2/submodule.h index f03ea2da8..1c139d0a7 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -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. diff --git a/src/.checkout.c.swp b/src/.checkout.c.swp Binary files differnew file mode 100644 index 000000000..d946ab551 --- /dev/null +++ b/src/.checkout.c.swp diff --git a/src/checkout.c b/src/checkout.c index f71be26f9..c06928138 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -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; diff --git a/src/cherrypick.c b/src/cherrypick.c index ebc9fcdd8..c92975194 100644 --- a/src/cherrypick.c +++ b/src/cherrypick.c @@ -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); diff --git a/src/revert.c b/src/revert.c index f8a7f4333..c481e7dea 100644 --- a/src/revert.c +++ b/src/revert.c @@ -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); diff --git a/tests/checkout/.icase.c.swp b/tests/checkout/.icase.c.swp Binary files differnew file mode 100644 index 000000000..facd136ff --- /dev/null +++ b/tests/checkout/.icase.c.swp diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c index b6d4e949a..ecbcc8a90 100644 --- a/tests/checkout/crlf.c +++ b/tests/checkout/crlf.c @@ -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"); diff --git a/tests/checkout/index.c b/tests/checkout/index.c index 112324a04..63ed4b177 100644 --- a/tests/checkout/index.c +++ b/tests/checkout/index.c @@ -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)); diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index 0fabadc8d..7ba9c250f 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -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); +} + diff --git a/tests/checkout/typechange.c b/tests/checkout/typechange.c index 7aa14b36d..c32330950 100644 --- a/tests/checkout/typechange.c +++ b/tests/checkout/typechange.c @@ -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)); diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index a0264b0d0..ac7c19212 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -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")); } diff --git a/tests/online/clone.c b/tests/online/clone.c index cae7b3338..3bb927955 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -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; diff --git a/tests/perf/helper__perf__do_merge.c b/tests/perf/helper__perf__do_merge.c index 00221851e..4c41f926c 100644 --- a/tests/perf/helper__perf__do_merge.c +++ b/tests/perf/helper__perf__do_merge.c @@ -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")); |