feat(client): lodge remote binds a repository to another server
This commit is contained in:
1 parent
45c81cfcaf
commit
91d83f3032
10 files changed
+639
-147
No files matched your search
@@ -42,8 +42,12 @@ type diskFiles struct {
|
||||
tracked map[string]bool
|
||||
}
|
||||
|
||||
func worktreePath(dataDir string, repo *gitrepo.Repo) string {
|
||||
return filepath.Join(dataDir, "repos", repo.Key, hashOf([]byte(repo.Root))[:16])
|
||||
}
|
||||
|
||||
func (c *Client) statePath(repo *gitrepo.Repo) string {
|
||||
return filepath.Join(c.DataDir, "repos", repo.Key, hashOf([]byte(repo.Root))[:16]+".json")
|
||||
return worktreePath(c.DataDir, repo) + "-" + hashOf([]byte(c.URL))[:16] + ".json"
|
||||
}
|
||||
|
||||
func (c *Client) loadState(repo *gitrepo.Repo) *worktreeState {
|
||||
@@ -60,8 +64,7 @@ func (c *Client) loadState(repo *gitrepo.Repo) *worktreeState {
|
||||
return st
|
||||
}
|
||||
|
||||
func (c *Client) lock(repo *gitrepo.Repo) (func(), error) {
|
||||
path := c.statePath(repo) + ".lock"
|
||||
func flock(path string) (func(), error) {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -76,31 +79,46 @@ func (c *Client) lock(repo *gitrepo.Repo) (func(), error) {
|
||||
return func() { file.Close() }, nil
|
||||
}
|
||||
|
||||
func (c *Client) Hook(ctx context.Context, dir string) error {
|
||||
func (cfg *Config) Hook(ctx context.Context, dir string) error {
|
||||
repo, err := gitrepo.Open(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
firstSight := !slices.Contains(c.Worktrees(), repo.Root)
|
||||
_, err = c.Sync(ctx, repo.Root, firstSight)
|
||||
firstSight := !slices.Contains(cfg.Worktrees(), repo.Root)
|
||||
_, err = cfg.Sync(ctx, repo.Root, firstSight)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) Sync(ctx context.Context, dir string, online bool) (Result, error) {
|
||||
var res Result
|
||||
func (cfg *Config) Sync(ctx context.Context, dir string, online bool) (Result, error) {
|
||||
repo, err := gitrepo.Open(dir)
|
||||
if err != nil {
|
||||
return res, err
|
||||
return Result{}, err
|
||||
}
|
||||
if err := c.register(repo.Root); err != nil {
|
||||
return res, err
|
||||
}
|
||||
unlock, err := c.lock(repo)
|
||||
worktree := worktreePath(cfg.DataDir, repo)
|
||||
unlock, err := flock(worktree + ".lock")
|
||||
if err != nil {
|
||||
return res, err
|
||||
return Result{}, err
|
||||
}
|
||||
defer unlock()
|
||||
current, err := cfg.reload()
|
||||
if err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
c, err := current.Server(repo.Key)
|
||||
if err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
if err := cfg.register(repo.Root); err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
if c.URL == current.URL {
|
||||
_ = os.Rename(worktree+".json", c.statePath(repo))
|
||||
}
|
||||
return c.sync(ctx, repo, online)
|
||||
}
|
||||
|
||||
func (c *Client) sync(ctx context.Context, repo *gitrepo.Repo, online bool) (Result, error) {
|
||||
var res Result
|
||||
st := c.loadState(repo)
|
||||
for range maxPasses {
|
||||
again, err := c.pass(ctx, repo, st, online, &res)
|
||||
|
||||
Reference in new issue
Block a user