-
Notifications
You must be signed in to change notification settings - Fork 29
/
git.rs
120 lines (112 loc) · 4.39 KB
/
git.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::{icons, Segment, CONFIG};
use std::path::Path;
use url::Url;
pub fn segment(segment: &mut Segment, args: &[&str]) {
for dir in CONFIG.git.ignore_dirs.iter() {
if std::env::current_dir().unwrap()
== Path::new(
&shellexpand::full_with_context_no_errors(
dir,
|| dirs::home_dir().map(|p| p.to_string_lossy().into_owned()),
|s| std::env::var(s).map(Some).unwrap_or_default(),
)
.into_owned(),
)
.canonicalize()
.unwrap()
{
return;
}
}
if let Ok(mut repo) = git2::Repository::discover(".") {
let mut domain = icons::get("git");
if let Ok(origin) = repo.find_remote("origin") {
let origin = origin.url().unwrap_or_default();
match Url::parse(origin) {
Ok(url) => {
match url.domain().unwrap_or_default() {
"github.com" => domain = icons::get("github"),
"gitlab.com" => domain = icons::get("gitlab"),
"bitbucket.org" => domain = icons::get("bitbucket"),
"dev.azure.com" => domain = icons::get("azure"),
_ => {}
}
}
Err(_) => {
if origin.starts_with("[email protected]:") {
domain = icons::get("github");
} else if origin.starts_with("[email protected]:") {
domain = icons::get("gitlab");
} else if origin.starts_with("[email protected]:") {
domain = icons::get("bitbucket");
}
}
}
}
let mut stashes = 0;
repo.stash_foreach(|_, _, _| {
stashes += 1;
true
})
.unwrap();
let stashes = icons::repeat("stash", stashes);
let mut graph = String::new();
let mut branch = String::new();
if let Ok(head) = repo.head() {
branch = head.shorthand().unwrap_or_default().to_owned();
let local = head.target().unwrap();
if let Ok(local_branch) = repo.find_branch(&branch, git2::BranchType::Local) {
let upstream = local_branch.upstream();
if let Ok(upstream) = upstream {
if let Some(upstream) = upstream.get().target() {
let (ahead, behind) = match repo.graph_ahead_behind(local, upstream) {
Ok((ahead, behind)) => (ahead, behind),
Err(_) => (0, 0),
};
graph = icons::repeat("ahead", ahead) + &icons::repeat("behind", behind);
}
}
}
}
let mut modified = String::new();
let mut staged = String::new();
if let Ok(statuses) =
repo.statuses(Some(git2::StatusOptions::new().include_untracked(true)))
{
for status in statuses.iter() {
// dirty
segment.background = if args.is_empty() { "yellow" } else { args[0] }.to_owned();
let status = status.status();
if modified.is_empty() && status.is_wt_new()
|| status.is_wt_modified()
|| status.is_wt_renamed()
|| status.is_wt_typechange()
{
modified = icons::get("modified");
}
if staged.is_empty() && status.is_index_new()
|| status.is_index_modified()
|| status.is_index_deleted()
|| status.is_index_renamed()
|| status.is_index_typechange()
{
staged = icons::get("staged");
}
if !modified.is_empty() && !staged.is_empty() {
break;
}
}
}
let mut parts = vec![domain];
if !stashes.is_empty() || !graph.is_empty() {
parts.push(stashes + &graph);
}
if !branch.is_empty() {
parts.push(branch);
}
if !modified.is_empty() || !staged.is_empty() {
parts.push(modified + &staged);
}
segment.value = parts.join(" ");
}
}