5346b02747
A common invocation of the 'git lfs migrate import' command is with '--include' and/or '--exclude' flag(s), which specify wildmatch pattern(s) for which paths to migrate and/or not migrate. This is useful for retroactively importing a set of files into Git LFS's care, or fixing up a file that should have been tracked by Git LFS but was accidentally committed as a large object instead. In the later case, it is often the reality that a user will run 'git lfs migrate --import' with an '--include' path that they believe will gather the file (and the file alone). This approach is brittle because it requires the user to infer not only the applicable pattern but the meaning of that pattern. It also requires the user to run more than one migration when fixing multiple types of files. The .gitattributes file(s) contained within a repository provide an authoritative source on what file(s) are considered by Git to be tracked in Git LFS. We can use this information to infer the correct patterns to ``fix up'' a broken repository. In the simplest case, if a repository's .gitattributes file contains the following: *.txt filter=lfs merge=lfs diff=lfs -text But a .txt file matched by that pattern is not parse-able as an LFS pointer, it will appear as unable to checkout. Running 'git lfs migrate import --fixup --everything' will correctly traverse history and find the affected .txt file, read it, create an object file for it, and store it as an LFS pointer in history. Thus, a user can run one command which will recognize arbitrarily complex problems where a file should be tracked by Git LFS, but isn't. Later, this feature could be combined with the new 'git lfs migrate export' functionality to also clean files _out_ of Git LFS to object files when they are not supposed to be tracked as Git LFS objects. |
||
---|---|---|
.. | ||
cmd | ||
git-lfs-test-server-api | ||
README.md | ||
test-askpass.sh | ||
test-batch-error-handling.sh | ||
test-batch-retries.sh | ||
test-batch-transfer.sh | ||
test-batch-unknown-oids.sh | ||
test-checkout.sh | ||
test-chunked-transfer-encoding.sh | ||
test-clean.sh | ||
test-clone-deprecated.sh | ||
test-clone.sh | ||
test-commit-delete-push.sh | ||
test-config.sh | ||
test-credentials-no-prompt.sh | ||
test-credentials.sh | ||
test-custom-transfers.sh | ||
test-duplicate-oids.sh | ||
test-env.sh | ||
test-expired.sh | ||
test-ext.sh | ||
test-extra-header.sh | ||
test-fetch-include.sh | ||
test-fetch-paths.sh | ||
test-fetch-recent.sh | ||
test-fetch-refspec.sh | ||
test-fetch.sh | ||
test-filter-branch.sh | ||
test-filter-process.sh | ||
test-fsck.sh | ||
test-happy-path.sh | ||
test-install-custom-hooks-path-unsupported.sh | ||
test-install-custom-hooks-path.sh | ||
test-install.sh | ||
test-lock.sh | ||
test-locks.sh | ||
test-logs.sh | ||
test-ls-files.sh | ||
test-malformed-pointers.sh | ||
test-mergetool.sh | ||
test-migrate-export.sh | ||
test-migrate-fixtures.sh | ||
test-migrate-fixup.sh | ||
test-migrate-import-no-rewrite.sh | ||
test-migrate-import.sh | ||
test-migrate-info.sh | ||
test-object-authenticated.sh | ||
test-pointer.sh | ||
test-post-checkout.sh | ||
test-post-commit.sh | ||
test-post-merge.sh | ||
test-pre-push.sh | ||
test-progress-meter.sh | ||
test-progress.sh | ||
test-prune-worktree.sh | ||
test-prune.sh | ||
test-pull.sh | ||
test-push-bad-dns.sh | ||
test-push-failures-local.sh | ||
test-push-failures-remote.sh | ||
test-push-file-with-branch-name.sh | ||
test-push.sh | ||
test-reference-clone.sh | ||
test-resume-http-range.sh | ||
test-resume-tus.sh | ||
test-smudge.sh | ||
test-ssh.sh | ||
test-status.sh | ||
test-submodule-lfsconfig.sh | ||
test-submodule.sh | ||
test-track-attrs.sh | ||
test-track-wildcards.sh | ||
test-track.sh | ||
test-uninstall.sh | ||
test-unlock.sh | ||
test-untrack.sh | ||
test-unusual-filenames.sh | ||
test-update.sh | ||
test-verify.sh | ||
test-version.sh | ||
test-worktree.sh | ||
test-zero-len-file.sh | ||
testenv.sh | ||
testhelpers.sh | ||
testlib.sh | ||
testutils.go |
Git LFS Tests
Git LFS uses two form of tests: unit tests for the internals written in Go, and
integration tests that run git
and git-lfs
in a real shell environment.
You can run them separately:
$ script/test # Tests the Go packages.
$ script/integration # Tests the commands in shell scripts.
CI servers should always run both:
$ script/cibuild
Internal Package Tests
The internal tests use Go's builtin testing package.
You can run individual tests by passing arguments to script/test
:
# test a specific Go package
$ script/test lfs
# pass other `go test` arguments
$ script/test lfs -run TestSuccessStatus -v
github.com/rubyist/tracerx
github.com/git-lfs/git-lfs/git
github.com/technoweenie/assert
=== RUN TestSuccessStatus
--- PASS: TestSuccessStatus (0.00 seconds)
PASS
ok _/Users/rick/git-lfs/git-lfs/lfs 0.011s
Integration Tests
Git LFS integration tests are shell scripts that test the git-lfs
command from
the shell. Each test file can be run individually, or in parallel through
script/integration
. Some tests will change the pwd
, so it's important that
they run in separate OS processes.
$ test/test-happy-path.sh
compile git-lfs for test/test-happy-path.sh
LFSTEST_URL=/Users/rick/git-lfs/git-lfs/test/remote/url LFSTEST_DIR=/Users/rick/git-lfs/git-lfs/test/remote lfstest-gitserver
test: happy path ... OK
- The integration tests should not rely on global system or git config.
- The tests should be cross platform (Linux, Mac, Windows).
- Tests should bootstrap an isolated, clean environment. See the Test Suite section.
- Successful test runs should have minimal output.
- Failing test runs should dump enough information to diagnose the bug. This includes stdout, stderr, any log files, and even the OS environment.
There are a few environment variables that you can set to change the test suite behavior:
GIT_LFS_TEST_DIR=path
- This sets the directory that is used as the current working directory of the tests. By default, this will be in your temp dir. It's recommended that this is set to a directory outside of any Git repository.GIT_LFS_TEST_MAXPROCS=N
- This tellsscript/integration
how many tests to run in parallel. Default: 4.KEEPTRASH=1
- This will leave the local repository data in atmp
directory and the remote repository data intest/remote
.SKIPCOMPILE=1
- This skips the Git LFS compilation step. Speeds up the tests when you're running the same test script multiple times without changing any Go code.
Also ensure that your noproxy
environment variable contains 127.0.0.1
host,
to allow git commands to reach the local Git server lfstest-gitserver
.
Test Suite
The testenv.sh
script includes some global variables used in tests. This
should be automatically included in every test/test-*.sh
script and
script/integration
.
testhelpers.sh
defines some shell functions. Most are only used in the test
scripts themselves. script/integration
uses the setup()
and shutdown()
functions.
testlib.sh
is a fork of a lightweight shell testing lib that is
used internally at GitHub. Only the test/test-*.sh
scripts should include
this.
Tests live in this ./test
directory, and must have a unique name like:
test-{name}.sh
. All tests should start with a basic template. See
test/test-happy-path.sh
for an example.
#!/usr/bin/env bash
. "test/testlib.sh"
begin_test "template"
(
set -e
echo "your tests go here"
)
end_test
The set -e
command will bail on the test at the first command that returns a
non zero exit status. Use simple shell commands like grep
as assertions.
The test suite has standard setup
and shutdown
functions that should be
run only once, before/after running the tests. The setup
and shutdown
functions are run by script/integration
and also by individual test scripts
when they are executed directly. Setup does the following:
- Resets temporary test directories.
- Compiles git-lfs with the latest code changes.
- Compiles Go files in
test/cmd
tobin
, and adds them the PATH. - Spins up a test Git and Git LFS server so the entire push/pull flow can be exercised.
- Sets up a git credential helper that always returns a set username and password.
The test Git server writes a test/remote/url
file when it's complete. This
file is how individual test scripts detect if script/integration
is being
run. You can fake this by manually spinning up the Git server using the
lfstest-gitserver
line that is output after Git LFS is compiled.
By default, temporary directories in tmp
and the test/remote
directory are
cleared after test runs. Send the "KEEPTRASH" if you want to keep these files
around for debugging failed tests.