Skip to content

Commit ddda0b7

Browse files
authored
Merge pull request #204 from p1k0chu/118-root-option
Add --no-limit option
2 parents a1de60b + 35e0dd7 commit ddda0b7

File tree

4 files changed

+62
-5
lines changed

4 files changed

+62
-5
lines changed

Documentation/git-absorb.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ FLAGS
5151
--dry-run::
5252
Don't make any actual changes
5353

54+
--no-limit::
55+
Remove absorb stack limit. Has no effect when used with `--base`
56+
+
57+
This will consider all commits until
58+
either root, merge commit, or a commit by other author
59+
(unless `--force-author` is used)
60+
+
61+
Which is why you should be careful when using this flag.
62+
5463
--force-author::
5564
Generate fixups to commits not made by you
5665

@@ -153,6 +162,8 @@ edit your local or global `.gitconfig` and add the following section:
153162
maxStack=50 # Or any other reasonable value for your project
154163
.............................................................................
155164

165+
Stack size can also be disabled temporarily for one command (see `--no-limit`)
166+
156167
ONE FIXUP PER FIXABLE COMMIT
157168
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158169

src/lib.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::path::Path;
1313

1414
pub struct Config<'a> {
1515
pub dry_run: bool,
16+
pub no_limit: bool,
1617
pub force_author: bool,
1718
pub force_detach: bool,
1819
pub base: Option<&'a str>,
@@ -64,6 +65,7 @@ fn run_with_repo(logger: &slog::Logger, config: &Config, repo: &git2::Repository
6465

6566
let (stack, stack_end_reason) = stack::working_stack(
6667
repo,
68+
config.no_limit,
6769
config.base,
6870
config.force_author,
6971
config.force_detach,
@@ -1031,6 +1033,38 @@ lines
10311033
);
10321034
}
10331035

