Merge pull request #1213 from github/smudge-optional-fail

Allow smudge filter to return 0 on download failure
This commit is contained in:
Steve Streeting 2016-05-10 16:26:19 +01:00
commit e4e1c5db52
7 changed files with 162 additions and 2 deletions

@ -63,7 +63,7 @@ func smudgeCommand(cmd *cobra.Command, args []string) {
cfg := lfs.Config
download := lfs.FilenamePassesIncludeExcludeFilter(filename, cfg.FetchIncludePaths(), cfg.FetchExcludePaths())
if smudgeSkip || lfs.Config.GetenvBool("GIT_LFS_SKIP_SMUDGE", false) {
if smudgeSkip || cfg.GetenvBool("GIT_LFS_SKIP_SMUDGE", false) {
download = false
}
@ -77,7 +77,9 @@ func smudgeCommand(cmd *cobra.Command, args []string) {
// Download declined error is ok to skip if we weren't requesting download
if !(lfs.IsDownloadDeclinedError(err) && !download) {
LoggedError(err, "Error downloading object: %s (%s)", filename, ptr.Oid)
os.Exit(2)
if !cfg.SkipDownloadErrors() {
os.Exit(2)
}
}
}
}

@ -130,6 +130,20 @@ lfs option can be scoped inside the configuration for a remote.
If set to "basic" then credentials will be requested before making batch
requests to this url, otherwise a public request will initially be attempted.
* `lfs.skipdownloaderrors`
Causes Git LFS not to abort the smudge filter when a download error is
encountered, which allows actions such as checkout to work when you are unable
to download the LFS content. LFS files which could not download will contain
pointer content instead.
Note that this will result in git commands which call the smudge filter to
report success even in cases when LFS downloads fail, which may affect
scripts.
You can also set the environment variable GIT_LFS_SKIP_DOWNLOAD_ERRORS=1 to
get the same effect.
## SEE ALSO
git-config(1), git-lfs-install(1), gitattributes(5).

@ -333,6 +333,17 @@ func (c *Configuration) GitConfigInt(key string, def int) int {
return i
}
// GitConfigBool parses a git config value and returns true if defined as
// anything other than blank or "0"
func (c *Configuration) GitConfigBool(key string) bool {
s, _ := c.GitConfig(key)
if len(s) == 0 {
return false
}
return s != "0"
}
func (c *Configuration) GitConfig(key string) (string, bool) {
c.loadGitConfig()
value, ok := c.gitConfig[strings.ToLower(key)]
@ -395,6 +406,10 @@ func (c *Configuration) FetchPruneConfig() *FetchPruneConfig {
return c.fetchPruneConfig
}
func (c *Configuration) SkipDownloadErrors() bool {
return c.GetenvBool("GIT_LFS_SKIP_DOWNLOAD_ERRORS", false) || c.GitConfigBool("lfs.skipdownloaderrors")
}
func parseConfigBool(str string) (bool, error) {
switch strings.ToLower(str) {
case "true", "1", "on", "yes", "t":

@ -81,6 +81,7 @@ func Environ() []string {
fmt.Sprintf("TempDir=%s", TempDir),
fmt.Sprintf("ConcurrentTransfers=%d", Config.ConcurrentTransfers()),
fmt.Sprintf("BatchTransfer=%v", Config.BatchTransfer()),
fmt.Sprintf("SkipDownloadErrors=%v", Config.SkipDownloadErrors()),
)
for _, e := range osEnviron {

@ -31,6 +31,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -68,6 +69,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$endpoint" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -112,6 +114,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$endpoint" "$endpoint2" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -154,6 +157,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$endpoint" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -198,6 +202,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$endpoint" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -243,6 +248,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -290,6 +296,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=5
BatchTransfer=false
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -343,6 +350,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -390,6 +398,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -430,6 +439,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -481,6 +491,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -500,6 +511,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -530,6 +542,7 @@ LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
%s
%s
" "$(git lfs version)" "$(git version)" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
@ -557,3 +570,73 @@ Endpoint (other)=https://other-git-server.com/user/repo.git/info/lfs (auth=none)
contains_same_elements "$expected" "$(git lfs env | grep -e "Endpoint" -e "SSH=")"
)
end_test
begin_test "env with skip download errors"
(
set -e
reponame="env-with-skip-dl"
git init $reponame
cd $reponame
git config lfs.skipdownloaderrors 1
localgit=$(native_path "$TRASHDIR/$reponame")
localgitstore=$(native_path "$TRASHDIR/$reponame")
localmedia=$(native_path "$TRASHDIR/$reponame/lfs/objects")
tempdir=$(native_path "$TRASHDIR/$reponame/lfs/tmp")
envVars=$(printf "%s" "$(env | grep "^GIT")")
localwd=$(native_path "$TRASHDIR/$reponame")
localgit=$(native_path "$TRASHDIR/$reponame/.git")
localgitstore=$(native_path "$TRASHDIR/$reponame/.git")
localmedia=$(native_path "$TRASHDIR/$reponame/.git/lfs/objects")
tempdir=$(native_path "$TRASHDIR/$reponame/.git/lfs/tmp")
envVars=$(printf "%s" "$(env | grep "^GIT")")
expectedenabled=$(printf '%s
%s
LocalWorkingDir=%s
LocalGitDir=%s
LocalGitStorageDir=%s
LocalMediaDir=%s
LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=true
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
actual=$(git lfs env)
contains_same_elements "$expectedenabled" "$actual"
git config --unset lfs.skipdownloaderrors
# prove it's usually off
expecteddisabled=$(printf '%s
%s
LocalWorkingDir=%s
LocalGitDir=%s
LocalGitStorageDir=%s
LocalMediaDir=%s
LocalReferenceDir=
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=true
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
actual=$(git lfs env)
contains_same_elements "$expecteddisabled" "$actual"
# now enable via env var
actual=$(GIT_LFS_SKIP_DOWNLOAD_ERRORS=1 git lfs env)
contains_same_elements "$expectedenabled" "$actual"
)
end_test

@ -190,3 +190,46 @@ begin_test "smudge clone with include/exclude"
)
end_test
begin_test "smudge skip download failure"
(
set -e
reponame="$(basename "$0" ".sh")-skipdownloadfail"
setup_remote_repo "$reponame"
clone_repo "$reponame" skipdownloadfail
git lfs track "*.dat"
echo "smudge a" > a.dat
git add .gitattributes a.dat
git commit -m "add a.dat"
pointer="$(pointer fcf5015df7a9089a7aa7fe74139d4b8f7d62e52d5a34f9a87aeffc8e8c668254 9)"
# smudge works even though it hasn't been pushed, by reading from .git/lfs/objects
[ "smudge a" = "$(echo "$pointer" | git lfs smudge)" ]
git push origin master
# make it try to download but we're going to make it fail
rm -rf .git/lfs/objects
git remote set-url origin httpnope://nope.com/nope
# this should fail
set +e
echo "$pointer" | git lfs smudge a.dat; test ${PIPESTATUS[1]} -ne 0
set -e
git config lfs.skipdownloaderrors true
echo "$pointer" | git lfs smudge a.dat
# check content too
[ "$pointer" = "$(echo "$pointer" | git lfs smudge a.dat)" ]
# now try env var
git config --unset lfs.skipdownloaderrors
echo "$pointer" | GIT_LFS_SKIP_DOWNLOAD_ERRORS=1 git lfs smudge a.dat
)
end_test

@ -28,6 +28,7 @@ LocalReferenceDir=
TempDir=$(native_path_escaped "$TRASHDIR/$reponame/.git/lfs/tmp")
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
$(escape_path "$(env | grep "^GIT")")
%s
" "$(git lfs version)" "$(git version)" "$envInitConfig")
@ -50,6 +51,7 @@ LocalReferenceDir=
TempDir=$(native_path_escaped "$TRASHDIR/$reponame/.git/worktrees/$worktreename/lfs/tmp")
ConcurrentTransfers=3
BatchTransfer=true
SkipDownloadErrors=false
$(escape_path "$(env | grep "^GIT")")
%s
" "$(git lfs version)" "$(git version)" "$envInitConfig")