Allow literal local paths as remotes
Currently, we allow literal paths as named remotes, but not specified as literal remotes on the command line, since they fail to validate as URLs. To make this experience better, let's rewrite the local paths as file URLs using the existing endpoint code if the validation fails and then try validation again. We check specifically that users can use "." as a remote since that's a common idiom to update branches.
This commit is contained in:
parent
781f595eec
commit
b2d3f1d787
@ -268,7 +268,10 @@ func (c *Configuration) PushRemote() string {
|
||||
|
||||
func (c *Configuration) SetValidRemote(name string) error {
|
||||
if err := git.ValidateRemote(name); err != nil {
|
||||
return err
|
||||
name := git.RewriteLocalPathAsURL(name)
|
||||
if err := git.ValidateRemote(name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.SetRemote(name)
|
||||
return nil
|
||||
@ -276,7 +279,10 @@ func (c *Configuration) SetValidRemote(name string) error {
|
||||
|
||||
func (c *Configuration) SetValidPushRemote(name string) error {
|
||||
if err := git.ValidateRemote(name); err != nil {
|
||||
return err
|
||||
name := git.RewriteLocalPathAsURL(name)
|
||||
if err := git.ValidateRemote(name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.SetPushRemote(name)
|
||||
return nil
|
||||
|
28
git/git.go
28
git/git.go
@ -503,6 +503,34 @@ func ValidateRemoteURL(remote string) error {
|
||||
}
|
||||
}
|
||||
|
||||
func RewriteLocalPathAsURL(path string) string {
|
||||
var slash string
|
||||
if abs, err := filepath.Abs(path); err == nil {
|
||||
// Required for Windows paths to work.
|
||||
if !strings.HasPrefix(abs, "/") {
|
||||
slash = "/"
|
||||
}
|
||||
path = abs
|
||||
}
|
||||
|
||||
var gitpath string
|
||||
if filepath.Base(path) == ".git" {
|
||||
gitpath = path
|
||||
path = filepath.Dir(path)
|
||||
} else {
|
||||
gitpath = filepath.Join(path, ".git")
|
||||
}
|
||||
|
||||
if _, err := os.Stat(gitpath); err == nil {
|
||||
path = gitpath
|
||||
} else if _, err := os.Stat(path); err != nil {
|
||||
// Not a local path. We check down here because we perform
|
||||
// canonicalization by stripping off the .git above.
|
||||
return path
|
||||
}
|
||||
return fmt.Sprintf("file://%s%s", slash, filepath.ToSlash(path))
|
||||
}
|
||||
|
||||
func UpdateIndexFromStdin() *subprocess.Cmd {
|
||||
return git("update-index", "-q", "--refresh", "--stdin")
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package lfshttp
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/git-lfs/git-lfs/git"
|
||||
)
|
||||
|
||||
const UrlUnknown = "<unknown>"
|
||||
@ -109,26 +109,7 @@ func EndpointFromHttpUrl(u *url.URL) Endpoint {
|
||||
}
|
||||
|
||||
func EndpointFromLocalPath(path string) Endpoint {
|
||||
var slash string
|
||||
if abs, err := filepath.Abs(path); err == nil {
|
||||
// Required for Windows paths to work.
|
||||
if !strings.HasPrefix(abs, "/") {
|
||||
slash = "/"
|
||||
}
|
||||
path = abs
|
||||
}
|
||||
|
||||
var gitpath string
|
||||
if filepath.Base(path) == ".git" {
|
||||
gitpath = path
|
||||
path = filepath.Dir(path)
|
||||
} else {
|
||||
gitpath = filepath.Join(path, ".git")
|
||||
}
|
||||
if _, err := os.Stat(gitpath); err == nil {
|
||||
path = gitpath
|
||||
}
|
||||
return Endpoint{Url: fmt.Sprintf("file://%s%s", slash, filepath.ToSlash(path))}
|
||||
return Endpoint{Url: git.RewriteLocalPathAsURL(path)}
|
||||
}
|
||||
|
||||
// Construct a new endpoint from a file URL
|
||||
|
@ -1275,3 +1275,30 @@ begin_test "pre-push with force-pushed ref"
|
||||
git push origin +tagname
|
||||
)
|
||||
end_test
|
||||
|
||||
begin_test "pre-push with local path"
|
||||
(
|
||||
set -e
|
||||
reponame="pre-push-local-path"
|
||||
setup_remote_repo "$reponame"
|
||||
clone_repo "$reponame" "$reponame-2"
|
||||
cd ..
|
||||
clone_repo "$reponame" "$reponame"
|
||||
|
||||
git lfs track "*.dat"
|
||||
echo "hi" > a.dat
|
||||
git add .gitattributes a.dat
|
||||
git commit -m "add a.dat"
|
||||
|
||||
# Push to the other repo.
|
||||
git push "../$reponame-2" master:foo
|
||||
|
||||
# Push to . to make sure that works.
|
||||
git push "." master:foo
|
||||
|
||||
git lfs fsck
|
||||
cd "../$reponame-2"
|
||||
git checkout foo
|
||||
git lfs fsck
|
||||
)
|
||||
end_test
|
||||
|
Loading…
Reference in New Issue
Block a user