~gitpocket/gitpocket

8

fix(pulls): hide the push notice once a branch has a merged or closed pull

commit
e3842ceec81f72b2c93afa6d77c9114a1b721e1b browse tree
parent
4f0c3accd8316881ee1f5aefa11105038b1589ba
author
~james <354576047+[email protected]>
signature
Signed by: ~james SHA256:KlzJ0P0gvJcnOYpaxD5yCUw52ImHttTKRjVAEnnYnKg
date
2026-11-14 14:53 UTC

4 files changed, +17 −6

forge/flow_test.go modified

@@ -373,6 +373,16 @@ func TestBranchPushAndPullMerge(t *testing.T) {
373373 if body := get(h, "/~alice/proj/pulls/1", own).Body.String(); !strings.Contains(strings.ToLower(body), "merged") {
374374 t.Error("pull request not shown as merged")
375375 }
376+ head, _ = g.Resolve(g.Head())
377+ topic := commitFile(t, g, "topic", head, "c.txt", "three\n")
378+ commitFile(t, g, "topic", topic, "d.txt", "four\n")
379+ post(h, "/~alice/proj/pulls/new", url.Values{"title": {"Add c"}, "source": {"~alice/proj:topic"}, "target": {g.Head()}}, own)
380+ if w := post(h, "/~alice/proj/pulls/2/merge", url.Values{"strategy": {"squash"}}, own); w.Code != http.StatusSeeOther {
381+ t.Fatalf("squash failed: %d", w.Code)
382+ }
383+ if strings.Contains(get(h, "/~alice/proj", own).Body.String(), `class="pushnote"`) {
384+ t.Error("notice still shown for a branch whose pull request was squashed")
385+ }
376386 }
377387
378388 func TestAppearance(t *testing.T) {

forge/pull.go modified

@@ -852,8 +852,8 @@ func (g Git) FastForward(target, head, baseRef string) (string, error) {
852852 return headHash, nil
853853 }
854854
855-func (s *Store) HasOpenPull(repo int64, branch string) bool {
855+func (s *Store) Proposed(repo int64, branch string, tip time.Time) bool {
856856 var n int
857- s.db.QueryRow(`select count(*) from pulls where repo = ? and source_repo = ? and source_branch = ? and state = 'open'`, repo, repo, branch).Scan(&n)
857+ s.db.QueryRow(`select count(*) from pulls where repo = ? and source_repo = ? and source_branch = ? and (state = 'open' or updated >= ?)`, repo, repo, branch, tip.Unix()).Scan(&n)
858858 return n > 0
859859 }

forge/web.go modified

@@ -1949,6 +1949,7 @@ func (rs refSet) branches() []Ref {
19491949 type pushedBranch struct {
19501950 Ref
19511951 Ahead int
1952+ Base string
19521953 }
19531954
19541955 func (s *Server) recentPushes(repo Repo, g Git, rp repoPage) []pushedBranch {
@@ -1961,12 +1962,12 @@ func (s *Server) recentPushes(repo Repo, g Git, rp repoPage) []pushedBranch {
19611962 if len(out) == 3 || time.Since(b.Time) > 72*time.Hour {
19621963 break
19631964 }
1964- if b.Name == head || s.store.HasOpenPull(repo.ID, b.Name) {
1965+ if b.Name == head || s.store.Proposed(repo.ID, b.Name, b.Time) {
19651966 continue
19661967 }
1967- n, err := g.run(nil, "rev-list", "--count", "--end-of-options", "refs/heads/"+head+"..refs/heads/"+b.Name)
1968+ n, err := g.run(nil, "rev-list", "--count", "--right-only", "--cherry-pick", "--end-of-options", "refs/heads/"+head+"...refs/heads/"+b.Name)
19681969 if ahead, _ := strconv.Atoi(strings.TrimSpace(string(n))); err == nil && ahead > 0 {
1969- out = append(out, pushedBranch{b, ahead})
1970+ out = append(out, pushedBranch{b, ahead, head})
19701971 }
19711972 }
19721973 return out

web/templates/meta.tmpl modified

@@ -11,7 +11,7 @@
1111 {{define "who"}}{{with account .}}<a href="/~{{.}}" title="{{$.Author}}">~{{.}}</a>{{else}}{{.Author}}{{end}}{{end}}
1212 {{define "repoitem"}}<div class="event repo"><h4><a href="/{{.Path}}">{{.Name}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/search?q=tag:{{.}}">#{{.}}</a> {{end}}</p>{{end}}{{template "repometa" .}}</div>{{end}}
1313 {{define "repometa"}}{{$l := lang .}}<p class="repometa">{{with $l.Name}}<span><i class="dot" style="background:{{$l.Colour}}"></i>{{.}}</span>{{end}}<span title="{{.Stars}} star{{if ne .Stars 1}}s{{end}}"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="M8 1.6l1.9 4 4.4.5-3.3 3 .9 4.3L8 11.2 4.1 13.4l.9-4.3-3.3-3 4.4-.5z"/></svg>{{.Stars}}</span><span title="{{.Forks}} fork{{if ne .Forks 1}}s{{end}}"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="4" cy="3" r="1.6"/><circle cx="12" cy="3" r="1.6"/><circle cx="8" cy="13" r="1.6"/><path d="M4 4.6v1.4a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V4.6M8 8v3.4"/></svg>{{.Forks}}</span></p>{{end}}
14-{{define "pushed"}}{{$p := .Page}}{{range .Pushed}}<div class="pushnote"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="4" cy="3" r="1.6"/><circle cx="4" cy="13" r="1.6"/><circle cx="12" cy="5" r="1.6"/><path d="M4 4.6v6.8M12 6.6c0 3-4 2.6-7.4 5.2"/></svg><span><strong>{{.Name}}</strong> had recent pushes {{ago .Time}}, {{.Ahead}} commit{{if ne .Ahead 1}}s{{end}} ahead of {{$p.Ref}}</span><a class="btn primary" href="/{{$p.Repo.Path}}/pulls/new?source={{$p.Repo.Path}}:{{.Name}}&amp;target={{$p.Ref}}">Open pull request ▸</a></div>{{end}}{{end}}
14+{{define "pushed"}}{{$p := .Page}}{{range .Pushed}}<div class="pushnote"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="4" cy="3" r="1.6"/><circle cx="4" cy="13" r="1.6"/><circle cx="12" cy="5" r="1.6"/><path d="M4 4.6v6.8M12 6.6c0 3-4 2.6-7.4 5.2"/></svg><span><strong>{{.Name}}</strong> was pushed {{ago .Time}} and is {{.Ahead}} commit{{if ne .Ahead 1}}s{{end}} ahead of {{.Base}}</span><a class="btn primary" href="/{{$p.Repo.Path}}/pulls/new?source={{$p.Repo.Path}}:{{.Name}}&amp;target={{.Base}}">Open pull request</a></div>{{end}}{{end}}
1515 {{define "lock"}}<svg class="lock" viewBox="0 0 16 16" aria-hidden="true"><path d="M4 7V5a4 4 0 0 1 8 0v2h.5A1.5 1.5 0 0 1 14 8.5v5a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 13.5v-5A1.5 1.5 0 0 1 3.5 7H4zm1.5 0h5V5a2.5 2.5 0 0 0-5 0v2z"/></svg>{{end}}
1616 {{define "seal"}}{{with signer .}}<span class="seal ok" title="Signed with a key registered by ~{{.}}">{{template "lock"}}<img src="/~{{.}}/avatar" alt="~{{.}}"></span>{{else}}{{if and .Signature (ne .Signature "N")}}<span class="seal" title="Signed with an unregistered key">{{template "lock"}}</span>{{end}}{{end}}{{end}}
1717 {{define "gistbody"}}{{if .Image}}<div class="media"><img src="{{.Raw}}" alt="{{.Name}}"></div>{{else if .Binary}}<p class="muted gistnote">Binary file, <a href="{{.Raw}}">view raw</a>.</p>{{else if .Large}}<p class="muted gistnote">File too large to display, <a href="{{.Raw}}">view raw</a>.</p>{{else if .Markdown}}<article class="readme gistmd">{{.Markdown}}</article>{{else if .Highlighted}}<div class="code">{{.Highlighted}}</div>{{else}}<div class="code"><table class="blob">{{range $i, $l := lines .Content}}<tr><td class="n">{{inc $i}}</td><td class="l">{{$l}}</td></tr>{{end}}</table></div>{{end}}{{end}}