Code

checkout/merge: optionally fail operation when ignored files need to be overwritten
authorClemens Buchacher <drizzd@aon.at>
Sat, 21 Aug 2010 06:48:44 +0000 (08:48 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sun, 22 Aug 2010 06:45:31 +0000 (23:45 -0700)
Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
builtin/checkout.c
builtin/merge.c
cache.h
config.c
environment.c

index 5e86a28f92b38865a767ba569ab453aeda454f8d..fdaa586f08b60758aafca7d8b01ab6cd979dd039 100644 (file)
@@ -450,6 +450,13 @@ core.excludesfile::
        to the value of `$HOME` and "{tilde}user/" to the specified user's
        home directory.  See linkgit:gitignore[5].
 
+core.ignoredareprecious::
+       By default ignored (i.e. trashable) untracked files are
+       automatically removed from the working tree when they get in
+       the way of merge or switching between branches.  This option
+       declares that such files are precious instead, and prevents
+       merges and checkouts from succeeding.
+
 core.editor::
        Commands such as `commit` and `tag` that lets you edit
        messages by launching an editor uses the value of this
index 7f81120c728dce6fe712280f40583925eda264e3..cb83e6a6318b8b723a3ab9d97eac1556e2aa1d9b 100644 (file)
@@ -392,9 +392,11 @@ static int merge_working_tree(struct checkout_opts *opts,
                topts.gently = opts->merge && old->commit;
                topts.verbose_update = !opts->quiet;
                topts.fn = twoway_merge;
-               topts.dir = xcalloc(1, sizeof(*topts.dir));
-               topts.dir->flags |= DIR_SHOW_IGNORED;
-               topts.dir->exclude_per_dir = ".gitignore";
+               if (!ignored_are_precious) {
+                       topts.dir = xcalloc(1, sizeof(*topts.dir));
+                       topts.dir->flags |= DIR_SHOW_IGNORED;
+                       topts.dir->exclude_per_dir = ".gitignore";
+               }
                tree = parse_tree_indirect(old->commit ?
                                           old->commit->object.sha1 :
                                           (unsigned char *)EMPTY_TREE_SHA1_BIN);
@@ -677,6 +679,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
                OPT_SET_INT('3', "theirs", &opts.writeout_stage, "stage",
                            3),
                OPT_BOOLEAN('f', "force", &opts.force, "force"),
+               OPT_BOOLEAN('i', "ignored-are-precious", &ignored_are_precious,
+                 "fail when an ignored file needs to be overwritten"),
                OPT_BOOLEAN('m', "merge", &opts.merge, "merge"),
                OPT_STRING(0, "conflict", &conflict_style, "style",
                           "conflict style (merge or diff3)"),
index 37ce4f589f6582abf0d1ef5bd263f590a16853d5..9ca7c5c726aa381a980c5a52593d8277717c13bb 100644 (file)
@@ -185,6 +185,8 @@ static struct option builtin_merge_options[] = {
                "allow fast-forward (default)"),
        OPT_BOOLEAN(0, "ff-only", &fast_forward_only,
                "abort if fast-forward is not possible"),
+       OPT_BOOLEAN('i', "ignored-are-precious", &ignored_are_precious,
+         "fail when an ignored file needs to be overwritten"),
        OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
        OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
                "merge strategy to use", option_parse_strategy),
@@ -693,9 +695,11 @@ int checkout_fast_forward(const unsigned char *head, const unsigned char *remote
        memset(&opts, 0, sizeof(opts));
        memset(&t, 0, sizeof(t));
        memset(&dir, 0, sizeof(dir));
-       dir.flags |= DIR_SHOW_IGNORED;
-       dir.exclude_per_dir = ".gitignore";
-       opts.dir = &dir;
+       if (!ignored_are_precious) {
+               dir.flags |= DIR_SHOW_IGNORED;
+               dir.exclude_per_dir = ".gitignore";
+               opts.dir = &dir;
+       }
 
        opts.head_idx = 1;
        opts.src_index = &the_index;
diff --git a/cache.h b/cache.h
index 37ef9d8a0058bb0cc7826b2a22706064a3f6d3d7..cf5516faf0f9e755b38678cc17741f1d186859aa 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -548,6 +548,7 @@ extern size_t packed_git_window_size;
 extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
 extern int read_replace_refs;
+extern int ignored_are_precious;
 extern int fsync_object_files;
 extern int core_preload_index;
 extern int core_apply_sparse_checkout;
index cdcf5836c6c374eb59e80f89dbcf525fd6bf780f..c06b7f6440defc7ebe6c79e0945ceaf4c9d48383 100644 (file)
--- a/config.c
+++ b/config.c
@@ -563,6 +563,11 @@ static int git_default_core_config(const char *var, const char *value)
        if (!strcmp(var, "core.excludesfile"))
                return git_config_pathname(&excludes_file, var, value);
 
+       if (!strcmp(var, "core.ignoredareprecious")) {
+               ignored_are_precious = git_config_bool(var, value);
+               return 0;
+       }
+
        if (!strcmp(var, "core.whitespace")) {
                if (!value)
                        return config_error_nonbool(var);
index 83d38d3c2354e8582d5af91c6d529a2f2836dc2c..0667c1f170444dd03fdf11f24e5def481359d0cd 100644 (file)
@@ -30,6 +30,7 @@ const char *apply_default_ignorewhitespace;
 int zlib_compression_level = Z_BEST_SPEED;
 int core_compression_level;
 int core_compression_seen;
+int ignored_are_precious;
 int fsync_object_files;
 size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
 size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;