Support in-place updates from v3
A few small accomodations and we can clean up properly.
This commit is contained in:
parent
7eaba7605a
commit
12c1ece35f
|
|
@ -1554,6 +1554,8 @@ func (git *repoSync) cleanup(ctx context.Context, worktree worktree) error {
|
||||||
if err := removeDirContents(git.worktreeFor("").Path(), git.log, worktree.Hash()); err != nil {
|
if err := removeDirContents(git.worktreeFor("").Path(), git.log, worktree.Hash()); err != nil {
|
||||||
cleanupErrs = append(cleanupErrs, err)
|
cleanupErrs = append(cleanupErrs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Let git know we don't need those old commits any more.
|
||||||
if _, err := git.Run(ctx, git.root, "worktree", "prune", "--verbose"); err != nil {
|
if _, err := git.Run(ctx, git.root, "worktree", "prune", "--verbose"); err != nil {
|
||||||
cleanupErrs = append(cleanupErrs, err)
|
cleanupErrs = append(cleanupErrs, err)
|
||||||
}
|
}
|
||||||
|
|
@ -1678,6 +1680,9 @@ func (git *repoSync) currentWorktree() (worktree, error) {
|
||||||
if target == "" {
|
if target == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
if filepath.IsAbs(target) {
|
||||||
|
return worktree(target), nil
|
||||||
|
}
|
||||||
return worktree(git.root.Join(target)), nil
|
return worktree(git.root.Join(target)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1736,12 +1741,17 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
|
||||||
currentHash = ""
|
currentHash = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changed := (currentHash != remoteHash)
|
|
||||||
if changed || git.syncCount == 0 {
|
|
||||||
git.log.V(0).Info("update required", "ref", git.ref, "local", currentHash, "remote", remoteHash)
|
|
||||||
|
|
||||||
// We have to do at least one fetch, to ensure that parameters like depth
|
// This catches in-place upgrades from older versions where the worktree
|
||||||
// are set properly. This is cheap when we already have the target hash.
|
// path was different.
|
||||||
|
changed := (currentHash != remoteHash) || (currentWorktree != git.worktreeFor(currentHash))
|
||||||
|
|
||||||
|
// We have to do at least one fetch, to ensure that parameters like depth
|
||||||
|
// are set properly. This is cheap when we already have the target hash.
|
||||||
|
if changed || git.syncCount == 0 {
|
||||||
|
git.log.V(0).Info("update required", "ref", git.ref, "local", currentHash, "remote", remoteHash, "syncCount", git.syncCount)
|
||||||
|
|
||||||
|
// Parameters like depth are set at fetch time.
|
||||||
if err := git.fetch(ctx, remoteHash); err != nil {
|
if err := git.fetch(ctx, remoteHash); err != nil {
|
||||||
return false, "", err
|
return false, "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1785,6 +1795,11 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
|
||||||
git.syncCount++
|
git.syncCount++
|
||||||
|
|
||||||
// Clean up old worktree(s) and run GC.
|
// Clean up old worktree(s) and run GC.
|
||||||
|
if currentWorktree != git.worktreeFor(currentHash) {
|
||||||
|
// The old worktree might have come from a prior version, and so
|
||||||
|
// not get caught by the normal cleanup.
|
||||||
|
os.RemoveAll(currentWorktree.Path().String())
|
||||||
|
}
|
||||||
if err := git.cleanup(ctx, newWorktree); err != nil {
|
if err := git.cleanup(ctx, newWorktree); err != nil {
|
||||||
git.log.Error(err, "git cleanup failed", "newWorktree", newWorktree)
|
git.log.Error(err, "git cleanup failed", "newWorktree", newWorktree)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
test_e2e.sh
44
test_e2e.sh
|
|
@ -591,6 +591,50 @@ function e2e::worktree_cleanup() {
|
||||||
assert_file_absent "$ROOT/.worktrees/not_a_directory"
|
assert_file_absent "$ROOT/.worktrees/not_a_directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##############################################
|
||||||
|
# Test v3->v4 upgrade
|
||||||
|
##############################################
|
||||||
|
function e2e::v3_v4_upgrade_in_place() {
|
||||||
|
echo "$FUNCNAME 1" > "$REPO"/file
|
||||||
|
git -C "$REPO" commit -qam "$FUNCNAME"
|
||||||
|
|
||||||
|
# sync once
|
||||||
|
GIT_SYNC \
|
||||||
|
--one-time \
|
||||||
|
--repo="file://$REPO" \
|
||||||
|
--root="$ROOT" \
|
||||||
|
--link="link"
|
||||||
|
|
||||||
|
assert_link_exists "$ROOT"/link
|
||||||
|
assert_file_exists "$ROOT"/link/file
|
||||||
|
assert_file_eq "$ROOT"/link/file "$FUNCNAME 1"
|
||||||
|
|
||||||
|
# simulate v3's worktrees
|
||||||
|
WT="$(readlink "$ROOT/link")"
|
||||||
|
SHA="$(basename "$WT")"
|
||||||
|
mv -f "$ROOT/$WT" "$ROOT/$SHA"
|
||||||
|
ln -sf "$SHA" "$ROOT/link"
|
||||||
|
|
||||||
|
# make a second commit
|
||||||
|
echo "$FUNCNAME 2" > "$REPO"/file2
|
||||||
|
git -C "$REPO" add file2
|
||||||
|
git -C "$REPO" commit -qam "$FUNCNAME new file"
|
||||||
|
|
||||||
|
# sync again
|
||||||
|
GIT_SYNC \
|
||||||
|
--one-time \
|
||||||
|
--repo="file://$REPO" \
|
||||||
|
--root="$ROOT" \
|
||||||
|
--link="link"
|
||||||
|
|
||||||
|
assert_link_exists "$ROOT"/link
|
||||||
|
assert_file_exists "$ROOT"/link/file
|
||||||
|
assert_file_eq "$ROOT"/link/file "$FUNCNAME 1"
|
||||||
|
assert_file_exists "$ROOT"/link/file2
|
||||||
|
assert_file_eq "$ROOT"/link/file2 "$FUNCNAME 2"
|
||||||
|
assert_file_absent "$ROOT/$SHA"
|
||||||
|
}
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
# Test readlink
|
# Test readlink
|
||||||
##############################################
|
##############################################
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,11 @@ Git-sync v4 is a significant change from v3. It includes several flag changes
|
||||||
(though many of the old flags are kept for backwards compatibility), but more
|
(though many of the old flags are kept for backwards compatibility), but more
|
||||||
importantly it fundamentally changes the way the internal sync-loop works.
|
importantly it fundamentally changes the way the internal sync-loop works.
|
||||||
|
|
||||||
|
It should be possible to upgrade a synced repo (e.g. in a volume) from git-sync
|
||||||
|
v3 to git-sync v4, but appropriate caution should be used for critical
|
||||||
|
deployments. We have a test which covers this, but there are many degrees of
|
||||||
|
config which we simply can't predict.
|
||||||
|
|
||||||
## The v3 loop
|
## The v3 loop
|
||||||
|
|
||||||
The way git-sync v3.x works is sort of like how a human might work:
|
The way git-sync v3.x works is sort of like how a human might work:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue