@@ -757,3 +757,117 @@ func TriggerTask(ctx *context.Context) {
757
757
go models .AddTestPullRequestTask (pusher , repo .ID , branch , true )
758
758
ctx .Status (202 )
759
759
}
760
+
761
+ // CleanUpPullRequest responses for delete merged branch when PR has been merged
762
+ func CleanUpPullRequest (ctx * context.Context ) {
763
+ issue := checkPullInfo (ctx )
764
+ if ctx .Written () {
765
+ return
766
+ }
767
+
768
+ pr , err := models .GetPullRequestByIssueID (issue .ID )
769
+ if err != nil {
770
+ if models .IsErrPullRequestNotExist (err ) {
771
+ ctx .Handle (404 , "GetPullRequestByIssueID" , nil )
772
+ } else {
773
+ ctx .Handle (500 , "GetPullRequestByIssueID" , err )
774
+ }
775
+ return
776
+ }
777
+
778
+ // Allow cleanup only for merged PR
779
+ if ! pr .HasMerged {
780
+ ctx .Handle (404 , "CleanUpPullRequest" , nil )
781
+ return
782
+ }
783
+
784
+ if err = pr .GetHeadRepo (); err != nil {
785
+ ctx .Handle (500 , "GetHeadRepo" , err )
786
+ return
787
+ } else if pr .GetBaseRepo (); err != nil {
788
+ ctx .Handle (500 , "GetBaseRepo" , err )
789
+ return
790
+ } else if pr .HeadRepo .GetOwner (); err != nil {
791
+ ctx .Handle (500 , "GetOwner" , err )
792
+ return
793
+ }
794
+
795
+ if ! ctx .User .IsWriterOfRepo (pr .HeadRepo ) {
796
+ ctx .Handle (404 , "CleanUpPullRequest" , nil )
797
+ return
798
+ }
799
+
800
+ fullBranchName := pr .HeadRepo .Owner .Name + "/" + pr .HeadBranch
801
+
802
+ gitRepo , err := git .OpenRepository (pr .HeadRepo .RepoPath ())
803
+ if err != nil {
804
+ ctx .Handle (500 , fmt .Sprintf ("OpenRepository[%s]" , pr .HeadRepo .RepoPath ()), err )
805
+ return
806
+ }
807
+
808
+ gitBaseRepo , err := git .OpenRepository (pr .BaseRepo .RepoPath ())
809
+ if err != nil {
810
+ ctx .Handle (500 , fmt .Sprintf ("OpenRepository[%s]" , pr .BaseRepo .RepoPath ()), err )
811
+ return
812
+ }
813
+
814
+ defer func () {
815
+ ctx .JSON (200 , map [string ]interface {}{
816
+ "redirect" : pr .BaseRepo .Link () + "/pulls/" + com .ToStr (issue .Index ),
817
+ })
818
+ }()
819
+
820
+ if pr .HeadBranch == pr .HeadRepo .DefaultBranch || ! gitRepo .IsBranchExist (pr .HeadBranch ) {
821
+ ctx .Flash .Error (ctx .Tr ("repo.branch.deletion_failed" , fullBranchName ))
822
+ return
823
+ }
824
+
825
+ // Check if branch has no new commits
826
+ if len (pr .MergedCommitID ) > 0 {
827
+ branchCommitID , err := gitRepo .GetBranchCommitID (pr .HeadBranch )
828
+ if err != nil {
829
+ log .Error (4 , "GetBranchCommitID: %v" , err )
830
+ ctx .Flash .Error (ctx .Tr ("repo.branch.deletion_failed" , fullBranchName ))
831
+ return
832
+ }
833
+
834
+ commit , err := gitBaseRepo .GetCommit (pr .MergedCommitID )
835
+ if err != nil {
836
+ log .Error (4 , "GetCommit: %v" , err )
837
+ ctx .Flash .Error (ctx .Tr ("repo.branch.deletion_failed" , fullBranchName ))
838
+ return
839
+ }
840
+
841
+ isParent := false
842
+ for i := 0 ; i < commit .ParentCount (); i ++ {
843
+ if parent , err := commit .Parent (i ); err != nil {
844
+ log .Error (4 , "Parent: %v" , err )
845
+ ctx .Flash .Error (ctx .Tr ("repo.branch.deletion_failed" , fullBranchName ))
846
+ return
847
+ } else if parent .ID .String () == branchCommitID {
848
+ isParent = true
849
+ break
850
+ }
851
+ }
852
+
853
+ if ! isParent {
854
+ ctx .Flash .Error (ctx .Tr ("repo.branch.delete_branch_has_new_commits" , fullBranchName ))
855
+ return
856
+ }
857
+ }
858
+
859
+ if err := gitRepo .DeleteBranch (pr .HeadBranch , git.DeleteBranchOptions {
860
+ Force : true ,
861
+ }); err != nil {
862
+ log .Error (4 , "DeleteBranch: %v" , err )
863
+ ctx .Flash .Error (ctx .Tr ("repo.branch.deletion_failed" , fullBranchName ))
864
+ return
865
+ }
866
+
867
+ if err := models .AddDeletePRBranchComment (ctx .User , pr .BaseRepo , issue .ID , pr .HeadBranch ); err != nil {
868
+ // Do not fail here as branch has already been deleted
869
+ log .Error (4 , "DeleteBranch: %v" , err )
870
+ }
871
+
872
+ ctx .Flash .Success (ctx .Tr ("repo.branch.deletion_success" , fullBranchName ))
873
+ }
0 commit comments