зеркало из https://github.com/microsoft/git.git
unpack_trees(): apply $GIT_DIR/info/sparse-checkout to the final index
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
08aefc9e47
Коммит
e800ec9d72
|
@ -32,6 +32,12 @@ static struct unpack_trees_error_msgs unpack_plumbing_errors = {
|
|||
|
||||
/* bind_overlap */
|
||||
"Entry '%s' overlaps with '%s'. Cannot bind.",
|
||||
|
||||
/* sparse_not_uptodate_file */
|
||||
"Entry '%s' not uptodate. Cannot update sparse checkout.",
|
||||
|
||||
/* would_lose_orphaned */
|
||||
"Working tree file '%s' would be %s by sparse checkout update.",
|
||||
};
|
||||
|
||||
#define ERRORMSG(o,fld) \
|
||||
|
@ -125,6 +131,57 @@ static int check_updates(struct unpack_trees_options *o)
|
|||
return errs != 0;
|
||||
}
|
||||
|
||||
static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o);
|
||||
static int verify_absent_sparse(struct cache_entry *ce, const char *action, struct unpack_trees_options *o);
|
||||
|
||||
static int will_have_skip_worktree(const struct cache_entry *ce, struct unpack_trees_options *o)
|
||||
{
|
||||
const char *basename;
|
||||
|
||||
if (ce_stage(ce))
|
||||
return 0;
|
||||
|
||||
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)
|
||||
{
|
||||
int was_skip_worktree = ce_skip_worktree(ce);
|
||||
|
||||
if (will_have_skip_worktree(ce, o))
|
||||
ce->ce_flags |= CE_SKIP_WORKTREE;
|
||||
else
|
||||
ce->ce_flags &= ~CE_SKIP_WORKTREE;
|
||||
|
||||
/*
|
||||
* We only care about files getting into the checkout area
|
||||
* If merge strategies want to remove some, go ahead, this
|
||||
* flag will be removed eventually in unpack_trees() if it's
|
||||
* outside checkout area.
|
||||
*/
|
||||
if (ce->ce_flags & CE_REMOVE)
|
||||
return 0;
|
||||
|
||||
if (!was_skip_worktree && ce_skip_worktree(ce)) {
|
||||
/*
|
||||
* If CE_UPDATE is set, verify_uptodate() must be called already
|
||||
* also stat info may have lost after merged_entry() so calling
|
||||
* verify_uptodate() again may fail
|
||||
*/
|
||||
if (!(ce->ce_flags & CE_UPDATE) && verify_uptodate_sparse(ce, o))
|
||||
return -1;
|
||||
ce->ce_flags |= CE_WT_REMOVE;
|
||||
}
|
||||
if (was_skip_worktree && !ce_skip_worktree(ce)) {
|
||||
if (verify_absent_sparse(ce, "overwritten", o))
|
||||
return -1;
|
||||
ce->ce_flags |= CE_UPDATE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o)
|
||||
{
|
||||
int ret = o->fn(src, o);
|
||||
|
@ -376,7 +433,7 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
|
|||
*/
|
||||
int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
|
||||
{
|
||||
int ret;
|
||||
int i, ret;
|
||||
static struct cache_entry *dfc;
|
||||
struct exclude_list el;
|
||||
|
||||
|
@ -440,6 +497,17 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!o->skip_sparse_checkout) {
|
||||
for (i = 0;i < o->result.cache_nr;i++) {
|
||||
struct cache_entry *ce = o->result.cache[i];
|
||||
|
||||
if (apply_sparse_checkout(ce, o)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
o->src_index = NULL;
|
||||
ret = check_updates(o) ? (-2) : 0;
|
||||
if (o->dst_index)
|
||||
|
@ -512,6 +580,12 @@ static int verify_uptodate(struct cache_entry *ce,
|
|||
return verify_uptodate_1(ce, o, ERRORMSG(o, not_uptodate_file));
|
||||
}
|
||||
|
||||
static int verify_uptodate_sparse(struct cache_entry *ce,
|
||||
struct unpack_trees_options *o)
|
||||
{
|
||||
return verify_uptodate_1(ce, o, ERRORMSG(o, sparse_not_uptodate_file));
|
||||
}
|
||||
|
||||
static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o)
|
||||
{
|
||||
if (ce)
|
||||
|
@ -705,6 +779,12 @@ static int verify_absent(struct cache_entry *ce, const char *action,
|
|||
return verify_absent_1(ce, action, o, ERRORMSG(o, would_lose_untracked));
|
||||
}
|
||||
|
||||
static int verify_absent_sparse(struct cache_entry *ce, const char *action,
|
||||
struct unpack_trees_options *o)
|
||||
{
|
||||
return verify_absent_1(ce, action, o, ERRORMSG(o, would_lose_orphaned));
|
||||
}
|
||||
|
||||
static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
|
||||
struct unpack_trees_options *o)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,8 @@ struct unpack_trees_error_msgs {
|
|||
const char *not_uptodate_dir;
|
||||
const char *would_lose_untracked;
|
||||
const char *bind_overlap;
|
||||
const char *sparse_not_uptodate_file;
|
||||
const char *would_lose_orphaned;
|
||||
};
|
||||
|
||||
struct unpack_trees_options {
|
||||
|
|
Загрузка…
Ссылка в новой задаче