1036+
#[test]
1037+
fn no_stack_limit_exceeds_stack_limit() {
1038+
let (ctx, initial_fp) = repo_utils::prepare_repo();
1039+
let parent_commit = ctx.repo.head().unwrap().peel_to_commit().unwrap();
1040+
repo_utils::empty_commit_chain(&ctx.repo, "HEAD", &[&parent_commit], config::MAX_STACK);
1041+
1042+
repo_utils::stage_file_changes(&ctx, &initial_fp);
1043+
1044+
let config = Config {
1045+
no_limit: true,
1046+
// to have a predictable number of commits for unit test
1047+
one_fixup_per_commit: true,
1048+
..DEFAULT_CONFIG
1049+
};
1050+
1051+
// run 'git-absorb'
1052+
let capturing_logger = log_utils::CapturingLogger::new();
1053+
run_with_repo(&capturing_logger.logger, &config, &ctx.repo).unwrap();
1054+
1055+
let mut revwalk = ctx.repo.revwalk().unwrap();
1056+
revwalk.push_head().unwrap();
1057+
1058+
assert_eq!(
1059+
revwalk.count(),
1060+
// initial + 10 empty + fixup
1061+
config::MAX_STACK + 2,
1062+
"Wrong number of commits."
1063+
);
1064+
1065+
assert!(nothing_left_in_index(&ctx.repo).unwrap());
1066+
}
1067+
10341068
#[test]
10351069
fn reached_root() {
10361070
let (ctx, _) = repo_utils::prepare_repo();
@@ -2073,6 +2107,7 @@ lines
20732107

20742108
const DEFAULT_CONFIG: Config = Config {
20752109
dry_run: false,
2110+
no_limit: false,
20762111
force_author: false,
20772112
force_detach: false,
20782113
base: None,

src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ struct Cli {
1919
/// Don't make any actual changes
2020
#[clap(long, short = 'n')]
2121
dry_run: bool,
22+
/// Remove absorb stack limit. Be careful with this
23+
#[clap(long)]
24+
no_limit: bool,
2225
/// Generate fixups to commits not made by you
2326
#[clap(long)]
2427
force_author: bool,
@@ -58,6 +61,7 @@ fn main() {
5861
let Cli {
5962
base,
6063
dry_run,
64+
no_limit,
6165
force_author,
6266
force_detach,
6367
force,
@@ -120,6 +124,7 @@ fn main() {
120124
base: base.as_deref(),
121125
and_rebase,
122126
rebase_options: &rebase_options,
127+
no_limit,
123128
whole_file,
124129
one_fixup_per_commit,
125130
squash,

src/stack.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub enum StackEndReason {
1616

1717
pub fn working_stack<'repo>(
1818
repo: &'repo git2::Repository,
19+
no_limit: bool,
1920
user_provided_base: Option<&str>,
2021
force_author: bool,
2122
force_detach: bool,
@@ -88,7 +89,7 @@ pub fn working_stack<'repo>(
8889
break;
8990
}
9091

91-
if ret.len() == config::max_stack(repo) && user_provided_base.is_none() {
92+
if !no_limit && ret.len() == config::max_stack(repo) && user_provided_base.is_none() {
9293
debug!(logger, "Stopping at stack limit.";
9394
"limit" => ret.len());
9495
stack_end_reason = Some(StackEndReason::ReachedLimit);
@@ -203,7 +204,8 @@ mod tests {
203204
let commits = repo_utils::empty_commit_chain(&repo, "HEAD", &[], 2);
204205
repo.branch("hide", &commits[0], false).unwrap();
205206

206-
let (stack, reason) = working_stack(&repo, None, false, false, &empty_slog()).unwrap();
207+
let (stack, reason) =
208+
working_stack(&repo, false, None, false, false, &empty_slog()).unwrap();
207209
assert_stack_matches_chain(1, &stack, &commits);
208210
assert_eq!(reason, StackEndReason::CommitsHiddenByBranches);
209211
}
@@ -216,6 +218,7 @@ mod tests {
216218

217219
let (stack, reason) = working_stack(
218220
&repo,
221+
false,
219222
Some(&commits[0].id().to_string()),
220223
false,
221224
false,
@@ -238,7 +241,8 @@ mod tests {
238241
)
239242
.unwrap();
240243

241-
let (stack, reason) = working_stack(&repo, None, false, false, &empty_slog()).unwrap();
244+
let (stack, reason) =
245+
working_stack(&repo, false, None, false, false, &empty_slog()).unwrap();
242246
assert_stack_matches_chain(config::MAX_STACK + 1, &stack, &commits);
243247
assert_eq!(reason, StackEndReason::ReachedLimit);
244248
}
@@ -254,7 +258,8 @@ mod tests {
254258
let new_commits =
255259
repo_utils::empty_commit_chain(&repo, "HEAD", &[old_commits.last().unwrap()], 2);
256260

257-
let (stack, reason) = working_stack(&repo, None, false, false, &empty_slog()).unwrap();
261+
let (stack, reason) =
262+
working_stack(&repo, false, None, false, false, &empty_slog()).unwrap();
258263
assert_stack_matches_chain(2, &stack, &new_commits);
259264
assert_eq!(reason, StackEndReason::ReachedAnotherAuthor);
260265
}
@@ -265,7 +270,8 @@ mod tests {
265270
let merge = repo_utils::merge_commit(&repo, &[]);
266271
let commits = repo_utils::empty_commit_chain(&repo, "HEAD", &[&merge], 2);
267272

268-
let (stack, reason) = working_stack(&repo, None, false, false, &empty_slog()).unwrap();
273+
let (stack, reason) =
274+
working_stack(&repo, false, None, false, false, &empty_slog()).unwrap();
269275
assert_stack_matches_chain(2, &stack, &commits);
270276
assert_eq!(reason, StackEndReason::ReachedMergeCommit);
271277
}

0 commit comments

Comments
 (0)