mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Restore deleted branches when syncing (#29898)
Regression of #29493. If a branch has been deleted, repushing it won't restore it. Lunny may have noticed that, but I didn't delve into the comment then overlooked it: https://github.com/go-gitea/gitea/pull/29493#discussion_r1509046867 The additional comments added are to explain the issue I found during testing, which are unrelated to the fixes.
This commit is contained in:
		@@ -75,6 +75,10 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
 | 
				
			|||||||
			updates = append(updates, option)
 | 
								updates = append(updates, option)
 | 
				
			||||||
			if repo.IsEmpty && (refFullName.BranchName() == "master" || refFullName.BranchName() == "main") {
 | 
								if repo.IsEmpty && (refFullName.BranchName() == "master" || refFullName.BranchName() == "main") {
 | 
				
			||||||
				// put the master/main branch first
 | 
									// put the master/main branch first
 | 
				
			||||||
 | 
									// FIXME: It doesn't always work, since the master/main branch may not be the first batch of updates.
 | 
				
			||||||
 | 
									//        If the user pushes many branches at once, the Git hook will call the internal API in batches, rather than all at once.
 | 
				
			||||||
 | 
									//        See https://github.com/go-gitea/gitea/blob/cb52b17f92e2d2293f7c003649743464492bca48/cmd/hook.go#L27
 | 
				
			||||||
 | 
									//        If the user executes `git push origin --all` and pushes more than 30 branches, the master/main may not be the default branch.
 | 
				
			||||||
				copy(updates[1:], updates)
 | 
									copy(updates[1:], updates)
 | 
				
			||||||
				updates[0] = option
 | 
									updates[0] = option
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -129,9 +133,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
 | 
				
			|||||||
				commitIDs = append(commitIDs, update.NewCommitID)
 | 
									commitIDs = append(commitIDs, update.NewCommitID)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err := repo_service.SyncBranchesToDB(ctx, repo.ID, opts.UserID, branchNames, commitIDs, func(commitID string) (*git.Commit, error) {
 | 
								if err := repo_service.SyncBranchesToDB(ctx, repo.ID, opts.UserID, branchNames, commitIDs, gitRepo.GetCommit); err != nil {
 | 
				
			||||||
				return gitRepo.GetCommit(commitID)
 | 
					 | 
				
			||||||
			}); err != nil {
 | 
					 | 
				
			||||||
				ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
 | 
									ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
 | 
				
			||||||
					Err: fmt.Sprintf("Failed to sync branch to DB in repository: %s/%s Error: %v", ownerName, repoName, err),
 | 
										Err: fmt.Sprintf("Failed to sync branch to DB in repository: %s/%s Error: %v", ownerName, repoName, err),
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -318,11 +318,11 @@ func SyncBranchesToDB(ctx context.Context, repoID, pusherID int64, branchNames,
 | 
				
			|||||||
		for i, branchName := range branchNames {
 | 
							for i, branchName := range branchNames {
 | 
				
			||||||
			commitID := commitIDs[i]
 | 
								commitID := commitIDs[i]
 | 
				
			||||||
			branch, exist := branchMap[branchName]
 | 
								branch, exist := branchMap[branchName]
 | 
				
			||||||
			if exist && branch.CommitID == commitID {
 | 
								if exist && branch.CommitID == commitID && !branch.IsDeleted {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			commit, err := getCommit(branchName)
 | 
								commit, err := getCommit(commitID)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return fmt.Errorf("get commit of %s failed: %v", branchName, err)
 | 
									return fmt.Errorf("get commit of %s failed: %v", branchName, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,6 +69,23 @@ func testGitPush(t *testing.T, u *url.URL) {
 | 
				
			|||||||
			return pushed, deleted
 | 
								return pushed, deleted
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Run("Push to deleted branch", func(t *testing.T) {
 | 
				
			||||||
 | 
							runTestGitPush(t, u, func(t *testing.T, gitPath string) (pushed, deleted []string) {
 | 
				
			||||||
 | 
								doGitPushTestRepository(gitPath, "origin", "master")(t) // make sure master is the default branch instead of a branch we are going to delete
 | 
				
			||||||
 | 
								pushed = append(pushed, "master")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								doGitCreateBranch(gitPath, "branch-1")(t)
 | 
				
			||||||
 | 
								doGitPushTestRepository(gitPath, "origin", "branch-1")(t)
 | 
				
			||||||
 | 
								pushed = append(pushed, "branch-1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// delete and restore
 | 
				
			||||||
 | 
								doGitPushTestRepository(gitPath, "origin", "--delete", "branch-1")(t)
 | 
				
			||||||
 | 
								doGitPushTestRepository(gitPath, "origin", "branch-1")(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return pushed, deleted
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func runTestGitPush(t *testing.T, u *url.URL, gitOperation func(t *testing.T, gitPath string) (pushed, deleted []string)) {
 | 
					func runTestGitPush(t *testing.T, u *url.URL, gitOperation func(t *testing.T, gitPath string) (pushed, deleted []string)) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user