Skip to content

Commit fb86bbb

Browse files
author
Bryan C. Mills
committed
[release-branch.go1.13] cmd/go/internal/modfetch/codehost: work around an apparent bug in 'git fetch --unshallow'
When 'git fetch' is passed the '--unshallow' flag, it assumes that the local and remote refs are equal.¹ However, we were fetching an expanded set of refs explicitly in the same command, violating that assumption. Now we first expand the set of refs, then unshallow the repo in a separate fetch. Empirically, this seems to work, whereas the opposite order does not. ¹https://github.com/git/git/blob/4c86140027f4a0d2caaa3ab4bd8bfc5ce3c11c8a/transport.c#L1303-L1309 Updates #34266 Fixes #34477 Change-Id: Ie97eb7c1223f944003a1e31d0ec9e69aad0efc0d Reviewed-on: https://go-review.googlesource.com/c/go/+/196961 Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Jay Conrod <[email protected]> (cherry picked from commit 1804bba) Reviewed-on: https://go-review.googlesource.com/c/go/+/197060
1 parent 94227d2 commit fb86bbb

File tree

2 files changed

+35
-53
lines changed

2 files changed

+35
-53
lines changed

src/cmd/go/internal/modfetch/codehost/git.go

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -241,13 +241,6 @@ func (r *gitRepo) findRef(hash string) (ref string, ok bool) {
241241
return "", false
242242
}
243243

244-
func unshallow(gitDir string) []string {
245-
if _, err := os.Stat(filepath.Join(gitDir, "shallow")); err == nil {
246-
return []string{"--unshallow"}
247-
}
248-
return []string{}
249-
}
250-
251244
// minHashDigits is the minimum number of digits to require
252245
// before accepting a hex digit sequence as potentially identifying
253246
// a specific commit in a git repo. (Of course, users can always
@@ -397,29 +390,27 @@ func (r *gitRepo) stat(rev string) (*RevInfo, error) {
397390
// fetchRefsLocked requires that r.mu remain locked for the duration of the call.
398391
func (r *gitRepo) fetchRefsLocked() error {
399392
if r.fetchLevel < fetchAll {
400-
if err := r.fetchUnshallow("refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"); err != nil {
393+
// NOTE: To work around a bug affecting Git clients up to at least 2.23.0
394+
// (2019-08-16), we must first expand the set of local refs, and only then
395+
// unshallow the repository as a separate fetch operation. (See
396+
// golang.org/issue/34266 and
397+
// https://github.com/git/git/blob/4c86140027f4a0d2caaa3ab4bd8bfc5ce3c11c8a/transport.c#L1303-L1309.)
398+
399+
if _, err := Run(r.dir, "git", "fetch", "-f", r.remote, "refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"); err != nil {
401400
return err
402401
}
402+
403+
if _, err := os.Stat(filepath.Join(r.dir, "shallow")); err == nil {
404+
if _, err := Run(r.dir, "git", "fetch", "--unshallow", "-f", r.remote); err != nil {
405+
return err
406+
}
407+
}
408+
403409
r.fetchLevel = fetchAll
404410
}
405411
return nil
406412
}
407413

408-
func (r *gitRepo) fetchUnshallow(refSpecs ...string) error {
409-
// To work around a protocol version 2 bug that breaks --unshallow,
410-
// add -c protocol.version=0.
411-
// TODO(rsc): The bug is believed to be server-side, meaning only
412-
// on Google's Git servers. Once the servers are fixed, drop the
413-
// protocol.version=0. See Google-internal bug b/110495752.
414-
var protoFlag []string
415-
unshallowFlag := unshallow(r.dir)
416-
if len(unshallowFlag) > 0 {
417-
protoFlag = []string{"-c", "protocol.version=0"}
418-
}
419-
_, err := Run(r.dir, "git", protoFlag, "fetch", unshallowFlag, "-f", r.remote, refSpecs)
420-
return err
421-
}
422-
423414
// statLocal returns a RevInfo describing rev in the local git repository.
424415
// It uses version as info.Version.
425416
func (r *gitRepo) statLocal(version, rev string) (*RevInfo, error) {
@@ -539,39 +530,10 @@ func (r *gitRepo) ReadFileRevs(revs []string, file string, maxSize int64) (map[s
539530
}
540531
defer unlock()
541532

542-
var refs []string
543-
var protoFlag []string
544-
var unshallowFlag []string
545-
for _, tag := range redo {
546-
refs = append(refs, "refs/tags/"+tag+":refs/tags/"+tag)
547-
}
548-
if len(refs) > 1 {
549-
unshallowFlag = unshallow(r.dir)
550-
if len(unshallowFlag) > 0 {
551-
// To work around a protocol version 2 bug that breaks --unshallow,
552-
// add -c protocol.version=0.
553-
// TODO(rsc): The bug is believed to be server-side, meaning only
554-
// on Google's Git servers. Once the servers are fixed, drop the
555-
// protocol.version=0. See Google-internal bug b/110495752.
556-
protoFlag = []string{"-c", "protocol.version=0"}
557-
}
558-
}
559-
if _, err := Run(r.dir, "git", protoFlag, "fetch", unshallowFlag, "-f", r.remote, refs); err != nil {
533+
if err := r.fetchRefsLocked(); err != nil {
560534
return nil, err
561535
}
562536

563-
// TODO(bcmills): after the 1.11 freeze, replace the block above with:
564-
// if r.fetchLevel <= fetchSome {
565-
// r.fetchLevel = fetchSome
566-
// var refs []string
567-
// for _, tag := range redo {
568-
// refs = append(refs, "refs/tags/"+tag+":refs/tags/"+tag)
569-
// }
570-
// if _, err := Run(r.dir, "git", "fetch", "--update-shallow", "-f", r.remote, refs); err != nil {
571-
// return nil, err
572-
// }
573-
// }
574-
575537
if _, err := r.readFileRevs(redo, file, files); err != nil {
576538
return nil, err
577539
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Regression test for golang.org/issue/34092: with an empty module cache,
2+
# 'GOPROXY=direct go get golang.org/x/tools/gopls@master' did not correctly
3+
# resolve the pseudo-version for its dependency on golang.org/x/tools.
4+
5+
[short] skip
6+
[!net] skip
7+
[!exec:git] skip
8+
9+
env GO111MODULE=on
10+
env GOPROXY=direct
11+
env GOSUMDB=off
12+
13+
go list -m cloud.google.com/go@master
14+
! stdout 'v0.0.0-'
15+
16+
-- go.mod --
17+
module example.com
18+
19+
go 1.14
20+
-- go.sum --

0 commit comments

Comments
 (0)