Skip to content

Commit 7525450

Browse files
lunnyzeripath6543
authored
When transfering repository and database transaction failed, rollback the renames (#14864)
Fix #14821 Co-authored-by: Andrew Thornton <[email protected]> Co-authored-by: 6543 <[email protected]>
1 parent 0a8a3ab commit 7525450

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

models/repo_transfer.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,39 @@ func CreatePendingRepositoryTransfer(doer, newOwner *User, repoID int64, teams [
195195
}
196196

197197
// TransferOwnership transfers all corresponding repository items from old user to new one.
198-
func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error {
198+
func TransferOwnership(doer *User, newOwnerName string, repo *Repository) (err error) {
199+
repoRenamed := false
200+
wikiRenamed := false
201+
oldOwnerName := doer.Name
202+
203+
defer func() {
204+
if !repoRenamed && !wikiRenamed {
205+
return
206+
}
207+
208+
recoverErr := recover()
209+
if err == nil && recoverErr == nil {
210+
return
211+
}
212+
213+
if repoRenamed {
214+
if err := os.Rename(RepoPath(newOwnerName, repo.Name), RepoPath(oldOwnerName, repo.Name)); err != nil {
215+
log.Critical("Unable to move repository %s/%s directory from %s back to correct place %s: %v", oldOwnerName, repo.Name, RepoPath(newOwnerName, repo.Name), RepoPath(oldOwnerName, repo.Name), err)
216+
}
217+
}
218+
219+
if wikiRenamed {
220+
if err := os.Rename(WikiPath(newOwnerName, repo.Name), WikiPath(oldOwnerName, repo.Name)); err != nil {
221+
log.Critical("Unable to move wiki for repository %s/%s directory from %s back to correct place %s: %v", oldOwnerName, repo.Name, WikiPath(newOwnerName, repo.Name), WikiPath(oldOwnerName, repo.Name), err)
222+
}
223+
}
224+
225+
if recoverErr != nil {
226+
log.Error("Panic within TransferOwnership: %v\n%s", recoverErr, log.Stack(2))
227+
panic(recoverErr)
228+
}
229+
}()
230+
199231
sess := x.NewSession()
200232
defer sess.Close()
201233
if err := sess.Begin(); err != nil {
@@ -206,6 +238,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
206238
if err != nil {
207239
return fmt.Errorf("get new owner '%s': %v", newOwnerName, err)
208240
}
241+
newOwnerName = newOwner.Name // ensure capitalisation matches
209242

210243
// Check if new owner has repository with same name.
211244
if has, err := isRepositoryExist(sess, newOwner, repo.Name); err != nil {
@@ -215,6 +248,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
215248
}
216249

217250
oldOwner := repo.Owner
251+
oldOwnerName = oldOwner.Name
218252

219253
// Note: we have to set value here to make sure recalculate accesses is based on
220254
// new owner.
@@ -301,6 +335,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
301335
if err := os.Rename(RepoPath(oldOwner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
302336
return fmt.Errorf("rename repository directory: %v", err)
303337
}
338+
repoRenamed = true
304339

305340
// Rename remote wiki repository to new path and delete local copy.
306341
wikiPath := WikiPath(oldOwner.Name, repo.Name)
@@ -312,6 +347,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
312347
if err := os.Rename(wikiPath, WikiPath(newOwner.Name, repo.Name)); err != nil {
313348
return fmt.Errorf("rename repository wiki: %v", err)
314349
}
350+
wikiRenamed = true
315351
}
316352

317353
if err := deleteRepositoryTransfer(sess, repo.ID); err != nil {

0 commit comments

Comments
 (0)