@@ -17,8 +17,10 @@ package cmd
1717import (
1818 "fmt"
1919 "os"
20+ "strings"
2021
2122 "github.com/pfnet-research/git-ghost/pkg/ghost"
23+ "github.com/pfnet-research/git-ghost/pkg/ghost/git"
2224 "github.com/pfnet-research/git-ghost/pkg/ghost/types"
2325 "github.com/pfnet-research/git-ghost/pkg/util/errors"
2426
@@ -43,7 +45,7 @@ func NewPushCommand() *cobra.Command {
4345 Short : "push commits(hash1...hash2), diff(hash...current state) to your ghost repo" ,
4446 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." ,
4547 Args : cobra .RangeArgs (0 , 1 ),
46- Run : runPushDiffCommand (& flags ),
48+ Run : runPushCommitsCommand (& flags ),
4749 }
4850 command .AddCommand (& cobra.Command {
4951 Use : "commits [from-hash] [to-hash(default=HEAD)]" ,
@@ -73,6 +75,32 @@ func NewPushCommand() *cobra.Command {
7375 return command
7476}
7577
78+ func getFirstRemoteAncestorCommit (commit string ) (string , errors.GitGhostError ) {
79+ dir := globalOpts .srcDir
80+ for {
81+ branchNames , err := git .GetRemoteBranchesContainingCommit (dir , commit )
82+ if err != nil {
83+ return "" , err
84+ }
85+ var originBranchNames []string
86+ for _ , branchName := range branchNames {
87+ if strings .HasPrefix (branchName , fmt .Sprintf ("refs/remotes/%s/" , git .ORIGIN )) {
88+ originBranchNames = append (originBranchNames , branchName )
89+ }
90+ }
91+ if len (originBranchNames ) > 0 {
92+ // This commit is the first ancestor commit in the origin remote.
93+ break
94+ }
95+ parentCommit , err := git .GetParentCommit (dir , commit )
96+ if err != nil {
97+ return "" , err
98+ }
99+ commit = parentCommit
100+ }
101+ return commit , nil
102+ }
103+
76104type pushCommitsArg struct {
77105 commitsFrom string
78106 commitsTo string
@@ -111,6 +139,16 @@ func (arg pushCommitsArg) validate() errors.GitGhostError {
111139func runPushCommitsCommand (flags * pushFlags ) func (cmd * cobra.Command , args []string ) {
112140 return func (cmd * cobra.Command , args []string ) {
113141 pushArg := newPushCommitsArg (args )
142+
143+ // If commitsFrom is not given, find the first ancestor commit that is included in the origin remote.
144+ if pushArg .commitsFrom == "" {
145+ commitsFrom , err := getFirstRemoteAncestorCommit (pushArg .commitsTo )
146+ if err != nil {
147+ errors .LogErrorWithStack (err )
148+ os .Exit (1 )
149+ }
150+ pushArg .commitsFrom = commitsFrom
151+ }
114152 if err := pushArg .validate (); err != nil {
115153 errors .LogErrorWithStack (err )
116154 os .Exit (1 )
0 commit comments