diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-12 16:19:29 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-12 16:19:29 +0000 |
| commit | 1be46b4fd7a78ce418765ef5467823b7ea5e60eb (patch) | |
| tree | ed474554c9f589492dd93f17ff3bcacb8daa374a /src/lib | |
| parent | c85ca81767d838797f6a1ab6651e9864c3f961c1 (diff) | |
fix: handle existing local branch that is behind when checking out PR
When a PR branch already exists locally, the previous code would silently
move the branch pointer without checking for tracking or fast-forward safety.
Now:
- If branch has tracking: checkout and warn user to git pull
- If no tracking and fast-forward: safely move pointer
- If no tracking and diverged: show copy-paste commands for reset/rebase
- If commit not found locally: suggest fetching
Uses console crate for yellow output instead of hardcoded ANSI codes.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/git/mod.rs | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs index b9711ae..516d9e2 100644 --- a/src/lib/git/mod.rs +++ b/src/lib/git/mod.rs | |||
| @@ -91,6 +91,7 @@ pub trait RepoActions { | |||
| 91 | ) -> Result<Oid>; | 91 | ) -> Result<Oid>; |
| 92 | fn parse_starting_commits(&self, starting_commits: &str) -> Result<Vec<Sha1Hash>>; | 92 | fn parse_starting_commits(&self, starting_commits: &str) -> Result<Vec<Sha1Hash>>; |
| 93 | fn ancestor_of(&self, decendant: &Sha1Hash, ancestor: &Sha1Hash) -> Result<bool>; | 93 | fn ancestor_of(&self, decendant: &Sha1Hash, ancestor: &Sha1Hash) -> Result<bool>; |
| 94 | fn get_upstream_for_branch(&self, branch_name: &str) -> Result<Option<String>>; | ||
| 94 | fn get_git_config_item(&self, item: &str, global: Option<bool>) -> Result<Option<String>>; | 95 | fn get_git_config_item(&self, item: &str, global: Option<bool>) -> Result<Option<String>>; |
| 95 | fn save_git_config_item(&self, item: &str, value: &str, global: bool) -> Result<()>; | 96 | fn save_git_config_item(&self, item: &str, value: &str, global: bool) -> Result<()>; |
| 96 | fn remove_git_config_item(&self, item: &str, global: bool) -> Result<bool>; | 97 | fn remove_git_config_item(&self, item: &str, global: bool) -> Result<bool>; |
| @@ -734,6 +735,21 @@ impl RepoActions for Repo { | |||
| 734 | } | 735 | } |
| 735 | } | 736 | } |
| 736 | 737 | ||
| 738 | fn get_upstream_for_branch(&self, branch_name: &str) -> Result<Option<String>> { | ||
| 739 | let branch = self | ||
| 740 | .git_repo | ||
| 741 | .find_branch(branch_name, git2::BranchType::Local) | ||
| 742 | .context(format!("failed to find local branch {branch_name}"))?; | ||
| 743 | let upstream = branch.upstream(); | ||
| 744 | match upstream { | ||
| 745 | Ok(upstream_branch) => { | ||
| 746 | let name = upstream_branch.name()?.map(|s| s.to_string()); | ||
| 747 | Ok(name) | ||
| 748 | } | ||
| 749 | Err(_) => Ok(None), | ||
| 750 | } | ||
| 751 | } | ||
| 752 | |||
| 737 | /// setting global to None will suppliment local config with global items | 753 | /// setting global to None will suppliment local config with global items |
| 738 | /// not in local | 754 | /// not in local |
| 739 | fn get_git_config_item(&self, item: &str, global: Option<bool>) -> Result<Option<String>> { | 755 | fn get_git_config_item(&self, item: &str, global: Option<bool>) -> Result<Option<String>> { |