From 4199d28053b228376a68a957297f332026fafa4e Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Thu, 19 Jan 2023 22:31:44 +0000
Subject: [PATCH] When updating by rebase we need to set the environment for
 head repo (#22535)

The update by rebase code reuses the merge code but shortcircuits and
pushes back up to the head. However, it doesn't set the correct pushing
environment - and just uses the same environment as the base repo. This
leads to the push update failing and thence the PR becomes out-of-sync
with the head.

This PR fixes this and adjusts the trace logging elsewhere to help make
this clearer.

Fix #18802

Signed-off-by: Andrew Thornton <art27@cantab.net>

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
---
 services/pull/merge.go      | 22 ++++++++++++++--------
 services/repository/push.go |  6 ++++--
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/services/pull/merge.go b/services/pull/merge.go
index d0ec943cfa..bdd2cb0e86 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -595,19 +595,25 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode
 		headUser = pr.HeadRepo.Owner
 	}
 
-	env = repo_module.FullPushingEnvironment(
-		headUser,
-		doer,
-		pr.BaseRepo,
-		pr.BaseRepo.Name,
-		pr.ID,
-	)
-
 	var pushCmd *git.Command
 	if mergeStyle == repo_model.MergeStyleRebaseUpdate {
 		// force push the rebase result to head branch
+		env = repo_module.FullPushingEnvironment(
+			headUser,
+			doer,
+			pr.HeadRepo,
+			pr.HeadRepo.Name,
+			pr.ID,
+		)
 		pushCmd = git.NewCommand(ctx, "push", "-f", "head_repo").AddDynamicArguments(stagingBranch + ":" + git.BranchPrefix + pr.HeadBranch)
 	} else {
+		env = repo_module.FullPushingEnvironment(
+			headUser,
+			doer,
+			pr.BaseRepo,
+			pr.BaseRepo.Name,
+			pr.ID,
+		)
 		pushCmd = git.NewCommand(ctx, "push", "origin").AddDynamicArguments(baseBranch + ":" + git.BranchPrefix + pr.BaseBranch)
 	}
 
diff --git a/services/repository/push.go b/services/repository/push.go
index dc8d564cb4..0135243388 100644
--- a/services/repository/push.go
+++ b/services/repository/push.go
@@ -103,6 +103,8 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 	var pusher *user_model.User
 
 	for _, opts := range optsList {
+		log.Trace("pushUpdates: %-v %s %s %s", repo, opts.OldCommitID, opts.NewCommitID, opts.RefFullName)
+
 		if opts.IsNewRef() && opts.IsDelRef() {
 			return fmt.Errorf("old and new revisions are both %s", git.EmptySHA)
 		}
@@ -128,7 +130,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 			} else { // is new tag
 				newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
 				if err != nil {
-					return fmt.Errorf("gitRepo.GetCommit: %w", err)
+					return fmt.Errorf("gitRepo.GetCommit(%s) in %s/%s[%d]: %w", opts.NewCommitID, repo.OwnerName, repo.Name, repo.ID, err)
 				}
 
 				commits := repo_module.NewPushCommits()
@@ -161,7 +163,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
 
 				newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
 				if err != nil {
-					return fmt.Errorf("gitRepo.GetCommit: %w", err)
+					return fmt.Errorf("gitRepo.GetCommit(%s) in %s/%s[%d]: %w", opts.NewCommitID, repo.OwnerName, repo.Name, repo.ID, err)
 				}
 
 				refName := opts.RefName()