mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Fix shallow git clone in docker-build
If the HEAD request fails, use a GET request to properly test if git server is smart-http. Signed-off-by: Andrew He <he.andrew.mail@gmail.com>
This commit is contained in:
parent
4ac4c8ef4b
commit
85afbbc2ed
1 changed files with 33 additions and 10 deletions
|
@ -1,7 +1,6 @@
|
||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -98,22 +97,46 @@ func getRefAndSubdir(fragment string) (ref string, subdir string) {
|
||||||
|
|
||||||
func fetchArgs(remoteURL string, ref string) []string {
|
func fetchArgs(remoteURL string, ref string) []string {
|
||||||
args := []string{"fetch", "--recurse-submodules=yes"}
|
args := []string{"fetch", "--recurse-submodules=yes"}
|
||||||
shallow := true
|
|
||||||
|
|
||||||
if urlutil.IsURL(remoteURL) {
|
if supportsShallowClone(remoteURL) {
|
||||||
res, err := http.Head(fmt.Sprintf("%s/info/refs?service=git-upload-pack", remoteURL))
|
|
||||||
if err != nil || res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" {
|
|
||||||
shallow = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if shallow {
|
|
||||||
args = append(args, "--depth", "1")
|
args = append(args, "--depth", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(args, "origin", ref)
|
return append(args, "origin", ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a given git URL supports a shallow git clone,
|
||||||
|
// i.e. it is a non-HTTP server or a smart HTTP server.
|
||||||
|
func supportsShallowClone(remoteURL string) bool {
|
||||||
|
if urlutil.IsURL(remoteURL) {
|
||||||
|
// Check if the HTTP server is smart
|
||||||
|
|
||||||
|
// Smart servers must correctly respond to a query for the git-upload-pack service
|
||||||
|
serviceURL := remoteURL + "/info/refs?service=git-upload-pack"
|
||||||
|
|
||||||
|
// Try a HEAD request and fallback to a Get request on error
|
||||||
|
res, err := http.Head(serviceURL)
|
||||||
|
if err != nil || res.StatusCode != http.StatusOK {
|
||||||
|
res, err = http.Get(serviceURL)
|
||||||
|
if err == nil {
|
||||||
|
res.Body.Close()
|
||||||
|
}
|
||||||
|
if err != nil || res.StatusCode != http.StatusOK {
|
||||||
|
// request failed
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" {
|
||||||
|
// Fallback, not a smart server
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// Non-HTTP protocols always support shallow clones
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func checkoutGit(root, ref, subdir string) (string, error) {
|
func checkoutGit(root, ref, subdir string) (string, error) {
|
||||||
// Try checking out by ref name first. This will work on branches and sets
|
// Try checking out by ref name first. This will work on branches and sets
|
||||||
// .git/HEAD to the current branch name
|
// .git/HEAD to the current branch name
|
||||||
|
|
Loading…
Reference in a new issue