This repository was archived by the owner on Sep 11, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 534
This repository was archived by the owner on Sep 11, 2020. It is now read-only.
plumbing.Reference.IsBranch is not working well on windows #462
Copy link
Copy link
Closed
Description
To Reproduce the problem
- Create some branches
> git branch
master
some_features
- Execute below code.
r, _ := git.PlainOpen(".")
refs, _ := r.References()
refs.ForEach(func(ref *plumbing.Reference) error {
fmt.Println(ref.Name(), ref.IsBranch())
return nil
})
Expected behavior
refs\heads\some_features true
refs\heads\master true
refs\remotes\origin\HEAD false
refs\remotes\origin\some_features false
refs\remotes\origin\master false
HEAD false
IsBranch()
should return true if reference name is "master" or "some_features".
Actual behavior
refs/remotes/origin/master false
refs\heads\some_features false
refs\heads\master false
refs\remotes\origin\HEAD false
refs\remotes\origin\some_features false
refs\remotes\origin\master false
HEAD false
There are two problems.
- Path separators "/" and "\" are mixed
refs\heads\master
andrefs\heads\some_features
are branch but IsBranch() return false
Cause of problems
Cause of the path separators are mixed
If reference is retrieved from refs/heads
, refs/remotes
and refs/tags
, path separator is determined by DotGit.fs.Join
when read reference path.
So path separator will be "\" on windows.
dotgit.go 468
func (d *DotGit) readReferenceFile(refsPath, refFile string) (ref *plumbing.Reference, err error) {
path := d.fs.Join(refsPath, refFile)
But if reference is retrieved from packed-refs
, the path written in the file has "/" as path separator even if it on windows and the path is used as reference path direct.
packed-refs example:
# pack-refs with: peeled fully-peeled
65fdeb52c589aed517facc3b2b0edefe5d26518d refs/remotes/origin/master
^29c35f9a455bf5ed601ec47d3ca93da079ce428a
Cause why IsBranch() return false even if it is branch
Windows path separator will be "\" but IsBranch()
expect "/"
func (r *Reference) IsBranch() bool {
return strings.HasPrefix(string(r.n), refHeadPrefix)
}
const (
refPrefix = "refs/"
refHeadPrefix = refPrefix + "heads/"
refTagPrefix = refPrefix + "tags/"
refRemotePrefix = refPrefix + "remotes/"
refNotePrefix = refPrefix + "notes/"
symrefPrefix = "ref: "
)
Possible Fix
I think there are two ways to fix these problems.
- Always join reference path by "/"
- Use strings.Join when concat RefsPrefixes and replace "/" to "\" when retrieve reference path from packed-refs if running on windows.