Ignored files can be marked precious to prevent being overwritten during a merge (or even a branch switch). If you really want to make sure no ignored files are overwritten, this config variable is for you. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Documentation/config/core.txt | 6 ++++++ Documentation/gitignore.txt | 5 +++-- unpack-trees.c | 21 ++++++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt index d0e6635fe0..bff5834c13 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -1,3 +1,9 @@ +core.allIgnoredFilesArePreciousWhenMerging:: + During a merge operation, if "precious" attribute is unset, + consider it set. You can explicitly remove "precious" + attribute if needed. See linkgit:gitattributes[5] for more + information. + core.fileMode:: Tells Git if the executable bit of files in the working tree is to be honored. diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt index 0e9614289e..2832df7178 100644 --- a/Documentation/gitignore.txt +++ b/Documentation/gitignore.txt @@ -142,8 +142,9 @@ To stop tracking a file that is currently tracked, use 'git rm --cached'. Ignored files are generally considered discardable. See `precious` -attribute in linkgit:gitattributes[5] to change the behavior regarding -ignored files. +attribute in linkgit:gitattributes[5] and +`core.allIgnoredFilesArePreciousWhenMerging` in linkgit:git-config[1] +to change the behavior regarding ignored files. EXAMPLES -------- diff --git a/unpack-trees.c b/unpack-trees.c index 9a5aadc084..df3b163e2e 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1877,6 +1877,25 @@ static int icase_exists(struct unpack_trees_options *o, const char *name, int le return src && !ie_match_stat(o->src_index, src, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); } +static int is_precious_ignored_file(struct index_state *istate, const char *path) +{ + static struct attr_check *check; + int all_precious; + + if (!check) + check = attr_check_initl("precious", NULL); + if (!check) + return 0; + + git_check_attr(istate, path, check); + if (ATTR_UNSET(check->items[0].value) && + !git_config_get_bool("core.allignoredfilesarepreciouswhenmerging", + &all_precious) && + all_precious) + return 1; + return ATTR_TRUE(check->items[0].value); +} + static int check_ok_to_remove(const char *name, int len, int dtype, const struct cache_entry *ce, struct stat *st, enum unpack_trees_error_types error_type, @@ -1895,7 +1914,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype, return 0; if (o->dir && - !is_precious_file(o->src_index, name) && + !is_precious_ignored_file(o->src_index, name) && is_excluded(o->dir, o->src_index, name, &dtype)) /* * ce->name is explicitly excluded, so it is Ok to -- 2.19.1.1327.g328c130451.dirty