我正在使用git2 crate获取git存储库上的statuses列表,这是我正在使用的代码:
use git2::{Repository, StatusOptions, StatusShow};
use std::{collections::HashMap, env};
fn main() {
let path = env::current_dir().unwrap();
let repo = Repository::discover(path).unwrap();
let mut status_opt = StatusOptions::new();
status_opt
.show(StatusShow::IndexAndWorkdir)
.include_untracked(true)
.include_unmodified(false)
.no_refresh(false);
let status_result = repo.statuses(Some(&mut status_opt)).unwrap();
let mut map: HashMap<git2::Status, u32> = HashMap::new();
for status_entry in status_result.iter() {
*map.entry(status_entry.status()).or_insert(0) += 1;
}
println!("{:?}", map);
}
基于当前存储库的修改,返回了git2::Status
和事件的映射,但是我想向命令git status --porcelain
返回类似的输出。
例如,根据存储库的更改,这是git status --porcelain
的输出:
M file_a
AM file_b
A file_c
?? file_e
?? file_f
将输出传递到awk
:
$ git status --porcelain | awk -v ORS=", " 'NR>0{arr[$1]++}END{for (a in arr) print a, arr[a]}'
A 1, ?? 2, M 1, AM 1,
使用上面的Rust代码将返回:
{INDEX_NEW: 1, WT_NEW: 2, INDEX_NEW | WT_MODIFIED: 1, INDEX_MODIFIED: 1}
我想知道如何将git2::Status
常量的值映射到自定义字符串(匹配porceline字符串),例如:
INDEX_NEW -> A
INDEX_NEW | WT_MODIFIED -> AM
INDEX_MODIFIED -> M
WT_NEW -> ??
主要是如何处理类似INDEX_NEW | WT_MODIFIED
的情况,例如将映射到AM
答案 0 :(得分:4)
以下代码段将您的map
转换为所需的表示形式。所提供的示例将这些值集合到另一个HashMap
中,并且有一个可以惊慌的手臂,但是可以随时动态转换git2::Status
值(即,当您第一次遍历它们时)。
let mut output = HashMap::new();
for (key, value) in map.iter()
{
let key = match key
{
s if s.contains(git2::Status::INDEX_NEW) &&
s.contains(git2::Status::WT_MODIFIED) => "AM",
s if s.contains(git2::Status::INDEX_NEW) => "A",
s if s.contains(git2::Status::INDEX_MODIFIED) => "M",
_ => panic!("Unexpected status"),
};
output.insert(key, value);
}
println!("{:?}", output);
如果您正在查看所选库的示例,则会发现非常相似的内容:git2-rs/examples/status.rs
有关模式匹配语法的更多信息,请参阅The Rust Programming Book。