Tool to create a git revision snapshot for an existing repository clone.
NAME:
git-snap - Create a git revision snapshot for an existing repository clone. Symbolic link files will be omitted.
USAGE:
git-snap --src value --rev value --out value [optional flags]
OPTIONS:
--src value, -s value path to existing git clone as source directory, may contain no more than .git directory, current git state doesn't affect the command
--rev value, -r value commit-ish Revision
--index value, -x value Create index file listing file paths and their blob IDs
--index-only, --xo Create index only - Don't checkout any files (default: false)
--out value, -o value output directory. will be created if does not exist
--include value, -i value patterns of file paths to include, comma delimited, may contain any glob pattern
--exclude value, -e value patterns of file paths to exclude, comma delimited, may contain any glob pattern
--hard-exclude value patterns of file paths to exclude, comma delimited, may contain any glob pattern; unlike --exclude, matching files are excluded even when they match include patterns. A pattern ending in /** (e.g. 'Specs/**') additionally prunes the matched directory's subtree from the tree walk, greatly speeding up snapshots of huge, directory-heavy repositories
--verbose, --vv verbose logging (default: false)
--text-only include only text files (default: false)
--hash-markers create also hint files mirroring the hash of original files at <path>.hash (default: false)
--ignore-case ignore case when checking path against inclusion patterns (default: false)
--max-size value maximal file size, in MB (default: 6)
--no-double-check disable files discrepancy double check (default: false)
--include-noise-dirs don't filter out noisy directory names in paths (bin, node_modules etc) (default: false)
--paths-file-location value, --pl value a location of a text file with all the paths to snap (one path per line)
--help, -h show help (default: false)
--version, -v print the version (default: false)
EXIT CODES:
0 Success
101 Some file name is too long
201 Clone path is invalid (fs-wise)
202 Clone path is invalid (git-wise)
203 Output path is invalid
204 Short sha is not supported
205 Provided revision could not be found
206 Double check for files discrepancy failed
207 HEAD ref not found
1 Any other error
git-snap --src /var/shared/git/dc-heacth --rev master --out /tmp/dc-heacth-master
git-snap --src /var/shared/git/dc-heacth --rev master --out /tmp/dc-heacth-master --include "**/*.java" --exclude "**/test/**"
git-snap --src /var/shared/git/dc-heacth --rev master --out /tmp/dc-heacth-master --include "**/*.java,pom.xml"
git-snap --src /var/shared/git/dc-heacth --rev master --out /tmp/dc-heacth-master --include "**/*.js,**/*.ts" --hard-exclude "**/node_modules/**"
# Skip a huge subtree entirely (not even walked) when building an index:
git-snap --src /var/shared/git/specs --rev master --out /tmp/specs --index-only --index /tmp/specs/index.tsv --hard-exclude "Specs/**"A --hard-exclude pattern ending in /** (e.g. Specs/**, **/node_modules/**) prunes the matched directory from the tree walk — its subtree is never decoded. This is the main speed-up on huge, directory-heavy repositories, and it applies to --index-only runs as well (which otherwise still walk the whole tree).
- Pruning applies only to
--hard-exclude, never to--exclude. Hard-exclude drops matching files unconditionally (even ones matched by--include), so skipping the subtree can never omit a file that should have been kept; a soft--excludeyields to--include, so it is not safe to prune. - Only
<prefix>/**patterns prune. Patterns that target specific files (e.g.Specs/*.json,Specs/*/*) still filter normally but do not prune, so their non-matching siblings are always walked. - A pruned directory's descendants are omitted from the
--indexoutput; the directory entry itself still appears once.
curl -s https://raw.githubusercontent.com/apiiro/git-snap/main/install.sh | sudo bash
# or for a specific version:
curl -s https://raw.githubusercontent.com/apiiro/git-snap/main/install.sh | sudo bash -s 1.4If that doesn't work, try:
curl -s https://raw.githubusercontent.com/apiiro/git-snap/main/install.sh -o install.sh
sudo bash install.shFor Apple M1 CPUs: If you're getting the following error:
Installing...
Archive: gitsnap.zip
inflating: gitsnap-1.6.8-osx
bash: line 29: /usr/local/bin/git-snap: Bad CPU type in executableTry installing Rossetta by running:
softwareupdate --install-rosettathen run with either:
git-snap -h
git snap -h# run tests:
make test
# run benchmark
make benchmark
# build binaries and run whole ci flow
makeRunning on 16 cores (relevant only for gitsnap)
+----------------------+-----------------------+------------+-----------------+
| Repository | Action | Time (sec) | Performance |
+----------------------+-----------------------+------------+-----------------+
| EVO-Exchange-BE-2019 | git-archive | 0.05 | baseline |
| EVO-Exchange-BE-2019 | git-archive + tar -x | 0.13 | x2.6 |
| EVO-Exchange-BE-2019 | git-worktree-checkout | 0.096 | x1.9 |
| EVO-Exchange-BE-2019 | gitsnap | 0.075 | x1.5 |
| EVO-Exchange-BE-2019 | gitsnap (**/*.java) | 0.032 | x0.64 (faster!) |
| elasticsearch | git-archive | 1.86 | baseline |
| elasticsearch | git-archive + tar -x | 7.92 | x4.25 |
| elasticsearch | git-worktree-checkout | 6.71 | x3.6 |
| elasticsearch | gitsnap | 6.31 | x3.4 |
| elasticsearch | gitsnap (**/*.java) | 5.3 | x2.85 |
+----------------------+-----------------------+------------+-----------------+
Legend:
git-archive -->
git archive <commitish> -o <output>
git-archive + tar -x -->
git archive <commitish> | tar -x -C <output>
git-worktree-checkout -->
git --work-tree <output> checkout <commitish> -f -q -- ./