From 4d45257405d06d3ae801644d7d57a068973717ef Mon Sep 17 00:00:00 2001 From: Dominik Schulz Date: Sat, 3 Mar 2018 12:50:09 +0100 Subject: [PATCH] Lookup correct remote for current branch Fixes #691 --- backend/sync/git/cli/config.go | 36 +++++++++++++++++++++++++++++++--- backend/sync/git/cli/git.go | 36 ++++++++++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/backend/sync/git/cli/config.go b/backend/sync/git/cli/config.go index a5678565d4..cfec86d085 100644 --- a/backend/sync/git/cli/config.go +++ b/backend/sync/git/cli/config.go @@ -1,7 +1,6 @@ package cli import ( - "bytes" "context" "fmt" "io/ioutil" @@ -80,17 +79,48 @@ func (g *Git) ConfigGet(ctx context.Context, key string) (string, error) { return "", store.ErrGitNotInit } - buf := &bytes.Buffer{} + buf := &strings.Builder{} cmd := exec.CommandContext(ctx, "git", "config", "--get", key) cmd.Dir = g.path cmd.Stdout = buf cmd.Stderr = os.Stderr - out.Debug(ctx, "store.gitConfigValue: %s %+v", cmd.Path, cmd.Args) + out.Debug(ctx, "store.gitConfigGet: %s %+v", cmd.Path, cmd.Args) if err := cmd.Run(); err != nil { return "", err } return strings.TrimSpace(buf.String()), nil } + +// ConfigList returns all git config settings +func (g *Git) ConfigList(ctx context.Context) (map[string]string, error) { + if !g.IsInitialized() { + return nil, store.ErrGitNotInit + } + + buf := &strings.Builder{} + + cmd := exec.CommandContext(ctx, "git", "config", "--list") + cmd.Dir = g.path + cmd.Stdout = buf + cmd.Stderr = os.Stderr + + out.Debug(ctx, "store.gitConfigList: %s %+v", cmd.Path, cmd.Args) + if err := cmd.Run(); err != nil { + return nil, err + } + + lines := strings.Split(buf.String(), "\n") + kv := make(map[string]string, len(lines)) + for _, line := range lines { + line = strings.TrimSpace(line) + p := strings.SplitN(line, "=", 2) + if len(p) < 2 { + continue + } + kv[p[0]] = p[1] + } + return kv, nil +} diff --git a/backend/sync/git/cli/git.go b/backend/sync/git/cli/git.go index a25a534d30..89ce2da52a 100644 --- a/backend/sync/git/cli/git.go +++ b/backend/sync/git/cli/git.go @@ -186,6 +186,34 @@ func (g *Git) Commit(ctx context.Context, msg string) error { return g.Cmd(ctx, "gitCommit", "commit", "-m", msg) } +func (g *Git) defaultRemote(ctx context.Context, branch string) string { + opts, err := g.ConfigList(ctx) + if err != nil { + return "origin" + } + + remote := opts["branch."+branch+".remote"] + if remote == "" { + return "origin" + } + + needle := "remote." + remote + ".url" + for k := range opts { + if k == needle { + return remote + } + } + return "origin" +} + +func (g *Git) defaultBranch(ctx context.Context) string { + out, _, err := g.captureCmd(ctx, "defaultBranch", "rev-parse", "--abbrev-ref", "HEAD") + if err != nil || string(out) == "" { + return "master" + } + return strings.TrimSpace(string(out)) +} + // PushPull pushes the repo to it's origin. // optional arguments: remote and branch func (g *Git) PushPull(ctx context.Context, op, remote, branch string) error { @@ -193,11 +221,11 @@ func (g *Git) PushPull(ctx context.Context, op, remote, branch string) error { return store.ErrGitNotInit } - if remote == "" { - remote = "origin" - } if branch == "" { - branch = "master" + branch = g.defaultBranch(ctx) + } + if remote == "" { + remote = g.defaultRemote(ctx, branch) } if v, err := g.ConfigGet(ctx, "remote."+remote+".url"); err != nil || v == "" {