When updating projects, set origin to the remote in the manifest.
Currently, changing the remote in the manifest after a project has been
created has no effect. This CL will set the origin to to the manifest
remote. It will error if the project does not have a remote listed in
the manifest.
It also renames RepoName to RemoteUrl, to better match its
functionality.
Change-Id: Ia114b14eb2c10861205924aa02dd2b088cec15fb
diff --git a/gitutil/git.go b/gitutil/git.go
index c97b418..d41b9a6 100644
--- a/gitutil/git.go
+++ b/gitutil/git.go
@@ -506,23 +506,24 @@
return g.run(args...)
}
-// RemoveUntrackedFiles removes untracked files and directories.
-func (g *Git) RemoveUntrackedFiles() error {
- return g.run("clean", "-d", "-f")
-}
-
-// RepoName gets the name of the current repository.
-func (g *Git) RepoName() (string, error) {
- out, err := g.runOutputWithOpts(g.disableDryRun(), "config", "--get", "remote.origin.url")
+// RemoteUrl gets the url of the remote with the given name.
+func (g *Git) RemoteUrl(name string) (string, error) {
+ configKey := fmt.Sprintf("remote.%s.url", name)
+ out, err := g.runOutputWithOpts(g.disableDryRun(), "config", "--get", configKey)
if err != nil {
return "", err
}
if got, want := len(out), 1; got != want {
- return "", fmt.Errorf("unexpected length of %v: got %v, want %v", out, got, want)
+ return "", fmt.Errorf("RemoteUrl: unexpected length of remotes %v: got %v, want %v", out, got, want)
}
return out[0], nil
}
+// RemoveUntrackedFiles removes untracked files and directories.
+func (g *Git) RemoveUntrackedFiles() error {
+ return g.run("clean", "-d", "-f")
+}
+
// Reset resets the current branch to the target, discarding any
// uncommitted changes.
func (g *Git) Reset(target string, opts ...ResetOpt) error {
@@ -538,6 +539,11 @@
return g.run(args...)
}
+// SetRemoteUrl sets the url of the remote with given name to the given url.
+func (g *Git) SetRemoteUrl(name, url string) error {
+ return g.run("remote", "set-url", name, url)
+}
+
// Stash attempts to stash any unsaved changes. It returns true if
// anything was actually stashed, otherwise false. An error is
// returned if the stash command fails.
diff --git a/project/project.go b/project/project.go
index 8af2d12..ade8eb8 100644
--- a/project/project.go
+++ b/project/project.go
@@ -447,7 +447,7 @@
return nil, err
}
- // Fetch the latest from remote.
+ // Fetch the latest from origin.
if err := ctx.Git().FetchRefspec("origin", updateOp.project.RemoteBranch); err != nil {
return nil, err
}
@@ -485,6 +485,20 @@
return p, t, e
}
+// getManifestRemote returns the remote url of the origin from the manifest
+// repo.
+// TODO(nlacasse,toddw): Once the manifest project is specified in the
+// manifest, we should get the remote directly from the manifest, and not from
+// the filesystem.
+func getManifestRemote(ctx *tool.Context, manifestPath string) (string, error) {
+ var remote string
+ return remote, ctx.NewSeq().Pushd(manifestPath).Call(
+ func() (e error) {
+ remote, e = ctx.Git().RemoteUrl("origin")
+ return
+ }, "get manifest origin").Done()
+}
+
// readManifest implements the ReadManifest logic and provides an
// optional flag that can be used to fetch the latest manifest updates
// from the manifest repository.
@@ -496,9 +510,14 @@
if err != nil {
return nil, nil, nil, nil, err
}
+ manifestRemote, err := getManifestRemote(ctx, manifestPath)
+ if err != nil {
+ return nil, nil, nil, nil, err
+ }
project := Project{
Path: manifestPath,
Protocol: "git",
+ Remote: manifestRemote,
Revision: "HEAD",
RemoteBranch: "master",
}
@@ -940,6 +959,12 @@
fn := func() error {
switch project.Protocol {
case "git":
+ if project.Remote == "" {
+ return fmt.Errorf("project %v does not have a remote", project.Name)
+ }
+ if err := ctx.Git().SetRemoteUrl("origin", project.Remote); err != nil {
+ return err
+ }
if err := ctx.Git().Fetch("origin"); err != nil {
return err
}