Merge branch 'ds/add-with-sparse-index' into ds/sparse-index-ignored-files
* ds/add-with-sparse-index: add: remove ensure_full_index() with --renormalize add: ignore outside the sparse-checkout in refresh() pathspec: stop calling ensure_full_index add: allow operating on a sparse-only index t1092: test merge conflicts outside cone
This commit is contained in:
@ -144,8 +144,6 @@ static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
|
|||||||
{
|
{
|
||||||
int i, retval = 0;
|
int i, retval = 0;
|
||||||
|
|
||||||
/* TODO: audit for interaction with sparse-index. */
|
|
||||||
ensure_full_index(&the_index);
|
|
||||||
for (i = 0; i < active_nr; i++) {
|
for (i = 0; i < active_nr; i++) {
|
||||||
struct cache_entry *ce = active_cache[i];
|
struct cache_entry *ce = active_cache[i];
|
||||||
|
|
||||||
@ -192,13 +190,21 @@ static int refresh(int verbose, const struct pathspec *pathspec)
|
|||||||
struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
|
struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
|
||||||
int flags = REFRESH_IGNORE_SKIP_WORKTREE |
|
int flags = REFRESH_IGNORE_SKIP_WORKTREE |
|
||||||
(verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
|
(verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
|
||||||
|
struct pattern_list pl = { 0 };
|
||||||
|
int sparse_checkout_enabled = !get_sparse_checkout_patterns(&pl);
|
||||||
|
|
||||||
seen = xcalloc(pathspec->nr, 1);
|
seen = xcalloc(pathspec->nr, 1);
|
||||||
refresh_index(&the_index, flags, pathspec, seen,
|
refresh_index(&the_index, flags, pathspec, seen,
|
||||||
_("Unstaged changes after refreshing the index:"));
|
_("Unstaged changes after refreshing the index:"));
|
||||||
for (i = 0; i < pathspec->nr; i++) {
|
for (i = 0; i < pathspec->nr; i++) {
|
||||||
if (!seen[i]) {
|
if (!seen[i]) {
|
||||||
if (matches_skip_worktree(pathspec, i, &skip_worktree_seen)) {
|
const char *path = pathspec->items[i].original;
|
||||||
|
int dtype = DT_REG;
|
||||||
|
|
||||||
|
if (matches_skip_worktree(pathspec, i, &skip_worktree_seen) ||
|
||||||
|
(sparse_checkout_enabled &&
|
||||||
|
!path_matches_pattern_list(path, strlen(path), NULL,
|
||||||
|
&dtype, &pl, &the_index))) {
|
||||||
string_list_append(&only_match_skip_worktree,
|
string_list_append(&only_match_skip_worktree,
|
||||||
pathspec->items[i].original);
|
pathspec->items[i].original);
|
||||||
} else {
|
} else {
|
||||||
@ -528,6 +534,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||||||
add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
|
add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize;
|
||||||
require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
|
require_pathspec = !(take_worktree_changes || (0 < addremove_explicit));
|
||||||
|
|
||||||
|
prepare_repo_settings(the_repository);
|
||||||
|
the_repository->settings.command_requires_full_index = 0;
|
||||||
|
|
||||||
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -37,8 +37,6 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec,
|
|||||||
num_unmatched++;
|
num_unmatched++;
|
||||||
if (!num_unmatched)
|
if (!num_unmatched)
|
||||||
return;
|
return;
|
||||||
/* TODO: audit for interaction with sparse-index. */
|
|
||||||
ensure_full_index(istate);
|
|
||||||
for (i = 0; i < istate->cache_nr; i++) {
|
for (i = 0; i < istate->cache_nr; i++) {
|
||||||
const struct cache_entry *ce = istate->cache[i];
|
const struct cache_entry *ce = istate->cache[i];
|
||||||
if (sw_action == PS_IGNORE_SKIP_WORKTREE && ce_skip_worktree(ce))
|
if (sw_action == PS_IGNORE_SKIP_WORKTREE && ce_skip_worktree(ce))
|
||||||
|
@ -114,6 +114,16 @@ test_expect_success 'setup' '
|
|||||||
git add . &&
|
git add . &&
|
||||||
git commit -m "file to dir" &&
|
git commit -m "file to dir" &&
|
||||||
|
|
||||||
|
for side in left right
|
||||||
|
do
|
||||||
|
git checkout -b merge-$side base &&
|
||||||
|
echo $side >>deep/deeper2/a &&
|
||||||
|
echo $side >>folder1/a &&
|
||||||
|
echo $side >>folder2/a &&
|
||||||
|
git add . &&
|
||||||
|
git commit -m "$side" || return 1
|
||||||
|
done &&
|
||||||
|
|
||||||
git checkout -b deepest base &&
|
git checkout -b deepest base &&
|
||||||
echo "updated deepest" >deep/deeper1/deepest/a &&
|
echo "updated deepest" >deep/deeper1/deepest/a &&
|
||||||
git commit -a -m "update deepest" &&
|
git commit -a -m "update deepest" &&
|
||||||
@ -312,9 +322,6 @@ test_expect_success 'commit including unstaged changes' '
|
|||||||
test_expect_success 'status/add: outside sparse cone' '
|
test_expect_success 'status/add: outside sparse cone' '
|
||||||
init_repos &&
|
init_repos &&
|
||||||
|
|
||||||
# adding a "missing" file outside the cone should fail
|
|
||||||
test_sparse_match test_must_fail git add folder1/a &&
|
|
||||||
|
|
||||||
# folder1 is at HEAD, but outside the sparse cone
|
# folder1 is at HEAD, but outside the sparse cone
|
||||||
run_on_sparse mkdir folder1 &&
|
run_on_sparse mkdir folder1 &&
|
||||||
cp initial-repo/folder1/a sparse-checkout/folder1/a &&
|
cp initial-repo/folder1/a sparse-checkout/folder1/a &&
|
||||||
@ -330,21 +337,23 @@ test_expect_success 'status/add: outside sparse cone' '
|
|||||||
|
|
||||||
test_sparse_match git status --porcelain=v2 &&
|
test_sparse_match git status --porcelain=v2 &&
|
||||||
|
|
||||||
# This "git add folder1/a" fails with a warning
|
# Adding the path outside of the sparse-checkout cone should fail.
|
||||||
# in the sparse repos, differing from the full
|
|
||||||
# repo. This is intentional.
|
|
||||||
test_sparse_match test_must_fail git add folder1/a &&
|
test_sparse_match test_must_fail git add folder1/a &&
|
||||||
test_sparse_match test_must_fail git add --refresh folder1/a &&
|
test_sparse_match test_must_fail git add --refresh folder1/a &&
|
||||||
test_all_match git status --porcelain=v2 &&
|
|
||||||
|
# NEEDSWORK: Adding a newly-tracked file outside the cone succeeds
|
||||||
|
test_sparse_match git add folder1/new &&
|
||||||
|
|
||||||
test_all_match git add . &&
|
test_all_match git add . &&
|
||||||
test_all_match git status --porcelain=v2 &&
|
test_all_match git status --porcelain=v2 &&
|
||||||
test_all_match git commit -m folder1/new &&
|
test_all_match git commit -m folder1/new &&
|
||||||
|
test_all_match git rev-parse HEAD^{tree} &&
|
||||||
|
|
||||||
run_on_all ../edit-contents folder1/newer &&
|
run_on_all ../edit-contents folder1/newer &&
|
||||||
test_all_match git add folder1/ &&
|
test_all_match git add folder1/ &&
|
||||||
test_all_match git status --porcelain=v2 &&
|
test_all_match git status --porcelain=v2 &&
|
||||||
test_all_match git commit -m folder1/newer
|
test_all_match git commit -m folder1/newer &&
|
||||||
|
test_all_match git rev-parse HEAD^{tree}
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'checkout and reset --hard' '
|
test_expect_success 'checkout and reset --hard' '
|
||||||
@ -482,6 +491,39 @@ test_expect_success 'merge' '
|
|||||||
test_all_match git rev-parse HEAD^{tree}
|
test_all_match git rev-parse HEAD^{tree}
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# NEEDSWORK: This test is documenting current behavior, but that
|
||||||
|
# behavior can be confusing to users so there is desire to change it.
|
||||||
|
# Right now, users might be using this flow to work through conflicts,
|
||||||
|
# so any solution should present advice to users who try this sequence
|
||||||
|
# of commands to follow whatever new method we create.
|
||||||
|
test_expect_success 'merge with conflict outside cone' '
|
||||||
|
init_repos &&
|
||||||
|
|
||||||
|
test_all_match git checkout -b merge-tip merge-left &&
|
||||||
|
test_all_match git status --porcelain=v2 &&
|
||||||
|
test_all_match test_must_fail git merge -m merge merge-right &&
|
||||||
|
test_all_match git status --porcelain=v2 &&
|
||||||
|
|
||||||
|
# Resolve the conflict in different ways:
|
||||||
|
# 1. Revert to the base
|
||||||
|
test_all_match git checkout base -- deep/deeper2/a &&
|
||||||
|
test_all_match git status --porcelain=v2 &&
|
||||||
|
|
||||||
|
# 2. Add the file with conflict markers
|
||||||
|
test_all_match git add folder1/a &&
|
||||||
|
test_all_match git status --porcelain=v2 &&
|
||||||
|
|
||||||
|
# 3. Rename the file to another sparse filename and
|
||||||
|
# accept conflict markers as resolved content.
|
||||||
|
run_on_all mv folder2/a folder2/z &&
|
||||||
|
test_all_match git add folder2 &&
|
||||||
|
test_all_match git status --porcelain=v2 &&
|
||||||
|
|
||||||
|
test_all_match git merge --continue &&
|
||||||
|
test_all_match git status --porcelain=v2 &&
|
||||||
|
test_all_match git rev-parse HEAD^{tree}
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'merge with outside renames' '
|
test_expect_success 'merge with outside renames' '
|
||||||
init_repos &&
|
init_repos &&
|
||||||
|
|
||||||
@ -598,7 +640,14 @@ test_expect_success 'sparse-index is not expanded' '
|
|||||||
git -C sparse-index reset --hard &&
|
git -C sparse-index reset --hard &&
|
||||||
ensure_not_expanded checkout rename-out-to-out -- deep/deeper1 &&
|
ensure_not_expanded checkout rename-out-to-out -- deep/deeper1 &&
|
||||||
git -C sparse-index reset --hard &&
|
git -C sparse-index reset --hard &&
|
||||||
ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1
|
ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 &&
|
||||||
|
|
||||||
|
echo >>sparse-index/README.md &&
|
||||||
|
ensure_not_expanded add -A &&
|
||||||
|
echo >>sparse-index/extra.txt &&
|
||||||
|
ensure_not_expanded add extra.txt &&
|
||||||
|
echo >>sparse-index/untracked.txt &&
|
||||||
|
ensure_not_expanded add .
|
||||||
'
|
'
|
||||||
|
|
||||||
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
|
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
|
||||||
|
Reference in New Issue
Block a user