Skip to content

Commit

Permalink
Merge branch 'ak/rebase-autosquash'
Browse files Browse the repository at this point in the history
"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
  • Loading branch information
gitster committed Dec 10, 2023
2 parents 98d0a1f + cb00f52 commit f8f87e0
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 47 deletions.
4 changes: 3 additions & 1 deletion Documentation/config/rebase.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 20 additions & 14 deletions Documentation/git-rebase.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
17 changes: 7 additions & 10 deletions builtin/rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand All @@ -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"))
Expand Down
38 changes: 28 additions & 10 deletions t/t3415-rebase-autosquash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 () {
Expand All @@ -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
Expand All @@ -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' '
Expand Down
12 changes: 0 additions & 12 deletions t/t3422-rebase-incompatible-options.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand All @@ -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 &&
Expand Down

0 comments on commit f8f87e0

Please sign in to comment.