/
plan.go
81 lines (71 loc) · 2.24 KB
/
plan.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package reorder
import (
"emperror.dev/errors"
"github.com/aviator-co/av/internal/git"
"github.com/aviator-co/av/internal/meta"
)
// CreatePlan creates a reorder plan for the stack rooted at rootBranch.
func CreatePlan(repo *git.Repo, tx meta.ReadTx, rootBranch string) ([]Cmd, error) {
var cmds []Cmd
branchNames := []string{rootBranch}
branchNames = append(branchNames, meta.SubsequentBranches(tx, rootBranch)...)
for _, branchName := range branchNames {
branch, _ := tx.Branch(branchName)
branchCmd := StackBranchCmd{
Name: branchName,
}
// Need to figure out the upstream commit to figure out the list of
// commits associated with this branch.
var upstreamCommit string
// TODO: would be nice to show the user whether or not the branch is
// already up-to-date with the parent.
if branch.Parent.Head != "" {
branchCmd.Parent = branch.Parent.Name
upstreamCommit = branch.Parent.Head
} else {
trunkCommit, err := repo.MergeBase(&git.MergeBase{
Revs: []string{branchName, branch.Parent.Name},
})
if err != nil {
return nil, err
}
branchCmd.Trunk = branch.Parent.Name + "@" + trunkCommit
upstreamCommit = trunkCommit
}
// Figure out the commits that belong to this branch.
// We'll use this to generate a "pick" command for each commit.
commitIDs, err := repo.RevList(git.RevListOpts{
Specifiers: []string{branchName, "^" + upstreamCommit},
Reverse: true,
})
if err != nil {
return nil, err
}
// If no commits associated with this branch, bail out early and add a
// helpful comment for the user.
if len(commitIDs) == 0 {
branchCmd.Comment = "this branch has no commits"
cmds = append(cmds, branchCmd)
continue
}
commitObjects, err := repo.GetRefs(&git.GetRefs{
Revisions: commitIDs,
})
if err != nil {
return nil, err
}
// Append the "stack-branch" command and each "pick" command to the plan
cmds = append(cmds, branchCmd)
for _, object := range commitObjects {
commit, err := git.ParseCommitContents(object.Contents)
if err != nil {
return nil, errors.WrapIff(err, "parsing commit %s", object.OID)
}
cmds = append(cmds, PickCmd{
Commit: git.ShortSha(object.OID),
Comment: commit.MessageTitle(),
})
}
}
return cmds, nil
}