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)
+	}
+}