lds_git/reset.rs
1//! Reset operations — destructive, so they're guarded by the same ownership
2//! check as `commit` / `merge`.
3//!
4//! `git reset --hard` is the most reflog-heavy thing this crate does. We
5//! capture HEAD before and after so callers can produce an audit line ("HEAD
6//! moved from X to Y, mode=hard"), and so an undo path is at least
7//! discoverable via the reflog rather than silently lost.
8
9use std::path::Path;
10
11use anyhow::Result;
12
13use crate::output::{ResetMode, ResetOutput};
14use crate::{GitModule, git_cmd};
15
16impl GitModule {
17 /// Move HEAD to `target`, with `mode` controlling the working tree
18 /// behaviour. The working directory MUST be owned by the current
19 /// session — see [`GitModule::ensure_session_scope`].
20 ///
21 /// * [`ResetMode::Soft`] — move HEAD only (`git reset --soft`)
22 /// * [`ResetMode::Mixed`] — also reset index but keep worktree (`--mixed`)
23 /// * [`ResetMode::Hard`] — also overwrite worktree (`--hard`)
24 pub fn reset(&self, working_dir: &Path, mode: ResetMode, target: &str) -> Result<ResetOutput> {
25 self.ensure_session_scope(working_dir)?;
26
27 let previous_head = git_cmd(working_dir, &["rev-parse", "HEAD"])?;
28 let flag = match mode {
29 ResetMode::Soft => "--soft",
30 ResetMode::Mixed => "--mixed",
31 ResetMode::Hard => "--hard",
32 };
33 git_cmd(working_dir, &["reset", flag, target])?;
34 let current_head = git_cmd(working_dir, &["rev-parse", "HEAD"])?;
35
36 Ok(ResetOutput {
37 mode,
38 target: target.to_string(),
39 previous_head,
40 current_head,
41 })
42 }
43}