Merge branch 'nd/maint-fix-add-typo-detection'
* nd/maint-fix-add-typo-detection: Revert "excluded_1(): support exclude files in index" unpack-trees: fix sparse checkout's "unable to match directories" unpack-trees: move all skip-worktree checks back to unpack_trees() dir.c: add free_excludes() cache.h: realign and use (1 << x) form for CE_* constants
This commit is contained in:
commit
e39212ab08
@ -416,13 +416,6 @@ turn `core.sparseCheckout` on in order to have sparse checkout
|
|||||||
support.
|
support.
|
||||||
|
|
||||||
|
|
||||||
BUGS
|
|
||||||
----
|
|
||||||
In order to match a directory with $GIT_DIR/info/sparse-checkout,
|
|
||||||
trailing slash must be used. The form without trailing slash, while
|
|
||||||
works with .gitignore, does not work with sparse checkout.
|
|
||||||
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkgit:git-write-tree[1]; linkgit:git-ls-files[1];
|
linkgit:git-write-tree[1]; linkgit:git-ls-files[1];
|
||||||
|
26
cache.h
26
cache.h
@ -170,26 +170,26 @@ struct cache_entry {
|
|||||||
*
|
*
|
||||||
* In-memory only flags
|
* In-memory only flags
|
||||||
*/
|
*/
|
||||||
#define CE_UPDATE (0x10000)
|
#define CE_UPDATE (1 << 16)
|
||||||
#define CE_REMOVE (0x20000)
|
#define CE_REMOVE (1 << 17)
|
||||||
#define CE_UPTODATE (0x40000)
|
#define CE_UPTODATE (1 << 18)
|
||||||
#define CE_ADDED (0x80000)
|
#define CE_ADDED (1 << 19)
|
||||||
|
|
||||||
#define CE_HASHED (0x100000)
|
#define CE_HASHED (1 << 20)
|
||||||
#define CE_UNHASHED (0x200000)
|
#define CE_UNHASHED (1 << 21)
|
||||||
#define CE_CONFLICTED (0x800000)
|
#define CE_WT_REMOVE (1 << 22) /* remove in work directory */
|
||||||
|
#define CE_CONFLICTED (1 << 23)
|
||||||
|
|
||||||
#define CE_WT_REMOVE (0x400000) /* remove in work directory */
|
#define CE_UNPACKED (1 << 24)
|
||||||
|
#define CE_NEW_SKIP_WORKTREE (1 << 25)
|
||||||
#define CE_UNPACKED (0x1000000)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extended on-disk flags
|
* Extended on-disk flags
|
||||||
*/
|
*/
|
||||||
#define CE_INTENT_TO_ADD 0x20000000
|
#define CE_INTENT_TO_ADD (1 << 29)
|
||||||
#define CE_SKIP_WORKTREE 0x40000000
|
#define CE_SKIP_WORKTREE (1 << 30)
|
||||||
/* CE_EXTENDED2 is for future extension */
|
/* CE_EXTENDED2 is for future extension */
|
||||||
#define CE_EXTENDED2 0x80000000
|
#define CE_EXTENDED2 (1 << 31)
|
||||||
|
|
||||||
#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD | CE_SKIP_WORKTREE)
|
#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD | CE_SKIP_WORKTREE)
|
||||||
|
|
||||||
|
19
dir.c
19
dir.c
@ -253,6 +253,18 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_excludes(struct exclude_list *el)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < el->nr; i++)
|
||||||
|
free(el->excludes[i]);
|
||||||
|
free(el->excludes);
|
||||||
|
|
||||||
|
el->nr = 0;
|
||||||
|
el->excludes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int add_excludes_from_file_to_list(const char *fname,
|
int add_excludes_from_file_to_list(const char *fname,
|
||||||
const char *base,
|
const char *base,
|
||||||
int baselen,
|
int baselen,
|
||||||
@ -389,13 +401,6 @@ int excluded_from_list(const char *pathname,
|
|||||||
int to_exclude = x->to_exclude;
|
int to_exclude = x->to_exclude;
|
||||||
|
|
||||||
if (x->flags & EXC_FLAG_MUSTBEDIR) {
|
if (x->flags & EXC_FLAG_MUSTBEDIR) {
|
||||||
if (!dtype) {
|
|
||||||
if (!prefixcmp(pathname, exclude) &&
|
|
||||||
pathname[x->patternlen] == '/')
|
|
||||||
return to_exclude;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (*dtype == DT_UNKNOWN)
|
if (*dtype == DT_UNKNOWN)
|
||||||
*dtype = get_dtype(NULL, pathname, pathlen);
|
*dtype = get_dtype(NULL, pathname, pathlen);
|
||||||
if (*dtype != DT_DIR)
|
if (*dtype != DT_DIR)
|
||||||
|
1
dir.h
1
dir.h
@ -78,6 +78,7 @@ extern int add_excludes_from_file_to_list(const char *fname, const char *base, i
|
|||||||
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
|
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
|
||||||
extern void add_exclude(const char *string, const char *base,
|
extern void add_exclude(const char *string, const char *base,
|
||||||
int baselen, struct exclude_list *which);
|
int baselen, struct exclude_list *which);
|
||||||
|
extern void free_excludes(struct exclude_list *el);
|
||||||
extern int file_exists(const char *);
|
extern int file_exists(const char *);
|
||||||
|
|
||||||
extern char *get_relative_cwd(char *buffer, int size, const char *dir);
|
extern char *get_relative_cwd(char *buffer, int size, const char *dir);
|
||||||
|
@ -94,12 +94,20 @@ test_expect_success 'match directories with trailing slash' '
|
|||||||
test -f sub/added
|
test -f sub/added
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_failure 'match directories without trailing slash' '
|
test_expect_success 'match directories without trailing slash' '
|
||||||
echo init.t >.git/info/sparse-checkout &&
|
|
||||||
echo sub >>.git/info/sparse-checkout &&
|
echo sub >>.git/info/sparse-checkout &&
|
||||||
git read-tree -m -u HEAD &&
|
git read-tree -m -u HEAD &&
|
||||||
git ls-files -t >result &&
|
git ls-files -t >result &&
|
||||||
test_cmp expected.swt result &&
|
test_cmp expected.swt-noinit result &&
|
||||||
|
test ! -f init.t &&
|
||||||
|
test -f sub/added
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'match directory pattern' '
|
||||||
|
echo "s?b" >>.git/info/sparse-checkout &&
|
||||||
|
git read-tree -m -u HEAD &&
|
||||||
|
git ls-files -t >result &&
|
||||||
|
test_cmp expected.swt-noinit result &&
|
||||||
test ! -f init.t &&
|
test ! -f init.t &&
|
||||||
test -f sub/added
|
test -f sub/added
|
||||||
'
|
'
|
||||||
|
238
unpack-trees.c
238
unpack-trees.c
@ -231,20 +231,11 @@ static int check_updates(struct unpack_trees_options *o)
|
|||||||
static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o);
|
static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o);
|
||||||
static int verify_absent_sparse(struct cache_entry *ce, enum unpack_trees_error_types, struct unpack_trees_options *o);
|
static int verify_absent_sparse(struct cache_entry *ce, enum unpack_trees_error_types, struct unpack_trees_options *o);
|
||||||
|
|
||||||
static int will_have_skip_worktree(const struct cache_entry *ce, struct unpack_trees_options *o)
|
|
||||||
{
|
|
||||||
const char *basename;
|
|
||||||
|
|
||||||
basename = strrchr(ce->name, '/');
|
|
||||||
basename = basename ? basename+1 : ce->name;
|
|
||||||
return excluded_from_list(ce->name, ce_namelen(ce), basename, NULL, o->el) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o)
|
static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o)
|
||||||
{
|
{
|
||||||
int was_skip_worktree = ce_skip_worktree(ce);
|
int was_skip_worktree = ce_skip_worktree(ce);
|
||||||
|
|
||||||
if (!ce_stage(ce) && will_have_skip_worktree(ce, o))
|
if (ce->ce_flags & CE_NEW_SKIP_WORKTREE)
|
||||||
ce->ce_flags |= CE_SKIP_WORKTREE;
|
ce->ce_flags |= CE_SKIP_WORKTREE;
|
||||||
else
|
else
|
||||||
ce->ce_flags &= ~CE_SKIP_WORKTREE;
|
ce->ce_flags &= ~CE_SKIP_WORKTREE;
|
||||||
@ -319,7 +310,7 @@ static void mark_all_ce_unused(struct index_state *index)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < index->cache_nr; i++)
|
for (i = 0; i < index->cache_nr; i++)
|
||||||
index->cache[i]->ce_flags &= ~CE_UNPACKED;
|
index->cache[i]->ce_flags &= ~(CE_UNPACKED | CE_ADDED | CE_NEW_SKIP_WORKTREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int locate_in_src_index(struct cache_entry *ce,
|
static int locate_in_src_index(struct cache_entry *ce,
|
||||||
@ -820,9 +811,177 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Whole directory matching */
|
||||||
|
static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
|
||||||
|
char *prefix, int prefix_len,
|
||||||
|
char *basename,
|
||||||
|
int select_mask, int clear_mask,
|
||||||
|
struct exclude_list *el)
|
||||||
|
{
|
||||||
|
struct cache_entry **cache_end = cache + nr;
|
||||||
|
int dtype = DT_DIR;
|
||||||
|
int ret = excluded_from_list(prefix, prefix_len, basename, &dtype, el);
|
||||||
|
|
||||||
|
prefix[prefix_len++] = '/';
|
||||||
|
|
||||||
|
/* included, no clearing for any entries under this directory */
|
||||||
|
if (!ret) {
|
||||||
|
for (; cache != cache_end; cache++) {
|
||||||
|
struct cache_entry *ce = *cache;
|
||||||
|
if (strncmp(ce->name, prefix, prefix_len))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return nr - (cache_end - cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* excluded, clear all selected entries under this directory. */
|
||||||
|
if (ret == 1) {
|
||||||
|
for (; cache != cache_end; cache++) {
|
||||||
|
struct cache_entry *ce = *cache;
|
||||||
|
if (select_mask && !(ce->ce_flags & select_mask))
|
||||||
|
continue;
|
||||||
|
if (strncmp(ce->name, prefix, prefix_len))
|
||||||
|
break;
|
||||||
|
ce->ce_flags &= ~clear_mask;
|
||||||
|
}
|
||||||
|
return nr - (cache_end - cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse the index, find every entry that matches according to
|
||||||
|
* o->el. Do "ce_flags &= ~clear_mask" on those entries. Return the
|
||||||
|
* number of traversed entries.
|
||||||
|
*
|
||||||
|
* If select_mask is non-zero, only entries whose ce_flags has on of
|
||||||
|
* those bits enabled are traversed.
|
||||||
|
*
|
||||||
|
* cache : pointer to an index entry
|
||||||
|
* prefix_len : an offset to its path
|
||||||
|
*
|
||||||
|
* The current path ("prefix") including the trailing '/' is
|
||||||
|
* cache[0]->name[0..(prefix_len-1)]
|
||||||
|
* Top level path has prefix_len zero.
|
||||||
|
*/
|
||||||
|
static int clear_ce_flags_1(struct cache_entry **cache, int nr,
|
||||||
|
char *prefix, int prefix_len,
|
||||||
|
int select_mask, int clear_mask,
|
||||||
|
struct exclude_list *el)
|
||||||
|
{
|
||||||
|
struct cache_entry **cache_end = cache + nr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process all entries that have the given prefix and meet
|
||||||
|
* select_mask condition
|
||||||
|
*/
|
||||||
|
while(cache != cache_end) {
|
||||||
|
struct cache_entry *ce = *cache;
|
||||||
|
const char *name, *slash;
|
||||||
|
int len, dtype;
|
||||||
|
|
||||||
|
if (select_mask && !(ce->ce_flags & select_mask)) {
|
||||||
|
cache++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix_len && strncmp(ce->name, prefix, prefix_len))
|
||||||
|
break;
|
||||||
|
|
||||||
|
name = ce->name + prefix_len;
|
||||||
|
slash = strchr(name, '/');
|
||||||
|
|
||||||
|
/* If it's a directory, try whole directory match first */
|
||||||
|
if (slash) {
|
||||||
|
int processed;
|
||||||
|
|
||||||
|
len = slash - name;
|
||||||
|
memcpy(prefix + prefix_len, name, len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* terminate the string (no trailing slash),
|
||||||
|
* clear_c_f_dir needs it
|
||||||
|
*/
|
||||||
|
prefix[prefix_len + len] = '\0';
|
||||||
|
processed = clear_ce_flags_dir(cache, cache_end - cache,
|
||||||
|
prefix, prefix_len + len,
|
||||||
|
prefix + prefix_len,
|
||||||
|
select_mask, clear_mask,
|
||||||
|
el);
|
||||||
|
|
||||||
|
/* clear_c_f_dir eats a whole dir already? */
|
||||||
|
if (processed) {
|
||||||
|
cache += processed;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix[prefix_len + len++] = '/';
|
||||||
|
cache += clear_ce_flags_1(cache, cache_end - cache,
|
||||||
|
prefix, prefix_len + len,
|
||||||
|
select_mask, clear_mask, el);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Non-directory */
|
||||||
|
dtype = ce_to_dtype(ce);
|
||||||
|
if (excluded_from_list(ce->name, ce_namelen(ce), name, &dtype, el) > 0)
|
||||||
|
ce->ce_flags &= ~clear_mask;
|
||||||
|
cache++;
|
||||||
|
}
|
||||||
|
return nr - (cache_end - cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clear_ce_flags(struct cache_entry **cache, int nr,
|
||||||
|
int select_mask, int clear_mask,
|
||||||
|
struct exclude_list *el)
|
||||||
|
{
|
||||||
|
char prefix[PATH_MAX];
|
||||||
|
return clear_ce_flags_1(cache, nr,
|
||||||
|
prefix, 0,
|
||||||
|
select_mask, clear_mask,
|
||||||
|
el);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set/Clear CE_NEW_SKIP_WORKTREE according to $GIT_DIR/info/sparse-checkout
|
||||||
|
*/
|
||||||
|
static void mark_new_skip_worktree(struct exclude_list *el,
|
||||||
|
struct index_state *the_index,
|
||||||
|
int select_flag, int skip_wt_flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Pretend the narrowest worktree: only unmerged entries
|
||||||
|
* are checked out
|
||||||
|
*/
|
||||||
|
for (i = 0; i < the_index->cache_nr; i++) {
|
||||||
|
struct cache_entry *ce = the_index->cache[i];
|
||||||
|
|
||||||
|
if (select_flag && !(ce->ce_flags & select_flag))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ce_stage(ce))
|
||||||
|
ce->ce_flags |= skip_wt_flag;
|
||||||
|
else
|
||||||
|
ce->ce_flags &= ~skip_wt_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2. Widen worktree according to sparse-checkout file.
|
||||||
|
* Matched entries will have skip_wt_flag cleared (i.e. "in")
|
||||||
|
*/
|
||||||
|
clear_ce_flags(the_index->cache, the_index->cache_nr,
|
||||||
|
select_flag, skip_wt_flag, el);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int verify_absent(struct cache_entry *, enum unpack_trees_error_types, struct unpack_trees_options *);
|
||||||
/*
|
/*
|
||||||
* N-way merge "len" trees. Returns 0 on success, -1 on failure to manipulate the
|
* N-way merge "len" trees. Returns 0 on success, -1 on failure to manipulate the
|
||||||
* resulting index, -2 on failure to reflect the changes to the work tree.
|
* resulting index, -2 on failure to reflect the changes to the work tree.
|
||||||
|
*
|
||||||
|
* CE_ADDED, CE_UNPACKED and CE_NEW_SKIP_WORKTREE are used internally
|
||||||
*/
|
*/
|
||||||
int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
|
int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
|
||||||
{
|
{
|
||||||
@ -855,6 +1014,12 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
|
|||||||
o->merge_size = len;
|
o->merge_size = len;
|
||||||
mark_all_ce_unused(o->src_index);
|
mark_all_ce_unused(o->src_index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sparse checkout loop #1: set NEW_SKIP_WORKTREE on existing entries
|
||||||
|
*/
|
||||||
|
if (!o->skip_sparse_checkout)
|
||||||
|
mark_new_skip_worktree(o->el, o->src_index, 0, CE_NEW_SKIP_WORKTREE);
|
||||||
|
|
||||||
if (!dfc)
|
if (!dfc)
|
||||||
dfc = xcalloc(1, cache_entry_size(0));
|
dfc = xcalloc(1, cache_entry_size(0));
|
||||||
o->df_conflict_entry = dfc;
|
o->df_conflict_entry = dfc;
|
||||||
@ -908,9 +1073,29 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
|
|||||||
|
|
||||||
if (!o->skip_sparse_checkout) {
|
if (!o->skip_sparse_checkout) {
|
||||||
int empty_worktree = 1;
|
int empty_worktree = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sparse checkout loop #2: set NEW_SKIP_WORKTREE on entries not in loop #1
|
||||||
|
* If the will have NEW_SKIP_WORKTREE, also set CE_SKIP_WORKTREE
|
||||||
|
* so apply_sparse_checkout() won't attempt to remove it from worktree
|
||||||
|
*/
|
||||||
|
mark_new_skip_worktree(o->el, &o->result, CE_ADDED, CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE);
|
||||||
|
|
||||||
for (i = 0; i < o->result.cache_nr; i++) {
|
for (i = 0; i < o->result.cache_nr; i++) {
|
||||||
struct cache_entry *ce = o->result.cache[i];
|
struct cache_entry *ce = o->result.cache[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entries marked with CE_ADDED in merged_entry() do not have
|
||||||
|
* verify_absent() check (the check is effectively disabled
|
||||||
|
* because CE_NEW_SKIP_WORKTREE is set unconditionally).
|
||||||
|
*
|
||||||
|
* Do the real check now because we have had
|
||||||
|
* correct CE_NEW_SKIP_WORKTREE
|
||||||
|
*/
|
||||||
|
if (ce->ce_flags & CE_ADDED &&
|
||||||
|
verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (apply_sparse_checkout(ce, o)) {
|
if (apply_sparse_checkout(ce, o)) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto done;
|
goto done;
|
||||||
@ -931,11 +1116,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
|
|||||||
*o->dst_index = o->result;
|
*o->dst_index = o->result;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
for (i = 0;i < el.nr;i++)
|
free_excludes(&el);
|
||||||
free(el.excludes[i]);
|
|
||||||
if (el.excludes)
|
|
||||||
free(el.excludes);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return_failed:
|
return_failed:
|
||||||
@ -1003,7 +1184,7 @@ static int verify_uptodate_1(struct cache_entry *ce,
|
|||||||
static int verify_uptodate(struct cache_entry *ce,
|
static int verify_uptodate(struct cache_entry *ce,
|
||||||
struct unpack_trees_options *o)
|
struct unpack_trees_options *o)
|
||||||
{
|
{
|
||||||
if (!o->skip_sparse_checkout && will_have_skip_worktree(ce, o))
|
if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE))
|
||||||
return 0;
|
return 0;
|
||||||
return verify_uptodate_1(ce, o, ERROR_NOT_UPTODATE_FILE);
|
return verify_uptodate_1(ce, o, ERROR_NOT_UPTODATE_FILE);
|
||||||
}
|
}
|
||||||
@ -1209,7 +1390,7 @@ static int verify_absent(struct cache_entry *ce,
|
|||||||
enum unpack_trees_error_types error_type,
|
enum unpack_trees_error_types error_type,
|
||||||
struct unpack_trees_options *o)
|
struct unpack_trees_options *o)
|
||||||
{
|
{
|
||||||
if (!o->skip_sparse_checkout && will_have_skip_worktree(ce, o))
|
if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE))
|
||||||
return 0;
|
return 0;
|
||||||
return verify_absent_1(ce, error_type, o);
|
return verify_absent_1(ce, error_type, o);
|
||||||
}
|
}
|
||||||
@ -1231,10 +1412,23 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
|
|||||||
int update = CE_UPDATE;
|
int update = CE_UPDATE;
|
||||||
|
|
||||||
if (!old) {
|
if (!old) {
|
||||||
|
/*
|
||||||
|
* New index entries. In sparse checkout, the following
|
||||||
|
* verify_absent() will be delayed until after
|
||||||
|
* traverse_trees() finishes in unpack_trees(), then:
|
||||||
|
*
|
||||||
|
* - CE_NEW_SKIP_WORKTREE will be computed correctly
|
||||||
|
* - verify_absent() be called again, this time with
|
||||||
|
* correct CE_NEW_SKIP_WORKTREE
|
||||||
|
*
|
||||||
|
* verify_absent() call here does nothing in sparse
|
||||||
|
* checkout (i.e. o->skip_sparse_checkout == 0)
|
||||||
|
*/
|
||||||
|
update |= CE_ADDED;
|
||||||
|
merge->ce_flags |= CE_NEW_SKIP_WORKTREE;
|
||||||
|
|
||||||
if (verify_absent(merge, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o))
|
if (verify_absent(merge, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o))
|
||||||
return -1;
|
return -1;
|
||||||
if (!o->skip_sparse_checkout && will_have_skip_worktree(merge, o))
|
|
||||||
update |= CE_SKIP_WORKTREE;
|
|
||||||
invalidate_ce_path(merge, o);
|
invalidate_ce_path(merge, o);
|
||||||
} else if (!(old->ce_flags & CE_CONFLICTED)) {
|
} else if (!(old->ce_flags & CE_CONFLICTED)) {
|
||||||
/*
|
/*
|
||||||
@ -1250,8 +1444,8 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
|
|||||||
} else {
|
} else {
|
||||||
if (verify_uptodate(old, o))
|
if (verify_uptodate(old, o))
|
||||||
return -1;
|
return -1;
|
||||||
if (ce_skip_worktree(old))
|
/* Migrate old flags over */
|
||||||
update |= CE_SKIP_WORKTREE;
|
update |= old->ce_flags & (CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE);
|
||||||
invalidate_ce_path(old, o);
|
invalidate_ce_path(old, o);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user