Skip to main content

git_policy_cli/
command_worktree.rs

1//! What:
2//!  The one fact the wrapper needs about `git worktree`:
3//!  whether the invocation
4//!       creates or moves a worktree.
5//! Why:
6//!  Only `git worktree add` and `git worktree move` are sources of ignored-state
7//!      synchronization,
8//!  and the worktree-copy opt-out is written after that second word.
9//!
10//! In TS you'd write (pseudocode):
11//! ```ts
12//! // changesWorktreeRegistrations(['add', '../topic']) === true
13//! ```
14
15/// What:
16///  `OsString` is owned operating-system text of raw bytes.
17///  Sibling the reader might
18///       expect:
19///  `String`,
20///  which must be valid UTF-8.
21/// Why:
22///   The region is compared as bytes and never decoded.
23///
24/// In TS you'd write (pseudocode):
25/// ```ts
26/// // string, but byte-preserving.
27/// ```
28use std::ffi::OsString;
29
30/// What:
31///  The `git worktree` subcommand words that register or re-register a worktree path.
32///       `&[&[u8]]` is a borrowed list of byte spellings baked into the program.
33/// Why:
34///   Git 2.56.0 `cmd_worktree` declares only subcommands and no option of its own
35///       (builtin/worktree.c),
36///  so the word directly after `worktree` selects the action
37///       and is never abbreviated.
38///
39/// In TS you'd write (pseudocode):
40/// ```ts
41/// const REGISTRATION_SUBCOMMANDS = ['add', 'move'];
42/// ```
43const REGISTRATION_SUBCOMMANDS: &[&[u8]] = &[b"add", b"move"];
44
45/// What:
46///  Whether the tokens after `worktree` start with `add` or `move`.
47///  `&[OsString]`
48///       borrows those tokens;
49///  `bool` is true or false.
50/// Why:
51///   The caller decides from this alone,
52///  without reading the subcommand's options,
53///  so
54///       a mistaken option table can never hide a worktree creation.
55///
56/// In TS you'd write (pseudocode):
57/// ```ts
58/// function changesWorktreeRegistrations(region: string[]): boolean;
59/// ```
60pub fn changes_worktree_registrations(region: &[OsString]) -> bool {
61    // `let Some(x) = ... else { ... };` unwraps the first token or returns for an empty region.
62    let Some(first) = region.first() else {
63        return false;
64    };
65    // `.as_encoded_bytes()` lends the raw bytes; `.contains(&x)` borrows them for the lookup.
66    return REGISTRATION_SUBCOMMANDS.contains(&first.as_encoded_bytes());
67}
68
69/// Word-position cases and a real Git 2.56.0 control stay out of the release executable.
70#[cfg(test)]
71#[path = "command_worktree_tests.rs"]
72mod tests;