Skip to content

Commit 7abc381

Browse files
committed
updates to status
1 parent 200f311 commit 7abc381

File tree

3 files changed

+69
-28
lines changed

3 files changed

+69
-28
lines changed

src/git.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ pub(crate) fn run_git(args: &[&str]) -> Result<GitOutput> {
4242
.with_context(|| format!("running git {args:?}"))?;
4343

4444
if !out.status.success() {
45-
bail!("git {:?} failed with exit status: {}", args, out.status);
45+
bail!(
46+
"`git {}` failed with exit status: {}",
47+
args.join(" "),
48+
out.status
49+
);
4650
}
4751
Ok(GitOutput {
4852
stdout: String::from_utf8_lossy(&out.stdout).trim().to_string(),
@@ -60,26 +64,28 @@ pub(crate) fn git_fetch() -> Result<()> {
6064
}
6165

6266
pub(crate) fn git_branch_exists(branch: &str) -> bool {
63-
run_git(&["rev-parse", "--verify", branch]).is_ok()
67+
run_git(&["rev-parse", "--verify", branch]).is_ok_and(|out| !out.is_empty())
6468
}
6569

6670
#[derive(Debug)]
6771
pub(crate) struct GitBranchStatus {
6872
pub(crate) exists: bool,
6973
pub(crate) is_descendent: bool,
74+
pub(crate) parent_branch: String,
7075
}
7176

7277
pub(crate) fn git_branch_status(
73-
parent_branch: Option<String>,
78+
parent_branch: Option<&str>,
7479
branch: &str,
7580
) -> Result<GitBranchStatus> {
7681
let exists = git_branch_exists(branch);
7782
let parent_branch = match parent_branch {
78-
Some(parent_branch) => parent_branch,
83+
Some(parent_branch) => parent_branch.to_string(),
7984
None => git_remote_main(DEFAULT_REMOTE)?,
8085
};
8186
let is_descendent = exists && is_ancestor(&parent_branch, branch)?;
8287
Ok(GitBranchStatus {
88+
parent_branch,
8389
exists,
8490
is_descendent,
8591
})

src/main.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ fn inner_main() -> Result<()> {
7575
let current_branch = run_git(&["rev-parse", "--abbrev-ref", "HEAD"])?
7676
.output()
7777
.ok_or(anyhow!("No current branch?"))?;
78-
let current_upstream = run_git(&["rev-parse", "--abbrev-ref", "@{upstream}"])?.output();
78+
let current_upstream = run_git(&["rev-parse", "--abbrev-ref", "@{upstream}"])
79+
.ok()
80+
.and_then(|out| out.output());
7981
tracing::debug!(run_version, current_branch, current_upstream);
8082

8183
match args.command {
@@ -95,7 +97,19 @@ fn selection_marker() -> &'static str {
9597
}
9698
}
9799

98-
fn recur_tree(branch: &Branch, depth: usize, orig_branch: &str) {
100+
fn recur_tree(
101+
branch: &Branch,
102+
depth: usize,
103+
orig_branch: &str,
104+
parent_branch: Option<&str>,
105+
) -> Result<()> {
106+
let branch_status: GitBranchStatus = git_branch_status(parent_branch, &branch.name)
107+
.with_context(|| {
108+
format!(
109+
"attempting to fetch the branch status of {}",
110+
branch.name.red()
111+
)
112+
})?;
99113
let is_current_branch = if branch.name == orig_branch {
100114
print!("{} ", selection_marker().purple());
101115
true
@@ -109,17 +123,38 @@ fn recur_tree(branch: &Branch, depth: usize, orig_branch: &str) {
109123
}
110124

111125
println!(
112-
"{}",
126+
"{} {}",
113127
if is_current_branch {
114128
branch.name.green()
115129
} else {
116130
branch.name.truecolor(178, 178, 178)
131+
},
132+
{
133+
let details: String = if branch_status.exists {
134+
if branch_status.is_descendent {
135+
format!(
136+
"{} with {}",
137+
"is up to date".truecolor(90, 120, 87),
138+
branch_status.parent_branch.yellow()
139+
)
140+
} else {
141+
format!(
142+
"{} {}",
143+
"is behind".red(),
144+
branch_status.parent_branch.yellow()
145+
)
146+
}
147+
} else {
148+
"does not exist".red().to_string()
149+
};
150+
details
117151
}
118152
);
119153

120154
for child in &branch.branches {
121-
recur_tree(child, depth + 1, orig_branch);
155+
recur_tree(child, depth + 1, orig_branch, Some(branch.name.as_ref()))?;
122156
}
157+
Ok(())
123158
}
124159

125160
fn status(state: State, repo: &str, orig_branch: &str) -> Result<()> {
@@ -132,7 +167,7 @@ fn status(state: State, repo: &str, orig_branch: &str) -> Result<()> {
132167
);
133168
return Ok(());
134169
};
135-
recur_tree(tree, 0, orig_branch);
170+
recur_tree(tree, 0, orig_branch, None)?;
136171
/*
137172
let stacks = state.get_stacks(repo);
138173
if stacks.is_empty() {

src/state.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ impl State {
5454
branch_name: String,
5555
) -> Result<()> {
5656
let branch_exists_in_tree = self.branch_exists_in_tree(repo, &branch_name);
57+
let current_branch_exists_in_tree = self.branch_exists_in_tree(repo, &current_branch);
5758

5859
if git_branch_exists(&branch_name) {
60+
println!("AAA");
5961
if !branch_exists_in_tree {
6062
tracing::warn!(
6163
"Branch {branch_name} exists in the git repo but is not tracked by git-stack. \
@@ -67,35 +69,33 @@ impl State {
6769
run_git(&["checkout", &branch_name])?;
6870
return Ok(());
6971
}
70-
// Check if the branch name already exists.
71-
if branch_exists_in_tree {
72-
run_git(&["checkout", &branch_name])?;
73-
return Ok(());
74-
}
72+
// The branch does not exist in git, let's create it, and add it to the tree.
7573
let remote_main = git_remote_main(DEFAULT_REMOTE)?;
7674
let main_branch = after_text(&remote_main, format!("{DEFAULT_REMOTE}/"))
7775
.ok_or(anyhow!("no branch?"))?
7876
.to_string();
79-
if current_branch == main_branch {
80-
// Allow creation of the main branch for this repo if we haven't added it yet.
81-
self.trees
82-
.entry(repo.to_string())
83-
.or_insert_with(|| Branch::new(current_branch.clone()));
84-
}
77+
// Ensure the main branch is in the git-stack tree for this repo if we haven't
78+
// added it yet.
79+
self.trees
80+
.entry(repo.to_string())
81+
.or_insert_with(|| Branch::new(main_branch.clone()));
82+
8583
let branch = self
8684
.get_tree_branch_mut(repo, &current_branch)
87-
.ok_or_else(|| anyhow::anyhow!("Branch '{current_branch}' is not being tracked."))?;
88-
if !self.trees.contains_key(repo) {
89-
self.trees
90-
.insert(repo.to_string(), Branch::new(current_branch.clone()));
91-
}
85+
.ok_or_else(|| {
86+
anyhow::anyhow!(
87+
"Branch '{current_branch}' is not being tracked in the git-stack tree."
88+
)
89+
})?;
90+
91+
branch.branches.push(Branch::new(branch_name.clone()));
92+
93+
// Actually create the git branch.
94+
run_git(&["checkout", "-b", &branch_name, &current_branch])?;
9295

9396
// Save the state after modifying it.
9497
save_state(self)?;
9598

96-
// Checkout the new branch.
97-
run_git(&["checkout", &branch_name])?;
98-
9999
Ok(())
100100
}
101101

0 commit comments

Comments
 (0)