ralph_workflow/git_helpers/repo/
snapshot.rs1use std::io;
2
3use crate::git_helpers::git2_to_io_error;
4
5pub fn git_snapshot() -> io::Result<String> {
9 let repo = git2::Repository::discover(".").map_err(|e| git2_to_io_error(&e))?;
10 git_snapshot_impl(&repo)
11}
12
13fn git_snapshot_impl(repo: &git2::Repository) -> io::Result<String> {
15 let mut opts = git2::StatusOptions::new();
16 opts.include_untracked(true).recurse_untracked_dirs(true);
17 let statuses = repo
18 .statuses(Some(&mut opts))
19 .map_err(|e| git2_to_io_error(&e))?;
20
21 let mut result = String::new();
22 for entry in statuses.iter() {
23 let status = entry.status();
24 let path = entry.path().unwrap_or("").to_string();
25
26 if status.contains(git2::Status::WT_NEW) {
29 result.push('?');
30 result.push('?');
31 result.push(' ');
32 result.push_str(&path);
33 result.push('\n');
34 continue;
35 }
36
37 let index_status = if status.contains(git2::Status::INDEX_NEW) {
39 'A'
40 } else if status.contains(git2::Status::INDEX_MODIFIED) {
41 'M'
42 } else if status.contains(git2::Status::INDEX_DELETED) {
43 'D'
44 } else if status.contains(git2::Status::INDEX_RENAMED) {
45 'R'
46 } else if status.contains(git2::Status::INDEX_TYPECHANGE) {
47 'T'
48 } else {
49 ' '
50 };
51
52 let wt_status = if status.contains(git2::Status::WT_MODIFIED) {
54 'M'
55 } else if status.contains(git2::Status::WT_DELETED) {
56 'D'
57 } else if status.contains(git2::Status::WT_RENAMED) {
58 'R'
59 } else if status.contains(git2::Status::WT_TYPECHANGE) {
60 'T'
61 } else {
62 ' '
63 };
64
65 result.push(index_status);
66 result.push(wt_status);
67 result.push(' ');
68 result.push_str(&path);
69 result.push('\n');
70 }
71
72 Ok(result)
73}