Skip to content

Commit

Permalink
Handle redirection symlink in windows: Handle eden rm to not restri…
Browse files Browse the repository at this point in the history
…ct redirected path deletion

Summary:
# Background
We have seen tools like Unity messing up with already existing redirection symlink by deleting and/or creating a folder/file instead of symlink.

# Solution
When a create/delete operation is triggered for a redirected path, handle it in a way such that redirection stay intact.

# This change

Not letting redirected path gets deleted will cause eden rm to fail (Ref: D64366283). Removing all redirection target entries from the checkout config for eden rm to proceed.
*There could be a cornercase scenario of partial success of eden rm where redirection targets might get deleted but user can still use the repo (eden rm did not succeed). In this case, normal source control operations should work as it is. Only this feature would not work as expected, which can be fixed by running `eden redirect fixup` or `eden doctor` as it is today

Differential Revision: D64424509

fbshipit-source-id: 9a6cf7c9be7fb29e8a0ffaf2a1d999b374e7299a
  • Loading branch information
Saurav Prakash authored and facebook-github-bot committed Oct 17, 2024
1 parent 3b3b7e2 commit 2b53561
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 0 deletions.
5 changes: 5 additions & 0 deletions eden/fs/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ class CheckoutConfig(typing.NamedTuple):
- redirections: dict where keys are relative pathnames in the EdenFS mount
and the values are RedirectionType enum values that describe the type of
the redirection.
- redirection_targets: dict where keys are relative pathnames in the EdenFS mount
and the values are target path for corresponding symlink.
"""

backing_repo: Path
Expand All @@ -201,6 +203,7 @@ class CheckoutConfig(typing.NamedTuple):
require_utf8_path: bool
default_revision: str
redirections: Dict[str, "RedirectionType"]
redirection_targets: Dict[str, str]
active_prefetch_profiles: List[str]
predictive_prefetch_profiles_active: bool
predictive_prefetch_num_dirs: int
Expand Down Expand Up @@ -1530,6 +1533,7 @@ def get_field(key: str) -> str:
require_utf8_path=require_utf8_path,
mount_protocol=mount_protocol,
redirections=redirections,
redirection_targets={}, # There is no need to read redirection targets in Python CLI for now.
default_revision=(
repository.get("default-revision") or DEFAULT_REVISION[scm_type]
),
Expand Down Expand Up @@ -2140,6 +2144,7 @@ def create_checkout_config(
require_utf8_path=True,
default_revision=DEFAULT_REVISION[repo.type],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand Down
1 change: 1 addition & 0 deletions eden/fs/cli/doctor/test/lib/fake_eden_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def create_test_mount(
require_utf8_path=True,
default_revision=snapshot,
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand Down
8 changes: 8 additions & 0 deletions eden/fs/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,14 @@ def run(self, args: argparse.Namespace) -> int:
exit_code = 0
for mount, remove_type in mounts:
print(f"Removing {mount}...")
# Removing reidrection targets from checkout config to allow deletion of redirected paths
instance, checkout, _rel_path = require_checkout(args, mount)
config = checkout.get_config()
config._replace(
redirection_targets={},
)
checkout.save_config(config)

if remove_type == RemoveType.ACTIVE_MOUNT:
try:
# We don't bother complaining about removing redirections on Windows
Expand Down
10 changes: 10 additions & 0 deletions eden/fs/cli/test/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def test_list_mounts_no_backing_repos(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["hg"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand All @@ -110,6 +111,7 @@ def test_list_mounts_no_backing_repos(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["git"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand All @@ -136,6 +138,7 @@ def test_list_mounts_no_backing_repos(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["git"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand All @@ -162,6 +165,7 @@ def test_list_mounts_no_backing_repos(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["git"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand All @@ -188,6 +192,7 @@ def test_list_mounts_no_backing_repos(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["hg"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand Down Expand Up @@ -315,6 +320,7 @@ def test_list_mounts_no_state(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["hg"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand All @@ -341,6 +347,7 @@ def test_list_mounts_no_state(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["git"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand All @@ -367,6 +374,7 @@ def test_list_mounts_no_state(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["hg"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand Down Expand Up @@ -485,6 +493,7 @@ def test_list_mounts_with_backing_repos(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["hg"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand All @@ -511,6 +520,7 @@ def test_list_mounts_with_backing_repos(self) -> None:
require_utf8_path=True,
default_revision=DEFAULT_REVISION["git"],
redirections={},
redirection_targets={},
active_prefetch_profiles=[],
predictive_prefetch_profiles_active=False,
predictive_prefetch_num_dirs=0,
Expand Down

0 comments on commit 2b53561

Please sign in to comment.