-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sparse-checkout: modify 'git add', 'git rm', and 'git mv' behavior #1018
Changes from 4 commits
642b05f
58389ed
2ebaf8e
24bffda
e3a749e
2c5c834
430ab44
4f7b5cd
30ec609
99d5092
47a1444
28e703d
9fbc88e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1294,7 +1294,7 @@ int match_pathname(const char *pathname, int pathlen, | |
* then our prefix match is all we need; we | ||
* do not need to call fnmatch at all. | ||
*/ | ||
if (!patternlen && !namelen) | ||
if (!patternlen && (!namelen || (flags & PATTERN_FLAG_MUSTBEDIR))) | ||
return 1; | ||
} | ||
|
||
|
@@ -1303,6 +1303,44 @@ int match_pathname(const char *pathname, int pathlen, | |
WM_PATHNAME) == 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Junio C Hamano wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Junio C Hamano wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
|
||
} | ||
|
||
static int path_matches_dir_pattern(const char *pathname, | ||
int pathlen, | ||
struct strbuf **path_parent, | ||
int *dtype, | ||
struct path_pattern *pattern, | ||
struct index_state *istate) | ||
{ | ||
if (!*path_parent) { | ||
char *slash; | ||
CALLOC_ARRAY(*path_parent, 1); | ||
strbuf_add(*path_parent, pathname, pathlen); | ||
slash = find_last_dir_sep((*path_parent)->buf); | ||
|
||
if (slash) | ||
strbuf_setlen(*path_parent, slash - (*path_parent)->buf); | ||
else | ||
strbuf_setlen(*path_parent, 0); | ||
} | ||
|
||
/* | ||
* If the parent directory matches the pattern, then we do not | ||
* need to check for dtype. | ||
*/ | ||
if ((*path_parent)->len && | ||
match_pathname((*path_parent)->buf, (*path_parent)->len, | ||
pattern->base, | ||
pattern->baselen ? pattern->baselen - 1 : 0, | ||
pattern->pattern, pattern->nowildcardlen, | ||
pattern->patternlen, pattern->flags)) | ||
return 1; | ||
|
||
*dtype = resolve_dtype(*dtype, istate, pathname, pathlen); | ||
if (*dtype != DT_DIR) | ||
return 0; | ||
|
||
return 1; | ||
} | ||
|
||
/* | ||
* Scan the given exclude list in reverse to see whether pathname | ||
* should be ignored. The first match (i.e. the last on the list), if | ||
|
@@ -1318,6 +1356,7 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname | |
{ | ||
struct path_pattern *res = NULL; /* undecided */ | ||
int i; | ||
struct strbuf *path_parent = NULL; | ||
|
||
if (!pl->nr) | ||
return NULL; /* undefined */ | ||
|
@@ -1327,11 +1366,10 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname | |
const char *exclude = pattern->pattern; | ||
int prefix = pattern->nowildcardlen; | ||
|
||
if (pattern->flags & PATTERN_FLAG_MUSTBEDIR) { | ||
*dtype = resolve_dtype(*dtype, istate, pathname, pathlen); | ||
if (*dtype != DT_DIR) | ||
continue; | ||
} | ||
if (pattern->flags & PATTERN_FLAG_MUSTBEDIR && | ||
!path_matches_dir_pattern(pathname, pathlen, &path_parent, | ||
dtype, pattern, istate)) | ||
continue; | ||
|
||
if (pattern->flags & PATTERN_FLAG_NODIR) { | ||
if (match_basename(basename, | ||
|
@@ -1355,6 +1393,12 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname | |
break; | ||
} | ||
} | ||
|
||
if (path_parent) { | ||
strbuf_release(path_parent); | ||
free(path_parent); | ||
} | ||
|
||
return res; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -187,6 +187,16 @@ test_sparse_match () { | |
test_cmp sparse-checkout-err sparse-index-err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Junio C Hamano wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
|
||
} | ||
|
||
test_sparse_unstaged () { | ||
file=$1 && | ||
for repo in sparse-checkout sparse-index | ||
do | ||
# Skip "unmerged" paths | ||
git -C $repo diff --staged --diff-filter=ACDMRTXB -- "$file" >diff && | ||
test_must_be_empty diff || return 1 | ||
done | ||
} | ||
|
||
test_expect_success 'sparse-index contents' ' | ||
init_repos && | ||
|
||
|
@@ -291,6 +301,20 @@ test_expect_success 'add, commit, checkout' ' | |
test_all_match git checkout - | ||
' | ||
|
||
# NEEDSWORK: This documents current behavior, but is not a desirable | ||
# behavior (untracked files are handled differently than tracked). | ||
test_expect_success 'add outside sparse cone' ' | ||
init_repos && | ||
|
||
run_on_sparse mkdir folder1 && | ||
run_on_sparse ../edit-contents folder1/a && | ||
run_on_sparse ../edit-contents folder1/newfile && | ||
test_sparse_match test_must_fail git add folder1/a && | ||
grep "Disable or modify the sparsity rules" sparse-checkout-err && | ||
test_sparse_unstaged folder1/a && | ||
test_sparse_match git add folder1/newfile | ||
' | ||
|
||
test_expect_success 'commit including unstaged changes' ' | ||
init_repos && | ||
|
||
|
@@ -339,7 +363,11 @@ test_expect_success 'status/add: outside sparse cone' ' | |
|
||
# Adding the path outside of the sparse-checkout cone should fail. | ||
test_sparse_match test_must_fail git add folder1/a && | ||
grep "Disable or modify the sparsity rules" sparse-checkout-err && | ||
test_sparse_unstaged folder1/a && | ||
test_sparse_match test_must_fail git add --refresh folder1/a && | ||
grep "Disable or modify the sparsity rules" sparse-checkout-err && | ||
test_sparse_unstaged folder1/a && | ||
|
||
# NEEDSWORK: Adding a newly-tracked file outside the cone succeeds | ||
test_sparse_match git add folder1/new && | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ setup_sparse_entry () { | |
fi && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Junio C Hamano wrote (reply to this):
|
||
git add sparse_entry && | ||
git update-index --skip-worktree sparse_entry && | ||
git commit --allow-empty -m "ensure sparse_entry exists at HEAD" && | ||
SPARSE_ENTRY_BLOB=$(git rev-parse :sparse_entry) | ||
} | ||
|
||
|
@@ -36,6 +37,11 @@ setup_gitignore () { | |
EOF | ||
} | ||
|
||
test_sparse_entry_unstaged () { | ||
git diff --staged -- sparse_entry >diff && | ||
test_must_be_empty diff | ||
} | ||
|
||
test_expect_success 'setup' " | ||
cat >sparse_error_header <<-EOF && | ||
The following pathspecs didn't match any eligible path, but they do match index | ||
|
@@ -55,6 +61,7 @@ test_expect_success 'git add does not remove sparse entries' ' | |
setup_sparse_entry && | ||
rm sparse_entry && | ||
test_must_fail git add sparse_entry 2>stderr && | ||
test_sparse_entry_unstaged && | ||
test_cmp error_and_hint stderr && | ||
test_sparse_entry_unchanged | ||
' | ||
|
@@ -73,6 +80,7 @@ test_expect_success 'git add . does not remove sparse entries' ' | |
rm sparse_entry && | ||
setup_gitignore && | ||
test_must_fail git add . 2>stderr && | ||
test_sparse_entry_unstaged && | ||
|
||
cat sparse_error_header >expect && | ||
echo . >>expect && | ||
|
@@ -88,6 +96,7 @@ do | |
setup_sparse_entry && | ||
echo modified >sparse_entry && | ||
test_must_fail git add $opt sparse_entry 2>stderr && | ||
test_sparse_entry_unstaged && | ||
test_cmp error_and_hint stderr && | ||
test_sparse_entry_unchanged | ||
' | ||
|
@@ -98,6 +107,7 @@ test_expect_success 'git add --refresh does not update sparse entries' ' | |
git ls-files --debug sparse_entry | grep mtime >before && | ||
test-tool chmtime -60 sparse_entry && | ||
test_must_fail git add --refresh sparse_entry 2>stderr && | ||
test_sparse_entry_unstaged && | ||
test_cmp error_and_hint stderr && | ||
git ls-files --debug sparse_entry | grep mtime >after && | ||
test_cmp before after | ||
|
@@ -106,6 +116,7 @@ test_expect_success 'git add --refresh does not update sparse entries' ' | |
test_expect_success 'git add --chmod does not update sparse entries' ' | ||
setup_sparse_entry && | ||
test_must_fail git add --chmod=+x sparse_entry 2>stderr && | ||
test_sparse_entry_unstaged && | ||
test_cmp error_and_hint stderr && | ||
test_sparse_entry_unchanged && | ||
! test -x sparse_entry | ||
|
@@ -116,6 +127,7 @@ test_expect_success 'git add --renormalize does not update sparse entries' ' | |
setup_sparse_entry "LINEONE\r\nLINETWO\r\n" && | ||
echo "sparse_entry text=auto" >.gitattributes && | ||
test_must_fail git add --renormalize sparse_entry 2>stderr && | ||
test_sparse_entry_unstaged && | ||
test_cmp error_and_hint stderr && | ||
test_sparse_entry_unchanged | ||
' | ||
|
@@ -124,6 +136,7 @@ test_expect_success 'git add --dry-run --ignore-missing warn on sparse path' ' | |
setup_sparse_entry && | ||
rm sparse_entry && | ||
test_must_fail git add --dry-run --ignore-missing sparse_entry 2>stderr && | ||
test_sparse_entry_unstaged && | ||
test_cmp error_and_hint stderr && | ||
test_sparse_entry_unchanged | ||
' | ||
|
@@ -148,6 +161,7 @@ test_expect_success 'do not warn when pathspec matches dense entries' ' | |
test_expect_success 'add obeys advice.updateSparsePath' ' | ||
setup_sparse_entry && | ||
test_must_fail git -c advice.updateSparsePath=false add sparse_entry 2>stderr && | ||
test_sparse_entry_unstaged && | ||
test_cmp sparse_entry_error stderr | ||
|
||
' | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Glen Choo wrote (reply to this):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Junio C Hamano wrote (reply to this):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Junio C Hamano wrote (reply to this):