Skip to content

Commit 1ad4d68

Browse files
feat: git diff version
1 parent c7c915e commit 1ad4d68

File tree

1 file changed

+63
-39
lines changed

1 file changed

+63
-39
lines changed

src/main.rs

Lines changed: 63 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,63 +2,87 @@ use std::env;
22
use std::process::Command;
33
use std::str;
44

5-
fn main() {
6-
// 获取命令行参数中的关键字
7-
let args: Vec<String> = env::args().collect();
8-
if args.len() != 2 {
9-
eprintln!("Usage: git_commit_stats <keyword>");
10-
return;
5+
fn get_commit_list(keyword: &str, include_merge: bool) -> Vec<String> {
6+
let k = format!("--grep={}", keyword);
7+
let mut args = vec!["log", &k, "--pretty=format:%H"];
8+
9+
if !include_merge {
10+
args.push("--no-merges");
1111
}
12-
let keyword = &args[1];
1312

14-
// 获取包含关键字的 commit 列表
1513
let output = Command::new("git")
16-
.arg("log")
17-
.arg(format!("--grep={}", keyword))
18-
.arg("--pretty=format:%H")
14+
.args(&args)
1915
.output()
2016
.expect("Failed to execute git log");
2117

2218
let commits = String::from_utf8_lossy(&output.stdout);
23-
let commits: Vec<&str> = commits.lines().collect();
19+
commits.lines().map(String::from).collect()
20+
}
21+
22+
fn calculate_diff(commit: &str) -> (usize, usize) {
23+
let output = Command::new("git")
24+
.arg("diff")
25+
.arg("--shortstat")
26+
.arg(commit)
27+
.output()
28+
.expect("Failed to execute git diff");
2429

25-
println!("commits length {}", commits.len());
30+
let diff_stats = String::from_utf8_lossy(&output.stdout);
31+
let lines: Vec<&str> = diff_stats.lines().collect();
2632

33+
if let Some(last_line) = lines.last() {
34+
let parts: Vec<&str> = last_line.split_whitespace().collect();
35+
if parts.len() >= 6 {
36+
let added: usize = parts[3].parse().unwrap_or(0);
37+
let deleted: usize = parts[5].parse().unwrap_or(0);
38+
return (added, deleted);
39+
}
40+
}
41+
(0, 0)
42+
}
43+
44+
fn print_commit_stats(commits: Vec<String>) {
2745
let mut total_added = 0;
2846
let mut total_deleted = 0;
2947

3048
for commit in commits {
31-
let output = Command::new("git")
32-
.arg("diff")
33-
.arg("--shortstat")
34-
.arg(commit)
35-
.output()
36-
.expect("Failed to execute git command");
37-
38-
let diff_stats = String::from_utf8_lossy(&output.stdout);
39-
let lines: Vec<&str> = diff_stats.lines().collect();
49+
let (added, deleted) = calculate_diff(&commit);
4050

41-
if !lines.is_empty() {
42-
let last_line = lines.last().unwrap();
43-
let parts: Vec<&str> = last_line.split_whitespace().collect();
51+
println!(
52+
"Commit {}: Added {} lines, Deleted {} lines",
53+
commit, added, deleted
54+
);
4455

45-
if parts.len() >= 6 {
46-
// let added = usize::from_str(parts[3]).unwrap();
47-
let added: usize = parts[3].parse().unwrap();
48-
let deleted: usize = parts[5].parse().unwrap();
49-
// let deleted = usize::from_str(parts[5]).unwrap();
56+
total_added += added;
57+
total_deleted += deleted;
58+
}
5059

51-
println!(
52-
"Commit {}: Added {} lines, Deleted {} lines",
53-
commit, added, deleted
54-
);
60+
println!("Total Added: {} lines", total_added);
61+
println!("Total Deleted: {} lines", total_deleted);
62+
}
5563

56-
total_added += added;
57-
total_deleted += deleted;
64+
fn main() {
65+
let args: Vec<String> = env::args().collect();
66+
if args.len() < 2 {
67+
eprintln!("Usage: git_commit_stats <keyword> [--merge | --no-merge]");
68+
return;
69+
}
70+
let keyword = &args[1];
71+
let include_merge = if args.len() > 2 {
72+
match args[2].as_str() {
73+
"--merge" => true,
74+
"--no-merge" => false,
75+
_ => {
76+
eprintln!("Invalid option: {}. Use --merge or --no-merge", args[2]);
77+
return;
5878
}
5979
}
60-
}
80+
} else {
81+
true // 默认包含 merge
82+
};
6183

62-
println!("Total Added: {} lines", total_added);
63-
println!("Total Deleted: {} lines", total_deleted);
84+
let commits = get_commit_list(keyword, include_merge);
85+
println!("Commits length: {}", commits.len());
86+
87+
print_commit_stats(commits);
6488
}

0 commit comments

Comments
 (0)