Skip to content

Commit c338416

Browse files
authored
Merge pull request #183 from blairconrad/what-next
Tell user how to rebase
2 parents e70893c + 9fd0bf1 commit c338416

File tree

1 file changed

+109
-45
lines changed

1 file changed

+109
-45
lines changed

src/lib.rs

Lines changed: 109 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -453,56 +453,70 @@ fn run_with_repo(logger: &slog::Logger, config: &Config, repo: &git2::Repository
453453
}
454454
}
455455

456-
if config.and_rebase && !hunks_with_commit.is_empty() {
456+
if !hunks_with_commit.is_empty() {
457457
use std::process::Command;
458458
// unwrap() is safe here, as we exit early if the stack is empty
459459
let last_commit_in_stack = &stack.last().unwrap().0;
460460
// The stack isn't supposed to have any merge commits, per the check in working_stack()
461461
let number_of_parents = last_commit_in_stack.parents().len();
462462
assert!(number_of_parents <= 1);
463463

464-
let mut command = Command::new("git");
465-
466-
// We'd generally expect to be run from within the repository, but just in case,
467-
// try to have git run rebase from the repository root.
468-
// This simplifies writing tests that execute from within git-absorb's source directory
469-
// but operate on temporary repositories created elsewhere.
470-
// (The tests could explicitly change directories, but then must be serialized.)
471-
let repo_path = repo.path().parent().and_then(Path::to_str);
472-
match repo_path {
473-
Some(path) => {
474-
command.args(["-C", path]);
475-
}
476-
_ => {
477-
warn!(
478-
logger,
479-
"Could not determine repository path for rebase. Running in current directory."
480-
);
481-
}
482-
}
483-
484-
command.args(["rebase", "--interactive", "--autosquash", "--autostash"]);
485-
486-
for arg in config.rebase_options {
487-
command.arg(arg);
488-
}
489-
490-
if number_of_parents == 0 {
491-
command.arg("--root");
464+
let rebase_root = if number_of_parents == 0 {
465+
"--root"
492466
} else {
493467
// Use a range that is guaranteed to include all the commits we might have
494468
// committed "fixup!" commits for.
495-
let base_commit_sha = last_commit_in_stack.parent(0)?.id().to_string();
496-
command.arg(&base_commit_sha);
497-
}
469+
&*last_commit_in_stack.parent(0)?.id().to_string()
470+
};
498471

499-
if config.dry_run {
500-
info!(logger, "would have run git rebase"; "command" => format!("{:?}", command));
501-
} else {
502-
debug!(logger, "running git rebase"; "command" => format!("{:?}", command));
503-
// Don't check that we have successfully absorbed everything, nor git's
504-
// exit code -- as git will print helpful messages on its own.
505-
command.status().expect("could not run git rebase");
472+
let rebase_args = [
473+
"rebase",
474+
"--interactive",
475+
"--autosquash",
476+
"--autostash",
477+
rebase_root,
478+
];
479+
480+
if config.and_rebase {
481+
let mut command = Command::new("git");
482+
483+
// We'd generally expect to be run from within the repository, but just in case,
484+
// try to have git run rebase from the repository root.
485+
// This simplifies writing tests that execute from within git-absorb's source directory
486+
// but operate on temporary repositories created elsewhere.
487+
// (The tests could explicitly change directories, but then must be serialized.)
488+
let repo_path = repo.path().parent().and_then(Path::to_str);
489+
match repo_path {
490+
Some(path) => {
491+
command.args(["-C", path]);
492+
}
493+
_ => {
494+
warn!(
495+
logger,
496+
"Could not determine repository path for rebase. \
497+
Running in current directory."
498+
);
499+
}
500+
}
501+
502+
command.args(rebase_args);
503+
504+
for arg in config.rebase_options {
505+
command.arg(arg);
506+
}
507+
508+
if config.dry_run {
509+
info!(logger, "would have run git rebase"; "command" => format!("{:?}", command));
510+
} else {
511+
debug!(logger, "running git rebase"; "command" => format!("{:?}", command));
512+
// Don't check that we have successfully absorbed everything, nor git's
513+
// exit code -- as git will print helpful messages on its own.
514+
command.status().expect("could not run git rebase");
515+
}
516+
} else if !config.dry_run {
517+
info!(logger, "To squash the new commits, rebase:";
518+
"command" => format!("git {}", rebase_args.join(" ")),
519+
);
506520
}
507521
}
508522

@@ -654,6 +668,11 @@ mod tests {
654668
vec![
655669
&json!({"level": "INFO", "msg": "committed"}),
656670
&json!({"level": "INFO", "msg": "committed"}),
671+
&json!({
672+
"level": "INFO",
673+
"msg": "To squash the new commits, rebase:",
674+
"command": "git rebase --interactive --autosquash --autostash --root",
675+
}),
657676
],
658677
);
659678
}
@@ -927,10 +946,16 @@ mod tests {
927946

928947
log_utils::assert_log_messages_are(
929948
capturing_logger.visible_logs(),
930-
vec![&json!({
931-
"level": "INFO",
932-
"msg": "committed",
933-
})],
949+
vec![
950+
&json!({"level": "INFO", "msg": "committed",}),
951+
&json!({
952+
"level": "INFO",
953+
"msg": "To squash the new commits, rebase:",
954+
"command": format!(
955+
"git rebase --interactive --autosquash --autostash {}",
956+
merge_commit.id()),
957+
}),
958+
],
934959
);
935960
}
936961

@@ -1073,7 +1098,14 @@ mod tests {
10731098

10741099
log_utils::assert_log_messages_are(
10751100
capturing_logger.visible_logs(),
1076-
vec![&json!({"level": "INFO", "msg": "committed"})],
1101+
vec![
1102+
&json!({"level": "INFO", "msg": "committed"}),
1103+
&json!({
1104+
"level": "INFO",
1105+
"msg": "To squash the new commits, rebase:",
1106+
"command": "git rebase --interactive --autosquash --autostash --root",
1107+
}),
1108+
],
10771109
);
10781110
}
10791111

@@ -1135,6 +1167,11 @@ mod tests {
11351167
vec![
11361168
&json!({"level": "INFO", "msg": "committed"}),
11371169
&json!({"level": "INFO", "msg": "committed"}),
1170+
&json!({
1171+
"level": "INFO",
1172+
"msg": "To squash the new commits, rebase:",
1173+
"command": "git rebase --interactive --autosquash --autostash --root",
1174+
}),
11381175
],
11391176
);
11401177
}
@@ -1162,6 +1199,11 @@ mod tests {
11621199
vec![
11631200
&json!({"level": "INFO", "msg": "committed"}),
11641201
&json!({"level": "INFO", "msg": "committed"}),
1202+
&json!({
1203+
"level": "INFO",
1204+
"msg": "To squash the new commits, rebase:",
1205+
"command": "git rebase --interactive --autosquash --autostash --root",
1206+
}),
11651207
],
11661208
);
11671209
}
@@ -1253,6 +1295,11 @@ mod tests {
12531295
}),
12541296
&json!({"level": "INFO", "msg": "committed"}),
12551297
&json!({"level": "INFO", "msg": "committed"}),
1298+
&json!({
1299+
"level": "INFO",
1300+
"msg": "To squash the new commits, rebase:",
1301+
"command": "git rebase --interactive --autosquash --autostash --root",
1302+
}),
12561303
],
12571304
);
12581305
}
@@ -1283,6 +1330,11 @@ mod tests {
12831330
}),
12841331
&json!({"level": "INFO", "msg": "committed"}),
12851332
&json!({"level": "INFO", "msg": "committed"}),
1333+
&json!({
1334+
"level": "INFO",
1335+
"msg": "To squash the new commits, rebase:",
1336+
"command": "git rebase --interactive --autosquash --autostash --root",
1337+
}),
12861338
],
12871339
);
12881340
}
@@ -1502,7 +1554,14 @@ mod tests {
15021554

15031555
log_utils::assert_log_messages_are(
15041556
capturing_logger.visible_logs(),
1505-
vec![&json!({"level": "INFO", "msg": "committed"})],
1557+
vec![
1558+
&json!({"level": "INFO", "msg": "committed"}),
1559+
&json!({
1560+
"level": "INFO",
1561+
"msg": "To squash the new commits, rebase:",
1562+
"command": "git rebase --interactive --autosquash --autostash --root",
1563+
}),
1564+
],
15061565
);
15071566
}
15081567

@@ -1638,6 +1697,11 @@ mod tests {
16381697
vec![
16391698
&json!({"level": "INFO", "msg": "committed"}),
16401699
&json!({"level": "INFO", "msg": "committed"}),
1700+
&json!({
1701+
"level": "INFO",
1702+
"msg": "To squash the new commits, rebase:",
1703+
"command": "git rebase --interactive --autosquash --autostash --root",
1704+
}),
16411705
],
16421706
);
16431707
}

0 commit comments

Comments
 (0)