1
1
package git
2
2
3
3
import (
4
+ "fmt"
4
5
"os"
5
6
"path/filepath"
6
7
"regexp"
@@ -10,23 +11,26 @@ import (
10
11
)
11
12
12
13
const (
13
- cmdRootPath = "git rev-parse --show-toplevel"
14
- cmdHooksPath = "git rev-parse --git-path hooks"
15
- cmdInfoPath = "git rev-parse --git-path info"
16
- cmdGitPath = "git rev-parse --git-dir"
17
- cmdStagedFiles = "git diff --name-only --cached --diff-filter=ACMR"
18
- cmdAllFiles = "git ls-files --cached"
19
- cmdPushFiles = "git diff --name-only HEAD @{push} || git diff --name-only HEAD master"
20
- cmdStatusShort = "git status --short"
21
- cmdCreateStash = "git stash create"
22
- cmdListStash = "git stash list"
14
+ cmdRootPath = "git rev-parse --show-toplevel"
15
+ cmdHooksPath = "git rev-parse --git-path hooks"
16
+ cmdInfoPath = "git rev-parse --git-path info"
17
+ cmdGitPath = "git rev-parse --git-dir"
18
+ cmdStagedFiles = "git diff --name-only --cached --diff-filter=ACMR"
19
+ cmdAllFiles = "git ls-files --cached"
20
+ cmdPushFilesBase = "git diff --name-only HEAD @{push}"
21
+ cmdPushFilesHead = "git diff --name-only HEAD %s"
22
+ cmdStatusShort = "git status --short"
23
+ cmdCreateStash = "git stash create"
24
+ cmdListStash = "git stash list"
23
25
24
26
stashMessage = "lefthook auto backup"
25
27
unstagedPatchName = "lefthook-unstaged.patch"
26
28
infoDirMode = 0o775
27
29
minStatusLen = 3
28
30
)
29
31
32
+ var headBranchRegexp = regexp .MustCompile (`HEAD -> (?P<name>.*)$` )
33
+
30
34
// Repository represents a git repository.
31
35
type Repository struct {
32
36
Fs afero.Fs
@@ -36,6 +40,7 @@ type Repository struct {
36
40
GitPath string
37
41
InfoPath string
38
42
unstagedPatchPath string
43
+ headBranch string
39
44
}
40
45
41
46
// NewRepository returns a Repository or an error, if git repository it not initialized.
@@ -99,7 +104,27 @@ func (r *Repository) AllFiles() ([]string, error) {
99
104
// PushFiles returns a list of files that are ready to be pushed
100
105
// or an error if git command fails.
101
106
func (r * Repository ) PushFiles () ([]string , error ) {
102
- return r .FilesByCommand (cmdPushFiles )
107
+ res , err := r .FilesByCommand (cmdPushFilesBase )
108
+ if err == nil {
109
+ return res , nil
110
+ }
111
+
112
+ if len (r .headBranch ) == 0 {
113
+ branches , err := r .Git .CmdLines ("git branch --remotes" )
114
+ if err != nil {
115
+ return nil , err
116
+ }
117
+ for _ , branch := range branches {
118
+ if ! headBranchRegexp .MatchString (branch ) {
119
+ continue
120
+ }
121
+
122
+ matches := headBranchRegexp .FindStringSubmatch (branch )
123
+ r .headBranch = matches [headBranchRegexp .SubexpIndex ("name" )]
124
+ break
125
+ }
126
+ }
127
+ return r .FilesByCommand (fmt .Sprintf (cmdPushFilesHead , r .headBranch ))
103
128
}
104
129
105
130
// PartiallyStagedFiles returns the list of files that have both staged and
0 commit comments