aboutsummaryrefslogtreecommitdiff
path: root/git-codereview/branch.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2021-01-07 12:26:06 -0500
committerRuss Cox <rsc@golang.org>2021-01-13 14:40:05 +0000
commitfdc5e6a4e6b93c6381d20cf1dfbfaa49f420a43d (patch)
tree50b026373387e0ea57d83ac46e80d27a906a13de /git-codereview/branch.go
parent4aa052da7f65ad6eeb77cce14ef70dac82d242cc (diff)
downloadgo-x-review-fdc5e6a4e6b93c6381d20cf1dfbfaa49f420a43d.tar.xz
git-codereview: add reword command
Quoting the new docs: The reword command edits pending commit messages. git codereview reword [commit...] Reword opens the editor on the commit message for each named commit in turn. When all the editing is finished, it applies the changes to the pending commits. If no commit is listed, reword applies to the most recent pending commit. Reword is similar in effect to running “git codereview rebase-work” and changing the script action for the named commits to “reword”, or (with no arguments) to “git commit --amend”, but it only affects the commit messages, not the state of the git staged index, nor any checked-out files. This more careful implementation makes it safe to use when there are local changes or, for example, when tests are running that would be broken by temporary changes to the checked-out tree, as would happen during “git codereview rebase-work”. Change-Id: I38ac939b8530bf237c6cafb911f2b17d22eaca60 Reviewed-on: https://go-review.googlesource.com/c/review/+/279718 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'git-codereview/branch.go')
-rw-r--r--git-codereview/branch.go71
1 files changed, 46 insertions, 25 deletions
diff --git a/git-codereview/branch.go b/git-codereview/branch.go
index 787a80d..5d277c8 100644
--- a/git-codereview/branch.go
+++ b/git-codereview/branch.go
@@ -33,13 +33,18 @@ type Branch struct {
// A Commit describes a single pending commit on a Git branch.
type Commit struct {
- Hash string // commit hash
- ShortHash string // abbreviated commit hash
- Parent string // parent hash
- Merge string // for merges, hash of commit being merged into Parent
- Message string // commit message
- Subject string // first line of commit message
- ChangeID string // Change-Id in commit message ("" if missing)
+ Hash string // commit hash
+ ShortHash string // abbreviated commit hash
+ Parent string // parent hash (== Parents[0])
+ Parents []string // all parent hashes (merges have > 1)
+ Tree string // tree hash
+ Message string // commit message
+ Subject string // first line of commit message
+ ChangeID string // Change-Id in commit message ("" if missing)
+
+ AuthorName string // author name (from %an)
+ AuthorEmail string // author email (from %ae)
+ AuthorDate string // author date as Unix timestamp string (from %at)
// For use by pending command.
g *GerritChange // associated Gerrit change data
@@ -47,6 +52,16 @@ type Commit struct {
committed []string // list of files in this commit
}
+// HasParent reports whether hash appears in c.Parents.
+func (c *Commit) HasParent(hash string) bool {
+ for _, p := range c.Parents {
+ if p == hash {
+ return true
+ }
+ }
+ return false
+}
+
// Config returns the configuration for the branch.
func (b *Branch) Config() map[string]string {
if b.config != nil {
@@ -227,8 +242,10 @@ func (b *Branch) loadPending() {
// Note: --topo-order means child first, then parent.
origin := b.OriginBranch()
- const numField = 5
- all := trim(cmdOutput("git", "log", "--topo-order", "--format=format:%H%x00%h%x00%P%x00%B%x00%s%x00", origin+".."+b.FullName(), "--"))
+ const numField = 9
+ all := trim(cmdOutput("git", "log", "--topo-order",
+ "--format=format:%H%x00%h%x00%P%x00%T%x00%B%x00%s%x00%an%x00%ae%x00%at%x00",
+ origin+".."+b.FullName(), "--"))
fields := strings.Split(all, "\x00")
if len(fields) < numField {
return // nothing pending
@@ -236,16 +253,23 @@ func (b *Branch) loadPending() {
for i, field := range fields {
fields[i] = strings.TrimLeft(field, "\r\n")
}
+Log:
for i := 0; i+numField <= len(fields); i += numField {
+ parents := strings.Fields(fields[i+2])
c := &Commit{
- Hash: fields[i],
- ShortHash: fields[i+1],
- Parent: strings.TrimSpace(fields[i+2]), // %P starts with \n for some reason
- Message: fields[i+3],
- Subject: fields[i+4],
+ Hash: fields[i],
+ ShortHash: fields[i+1],
+ Parent: parents[0],
+ Parents: parents,
+ Tree: fields[i+3],
+ Message: fields[i+4],
+ Subject: fields[i+5],
+ AuthorName: fields[i+6],
+ AuthorEmail: fields[i+7],
+ AuthorDate: fields[i+8],
}
- if j := strings.Index(c.Parent, " "); j >= 0 {
- c.Parent, c.Merge = c.Parent[:j], c.Parent[j+1:]
+
+ if len(c.Parents) > 1 {
// Found merge point.
// Merges break the invariant that the last shared commit (the branchpoint)
// is the parent of the final commit in the log output.
@@ -254,15 +278,12 @@ func (b *Branch) loadPending() {
// even if we later see additional commits on a different branch leading down to
// a lower location on the same origin branch.
// Check c.Merge (the second parent) too, so we don't depend on the parent order.
- if strings.Contains(cmdOutput("git", "branch", "-a", "--contains", c.Parent), " remotes/"+origin+"\n") {
- b.pending = append(b.pending, c)
- b.branchpoint = c.Parent
- break
- }
- if strings.Contains(cmdOutput("git", "branch", "-a", "--contains", c.Merge), " remotes/"+origin+"\n") {
- b.pending = append(b.pending, c)
- b.branchpoint = c.Merge
- break
+ for _, parent := range c.Parents {
+ if strings.Contains(cmdOutput("git", "branch", "-a", "--contains", parent), " remotes/"+origin+"\n") {
+ b.pending = append(b.pending, c)
+ b.branchpoint = parent
+ break Log
+ }
}
}
for _, line := range lines(c.Message) {