[RFC PATCH v2 5/7] git-rebase.txt: document behavioral inconsistencies between modes

2018-06-16 Thread Elijah Newren
There are a variety of aspects that are common to all rebases regardless
of which backend is in use; however, the behavior for these different
aspects varies in ways that could surprise users.  (In fact, it's not
clear -- to me at least -- that these differences were even desirable or
intentional.)  Document these differences.

Signed-off-by: Elijah Newren 
---
 Documentation/git-rebase.txt | 57 
 1 file changed, 57 insertions(+)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index adccc15284..0dbfab06d0 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -555,6 +555,63 @@ Other incompatible flag pairs:
  * --preserve-merges && --rebase-merges
  * --rebase-merges && --strategy
 
+BEHAVIORAL INCONSISTENCIES
+--
+
+  * --no-ff vs. --force-rebase
+
+These options are actually identical, though their description
+leads people to believe they might not be.
+
+ * 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.
+
+  * empty commit messages:
+
+am-based rebase will silently apply commits with empty commit
+messages.
+
+merge-based and interactive-based rebases will by default halt
+on any such commits.  The --allow-empty-message option exists to
+allow interactive-based rebases to apply such commits without
+halting.
+
+  * directory rename detection:
+
+merge-based and interactive-based rebases work fine with
+directory rename detection.  am-based rebases sometimes do not.
+
+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.
+
+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.  merged-based rebases (rebase -m) and
+cherry-pick-based rebases (rebase -i) are not affected by this
+shortcoming.
+
 include::merge-strategies.txt[]
 
 NOTES
-- 
2.18.0.rc2.1.g5453d3f70b.dirty



[RFC PATCH v2 4/7] git-rebase: error out when incompatible options passed

2018-06-16 Thread Elijah Newren
git rebase has three different types: am, merge, and interactive, all of
which are implemented in terms of separate scripts.  am builds on git-am,
merge builds on git-merge-recursive, and interactive builds on
git-cherry-pick.  We make use of features in those lower-level commands in
the different rebase types, but those features don't exist in all of the
lower level commands so we have a range of incompatibilities.  Previously,
we just accepted nearly any argument and silently ignored whichever ones
weren't implemented for the type of rebase specified.  Change this so the
incompatibilities are documented, included in the testsuite, and tested
for at runtime with an appropriate error message shown.

Some exceptions I left out:

  * --merge and --interactive are technically incompatible since they are
supposed to run different underlying scripts, but with a few small
changes, --interactive can do everything that --merge can.  In fact,
I'll shortly be sending another patch to remove git-rebase--merge and
reimplement it on top of git-rebase--interactive.

  * One could argue that --interactive and --quiet are incompatible since
--interactive doesn't implement a --quiet mode (perhaps since
cherry-pick itself does not implement one).  However, the interactive
mode is more quiet than the other modes in general with progress
messages, so one could argue that it's already quiet.

Signed-off-by: Elijah Newren 
---
 git-rebase.sh  | 17 +
 t/t3422-rebase-incompatible-options.sh | 10 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/git-rebase.sh b/git-rebase.sh
