Skip to content

Commit 9715e28

Browse files
committed
Filter upstream PR rows that already match main
1 parent f1b75fb commit 9715e28

2 files changed

Lines changed: 130 additions & 1 deletion

File tree

internal/remote/dolthub.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,12 +1040,63 @@ func (d *DoltHubProvider) ListPendingWantedIDs(upstreamOrg, db string) (map[stri
10401040
wg.Wait()
10411041
close(diffCh)
10421042

1043-
ids := make(map[string][]PendingWantedState)
1043+
branchResults := make([]pendingBranchRows, 0, len(branchPRs))
1044+
compareIDs := make(map[string]struct{})
10441045
for result := range diffCh {
10451046
if result.err != nil {
10461047
return nil, result.err
10471048
}
1049+
branchResults = append(branchResults, result)
1050+
if result.source.branch == "main" {
1051+
continue
1052+
}
1053+
for _, row := range result.rows {
1054+
if row.wantedID != "" {
1055+
compareIDs[row.wantedID] = struct{}{}
1056+
}
1057+
}
1058+
}
1059+
1060+
if len(compareIDs) > 0 && upstreamItems == nil {
1061+
wantedIDs := make([]string, 0, len(compareIDs))
1062+
for wantedID := range compareIDs {
1063+
wantedIDs = append(wantedIDs, wantedID)
1064+
}
1065+
slices.Sort(wantedIDs)
1066+
quotedIDs := make([]string, 0, len(wantedIDs))
1067+
for _, wantedID := range wantedIDs {
1068+
quotedIDs = append(quotedIDs, fmt.Sprintf("'%s'", strings.ReplaceAll(wantedID, "'", "''")))
1069+
}
1070+
upstreamItems = make(map[string]wantedItem, len(wantedIDs))
1071+
upstreamCompareQuery := fmt.Sprintf(
1072+
"SELECT id, status, COALESCE(claimed_by, '') as claimed_by FROM wanted WHERE id IN (%s)",
1073+
strings.Join(quotedIDs, ","),
1074+
)
1075+
upstreamURL := fmt.Sprintf("%s/%s/%s/main?q=%s",
1076+
dolthubAPIBase, upstreamOrg, db, url.QueryEscape(upstreamCompareQuery))
1077+
body, err := d.dolthubGet(upstreamURL)
1078+
if err == nil {
1079+
var qr queryResponse
1080+
if json.Unmarshal(body, &qr) == nil {
1081+
for _, row := range qr.Rows {
1082+
upstreamItems[row["id"]] = wantedItem{
1083+
status: row["status"],
1084+
claimedBy: row["claimed_by"],
1085+
}
1086+
}
1087+
}
1088+
}
1089+
}
1090+
1091+
ids := make(map[string][]PendingWantedState)
1092+
for _, result := range branchResults {
10481093
for _, row := range result.rows {
1094+
if result.source.branch != "main" {
1095+
if upstream, exists := upstreamItems[row.wantedID]; exists &&
1096+
upstream.status == row.status && upstream.claimedBy == row.claimedBy {
1097+
continue
1098+
}
1099+
}
10491100
for _, pr := range branchPRs[result.source] {
10501101
branchURL := fmt.Sprintf("%s/%s/%s/data/%s",
10511102
dolthubRepoBase, result.source.owner, db, url.PathEscape(pr.fromBranch))

internal/remote/dolthub_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,84 @@ func TestDoltHubProvider_ListPendingWantedIDs_NonStandardBranch(t *testing.T) {
18621862
}
18631863
}
18641864

1865+
func TestDoltHubProvider_ListPendingWantedIDs_FiltersRowsMatchingUpstreamMain(t *testing.T) {
1866+
mux := http.NewServeMux()
1867+
mux.HandleFunc("/org/db/pulls", func(w http.ResponseWriter, r *http.Request) {
1868+
if strings.Contains(r.URL.Path, "/pulls/") {
1869+
return
1870+
}
1871+
w.Header().Set("Content-Type", "application/json")
1872+
_ = json.NewEncoder(w).Encode(map[string]any{
1873+
"pulls": []map[string]any{{"pull_id": "1", "state": "open"}},
1874+
})
1875+
})
1876+
mux.HandleFunc("/org/db/pulls/1", func(w http.ResponseWriter, _ *http.Request) {
1877+
w.Header().Set("Content-Type", "application/json")
1878+
_ = json.NewEncoder(w).Encode(map[string]any{
1879+
"from_branch": "wl/bob/w-real",
1880+
"from_branch_owner": "bob-fork",
1881+
"author": "bob",
1882+
})
1883+
})
1884+
mux.HandleFunc("/org/db/main", func(w http.ResponseWriter, r *http.Request) {
1885+
w.Header().Set("Content-Type", "application/json")
1886+
q := r.URL.Query().Get("q")
1887+
if !strings.Contains(q, "'w-open'") || !strings.Contains(q, "'w-same-claim'") || !strings.Contains(q, "'w-real'") {
1888+
t.Fatalf("upstream comparison query missing wanted IDs: %s", q)
1889+
}
1890+
_ = json.NewEncoder(w).Encode(map[string]any{
1891+
"rows": []map[string]string{
1892+
{"id": "w-open", "status": "open", "claimed_by": ""},
1893+
{"id": "w-same-claim", "status": "claimed", "claimed_by": "alice"},
1894+
{"id": "w-real", "status": "open", "claimed_by": ""},
1895+
},
1896+
})
1897+
})
1898+
mux.HandleFunc("/bob-fork/db/", func(w http.ResponseWriter, r *http.Request) {
1899+
w.Header().Set("Content-Type", "application/json")
1900+
if strings.Contains(r.URL.Query().Get("q"), "FROM completions") {
1901+
_ = json.NewEncoder(w).Encode(map[string]any{"rows": []map[string]string{}})
1902+
return
1903+
}
1904+
_ = json.NewEncoder(w).Encode(map[string]any{
1905+
"rows": []map[string]string{
1906+
{"id": "w-open", "status": "open", "claimed_by": "", "diff_type": "added"},
1907+
{"id": "w-same-claim", "status": "claimed", "claimed_by": "alice", "diff_type": "modified"},
1908+
{"id": "w-real", "status": "claimed", "claimed_by": "bob", "diff_type": "modified"},
1909+
},
1910+
})
1911+
})
1912+
1913+
server := httptest.NewServer(mux)
1914+
defer server.Close()
1915+
oldAPIBase, oldRepoBase := dolthubAPIBase, dolthubRepoBase
1916+
dolthubAPIBase = server.URL
1917+
dolthubRepoBase = server.URL + "/repositories"
1918+
defer func() {
1919+
dolthubAPIBase = oldAPIBase
1920+
dolthubRepoBase = oldRepoBase
1921+
}()
1922+
1923+
provider := NewDoltHubProvider("token")
1924+
ids, err := provider.ListPendingWantedIDs("org", "db")
1925+
if err != nil {
1926+
t.Fatalf("ListPendingWantedIDs() error: %v", err)
1927+
}
1928+
1929+
if len(ids) != 1 {
1930+
t.Fatalf("expected 1 pending ID after upstream filtering, got %d: %+v", len(ids), ids)
1931+
}
1932+
if _, ok := ids["w-open"]; ok {
1933+
t.Fatalf("w-open should be filtered as identical to upstream: %+v", ids["w-open"])
1934+
}
1935+
if _, ok := ids["w-same-claim"]; ok {
1936+
t.Fatalf("w-same-claim should be filtered as identical to upstream: %+v", ids["w-same-claim"])
1937+
}
1938+
if pending := ids["w-real"]; len(pending) != 1 || pending[0].RigHandle != "bob" || pending[0].Status != "claimed" {
1939+
t.Fatalf("w-real pending = %+v, want only the real branch-owned change", pending)
1940+
}
1941+
}
1942+
18651943
func TestDoltHubProvider_ListPendingWantedIDs_PRFromMain(t *testing.T) {
18661944
mux := http.NewServeMux()
18671945
mux.HandleFunc("/org/db/pulls", func(w http.ResponseWriter, r *http.Request) {

0 commit comments

Comments
 (0)