summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Jung <tummychow511@gmail.com>2024-02-22 22:29:12 -0500
committerGitHub <noreply@github.com>2024-02-22 22:29:12 -0500
commit172ee0f1525c8a23e0e80854928917b44856e795 (patch)
treed4da2637a718adda8c14693035f4f59526b80a28
parent656261484570534ac4ce8d373bfea8c32b8910d1 (diff)
parentd6128a307a56955d7013597b5a2c98fd836aff1d (diff)
Merge pull request #101 from kiprasmel/config-one-commit-per-fixup
introduce git config option `absorb.oneFixupPerCommit`
-rw-r--r--README.md10
-rw-r--r--src/config.rs25
-rw-r--r--src/lib.rs16
-rw-r--r--src/main.rs2
-rw-r--r--src/stack.rs24
5 files changed, 59 insertions, 18 deletions
diff --git a/README.md b/README.md
index ae29a89..6a568cd 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,16 @@ edit your local or global `.gitconfig` and add the following section
maxStack=50 # Or any other reasonable value for your project
```
+### One fixup per fixable commit
+
+By default, git-absorb will generate separate fixup commits for every absorbable hunk. Instead, can use the `-F` flag to create only 1 fixup commit for all hunks that absorb into the same commit.
+To always have this behavior, set
+
+```ini
+[absorb]
+ oneFixupPerCommit = true
+```
+
## TODO
- implement force flag
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..84cd601
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,25 @@
+pub const MAX_STACK_CONFIG_NAME: &str = "absorb.maxStack";
+pub const MAX_STACK: usize = 10;
+
+pub const ONE_FIXUP_PER_COMMIT_CONFIG_NAME: &str = "absorb.oneFixupPerCommit";
+pub const ONE_FIXUP_PER_COMMIT_DEFAULT: bool = false;
+
+pub fn max_stack(repo: &git2::Repository) -> usize {
+ match repo
+ .config()
+ .and_then(|config| config.get_i64(MAX_STACK_CONFIG_NAME))
+ {
+ Ok(max_stack) if max_stack > 0 => max_stack as usize,
+ _ => MAX_STACK,
+ }
+}
+
+pub fn one_fixup_per_commit(repo: &git2::Repository) -> bool {
+ match repo
+ .config()
+ .and_then(|config| config.get_bool(ONE_FIXUP_PER_COMMIT_CONFIG_NAME))
+ {
+ Ok(one_commit_per_fixup) => one_commit_per_fixup,
+ _ => ONE_FIXUP_PER_COMMIT_DEFAULT,
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index fe9e3e6..6898f91 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,7 @@ extern crate slog;
use anyhow::{anyhow, Result};
mod commute;
+mod config;
mod owned;
mod stack;
@@ -18,9 +19,22 @@ pub struct Config<'a> {
pub logger: &'a slog::Logger,
}
-pub fn run(config: &Config) -> Result<()> {
+pub fn run(config: &mut Config) -> Result<()> {
let repo = git2::Repository::open_from_env()?;
debug!(config.logger, "repository found"; "path" => repo.path().to_str());
+
+ // here, we default to the git config value,
+ // if the flag was not provided in the CLI.
+ //
+ // in the future, we'd likely want to differentiate between
+ // a "non-provided" option, vs an explicit --no-<option>
+ // that disables a behavior, much like git does.
+ // e.g. user may want to overwrite a config value with
+ // --no-one-fixup-per-commit -- then, defaulting to the config value
+ // like we do here is no longer sufficient. but until then, this is fine.
+ //
+ config.one_fixup_per_commit |= config::one_fixup_per_commit(&repo);
+
run_with_repo(config, &repo)
}
diff --git a/src/main.rs b/src/main.rs
index 5ee6fef..26d0edc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -113,7 +113,7 @@ fn main() {
));
}
- if let Err(e) = git_absorb::run(&git_absorb::Config {
+ if let Err(e) = git_absorb::run(&mut git_absorb::Config {
dry_run: args.is_present("dry-run"),
force: args.is_present("force"),
base: args.value_of("base"),
diff --git a/src/stack.rs b/src/stack.rs
index 47b00dd..503a467 100644
--- a/src/stack.rs
+++ b/src/stack.rs
@@ -2,18 +2,7 @@ use anyhow::{anyhow, Result};
use std::collections::HashMap;
-pub const MAX_STACK_CONFIG_NAME: &str = "absorb.maxStack";
-pub const MAX_STACK: usize = 10;
-
-fn max_stack(repo: &git2::Repository) -> usize {
- match repo
- .config()
- .and_then(|config| config.get_i64(MAX_STACK_CONFIG_NAME))
- {
- Ok(max_stack) if max_stack > 0 => max_stack as usize,
- _ => MAX_STACK,
- }
-}
+use crate::config;
pub fn working_stack<'repo>(
repo: &'repo git2::Repository,
@@ -87,7 +76,7 @@ pub fn working_stack<'repo>(
break;
}
}
- if ret.len() == max_stack(repo) && user_provided_base.is_none() {
+ if ret.len() == config::max_stack(repo) && user_provided_base.is_none() {
warn!(logger, "stack limit reached, use --base or configure absorb.maxStack to override";
"limit" => ret.len());
break;
@@ -230,14 +219,17 @@ mod tests {
#[test]
fn test_stack_stops_at_configured_limit() {
let (_dir, repo) = init_repo();
- let commits = empty_commit_chain(&repo, "HEAD", &[], MAX_STACK + 2);
+ let commits = empty_commit_chain(&repo, "HEAD", &[], config::MAX_STACK + 2);
repo.config()
.unwrap()
- .set_i64(MAX_STACK_CONFIG_NAME, (MAX_STACK + 1) as i64)
+ .set_i64(
+ config::MAX_STACK_CONFIG_NAME,
+ (config::MAX_STACK + 1) as i64,
+ )
.unwrap();
assert_stack_matches_chain(
- MAX_STACK + 1,
+ config::MAX_STACK + 1,
&working_stack(&repo, None, false, &empty_slog()).unwrap(),
&commits,
);