-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sparse-checkout: create builtin with 'list' subcommand
The sparse-checkout feature is mostly hidden to users, as its only documentation is supplementary information in the docs for 'git read-tree'. In addition, users need to know how to edit the .git/info/sparse-checkout file with the right patterns, then run the appropriate 'git read-tree -mu HEAD' command. Keeping the working directory in sync with the sparse-checkout file requires care. Begin an effort to make the sparse-checkout feature a porcelain feature by creating a new 'git sparse-checkout' builtin. This builtin will be the preferred mechanism for manipulating the sparse-checkout file and syncing the working directory. The documentation provided is adapted from the "git read-tree" documentation with a few edits for clarity in the new context. Extra sections are added to hint toward a future change to a more restricted pattern set. Helped-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
- Loading branch information
1 parent
d9f6f3b
commit 94c0956
Showing
9 changed files
with
226 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
git-sparse-checkout(1) | ||
====================== | ||
|
||
NAME | ||
---- | ||
git-sparse-checkout - Initialize and modify the sparse-checkout | ||
configuration, which reduces the checkout to a set of paths | ||
given by a list of atterns. | ||
|
||
|
||
SYNOPSIS | ||
-------- | ||
[verse] | ||
'git sparse-checkout <subcommand> [options]' | ||
|
||
|
||
DESCRIPTION | ||
----------- | ||
|
||
Initialize and modify the sparse-checkout configuration, which reduces | ||
the checkout to a set of paths given by a list of patterns. | ||
|
||
THIS COMMAND IS EXPERIMENTAL. ITS BEHAVIOR, AND THE BEHAVIOR OF OTHER | ||
COMMANDS IN THE PRESENCE OF SPARSE-CHECKOUTS, WILL LIKELY CHANGE IN | ||
THE FUTURE. | ||
|
||
|
||
COMMANDS | ||
-------- | ||
'list':: | ||
Provide a list of the contents in the sparse-checkout file. | ||
|
||
|
||
SPARSE CHECKOUT | ||
--------------- | ||
|
||
"Sparse checkout" allows populating the working directory sparsely. | ||
It uses the skip-worktree bit (see linkgit:git-update-index[1]) to tell | ||
Git whether a file in the working directory is worth looking at. If | ||
the skip-worktree bit is set, then the file is ignored in the working | ||
directory. Git will not populate the contents of those files, which | ||
makes a sparse checkout helpful when working in a repository with many | ||
files, but only a few are important to the current user. | ||
|
||
The `$GIT_DIR/info/sparse-checkout` file is used to define the | ||
skip-worktree reference bitmap. When Git updates the working | ||
directory, it updates the skip-worktree bits in the index based | ||
on this file. The files matching the patterns in the file will | ||
appear in the working directory, and the rest will not. | ||
|
||
## FULL PATTERN SET | ||
|
||
By default, the sparse-checkout file uses the same syntax as `.gitignore` | ||
files. | ||
|
||
While `$GIT_DIR/info/sparse-checkout` is usually used to specify what | ||
files are included, you can also specify what files are _not_ included, | ||
using negative patterns. For example, to remove the file `unwanted`: | ||
|
||
---------------- | ||
/* | ||
!unwanted | ||
---------------- | ||
|
||
Another tricky thing is fully repopulating the working directory when you | ||
no longer want sparse checkout. You cannot just disable "sparse | ||
checkout" because skip-worktree bits are still in the index and your working | ||
directory is still sparsely populated. You should re-populate the working | ||
directory with the `$GIT_DIR/info/sparse-checkout` file content as | ||
follows: | ||
|
||
---------------- | ||
/* | ||
---------------- | ||
|
||
Then you can disable sparse checkout. Sparse checkout support in 'git | ||
checkout' and similar commands is disabled by default. You need to | ||
set `core.sparseCheckout` to `true` in order to have sparse checkout | ||
support. | ||
|
||
SEE ALSO | ||
-------- | ||
|
||
linkgit:git-read-tree[1] | ||
linkgit:gitignore[5] | ||
|
||
GIT | ||
--- | ||
Part of the linkgit:git[1] suite |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include "builtin.h" | ||
#include "config.h" | ||
#include "dir.h" | ||
#include "parse-options.h" | ||
#include "pathspec.h" | ||
#include "repository.h" | ||
#include "run-command.h" | ||
#include "strbuf.h" | ||
|
||
static char const * const builtin_sparse_checkout_usage[] = { | ||
N_("git sparse-checkout list"), | ||
NULL | ||
}; | ||
|
||
static char *get_sparse_checkout_filename(void) | ||
{ | ||
return git_pathdup("info/sparse-checkout"); | ||
} | ||
|
||
static void write_patterns_to_file(FILE *fp, struct pattern_list *pl) | ||
{ | ||
int i; | ||
|
||
for (i = 0; i < pl->nr; i++) { | ||
struct path_pattern *p = pl->patterns[i]; | ||
|
||
if (p->flags & PATTERN_FLAG_NEGATIVE) | ||
fprintf(fp, "!"); | ||
|
||
fprintf(fp, "%s", p->pattern); | ||
|
||
if (p->flags & PATTERN_FLAG_MUSTBEDIR) | ||
fprintf(fp, "/"); | ||
|
||
fprintf(fp, "\n"); | ||
} | ||
} | ||
|
||
static int sparse_checkout_list(int argc, const char **argv) | ||
{ | ||
struct pattern_list pl; | ||
char *sparse_filename; | ||
int res; | ||
|
||
memset(&pl, 0, sizeof(pl)); | ||
|
||
sparse_filename = get_sparse_checkout_filename(); | ||
res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL); | ||
free(sparse_filename); | ||
|
||
if (res < 0) { | ||
warning(_("this worktree is not sparse (sparse-checkout file may not exist)")); | ||
return 0; | ||
} | ||
|
||
write_patterns_to_file(stdout, &pl); | ||
clear_pattern_list(&pl); | ||
|
||
return 0; | ||
} | ||
|
||
int cmd_sparse_checkout(int argc, const char **argv, const char *prefix) | ||
{ | ||
static struct option builtin_sparse_checkout_options[] = { | ||
OPT_END(), | ||
}; | ||
|
||
if (argc == 2 && !strcmp(argv[1], "-h")) | ||
usage_with_options(builtin_sparse_checkout_usage, | ||
builtin_sparse_checkout_options); | ||
|
||
argc = parse_options(argc, argv, prefix, | ||
builtin_sparse_checkout_options, | ||
builtin_sparse_checkout_usage, | ||
PARSE_OPT_STOP_AT_NON_OPTION); | ||
|
||
git_config(git_default_config, NULL); | ||
|
||
if (argc > 0) { | ||
if (!strcmp(argv[0], "list")) | ||
return sparse_checkout_list(argc, argv); | ||
} | ||
|
||
usage_with_options(builtin_sparse_checkout_usage, | ||
builtin_sparse_checkout_options); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/bin/sh | ||
|
||
test_description='sparse checkout builtin tests' | ||
|
||
. ./test-lib.sh | ||
|
||
test_expect_success 'setup' ' | ||
git init repo && | ||
( | ||
cd repo && | ||
echo "initial" >a && | ||
mkdir folder1 folder2 deep && | ||
mkdir deep/deeper1 deep/deeper2 && | ||
mkdir deep/deeper1/deepest && | ||
cp a folder1 && | ||
cp a folder2 && | ||
cp a deep && | ||
cp a deep/deeper1 && | ||
cp a deep/deeper2 && | ||
cp a deep/deeper1/deepest && | ||
git add . && | ||
git commit -m "initial commit" | ||
) | ||
' | ||
|
||
test_expect_success 'git sparse-checkout list (empty)' ' | ||
git -C repo sparse-checkout list >list 2>err && | ||
test_must_be_empty list && | ||
test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err | ||
' | ||
|
||
test_expect_success 'git sparse-checkout list (populated)' ' | ||
test_when_finished rm -f repo/.git/info/sparse-checkout && | ||
cat >repo/.git/info/sparse-checkout <<-EOF && | ||
/folder1/* | ||
/deep/ | ||
**/a | ||
!*bin* | ||
EOF | ||
cp repo/.git/info/sparse-checkout expect && | ||
git -C repo sparse-checkout list >list && | ||
test_cmp expect list | ||
' | ||
|
||
test_done |