diff --git a/imagrc.toml b/imagrc.toml index a2b83804..0e441220 100644 --- a/imagrc.toml +++ b/imagrc.toml @@ -133,6 +133,14 @@ try_checkout_ensure_branch = true # by the other git hooks. enabled = true +# Do a git-add on all files that are not in the index yet, before committing. +# This must be turned on, as we do not support adding with "Update" hooks and +# only committing with the "Drop" hook, yet. +# So, effectively, disabling this will disable committing. +# +# If not set: false +add_wt_changes = true + # Whether to do the commit interactively interactive = false diff --git a/libimagstorestdhook/src/vcs/git/config.rs b/libimagstorestdhook/src/vcs/git/config.rs index ee5871f3..0d33c708 100644 --- a/libimagstorestdhook/src/vcs/git/config.rs +++ b/libimagstorestdhook/src/vcs/git/config.rs @@ -212,3 +212,7 @@ pub fn committing_is_enabled(cfg: &Value) -> Result { .map_err_into(GHEK::ConfigError) } +pub fn add_wt_changes_before_committing(cfg: &Value) -> bool { + get_bool_cfg(Some(cfg), "commit.add_wt_changes", true, true) +} + diff --git a/libimagstorestdhook/src/vcs/git/store_unload.rs b/libimagstorestdhook/src/vcs/git/store_unload.rs index c577bb4e..36e5f812 100644 --- a/libimagstorestdhook/src/vcs/git/store_unload.rs +++ b/libimagstorestdhook/src/vcs/git/store_unload.rs @@ -100,6 +100,7 @@ impl StoreIdAccessor for StoreUnloadHook { use vcs::git::config::abort_on_repo_init_err; use vcs::git::config::is_enabled; use vcs::git::config::committing_is_enabled; + use vcs::git::config::add_wt_changes_before_committing; use git2::StatusOptions; use git2::StatusShow; @@ -111,6 +112,7 @@ impl StoreIdAccessor for StoreUnloadHook { STATUS_WT_DELETED, STATUS_WT_RENAMED, STATUS_WT_MODIFIED}; + use git2::ADD_DEFAULT; let action = StoreAction::StoreUnload; let cfg = try!(self.runtime.config_value_or_err(&action)); @@ -139,27 +141,10 @@ impl StoreIdAccessor for StoreUnloadHook { let repo = try!(self.runtime.repository(&action)); let mut index = try!(fetch_index(repo, &action)); - - let mut status_options = StatusOptions::new(); - status_options.show(StatusShow::Index); - status_options.include_untracked(true); - let status = try!(repo.statuses(Some(&mut status_options)).map(|statuses| { - statuses.iter() - .map(|s| s.status()) - .map(|s| { - debug!("STATUS_INDEX_NEW = {}", s == STATUS_INDEX_NEW); - debug!("STATUS_INDEX_MODIFIED = {}", s == STATUS_INDEX_MODIFIED); - debug!("STATUS_INDEX_DELETED = {}", s == STATUS_INDEX_DELETED); - debug!("STATUS_INDEX_RENAMED = {}", s == STATUS_INDEX_RENAMED); - s - }) - .any(|s| s == STATUS_INDEX_NEW || s == STATUS_INDEX_MODIFIED || s == STATUS_INDEX_DELETED || s == STATUS_INDEX_RENAMED) - }).map_err_into(GHEK::RepositoryError).map_into_hook_error()); - let mut status_options = StatusOptions::new(); status_options.show(StatusShow::Workdir); status_options.include_untracked(true); - let status = status || try!(repo.statuses(Some(&mut status_options)).map(|statuses| { + let wt_dirty = try!(repo.statuses(Some(&mut status_options)).map(|statuses| { statuses.iter() .map(|s| s.status()) .map(|s| { @@ -172,7 +157,37 @@ impl StoreIdAccessor for StoreUnloadHook { .any(|s| s == STATUS_WT_NEW || s == STATUS_WT_MODIFIED || s == STATUS_WT_DELETED || s == STATUS_WT_RENAMED) }).map_err_into(GHEK::RepositoryError).map_into_hook_error()); - if status { + if wt_dirty { + if add_wt_changes_before_committing(cfg) { + debug!("Adding WT changes before committing."); + try!(index.add_all(&["*"], ADD_DEFAULT, None) + .map_err_into(GHEK::RepositoryError) + .map_into_hook_error()); + } else { + warn!("WT dirty, but adding files before committing on Drop disabled."); + warn!("Continuing without adding changes to the index."); + } + } else { + debug!("WT not dirty."); + } + + let mut status_options = StatusOptions::new(); + status_options.show(StatusShow::Index); + status_options.include_untracked(true); + let index_dirty = try!(repo.statuses(Some(&mut status_options)).map(|statuses| { + statuses.iter() + .map(|s| s.status()) + .map(|s| { + debug!("STATUS_INDEX_NEW = {}", s == STATUS_INDEX_NEW); + debug!("STATUS_INDEX_MODIFIED = {}", s == STATUS_INDEX_MODIFIED); + debug!("STATUS_INDEX_DELETED = {}", s == STATUS_INDEX_DELETED); + debug!("STATUS_INDEX_RENAMED = {}", s == STATUS_INDEX_RENAMED); + s + }) + .any(|s| s == STATUS_INDEX_NEW || s == STATUS_INDEX_MODIFIED || s == STATUS_INDEX_DELETED || s == STATUS_INDEX_RENAMED) + }).map_err_into(GHEK::RepositoryError).map_into_hook_error()); + + if index_dirty { debug!("INDEX DIRTY!"); } else { debug!("INDEX CLEAN... not continuing!");