Merge branch 'ak/rebase-autosquash'

"git rebase --autosquash" is now enabled for non-interactive rebase,
but it is still incompatible with the apply backend.

* ak/rebase-autosquash:
  rebase: rewrite --(no-)autosquash documentation
  rebase: support --autosquash without -i
  rebase: fully ignore rebase.autoSquash without -i
This commit is contained in:
Junio C Hamano
2023-12-09 16:37:50 -08:00
5 changed files with 58 additions and 47 deletions

View File

@@ -9,7 +9,9 @@ rebase.stat::
rebase. False by default.
rebase.autoSquash::
If set to true enable `--autosquash` option by default.
If set to true, enable the `--autosquash` option of
linkgit:git-rebase[1] by default for interactive mode.
This can be overridden with the `--no-autosquash` option.
rebase.autoStash::
When set to true, automatically create a temporary stash entry

View File

@@ -589,21 +589,27 @@ See also INCOMPATIBLE OPTIONS below.
--autosquash::
--no-autosquash::
When the commit log message begins with "squash! ..." or "fixup! ..."
or "amend! ...", and there is already a commit in the todo list that
matches the same `...`, automatically modify the todo list of
`rebase -i`, so that the commit marked for squashing comes right after
the commit to be modified, and change the action of the moved commit
from `pick` to `squash` or `fixup` or `fixup -C` respectively. A commit
matches the `...` if the commit subject matches, or if the `...` refers
to the commit's hash. As a fall-back, partial matches of the commit
subject work, too. The recommended way to create fixup/amend/squash
commits is by using the `--fixup`, `--fixup=amend:` or `--fixup=reword:`
and `--squash` options respectively of linkgit:git-commit[1].
Automatically squash commits with specially formatted messages into
previous commits being rebased. If a commit message starts with
"squash! ", "fixup! " or "amend! ", the remainder of the subject line
is taken as a commit specifier, which matches a previous commit if it
matches the subject line or the hash of that commit. If no commit
matches fully, matches of the specifier with the start of commit
subjects are considered.
+
If the `--autosquash` option is enabled by default using the
configuration variable `rebase.autoSquash`, this option can be
used to override and disable this setting.
In the rebase todo list, the actions of squash, fixup and amend commits are
changed from `pick` to `squash`, `fixup` or `fixup -C`, respectively, and they
are moved right after the commit they modify. The `--interactive` option can
be used to review and edit the todo list before proceeding.
+
The recommended way to create commits with squash markers is by using the
`--squash`, `--fixup`, `--fixup=amend:` or `--fixup=reword:` options of
linkgit:git-commit[1], which take the target commit as an argument and
automatically fill in the subject line of the new commit from that.
+
Settting configuration variable `rebase.autoSquash` to true enables
auto-squashing by default for interactive rebase. The `--no-autosquash`
option can be used to override that setting.
+
See also INCOMPATIBLE OPTIONS below.

View File