index bf71b7fa20..5f891214fa 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -503,6 +503,23 @@ 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//')
+   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" &&
diff --git a/t/t3422-rebase-incompatible-options.sh 
b/t/t3422-rebase-incompatible-options.sh
index 04cdae921b..66a83363bf 100755
--- a/t/t3422-rebase-incompatible-options.sh
+++ b/t/t3422-rebase-incompatible-options.sh
@@ -34,27 +34,27 @@ test_expect_success 'setup' '
 test_run_rebase () {
opt=$1
shift
-   test_expect_failure "$opt incompatible with --merge" "
+   test_expect_success "$opt incompatible with --merge" "
git checkout B^0 &&
test_must_fail git rebase $opt --merge A
"
 
-   test_expect_failure "$opt incompatible with --strategy=ours" "
+   test_expect_success "$opt incompatible with --strategy=ours" "
git checkout B^0 &&
test_must_fail git rebase $opt --strategy=ours A
"
 
-   test_expect_failure "$opt incompatible with --strategy-option=ours" "
+   test_expect_success "$opt incompatible with --strategy-option=ours" "
git checkout B^0 &&
test_must_fail git rebase $opt --strategy=ours A
"
 
-   test_expect_failure "$opt incompatible with --interactive" "
+   test_expect_success "$opt incompatible with --interactive" "
git checkout B^0 &&
test_must_fail git rebase $opt --interactive A
"
 
-   test_expect_failure "$opt incompatible with --exec" "
+   test_expect_success "$opt incompatible with --exec" "
git checkout B^0 &&
test_must_fail git rebase $opt --exec 'true' A
"
-- 
2.18.0.rc2.1.g5453d3f70b.dirty



[RFC PATCH v2 6/7] git-rebase.txt: address confusion between --no-ff vs --force-rebase

2018-06-16 Thread Elijah Newren
rebase was taught the --force-rebase option in commit b2f82e05de ("Teach
rebase to rebase even if upstream is up to date", 2009-02-13).  This flag
worked for the am and merge backends, but wasn't a valid option for the
interactive backend.

rebase was taught the --no-ff option for interactive rebases in commit
b499549401cb ("Teach rebase the --no-ff option.", 2010-03-24), to do the
exact same thing as --force-rebase does for non-interactive rebases.  This
commit explicitly documented the fact that --force-rebase was incompatible
with --interactive, though it made --no-ff a synonym for --force-rebase
for non-interactive rebases.  The choice of a new option was based on the
fact that "force rebase" didn't sound like an appropriate term for the
interactive machinery.

In commit 6bb4e485cff8 ("rebase: align variable names", 2011-02-06), the
separate parsing of command line options in the different rebase scripts
was removed, and whether on accident or because the author noticed that
these options did the same thing, the options became synonyms and both
were accepted by all three rebase types.

In commit 2d26d533a012 ("Documentation/git-rebase.txt: -f forces a rebase
that would otherwise be a no-op", 2014-08-12), which reworded the
description of the --force-rebase option, the (no-longer correct) sentence
stating that --force-rebase was incompatible with --interactive was
finally removed.

Finally, as explained at
https://public-inbox.org/git/98279912-0f52-969d-44a6-222420393...@xiplink.com

In the original discussion around this option [1], at one point I
proposed teaching rebase--interactive to respect --force-rebase
instead of adding a new option [2].  Ultimately --no-ff was chosen as
the better user interface design [3], because an interactive rebase
can't be "forced" to run.

We have accepted both --no-ff and --force-rebase as full synonyms for all
three rebase types for over seven years.  Documenting them differently
and in ways that suggest they might not be quite synonyms simply leads to
confusion.  Adjust the documentation to match reality.

Signed-off-by: Elijah Newren 
---
 Documentation/git-rebase.txt | 35 ++-
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 0dbfab06d0..7a2ed9efdc 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -337,16 +337,18 @@ See also INCOMPATIBLE OPTIONS below.
 +
 See also INCOMPATIBLE OPTIONS below.
 
--f::
+--no-ff::
 --force-rebase::
-   Force a rebase even if the current branch is up to date and
-   the command without `--force` would return without doing anything.
+-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 (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).
+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::
@@ -498,18 +500,6 @@ See also INCOMPATIBLE OPTIONS below.
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
 
 
@@ -558,11 +548,6 @@ Other incompatible flag pairs:
 BEHAVIORAL INCONSISTENCIES
 --
 
-  * --no-ff vs. --force-rebase
-
-These options are actually identical, though their description
-leads people to believe they might not be.
-
  * empty commits:
 
 am-based rebase will drop any "empty" commits, whether the
-- 
2.18.0.rc2.1.g5453d3f70b.dirty



[RFC PATCH v2 7/7] git-rebase: make --allow-empty-message the default

2018-06-16 Thread Elijah Newren
am-based rebases already apply commits with an empty commit message
without requiring the user to specify an extra flag.  Make merge-based and
interactive-based rebases behave the same.

Signed-off-by: Elijah Newren 
---
 Documentation/git-rebase.txt  | 10 --
 git-rebase.sh |  2 +-
 t/t3404-rebase-interactive.sh |  7 ---
 t/t3405-rebase-malformed.sh   | 11 +++
 4 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 7a2ed9efdc..a5608f481f 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -562,16 +562,6 @@ BEHAVIORAL INCONSISTENCIES
 The --keep-empty option exists for interactive rebases to allow
 it to keep commits that started empty.
 
-  * empty commit messages:
-
-am-based rebase will silently apply commits with empty commit
-messages.
-
-merge-based and interactive-based rebases will by default halt
-on any such commits.  The --allow-empty-message option exists to
-allow interactive-based rebases to apply such commits without
-halting.
-
   * directory rename detection:
 
 merge-based and interactive-based rebases work fine with
diff --git a/git-rebase.sh b/git-rebase.sh
index 5f891214fa..bf033da4e5 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -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
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index c65826ddac..f84fa63b15 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -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"' '
diff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh
index cb7c6de84a..da94dddc86 100755
--- a/t/t3405-rebase-malformed.sh
+++ b/t/t3405-rebase-malformed.sh
@@ -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
-- 
2.18.0.rc2.1.g5453d3f70b.dirty



[RFC PATCH v2 2/7] git-rebase.sh: update help messages a bit

2018-06-16 Thread Elijah Newren
signoff is not specific to the am-backend.  Also, re-order a few options
to make like things (e.g. strategy and strategy-option) be near each
other.
---
 git-rebase.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/git-rebase.sh b/git-rebase.sh
index 40be59ecc4..bf71b7fa20 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -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
+signoffadd a Signed-off-by: line to each commit
 committer-date-is-author-date! passed to 'git am'
 ignore-date!   passed to 'git am'
-signoffpassed to 'git am'
 whitespace=!   passed to 'git apply'
 ignore-whitespace! passed to 'git apply'
 C=!passed to 'git apply'
-- 
2.18.0.rc2.1.g5453d3f70b.dirty



[RFC PATCH v2 1/7] git-rebase.txt: document incompatible options

2018-06-16 Thread Elijah Newren
git rebase has many options that only work with one of its three backends.
It also has a few other pairs of incompatible options.  Document these.

Signed-off-by: Elijah Newren 
---
 Documentation/git-rebase.txt | 84 
 1 file changed, 76 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 0e20a66e73..adccc15284 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -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  branch.  Because of this, 
when a merge
 conflict happens, the side reported as 'ours' is the so-far rebased
 series, starting with , and 'theirs' is the working branch.  In
 other words, the sides are swapped.
++
+See also INCOMPATIBLE OPTIONS below.
 
 -s ::
 --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  branch using the given strategy, using
-the 'ours' strategy simply discards all patches from the ,
+the 'ours' strategy simply empties all patches from the ,
 which makes little sense.
++
+See also INCOMPATIBLE OPTIONS below.
 
 -X ::
 --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[]::
 --gpg-sign[=]::
@@ -324,6 +334,8 @@ 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.
++
+See also INCOMPATIBLE OPTIONS below.
 
 -f::
 --force-rebase::
@@ -355,19 +367,22 @@ default is `--no-fork-point`, otherwise the default is 
`--fork-point`.
 --whitespace=::
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 +393,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 +421,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  [...]` commands.
 +
-See also REBASING MERGES below.
+See also REBASING MERGES and INCOMPATIBLE OPTIONS below.
 
 -p::
 --preserve-merges::
@@ -415,6 +432,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 ::
 --exec ::
@@ -437,6 +456,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 , instead of
@@ -447,6 +468,8 @@ without an explicit `--interactive`.
When used together with both --onto and --preserve-merges,
'all' root commits will be rewritten to have  as parent
instead.
++
+See also INCOMPATIBLE OPTIONS below.
 
 --autosquash::
 --no-autosquash::
@@ -461,11 +484,11 @@ without an explicit `--interactive`.
too.  

[RFC PATCH v2 3/7] t3422: new testcases for checking when incompatible options passed

2018-06-16 Thread Elijah Newren
git rebase is split into three types: am, merge, and interactive.  Various
options imply different types, and which mode we are using determine which
sub-script (git-rebase--$type) is executed to finish the work.  Not all
options work with all types, so add tests for combinations where we expect
to receive an error rather than having options be silently ignored.

Signed-off-by: Elijah Newren 
---
 t/t3422-rebase-incompatible-options.sh | 69 ++
 1 file changed, 69 insertions(+)
 create mode 100755 t/t3422-rebase-incompatible-options.sh

diff --git a/t/t3422-rebase-incompatible-options.sh 
b/t/t3422-rebase-incompatible-options.sh
new file mode 100755
index 00..04cdae921b
--- /dev/null
+++ b/t/t3422-rebase-incompatible-options.sh
@@ -0,0 +1,69 @@
+#!/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 &&
+   # This is indented with HT SP HT.
+   echo "  foo();" >>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_run_rebase () {
+   opt=$1
+   shift
+   test_expect_failure "$opt incompatible with --merge" "
+   git checkout B^0 &&
+   test_must_fail git rebase $opt --merge A
+   "
+
+   test_expect_failure "$opt incompatible with --strategy=ours" "
+   git checkout B^0 &&
+   test_must_fail git rebase $opt --strategy=ours A
+   "
+
+   test_expect_failure "$opt incompatible with --strategy-option=ours" "
+   git checkout B^0 &&
+   test_must_fail git rebase $opt --strategy=ours A
+   "
+
+   test_expect_failure "$opt incompatible with --interactive" "
+   git checkout B^0 &&
+   test_must_fail git rebase $opt --interactive A
+   "
+
+   test_expect_failure "$opt incompatible with --exec" "
+   git checkout B^0 &&
+   test_must_fail git rebase $opt --exec 'true' A
+   "
+
+}
+
+test_run_rebase --whitespace=fix
+test_run_rebase --ignore-whitespace
+test_run_rebase --committer-date-is-author-date
+test_run_rebase -C4
+
+test_done
-- 
2.18.0.rc2.1.g5453d3f70b.dirty



[RFC PATCH v2 0/7] Document/fix/warn about rebase incompatibilities and inconsistences

2018-06-16 Thread Elijah Newren
git-rebase has lots of options that are mutually incompatible.  Even among
aspects of its behavior that is common to all rebase types, it has a number
of inconsistencies.  This series tries to document, fix, and/or warn users
about many of these.

I have a much higher than average expectation that folks will object
to some of these patches.  I've tried to divide them up so that any parts
we decide to drop or redo can be more easily excised.

No branch-diff; because it's a significant re-work; instead I'll comment
briefly on the individual patches...


Elijah Newren (7):
  git-rebase.txt: document incompatible options

Both Dscho (on a related patch series) and Phillip suggested changing the
documentation to avoid implementational details.  I instead made a separate
section with sets of incompatible options...but it still mentions the
different backends while doing so.  Does that seem alright?

  git-rebase.sh: update help messages a bit

Minor tweaks to `git rebase -h` output.

  t3422: new testcases for checking when incompatible options passed

The one unmodified patch from the first round.

  git-rebase: error out when incompatible options passed

Almost the same as the first round, except:
  * Documentation pulled into a separate patch (patch 1)
  * $() instead of ``

  git-rebase.txt: document behavioral inconsistencies between modes

Add another section to the documentation for aspects that ideally
should be common between all modes but are handled differently.

  git-rebase.txt: address confusion between --no-ff vs --force-rebase

This came up on the list not that long ago; fix the documentation.

  git-rebase: make --allow-empty-message the default

Address the easiest of the inconsistencies, assuming the am-based backend
has the correct default and the merge-based and interactive-based backends
are the ones that need to change.

 Documentation/git-rebase.txt   | 154 -
 git-rebase.sh  |  25 +++-
 t/t3404-rebase-interactive.sh  |   7 +-
 t/t3405-rebase-malformed.sh|  11 +-
 t/t3422-rebase-incompatible-options.sh |  69 +++
 5 files changed, 224 insertions(+), 42 deletions(-)
 create mode 100755 t/t3422-rebase-incompatible-options.sh

-- 
2.18.0.rc2.1.g5453d3f70b.dirty


[PATCH v2] sequencer: do not squash 'reword' commits when we hit conflicts

2018-06-16 Thread Elijah Newren
Ever since commit 18633e1a22 ("rebase -i: use the rebase--helper builtin",
2017-02-09), when a commit marked as 'reword' in an interactive rebase
has conflicts and fails to apply, when the rebase is resumed that commit
will be squashed into its parent with its commit message taken.

The issue can be understood better by looking at commit 56dc3ab04b
("sequencer (rebase -i): implement the 'edit' command", 2017-01-02), which
introduced error_with_patch() for the edit command.  For the edit command,
it needs to stop the rebase whether or not the patch applies cleanly.  If
the patch does apply cleanly, then when it resumes it knows it needs to
amend all changes into the previous commit.  If it does not apply cleanly,
then the changes should not be amended.  Thus, it passes !res (success of
applying the 'edit' commit) to error_with_patch() for the to_amend flag.

The problematic line of code actually came from commit 04efc8b57c
("sequencer (rebase -i): implement the 'reword' command", 2017-01-02).
Note that to get to this point in the code:
  * !!res (i.e. patch application failed)
  * item->command < TODO_SQUASH
  * item->command != TODO_EDIT
  * !is_fixup(item->command) [i.e. not squash or fixup]
So that means this can only be a failed patch application that is either a
pick, revert, or reword.  For any of those cases we want a new commit, so
we should not set the to_amend flag.

Signed-off-by: Elijah Newren 
---
Differences since v1 (Thanks to Eric Sunshine for the suggestions):
  * Add test_when_finished "reset_rebase" calls
  * Remove unnecessary word from description of test

 sequencer.c  |  2 +-
 t/t3423-rebase-reword.sh | 48 
 2 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100755 t/t3423-rebase-reword.sh

diff --git a/sequencer.c b/sequencer.c
index cca968043e..9e6d1ee368 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -3217,7 +3217,7 @@ static int pick_commits(struct todo_list *todo_list, 
struct replay_opts *opts)
} else if (res && is_rebase_i(opts) && item->commit)
return res | error_with_patch(item->commit,
item->arg, item->arg_len, opts, res,
-   item->command == TODO_REWORD);
+   0);
} else if (item->command == TODO_EXEC) {
char *end_of_arg = (char *)(item->arg + item->arg_len);
int saved = *end_of_arg;
diff --git a/t/t3423-rebase-reword.sh b/t/t3423-rebase-reword.sh
new file mode 100755
index 00..6963750794
--- /dev/null
+++ b/t/t3423-rebase-reword.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+test_description='git rebase interactive with rewording'
+
+. ./test-lib.sh
+
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+test_expect_success 'setup' '
+   test_commit master file-1 test &&
+
+   git checkout -b stuff &&
+
+   test_commit feature_a file-2 aaa &&
+   test_commit feature_b file-2 ddd
+'
+
+test_expect_success 'reword without issues functions as intended' '
+   test_when_finished "reset_rebase" &&
+
+   git checkout stuff^0 &&
+
+   set_fake_editor &&
+   FAKE_LINES="pick 1 reword 2" FAKE_COMMIT_MESSAGE="feature_b_reworded" \
+   git rebase -i -v master &&
+
+   test "$(git log -1 --format=%B)" = "feature_b_reworded" &&
+   test $(git rev-list --count HEAD) = 3
+'
+
+test_expect_success 'reword after a conflict preserves commit' '
+   test_when_finished "reset_rebase" &&
+
+   git checkout stuff^0 &&
+
+   set_fake_editor &&
+   test_must_fail env FAKE_LINES="reword 2" \
+   git rebase -i -v master &&
+
+   git checkout --theirs file-2 &&
+   git add file-2 &&
+   FAKE_COMMIT_MESSAGE="feature_b_reworded" git rebase --continue &&
+
+   test "$(git log -1 --format=%B)" = "feature_b_reworded" &&
+   test $(git rev-list --count HEAD) = 2
+'
+
+test_done
-- 
2.18.0.rc2.1.g5453d3f70b.dirty


[PATCH v2 signed off] doc: fix typos in documentation and release notes

2018-06-16 Thread Xtreak
Signed-off-by: Karthikeyan Singaravelan 
---
 Documentation/RelNotes/1.7.11.7.txt | 2 +-
 Documentation/RelNotes/2.17.0.txt   | 2 +-
 Documentation/RelNotes/2.18.0.txt   | 2 +-
 Documentation/diff-options.txt  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/RelNotes/1.7.11.7.txt 
b/Documentation/RelNotes/1.7.11.7.txt
index e7e79d999bd38..e743a2a8e46eb 100644
--- a/Documentation/RelNotes/1.7.11.7.txt
+++ b/Documentation/RelNotes/1.7.11.7.txt
@@ -25,7 +25,7 @@ Fixes since v1.7.11.6
references" nor "Reload" did not update what is shown as the
contents of it, when the user overwrote the tag with "git tag -f".
 
- * "git for-each-ref" did not currectly support more than one --sort
+ * "git for-each-ref" did not correctly support more than one --sort
option.
 
  * "git log .." errored out saying it is both rev range and a path
diff --git a/Documentation/RelNotes/2.17.0.txt 
b/Documentation/RelNotes/2.17.0.txt
index d6db0e19cf17b..c2cf891f71adf 100644
--- a/Documentation/RelNotes/2.17.0.txt
+++ b/Documentation/RelNotes/2.17.0.txt
@@ -342,7 +342,7 @@ Fixes since v2.16
validate the data and connected-ness of objects in the received
pack; the code to perform this check has been taught about the
narrow clone's convention that missing objects that are reachable
-   from objects in a pack that came from a promissor remote is OK.
+   from objects in a pack that came from a promisor remote is OK.
 
  * There was an unused file-scope static variable left in http.c when
building for versions of libCURL that is older than 7.19.4, which
diff --git a/Documentation/RelNotes/2.18.0.txt 
b/Documentation/RelNotes/2.18.0.txt
index 7c59bd92fbd99..1eb13ece53600 100644
--- a/Documentation/RelNotes/2.18.0.txt
+++ b/Documentation/RelNotes/2.18.0.txt
@@ -324,7 +324,7 @@ Fixes since v2.17
after giving an error message.
(merge 3bb0923f06 ps/contains-id-error-message later to maint).
 
- * "diff-highlight" filter (in contrib/) learned to undertand "git log
+ * "diff-highlight" filter (in contrib/) learned to understand "git log
--graph" output better.
(merge 4551fbba14 jk/diff-highlight-graph-fix later to maint).
 
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index f466600972f86..bfa3808e49cc0 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -133,7 +133,7 @@ These parameters can also be set individually with 
`--stat-width=`,
as file creations or deletions ("new" or "gone", optionally "+l"
if it's a symlink) and mode changes ("+x" or "-x" for adding
or removing executable bit respectively) in diffstat. The
-   information is put betwen the filename part and the graph
+   information is put between the filename part and the graph
part. Implies `--stat`.
 
 --numstat::

--
https://github.com/git/git/pull/510


Re: [PATCH] doc: fix typos in documentation and release notes

2018-06-16 Thread Eric Sunshine
On Sat, Jun 16, 2018 at 11:36 PM Karthikeyan  wrote:
> On Sun, Jun 17, 2018, 8:55 AM Eric Sunshine  wrote:
>> Please sign-off[1] your patch so it can be included in the project.
>
> Thanks. I am a beginner using Gmail and I have used SubmitToGit for
> this. Is it possible to do this using SubmitToGit or should I do git
> commit --amend -s to sign off and make a force push to submit it
> again from SubmitToGit as newer one?

Amending the commit with sign-off and re-submit should work fine.
Alternately, you can reply to this email thread with your sign off
in-line, like this:

Signed-off-by: Your Name 


Re: Is NO_ICONV misnamed or is it broken?

2018-06-16 Thread Eric Sunshine
On Sat, Jun 16, 2018 at 10:57 PM Christian Couder
 wrote:
> On Fri, Jun 15, 2018 at 12:47 AM, Mahmoud Al-Qudsi  
> wrote:
> > ~> make NO_ICONV=1
> > # ommitted
> > LINK git-credential-store
> > /usr/bin/ld: cannot find -liconv
> I think 597c9cc540 (Flatten tools/ directory to make build procedure
> simpler., 2005-09-07) which introduces NEEDS_LIBICONV is even older
> than the commit that introduced NO_ICONV (see above), so you might
> want to play with NEEDS_LIBICONV too and see if it works better for
> you.
>
> I CC'ed the people involved in related commits. Maybe they can give
> you a better answer. It might also help if you could tell us on which
> OS/Platform and perhaps for which purpose you want to compile Git.

For completeness, for those reading this thread, a patch fixing this
issue has already been sent[1] to the list.

[1]: 
https://public-inbox.org/git/20180615022503.34111-1-sunsh...@sunshineco.com/


Re: [BUG] git-rebase: reword squashes commits in case of merge-conflicts

2018-06-16 Thread Eric Sunshine
On Sat, Jun 16, 2018 at 12:08 PM Elijah Newren  wrote:
> Subject: [PATCH] sequencer: do not squash 'reword' commits when we hit
>  conflicts
> [...]
> Signed-off-by: Elijah Newren 
> ---
> diff --git a/t/t3423-rebase-reword.sh b/t/t3423-rebase-reword.sh
> @@ -0,0 +1,44 @@
> +test_expect_success 'reword comes after a conflict preserves commit' '

s/comes//

> +   git checkout stuff^0 &&
> +
> +   set_fake_editor &&
> +   test_must_fail env FAKE_LINES="reword 2" \
> +   git rebase -i -v master &&

If some command fails between here and "git rebase --continue" below,
then the test will exit with an in-progress (dangling) rebase, which
could confuse tests added later to this script. I wonder, therefore,
if it would make sense to insert the following cleanup before "git
rebase -i":

test_when_finished "reset_rebase" &&

> +   git checkout --theirs file-2 &&
> +   git add file-2 &&
> +   FAKE_COMMIT_MESSAGE="feature_b_reworded" git rebase --continue &&
> +
> +   test "$(git log -1 --format=%B)" = "feature_b_reworded" &&
> +   test $(git rev-list --count HEAD) = 2
> +'


Re: [PATCH] doc: fix typos in documentation and release notes

2018-06-16 Thread Eric Sunshine
On Sat, Jun 16, 2018 at 2:08 PM Xtreak  wrote:
> doc: fix typos in documentation and release notes

Thanks for the patch. All the fixes look "obviously correct".

Please sign-off[1] your patch so it can be included in the project.

[1]: 
https://github.com/git/git/blob/v2.8.1/Documentation/SubmittingPatches#L234-L286


Re: Is NO_ICONV misnamed or is it broken?

2018-06-16 Thread Christian Couder
Hi,

On Fri, Jun 15, 2018 at 12:47 AM, Mahmoud Al-Qudsi  wrote:
> Hello list,
>
> With regards to the Makefile define/variable `NO_ICONV` - the Makefile
> comments imply that it should be used if "your libc doesn't properly support
> iconv," which could mean anything from "a patch will be applied" to "iconv
> won't be used."

b6e56eca8a (Allow building Git in systems without iconv, 2006-02-16)
which added NO_ICONV says:

Systems using some uClibc versions do not properly support
iconv stuff. This patch allows Git to be built on those
systems by passing NO_ICONV=YesPlease to make. The only
drawback is mailinfo won't do charset conversion in those
systems.

> Based off the name of the varibale, the assumption is that iconv is an
> optional dependency that can be omitted if compiled with NO_ICONV. However, in
> practice attempting to compile git with `make ... NO_ICONV=1` and libiconv not
> installed results in linker errors as follows:
>
> ```
> ~> make clean
> # omitted
> ~> make NO_ICONV=1
> # ommitted
> LINK git-credential-store
> /usr/bin/ld: cannot find -liconv
> cc: error: linker command failed with exit code 1 (use -v to see invocation)
> gmake: *** [Makefile:2327: git-credential-store] Error 1
> ```

Yeah, this might be an issue with the Makefile options.

> Am I misunderstanding the intended behavior when NO_ICONV is defined (i.e. it
> does not remove the dependency on libiconv) or is this a bug and iconv should
> not, in fact, be required?

It's difficult to tell from reading the comments and commit messages.

I think 597c9cc540 (Flatten tools/ directory to make build procedure
simpler., 2005-09-07) which introduces NEEDS_LIBICONV is even older
than the commit that introduced NO_ICONV (see above), so you might
want to play with NEEDS_LIBICONV too and see if it works better for
you.

(I understand that "you might want to play with such and such other
options" is perhaps not as helpful as what you expected, but I
previously tried to tighten the way we handle dependencies in the
Makefile and it was considered "too heavy handed". So yeah, we
consider it ok if people have to tinker a bit when they want to build
Git.)

I CC'ed the people involved in related commits. Maybe they can give
you a better answer. It might also help if you could tell us on which
OS/Platform and perhaps for which purpose you want to compile Git.

Best,
Christian.


git@vger.kernel.org

2018-06-16 Thread SZEDER Gábor
Three tests in 't7406-submodule-update' contain broken &&-chains, but
since they are all in subshells, chain-lint couldn't notice them.

Signed-off-by: SZEDER Gábor 
---
 t/t7406-submodule-update.sh | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 6f083c4d68..9e0d31700e 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -65,7 +65,7 @@ test_expect_success 'setup a submodule tree' '
 git commit -m "none"
) &&
git clone . recursivesuper &&
-   ( cd recursivesuper
+   ( cd recursivesuper &&
 git submodule add ../super super
)
 '
@@ -245,13 +245,13 @@ test_expect_success 'submodule update --remote should 
fetch upstream changes wit
(
cd super &&
git submodule update --remote --force submodule &&
-   git -C submodule log -1 --oneline >actual
-   git -C ../submodule log -1 --oneline master >expect
+   git -C submodule log -1 --oneline >actual &&
+   git -C ../submodule log -1 --oneline master >expect &&
test_cmp expect actual &&
git checkout -b test-branch &&
git submodule update --remote --force submodule &&
-   git -C submodule log -1 --oneline >actual
-   git -C ../submodule log -1 --oneline test-branch >expect
+   git -C submodule log -1 --oneline >actual &&
+   git -C ../submodule log -1 --oneline test-branch >expect &&
test_cmp expect actual &&
git checkout master &&
git branch -d test-branch &&
@@ -891,7 +891,7 @@ test_expect_success 'submodule update properly revives a 
moved submodule' '
 rm -rf submodule2 &&
 mkdir -p "moved/sub module" &&
 git update-index --add --cacheinfo 16 $H "moved/sub module" &&
-git config -f .gitmodules submodule.submodule2.path "moved/sub module"
+git config -f .gitmodules submodule.submodule2.path "moved/sub module" 
&&
 git commit -am "post move" &&
 git submodule update &&
 git status | sed "s/$H2/XXX/" >actual &&
-- 
2.18.0.rc0.207.ga6211da864



Re: [PATCH 2/3] submodule: ensure core.worktree is set after update

2018-06-16 Thread SZEDER Gábor
> +static int connect_gitdir_workingtree(int argc, const char **argv, const 
> char *prefix)
> +{
> + struct strbuf sb = STRBUF_INIT;
> + const char *name, *path;
> + char *sm_gitdir;
> +
> + if (argc != 3)
> + BUG("submodule--helper connect-gitdir-workingtree  
> ");

So this aborts when it's invoked with the wrong number of cmdline
arguments.

> +
> + name = argv[1];
> + path = argv[2];
> +
> + strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
> + sm_gitdir = absolute_pathdup(sb.buf);
> +
> + connect_work_tree_and_git_dir(path, sm_gitdir, 0);
> +
> + strbuf_release(&sb);
> + free(sm_gitdir);
> +
> + return 0;
> +}
> +
>  #define SUPPORT_SUPER_PREFIX (1<<0)
>  
>  struct cmd_struct {

> diff --git a/git-submodule.sh b/git-submodule.sh
> index 78073cd87d1..6596a77c5ef 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -615,6 +615,11 @@ cmd_update()
>   die "$(eval_gettext "Unable to find current 
> \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
>   fi
>  
> + if ! $(git config -f "$(git rev-parse 
> --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
> + then
> + git submodule--helper connect-gitdir-workingtree $name 
> $sm_path

The path to the submodule, $sm_path, may contain spaces, so it must
be quoted.

I'm sure you would have noticed this already, had you checked this
'submodule--helper's exit code :)  In t7406 the test 'submodule update
properly revives a moved submodule' does update a submodule with a
space in its name, and thus executes 'submodule--helper' with one more
argument than expected, causing it to abort, but since there is no
error checking, 'git submodule update' continues anyway, and in the
end the test tends to pass[1].

I think it would be prudent to check the exit code of all
'submodule--helper' executions.


[1] I wrote "tends to", because e.g. on Travis CI the aborting
'submodule--helper' often dumps its core, and the extra 'core'
file shows up in the output of 'git status' and 'test_cmp' notices
it.


> + fi
> +
>   if test "$subsha1" != "$sha1" || test -n "$force"
>   then
>   subforce=$force
> -- 
> 2.18.0.rc1.244.gcf134e6275-goog
> 
> 


Re: [PATCH 0/2] rebase --root: fix `reword` on a root commit

2018-06-16 Thread Todd Zullinger
Hi Johannes,

Johannes Schindelin via GitGitGadget wrote:
> From: GitGitGadget 
> 
> Todd Zullinger reported this bug in
> https://public-inbox.org/git/20180615043111.gs3...@zaya.teonanacatl.net/:
> when calling git rebase --root and trying to reword the
> root commit's message, a BUG is reported.
>
> This fixes that.
> 
> IMO the bug fix is trivial enough to qualify for inclusion into v2.18.0, 
> still.

It does indeed fix the issue.  I agree it would be nice to
see it in 2.18.0.  As a fix for a minor regression
introduced in this cycle, that seems reasonable.

> Johannes Schindelin (1):
>   rebase --root: fix amending root commit messages
> 
> Todd Zullinger (1):
>   rebase --root: demonstrate a bug while amending root commit messages
> 
>  sequencer.c   | 2 +-
>  t/t3404-rebase-interactive.sh | 9 +
>  2 files changed, 10 insertions(+), 1 deletion(-)
> 
> 
> base-commit: 68372c88794aba15f853542008cda39def768372

-- 
Todd
~~
I don't mean to sound cold, or cruel, or vicious,
but I am, so that's the way it comes out.
-- Bill Hicks



[PATCH 2/2] rebase --root: fix amending root commit messages

2018-06-16 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

The code path that triggered that "BUG" really does not want to run
without an explicit commit message. In the case where we want to amend a
commit message, we have an *implicit* commit message, though: the one of
the commit to amend. Therefore, this code path should not even be
entered.

Signed-off-by: Johannes Schindelin 
---
 sequencer.c   | 2 +-
 t/t3404-rebase-interactive.sh | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index cca968043..4034c0461 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -784,7 +784,7 @@ static int run_git_commit(const char *defmsg, struct 
replay_opts *opts,
struct child_process cmd = CHILD_PROCESS_INIT;
const char *value;
 
-   if (flags & CREATE_ROOT_COMMIT) {
+   if ((flags & CREATE_ROOT_COMMIT) && !(flags & AMEND_MSG)) {
struct strbuf msg = STRBUF_INIT, script = STRBUF_INIT;
const char *author = is_rebase_i(opts) ?
read_author_ident(&script) : NULL;
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index ca94c688d..e500d7c32 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -971,7 +971,7 @@ test_expect_success 'rebase -i --root fixup root commit' '
test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
 '
 
-test_expect_failure 'rebase -i --root reword root commit' '
+test_expect_success 'rebase -i --root reword root commit' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout -b reword-root-branch master &&
set_fake_editor &&
-- 
2.17.0.windows.1


[PATCH 1/2] rebase --root: demonstrate a bug while amending root commit messages

2018-06-16 Thread Johannes Schindelin via GitGitGadget
From: Todd Zullinger 

When splitting a repository, running `git rebase -i --root` to reword
the initial commit, Git dies with

BUG: sequencer.c:795: root commit without message.

Signed-off-by: Todd Zullinger 
Signed-off-by: Johannes Schindelin 
---
 t/t3404-rebase-interactive.sh | 9 +
 1 file changed, 9 insertions(+)

diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index c65826dda..ca94c688d 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -971,6 +971,15 @@ test_expect_success 'rebase -i --root fixup root commit' '
test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
 '
 
+test_expect_failure 'rebase -i --root reword root commit' '
+   test_when_finished "test_might_fail git rebase --abort" &&
+   git checkout -b reword-root-branch master &&
+   set_fake_editor &&
+   FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
+   git rebase -i --root &&
+   git show HEAD^ | grep "A changed"
+'
+
 test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on 
non-interactive rebase' '
git reset --hard &&
git checkout conflict-branch &&
-- 
2.17.0.windows.1



[PATCH 0/2] rebase --root: fix `reword` on a root commit

2018-06-16 Thread Johannes Schindelin via GitGitGadget
From: GitGitGadget 

Todd Zullinger reported this bug in 
https://public-inbox.org/git/20180615043111.gs3...@zaya.teonanacatl.net/: when 
calling git rebase --root and trying to reword the root commit's message, a BUG 
is reported.

This fixes that.

IMO the bug fix is trivial enough to qualify for inclusion into v2.18.0, still.

Johannes Schindelin (1):
  rebase --root: fix amending root commit messages

Todd Zullinger (1):
  rebase --root: demonstrate a bug while amending root commit messages

 sequencer.c   | 2 +-
 t/t3404-rebase-interactive.sh | 9 +
 2 files changed, 10 insertions(+), 1 deletion(-)


base-commit: 68372c88794aba15f853542008cda39def768372
-- 
2.17.0.windows.1


Re: [PATCH 1/3] ewah_read_mmap: bounds-check mmap reads

2018-06-16 Thread Jeff King
On Sat, Jun 16, 2018 at 04:35:13PM +0200, SZEDER Gábor wrote:

> > +   head -c 512 <$bitmap >$bitmap.tmp &&
> > +   mv $bitmap.tmp $bitmap &&
> 
> This line turns out to be problematic on OSX and ultimately causes the
> test to fail.
> 
> When OSX's 'mv's destination is read-only, it asks whether to replace
> the destination even though in the test its stdin is not a terminal
> (and thus doesn't conform to POSIX[1]).  Since the '.bitmap' file is
> read-only, and since 'mv' obviously doesn't get an affirmative
> response from /dev/null, the original '.bitmap' file is not
> overwritten, the subsequent 'git rev-list' doesn't print any error
> message, and finally 'test_i18ngrep' causes the test to fail.

Right, sorry, I should have remembered that we've run into this before.
Using "mv -f" is the standard solution. E.g., c20d4d702f (t1450: use "mv
-f" within loose object directory, 2017-01-24).

Junio, can you squash this in to jk/ewah-bounds-check~1?

diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index c4ed88030c..b11bc392a8 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -338,7 +338,7 @@ test_expect_success 'truncated bitmap fails gracefully' '
bitmap=$(ls .git/objects/pack/*.bitmap) &&
test_when_finished "rm -f $bitmap" &&
head -c 512 <$bitmap >$bitmap.tmp &&
-   mv $bitmap.tmp $bitmap &&
+   mv -f $bitmap.tmp $bitmap &&
git rev-list --use-bitmap-index --count --all >actual 2>stderr &&
test_cmp expect actual &&
test_i18ngrep corrupt stderr

-Peff


[PATCH] doc: fix typos in documentation and release notes

2018-06-16 Thread Xtreak
---
 Documentation/RelNotes/1.7.11.7.txt | 2 +-
 Documentation/RelNotes/2.17.0.txt   | 2 +-
 Documentation/RelNotes/2.18.0.txt   | 2 +-
 Documentation/diff-options.txt  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/RelNotes/1.7.11.7.txt 
b/Documentation/RelNotes/1.7.11.7.txt
index e7e79d999bd38..e743a2a8e46eb 100644
--- a/Documentation/RelNotes/1.7.11.7.txt
+++ b/Documentation/RelNotes/1.7.11.7.txt
@@ -25,7 +25,7 @@ Fixes since v1.7.11.6
references" nor "Reload" did not update what is shown as the
contents of it, when the user overwrote the tag with "git tag -f".
 
- * "git for-each-ref" did not currectly support more than one --sort
+ * "git for-each-ref" did not correctly support more than one --sort
option.
 
  * "git log .." errored out saying it is both rev range and a path
diff --git a/Documentation/RelNotes/2.17.0.txt 
b/Documentation/RelNotes/2.17.0.txt
index d6db0e19cf17b..c2cf891f71adf 100644
--- a/Documentation/RelNotes/2.17.0.txt
+++ b/Documentation/RelNotes/2.17.0.txt
@@ -342,7 +342,7 @@ Fixes since v2.16
validate the data and connected-ness of objects in the received
pack; the code to perform this check has been taught about the
narrow clone's convention that missing objects that are reachable
-   from objects in a pack that came from a promissor remote is OK.
+   from objects in a pack that came from a promisor remote is OK.
 
  * There was an unused file-scope static variable left in http.c when
building for versions of libCURL that is older than 7.19.4, which
diff --git a/Documentation/RelNotes/2.18.0.txt 
b/Documentation/RelNotes/2.18.0.txt
index 7c59bd92fbd99..1eb13ece53600 100644
--- a/Documentation/RelNotes/2.18.0.txt
+++ b/Documentation/RelNotes/2.18.0.txt
@@ -324,7 +324,7 @@ Fixes since v2.17
after giving an error message.
(merge 3bb0923f06 ps/contains-id-error-message later to maint).
 
- * "diff-highlight" filter (in contrib/) learned to undertand "git log
+ * "diff-highlight" filter (in contrib/) learned to understand "git log
--graph" output better.
(merge 4551fbba14 jk/diff-highlight-graph-fix later to maint).
 
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index f466600972f86..bfa3808e49cc0 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -133,7 +133,7 @@ These parameters can also be set individually with 
`--stat-width=`,
as file creations or deletions ("new" or "gone", optionally "+l"
if it's a symlink) and mode changes ("+x" or "-x" for adding
or removing executable bit respectively) in diffstat. The
-   information is put betwen the filename part and the graph
+   information is put between the filename part and the graph
part. Implies `--stat`.
 
 --numstat::

--
https://github.com/git/git/pull/510


Re: [BUG] git-rebase: reword squashes commits in case of merge-conflicts

2018-06-16 Thread Elijah Newren
On Mon, Jun 11, 2018 at 06:06:11PM +0200, ch wrote:

> During a recent rebase operation on one of my repositories a number of commits
> unexpectedly ended up getting squashed into other commits. After some
> experiments it turned out that the 'reword' instruction seems to squash the
> referenced commit into the preceding commit if there's a merge-conflict.
> 
> Here's a small reproduction recipe to illustrate the behavior:

Indeed I can reproduce.  It bisects back to when we switched to using the
rebase-helper builtin, so this started with git-2.13.0.  I can also slim down
your reproduction testcase a bit; you don't need any additional commits after
the reword, and the only reason to have commits before it is to induce a merge
conflict by dropping them.  The fact that there are lots of fixups floating
around is not necessary.

Anyway, patch below.

-- >8 --
Subject: [PATCH] sequencer: do not squash 'reword' commits when we hit
 conflicts

Ever since commit 18633e1a22 ("rebase -i: use the rebase--helper builtin",
2017-02-09), when a commit marked as 'reword' in an interactive rebase
has conflicts and fails to apply, when the rebase is resumed that commit
will be squashed into its parent with its commit message taken.

The issue can be understood better by looking at commit 56dc3ab04b
("sequencer (rebase -i): implement the 'edit' command", 2017-01-02), which
introduced error_with_patch() for the edit command.  For the edit command,
it needs to stop the rebase whether or not the patch applies cleanly.  If
the patch does apply cleanly, then when it resumes it knows it needs to
amend all changes into the previous commit.  If it does not apply cleanly,
then the changes should not be amended.  Thus, it passes !res (success of
applying the 'edit' commit) to error_with_patch() for the to_amend flag.

The problematic line of code actually came from commit 04efc8b57c
("sequencer (rebase -i): implement the 'reword' command", 2017-01-02).
Note that to get to this point in the code:
  * !!res (i.e. patch application failed)
  * item->command < TODO_SQUASH
  * item->command != TODO_EDIT
  * !is_fixup(item->command) [i.e. not squash or fixup]
So that means this can only be a failed patch application that is either a
pick, revert, or reword.  For any of those cases we want a new commit, so
we should not set the to_amend flag.

Reported-by: ch 
Signed-off-by: Elijah Newren 
---
 sequencer.c  |  2 +-
 t/t3423-rebase-reword.sh | 44 
 2 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100755 t/t3423-rebase-reword.sh

diff --git a/sequencer.c b/sequencer.c
index cca968043e..9e6d1ee368 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -3217,7 +3217,7 @@ static int pick_commits(struct todo_list *todo_list, 
struct replay_opts *opts)
} else if (res && is_rebase_i(opts) && item->commit)
return res | error_with_patch(item->commit,
item->arg, item->arg_len, opts, res,
-   item->command == TODO_REWORD);
+   0);
} else if (item->command == TODO_EXEC) {
char *end_of_arg = (char *)(item->arg + item->arg_len);
int saved = *end_of_arg;
diff --git a/t/t3423-rebase-reword.sh b/t/t3423-rebase-reword.sh
new file mode 100755
index 00..31c09efd22
--- /dev/null
+++ b/t/t3423-rebase-reword.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+test_description='git rebase interactive with rewording'
+
+. ./test-lib.sh
+
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+test_expect_success 'setup' '
+   test_commit master file-1 test &&
+
+   git checkout -b stuff &&
+
+   test_commit feature_a file-2 aaa &&
+   test_commit feature_b file-2 ddd
+'
+
+test_expect_success 'reword without issues functions as intended' '
+   git checkout stuff^0 &&
+
+   set_fake_editor &&
+   FAKE_LINES="pick 1 reword 2" FAKE_COMMIT_MESSAGE="feature_b_reworded" \
+   git rebase -i -v master &&
+
+   test "$(git log -1 --format=%B)" = "feature_b_reworded" &&
+   test $(git rev-list --count HEAD) = 3
+'
+
+test_expect_success 'reword comes after a conflict preserves commit' '
+   git checkout stuff^0 &&
+
+   set_fake_editor &&
+   test_must_fail env FAKE_LINES="reword 2" \
+   git rebase -i -v master &&
+
+   git checkout --theirs file-2 &&
+   git add file-2 &&
+   FAKE_COMMIT_MESSAGE="feature_b_reworded" git rebase --continue &&
+
+   test "$(git log -1 --format=%B)" = "feature_b_reworded" &&
+   test $(git rev-list --count HEAD) = 2
+'
+
+test_done
-- 
2.18.0.rc2.3.g7fc0d4cb57



[L10N] Start l10n round 3 for one more l10n update from v2.18.0-rc2

2018-06-16 Thread Jiang Xin
Hi,

Git v2.18.0-rc2 introduced a new l10n update, and it's easy to be
fixed, even though there are only two days left for the release of Git
2.18.0.

There are too many l10n updates for Git 2.18.0, and some l10n teams
may not have enough time to update.  Not worry about that, we can send
one more pull request to the maint branch after Git 2.18.0 is
released.

Find and update your translations from the usual place:

https://github.com/git-l10n/git-po/

As how to update your XX.po and help to translate Git, please see
"Updating a XX.po file" and other sections in “po/README" file.

--
Jiang Xin


Re: [PATCH 1/3] ewah_read_mmap: bounds-check mmap reads

2018-06-16 Thread SZEDER Gábor
> diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
> index 423c0a475f..237ee6e5fc 100755
> --- a/t/t5310-pack-bitmaps.sh
> +++ b/t/t5310-pack-bitmaps.sh
> @@ -331,4 +331,17 @@ test_expect_success 'pack reuse respects --incremental' '
>   git show-index actual &&
>   test_cmp expect actual
>  '
> +
> +test_expect_success 'truncated bitmap fails gracefully' '
> + git repack -ad &&
> + git rev-list --use-bitmap-index --count --all >expect &&
> + bitmap=$(ls .git/objects/pack/*.bitmap) &&
> + test_when_finished "rm -f $bitmap" &&
> + head -c 512 <$bitmap >$bitmap.tmp &&
> + mv $bitmap.tmp $bitmap &&

This line turns out to be problematic on OSX and ultimately causes the
test to fail.

When OSX's 'mv's destination is read-only, it asks whether to replace
the destination even though in the test its stdin is not a terminal
(and thus doesn't conform to POSIX[1]).  Since the '.bitmap' file is
read-only, and since 'mv' obviously doesn't get an affirmative
response from /dev/null, the original '.bitmap' file is not
overwritten, the subsequent 'git rev-list' doesn't print any error
message, and finally 'test_i18ngrep' causes the test to fail.

The relevant part of the '-x' test output on Travis CI:

  ++mv 
.git/objects/pack/pack-8886db3fce4f9657c1a43fee7d3ea4f2a4b5be2d.bitmap.tmp 
.git/objects/pack/pack-8886db3fce4f9657c1a43fee7d3ea4f2a4b5be2d.bitmap
  override r--r--r--  travis/staff for 
.git/objects/pack/pack-8886db3fce4f9657c1a43fee7d3ea4f2a4b5be2d.bitmap? (y/n 
[n]) not overwritten
  ++git rev-list --use-bitmap-index --count --all
  ++test_cmp expect actual
  ++diff -u expect actual
  ++test_i18ngrep corrupt stderr
  ++eval 'last_arg=${2}'
  +++last_arg=stderr
  ++test -f stderr
  ++test 2 -lt 2
  ++test 'x!' = xcorrupt
  ++test -n ''
  ++test 'x!' = xcorrupt
  ++grep corrupt stderr
  ++echo 'error: '\''grep corrupt' 'stderr'\'' didn'\''t find a match in:'
  error: 'grep corrupt stderr' didn't find a match in:
  ++test -s stderr
  ++echo ''
  
  ++return 1
  error: last command exited with $?=1
  not ok 43 - truncated bitmap fails gracefully

As far as I can tell, 'mv -f' appears to make the test work on OSX as
well.

I've run a build job with an additional 'grep ^override
t/test-results/*.out' command following the tests to see whether there
are any other cases where OSX 'mv' doesn't overwrite a read-only file
without causing the tests to fail, but found nothing.  (But note that
the OSX build jobs don't run all tests.)

[1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/mv.html

> + git rev-list --use-bitmap-index --count --all >actual 2>stderr &&
> + test_cmp expect actual &&
> + test_i18ngrep corrupt stderr
> +'
> +


Re: [PATCH] unpack-trees: do not fail reset because of unmerged skipped entry

2018-06-16 Thread Max Kirillov
> I do not know offhand if "reset --merge" should force succeeding in
such a case, but I agree that it is criminal to stop "reset --hard"
with "not uptodate", as the whole point of "hard reset" is to get
rid of the 'not up-to-date' modification.

I originally had a fix just for "reset --hard". It was in
verify_uptodate_1(), to move check for "->reset" earlier. But then I
found that "merge --abort" does not use "reset --hard", but rather
--merge, so I fixed that. Because --merge should work also, shouldn't
it?

Actually, I think that fix in verify_uptodate_1() was right, I just
did not find what it affects, after the other fix