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) ![](assets/cmdbar.gif)
### Added ### 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)) - 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)) - 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)) - 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 scopetime::scope_time;
use std::{fs, path::Path}; use std::{fs, path::Path};
use utils::work_dir;
/// type of diff of a single line /// type of diff of a single line
#[derive(Copy, Clone, PartialEq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Hash, Debug)]
@ -127,12 +128,7 @@ pub fn get_diff(
scope_time!("get_diff"); scope_time!("get_diff");
let repo = utils::repo(repo_path)?; let repo = utils::repo(repo_path)?;
let repo_path = repo.path().parent().ok_or_else(|| { let work_dir = work_dir(&repo);
Error::Generic(
"repositories located at root are not supported."
.to_string(),
)
})?;
let diff = get_diff_raw(&repo, &p, stage, false)?; let diff = get_diff_raw(&repo, &p, stage, false)?;
let mut res: FileDiff = FileDiff::default(); 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) = if let Some(newfile_content) =
new_file_content(&newfile_path) 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; pub mod diff;
mod hooks; mod hooks;
mod hunks; mod hunks;
mod ignore;
mod logwalker; mod logwalker;
mod reset; mod reset;
mod stash; mod stash;
@ -14,6 +15,7 @@ pub mod utils;
pub use commits_info::{get_commits_info, CommitId, CommitInfo}; pub use commits_info::{get_commits_info, CommitId, CommitInfo};
pub use hooks::{hooks_commit_msg, hooks_post_commit, HookResult}; pub use hooks::{hooks_commit_msg, hooks_post_commit, HookResult};
pub use hunks::{stage_hunk, unstage_hunk}; pub use hunks::{stage_hunk, unstage_hunk};
pub use ignore::add_to_ignore;
pub use logwalker::LogWalker; pub use logwalker::LogWalker;
pub use reset::{ pub use reset::{
reset_stage, reset_workdir_file, reset_workdir_folder, reset_stage, reset_workdir_file, reset_workdir_folder,

View file

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

View file

@ -124,6 +124,17 @@ impl ChangesComponent {
} }
false 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 { impl DrawableComponent for ChangesComponent {
@ -159,6 +170,11 @@ impl Component for ChangesComponent {
some_selection, some_selection,
self.focused(), self.focused(),
)); ));
out.push(CommandInfo::new(
commands::IGNORE_ITEM,
some_selection,
self.focused(),
));
} else { } else {
out.push(CommandInfo::new( out.push(CommandInfo::new(
commands::UNSTAGE_ITEM, commands::UNSTAGE_ITEM,
@ -210,6 +226,13 @@ impl Component for ChangesComponent {
{ {
Ok(self.dispatch_reset_workdir()) Ok(self.dispatch_reset_workdir())
} }
keys::STATUS_IGNORE_FILE
if self.is_working_dir
&& !self.is_empty() =>
{
Ok(self.add_to_ignore()?)
}
_ => Ok(false), _ => 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_STAGE_FILE: KeyEvent = no_mod(KeyCode::Enter);
pub const STATUS_RESET_FILE: KeyEvent = pub const STATUS_RESET_FILE: KeyEvent =
with_mod(KeyCode::Char('D'), KeyModifiers::SHIFT); 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_SAVE: KeyEvent = no_mod(KeyCode::Char('s'));
pub const STASHING_TOGGLE_UNTRACKED: KeyEvent = pub const STASHING_TOGGLE_UNTRACKED: KeyEvent =
no_mod(KeyCode::Char('u')); no_mod(KeyCode::Char('u'));

View file

@ -140,6 +140,12 @@ pub mod commands {
"revert changes in selected file or entire path", "revert changes in selected file or entire path",
CMD_GROUP_CHANGES, 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( pub static STATUS_FOCUS_LEFT: CommandText = CommandText::new(