@@ -149,7 +149,6 @@ struct rebase_options {
.reapply_cherry_picks = -1, \
.allow_empty_message = 1, \
.autosquash = -1, \
.config_autosquash = -1, \
.rebase_merges = -1, \
.config_rebase_merges = -1, \
.update_refs = -1, \
@@ -711,10 +710,8 @@ static int run_specific_rebase(struct rebase_options *opts)
if (opts->type == REBASE_MERGE) {
/* Run sequencer-based rebase */
setenv("GIT_CHERRY_PICK_HELP", resolvemsg, 1);
if (!(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {
if (!(opts->flags & REBASE_INTERACTIVE_EXPLICIT))
setenv("GIT_SEQUENCE_EDITOR", ":", 1);
opts->autosquash = 0;
}
if (opts->gpg_sign_opt) {
/* remove the leading "-S" */
char *tmp = xstrdup(opts->gpg_sign_opt + 2);
@@ -1405,7 +1402,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||
(options.action != ACTION_NONE) ||
(options.exec.nr > 0) ||
(options.autosquash == -1 && options.config_autosquash == 1) ||
options.autosquash == 1) {
allow_preemptive_ff = 0;
}
@@ -1508,8 +1504,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
if (is_merge(&options))
die(_("apply options and merge options "
"cannot be used together"));
else if (options.autosquash == -1 && options.config_autosquash == 1)
die(_("apply options are incompatible with rebase.autoSquash. Consider adding --no-autosquash"));
else if (options.rebase_merges == -1 && options.config_rebase_merges == 1)
die(_("apply options are incompatible with rebase.rebaseMerges. Consider adding --no-rebase-merges"));
else if (options.update_refs == -1 && options.config_update_refs == 1)
@@ -1529,10 +1523,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
options.rebase_merges = (options.rebase_merges >= 0) ? options.rebase_merges :
((options.config_rebase_merges >= 0) ? options.config_rebase_merges : 0);
if (options.autosquash == 1)
if (options.autosquash == 1) {
imply_merge(&options, "--autosquash");
options.autosquash = (options.autosquash >= 0) ? options.autosquash :
((options.config_autosquash >= 0) ? options.config_autosquash : 0);
} else if (options.autosquash == -1) {
options.autosquash =
options.config_autosquash &&
(options.flags & REBASE_INTERACTIVE_EXPLICIT);
}
if (options.type == REBASE_UNSPECIFIED) {
if (!strcmp(options.default_backend, "merge"))

View File

@@ -43,7 +43,7 @@ test_auto_fixup () {
git tag $1 &&
test_tick &&
git rebase $2 -i HEAD^^^ &&
git rebase $2 HEAD^^^ &&
git log --oneline >actual &&
if test -n "$no_squash"
then
@@ -61,15 +61,24 @@ test_auto_fixup () {
}
test_expect_success 'auto fixup (option)' '
test_auto_fixup final-fixup-option --autosquash
test_auto_fixup fixup-option --autosquash &&
test_auto_fixup fixup-option-i "--autosquash -i"
'
test_expect_success 'auto fixup (config)' '
test_expect_success 'auto fixup (config true)' '
git config rebase.autosquash true &&
test_auto_fixup final-fixup-config-true &&
test_auto_fixup ! fixup-config-true &&
test_auto_fixup fixup-config-true-i -i &&
test_auto_fixup ! fixup-config-true-no --no-autosquash &&
test_auto_fixup ! fixup-config-true-i-no "-i --no-autosquash"
'
test_expect_success 'auto fixup (config false)' '
git config rebase.autosquash false &&
test_auto_fixup ! final-fixup-config-false
test_auto_fixup ! fixup-config-false &&
test_auto_fixup ! fixup-config-false-i -i &&
test_auto_fixup fixup-config-false-yes --autosquash &&
test_auto_fixup fixup-config-false-i-yes "-i --autosquash"
'
test_auto_squash () {
@@ -87,7 +96,7 @@ test_auto_squash () {
git commit -m "squash! first" -m "extra para for first" &&
git tag $1 &&
test_tick &&
git rebase $2 -i HEAD^^^ &&
git rebase $2 HEAD^^^ &&
git log --oneline >actual &&
if test -n "$no_squash"
then
@@ -105,15 +114,24 @@ test_auto_squash () {
}
test_expect_success 'auto squash (option)' '
test_auto_squash final-squash --autosquash
test_auto_squash squash-option --autosquash &&
test_auto_squash squash-option-i "--autosquash -i"
'
test_expect_success 'auto squash (config)' '
test_expect_success 'auto squash (config true)' '
git config rebase.autosquash true &&
test_auto_squash final-squash-config-true &&
test_auto_squash ! squash-config-true &&
test_auto_squash squash-config-true-i -i &&
test_auto_squash ! squash-config-true-no --no-autosquash &&
test_auto_squash ! squash-config-true-i-no "-i --no-autosquash"
'
test_expect_success 'auto squash (config false)' '
git config rebase.autosquash false &&
test_auto_squash ! final-squash-config-false
test_auto_squash ! squash-config-false &&
test_auto_squash ! squash-config-false-i -i &&
test_auto_squash squash-config-false-yes --autosquash &&
test_auto_squash squash-config-false-i-yes "-i --autosquash"
'
test_expect_success 'misspelled auto squash' '

View File

@@ -100,12 +100,6 @@ test_rebase_am_only () {
test_must_fail git rebase $opt --root A
"
test_expect_success "$opt incompatible with rebase.autosquash" "
git checkout B^0 &&
test_must_fail git -c rebase.autosquash=true rebase $opt A 2>err &&
grep -e --no-autosquash err
"
test_expect_success "$opt incompatible with rebase.rebaseMerges" "
git checkout B^0 &&
test_must_fail git -c rebase.rebaseMerges=true rebase $opt A 2>err &&
@@ -118,12 +112,6 @@ test_rebase_am_only () {
grep -e --no-update-refs err
"
test_expect_success "$opt okay with overridden rebase.autosquash" "
test_when_finished \"git reset --hard B^0\" &&
git checkout B^0 &&
git -c rebase.autosquash=true rebase --no-autosquash $opt A
"
test_expect_success "$opt okay with overridden rebase.rebaseMerges" "
test_when_finished \"git reset --hard B^0\" &&
git checkout B^0 &&