Skip to content

Commit eea75a4

Browse files
committed
Fix #236, alt link only if necessary
Tests: #65 (test_stale_link_removal) still passes. #236 (test_alt_preserves_user_symlink_until_alt_tracked) lazy touch (test_alt_skips_correct_symlink_without_touching)
1 parent bbb58e6 commit eea75a4

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

test/test_alt.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,3 +442,34 @@ def setup_standard_yadm_dir(paths):
442442
std_yadm_data.join("repo.git").mksymlinkto(paths.repo, absolute=1)
443443
std_yadm_dir.join("encrypt").mksymlinkto(paths.encrypt, absolute=1)
444444
return std_yadm_dir, std_yadm_data
445+
446+
447+
@pytest.mark.usefixtures("ds1_copy")
448+
def test_alt_preserves_user_symlink_when_no_alt_tracked(runner, paths):
449+
"""Issue #236: User symlinks preserved when no yadm alternate is tracked."""
450+
yadm_dir, yadm_data = setup_standard_yadm_dir(paths)
451+
user_target = paths.work.join("user_target")
452+
user_target.write("user-data")
453+
link_file = paths.work.join(utils.ALT_FILE1)
454+
link_file.mksymlinkto(user_target)
455+
# now test-file -> user_target
456+
alt_file = yadm_dir.join("alt").join(f"{utils.ALT_FILE1}##default")
457+
alt_file.write("alt-data", ensure=True)
458+
run = runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "alt"])
459+
assert run.success
460+
assert os.path.realpath(str(link_file)) == str(user_target)
461+
assert link_file.read() == "user-data"
462+
463+
464+
@pytest.mark.usefixtures("ds1_copy")
465+
def test_alt_skips_correct_symlink_without_touching(runner, paths):
466+
"""Optimization: yadm alt skips already-correct symlinks (no filesystem ops)."""
467+
yadm_dir, yadm_data = setup_standard_yadm_dir(paths)
468+
alt_file = yadm_dir.join("alt").join(f"{utils.ALT_FILE1}##default")
469+
alt_file.write("alt-data", ensure=True)
470+
runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "add", alt_file])
471+
runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "alt"])
472+
link_file = paths.work.join(utils.ALT_FILE1)
473+
mtime_before = link_file.lstat().mtime
474+
runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "alt"])
475+
assert link_file.lstat().mtime == mtime_before

yadm

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -603,12 +603,12 @@ function alt() {
603603
target="$target$suffix"
604604
fi
605605

606-
# Remove target if it's a symlink pointing at source
607-
if [ -L "$target" ] && [ "$target" -ef "$source" ]; then
606+
score_file "$source" "$target" "$conditions"
607+
608+
# Remove target if it's a symlink pointing at source with score 0 (stale)
609+
if [ -L "$target" ] && [ "$target" -ef "$source" ] && [ "$score" -eq 0 ]; then
608610
rm -f "$target"
609611
fi
610-
611-
score_file "$source" "$target" "$conditions"
612612
done
613613

614614
local alt_linked=()
@@ -705,6 +705,12 @@ function alt_linking() {
705705
local source="${alt_sources[$index]}"
706706
local template_processor="${alt_template_processors[$index]}"
707707

708+
if [ -L "$target" ] && [ "$target" -ef "$source" ] && [ "$do_copy" -eq 0 ]; then
709+
$log "Keeping $target; already linked to $source"
710+
exclude+=("${target#"$YADM_WORK"}")
711+
continue
712+
fi
713+
708714
if [ -L "$target" ]; then
709715
rm -f "$target"
710716
elif [ -d "$target" ]; then

0 commit comments

Comments
 (0)