repo commit-file acts on commit references !378
3 files changed, +35 −1
Layout: unified · split
.gitbay/wiki/Users.org +2 −1
| @@ -345,7 +345,8 @@ activity on their public repositories at =/you/activity.atom=. The | |||
| 345 | pages carry the discovery link. | 345 | pages carry the discovery link. |
| 346 | 346 | ||
| 347 | Commit messages act on issues when the commits land on the default | 347 | Commit messages act on issues when the commits land on the default |
| 348 | branch (direct push or MR merge): =closes/fixes/resolves #4= closes the | 348 | branch (direct push, MR merge, =repo commit-file= or the web editor): |
| 349 | =closes/fixes/resolves #4= closes the | ||
| 349 | issue with a linking comment, and a bare =#4= leaves a reference | 350 | issue with a linking comment, and a bare =#4= leaves a reference |
| 350 | comment. Each issue/commit pair acts once, ever. =Closes owner/name#N= closes an issue in another repository when | 351 | comment. Each issue/commit pair acts once, ever. =Closes owner/name#N= closes an issue in another repository when |
| 351 | you hold write there; otherwise it stays a plain link. The comment left | 352 | you hold write there; otherwise it stays a plain link. The comment left |
e2e/commitrefs_test.go +24
| @@ -109,4 +109,28 @@ func TestCommitMessageIssueActions(t *testing.T) { | |||
| 109 | if strings.Count(out, "referenced in commit") != 1 { | 109 | if strings.Count(out, "referenced in commit") != 1 { |
| 110 | t.Fatalf("reference duplicated: %s", out) | 110 | t.Fatalf("reference duplicated: %s", out) |
| 111 | } | 111 | } |
| 112 | |||
| 113 | // A commit written by repo commit-file (the web editor's path) lands | ||
| 114 | // on the default branch without receive-pack or a merge, and acts | ||
| 115 | // the same (#210). On another branch it does nothing. | ||
| 116 | if _, errOut, code := inst.ssh(t, aliceKey, "e\n", "repo", "commit-file", "alice/app", "e.txt", | ||
| 117 | "--ref", "feat", "--message", "'Closes #2 on a branch'", "--file", "-"); code != 0 { | ||
| 118 | t.Fatalf("commit-file on branch: %s", errOut) | ||
| 119 | } | ||
| 120 | out, _, _ = inst.ssh(t, aliceKey, "", "issue", "show", "alice/app", "2", "--json") | ||
| 121 | if !strings.Contains(out, `"state":"open"`) { | ||
| 122 | t.Fatalf("commit-file on a branch acted: %s", out) | ||
| 123 | } | ||
| 124 | if _, errOut, code := inst.ssh(t, aliceKey, "e\n", "repo", "commit-file", "alice/app", "e.txt", | ||
| 125 | "--ref", "main", "--message", "'Closes #2 from the editor'", "--file", "-"); code != 0 { | ||
| 126 | t.Fatalf("commit-file: %s", errOut) | ||
| 127 | } | ||
| 128 | out, _, _ = inst.ssh(t, aliceKey, "", "issue", "show", "alice/app", "2", "--json") | ||
| 129 | if !strings.Contains(out, `"state":"closed"`) || !strings.Contains(out, "closed by commit") || | ||
| 130 | !strings.Contains(out, "by [alice](/alice): Closes #2 from the editor") { | ||
| 131 | t.Fatalf("commit-file did not close issue 2: %s", out) | ||
| 132 | } | ||
| 133 | if strings.Count(out, "referenced in commit") != 1 { | ||
| 134 | t.Fatalf("commit-file re-acted on earlier commits: %s", out) | ||
| 135 | } | ||
| 112 | } | 136 | } |
internal/control/commitfile.go +9
| @@ -90,12 +90,21 @@ func runCommitFile(c *Ctx, args []string) int { | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | dir := RepoDir(c.Cfg.Server.Root, repo.OwnerName, repo.Name) | 92 | dir := RepoDir(c.Cfg.Server.Root, repo.OwnerName, repo.Name) |
| 93 | // The head before the commit bounds what landed; a branch that does | ||
| 94 | // not exist fails in CommitFileChange with its own message. | ||
| 95 | parent, _ := gitutil.ResolveRef(dir, "refs/heads/"+ref) | ||
| 93 | sha, err := gitutil.CommitFileChange(dir, ref, filePath, content, | 96 | sha, err := gitutil.CommitFileChange(dir, ref, filePath, content, |
| 94 | c.User.Username, email, message) | 97 | c.User.Username, email, message) |
| 95 | if err != nil { | 98 | if err != nil { |
| 96 | return c.fail(protocol.ExitFailure, "%v", err) | 99 | return c.fail(protocol.ExitFailure, "%v", err) |
| 97 | } | 100 | } |
| 98 | c.Store.MarkMirrorsDirty(repo.ID, "push") | 101 | c.Store.MarkMirrorsDirty(repo.ID, "push") |
| 102 | // This bypasses receive-pack like a merge does, so the commit-message | ||
| 103 | // issue actions (closes #N, references) run here for the default | ||
| 104 | // branch, with the session's scope (#210). | ||
| 105 | if ref == repo.DefaultBranch { | ||
| 106 | ProcessCommitMessages(c.Store, dir, repo, c.User.ID, c.Scope, parent, sha) | ||
| 107 | } | ||
| 99 | 108 | ||
| 100 | d := struct { | 109 | d := struct { |
| 101 | Path string `json:"path"` | 110 | Path string `json:"path"` |