summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Jung <tummychow511@gmail.com>2024-02-25 16:27:22 -0500
committerGitHub <noreply@github.com>2024-02-25 16:27:22 -0500
commit64dda70b416c364ed5d7a00f204d0dc397786b84 (patch)
treec6f025ae19ac3522e7eecf8d4a7dec876a15bcb9
parentd29adcb33f3b0cb5b04933cdcf14b544ceb0030f (diff)
parentceed565a99e695fb2a2c8595fdb085d46180bbb6 (diff)
Merge pull request #102 from kiprasmel/always-sha
introduce git config option `absorb.fixupTargetAlwaysSHA`
-rw-r--r--README.md9
-rw-r--r--src/config.rs13
-rw-r--r--src/lib.rs52
3 files changed, 69 insertions, 5 deletions
diff --git a/README.md b/README.md
index 7bd4a5b..9a9480e 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,15 @@ By default, git-absorb will only consider files that you've staged to the index
which tells git-absorb, when no changes are staged, to auto-stage them all, create fixup commits where possible, and unstage remaining changes from the index.
+### Fixup target always SHA
+
+By default, git-absorb will create fixup commits with their messages pointing to the target commit's summary, and if there are duplicate summaries, will fallback to pointing to the target's SHA. Instead, can always point to the target's SHA via:
+
+```ini
+[absorb]
+ fixupTargetAlwaysSHA = true
+```
+
## TODO
- implement force flag
diff --git a/src/config.rs b/src/config.rs
index bc212f0..726fac6 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -7,6 +7,9 @@ pub const ONE_FIXUP_PER_COMMIT_DEFAULT: bool = false;
pub const AUTO_STAGE_IF_NOTHING_STAGED_CONFIG_NAME: &str = "absorb.autoStageIfNothingStaged";
pub const AUTO_STAGE_IF_NOTHING_STAGED_DEFAULT: bool = false;
+pub const FIXUP_TARGET_ALWAYS_SHA_CONFIG_NAME: &str = "absorb.fixupTargetAlwaysSHA";
+pub const FIXUP_TARGET_ALWAYS_SHA_DEFAULT: bool = false;
+
pub fn max_stack(repo: &git2::Repository) -> usize {
match repo
.config()
@@ -36,3 +39,13 @@ pub fn auto_stage_if_nothing_staged(repo: &git2::Repository) -> bool {
_ => AUTO_STAGE_IF_NOTHING_STAGED_DEFAULT,
}
}
+
+pub fn fixup_target_always_sha(repo: &git2::Repository) -> bool {
+ match repo
+ .config()
+ .and_then(|config| config.get_bool(FIXUP_TARGET_ALWAYS_SHA_CONFIG_NAME))
+ {
+ Ok(val) => val,
+ _ => FIXUP_TARGET_ALWAYS_SHA_DEFAULT,
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index f93443a..6450a1a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -271,6 +271,8 @@ fn run_with_repo(config: &Config, repo: &git2::Repository) -> Result<()> {
}
}
+ let target_always_sha: bool = config::fixup_target_always_sha(&repo);
+
hunks_with_commit.sort_by_key(|h| h.dest_commit.id());
// * apply all hunks that are going to be fixed up into `dest_commit`
// * commit the fixup
@@ -301,11 +303,14 @@ fn run_with_repo(config: &Config, repo: &git2::Repository) -> Result<()> {
// https://docs.rs/git2/0.7.5/src/git2/repo.rs.html#998
// https://libgit2.org/libgit2/#HEAD/group/commit/git_commit_create
let dest_commit_id = current.dest_commit.id().to_string();
- let dest_commit_locator = current
- .dest_commit
- .summary()
- .filter(|&msg| summary_counts[msg] == 1)
- .unwrap_or(&dest_commit_id);
+ let dest_commit_locator = match target_always_sha {
+ true => &dest_commit_id,
+ false => current
+ .dest_commit
+ .summary()
+ .filter(|&msg| summary_counts[msg] == 1)
+ .unwrap_or(&dest_commit_id),
+ };
let diff = repo
.diff_tree_to_tree(Some(&head_commit.tree()?), Some(&new_head_tree), None)?
.stats()?;
@@ -730,4 +735,41 @@ lines
assert!(nothing_left_in_index(&ctx.repo).unwrap());
}
+
+ #[test]
+ fn fixup_message_always_commit_sha_if_configured() {
+ let ctx = prepare_and_stage();
+
+ ctx.repo
+ .config()
+ .unwrap()
+ .set_bool(config::FIXUP_TARGET_ALWAYS_SHA_CONFIG_NAME, true)
+ .unwrap();
+
+ // run 'git-absorb'
+ let drain = slog::Discard;
+ let logger = slog::Logger::root(drain, o!());
+ let config = Config {
+ dry_run: false,
+ force: false,
+ base: None,
+ and_rebase: false,
+ whole_file: false,
+ one_fixup_per_commit: true,
+ logger: &logger,
+ };
+ run_with_repo(&config, &ctx.repo).unwrap();
+ assert!(nothing_left_in_index(&ctx.repo).unwrap());
+
+ let mut revwalk = ctx.repo.revwalk().unwrap();
+ revwalk.push_head().unwrap();
+
+ let oids: Vec<git2::Oid> = revwalk.by_ref().collect::<Result<Vec<_>, _>>().unwrap();
+ assert_eq!(oids.len(), 2);
+
+ let commit = ctx.repo.find_commit(oids[0]).unwrap();
+ let actual_msg = commit.summary().unwrap();
+ let expected_msg = format!("fixup! {}", oids[1]);
+ assert_eq!(actual_msg, expected_msg);
+ }
}