diff --git a/commands/command_lock.go b/commands/command_lock.go index c0bad36a..cdc455e8 100644 --- a/commands/command_lock.go +++ b/commands/command_lock.go @@ -60,7 +60,7 @@ func lockCommand(cmd *cobra.Command, args []string) { // Windows path of "\foo\bar" will be normalized to "foo/bar". // // If the root directory, working directory, or file cannot be -// determined/opened, an error will be returned. If the file in question is +// determined, an error will be returned. If the file in question is // actually a directory, an error will be returned. Otherwise, the cleaned path // will be returned. // @@ -96,15 +96,11 @@ func lockPath(file string) (string, error) { return "", fmt.Errorf("lfs: unable to canonicalize path %q", path) } - if stat, err := os.Stat(abs); err != nil { - return "", err - } else { - if stat.IsDir() { - return path, fmt.Errorf("lfs: cannot lock directory: %s", file) - } - - return filepath.ToSlash(path), nil + if stat, err := os.Stat(abs); err == nil && stat.IsDir() { + return path, fmt.Errorf("lfs: cannot lock directory: %s", file) } + + return filepath.ToSlash(path), nil } func init() { diff --git a/locking/locks.go b/locking/locks.go index f4662fc4..799838fc 100644 --- a/locking/locks.go +++ b/locking/locks.go @@ -125,9 +125,11 @@ func (c *Client) LockFile(path string) (Lock, error) { return Lock{}, errors.Wrap(err, "make lockpath absolute") } - // Ensure writeable on return - if err := tools.SetFileWriteFlag(abs, true); err != nil { - return Lock{}, err + // If the file exists, ensure that it's writeable on return + if tools.FileExists(abs) { + if err := tools.SetFileWriteFlag(abs, true); err != nil { + return Lock{}, errors.Wrap(err, "set file write flag") + } } return lock, nil diff --git a/t/t-lock.sh b/t/t-lock.sh index 08337c09..e1d8ef3a 100755 --- a/t/t-lock.sh +++ b/t/t-lock.sh @@ -100,6 +100,20 @@ begin_test "creating a lock (with output)" ) end_test +begin_test "locking a file that doesn't exist" +( + set -e + + reponame="lock_create_nonexistent" + setup_remote_repo_with_file "$reponame" "a_output.dat" + + git lfs lock "b_output.dat" | tee lock.log + grep "Locked b_output.dat" lock.log + id=$(grep -oh "\((.*)\)" lock.log | tr -d \(\)) + assert_server_lock "$reponame" "$id" +) +end_test + begin_test "locking a previously locked file" ( set -e diff --git a/t/t-unlock.sh b/t/t-unlock.sh index c5d65ea9..3e3131e7 100755 --- a/t/t-unlock.sh +++ b/t/t-unlock.sh @@ -140,11 +140,11 @@ begin_test "unlocking a file ignores readonly" ) end_test -begin_test "force unlocking lock with missing file" +begin_test "unlocking lock removed file" ( set -e - reponame="force-unlock-missing-file" + reponame="unlock-removed-file" setup_remote_repo_with_file "$reponame" "a.dat" git lfs lock --json "a.dat" | tee lock.log @@ -156,12 +156,23 @@ begin_test "force unlocking lock with missing file" rm *.log *.json # ensure clean git status git status - git lfs unlock "a.dat" 2>&1 | tee unlock.log - grep "Unable to determine path" unlock.log + git lfs unlock --force "a.dat" 2>&1 | tee unlock.log + refute_server_lock "$reponame" "$id" +) +end_test + +begin_test "unlocking nonexistent file" +( + set -e + + reponame="unlock-nonexistent-file" + setup_remote_repo_with_file "$reponame" "a.dat" + + git lfs lock --json "b.dat" | tee lock.log + id=$(assert_lock lock.log b.dat) assert_server_lock "$reponame" "$id" - rm unlock.log - git lfs unlock --force "a.dat" 2>&1 | tee unlock.log + git lfs unlock --force "b.dat" 2>&1 | tee unlock.log refute_server_lock "$reponame" "$id" ) end_test