diff options
Diffstat (limited to 'src/modules/git_status.rs')
-rw-r--r-- | src/modules/git_status.rs | 196 |
1 files changed, 0 insertions, 196 deletions
diff --git a/src/modules/git_status.rs b/src/modules/git_status.rs deleted file mode 100644 index 9b97a2f24..000000000 --- a/src/modules/git_status.rs +++ /dev/null @@ -1,196 +0,0 @@ -use ansi_term::Color; -use git2::{Repository, Status}; - -use super::{Context, Module}; - -/// Creates a module with the Git branch in the current directory -/// -/// Will display the branch name if the current directory is a git repo -/// By default, the following symbols will be used to represent the repo's status: -/// - `=` – This branch has merge conflicts -/// - `⇡` – This branch is ahead of the branch being tracked -/// - `⇣` – This branch is behind of the branch being tracked -/// - `⇕` – This branch has diverged from the branch being tracked -/// - `?` — There are untracked files in the working directory -/// - `$` — A stash exists for the local repository -/// - `!` — There are file modifications in the working directory -/// - `+` — A new file has been added to the staging area -/// - `»` — A renamed file has been added to the staging area -/// - `✘` — A file's deletion has been added to the staging area -pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> { - // This is the order that the sections will appear in - const GIT_STATUS_CONFLICTED: &str = "="; - const GIT_STATUS_AHEAD: &str = "⇡"; - const GIT_STATUS_BEHIND: &str = "⇣"; - const GIT_STATUS_DIVERGED: &str = "⇕"; - const GIT_STATUS_UNTRACKED: &str = "?"; - const GIT_STATUS_STASHED: &str = "$"; - const GIT_STATUS_MODIFIED: &str = "!"; - const GIT_STATUS_ADDED: &str = "+"; - const GIT_STATUS_RENAMED: &str = "»"; - const GIT_STATUS_DELETED: &str = "✘"; - const PREFIX: &str = "["; - const SUFFIX: &str = "] "; - - let repo = context.get_repo().ok()?; - let branch_name = repo.branch.as_ref()?; - let repo_root = repo.root.as_ref()?; - let repository = Repository::open(repo_root).ok()?; - - let mut module = context.new_module("git_status"); - let show_sync_count = module.config_value_bool("show_sync_count").unwrap_or(false); - let module_style = module - .config_value_style("style") - .unwrap_or_else(|| Color::Red.bold()); - let start_symbol = module - .config_value_str("prefix") - .unwrap_or(PREFIX) - .to_owned(); - let end_symbol = module - .config_value_str("suffix") - .unwrap_or(SUFFIX) - .to_owned(); - - module - .get_prefix() - .set_value(start_symbol) - .set_style(module_style); - module - .get_suffix() - .set_value(end_symbol) - .set_style(module_style); - module.set_style(module_style); - - let ahead_behind = get_ahead_behind(&repository, branch_name); - if ahead_behind == Ok((0, 0)) { - log::trace!("No ahead/behind found"); - } else { - log::debug!("Repo ahead/behind: {:?}", ahead_behind); - } - - let stash_object = repository.revparse_single("refs/stash"); - if stash_object.is_ok() { - log::debug!("Stash object: {:?}", stash_object); - } else { - log::trace!("No stash object found"); - } - - let repo_status = get_repo_status(&repository); - log::debug!("Repo status: {:?}", repo_status); - - // Add the conflicted segment - if let Ok(repo_status) = repo_status { - if repo_status.is_conflicted() { - module.new_segment("conflicted", GIT_STATUS_CONFLICTED); - } - } - - // Add the ahead/behind segment - if let Ok((ahead, behind)) = ahead_behind { - let add_ahead = |m: &mut Module<'a>| { - m.new_segment("ahead", GIT_STATUS_AHEAD); - - if show_sync_count { - m.new_segment("ahead_count", &ahead.to_string()); - } - }; - - let add_behind = |m: &mut Module<'a>| { - m.new_segment("behind", GIT_STATUS_BEHIND); - - if show_sync_count { - m.new_segment("behind_count", &behind.to_string()); - } - }; - - if ahead > 0 && behind > 0 { - module.new_segment("diverged", GIT_STATUS_DIVERGED); - - if show_sync_count { - add_ahead(&mut module); - add_behind(&mut module); - } - } - - if ahead > 0 && behind == 0 { - add_ahead(&mut module); - } - - if behind > 0 && ahead == 0 { - add_behind(&mut module); - } - } - - // Add the stashed segment - if stash_object.is_ok() { - module.new_segment("stashed", GIT_STATUS_STASHED); - } - - // Add all remaining status segments - if let Ok(repo_status) = repo_status { - if repo_status.is_wt_deleted() || repo_status.is_index_deleted() { - module.new_segment("deleted", GIT_STATUS_DELETED); - } - - if repo_status.is_wt_renamed() || repo_status.is_index_renamed() { - module.new_segment("renamed", GIT_STATUS_RENAMED); - } - - if repo_status.is_wt_modified() { - module.new_segment("modified", GIT_STATUS_MODIFIED); - } - - if repo_status.is_index_modified() || repo_status.is_index_new() { - module.new_segment("staged", GIT_STATUS_ADDED); - } - - if repo_status.is_wt_new() { - module.new_segment("untracked", GIT_STATUS_UNTRACKED); - } - } - - if module.is_empty() { - return None; - } - - Some(module) -} - -/// Gets the bitflags associated with the repo's git status -fn get_repo_status(repository: &Repository) -> Result<Status, git2::Error> { - let mut status_options = git2::StatusOptions::new(); - - match repository.config()?.get_entry("status.showUntrackedFiles") { - Ok(entry) => status_options.include_untracked(entry.value() != Some("no")), - _ => status_options.include_untracked(true), - }; - status_options.renames_from_rewrites(true); - status_options.renames_head_to_index(true); - status_options.renames_index_to_workdir(true); - - let repo_file_statuses = repository.statuses(Some(&mut status_options))?; - - // Statuses are stored as bitflags, so use BitOr to join them all into a single value - let repo_status: Status = repo_file_statuses.iter().map(|e| e.status()).collect(); - if repo_status.is_empty() { - return Err(git2::Error::from_str("Repo has no status")); - } - - Ok(repo_status) -} - -/// Compares the current branch with the branch it is tracking to determine how -/// far ahead or behind it is in relation -fn get_ahead_behind( - repository: &Repository, - branch_name: &str, -) -> Result<(usize, usize), git2::Error> { - let branch_object = repository.revparse_single(branch_name)?; - let tracking_branch_name = format!("{}@{{upstream}}", branch_name); - let tracking_object = repository.revparse_single(&tracking_branch_name)?; - - let branch_oid = branch_object.id(); - let tracking_oid = tracking_object.id(); - - repository.graph_ahead_behind(branch_oid, tracking_oid) -} |