commands: canonicalize paths properly on Windows

When we form a lock path, we take the working directory and resolve all
symlinks in it, and then append the name of the file specified on the
command line.  However, the working directory we get need not be
canonicalized for the system: it may contain lowercase drive paths (on
Windows) or components that differ in case or normalization from the
canonical form written on the file system.

We then made the path relative to the root of the repository by using
the strings module to pull of the prefix of the Git repository, which
will always be canonicalized.  If the working directory was
noncanonical, the paths would end up just concatenated together, leading
to failures down the line.  On Windows, this could lead to multiple
drive components, and hence a syntax error when trying to use the path.

Use the filepath.Rel function that's built into Go to help us make the
path relative in a way that is appropriate for the operating system.
Convert the path to slashes so that we store paths using slashes and
expose only slashes to the remote API.
This commit is contained in:
brian m. carlson 2018-09-21 14:47:08 +00:00
parent 7ae61d42c9
commit 95d1c1f737
No known key found for this signature in database
GPG Key ID: 2D0C9BC12F82B3A1

@ -5,7 +5,6 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/git-lfs/git-lfs/errors"
"github.com/git-lfs/git-lfs/git"
@ -86,8 +85,13 @@ func lockPath(file string) (string, error) {
}
abs := filepath.Join(wd, file)
path := strings.TrimPrefix(abs, repo)
path = strings.TrimPrefix(path, string(os.PathSeparator))
path, err := filepath.Rel(repo, abs)
if err != nil {
return "", err
}
path = filepath.ToSlash(path)
if stat, err := os.Stat(abs); err != nil {
return "", err
} else {