1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//! Encodes a root-relative worktree path into a worktree admin (metadata directory) name.
//!
//! See [ADR-027](../../../docs/adr/027-path-encoded-worktree-names.md). Git discovers
//! worktrees by listing `.bare/worktrees/` exactly one level deep, so the admin name can
//! never contain `/`. Deriving it as a plain basename lets two worktrees whose paths end
//! in the same component collide (`ee/feature-name` and `archive/feature-name` both reduce
//! to `feature-name`). Encoding the full path avoids that: every `/` becomes `~`, a
//! separator `git check-ref-format` rejects, so an encoded name can never alias a real
//! branch and no branch can ever produce one by accident.
use Path;
use Repository;
use crateworkon_root;
/// Encode a root-relative worktree path into a worktree admin name.
///
/// Replaces every `/` with `~`. Called at the two sites that compute an admin name from a
/// path — [`add_worktree`](crate::add_worktree) and
/// [`move_worktree`](crate::move_worktree) — never anywhere else. Nothing decodes the
/// result back into a path; a stored name is a label, not a key.
/// Compute `path`'s root-relative path, robust to symlinks on either side.
///
/// `workon_root()` and a worktree's `path()` can disagree on symlink resolution — git
/// canonicalizes the paths it writes into `gitdir`/`commondir`, while a path computed
/// from `workon_root()` may not be (e.g. macOS routes both `/tmp` and `/var/folders`
/// through symlinks). A plain `strip_prefix` fails silently in that case, which would
/// make every path-based lookup miss every worktree under a symlinked root. Canonicalize
/// both sides first, falling back to the original when `canonicalize` fails (e.g. a
/// worktree directory that no longer exists).
///
/// Returns `None` if `path` isn't inside `workon_root()`. The result always uses `/`
/// separators, matching the format `encode_worktree_name` expects.