gitindex: set fetch refspecs after cloning
A recent Git release broke the capability to set refspecs on the
command-line. This was stopped in 47ff3037, and as a result fetches
now update FETCH_HEAD rather than the required refs.
Instead, set the refspecs to refs/heads/* => refs/heads/* after the
successful clone.
Fixes #106
Change-Id: I1907094aecd81e35d2081218ccbe8d005caf4863
diff --git a/gitindex/clone.go b/gitindex/clone.go
index 9851e88..7ca99a1 100644
--- a/gitindex/clone.go
+++ b/gitindex/clone.go
@@ -21,6 +21,9 @@
"os/exec"
"path/filepath"
"sort"
+
+ git "gopkg.in/src-d/go-git.v4"
+ "gopkg.in/src-d/go-git.v4/config"
)
// CloneRepo clones one repository, adding the given config
@@ -64,5 +67,30 @@
return "", err
}
+ if err := setFetch(repoDest, "origin", "+refs/heads/*:refs/heads/*"); err != nil {
+ log.Printf("addFetch: %v", err)
+ }
return repoDest, nil
}
+
+func setFetch(repoDir, remote, refspec string) error {
+ repo, err := git.PlainOpen(repoDir)
+ if err != nil {
+ return err
+ }
+
+ cfg, err := repo.Config()
+ if err != nil {
+ return err
+ }
+
+ rm := cfg.Remotes[remote]
+ if rm != nil {
+ rm.Fetch = []config.RefSpec{config.RefSpec(refspec)}
+ }
+ if err := repo.Storer.SetConfig(cfg); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/gitindex/clone_test.go b/gitindex/clone_test.go
new file mode 100644
index 0000000..2d4e594
--- /dev/null
+++ b/gitindex/clone_test.go
@@ -0,0 +1,63 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package gitindex
+
+import (
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "testing"
+
+ git "gopkg.in/src-d/go-git.v4"
+)
+
+func TestSetRemote(t *testing.T) {
+ dir, err := ioutil.TempDir("", "")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(dir)
+ script := `mkdir orig
+cd orig
+git init
+cd ..
+git clone orig/.git clone.git
+`
+
+ cmd := exec.Command("/bin/sh", "-euxc", script)
+ cmd.Dir = dir
+
+ if out, err := cmd.CombinedOutput(); err != nil {
+ t.Fatalf("execution error: %v, output %s", err, out)
+ }
+
+ r := dir + "/clone.git"
+ if err := setFetch(r, "origin", "+refs/heads/*:refs/heads/*"); err != nil {
+ t.Fatalf("addFetch: %v", err)
+ }
+
+ repo, err := git.PlainOpen(r)
+ if err != nil {
+ t.Fatal("PlainOpen", err)
+ }
+
+ rm, err := repo.Remote("origin")
+ if err != nil {
+ t.Fatal("Remote", err)
+ }
+ if got, want := rm.Config().Fetch[0].String(), "+refs/heads/*:refs/heads/*"; got != want {
+ t.Fatalf("got %q want %q", got, want)
+ }
+}