support adding file/folder to gitignore (closes #44)

This commit is contained in:
Stephan Dilly 2020-06-01 23:32:11 +02:00
parent 8e41dd2cbe
commit 14a93cbefd
8 changed files with 68 additions and 7 deletions

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
![](assets/cmdbar.gif)
### Added
- support adding untracked file/folder to `.gitignore` ([#44](https://github.com/extrawurst/gitui/issues/44))
- support reverse tabbing using shift+tab ([#92](https://github.com/extrawurst/gitui/issues/92))
- switch to using cmd line args instead of `ENV` (`-l` for logging and `--version`) **please convert your GITUI_LOGGING usage** [[@shenek](https://github.com/shenek)] ([#88](https://github.com/extrawurst/gitui/issues/88))
- added missing LICENSE.md files in sub-crates [[@ignatenkobrain](https://github.com/ignatenkobrain)] ([#94](https://github.com/extrawurst/gitui/pull/94))

View File

@ -8,6 +8,7 @@ use git2::{
};
use scopetime::scope_time;
use std::{fs, path::Path};
use utils::work_dir;
/// type of diff of a single line
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
@ -127,12 +128,7 @@ pub fn get_diff(
scope_time!("get_diff");
let repo = utils::repo(repo_path)?;
let repo_path = repo.path().parent().ok_or_else(|| {
Error::Generic(
"repositories located at root are not supported."
.to_string(),
)
})?;
let work_dir = work_dir(&repo);
let diff = get_diff_raw(&repo, &p, stage, false)?;
let mut res: FileDiff = FileDiff::default();
@ -190,7 +186,7 @@ pub fn get_diff(
)
})?;
let newfile_path = repo_path.join(relative_path);
let newfile_path = work_dir.join(relative_path);
if let Some(newfile_content) =
new_file_content(&newfile_path)

View File

@ -0,0 +1,27 @@
use super::utils::{repo, work_dir};
use crate::error::Result;
use scopetime::scope_time;
use std::{fs::OpenOptions, io::Write};
static GITIGNORE: &str = ".gitignore";
/// add file or path to root ignore file
pub fn add_to_ignore(
repo_path: &str,
path_to_ignore: String,
) -> Result<()> {
scope_time!("add_to_ignore");
let repo = repo(repo_path)?;
let ignore_file = work_dir(&repo).join(GITIGNORE);
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open(ignore_file)?;
writeln!(file, "{}", path_to_ignore)?;
Ok(())
}

View File

@ -4,6 +4,7 @@ mod commits_info;
pub mod diff;
mod hooks;
mod hunks;
mod ignore;
mod logwalker;
mod reset;
mod stash;
@ -14,6 +15,7 @@ pub mod utils;
pub use commits_info::{get_commits_info, CommitId, CommitInfo};
pub use hooks::{hooks_commit_msg, hooks_post_commit, HookResult};
pub use hunks::{stage_hunk, unstage_hunk};
pub use ignore::add_to_ignore;
pub use logwalker::LogWalker;
pub use reset::{
reset_stage, reset_workdir_file, reset_workdir_folder,

View File

@ -41,6 +41,11 @@ pub fn repo(repo_path: &str) -> Result<Repository> {
Ok(repo)
}
///
pub fn work_dir(repo: &Repository) -> &Path {
repo.workdir().expect("unable to query workdir")
}
/// this does not run any git hooks
pub fn commit(repo_path: &str, msg: &str) -> Result<Oid> {
scope_time!("commit");

View File

@ -124,6 +124,17 @@ impl ChangesComponent {
}
false
}
fn add_to_ignore(&mut self) -> Result<bool> {
if let Some(tree_item) = self.selection() {
sync::add_to_ignore(CWD, tree_item.info.full_path)?;
self.queue
.borrow_mut()
.push_back(InternalEvent::Update(NeedsUpdate::ALL));
return Ok(true);
}
Ok(false)
}
}
impl DrawableComponent for ChangesComponent {
@ -159,6 +170,11 @@ impl Component for ChangesComponent {
some_selection,
self.focused(),
));
out.push(CommandInfo::new(
commands::IGNORE_ITEM,
some_selection,
self.focused(),
));
} else {
out.push(CommandInfo::new(
commands::UNSTAGE_ITEM,
@ -210,6 +226,13 @@ impl Component for ChangesComponent {
{
Ok(self.dispatch_reset_workdir())
}
keys::STATUS_IGNORE_FILE
if self.is_working_dir
&& !self.is_empty() =>
{
Ok(self.add_to_ignore()?)
}
_ => Ok(false),
};
}

View File

@ -42,6 +42,7 @@ pub const ENTER: KeyEvent = no_mod(KeyCode::Enter);
pub const STATUS_STAGE_FILE: KeyEvent = no_mod(KeyCode::Enter);
pub const STATUS_RESET_FILE: KeyEvent =
with_mod(KeyCode::Char('D'), KeyModifiers::SHIFT);
pub const STATUS_IGNORE_FILE: KeyEvent = no_mod(KeyCode::Char('i'));
pub const STASHING_SAVE: KeyEvent = no_mod(KeyCode::Char('s'));
pub const STASHING_TOGGLE_UNTRACKED: KeyEvent =
no_mod(KeyCode::Char('u'));

View File

@ -140,6 +140,12 @@ pub mod commands {
"revert changes in selected file or entire path",
CMD_GROUP_CHANGES,
);
///
pub static IGNORE_ITEM: CommandText = CommandText::new(
"Ignore [i]",
"Add file or path to .gitignore",
CMD_GROUP_CHANGES,
);
///
pub static STATUS_FOCUS_LEFT: CommandText = CommandText::new(