зеркало из https://github.com/microsoft/git.git
Merge branch 'en/rebase-consistency'
"git rebase" behaved slightly differently depending on which one of the three backends gets used; this has been documented and an effort to make them more uniform has begun. * en/rebase-consistency: git-rebase: make --allow-empty-message the default t3401: add directory rename testcases for rebase and am git-rebase.txt: document behavioral differences between modes directory-rename-detection.txt: technical docs on abilities and limitations git-rebase.txt: address confusion between --no-ff vs --force-rebase git-rebase: error out when incompatible options passed t3422: new testcases for checking when incompatible options passed git-rebase.sh: update help messages a bit git-rebase.txt: document incompatible options
This commit is contained in:
Коммит
0ce5a698c6
|
@ -243,11 +243,15 @@ leave out at most one of A and B, in which case it defaults to HEAD.
|
|||
--keep-empty::
|
||||
Keep the commits that do not change anything from its
|
||||
parents in the result.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--allow-empty-message::
|
||||
By default, rebasing commits with an empty message will fail.
|
||||
This option overrides that behavior, allowing commits with empty
|
||||
messages to be rebased.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--skip::
|
||||
Restart the rebasing process by skipping the current patch.
|
||||
|
@ -271,6 +275,8 @@ branch on top of the <upstream> branch. Because of this, when a merge
|
|||
conflict happens, the side reported as 'ours' is the so-far rebased
|
||||
series, starting with <upstream>, and 'theirs' is the working branch. In
|
||||
other words, the sides are swapped.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
-s <strategy>::
|
||||
--strategy=<strategy>::
|
||||
|
@ -280,8 +286,10 @@ other words, the sides are swapped.
|
|||
+
|
||||
Because 'git rebase' replays each commit from the working branch
|
||||
on top of the <upstream> branch using the given strategy, using
|
||||
the 'ours' strategy simply discards all patches from the <branch>,
|
||||
the 'ours' strategy simply empties all patches from the <branch>,
|
||||
which makes little sense.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
-X <strategy-option>::
|
||||
--strategy-option=<strategy-option>::
|
||||
|
@ -289,6 +297,8 @@ which makes little sense.
|
|||
This implies `--merge` and, if no strategy has been
|
||||
specified, `-s recursive`. Note the reversal of 'ours' and
|
||||
'theirs' as noted above for the `-m` option.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
-S[<keyid>]::
|
||||
--gpg-sign[=<keyid>]::
|
||||
|
@ -324,17 +334,21 @@ which makes little sense.
|
|||
and after each change. When fewer lines of surrounding
|
||||
context exist they all must match. By default no context is
|
||||
ever ignored.
|
||||
|
||||
-f::
|
||||
--force-rebase::
|
||||
Force a rebase even if the current branch is up to date and
|
||||
the command without `--force` would return without doing anything.
|
||||
+
|
||||
You may find this (or --no-ff with an interactive rebase) helpful after
|
||||
reverting a topic branch merge, as this option recreates the topic branch with
|
||||
fresh commits so it can be remerged successfully without needing to "revert
|
||||
the reversion" (see the
|
||||
link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for details).
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--no-ff::
|
||||
--force-rebase::
|
||||
-f::
|
||||
Individually replay all rebased commits instead of fast-forwarding
|
||||
over the unchanged ones. This ensures that the entire history of
|
||||
the rebased branch is composed of new commits.
|
||||
+
|
||||
You may find this helpful after reverting a topic branch merge, as this option
|
||||
recreates the topic branch with fresh commits so it can be remerged
|
||||
successfully without needing to "revert the reversion" (see the
|
||||
link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for
|
||||
details).
|
||||
|
||||
--fork-point::
|
||||
--no-fork-point::
|
||||
|
@ -355,19 +369,22 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
|
|||
--whitespace=<option>::
|
||||
These flag are passed to the 'git apply' program
|
||||
(see linkgit:git-apply[1]) that applies the patch.
|
||||
Incompatible with the --interactive option.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--committer-date-is-author-date::
|
||||
--ignore-date::
|
||||
These flags are passed to 'git am' to easily change the dates
|
||||
of the rebased commits (see linkgit:git-am[1]).
|
||||
Incompatible with the --interactive option.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--signoff::
|
||||
Add a Signed-off-by: trailer to all the rebased commits. Note
|
||||
that if `--interactive` is given then only commits marked to be
|
||||
picked, edited or reworded will have the trailer added. Incompatible
|
||||
with the `--preserve-merges` option.
|
||||
picked, edited or reworded will have the trailer added.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
-i::
|
||||
--interactive::
|
||||
|
@ -378,6 +395,8 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
|
|||
The commit list format can be changed by setting the configuration option
|
||||
rebase.instructionFormat. A customized instruction format will automatically
|
||||
have the long commit hash prepended to the format.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
-r::
|
||||
--rebase-merges[=(rebase-cousins|no-rebase-cousins)]::
|
||||
|
@ -404,7 +423,7 @@ It is currently only possible to recreate the merge commits using the
|
|||
`recursive` merge strategy; Different merge strategies can be used only via
|
||||
explicit `exec git merge -s <strategy> [...]` commands.
|
||||
+
|
||||
See also REBASING MERGES below.
|
||||
See also REBASING MERGES and INCOMPATIBLE OPTIONS below.
|
||||
|
||||
-p::
|
||||
--preserve-merges::
|
||||
|
@ -415,6 +434,8 @@ See also REBASING MERGES below.
|
|||
This uses the `--interactive` machinery internally, but combining it
|
||||
with the `--interactive` option explicitly is generally not a good
|
||||
idea unless you know what you are doing (see BUGS below).
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
-x <cmd>::
|
||||
--exec <cmd>::
|
||||
|
@ -437,6 +458,8 @@ squash/fixup series.
|
|||
+
|
||||
This uses the `--interactive` machinery internally, but it can be run
|
||||
without an explicit `--interactive`.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--root::
|
||||
Rebase all commits reachable from <branch>, instead of
|
||||
|
@ -447,6 +470,8 @@ without an explicit `--interactive`.
|
|||
When used together with both --onto and --preserve-merges,
|
||||
'all' root commits will be rewritten to have <newbase> as parent
|
||||
instead.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--autosquash::
|
||||
--no-autosquash::
|
||||
|
@ -461,11 +486,11 @@ without an explicit `--interactive`.
|
|||
too. The recommended way to create fixup/squash commits is by using
|
||||
the `--fixup`/`--squash` options of linkgit:git-commit[1].
|
||||
+
|
||||
This option is only valid when the `--interactive` option is used.
|
||||
+
|
||||
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.
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
--autostash::
|
||||
--no-autostash::
|
||||
|
@ -475,17 +500,73 @@ used to override and disable this setting.
|
|||
with care: the final stash application after a successful
|
||||
rebase might result in non-trivial conflicts.
|
||||
|
||||
--no-ff::
|
||||
With --interactive, cherry-pick all rebased commits instead of
|
||||
fast-forwarding over the unchanged ones. This ensures that the
|
||||
entire history of the rebased branch is composed of new commits.
|
||||
+
|
||||
Without --interactive, this is a synonym for --force-rebase.
|
||||
+
|
||||
You may find this helpful after reverting a topic branch merge, as this option
|
||||
recreates the topic branch with fresh commits so it can be remerged
|
||||
successfully without needing to "revert the reversion" (see the
|
||||
link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for details).
|
||||
INCOMPATIBLE OPTIONS
|
||||
--------------------
|
||||
|
||||
git-rebase has many flags that are incompatible with each other,
|
||||
predominantly due to the fact that it has three different underlying
|
||||
implementations:
|
||||
|
||||
* one based on linkgit:git-am[1] (the default)
|
||||
* one based on git-merge-recursive (merge backend)
|
||||
* one based on linkgit:git-cherry-pick[1] (interactive backend)
|
||||
|
||||
Flags only understood by the am backend:
|
||||
|
||||
* --committer-date-is-author-date
|
||||
* --ignore-date
|
||||
* --whitespace
|
||||
* --ignore-whitespace
|
||||
* -C
|
||||
|
||||
Flags understood by both merge and interactive backends:
|
||||
|
||||
* --merge
|
||||
* --strategy
|
||||
* --strategy-option
|
||||
* --allow-empty-message
|
||||
|
||||
Flags only understood by the interactive backend:
|
||||
|
||||
* --[no-]autosquash
|
||||
* --rebase-merges
|
||||
* --preserve-merges
|
||||
* --interactive
|
||||
* --exec
|
||||
* --keep-empty
|
||||
* --autosquash
|
||||
* --edit-todo
|
||||
* --root when used in combination with --onto
|
||||
|
||||
Other incompatible flag pairs:
|
||||
|
||||
* --preserve-merges and --interactive
|
||||
* --preserve-merges and --signoff
|
||||
* --preserve-merges and --rebase-merges
|
||||
* --rebase-merges and --strategy
|
||||
* --rebase-merges and --strategy-option
|
||||
|
||||
BEHAVIORAL DIFFERENCES
|
||||
-----------------------
|
||||
|
||||
* empty commits:
|
||||
|
||||
am-based rebase will drop any "empty" commits, whether the
|
||||
commit started empty (had no changes relative to its parent to
|
||||
start with) or ended empty (all changes were already applied
|
||||
upstream in other commits).
|
||||
|
||||
merge-based rebase does the same.
|
||||
|
||||
interactive-based rebase will by default drop commits that
|
||||
started empty and halt if it hits a commit that ended up empty.
|
||||
The `--keep-empty` option exists for interactive rebases to allow
|
||||
it to keep commits that started empty.
|
||||
|
||||
* directory rename detection:
|
||||
|
||||
merge-based and interactive-based rebases work fine with
|
||||
directory rename detection. am-based rebases sometimes do not.
|
||||
|
||||
include::merge-strategies.txt[]
|
||||
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
Directory rename detection
|
||||
==========================
|
||||
|
||||
Rename detection logic in diffcore-rename that checks for renames of
|
||||
individual files is aggregated and analyzed in merge-recursive for cases
|
||||
where combinations of renames indicate that a full directory has been
|
||||
renamed.
|
||||
|
||||
Scope of abilities
|
||||
------------------
|
||||
|
||||
It is perhaps easiest to start with an example:
|
||||
|
||||
* When all of x/a, x/b and x/c have moved to z/a, z/b and z/c, it is
|
||||
likely that x/d added in the meantime would also want to move to z/d by
|
||||
taking the hint that the entire directory 'x' moved to 'z'.
|
||||
|
||||
More interesting possibilities exist, though, such as:
|
||||
|
||||
* one side of history renames x -> z, and the other renames some file to
|
||||
x/e, causing the need for the merge to do a transitive rename.
|
||||
|
||||
* one side of history renames x -> z, but also renames all files within
|
||||
x. For example, x/a -> z/alpha, x/b -> z/bravo, etc.
|
||||
|
||||
* both 'x' and 'y' being merged into a single directory 'z', with a
|
||||
directory rename being detected for both x->z and y->z.
|
||||
|
||||
* not all files in a directory being renamed to the same location;
|
||||
i.e. perhaps most the files in 'x' are now found under 'z', but a few
|
||||
are found under 'w'.
|
||||
|
||||
* a directory being renamed, which also contained a subdirectory that was
|
||||
renamed to some entirely different location. (And perhaps the inner
|
||||
directory itself contained inner directories that were renamed to yet
|
||||
other locations).
|
||||
|
||||
* combinations of the above; see t/t6043-merge-rename-directories.sh for
|
||||
various interesting cases.
|
||||
|
||||
Limitations -- applicability of directory renames
|
||||
-------------------------------------------------
|
||||
|
||||
In order to prevent edge and corner cases resulting in either conflicts
|
||||
that cannot be represented in the index or which might be too complex for
|
||||
users to try to understand and resolve, a couple basic rules limit when
|
||||
directory rename detection applies:
|
||||
|
||||
1) If a given directory still exists on both sides of a merge, we do
|
||||
not consider it to have been renamed.
|
||||
|
||||
2) If a subset of to-be-renamed files have a file or directory in the
|
||||
way (or would be in the way of each other), "turn off" the directory
|
||||
rename for those specific sub-paths and report the conflict to the
|
||||
user.
|
||||
|
||||
3) If the other side of history did a directory rename to a path that
|
||||
your side of history renamed away, then ignore that particular
|
||||
rename from the other side of history for any implicit directory
|
||||
renames (but warn the user).
|
||||
|
||||
Limitations -- detailed rules and testcases
|
||||
-------------------------------------------
|
||||
|
||||
t/t6043-merge-rename-directories.sh contains extensive tests and commentary
|
||||
which generate and explore the rules listed above. It also lists a few
|
||||
additional rules:
|
||||
|
||||
a) If renames split a directory into two or more others, the directory
|
||||
with the most renames, "wins".
|
||||
|
||||
b) Avoid directory-rename-detection for a path, if that path is the
|
||||
source of a rename on either side of a merge.
|
||||
|
||||
c) Only apply implicit directory renames to directories if the other side
|
||||
of history is the one doing the renaming.
|
||||
|
||||
Limitations -- support in different commands
|
||||
--------------------------------------------
|
||||
|
||||
Directory rename detection is supported by 'merge' and 'cherry-pick'.
|
||||
Other git commands which users might be surprised to see limited or no
|
||||
directory rename detection support in:
|
||||
|
||||
* diff
|
||||
|
||||
Folks have requested in the past that `git diff` detect directory
|
||||
renames and somehow simplify its output. It is not clear whether this
|
||||
would be desirable or how the output should be simplified, so this was
|
||||
simply not implemented. Further, to implement this, directory rename
|
||||
detection logic would need to move from merge-recursive to
|
||||
diffcore-rename.
|
||||
|
||||
* am
|
||||
|
||||
git-am tries to avoid a full three way merge, instead calling
|
||||
git-apply. That prevents us from detecting renames at all, which may
|
||||
defeat the directory rename detection. There is a fallback, though; if
|
||||
the initial git-apply fails and the user has specified the -3 option,
|
||||
git-am will fall back to a three way merge. However, git-am lacks the
|
||||
necessary information to do a "real" three way merge. Instead, it has
|
||||
to use build_fake_ancestor() to get a merge base that is missing files
|
||||
whose rename may have been important to detect for directory rename
|
||||
detection to function.
|
||||
|
||||
* rebase
|
||||
|
||||
Since am-based rebases work by first generating a bunch of patches
|
||||
(which no longer record what the original commits were and thus don't
|
||||
have the necessary info from which we can find a real merge-base), and
|
||||
then calling git-am, this implies that am-based rebases will not always
|
||||
successfully detect directory renames either (see the 'am' section
|
||||
above). merged-based rebases (rebase -m) and cherry-pick-based rebases
|
||||
(rebase -i) are not affected by this shortcoming, and fully support
|
||||
directory rename detection.
|
|
@ -20,23 +20,23 @@ onto=! rebase onto given branch instead of upstream
|
|||
r,rebase-merges? try to rebase merges instead of skipping them
|
||||
p,preserve-merges! try to recreate merges instead of ignoring them
|
||||
s,strategy=! use the given merge strategy
|
||||
X,strategy-option=! pass the argument through to the merge strategy
|
||||
no-ff! cherry-pick all commits, even if unchanged
|
||||
f,force-rebase! cherry-pick all commits, even if unchanged
|
||||
m,merge! use merging strategies to rebase
|
||||
i,interactive! let the user edit the list of commits to rebase
|
||||
x,exec=! add exec lines after each commit of the editable list
|
||||
k,keep-empty preserve empty commits during rebase
|
||||
allow-empty-message allow rebasing commits with empty messages
|
||||
f,force-rebase! force rebase even if branch is up to date
|
||||
X,strategy-option=! pass the argument through to the merge strategy
|
||||
stat! display a diffstat of what changed upstream
|
||||
n,no-stat! do not show diffstat of what changed upstream
|
||||
verify allow pre-rebase hook to run
|
||||
rerere-autoupdate allow rerere to update index with resolved conflicts
|
||||
root! rebase all reachable commits up to the root(s)
|
||||
autosquash move commits that begin with squash!/fixup! under -i
|
||||
signoff add a Signed-off-by: line to each commit
|
||||
committer-date-is-author-date! passed to 'git am'
|
||||
ignore-date! passed to 'git am'
|
||||
signoff passed to 'git am'
|
||||
whitespace=! passed to 'git apply'
|
||||
ignore-whitespace! passed to 'git apply'
|
||||
C=! passed to 'git apply'
|
||||
|
@ -95,7 +95,7 @@ rebase_cousins=
|
|||
preserve_merges=
|
||||
autosquash=
|
||||
keep_empty=
|
||||
allow_empty_message=
|
||||
allow_empty_message=--allow-empty-message
|
||||
signoff=
|
||||
test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
|
||||
case "$(git config --bool commit.gpgsign)" in
|
||||
|
@ -521,6 +521,24 @@ then
|
|||
git_format_patch_opt="$git_format_patch_opt --progress"
|
||||
fi
|
||||
|
||||
if test -n "$git_am_opt"; then
|
||||
incompatible_opts=$(echo " $git_am_opt " | \
|
||||
sed -e 's/ -q / /g' -e 's/^ \(.*\) $/\1/')
|
||||
if test -n "$interactive_rebase"
|
||||
then
|
||||
if test -n "$incompatible_opts"
|
||||
then
|
||||
die "$(gettext "error: cannot combine interactive options (--interactive, --exec, --rebase-merges, --preserve-merges, --keep-empty, --root + --onto) with am options ($incompatible_opts)")"
|
||||
fi
|
||||
fi
|
||||
if test -n "$do_merge"; then
|
||||
if test -n "$incompatible_opts"
|
||||
then
|
||||
die "$(gettext "error: cannot combine merge options (--merge, --strategy, --strategy-option) with am options ($incompatible_opts)")"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$signoff"
|
||||
then
|
||||
test -n "$preserve_merges" &&
|
||||
|
@ -529,6 +547,23 @@ then
|
|||
force_rebase=t
|
||||
fi
|
||||
|
||||
if test -n "$preserve_merges"
|
||||
then
|
||||
# Note: incompatibility with --signoff handled in signoff block above
|
||||
# Note: incompatibility with --interactive is just a strong warning;
|
||||
# git-rebase.txt caveats with "unless you know what you are doing"
|
||||
test -n "$rebase_merges" &&
|
||||
die "$(gettext "error: cannot combine '--preserve_merges' with '--rebase-merges'")"
|
||||
fi
|
||||
|
||||
if test -n "$rebase_merges"
|
||||
then
|
||||
test -n "$strategy_opts" &&
|
||||
die "$(gettext "error: cannot combine '--rebase_merges' with '--strategy-option'")"
|
||||
test -n "$strategy" &&
|
||||
die "$(gettext "error: cannot combine '--rebase_merges' with '--strategy'")"
|
||||
fi
|
||||
|
||||
if test -z "$rebase_root"
|
||||
then
|
||||
case "$#" in
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
#!/bin/sh
|
||||
|
||||
test_description='git rebase + directory rename tests'
|
||||
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY"/lib-rebase.sh
|
||||
|
||||
test_expect_success 'setup testcase' '
|
||||
test_create_repo dir-rename &&
|
||||
(
|
||||
cd dir-rename &&
|
||||
|
||||
mkdir x &&
|
||||
test_seq 1 10 >x/a &&
|
||||
test_seq 11 20 >x/b &&
|
||||
test_seq 21 30 >x/c &&
|
||||
test_write_lines a b c d e f g h i >l &&
|
||||
git add x l &&
|
||||
git commit -m "Initial" &&
|
||||
|
||||
git branch O &&
|
||||
git branch A &&
|
||||
git branch B &&
|
||||
|
||||
git checkout A &&
|
||||
git mv x y &&
|
||||
git mv l letters &&
|
||||
git commit -m "Rename x to y, l to letters" &&
|
||||
|
||||
git checkout B &&
|
||||
echo j >>l &&
|
||||
test_seq 31 40 >x/d &&
|
||||
git add l x/d &&
|
||||
git commit -m "Modify l, add x/d"
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --interactive: directory rename detected' '
|
||||
(
|
||||
cd dir-rename &&
|
||||
|
||||
git checkout B^0 &&
|
||||
|
||||
set_fake_editor &&
|
||||
FAKE_LINES="1" git rebase --interactive A &&
|
||||
|
||||
git ls-files -s >out &&
|
||||
test_line_count = 5 out &&
|
||||
|
||||
test_path_is_file y/d &&
|
||||
test_path_is_missing x/d
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_failure 'rebase (am): directory rename detected' '
|
||||
(
|
||||
cd dir-rename &&
|
||||
|
||||
git checkout B^0 &&
|
||||
|
||||
git rebase A &&
|
||||
|
||||
git ls-files -s >out &&
|
||||
test_line_count = 5 out &&
|
||||
|
||||
test_path_is_file y/d &&
|
||||
test_path_is_missing x/d
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --merge: directory rename detected' '
|
||||
(
|
||||
cd dir-rename &&
|
||||
|
||||
git checkout B^0 &&
|
||||
|
||||
git rebase --merge A &&
|
||||
|
||||
git ls-files -s >out &&
|
||||
test_line_count = 5 out &&
|
||||
|
||||
test_path_is_file y/d &&
|
||||
test_path_is_missing x/d
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_failure 'am: directory rename detected' '
|
||||
(
|
||||
cd dir-rename &&
|
||||
|
||||
git checkout A^0 &&
|
||||
|
||||
git format-patch -1 B &&
|
||||
|
||||
git am --3way 0001*.patch &&
|
||||
|
||||
git ls-files -s >out &&
|
||||
test_line_count = 5 out &&
|
||||
|
||||
test_path_is_file y/d &&
|
||||
test_path_is_missing x/d
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
|
@ -553,15 +553,16 @@ test_expect_success '--continue tries to commit, even for "edit"' '
|
|||
'
|
||||
|
||||
test_expect_success 'aborted --continue does not squash commits after "edit"' '
|
||||
test_when_finished "git rebase --abort" &&
|
||||
old=$(git rev-parse HEAD) &&
|
||||
test_tick &&
|
||||
set_fake_editor &&
|
||||
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
|
||||
echo "edited again" > file7 &&
|
||||
git add file7 &&
|
||||
test_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue &&
|
||||
test $old = $(git rev-parse HEAD) &&
|
||||
git rebase --abort
|
||||
echo all the things >>conflict &&
|
||||
test_must_fail git rebase --continue &&
|
||||
test $old = $(git rev-parse HEAD)
|
||||
'
|
||||
|
||||
test_expect_success 'auto-amend only edited commits after "edit"' '
|
||||
|
|
|
@ -77,19 +77,14 @@ test_expect_success 'rebase commit with diff in message' '
|
|||
'
|
||||
|
||||
test_expect_success 'rebase -m commit with empty message' '
|
||||
test_must_fail git rebase -m master empty-message-merge &&
|
||||
git rebase --abort &&
|
||||
git rebase -m --allow-empty-message master empty-message-merge
|
||||
git rebase -m master empty-message-merge
|
||||
'
|
||||
|
||||
test_expect_success 'rebase -i commit with empty message' '
|
||||
git checkout diff-in-message &&
|
||||
set_fake_editor &&
|
||||
test_must_fail env FAKE_COMMIT_MESSAGE=" " FAKE_LINES="reword 1" \
|
||||
git rebase -i HEAD^ &&
|
||||
git rebase --abort &&
|
||||
FAKE_COMMIT_MESSAGE=" " FAKE_LINES="reword 1" \
|
||||
git rebase -i --allow-empty-message HEAD^
|
||||
env FAKE_COMMIT_MESSAGE=" " FAKE_LINES="reword 1" \
|
||||
git rebase -i HEAD^
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#!/bin/sh
|
||||
|
||||
test_description='test if rebase detects and aborts on incompatible options'
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
test_seq 2 9 >foo &&
|
||||
git add foo &&
|
||||
git commit -m orig &&
|
||||
|
||||
git branch A &&
|
||||
git branch B &&
|
||||
|
||||
git checkout A &&
|
||||
test_seq 1 9 >foo &&
|
||||
git add foo &&
|
||||
git commit -m A &&
|
||||
|
||||
git checkout B &&
|
||||
echo "q qfoo();" | q_to_tab >>foo &&
|
||||
git add foo &&
|
||||
git commit -m B
|
||||
'
|
||||
|
||||
#
|
||||
# Rebase has lots of useful options like --whitepsace=fix, which are
|
||||
# actually all built in terms of flags to git-am. Since neither
|
||||
# --merge nor --interactive (nor any options that imply those two) use
|
||||
# git-am, using them together will result in flags like --whitespace=fix
|
||||
# being ignored. Make sure rebase warns the user and aborts instead.
|
||||
#
|
||||
|
||||
test_rebase_am_only () {
|
||||
opt=$1
|
||||
shift
|
||||
test_expect_success "$opt incompatible with --merge" "
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase $opt --merge A
|
||||
"
|
||||
|
||||
test_expect_success "$opt incompatible with --strategy=ours" "
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase $opt --strategy=ours A
|
||||
"
|
||||
|
||||
test_expect_success "$opt incompatible with --strategy-option=ours" "
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase $opt --strategy-option=ours A
|
||||
"
|
||||
|
||||
test_expect_success "$opt incompatible with --interactive" "
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase $opt --interactive A
|
||||
"
|
||||
|
||||
test_expect_success "$opt incompatible with --exec" "
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase $opt --exec 'true' A
|
||||
"
|
||||
|
||||
}
|
||||
|
||||
test_rebase_am_only --whitespace=fix
|
||||
test_rebase_am_only --ignore-whitespace
|
||||
test_rebase_am_only --committer-date-is-author-date
|
||||
test_rebase_am_only -C4
|
||||
|
||||
test_expect_success '--preserve-merges incompatible with --signoff' '
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase --preserve-merges --signoff A
|
||||
'
|
||||
|
||||
test_expect_success '--preserve-merges incompatible with --rebase-merges' '
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase --preserve-merges --rebase-merges A
|
||||
'
|
||||
|
||||
test_expect_success '--rebase-merges incompatible with --strategy' '
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase --rebase-merges -s resolve A
|
||||
'
|
||||
|
||||
test_expect_success '--rebase-merges incompatible with --strategy-option' '
|
||||
git checkout B^0 &&
|
||||
test_must_fail git rebase --rebase-merges -Xignore-space-change A
|
||||
'
|
||||
|
||||
test_done
|
Загрузка…
Ссылка в новой задаче