Merge merges pull request to base repository. FIXME: add repoWorkingPull make sure two merges does not happen at same time.
(doer *User, baseGitRepo *git.Repository, mergeStyle MergeStyle, commitDescription string)
| 192 | // Merge merges pull request to base repository. |
| 193 | // FIXME: add repoWorkingPull make sure two merges does not happen at same time. |
| 194 | func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle MergeStyle, commitDescription string) (err error) { |
| 195 | ctx := context.TODO() |
| 196 | |
| 197 | defer func() { |
| 198 | go HookQueue.Add(pr.BaseRepo.ID) |
| 199 | go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false) |
| 200 | }() |
| 201 | |
| 202 | sess := x.NewSession() |
| 203 | defer sess.Close() |
| 204 | if err = sess.Begin(); err != nil { |
| 205 | return err |
| 206 | } |
| 207 | |
| 208 | if err = pr.Issue.changeStatus(sess, doer, pr.Issue.Repo, true); err != nil { |
| 209 | return errors.Newf("Issue.changeStatus: %v", err) |
| 210 | } |
| 211 | |
| 212 | headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name) |
| 213 | headGitRepo, err := git.Open(headRepoPath) |
| 214 | if err != nil { |
| 215 | return errors.Newf("open repository: %v", err) |
| 216 | } |
| 217 | |
| 218 | // Create temporary directory to store temporary copy of the base repository, |
| 219 | // and clean it up when operation finished regardless of succeed or not. |
| 220 | tmpBasePath := filepath.Join(conf.Server.AppDataPath, "tmp", "repos", com.ToStr(time.Now().Nanosecond())+".git") |
| 221 | if err = os.MkdirAll(filepath.Dir(tmpBasePath), os.ModePerm); err != nil { |
| 222 | return err |
| 223 | } |
| 224 | defer func() { |
| 225 | _ = os.RemoveAll(filepath.Dir(tmpBasePath)) |
| 226 | }() |
| 227 | |
| 228 | // Clone the base repository to the defined temporary directory, |
| 229 | // and checks out to base branch directly. |
| 230 | var stderr string |
| 231 | if err = git.Clone(baseGitRepo.Path(), tmpBasePath, git.CloneOptions{ |
| 232 | Branch: pr.BaseBranch, |
| 233 | Timeout: 5 * time.Minute, |
| 234 | }); err != nil { |
| 235 | return errors.Newf("git clone: %v", err) |
| 236 | } |
| 237 | |
| 238 | // Add remote which points to the head repository. |
| 239 | if _, stderr, err = process.ExecDir(-1, tmpBasePath, |
| 240 | fmt.Sprintf("PullRequest.Merge (git remote add): %s", tmpBasePath), |
| 241 | "git", "remote", "add", "head_repo", headRepoPath); err != nil { |
| 242 | return errors.Newf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr) |
| 243 | } |
| 244 | |
| 245 | // Fetch information from head repository to the temporary copy. |
| 246 | if _, stderr, err = process.ExecDir(-1, tmpBasePath, |
| 247 | fmt.Sprintf("PullRequest.Merge (git fetch): %s", tmpBasePath), |
| 248 | "git", "fetch", "head_repo"); err != nil { |
| 249 | return errors.Newf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr) |
| 250 | } |
| 251 |
no test coverage detected