woof2

7387a13 · gmorell · 2026-05-15 04:48

1 files +21 -1

Files changed

modified lib/git_gud/repositories.ex
+21 −1
@@ -26,10 +26,16 @@ defmodule GitGud.Repositories do
26 26
27 27 # ── repository lifecycle ─────────────────────────────────────────────
28 28
29 @doc "List repositories visible to the given scope."
29 + @doc """
30 + List repositories visible to the given scope. Filters out same-name
31 + profile-README repos (`alice/alice`, `acme/acme`) so the global
32 + listing doesn't get cluttered with them — they're still reachable
33 + via the owner's profile page.
34 + """
30 35 def list_repositories(%Scope{user: %User{id: uid}}) do
31 36 Repository
32 37 |> where([r], r.owner_id == ^uid or r.visibility in ["public", "internal"])
38 + |> without_profile_repos()
33 39 |> order_by([r], desc: r.pushed_at, asc: r.name)
34 40 |> Repo.all()
35 41 end
@@ -37,10 +43,24 @@ defmodule GitGud.Repositories do
37 43 def list_repositories(nil) do
38 44 Repository
39 45 |> where([r], r.visibility == "public")
46 + |> without_profile_repos()
40 47 |> order_by([r], asc: r.name)
41 48 |> Repo.all()
42 49 end
43 50
51 + # A repo is the same-name profile repo when its `name` matches its
52 + # namespace's handle. For org-owned repos that's the org's handle;
53 + # for user-owned (no org) that's the user's handle. The COALESCE
54 + # picks whichever is non-null.
55 + defp without_profile_repos(query) do
56 + from r in query,
57 + left_join: u in User,
58 + on: u.id == r.owner_id and is_nil(r.organization_id),
59 + left_join: o in GitGud.Organizations.Organization,
60 + on: o.id == r.organization_id,
61 + where: r.name != coalesce(o.handle, u.handle)
62 + end
63 +
44 64 def get_repository!(id), do: Repo.get!(Repository, id)
45 65
46 66 @doc "List repos owned by a user or organization, namespaced view."

Parents: 37d7949