aboutsummaryrefslogtreecommitdiffstats
path: root/storage/filesystem
diff options
context:
space:
mode:
authorenverbisevac <enver@bisevac.com>2023-10-06 02:54:20 +0200
committerenverbisevac <enver@bisevac.com>2023-10-08 00:40:30 +0200
commit479d3e952e75d6e41b71a81cc9a92dec792825ba (patch)
treed2cfec4017f7a1aadd295cb900046fe34c90a39b /storage/filesystem
parentced662e9db6667069a5255446425ec40d388f7e1 (diff)
downloadgo-git-479d3e952e75d6e41b71a81cc9a92dec792825ba.tar.gz
git: clone --shared implemented
Diffstat (limited to 'storage/filesystem')
-rw-r--r--storage/filesystem/dotgit/dotgit.go33
-rw-r--r--storage/filesystem/storage.go4
2 files changed, 36 insertions, 1 deletions
diff --git a/storage/filesystem/dotgit/dotgit.go b/storage/filesystem/dotgit/dotgit.go
index e02e6dd..3080e4a 100644
--- a/storage/filesystem/dotgit/dotgit.go
+++ b/storage/filesystem/dotgit/dotgit.go
@@ -8,7 +8,9 @@ import (
"fmt"
"io"
"os"
+ "path"
"path/filepath"
+ "runtime"
"sort"
"strings"
"time"
@@ -38,6 +40,7 @@ const (
remotesPath = "remotes"
logsPath = "logs"
worktreesPath = "worktrees"
+ alternatesPath = "alternates"
tmpPackedRefsPrefix = "._packed-refs"
@@ -1105,10 +1108,38 @@ func (d *DotGit) Module(name string) (billy.Filesystem, error) {
return d.fs.Chroot(d.fs.Join(modulePath, name))
}
+func (d *DotGit) AddAlternate(remote string) error {
+ altpath := d.fs.Join(objectsPath, infoPath, alternatesPath)
+
+ f, err := d.fs.OpenFile(altpath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0640)
+ if err != nil {
+ return fmt.Errorf("cannot open file: %w", err)
+ }
+ defer f.Close()
+
+ // locking in windows throws an error, based on comments
+ // https://github.com/go-git/go-git/pull/860#issuecomment-1751823044
+ // do not lock on windows platform.
+ if runtime.GOOS != "windows" {
+ if err = f.Lock(); err != nil {
+ return fmt.Errorf("cannot lock file: %w", err)
+ }
+ defer f.Unlock()
+ }
+
+ line := path.Join(remote, objectsPath) + "\n"
+ _, err = io.WriteString(f, line)
+ if err != nil {
+ return fmt.Errorf("error writing 'alternates' file: %w", err)
+ }
+
+ return nil
+}
+
// Alternates returns DotGit(s) based off paths in objects/info/alternates if
// available. This can be used to checks if it's a shared repository.
func (d *DotGit) Alternates() ([]*DotGit, error) {
- altpath := d.fs.Join("objects", "info", "alternates")
+ altpath := d.fs.Join(objectsPath, infoPath, alternatesPath)
f, err := d.fs.Open(altpath)
if err != nil {
return nil, err
diff --git a/storage/filesystem/storage.go b/storage/filesystem/storage.go
index 7e7a2c5..2069d3a 100644
--- a/storage/filesystem/storage.go
+++ b/storage/filesystem/storage.go
@@ -74,3 +74,7 @@ func (s *Storage) Filesystem() billy.Filesystem {
func (s *Storage) Init() error {
return s.dir.Initialize()
}
+
+func (s *Storage) AddAlternate(remote string) error {
+ return s.dir.AddAlternate(remote)
+}