Skip to content

Commit 0b2d042

Browse files
committed
push: Resolve from commit
1 parent 9c3a136 commit 0b2d042

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

cmd/push.go

+32-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"os"
2020

2121
"github.com/pfnet-research/git-ghost/pkg/ghost"
22+
"github.com/pfnet-research/git-ghost/pkg/ghost/git"
2223
"github.com/pfnet-research/git-ghost/pkg/ghost/types"
2324
"github.com/pfnet-research/git-ghost/pkg/util/errors"
2425

@@ -43,7 +44,7 @@ func NewPushCommand() *cobra.Command {
4344
Short: "push commits(hash1...hash2), diff(hash...current state) to your ghost repo",
4445
Long: "push commits or diff or all to your ghost repo. If you didn't specify any subcommand, this commands works as an alias for 'push diff' command.",
4546
Args: cobra.RangeArgs(0, 1),
46-
Run: runPushDiffCommand(&flags),
47+
Run: runPushCommitsCommand(&flags),
4748
}
4849
command.AddCommand(&cobra.Command{
4950
Use: "commits [from-hash] [to-hash(default=HEAD)]",
@@ -73,6 +74,26 @@ func NewPushCommand() *cobra.Command {
7374
return command
7475
}
7576

77+
func getFirstRemoteAncestorCommit(commit string) (string, errors.GitGhostError) {
78+
dir := globalOpts.srcDir
79+
for {
80+
branchNames, err := git.GetRemoteBranchesContainingCommit(dir, commit)
81+
if err != nil {
82+
return "", err
83+
}
84+
if len(branchNames) > 0 {
85+
// This commit is the first ancestor commit in any of remotes.
86+
break
87+
}
88+
parentCommit, err := git.GetParentCommit(dir, commit)
89+
if err != nil {
90+
return "", err
91+
}
92+
commit = parentCommit
93+
}
94+
return commit, nil
95+
}
96+
7697
type pushCommitsArg struct {
7798
commitsFrom string
7899
commitsTo string
@@ -111,6 +132,16 @@ func (arg pushCommitsArg) validate() errors.GitGhostError {
111132
func runPushCommitsCommand(flags *pushFlags) func(cmd *cobra.Command, args []string) {
112133
return func(cmd *cobra.Command, args []string) {
113134
pushArg := newPushCommitsArg(args)
135+
136+
// If commitsFrom is not given, find the first ancestor commit that is included in any of remotes.
137+
if pushArg.commitsFrom == "" {
138+
commitsFrom, err := getFirstRemoteAncestorCommit(pushArg.commitsTo)
139+
if err != nil {
140+
errors.LogErrorWithStack(err)
141+
os.Exit(1)
142+
}
143+
pushArg.commitsFrom = commitsFrom
144+
}
114145
if err := pushArg.validate(); err != nil {
115146
errors.LogErrorWithStack(err)
116147
os.Exit(1)

pkg/ghost/git/repo.go

+26
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package git
1616

1717
import (
18+
"bytes"
1819
"fmt"
1920
"os/exec"
2021
"strings"
@@ -146,3 +147,28 @@ func ResetHardToBranch(dir, branch string) errors.GitGhostError {
146147
exec.Command("git", "-C", dir, "reset", "--hard", branch),
147148
)
148149
}
150+
151+
// GetParentCommit returns the parent commit of the given commit
152+
func GetParentCommit(dir, commit string) (string, errors.GitGhostError) {
153+
resultBytes, err := util.JustOutputCmd(exec.Command("git", "-C", dir, "rev-parse", fmt.Sprintf("%s^", commit)))
154+
if err != nil {
155+
return "", errors.WithStack(gherrors.WithMessage(err, "failed to get the parent commit of a commit"))
156+
}
157+
return strings.TrimSuffix(string(resultBytes), "\n"), nil
158+
}
159+
160+
// GetRemoteBranchesContainingCommit returns a slice of remote branch names each of which contain the given commit
161+
func GetRemoteBranchesContainingCommit(dir, commit string) ([]string, errors.GitGhostError) {
162+
resultBytes, err := util.JustOutputCmd(exec.Command("git", "-C", dir, "branch", "--no-color", "--format", "%(refname)", "--remotes", "--contains", commit))
163+
if err != nil {
164+
return nil, errors.WithStack(gherrors.WithMessage(err, "failed to get remote branches containing a commit"))
165+
}
166+
var branchNames []string
167+
for _, line := range bytes.Split(resultBytes, []byte("\n")) {
168+
branchName := string(line)
169+
if len(branchName) > 0 {
170+
branchNames = append(branchNames, string(line))
171+
}
172+
}
173+
return branchNames, nil
174+
}

0 commit comments

Comments
 (0)