+230
-85
appview/pulls/pulls.go
+230
-85
appview/pulls/pulls.go
···
2
3
import (
4
"database/sql"
5
"errors"
6
"fmt"
7
"log"
···
21
"tangled.sh/tangled.sh/core/appview/reporesolver"
22
"tangled.sh/tangled.sh/core/appview/xrpcclient"
23
"tangled.sh/tangled.sh/core/idresolver"
24
-
"tangled.sh/tangled.sh/core/knotclient"
25
"tangled.sh/tangled.sh/core/patchutil"
26
"tangled.sh/tangled.sh/core/tid"
27
"tangled.sh/tangled.sh/core/types"
···
99
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
100
resubmitResult := pages.Unknown
101
if user.Did == pull.OwnerDid {
102
-
resubmitResult = s.resubmitCheck(f, pull, stack)
103
}
104
105
s.pages.PullActionsFragment(w, pages.PullActionsParams{
···
154
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
155
resubmitResult := pages.Unknown
156
if user != nil && user.Did == pull.OwnerDid {
157
-
resubmitResult = s.resubmitCheck(f, pull, stack)
158
}
159
160
repoInfo := f.RepoInfo(user)
···
282
return result
283
}
284
285
-
func (s *Pulls) resubmitCheck(f *reporesolver.ResolvedRepo, pull *db.Pull, stack db.Stack) pages.ResubmitResult {
286
if pull.State == db.PullMerged || pull.State == db.PullDeleted || pull.PullSource == nil {
287
return pages.Unknown
288
}
···
307
repoName = f.Name
308
}
309
310
-
us, err := knotclient.NewUnsignedClient(knot, s.config.Core.Dev)
311
-
if err != nil {
312
-
log.Printf("failed to setup client for %s; ignoring: %v", knot, err)
313
-
return pages.Unknown
314
}
315
316
-
result, err := us.Branch(ownerDid, repoName, pull.PullSource.Branch)
317
if err != nil {
318
log.Println("failed to reach knotserver", err)
319
return pages.Unknown
320
}
321
322
latestSourceRev := pull.Submissions[pull.LastRoundNumber()].SourceRev
323
324
if pull.IsStacked() && stack != nil {
···
326
latestSourceRev = top.Submissions[top.LastRoundNumber()].SourceRev
327
}
328
329
-
if latestSourceRev != result.Branch.Hash {
330
return pages.ShouldResubmit
331
}
332
···
678
679
switch r.Method {
680
case http.MethodGet:
681
-
us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
682
if err != nil {
683
-
log.Printf("failed to create unsigned client for %s", f.Knot)
684
-
s.pages.Error503(w)
685
return
686
}
687
688
-
result, err := us.Branches(f.OwnerDid(), f.Name)
689
-
if err != nil {
690
-
log.Println("failed to fetch branches", err)
691
return
692
}
693
···
752
return
753
}
754
755
-
us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
756
-
if err != nil {
757
-
log.Printf("failed to create unsigned client to %s: %v", f.Knot, err)
758
-
s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.")
759
-
return
760
-
}
761
762
-
caps, err := us.Capabilities()
763
-
if err != nil {
764
-
log.Println("error fetching knot caps", f.Knot, err)
765
-
s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.")
766
-
return
767
}
768
769
if !caps.PullRequests.FormatPatch {
770
s.pages.Notice(w, "pull", "This knot doesn't support format-patch. Unfortunately, there is no fallback for now.")
···
806
sourceBranch string,
807
isStacked bool,
808
) {
809
-
// Generate a patch using /compare
810
-
ksClient, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
811
-
if err != nil {
812
-
log.Printf("failed to create signed client for %s: %s", f.Knot, err)
813
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
814
-
return
815
}
816
817
-
comparison, err := ksClient.Compare(f.OwnerDid(), f.Name, targetBranch, sourceBranch)
818
if err != nil {
819
log.Println("failed to compare", err)
820
s.pages.Notice(w, "pull", err.Error())
821
return
822
}
823
···
869
oauth.WithLxm(tangled.RepoHiddenRefNSID),
870
oauth.WithDev(s.config.Core.Dev),
871
)
872
-
if err != nil {
873
-
log.Printf("failed to connect to knot server: %v", err)
874
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
875
-
return
876
-
}
877
-
878
-
us, err := knotclient.NewUnsignedClient(fork.Knot, s.config.Core.Dev)
879
-
if err != nil {
880
-
log.Println("failed to create unsigned client:", err)
881
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
882
-
return
883
-
}
884
885
resp, err := tangled.RepoHiddenRef(
886
r.Context(),
···
911
// hiddenRef: hidden/feature-1/main (on repo-fork)
912
// targetBranch: main (on repo-1)
913
// sourceBranch: feature-1 (on repo-fork)
914
-
comparison, err := us.Compare(fork.Did, fork.Name, hiddenRef, sourceBranch)
915
if err != nil {
916
log.Println("failed to compare across branches", err)
917
s.pages.Notice(w, "pull", err.Error())
918
return
919
}
920
921
sourceRev := comparison.Rev2
922
patch := comparison.Patch
923
···
1211
return
1212
}
1213
1214
-
us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
1215
if err != nil {
1216
-
log.Printf("failed to create unsigned client for %s", f.Knot)
1217
-
s.pages.Error503(w)
1218
return
1219
}
1220
1221
-
result, err := us.Branches(f.OwnerDid(), f.Name)
1222
-
if err != nil {
1223
-
log.Println("failed to reach knotserver", err)
1224
return
1225
}
1226
···
1284
return
1285
}
1286
1287
-
sourceBranchesClient, err := knotclient.NewUnsignedClient(repo.Knot, s.config.Core.Dev)
1288
if err != nil {
1289
-
log.Printf("failed to create unsigned client for %s", repo.Knot)
1290
-
s.pages.Error503(w)
1291
return
1292
}
1293
1294
-
sourceResult, err := sourceBranchesClient.Branches(forkOwnerDid, repo.Name)
1295
-
if err != nil {
1296
-
log.Println("failed to reach knotserver for source branches", err)
1297
return
1298
}
1299
1300
-
targetBranchesClient, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
1301
if err != nil {
1302
-
log.Printf("failed to create unsigned client for target knot %s", f.Knot)
1303
-
s.pages.Error503(w)
1304
return
1305
}
1306
1307
-
targetResult, err := targetBranchesClient.Branches(f.OwnerDid(), f.Name)
1308
-
if err != nil {
1309
-
log.Println("failed to reach knotserver for target branches", err)
1310
return
1311
}
1312
1313
-
sourceBranches := sourceResult.Branches
1314
-
sort.Slice(sourceBranches, func(i int, j int) bool {
1315
-
return sourceBranches[i].Commit.Committer.When.After(sourceBranches[j].Commit.Committer.When)
1316
})
1317
1318
s.pages.PullCompareForkBranchesFragment(w, pages.PullCompareForkBranchesParams{
1319
RepoInfo: f.RepoInfo(user),
1320
-
SourceBranches: sourceBranches,
1321
-
TargetBranches: targetResult.Branches,
1322
})
1323
}
1324
···
1413
return
1414
}
1415
1416
-
ksClient, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
1417
-
if err != nil {
1418
-
log.Printf("failed to create client for %s: %s", f.Knot, err)
1419
-
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1420
-
return
1421
}
1422
1423
-
comparison, err := ksClient.Compare(f.OwnerDid(), f.Name, pull.TargetBranch, pull.PullSource.Branch)
1424
if err != nil {
1425
log.Printf("compare request failed: %s", err)
1426
s.pages.Notice(w, "resubmit-error", err.Error())
1427
return
1428
}
1429
···
1463
}
1464
1465
// extract patch by performing compare
1466
-
ksClient, err := knotclient.NewUnsignedClient(forkRepo.Knot, s.config.Core.Dev)
1467
if err != nil {
1468
-
log.Printf("failed to create client for %s: %s", forkRepo.Knot, err)
1469
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1470
return
1471
}
···
1501
return
1502
}
1503
1504
-
hiddenRef := fmt.Sprintf("hidden/%s/%s", pull.PullSource.Branch, pull.TargetBranch)
1505
-
comparison, err := ksClient.Compare(forkRepo.Did, forkRepo.Name, hiddenRef, pull.PullSource.Branch)
1506
-
if err != nil {
1507
-
log.Printf("failed to compare branches: %s", err)
1508
-
s.pages.Notice(w, "resubmit-error", err.Error())
1509
-
return
1510
-
}
1511
1512
sourceRev := comparison.Rev2
1513
patch := comparison.Patch
···
2
3
import (
4
"database/sql"
5
+
"encoding/json"
6
"errors"
7
"fmt"
8
"log"
···
22
"tangled.sh/tangled.sh/core/appview/reporesolver"
23
"tangled.sh/tangled.sh/core/appview/xrpcclient"
24
"tangled.sh/tangled.sh/core/idresolver"
25
"tangled.sh/tangled.sh/core/patchutil"
26
"tangled.sh/tangled.sh/core/tid"
27
"tangled.sh/tangled.sh/core/types"
···
99
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
100
resubmitResult := pages.Unknown
101
if user.Did == pull.OwnerDid {
102
+
resubmitResult = s.resubmitCheck(r, f, pull, stack)
103
}
104
105
s.pages.PullActionsFragment(w, pages.PullActionsParams{
···
154
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
155
resubmitResult := pages.Unknown
156
if user != nil && user.Did == pull.OwnerDid {
157
+
resubmitResult = s.resubmitCheck(r, f, pull, stack)
158
}
159
160
repoInfo := f.RepoInfo(user)
···
282
return result
283
}
284
285
+
func (s *Pulls) resubmitCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *db.Pull, stack db.Stack) pages.ResubmitResult {
286
if pull.State == db.PullMerged || pull.State == db.PullDeleted || pull.PullSource == nil {
287
return pages.Unknown
288
}
···
307
repoName = f.Name
308
}
309
310
+
scheme := "http"
311
+
if !s.config.Core.Dev {
312
+
scheme = "https"
313
+
}
314
+
host := fmt.Sprintf("%s://%s", scheme, knot)
315
+
xrpcc := &indigoxrpc.Client{
316
+
Host: host,
317
}
318
319
+
repo := fmt.Sprintf("%s/%s", ownerDid, repoName)
320
+
branchResp, err := tangled.RepoBranch(r.Context(), xrpcc, pull.PullSource.Branch, repo)
321
if err != nil {
322
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
323
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
324
+
return pages.Unknown
325
+
}
326
log.Println("failed to reach knotserver", err)
327
return pages.Unknown
328
}
329
330
+
targetBranch := branchResp
331
+
332
latestSourceRev := pull.Submissions[pull.LastRoundNumber()].SourceRev
333
334
if pull.IsStacked() && stack != nil {
···
336
latestSourceRev = top.Submissions[top.LastRoundNumber()].SourceRev
337
}
338
339
+
if latestSourceRev != targetBranch.Hash {
340
return pages.ShouldResubmit
341
}
342
···
688
689
switch r.Method {
690
case http.MethodGet:
691
+
scheme := "http"
692
+
if !s.config.Core.Dev {
693
+
scheme = "https"
694
+
}
695
+
host := fmt.Sprintf("%s://%s", scheme, f.Knot)
696
+
xrpcc := &indigoxrpc.Client{
697
+
Host: host,
698
+
}
699
+
700
+
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
701
+
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
702
if err != nil {
703
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
704
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
705
+
s.pages.Error503(w)
706
+
return
707
+
}
708
+
log.Println("failed to fetch branches", err)
709
return
710
}
711
712
+
var result types.RepoBranchesResponse
713
+
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
714
+
log.Println("failed to decode XRPC response", err)
715
+
s.pages.Error503(w)
716
return
717
}
718
···
777
return
778
}
779
780
+
// us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
781
+
// if err != nil {
782
+
// log.Printf("failed to create unsigned client to %s: %v", f.Knot, err)
783
+
// s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.")
784
+
// return
785
+
// }
786
787
+
// TODO: make capabilities an xrpc call
788
+
caps := struct {
789
+
PullRequests struct {
790
+
FormatPatch bool
791
+
BranchSubmissions bool
792
+
ForkSubmissions bool
793
+
PatchSubmissions bool
794
+
}
795
+
}{
796
+
PullRequests: struct {
797
+
FormatPatch bool
798
+
BranchSubmissions bool
799
+
ForkSubmissions bool
800
+
PatchSubmissions bool
801
+
}{
802
+
FormatPatch: true,
803
+
BranchSubmissions: true,
804
+
ForkSubmissions: true,
805
+
PatchSubmissions: true,
806
+
},
807
}
808
+
809
+
// caps, err := us.Capabilities()
810
+
// if err != nil {
811
+
// log.Println("error fetching knot caps", f.Knot, err)
812
+
// s.pages.Notice(w, "pull", "Failed to create a pull request. Try again later.")
813
+
// return
814
+
// }
815
816
if !caps.PullRequests.FormatPatch {
817
s.pages.Notice(w, "pull", "This knot doesn't support format-patch. Unfortunately, there is no fallback for now.")
···
853
sourceBranch string,
854
isStacked bool,
855
) {
856
+
scheme := "http"
857
+
if !s.config.Core.Dev {
858
+
scheme = "https"
859
+
}
860
+
host := fmt.Sprintf("%s://%s", scheme, f.Knot)
861
+
xrpcc := &indigoxrpc.Client{
862
+
Host: host,
863
}
864
865
+
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
866
+
xrpcBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, targetBranch, sourceBranch)
867
if err != nil {
868
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
869
+
log.Println("failed to call XRPC repo.compare", xrpcerr)
870
+
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
871
+
return
872
+
}
873
log.Println("failed to compare", err)
874
s.pages.Notice(w, "pull", err.Error())
875
+
return
876
+
}
877
+
878
+
var comparison types.RepoFormatPatchResponse
879
+
if err := json.Unmarshal(xrpcBytes, &comparison); err != nil {
880
+
log.Println("failed to decode XRPC compare response", err)
881
+
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
882
return
883
}
884
···
930
oauth.WithLxm(tangled.RepoHiddenRefNSID),
931
oauth.WithDev(s.config.Core.Dev),
932
)
933
934
resp, err := tangled.RepoHiddenRef(
935
r.Context(),
···
960
// hiddenRef: hidden/feature-1/main (on repo-fork)
961
// targetBranch: main (on repo-1)
962
// sourceBranch: feature-1 (on repo-fork)
963
+
forkScheme := "http"
964
+
if !s.config.Core.Dev {
965
+
forkScheme = "https"
966
+
}
967
+
forkHost := fmt.Sprintf("%s://%s", forkScheme, fork.Knot)
968
+
forkXrpcc := &indigoxrpc.Client{
969
+
Host: forkHost,
970
+
}
971
+
972
+
forkRepoId := fmt.Sprintf("%s/%s", fork.Did, fork.Name)
973
+
forkXrpcBytes, err := tangled.RepoCompare(r.Context(), forkXrpcc, forkRepoId, hiddenRef, sourceBranch)
974
if err != nil {
975
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
976
+
log.Println("failed to call XRPC repo.compare for fork", xrpcerr)
977
+
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
978
+
return
979
+
}
980
log.Println("failed to compare across branches", err)
981
s.pages.Notice(w, "pull", err.Error())
982
return
983
}
984
985
+
var comparison types.RepoFormatPatchResponse
986
+
if err := json.Unmarshal(forkXrpcBytes, &comparison); err != nil {
987
+
log.Println("failed to decode XRPC compare response for fork", err)
988
+
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
989
+
return
990
+
}
991
+
992
sourceRev := comparison.Rev2
993
patch := comparison.Patch
994
···
1282
return
1283
}
1284
1285
+
scheme := "http"
1286
+
if !s.config.Core.Dev {
1287
+
scheme = "https"
1288
+
}
1289
+
host := fmt.Sprintf("%s://%s", scheme, f.Knot)
1290
+
xrpcc := &indigoxrpc.Client{
1291
+
Host: host,
1292
+
}
1293
+
1294
+
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
1295
+
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
1296
if err != nil {
1297
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1298
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
1299
+
s.pages.Error503(w)
1300
+
return
1301
+
}
1302
+
log.Println("failed to fetch branches", err)
1303
return
1304
}
1305
1306
+
var result types.RepoBranchesResponse
1307
+
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
1308
+
log.Println("failed to decode XRPC response", err)
1309
+
s.pages.Error503(w)
1310
return
1311
}
1312
···
1370
return
1371
}
1372
1373
+
sourceScheme := "http"
1374
+
if !s.config.Core.Dev {
1375
+
sourceScheme = "https"
1376
+
}
1377
+
sourceHost := fmt.Sprintf("%s://%s", sourceScheme, repo.Knot)
1378
+
sourceXrpcc := &indigoxrpc.Client{
1379
+
Host: sourceHost,
1380
+
}
1381
+
1382
+
sourceRepo := fmt.Sprintf("%s/%s", forkOwnerDid, repo.Name)
1383
+
sourceXrpcBytes, err := tangled.RepoBranches(r.Context(), sourceXrpcc, "", 0, sourceRepo)
1384
if err != nil {
1385
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1386
+
log.Println("failed to call XRPC repo.branches for source", xrpcerr)
1387
+
s.pages.Error503(w)
1388
+
return
1389
+
}
1390
+
log.Println("failed to fetch source branches", err)
1391
return
1392
}
1393
1394
+
// Decode source branches
1395
+
var sourceBranches types.RepoBranchesResponse
1396
+
if err := json.Unmarshal(sourceXrpcBytes, &sourceBranches); err != nil {
1397
+
log.Println("failed to decode source branches XRPC response", err)
1398
+
s.pages.Error503(w)
1399
return
1400
}
1401
1402
+
targetScheme := "http"
1403
+
if !s.config.Core.Dev {
1404
+
targetScheme = "https"
1405
+
}
1406
+
targetHost := fmt.Sprintf("%s://%s", targetScheme, f.Knot)
1407
+
targetXrpcc := &indigoxrpc.Client{
1408
+
Host: targetHost,
1409
+
}
1410
+
1411
+
targetRepo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
1412
+
targetXrpcBytes, err := tangled.RepoBranches(r.Context(), targetXrpcc, "", 0, targetRepo)
1413
if err != nil {
1414
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1415
+
log.Println("failed to call XRPC repo.branches for target", xrpcerr)
1416
+
s.pages.Error503(w)
1417
+
return
1418
+
}
1419
+
log.Println("failed to fetch target branches", err)
1420
return
1421
}
1422
1423
+
// Decode target branches
1424
+
var targetBranches types.RepoBranchesResponse
1425
+
if err := json.Unmarshal(targetXrpcBytes, &targetBranches); err != nil {
1426
+
log.Println("failed to decode target branches XRPC response", err)
1427
+
s.pages.Error503(w)
1428
return
1429
}
1430
1431
+
sort.Slice(sourceBranches.Branches, func(i int, j int) bool {
1432
+
return sourceBranches.Branches[i].Commit.Committer.When.After(sourceBranches.Branches[j].Commit.Committer.When)
1433
})
1434
1435
s.pages.PullCompareForkBranchesFragment(w, pages.PullCompareForkBranchesParams{
1436
RepoInfo: f.RepoInfo(user),
1437
+
SourceBranches: sourceBranches.Branches,
1438
+
TargetBranches: targetBranches.Branches,
1439
})
1440
}
1441
···
1530
return
1531
}
1532
1533
+
scheme := "http"
1534
+
if !s.config.Core.Dev {
1535
+
scheme = "https"
1536
+
}
1537
+
host := fmt.Sprintf("%s://%s", scheme, f.Knot)
1538
+
xrpcc := &indigoxrpc.Client{
1539
+
Host: host,
1540
}
1541
1542
+
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
1543
+
xrpcBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, pull.TargetBranch, pull.PullSource.Branch)
1544
if err != nil {
1545
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1546
+
log.Println("failed to call XRPC repo.compare", xrpcerr)
1547
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1548
+
return
1549
+
}
1550
log.Printf("compare request failed: %s", err)
1551
s.pages.Notice(w, "resubmit-error", err.Error())
1552
+
return
1553
+
}
1554
+
1555
+
var comparison types.RepoFormatPatchResponse
1556
+
if err := json.Unmarshal(xrpcBytes, &comparison); err != nil {
1557
+
log.Println("failed to decode XRPC compare response", err)
1558
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1559
return
1560
}
1561
···
1595
}
1596
1597
// extract patch by performing compare
1598
+
forkScheme := "http"
1599
+
if !s.config.Core.Dev {
1600
+
forkScheme = "https"
1601
+
}
1602
+
forkHost := fmt.Sprintf("%s://%s", forkScheme, forkRepo.Knot)
1603
+
forkRepoId := fmt.Sprintf("%s/%s", forkRepo.Did, forkRepo.Name)
1604
+
forkXrpcBytes, err := tangled.RepoCompare(r.Context(), &indigoxrpc.Client{Host: forkHost}, forkRepoId, pull.TargetBranch, pull.PullSource.Branch)
1605
if err != nil {
1606
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1607
+
log.Println("failed to call XRPC repo.compare for fork", xrpcerr)
1608
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1609
+
return
1610
+
}
1611
+
log.Printf("failed to compare branches: %s", err)
1612
+
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1613
+
return
1614
+
}
1615
+
1616
+
var forkComparison types.RepoFormatPatchResponse
1617
+
if err := json.Unmarshal(forkXrpcBytes, &forkComparison); err != nil {
1618
+
log.Println("failed to decode XRPC compare response for fork", err)
1619
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1620
return
1621
}
···
1651
return
1652
}
1653
1654
+
// Use the fork comparison we already made
1655
+
comparison := forkComparison
1656
1657
sourceRev := comparison.Rev2
1658
patch := comparison.Patch