Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit da5d474

Browse files
committed
storage/filesystem: avoid norwfs build flag
norwfs build flag was used to work on filesystems that do not support neither opening a file in read/write mode or renaming a file (e.f. sivafs). This had two problems: - go-git could not be compiled to work properly both with regular filesystems and limited filesystems at the same time. - the norwfs trick was not available on Windows. This PR removes the norwfs build flag, as well as the windows conditional flag on the dotgit package. For the file open mode, we use the new billy capabilities, to check at runtime if the filesystem supports opening a file in read/write mode or not. For the renaming, we just try and fallback to alternative methods if billy.ErrNotSupported is returned. Signed-off-by: Santiago M. Mola <santi@mola.io>
1 parent b11eaab commit da5d474

File tree

5 files changed

+82
-94
lines changed

5 files changed

+82
-94
lines changed

storage/filesystem/dotgit/dotgit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ func (d *DotGit) openAndLockPackedRefs(doCreate bool) (
469469
// File mode is retrieved from a constant defined in the target specific
470470
// files (dotgit_rewrite_packed_refs_*). Some modes are not available
471471
// in all filesystems.
472-
openFlags := openAndLockPackedRefsMode
472+
openFlags := d.openAndLockPackedRefsMode()
473473
if doCreate {
474474
openFlags |= os.O_CREATE
475475
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package dotgit
2+
3+
import (
4+
"io"
5+
"os"
6+
"runtime"
7+
8+
"gopkg.in/src-d/go-billy.v4"
9+
"gopkg.in/src-d/go-git.v4/utils/ioutil"
10+
)
11+
12+
func (d *DotGit) openAndLockPackedRefsMode() int {
13+
if billy.CapabilityCheck(d.fs, billy.ReadAndWriteCapability) {
14+
return os.O_RDWR
15+
}
16+
17+
return os.O_RDONLY
18+
}
19+
20+
func (d *DotGit) rewritePackedRefsWhileLocked(
21+
tmp billy.File, pr billy.File) error {
22+
// Try plain rename. If we aren't using the bare Windows filesystem as the
23+
// storage layer, we might be able to get away with a rename over a locked
24+
// file.
25+
err := d.fs.Rename(tmp.Name(), pr.Name())
26+
if err == nil {
27+
return nil
28+
}
29+
30+
// If we are in a filesystem that does not support rename (e.g. sivafs)
31+
// a full copy is done.
32+
if err == billy.ErrNotSupported {
33+
return d.copyNewFile(tmp, pr)
34+
}
35+
36+
if runtime.GOOS != "windows" {
37+
return err
38+
}
39+
40+
// Otherwise, Windows doesn't let us rename over a locked file, so
41+
// we have to do a straight copy. Unfortunately this could result
42+
// in a partially-written file if the process fails before the
43+
// copy completes.
44+
return d.copyToExistingFile(tmp, pr)
45+
}
46+
47+
func (d *DotGit) copyToExistingFile(tmp, pr billy.File) error {
48+
_, err := pr.Seek(0, io.SeekStart)
49+
if err != nil {
50+
return err
51+
}
52+
err = pr.Truncate(0)
53+
if err != nil {
54+
return err
55+
}
56+
_, err = tmp.Seek(0, io.SeekStart)
57+
if err != nil {
58+
return err
59+
}
60+
_, err = io.Copy(pr, tmp)
61+
62+
return err
63+
}
64+
65+
func (d *DotGit) copyNewFile(tmp billy.File, pr billy.File) (err error) {
66+
prWrite, err := d.fs.Create(pr.Name())
67+
if err != nil {
68+
return err
69+
}
70+
71+
defer ioutil.CheckClose(prWrite, &err)
72+
73+
_, err = tmp.Seek(0, io.SeekStart)
74+
if err != nil {
75+
return err
76+
}
77+
78+
_, err = io.Copy(prWrite, tmp)
79+
80+
return err
81+
}

storage/filesystem/dotgit/dotgit_rewrite_packed_refs_nix.go

Lines changed: 0 additions & 17 deletions
This file was deleted.

storage/filesystem/dotgit/dotgit_rewrite_packed_refs_norwfs.go

Lines changed: 0 additions & 34 deletions
This file was deleted.

storage/filesystem/dotgit/dotgit_rewrite_packed_refs_windows.go

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)