RunGitPull runs a git pull command in the specified path.
(ctx context.Context, path string, discardLocal bool, remote, remoteName string)
| 108 | |
| 109 | // RunGitPull runs a git pull command in the specified path. |
| 110 | func RunGitPull(ctx context.Context, path string, discardLocal bool, remote, remoteName string) (string, error) { |
| 111 | // current status of the full repo |
| 112 | st, err := RunGitStatus(path, "", remoteName, "") |
| 113 | if err != nil { |
| 114 | return "", err |
| 115 | } |
| 116 | |
| 117 | if discardLocal { |
| 118 | // when discarding local changes it is okay to discard in full repo and not just in subpath |
| 119 | // instead of doing a hard clean, do a stash instead |
| 120 | if st.LocalChanges { |
| 121 | cmd := exec.CommandContext(ctx, "git", "-C", path, "stash", "--include-untracked") |
| 122 | if err := cmd.Run(); err != nil { |
| 123 | return "", fmt.Errorf("failed to remove local changes: %w", err) |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | if st.LocalCommits > 0 { |
| 128 | // reset local commits by moving HEAD to the remote tip; HEAD~N would be wrong |
| 129 | // because LocalCommits excludes merge commits. |
| 130 | remoteRef := fmt.Sprintf("%s/%s", remoteName, st.Branch) |
| 131 | cmd := exec.CommandContext(ctx, "git", "-C", path, "reset", "--mixed", remoteRef) |
| 132 | if out, err := cmd.CombinedOutput(); err != nil { |
| 133 | return "", fmt.Errorf("failed to reset local commits: %s (%w)", string(out), err) |
| 134 | } |
| 135 | // stash the changes |
| 136 | cmd = exec.CommandContext(ctx, "git", "-C", path, "stash", "--include-untracked") |
| 137 | if err := cmd.Run(); err != nil { |
| 138 | return "", fmt.Errorf("failed to remove local changes: %w", err) |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | // git -C <path> pull <remote> <branch> |
| 144 | args := []string{"-C", path, "pull"} |
| 145 | |
| 146 | if remote != "" { |
| 147 | args = append(args, remote, st.Branch) |
| 148 | } |
| 149 | |
| 150 | cmd := exec.CommandContext(ctx, "git", args...) |
| 151 | _, err = cmd.Output() |
| 152 | if err != nil { |
| 153 | var execErr *exec.ExitError |
| 154 | if errors.As(err, &execErr) { |
| 155 | // This is error msg returned by git when pull fails |
| 156 | return string(execErr.Stderr), nil |
| 157 | } |
| 158 | return "", err |
| 159 | } |
| 160 | // Skip the normal output of git pull, just return an empty string |
| 161 | return "", nil |
| 162 | } |
| 163 | |
| 164 | func RunUpstreamMerge(ctx context.Context, remote, path, branch string, favourLocal bool) error { |
| 165 | var args []string |