Skip to content

Commit c0da384

Browse files
committed
up/down navigation
1 parent 0a9717e commit c0da384

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

src/main.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ enum Command {
5656
},
5757
/// Launch interactive TUI mode for branch navigation and checkout.
5858
Interactive,
59+
/// Move up the stack to the parent branch.
60+
Up,
61+
/// Move down the stack to a child branch (only if there's exactly one child).
62+
Down,
5963
/// Open the git-stack state file in an editor for manual editing.
6064
Edit,
6165
/// Restack your active branch onto its parent branch.
@@ -370,6 +374,14 @@ fn inner_main() -> Result<()> {
370374
state.try_auto_mount(&git_repo, &repo, &current_branch)?;
371375
interactive(&git_repo, state, &repo, &current_branch, args.verbose)
372376
}
377+
Some(Command::Up) => {
378+
state.try_auto_mount(&git_repo, &repo, &current_branch)?;
379+
navigate_up(&state, &repo, &current_branch)
380+
}
381+
Some(Command::Down) => {
382+
state.try_auto_mount(&git_repo, &repo, &current_branch)?;
383+
navigate_down(&state, &repo, &current_branch)
384+
}
373385
Some(Command::Delete { branch_name }) => state.delete_branch(&repo, &branch_name),
374386
Some(Command::Cleanup { dry_run, all }) => {
375387
state.cleanup_missing_branches(&git_repo, &repo, dry_run, all)
@@ -592,6 +604,60 @@ fn interactive(
592604
Ok(())
593605
}
594606

607+
/// Navigate up the stack to the parent branch.
608+
fn navigate_up(state: &State, repo: &str, current_branch: &str) -> Result<()> {
609+
let parent = state.get_parent_branch_of(repo, current_branch);
610+
611+
match parent {
612+
Some(parent_branch) => {
613+
run_git(&["checkout", &parent_branch.name])?;
614+
Ok(())
615+
}
616+
None => {
617+
bail!(
618+
"Branch '{}' has no parent in the stack (already at root).",
619+
current_branch.yellow()
620+
);
621+
}
622+
}
623+
}
624+
625+
/// Navigate down the stack to a child branch.
626+
fn navigate_down(state: &State, repo: &str, current_branch: &str) -> Result<()> {
627+
let branch = state.get_tree_branch(repo, current_branch);
628+
629+
match branch {
630+
Some(branch) => {
631+
let children = &branch.branches;
632+
match children.len() {
633+
0 => {
634+
bail!(
635+
"Branch '{}' has no children in the stack.",
636+
current_branch.yellow()
637+
);
638+
}
639+
1 => {
640+
run_git(&["checkout", &children[0].name])?;
641+
Ok(())
642+
}
643+
n => {
644+
bail!(
645+
"Branch '{}' has {} children. Use `git stack interactive` to choose.",
646+
current_branch.yellow(),
647+
n
648+
);
649+
}
650+
}
651+
}
652+
None => {
653+
bail!(
654+
"Branch '{}' not found in the stack.",
655+
current_branch.yellow()
656+
);
657+
}
658+
}
659+
}
660+
595661
/// Get concatenated commit messages between ancestor and branch tip.
596662
fn get_concatenated_commit_messages(branch: &str, ancestor: &str) -> Result<String> {
597663
let output = run_git(&[

0 commit comments

Comments
 (0)