{"thread":{"id":"49877","subject":"[ANNOUNCE] Git v2.20.0-rc1","startedAt":"2018-11-21T15:20:38Z","lastAt":"2018-12-04T05:40:55Z","messageCount":53,"participants":["Junio C Hamano","Ævar Arnfjörð Bjarmason","Eric Sunshine","Elijah Newren","Johannes Schindelin","Jonathan Nieder","Ian Jackson","Martin Ågren"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"363836","messageId":"xmqqmuq25ufc.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":null,"subject":"[ANNOUNCE] Git v2.20.0-rc1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-21T15:20:23Z","receivedAt":"2018-11-21T15:20:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"A release candidate Git v2.20.0-rc1 is now available for testing\nat the usual places.  It is comprised of 915 non-merge commits\nsince v2.19.0, contributed by 73 people, 24 of which are new faces.\n\nThe tarballs are found at:\n\n    https://www.kernel.org/pub/software/scm/git/testing/\n\nThe following public repositories all have a copy of the\n'v2.20.0-rc1' tag and the 'master' branch that the tag points at:\n\n  url = https://kernel.googlesource.com/pub/scm/git/git\n  url = git://repo.or.cz/alt-git.git\n  url = https://github.com/gitster/git\n\nNew contributors whose contributions weren't in v2.19.0 are as follows.\nWelcome to the Git development community!\n\n  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan\n  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David\n  Zych, Đoàn Trần Công Danh, Frederick Eaton, James Knight,\n  Jann Horn, Joshua Watt, Loo Rong Jie, Lucas De Marchi, Matthew\n  DeVore, Mihir Mehta, Nickolai Belakovski, Roger Strain, Sam\n  McKelvie, Saulius Gurklys, Shulhan, Steven Fernandez, Strain,\n  Roger L, and Tim Schumacher.\n\nReturning contributors who helped this release are as follows.\nThanks for your continued support.\n\n  Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,\n  Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,\n  brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,\n  Derrick Stolee, Elijah Newren, Eric Sunshine, Jeff Hostetler,\n  Jeff King, Johannes Schindelin, Johannes Sixt, Jonathan Nieder,\n  Jonathan Tan, Josh Steadmon, Junio C Hamano, Karsten Blees,\n  Luke Diamand, Martin Ågren, Max Kirillov, Michael Witten,\n  Michał Górny, Nguyễn Thái Ngọc Duy, Noam Postavsky,\n  Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael Ascensão,\n  Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René Scharfe,\n  Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve Hoelzer,\n  SZEDER Gábor, Tao Qingyun, Taylor Blau, Thomas Gummerer,\n  Todd Zullinger, Torsten Bögershausen, and Uwe Kleine-König.\n\n----------------------------------------------------------------\n\nGit 2.20 Release Notes (draft)\n==============================\n\nBackward Compatibility Notes\n----------------------------\n\n * \"git branch -l <foo>\" used to be a way to ask a reflog to be\n   created while creating a new branch, but that is no longer the\n   case.  It is a short-hand for \"git branch --list <foo>\" now.\n\n * \"git push\" into refs/tags/* hierarchy is rejected without getting\n   forced, but \"git fetch\" (misguidedly) used the \"fast forwarding\"\n   rule used for the refs/heads/* hierarchy; this has been corrected,\n   which means some fetches of tags that did not fail with older\n   version of Git will fail without \"--force\" with this version.\n\n * \"git help -a\" now gives verbose output (same as \"git help -av\").\n   Those who want the old output may say \"git help --no-verbose -a\"..\n\n * \"git cpn --help\", when \"cpn\" is an alias to, say, \"cherry-pick -n\",\n   reported only the alias expansion of \"cpn\" in earlier versions of\n   Git.  It now runs \"git cherry-pick --help\" to show the manual page\n   of the command, while sending the alias expansion to the standard\n   error stream.\n\n * \"git send-email\" learned to grab address-looking string on any\n   trailer whose name ends with \"-by\". This is a backward-incompatible\n   change.  Adding \"--suppress-cc=misc-by\" on the command line, or\n   setting sendemail.suppresscc configuration variable to \"misc-by\",\n   can be used to disable this behaviour.\n\n\nUpdates since v2.19\n-------------------\n\nUI, Workflows & Features\n\n * Running \"git clone\" against a project that contain two files with\n   pathnames that differ only in cases on a case insensitive\n   filesystem would result in one of the files lost because the\n   underlying filesystem is incapable of holding both at the same\n   time.  An attempt is made to detect such a case and warn.\n\n * \"git checkout -b newbranch [HEAD]\" should not have to do as much as\n   checking out a commit different from HEAD.  An attempt is made to\n   optimize this special case.\n\n * \"git rev-list --stdin </dev/null\" used to be an error; it now shows\n   no output without an error.  \"git rev-list --stdin --default HEAD\"\n   still falls back to the given default when nothing is given on the\n   standard input.\n\n * Lift code from GitHub to restrict delta computation so that an\n   object that exists in one fork is not made into a delta against\n   another object that does not appear in the same forked repository.\n\n * \"git format-patch\" learned new \"--interdiff\" and \"--range-diff\"\n   options to explain the difference between this version and the\n   previous attempt in the cover letter (or after the three-dashes as\n   a comment).\n\n * \"git mailinfo\" used in \"git am\" learned to make a best-effort\n   recovery of a patch corrupted by MUA that sends text/plain with\n   format=flawed option.\n   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).\n\n * The rules used by \"git push\" and \"git fetch\" to determine if a ref\n   can or cannot be updated were inconsistent; specifically, fetching\n   to update existing tags were allowed even though tags are supposed\n   to be unmoving anchoring points.  \"git fetch\" was taught to forbid\n   updates to existing tags without the \"--force\" option.\n\n * \"git multi-pack-index\" learned to detect corruption in the .midx\n   file it uses, and this feature has been integrated into \"git fsck\".\n\n * Generation of (experimental) commit-graph files have so far been\n   fairly silent, even though it takes noticeable amount of time in a\n   meaningfully large repository.  The users will now see progress\n   output.\n\n * The minimum version of Windows supported by Windows port of Git is\n   now set to Vista.\n\n * The completion script (in contrib/) learned to complete a handful of\n   options \"git stash list\" command takes.\n\n * The completion script (in contrib/) learned that \"git fetch\n   --multiple\" only takes remote names as arguments and no refspecs.\n\n * \"git status\" learns to show progress bar when refreshing the index\n   takes a long time.\n   (merge ae9af12287 nd/status-refresh-progress later to maint).\n\n * \"git help -a\" and \"git help -av\" give different pieces of\n   information, and generally the \"verbose\" version is more friendly\n   to the new users.  \"git help -a\" by default now uses the more\n   verbose output (with \"--no-verbose\", you can go back to the\n   original).  Also \"git help -av\" now lists aliases and external\n   commands, which it did not used to.\n\n * Unlike \"grep\", \"git grep\" by default recurses to the whole tree.\n   The command learned \"git grep --recursive\" option, so that \"git\n   grep --no-recursive\" can serve as a synonym to setting the\n   max-depth to 0.\n\n * When pushing into a repository that borrows its objects from an\n   alternate object store, \"git receive-pack\" that responds to the\n   push request on the other side lists the tips of refs in the\n   alternate to reduce the amount of objects transferred.  This\n   sometimes is detrimental when the number of refs in the alternate\n   is absurdly large, in which case the bandwidth saved in potentially\n   fewer objects transferred is wasted in excessively large ref\n   advertisement.  The alternate refs that are advertised are now\n   configurable with a pair of configuration variables.\n\n * \"git cmd --help\" when \"cmd\" is aliased used to only say \"cmd is\n   aliased to ...\".  Now it shows that to the standard error stream\n   and runs \"git $cmd --help\" where $cmd is the first word of the\n   alias expansion.\n\n * The documentation of \"git gc\" has been updated to mention that it\n   is no longer limited to \"pruning away crufts\" but also updates\n   ancillary files like commit-graph as a part of repository\n   optimization.\n\n * \"git p4 unshelve\" improvements.\n\n * The logic to select the default user name and e-mail on Windows has\n   been improved.\n   (merge 501afcb8b0 js/mingw-default-ident later to maint).\n\n * The \"rev-list --filter\" feature learned to exclude all trees via\n   \"tree:0\" filter.\n\n * \"git send-email\" learned to grab address-looking string on any\n   trailer whose name ends with \"-by\"; --suppress-cc=misc-by on the\n   command line, or setting sendemail.suppresscc configuration\n   variable to \"misc-by\", can be used to disable this behaviour.\n\n * Developer builds now uses -Wunused-function compilation option.\n\n * One of our CI tests to run with \"unusual/experimental/random\"\n   settings now also uses commit-graph and midx.\n\n * \"git mergetool\" learned to take the \"--[no-]gui\" option, just like\n   \"git difftool\" does.\n\n * \"git rebase -i\" learned a new insn, 'break', that the user can\n   insert in the to-do list.  Upon hitting it, the command returns\n   control back to the user.\n\n * New \"--pretty=format:\" placeholders %GF and %GP that show the GPG\n   key fingerprints have been invented.\n\n * On platforms with recent cURL library, http.sslBackend configuration\n   variable can be used to choose a different SSL backend at runtime.\n   The Windows port uses this mechanism to switch between OpenSSL and\n   Secure Channel while talking over the HTTPS protocol.\n\n * \"git send-email\" learned to disable SMTP authentication via the\n   \"--smtp-auth=none\" option, even when the smtp username is given\n   (which turns the authentication on by default).\n\n * A fourth class of configuration files (in addition to the\n   traditional \"system wide\", \"per user in the $HOME directory\" and\n   \"per repository in the $GIT_DIR/config\") has been introduced so\n   that different worktrees that share the same repository (hence the\n   same $GIT_DIR/config file) can use different customization.\n\n * A pattern with '**' that does not have a slash on either side used\n   to be an invalid one, but the code now treats such double-asterisks\n   the same way as two normal asterisks that happen to be adjacent to\n   each other.\n   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).\n\n * The \"--no-patch\" option, which can be used to get a high-level\n   overview without the actual line-by-line patch difference shown, of\n   the \"range-diff\" command was earlier broken, which has been\n   corrected.\n\n * The recently merged \"rebase in C\" has an escape hatch to use the\n   scripted version when necessary, but it hasn't been documented,\n   which has been corrected.\n\n\nPerformance, Internal Implementation, Development Support etc.\n\n * When there are too many packfiles in a repository (which is not\n   recommended), looking up an object in these would require\n   consulting many pack .idx files; a new mechanism to have a single\n   file that consolidates all of these .idx files is introduced.\n\n * \"git submodule update\" is getting rewritten piece-by-piece into C.\n\n * The code for computing history reachability has been shuffled,\n   obtained a bunch of new tests to cover them, and then being\n   improved.\n\n * The unpack_trees() API used in checking out a branch and merging\n   walks one or more trees along with the index.  When the cache-tree\n   in the index tells us that we are walking a tree whose flattened\n   contents is known (i.e. matches a span in the index), as linearly\n   scanning a span in the index is much more efficient than having to\n   open tree objects recursively and listing their entries, the walk\n   can be optimized, which has been done.\n\n * When creating a thin pack, which allows objects to be made into a\n   delta against another object that is not in the resulting pack but\n   is known to be present on the receiving end, the code learned to\n   take advantage of the reachability bitmap; this allows the server\n   to send a delta against a base beyond the \"boundary\" commit.\n\n * spatch transformation to replace boolean uses of !hashcmp() to\n   newly introduced oideq() is added, and applied, to regain\n   performance lost due to support of multiple hash algorithms.\n\n * Fix a bug in which the same path could be registered under multiple\n   worktree entries if the path was missing (for instance, was removed\n   manually).  Also, as a convenience, expand the number of cases in\n   which --force is applicable.\n\n * Split Documentation/config.txt for easier maintenance.\n   (merge 6014363f0b nd/config-split later to maint).\n\n * Test helper binaries clean-up.\n   (merge c9a1f4161f nd/test-tool later to maint).\n\n * Various tests have been updated to make it easier to swap the\n   hash function used for object identification.\n   (merge ae0c89d41b bc/hash-independent-tests later to maint).\n\n * Update fsck.skipList implementation and documentation.\n   (merge 371a655074 ab/fsck-skiplist later to maint).\n\n * An alias that expands to another alias has so far been forbidden,\n   but now it is allowed to create such an alias.\n\n * Various test scripts have been updated for style and also correct\n   handling of exit status of various commands.\n\n * \"gc --auto\" ended up calling exit(-1) upon error, which has been\n   corrected to use exit(1).  Also the error reporting behaviour when\n   daemonized has been updated to exit with zero status when stopping\n   due to a previously discovered error (which implies there is no\n   point running gc to improve the situation); we used to exit with\n   failure in such a case.\n\n * Various codepaths in the core-ish part learned to work on an\n   arbitrary in-core index structure, not necessarily the default\n   instance \"the_index\".\n   (merge b3c7eef9b0 nd/the-index later to maint).\n\n * Code clean-up in the internal machinery used by \"git status\" and\n   \"git commit --dry-run\".\n   (merge 73ba5d78b4 ss/wt-status-committable later to maint).\n\n * Some environment variables that control the runtime options of Git\n   used during tests are getting renamed for consistency.\n   (merge 4231d1ba99 bp/rename-test-env-var later to maint).\n\n * A pair of new extensions to the index file have been introduced.\n   They allow the index file to be read in parallel for performance.\n\n * The oidset API was built on top of the oidmap API which in turn is\n   on the hashmap API.  Replace the implementation to build on top of\n   the khash API and gain performance.\n\n * Over some transports, fetching objects with an exact commit object\n   name can be done without first seeing the ref advertisements.  The\n   code has been optimized to exploit this.\n\n * In a partial clone that will lazily be hydrated from the\n   originating repository, we generally want to avoid \"does this\n   object exist (locally)?\" on objects that we deliberately omitted\n   when we created the clone.  The cache-tree codepath (which is used\n   to write a tree object out of the index) however insisted that the\n   object exists, even for paths that are outside of the partial\n   checkout area.  The code has been updated to avoid such a check.\n\n * To help developers, an EditorConfig file that attempts to follow\n   the project convention has been added.\n   (merge b548d698a0 bc/editorconfig later to maint).\n\n * The result of coverage test can be combined with \"git blame\" to\n   check the test coverage of code introduced recently with a new\n   'coverage-diff' tool (in contrib/).\n   (merge 783faedd65 ds/coverage-diff later to maint).\n\n * An experiment to fuzz test a few areas, hopefully we can gain more\n   coverage to various areas.\n\n * More codepaths are moving away from hardcoded hash sizes.\n\n * The way the Windows port figures out the current directory has been\n   improved.\n\n * The way DLLs are loaded on the Windows port has been improved.\n\n * Some tests have been reorganized and renamed; \"ls t/\" now gives a\n   better overview of what is tested for these scripts than before.\n\n * \"git rebase\" and \"git rebase -i\" have been reimplemented in C.\n\n * Windows port learned to use nano-second resolution file timestamps.\n\n * The overly large Documentation/config.txt file have been split into\n   million little pieces.  This potentially allows each individual piece\n   included into the manual page of the command it affects more easily.\n\n * Replace three string-list instances used as look-up tables in \"git\n   fetch\" with hashmaps.\n\n * Unify code to read the author-script used in \"git am\" and the\n   commands that use the sequencer machinery, e.g. \"git rebase -i\".\n\n * In preparation to the day when we can deprecate and remove the\n   \"rebase -p\", make sure we can skip and later remove tests for\n   it.\n\n * The history traversal used to implement the tag-following has been\n   optimized by introducing a new helper.\n\n * The helper function to refresh the cached stat information in the\n   in-core index has learned to perform the lstat() part of the\n   operation in parallel on multi-core platforms.\n\n * The code to traverse objects for reachability, used to decide what\n   objects are unreferenced and expendable, have been taught to also\n   consider per-worktree refs of other worktrees as starting points to\n   prevent data loss.\n\n * \"git add\" needs to internally run \"diff-files\" equivalent, and the\n   codepath learned the same optimization as \"diff-files\" has to run\n   lstat(2) in parallel to find which paths have been updated in the\n   working tree.\n\n * The procedure to install dependencies before testing at Travis CI\n   is getting revamped for both simplicity and flexibility, taking\n   advantage of the recent move to the vm-based environment.\n\n * The support for format-patch (and send-email) by the command-line\n   completion script (in contrib/) has been simplified a bit.\n\n * The revision walker machinery learned to take advantage of the\n   commit generation numbers stored in the commit-graph file.\n\n * The codebase has been cleaned up to reduce \"#ifndef NO_PTHREADS\".\n\n * The way -lcurl library gets linked has been simplified by taking\n   advantage of the fact that we can just ask curl-config command how.\n\n * Various functions have been audited for \"-Wunused-parameter\" warnings\n   and bugs in them got fixed.\n\n * A sanity check for start-up sequence has been added in the config\n   API codepath.\n\n * The build procedure to link for fuzzing test has been made\n   customizable with a new Makefile variable.\n\n * The way \"git rebase\" parses and forwards the command line options\n   meant for underlying \"git am\" has been revamped, which fixed for\n   options with parameters that were not passed correctly.\n\n * Our testing framework uses a special i18n \"poisoned localization\"\n   feature to find messages that ought to stay constant but are\n   incorrectly marked to be translated.  This feature has been made\n   into a runtime option (it used to be a compile-time option).\n\n * \"git push\" used to check ambiguities between object-names and\n   refnames while processing the list of refs' old and new values,\n   which was unnecessary (as it knew that it is feeding raw object\n   names).  This has been optimized out.\n\n * The xcurl_off_t() helper function is used to cast size_t to\n   curl_off_t, but some compilers gave warnings against the code to\n   ensure the casting is done without wraparound, when size_t is\n   narrower than curl_off_t.  This warning has been squelched.\n\n * Code preparation to replace ulong vars with size_t vars where\n   appropriate continues.\n\n * The \"test installed Git\" mode of our test suite has been updated to\n   work better.\n\n * A coding convention around the Coccinelle semantic patches to have\n   two classes to ease code migration process has been proposed and\n   its support has been added to the Makefile.\n\n\nFixes since v2.19\n-----------------\n\n * \"git interpret-trailers\" and its underlying machinery had a buggy\n   code that attempted to ignore patch text after commit log message,\n   which triggered in various codepaths that will always get the log\n   message alone and never get such an input.\n   (merge 66e83d9b41 jk/trailer-fixes later to maint).\n\n * Malformed or crafted data in packstream can make our code attempt\n   to read or write past the allocated buffer and abort, instead of\n   reporting an error, which has been fixed.\n\n * \"git rebase -i\" did not clear the state files correctly when a run\n   of \"squash/fixup\" is aborted and then the user manually amended the\n   commit instead, which has been corrected.\n   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).\n\n * When fsmonitor is in use, after operation on submodules updates\n   .gitmodules, we lost track of the fact that we did so and relied on\n   stale fsmonitor data.\n   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).\n\n * Fix for a long-standing bug that leaves the index file corrupt when\n   it shrinks during a partial commit.\n   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).\n\n * Further fix for O_APPEND emulation on Windows\n   (merge eeaf7ddac7 js/mingw-o-append later to maint).\n\n * A corner case bugfix in \"git rerere\" code.\n   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).\n\n * \"git add ':(attr:foo)'\" is not supported and is supposed to be\n   rejected while the command line arguments are parsed, but we fail\n   to reject such a command line upfront.\n   (merge 84d938b732 nd/attr-pathspec-fix later to maint).\n\n * Recent update broke the reachability algorithm when refs (e.g.\n   tags) that point at objects that are not commit were involved,\n   which has been fixed.\n\n * \"git rebase\" etc. in Git 2.19 fails to abort when given an empty\n   commit log message as result of editing, which has been corrected.\n   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).\n\n * The code to backfill objects in lazily cloned repository did not\n   work correctly, which has been corrected.\n   (merge e68302011c jt/lazy-object-fetch-fix later to maint).\n\n * Update error messages given by \"git remote\" and make them consistent.\n   (merge 5025425dff ms/remote-error-message-update later to maint).\n\n * \"git update-ref\" learned to make both \"--no-deref\" and \"--stdin\"\n   work at the same time.\n   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).\n\n * Recently added \"range-diff\" had a corner-case bug to cause it\n   segfault, which has been corrected.\n   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).\n\n * The recently introduced commit-graph auxiliary data is incompatible\n   with mechanisms such as replace & grafts that \"breaks\" immutable\n   nature of the object reference relationship.  Disable optimizations\n   based on its use (and updating existing commit-graph) when these\n   incompatible features are in use in the repository.\n   (merge 829a321569 ds/commit-graph-with-grafts later to maint).\n\n * The mailmap file update.\n   (merge 255eb03edf jn/mailmap-update later to maint).\n\n * The code in \"git status\" sometimes hit an assertion failure.  This\n   was caused by a structure that was reused without cleaning the data\n   used for the first run, which has been corrected.\n   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).\n\n * \"git fetch $repo $object\" in a partial clone did not correctly\n   fetch the asked-for object that is referenced by an object in\n   promisor packfile, which has been fixed.\n\n * A corner-case bugfix.\n   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).\n\n * Various fixes to \"diff --color-moved-ws\".\n\n * A partial clone that is configured to lazily fetch missing objects\n   will on-demand issue a \"git fetch\" request to the originating\n   repository to fill not-yet-obtained objects.  The request has been\n   optimized for requesting a tree object (and not the leaf blob\n   objects contained in it) by telling the originating repository that\n   no blobs are needed.\n   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).\n\n * The codepath to support the experimental split-index mode had\n   remaining \"racily clean\" issues fixed.\n   (merge 4c490f3d32 sg/split-index-racefix later to maint).\n\n * \"git log --graph\" showing an octopus merge sometimes miscounted the\n   number of display columns it is consuming to show the merge and its\n   parent commits, which has been corrected.\n   (merge 04005834ed np/log-graph-octopus-fix later to maint).\n\n * \"git range-diff\" did not work well when the compared ranges had\n   changes in submodules and the \"--submodule=log\" was used.\n\n * The implementation of run_command() API on the UNIX platforms had a\n   bug that caused a command not on $PATH to be found in the current\n   directory.\n   (merge f67b980771 jk/run-command-notdot later to maint).\n\n * A mutex used in \"git pack-objects\" were not correctly initialized\n   and this caused \"git repack\" to dump core on Windows.\n   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).\n\n * Under certain circumstances, \"git diff D:/a/b/c D:/a/b/d\" on\n   Windows would strip initial parts from the paths because they\n   were not recognized as absolute, which has been corrected.\n   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).\n\n * The receive.denyCurrentBranch=updateInstead codepath kicked in even\n   when the push should have been rejected due to other reasons, such\n   as it does not fast-forward or the update-hook rejects it, which\n   has been corrected.\n   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).\n\n * The logic to determine the archive type \"git archive\" uses did not\n   correctly kick in for \"git archive --remote\", which has been\n   corrected.\n\n * \"git repack\" in a shallow clone did not correctly update the\n   shallow points in the repository, leading to a repository that\n   does not pass fsck.\n   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).\n\n * Some codepaths failed to form a proper URL when .gitmodules record\n   the URL to a submodule repository as relative to the repository of\n   superproject, which has been corrected.\n   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).\n\n * \"git fetch\" over protocol v2 into a shallow repository failed to\n   fetch full history behind a new tip of history that was diverged\n   before the cut-off point of the history that was previously fetched\n   shallowly.\n\n * The command line completion machinery (in contrib/) has been\n   updated to allow the completion script to tweak the list of options\n   that are reported by the parse-options machinery correctly.\n   (merge 276b49ff34 nd/completion-negation later to maint).\n\n * Operations on promisor objects make sense in the context of only a\n   small subset of the commands that internally use the revisions\n   machinery, but the \"--exclude-promisor-objects\" option were taken\n   and led to nonsense results by commands like \"log\", to which it\n   didn't make much sense.  This has been corrected.\n   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).\n\n * The \"container\" mode of TravisCI is going away.  Our .travis.yml\n   file is getting prepared for the transition.\n   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).\n\n * Our test scripts can now take the '-V' option as a synonym for the\n   '--verbose-log' option.\n   (merge a5f52c6dab sg/test-verbose-log later to maint).\n\n * A regression in Git 2.12 era made \"git fsck\" fall into an infinite\n   loop while processing truncated loose objects.\n   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).\n\n * \"git ls-remote $there foo\" was broken by recent update for the\n   protocol v2 and stopped showing refs that match 'foo' that are not\n   refs/{heads,tags}/foo, which has been fixed.\n   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).\n\n * Additional comment on a tricky piece of code to help developers.\n   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).\n\n * A couple of tests used to leave the repository in a state that is\n   deliberately corrupt, which have been corrected.\n   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).\n\n * The submodule support has been updated to read from the blob at\n   HEAD:.gitmodules when the .gitmodules file is missing from the\n   working tree.\n   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).\n\n * \"git fetch\" was a bit loose in parsing responses from the other side\n   when talking over the protocol v2.\n\n * \"git rev-parse --exclude=* --branches --branches\"  (i.e. first\n   saying \"add only things that do not match '*' out of all branches\"\n   and then adding all branches, without any exclusion this time\")\n   worked as expected, but \"--exclude=* --all --all\" did not work the\n   same way, which has been fixed.\n   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).\n\n * \"git send-email --transfer-encoding=...\" in recent versions of Git\n   sometimes produced an empty \"Content-Transfer-Encoding:\" header,\n   which has been corrected.\n   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).\n\n * The interface into \"xdiff\" library used to discover the offset and\n   size of a generated patch hunk by first formatting it into the\n   textual hunk header \"@@ -n,m +k,l @@\" and then parsing the numbers\n   out.  A new interface has been introduced to allow callers a more\n   direct access to them.\n   (merge 5eade0746e jk/xdiff-interface later to maint).\n\n * Pathspec matching against a tree object were buggy when negative\n   pathspec elements were involved, which has been fixed.\n   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).\n\n * \"git merge\" and \"git pull\" that merges into an unborn branch used\n   to completely ignore \"--verify-signatures\", which has been\n   corrected.\n   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).\n\n * \"git rebase --autostash\" did not correctly re-attach the HEAD at times.\n\n * \"rev-parse --exclude=<pattern> --branches=<pattern>\" etc. did not\n   quite work, which has been corrected.\n   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).\n\n * When editing a patch in a \"git add -i\" session, a hunk could be\n   made to no-op.  The \"git apply\" program used to reject a patch with\n   such a no-op hunk to catch user mistakes, but it is now updated to\n   explicitly allow a no-op hunk in an edited patch.\n   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).\n\n * The URL to an MSDN page in a comment has been updated.\n   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).\n\n * \"git ls-remote --sort=<thing>\" can feed an object that is not yet\n   available into the comparison machinery and segfault, which has\n   been corrected to check such a request upfront and reject it.\n\n * When \"git bundle\" aborts due to an empty commit ranges\n   (i.e. resulting in an empty pack), it left a file descriptor to an\n   lockfile open, which resulted in leftover lockfile on Windows where\n   you cannot remove a file with an open file descriptor.  This has\n   been corrected.\n   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).\n\n * \"git format-patch --stat=<width>\" can be used to specify the width\n   used by the diffstat (shown in the cover letter).\n   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).\n\n * The way .git/index and .git/sharedindex* files were initially\n   created gave these files different perm bits until they were\n   adjusted for shared repository settings.  This was made consistent.\n   (merge c9d6c78870 cc/shared-index-permbits later to maint).\n\n * Code cleanup, docfix, build fix, etc.\n   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).\n   (merge b9b07efdb2 tg/conflict-marker-size later to maint).\n   (merge fa0aeea770 sg/doc-trace-appends later to maint).\n   (merge d64324cb60 tb/void-check-attr later to maint).\n   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).\n   (merge 79336116f5 sg/t3701-tighten-trace later to maint).\n   (merge 801fa63a90 jk/dev-build-format-security later to maint).\n   (merge 0597dd62ba sb/string-list-remove-unused later to maint).\n   (merge db2d36fad8 bw/protocol-v2 later to maint).\n   (merge 456d7cd3a9 sg/split-index-test later to maint).\n   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).\n   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).\n   (merge 55f6bce2c9 fe/doc-updates later to maint).\n   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).\n   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).\n   (merge 4c399442f7 ma/commit-graph-docs later to maint).\n   (merge fc0503b04e ma/t1400-undebug-test later to maint).\n   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).\n   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).\n   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).\n   (merge ad0b8f9575 mw/doc-typofixes later to maint).\n   (merge d9f079ad1a jc/how-to-document-api later to maint).\n   (merge b1492bf315 ma/t7005-bash-workaround later to maint).\n   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).\n   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).\n   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).\n   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).\n   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).\n   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).\n   (merge 2e3c894f4b tq/branch-style-fix later to maint).\n   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).\n   (merge 081d91618b ah/doc-updates later to maint).\n   (merge b84c783882 jc/cocci-preincr later to maint).\n   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).\n   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).\n   (merge 3063477445 tb/char-may-be-unsigned later to maint).\n   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).\n   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).\n   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).\n\n----------------------------------------------------------------\n\nChanges since v2.19.0 are as follows:\n\nAaron Lindsay (1):\n      send-email: avoid empty transfer encoding header\n\nAlban Gruin (21):\n      sequencer: make three functions and an enum from sequencer.c public\n      rebase -i: rewrite append_todo_help() in C\n      editor: add a function to launch the sequence editor\n      rebase -i: rewrite the edit-todo functionality in C\n      sequencer: add a new function to silence a command, except if it fails\n      rebase -i: rewrite setup_reflog_action() in C\n      rebase -i: rewrite checkout_onto() in C\n      sequencer: refactor append_todo_help() to write its message to a buffer\n      sequencer: change the way skip_unnecessary_picks() returns its result\n      t3404: todo list with commented-out commands only aborts\n      rebase -i: rewrite complete_action() in C\n      rebase -i: remove unused modes and functions\n      rebase -i: implement the logic to initialize $revisions in C\n      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C\n      rebase -i: rewrite write_basic_state() in C\n      rebase -i: rewrite init_basic_state() in C\n      rebase -i: implement the main part of interactive rebase as a builtin\n      rebase--interactive2: rewrite the submodes of interactive rebase in C\n      rebase -i: remove git-rebase--interactive.sh\n      rebase -i: move rebase--helper modes to rebase--interactive\n      p3400: replace calls to `git checkout -b' by `git checkout -B'\n\nAlexander Pyhalov (1):\n      t7005-editor: quote filename to fix whitespace-issue\n\nAndreas Gruenbacher (1):\n      rev-parse: clear --exclude list after 'git rev-parse --all'\n\nAndreas Heiduk (6):\n      doc: clarify boundaries of 'git worktree list --porcelain'\n      doc: fix ASCII art tab spacing\n      doc: fix inappropriate monospace formatting\n      doc: fix descripion for 'git tag --format'\n      doc: fix indentation of listing blocks in gitweb.conf.txt\n      doc: fix formatting in git-update-ref\n\nAnton Serbulov (1):\n      mingw: fix getcwd when the parent directory cannot be queried\n\nAntonio Ospite (10):\n      submodule: add a print_config_from_gitmodules() helper\n      submodule: factor out a config_set_in_gitmodules_file_gently function\n      t7411: merge tests 5 and 6\n      t7411: be nicer to future tests and really clean things up\n      submodule--helper: add a new 'config' subcommand\n      submodule: use the 'submodule--helper config' command\n      t7506: clean up .gitmodules properly before setting up new scenario\n      submodule: add a helper to check if it is safe to write to .gitmodules\n      submodule: support reading .gitmodules when it's not in the working tree\n      t/helper: add test-submodule-nested-repo-config\n\nBen Peart (19):\n      checkout: optimize \"git checkout -b <new_branch>\"\n      git-mv: allow submodules and fsmonitor to work together\n      t/README: correct spelling of \"uncommon\"\n      preload-index: use git_env_bool() not getenv() for customization\n      fsmonitor: update GIT_TEST_FSMONITOR support\n      read-cache: update TEST_GIT_INDEX_VERSION support\n      preload-index: update GIT_FORCE_PRELOAD_TEST support\n      read-cache: clean up casting and byte decoding\n      eoie: add End of Index Entry (EOIE) extension\n      config: add new index.threads config setting\n      read-cache: load cache extensions on a worker thread\n      ieot: add Index Entry Offset Table (IEOT) extension\n      read-cache: load cache entries on worker threads\n      reset: don't compute unstaged changes after reset when --quiet\n      reset: add new reset.quiet config setting\n      reset: warn when refresh_index() takes more than 2 seconds\n      speed up refresh_index() by utilizing preload_index()\n      add: speed up cmd_add() by utilizing read_cache_preload()\n      refresh_index: remove unnecessary calls to preload_index()\n\nBrandon Williams (1):\n      config: document value 2 for protocol.version\n\nBrendan Forster (1):\n      http: add support for disabling SSL revocation checks in cURL\n\nCarlo Marcelo Arenas Belón (8):\n      unpack-trees: avoid dead store for struct progress\n      multi-pack-index: avoid dead store for struct progress\n      read-cache: use of memory after it is freed\n      commit-slabs: move MAYBE_UNUSED out\n      khash: silence -Wunused-function for delta-islands\n      compat: make sure git_mmap is not expected to write\n      sequencer: cleanup for gcc warning in non developer mode\n      builtin/notes: remove unnecessary free\n\nChristian Couder (3):\n      pack-objects: refactor code into compute_layer_order()\n      pack-objects: move tree_depth into 'struct packing_data'\n      pack-objects: move 'layer' into 'struct packing_data'\n\nChristian Hesse (2):\n      subtree: add build targets 'man' and 'html'\n      subtree: make install targets depend on build targets\n\nDaniels Umanovskis (3):\n      doc: move git-rev-parse from porcelain to plumbing\n      doc: move git-get-tar-commit-id to plumbing\n      doc: move git-cherry to plumbing\n\nDavid Zych (1):\n      doc: clarify gitcredentials path component matching\n\nDenton Liu (3):\n      mergetool: accept -g/--[no-]gui as arguments\n      completion: support `git mergetool --[no-]gui`\n      doc: document diff/merge.guitool config keys\n\nDerrick Stolee (93):\n      multi-pack-index: add design document\n      multi-pack-index: add format details\n      multi-pack-index: add builtin\n      multi-pack-index: add 'write' verb\n      midx: write header information to lockfile\n      multi-pack-index: load into memory\n      t5319: expand test data\n      packfile: generalize pack directory list\n      multi-pack-index: read packfile list\n      multi-pack-index: write pack names in chunk\n      midx: read pack names into array\n      midx: sort and deduplicate objects from packfiles\n      midx: write object ids in a chunk\n      midx: write object id fanout chunk\n      midx: write object offsets\n      config: create core.multiPackIndex setting\n      midx: read objects from multi-pack-index\n      midx: use midx in abbreviation calculations\n      midx: use existing midx when writing new one\n      midx: use midx in approximate_object_count\n      midx: prevent duplicate packfile loads\n      packfile: skip loading index if in multi-pack-index\n      midx: clear midx on repack\n      commit-reach: move walk methods from commit.c\n      commit.h: remove method declarations\n      commit-reach: move ref_newer from remote.c\n      commit-reach: move commit_contains from ref-filter\n      upload-pack: make reachable() more generic\n      upload-pack: refactor ok_to_give_up()\n      upload-pack: generalize commit date cutoff\n      commit-reach: move can_all_from_reach_with_flags\n      test-reach: create new test tool for ref_newer\n      test-reach: test in_merge_bases\n      test-reach: test is_descendant_of\n      test-reach: test get_merge_bases_many\n      test-reach: test reduce_heads\n      test-reach: test can_all_from_reach_with_flags\n      test-reach: test commit_contains\n      commit-reach: replace ref_newer logic\n      commit-reach: make can_all_from_reach... linear\n      commit-reach: use can_all_from_reach\n      multi-pack-index: provide more helpful usage info\n      multi-pack-index: store local property\n      midx: mark bad packed objects\n      midx: stop reporting garbage\n      midx: fix bug that skips midx with alternates\n      packfile: add all_packs list\n      treewide: use get_all_packs\n      midx: test a few commands that use get_all_packs\n      pack-objects: consider packs in multi-pack-index\n      commit-graph: update design document\n      test-repository: properly init repo\n      commit-graph: not compatible with replace objects\n      commit-graph: not compatible with grafts\n      commit-graph: not compatible with uninitialized repo\n      commit-graph: close_commit_graph before shallow walk\n      commit-graph: define GIT_TEST_COMMIT_GRAPH\n      t3206-range-diff.sh: cover single-patch case\n      t5318: use test_oid for HASH_LEN\n      multi-pack-index: add 'verify' verb\n      multi-pack-index: verify bad header\n      multi-pack-index: verify corrupt chunk lookup table\n      multi-pack-index: verify packname order\n      multi-pack-index: verify missing pack\n      multi-pack-index: verify oid fanout order\n      multi-pack-index: verify oid lookup order\n      multi-pack-index: fix 32-bit vs 64-bit size check\n      multi-pack-index: verify object offsets\n      multi-pack-index: report progress during 'verify'\n      fsck: verify multi-pack-index\n      commit-reach: properly peel tags\n      commit-reach: fix memory and flag leaks\n      commit-reach: cleanups in can_all_from_reach...\n      commit-graph: clean up leaked memory during write\n      commit-graph: reduce initial oid allocation\n      midx: fix broken free() in close_midx()\n      contrib: add coverage-diff script\n      ci: add optional test variables\n      commit-reach: fix first-parent heuristic\n      midx: close multi-pack-index on repack\n      multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX\n      packfile: close multi-pack-index in close_all_packs\n      prio-queue: add 'peek' operation\n      test-reach: add run_three_modes method\n      test-reach: add rev-list tests\n      revision.c: begin refactoring --topo-order logic\n      commit/revisions: bookkeeping before refactoring\n      revision.c: generation-based topo-order algorithm\n      t6012: make rev-list tests more interesting\n      commit-reach: implement get_reachable_subset\n      test-reach: test get_reachable_subset\n      remote: make add_missing_tags() linear\n      pack-objects: ignore ambiguous object warnings\n\nElijah Newren (14):\n      Remove superfluous trailing semicolons\n      t4200: demonstrate rerere segfault on specially crafted merge\n      rerere: avoid buffer overrun\n      update-ref: fix type of update_flags variable to match its usage\n      update-ref: allow --no-deref with --stdin\n      sequencer: fix --allow-empty-message behavior, make it smarter\n      merge-recursive: set paths correctly when three-way merging content\n      merge-recursive: avoid wrapper function when unnecessary and wasteful\n      merge-recursive: remove final remaining caller of merge_file_one()\n      merge-recursive: rename merge_file_1() and merge_content()\n      commit: fix erroneous BUG, 'multiple renames on the same target? how?'\n      merge-recursive: improve auto-merging messages with path collisions\n      merge-recursive: avoid showing conflicts with merge branch before HEAD\n      fsck: move fsck_head_link() to get_default_heads() to avoid some globals\n\nEric Sunshine (26):\n      format-patch: allow additional generated content in make_cover_letter()\n      format-patch: add --interdiff option to embed diff in cover letter\n      format-patch: teach --interdiff to respect -v/--reroll-count\n      interdiff: teach show_interdiff() to indent interdiff\n      log-tree: show_log: make commentary block delimiting reusable\n      format-patch: allow --interdiff to apply to a lone-patch\n      range-diff: respect diff_option.file rather than assuming 'stdout'\n      range-diff: publish default creation factor\n      range-diff: relieve callers of low-level configuration burden\n      format-patch: add --range-diff option to embed diff in cover letter\n      format-patch: extend --range-diff to accept revision range\n      format-patch: teach --range-diff to respect -v/--reroll-count\n      format-patch: add --creation-factor tweak for --range-diff\n      format-patch: allow --range-diff to apply to a lone-patch\n      worktree: don't die() in library function find_worktree()\n      worktree: move delete_git_dir() earlier in file for upcoming new callers\n      worktree: generalize delete_git_dir() to reduce code duplication\n      worktree: prepare for more checks of whether path can become worktree\n      worktree: disallow adding same path multiple times\n      worktree: teach 'add' to respect --force for registered but missing path\n      worktree: teach 'move' to override lock when --force given twice\n      worktree: teach 'remove' to override lock when --force given twice\n      worktree: delete .git/worktrees if empty after 'remove'\n      doc-diff: fix non-portable 'man' invocation\n      doc-diff: add --clean mode to remove temporary working gunk\n      doc/Makefile: drop doc-diff worktree and temporary files on \"make clean\"\n\nFrederick Eaton (3):\n      git-archimport.1: specify what kind of Arch we're talking about\n      git-column.1: clarify initial description, provide examples\n      git-describe.1: clarify that \"human readable\" is also git-readable\n\nJames Knight (1):\n      build: link with curl-defined linker flags\n\nJann Horn (2):\n      patch-delta: fix oob read\n      patch-delta: consistently report corruption\n\nJeff Hostetler (2):\n      t0051: test GIT_TRACE to a windows named pipe\n      mingw: fix mingw_open_append to work with named pipes\n\nJeff King (97):\n      branch: make \"-l\" a synonym for \"--list\"\n      Add delta-islands.{c,h}\n      pack-objects: add delta-islands support\n      repack: add delta-islands support\n      t5320: tests for delta islands\n      t/perf: factor boilerplate out of test_perf\n      t/perf: factor out percent calculations\n      t/perf: add infrastructure for measuring sizes\n      t/perf: add perf tests for fetches from a bitmapped server\n      pack-bitmap: save \"have\" bitmap from walk\n      pack-objects: reuse on-disk deltas for thin \"have\" objects\n      SubmittingPatches: mention doc-diff\n      rev-list: make empty --stdin not an error\n      trailer: use size_t for string offsets\n      trailer: use size_t for iterating trailer list\n      trailer: pass process_trailer_opts to trailer_info_get()\n      interpret-trailers: tighten check for \"---\" patch boundary\n      interpret-trailers: allow suppressing \"---\" divider\n      pretty, ref-filter: format %(trailers) with no_divider option\n      sequencer: ignore \"---\" divider when parsing trailers\n      append_signoff: use size_t for string offsets\n      coccinelle: use <...> for function exclusion\n      introduce hasheq() and oideq()\n      convert \"oidcmp() == 0\" to oideq()\n      convert \"hashcmp() == 0\" to hasheq()\n      convert \"oidcmp() != 0\" to \"!oideq()\"\n      convert \"hashcmp() != 0\" to \"!hasheq()\"\n      convert hashmap comparison functions to oideq()\n      read-cache: use oideq() in ce_compare functions\n      show_dirstat: simplify same-content check\n      doc-diff: always use oids inside worktree\n      test-delta: read input into a heap buffer\n      t5303: test some corrupt deltas\n      patch-delta: handle truncated copy parameters\n      t5303: use printf to generate delta bases\n      doc/git-branch: remove obsolete \"-l\" references\n      bitmap_has_sha1_in_uninteresting(): drop BUG check\n      t5310: test delta reuse with bitmaps\n      traverse_bitmap_commit_list(): don't free result\n      pack-bitmap: drop \"loaded\" flag\n      reopen_tempfile(): truncate opened file\n      doc-diff: force worktree add\n      config.mak.dev: add -Wformat-security\n      pack-objects: handle island check for \"external\" delta base\n      receive-pack: update comment with check_everything_connected\n      submodule--helper: use \"--\" to signal end of clone options\n      submodule-config: ban submodule urls that start with dash\n      submodule-config: ban submodule paths that start with a dash\n      fsck: detect submodule urls starting with dash\n      fsck: detect submodule paths starting with dash\n      more oideq/hasheq conversions\n      transport: drop refnames from for_each_alternate_ref\n      test-tool: show tool list on error\n      config.mak.dev: enable -Wunused-function\n      run-command: mark path lookup errors with ENOENT\n      t5410: use longer path for sample script\n      upload-pack: fix broken if/else chain in config callback\n      t1450: check large blob in trailing-garbage test\n      check_stream_sha1(): handle input underflow\n      cat-file: handle streaming failures consistently\n      ls-remote: do not send ref prefixes for patterns\n      ls-remote: pass heads/tags prefixes to transport\n      read_istream_pack_non_delta(): document input handling\n      xdiff: provide a separate emit callback for hunks\n      xdiff-interface: provide a separate consume callback for hunks\n      rev-list: handle flags for --indexed-objects\n      approxidate: handle pending number for \"specials\"\n      pathspec: handle non-terminated strings with :(attr)\n      diff: avoid generating unused hunk header lines\n      diff: discard hunk headers for patch-ids earlier\n      diff: use hunk callback for word-diff\n      combine-diff: use an xdiff hunk callback\n      diff: convert --check to use a hunk callback\n      range-diff: use a hunk callback\n      xdiff-interface: drop parse_hunk_header()\n      apply: mark include/exclude options as NONEG\n      am: handle --no-patch-format option\n      ls-files: mark exclude options as NONEG\n      pack-objects: mark index-version option as NONEG\n      cat-file: mark batch options with NONEG\n      status: mark --find-renames option with NONEG\n      format-patch: mark \"--no-numbered\" option with NONEG\n      show-branch: mark --reflog option as NONEG\n      tag: mark \"--message\" option with NONEG\n      cat-file: report an error on multiple --batch options\n      apply: return -1 from option callback instead of calling exit(1)\n      parse-options: drop OPT_DATE()\n      assert NOARG/NONEG behavior of parse-options callbacks\n      midx: double-check large object write loop\n      merge: extract verify_merge_signature() helper\n      merge: handle --verify-signatures for unborn branch\n      pull: handle --verify-signatures for unborn branch\n      approxidate: fix NULL dereference in date_time()\n      bundle: dup() output descriptor closer to point-of-use\n      pack-objects: fix tree_depth and layer invariants\n      pack-objects: zero-initialize tree_depth/layer arrays\n      pack-objects: fix off-by-one in delta-island tree-depth computation\n\nJohannes Schindelin (62):\n      rebase -i --autosquash: demonstrate a problem skipping the last squash\n      rebase -i: be careful to wrap up fixup/squash chains\n      compat/poll: prepare for targeting Windows Vista\n      mingw: set _WIN32_WINNT explicitly for Git for Windows\n      mingw: bump the minimum Windows version to Vista\n      builtin rebase: prepare for builtin rebase -i\n      rebase -i: clarify what happens on a failed `exec`\n      rebase -i: introduce the 'break' command\n      getpwuid(mingw): initialize the structure only once\n      getpwuid(mingw): provide a better default for the user name\n      mingw: use domain information for default email\n      http: add support for selecting SSL backends at runtime\n      pack-objects: fix typo 'detla' -> 'delta'\n      pack-objects (mingw): demonstrate a segmentation fault with large deltas\n      pack-objects (mingw): initialize `packing_data` mutex in the correct spot\n      rebase (autostash): avoid duplicate call to state_dir_path()\n      rebase (autostash): store the full OID in <state-dir>/autostash\n      rebase (autostash): use an explicit OID to apply the stash\n      mingw: factor out code to set stat() data\n      rebase --autostash: demonstrate a problem with dirty submodules\n      rebase --autostash: fix issue with dirty submodules\n      mingw: load system libraries the recommended way\n      mingw: ensure `getcwd()` reports the correct case\n      repack: point out a bug handling stale shallow info\n      shallow: offer to prune only non-existing entries\n      repack -ad: prune the list of shallow commits\n      http: when using Secure Channel, ignore sslCAInfo by default\n      t7800: fix quoting\n      mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)\n      config: rename `dummy` parameter to `cb` in git_default_config()\n      config: allow for platform-specific core.* config settings\n      config: move Windows-specific config settings into compat/mingw.c\n      mingw: unset PERL5LIB by default\n      mingw: fix isatty() after dup2()\n      t3404: decouple some test cases from outcomes of previous test cases\n      t3418: decouple test cases from a previous `rebase -p` test case\n      tests: optionally skip `git rebase -p` tests\n      Windows: force-recompile git.res for differing architectures\n      built-in rebase: demonstrate regression with --autostash\n      built-in rebase --autostash: leave the current branch alone if possible\n      Update .mailmap\n      rebase -r: demonstrate bug with conflicting merges\n      rebase -r: do not write MERGE_HEAD unless needed\n      rebase -i: include MERGE_HEAD into files to clean up\n      built-in rebase --skip/--abort: clean up stale .git/<name> files\n      status: rebase and merge can be in progress at the same time\n      apply --recount: allow \"no-op hunks\"\n      rebase: consolidate clean-up code before leaving reset_head()\n      rebase: prepare reset_head() for more flags\n      built-in rebase: reinstate `checkout -q` behavior where appropriate\n      tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/\n      tests: respect GIT_TEST_INSTALLED when initializing repositories\n      t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set\n      mingw: use `CreateHardLink()` directly\n      rebase: really just passthru the `git am` options\n      rebase: validate -C<n> and --whitespace=<mode> parameters early\n      config: report a bug if git_dir exists without commondir\n      tests: do not require Git to be built when testing an installed Git\n      tests: explicitly use `git.exe` on Windows\n      mingw: replace an obsolete link with the superseding one\n      legacy-rebase: backport -C<n> and --whitespace=<option> checks\n      rebase: warn about the correct tree's OID\n\nJohannes Sixt (3):\n      diff: don't attempt to strip prefix from absolute Windows paths\n      rebase -i: recognize short commands without arguments\n      t3404-rebase-interactive: test abbreviated commands\n\nJonathan Nieder (9):\n      gc: improve handling of errors reading gc.log\n      gc: exit with status 128 on failure\n      gc: do not return error for prior errors in daemonized mode\n      commit-reach: correct accidental #include of C file\n      mailmap: consistently normalize brian m. carlson's name\n      git doc: direct bug reporters to mailing list archive\n      eoie: default to not writing EOIE section\n      ieot: default to not writing IEOT section\n      index: make index.threads=true enable ieot and eoie\n\nJonathan Tan (15):\n      fetch-object: unify fetch_object[s] functions\n      fetch-object: set exact_oid when fetching\n      connected: document connectivity in partial clones\n      fetch: in partial clone, check presence of targets\n      fetch-pack: avoid object flags if no_dependents\n      fetch-pack: exclude blobs when lazy-fetching trees\n      transport: allow skipping of ref listing\n      transport: do not list refs if possible\n      transport: list refs before fetch if necessary\n      fetch: do not list refs if fetching only hashes\n      cache-tree: skip some blob checks in partial clone\n      upload-pack: make have_obj not global\n      upload-pack: make want_obj not global\n      upload-pack: clear flags before each v2 request\n      fetch-pack: be more precise in parsing v2 response\n\nJosh Steadmon (4):\n      fuzz: add basic fuzz testing target.\n      fuzz: add fuzz testing for packfile indices.\n      archive: initialize archivers earlier\n      Makefile: use FUZZ_CXXFLAGS for linking fuzzers\n\nJoshua Watt (1):\n      send-email: explicitly disable authentication\n\nJunio C Hamano (34):\n      Revert \"doc/Makefile: drop doc-diff worktree and temporary files on \"make clean\"\"\n      Initial batch post 2.19\n      Second batch post 2.19\n      Git 2.14.5\n      Git 2.15.3\n      Git 2.16.5\n      Git 2.17.2\n      Git 2.18.1\n      Git 2.19.1\n      t0000: do not get self-test disrupted by environment warnings\n      CodingGuidelines: document the API in *.h files\n      Declare that the next one will be named 2.20\n      Third batch for 2.20\n      rebase: fix typoes in error messages\n      Fourth batch for 2.20\n      Revert \"subtree: make install targets depend on build targets\"\n      Fifth batch for 2.20\n      receive: denyCurrentBranch=updateinstead should not blindly update\n      cocci: simplify \"if (++u > 1)\" to \"if (u++)\"\n      fsck: s/++i > 1/i++/\n      http: give curl version warnings consistently\n      Sixth batch for 2.20\n      Seventh batch for 2.20\n      fetch: replace string-list used as a look-up table with a hashmap\n      rebase: apply cocci patch\n      Eighth batch for 2.20\n      Ninth batch for 2.20\n      Makefile: ease dynamic-gettext-poison transition\n      Tenth batch for 2.20\n      Git 2.20-rc0\n      RelNotes: name the release properly\n      Prepare for 2.20-rc1\n      Git 2.19.2\n      Git 2.20-rc1\n\nKarsten Blees (2):\n      mingw: replace MSVCRT's fstat() with a Win32-based implementation\n      mingw: implement nanosecond-precision file times\n\nLoo Rong Jie (1):\n      win32: replace pthread_cond_*() with much simpler code\n\nLucas De Marchi (1):\n      range-diff: allow to diff files regardless of submodule config\n\nLuke Diamand (3):\n      git-p4: do not fail in verbose mode for missing 'fileSize' key\n      git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved\n      git-p4: fully support unshelving changelists\n\nMartin Ågren (9):\n      Doc: use `--type=bool` instead of `--bool`\n      git-config.txt: fix 'see: above' note\n      git-commit-graph.txt: fix bullet lists\n      git-commit-graph.txt: typeset more in monospace\n      git-commit-graph.txt: refer to \"*commit*-graph file\"\n      Doc: refer to the \"commit-graph file\" with dash\n      t1400: drop debug `echo` to actually execute `test`\n      builtin/commit-graph.c: UNLEAK variables\n      sequencer: break out of loop explicitly\n\nMatthew DeVore (19):\n      list-objects: store common func args in struct\n      list-objects: refactor to process_tree_contents\n      list-objects: always parse trees gently\n      t/README: reformat Do, Don't, Keep in mind lists\n      Documentation: add shell guidelines\n      tests: standardize pipe placement\n      t/*: fix ordering of expected/observed arguments\n      tests: don't swallow Git errors upstream of pipes\n      t9109: don't swallow Git errors upstream of pipes\n      tests: order arguments to git-rev-list properly\n      rev-list: handle missing tree objects properly\n      revision: mark non-user-given objects instead\n      list-objects-filter: use BUG rather than die\n      list-objects-filter-options: do not over-strbuf_init\n      list-objects-filter: implement filter tree:0\n      filter-trees: code clean-up of tests\n      list-objects: support for skipping tree traversal\n      Documentation/git-log.txt: do not show --exclude-promisor-objects\n      exclude-promisor-objects: declare when option is allowed\n\nMax Kirillov (1):\n      http-backend test: make empty CONTENT_LENGTH test more realistic\n\nMichael Witten (3):\n      docs: typo: s/go/to/\n      docs: graph: remove unnecessary `graph_update()' call\n      docs: typo: s/isimilar/similar/\n\nMichał Górny (6):\n      gpg-interface.c: detect and reject multiple signatures on commits\n      gpg-interface.c: use flags to determine key/signer info presence\n      gpg-interface.c: support getting key fingerprint via %GF format\n      gpg-interface.c: obtain primary key fingerprint as well\n      t/t7510-signed-commit.sh: Add %GP to custom format checks\n      t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key\n\nMihir Mehta (1):\n      doc: fix a typo and clarify a sentence\n\nNguyễn Thái Ngọc Duy (168):\n      clone: report duplicate entries on case-insensitive filesystems\n      trace.h: support nested performance tracing\n      unpack-trees: add performance tracing\n      unpack-trees: optimize walking same trees with cache-tree\n      unpack-trees: reduce malloc in cache-tree walk\n      unpack-trees: reuse (still valid) cache-tree from src_index\n      unpack-trees: add missing cache invalidation\n      cache-tree: verify valid cache-tree in the test suite\n      Document update for nd/unpack-trees-with-cache-tree\n      bisect.c: make show_list() build again\n      t/helper: keep test-tool command list sorted\n      t/helper: merge test-dump-untracked-cache into test-tool\n      t/helper: merge test-pkt-line into test-tool\n      t/helper: merge test-parse-options into test-tool\n      t/helper: merge test-dump-fsmonitor into test-tool\n      Makefile: add a hint about TEST_BUILTINS_OBJS\n      config.txt: follow camelCase naming\n      config.txt: move fetch part out to a separate file\n      config.txt: move format part out to a separate file\n      config.txt: move gitcvs part out to a separate file\n      config.txt: move gui part out to a separate file\n      config.txt: move pull part out to a separate file\n      config.txt: move push part out to a separate file\n      config.txt: move receive part out to a separate file\n      config.txt: move sendemail part out to a separate file\n      config.txt: move sequence.editor out of \"core\" part\n      config.txt: move submodule part out to a separate file\n      archive.c: remove implicit dependency the_repository\n      status: show progress bar if refreshing the index takes too long\n      add: do not accept pathspec magic 'attr'\n      completion: support \"git fetch --multiple\"\n      read-cache.c: remove 'const' from index_has_changes()\n      diff.c: reduce implicit dependency on the_index\n      combine-diff.c: remove implicit dependency on the_index\n      blame.c: rename \"repo\" argument to \"r\"\n      diff.c: remove the_index dependency in textconv() functions\n      grep.c: remove implicit dependency on the_index\n      diff.c: remove implicit dependency on the_index\n      read-cache.c: remove implicit dependency on the_index\n      diff-lib.c: remove implicit dependency on the_index\n      ll-merge.c: remove implicit dependency on the_index\n      merge-blobs.c: remove implicit dependency on the_index\n      merge.c: remove implicit dependency on the_index\n      patch-ids.c: remove implicit dependency on the_index\n      sha1-file.c: remove implicit dependency on the_index\n      rerere.c: remove implicit dependency on the_index\n      userdiff.c: remove implicit dependency on the_index\n      line-range.c: remove implicit dependency on the_index\n      submodule.c: remove implicit dependency on the_index\n      tree-diff.c: remove implicit dependency on the_index\n      ws.c: remove implicit dependency on the_index\n      revision.c: remove implicit dependency on the_index\n      revision.c: reduce implicit dependency the_repository\n      read-cache.c: optimize reading index format v4\n      config.txt: correct the note about uploadpack.packObjectsHook\n      help -a: improve and make --verbose default\n      refs.c: indent with tabs, not spaces\n      Add a place for (not) sharing stuff between worktrees\n      submodule.c: remove some of the_repository references\n      completion: fix __gitcomp_builtin no longer consider extra options\n      t1300: extract and use test_cmp_config()\n      worktree: add per-worktree config files\n      refs: new ref types to make per-worktree refs visible to all worktrees\n      revision.c: correct a parameter name\n      revision.c: better error reporting on ref from different worktrees\n      fsck: check HEAD and reflog from other worktrees\n      reflog expire: cover reflog from all worktrees\n      Update makefile in preparation for Documentation/config/*.txt\n      config.txt: move advice.* to a separate file\n      config.txt: move core.* to a separate file\n      config.txt: move add.* to a separate file\n      config.txt: move alias.* to a separate file\n      config.txt: move am.* to a separate file\n      config.txt: move apply.* to a separate file\n      config.txt: move blame.* to a separate file\n      config.txt: move branch.* to a separate file\n      config.txt: move browser.* to a separate file\n      config.txt: move checkout.* to a separate file\n      config.txt: move clean.* to a separate file\n      config.txt: move color.* to a separate file\n      config.txt: move column.* to a separate file\n      config.txt: move commit.* to a separate file\n      config.txt: move credential.* to a separate file\n      config.txt: move completion.* to a separate file\n      config.txt: move diff-config.txt to config/\n      config.txt: move difftool.* to a separate file\n      config.txt: move fastimport.* to a separate file\n      config.txt: move fetch-config.txt to config/\n      config.txt: move filter.* to a separate file\n      config.txt: move format-config.txt to config/\n      config.txt: move fmt-merge-msg-config.txt to config/\n      config.txt: move fsck.* to a separate file\n      config.txt: move gc.* to a separate file\n      config.txt: move gitcvs-config.txt to config/\n      config.txt: move gitweb.* to a separate file\n      config.txt: move grep.* to a separate file\n      config.txt: move gpg.* to a separate file\n      config.txt: move gui-config.txt to config/\n      config.txt: move guitool.* to a separate file\n      config.txt: move help.* to a separate file\n      config.txt: move ssh.* to a separate file\n      config.txt: move http.* to a separate file\n      config.txt: move i18n.* to a separate file\n      git-imap-send.txt: move imap.* to a separate file\n      config.txt: move index.* to a separate file\n      config.txt: move init.* to a separate file\n      config.txt: move instaweb.* to a separate file\n      config.txt: move interactive.* to a separate file\n      config.txt: move log.* to a separate file\n      config.txt: move mailinfo.* to a separate file\n      config.txt: move mailmap.* to a separate file\n      config.txt: move man.* to a separate file\n      config.txt: move merge-config.txt to config/\n      config.txt: move mergetool.* to a separate file\n      config.txt: move notes.* to a separate file\n      config.txt: move pack.* to a separate file\n      config.txt: move pager.* to a separate file\n      config.txt: move pretty.* to a separate file\n      config.txt: move protocol.* to a separate file\n      config.txt: move pull-config.txt to config/\n      config.txt: move push-config.txt to config/\n      config.txt: move rebase-config.txt to config/\n      config.txt: move receive-config.txt to config/\n      config.txt: move remote.* to a separate file\n      config.txt: move remotes.* to a separate file\n      config.txt: move repack.* to a separate file\n      config.txt: move rerere.* to a separate file\n      config.txt: move reset.* to a separate file\n      config.txt: move sendemail-config.txt to config/\n      config.txt: move sequencer.* to a separate file\n      config.txt: move showBranch.* to a separate file\n      config.txt: move splitIndex.* to a separate file\n      config.txt: move status.* to a separate file\n      config.txt: move stash.* to a separate file\n      config.txt: move submodule.* to a separate file\n      config.txt: move tag.* to a separate file\n      config.txt: move transfer.* to a separate file\n      config.txt: move uploadarchive.* to a separate file\n      config.txt: move uploadpack.* to a separate file\n      config.txt: move url.* to a separate file\n      config.txt: move user.* to a separate file\n      config.txt: move versionsort.* to a separate file\n      config.txt: move web.* to a separate file\n      config.txt: move worktree.* to a separate file\n      config.txt: remove config/dummy.txt\n      thread-utils: macros to unconditionally compile pthreads API\n      wildmatch: change behavior of \"foo**bar\" in WM_PATHNAME mode\n      git-worktree.txt: correct linkgit command name\n      sequencer.c: remove a stray semicolon\n      tree-walk.c: fix overoptimistic inclusion in :(exclude) matching\n      run-command.h: include thread-utils.h instead of pthread.h\n      send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c\n      index-pack: remove #ifdef NO_PTHREADS\n      name-hash.c: remove #ifdef NO_PTHREADS\n      attr.c: remove #ifdef NO_PTHREADS\n      grep: remove #ifdef NO_PTHREADS\n      grep: clean up num_threads handling\n      preload-index.c: remove #ifdef NO_PTHREADS\n      pack-objects: remove #ifdef NO_PTHREADS\n      read-cache.c: remove #ifdef NO_PTHREADS\n      read-cache.c: reduce branching based on HAVE_THREADS\n      read-cache.c: initialize copy_len to shut up gcc 8\n      Clean up pthread_create() error handling\n      completion: use __gitcomp_builtin for format-patch\n      build: fix broken command-list.h generation with core.autocrlf\n      format-patch: respect --stat in cover letter's diffstat\n      doc: move extensions.worktreeConfig to the right place\n      clone: fix colliding file detection on APFS\n\nNickolai Belakovski (2):\n      worktree: update documentation for lock_reason and lock_reason_valid\n      worktree: rename is_worktree_locked to worktree_lock_reason\n\nNoam Postavsky (1):\n      log: fix coloring of certain octopus merge shapes\n\nOlga Telezhnaya (3):\n      ref-filter: free memory from used_atom\n      ls-remote: release memory instead of UNLEAK\n      ref-filter: free item->value and item->value->s\n\nPhillip Wood (11):\n      diff: fix --color-moved-ws=allow-indentation-change\n      diff --color-moved-ws: fix double free crash\n      diff --color-moved-ws: fix out of bounds string access\n      diff --color-moved-ws: fix a memory leak\n      diff --color-moved-ws: fix another memory leak\n      diff --color-moved: fix a memory leak\n      am: don't die in read_author_script()\n      am: improve author-script error reporting\n      am: rename read_author_script()\n      add read_author_script() to libgit\n      sequencer: use read_author_script()\n\nPratik Karki (46):\n      rebase: start implementing it as a builtin\n      rebase: refactor common shell functions into their own file\n      builtin/rebase: support running \"git rebase <upstream>\"\n      builtin rebase: support --onto\n      builtin rebase: support `git rebase --onto A...B`\n      builtin rebase: handle the pre-rebase hook and --no-verify\n      builtin rebase: support --quiet\n      builtin rebase: support the `verbose` and `diffstat` options\n      builtin rebase: require a clean worktree\n      builtin rebase: try to fast forward when possible\n      builtin rebase: support --force-rebase\n      builtin rebase: start a new rebase only if none is in progress\n      builtin rebase: only store fully-qualified refs in `options.head_name`\n      builtin rebase: support `git rebase <upstream> <switch-to>`\n      builtin rebase: support --continue\n      builtin rebase: support --skip\n      builtin rebase: support --abort\n      builtin rebase: support --quit\n      builtin rebase: support --edit-todo and --show-current-patch\n      builtin rebase: actions require a rebase in progress\n      builtin rebase: stop if `git am` is in progress\n      builtin rebase: allow selecting the rebase \"backend\"\n      builtin rebase: support --signoff\n      builtin rebase: support --rerere-autoupdate\n      builtin rebase: support --committer-date-is-author-date\n      builtin rebase: support `ignore-whitespace` option\n      builtin rebase: support `ignore-date` option\n      builtin rebase: support `keep-empty` option\n      builtin rebase: support `--autosquash`\n      builtin rebase: support `--gpg-sign` option\n      builtin rebase: support `-C` and `--whitespace=<type>`\n      builtin rebase: support `--autostash` option\n      builtin rebase: support `--exec`\n      builtin rebase: support `--allow-empty-message` option\n      builtin rebase: support --rebase-merges[=[no-]rebase-cousins]\n      merge-base --fork-point: extract libified function\n      builtin rebase: support `fork-point` option\n      builtin rebase: add support for custom merge strategies\n      builtin rebase: support --root\n      builtin rebase: optionally auto-detect the upstream\n      builtin rebase: optionally pass custom reflogs to reset_head()\n      builtin rebase: fast-forward to onto if it is a proper descendant\n      builtin rebase: show progress when connected to a terminal\n      builtin rebase: use no-op editor when interactive is \"implied\"\n      builtin rebase: error out on incompatible option/mode combinations\n      rebase: default to using the builtin rebase\n\nRafael Ascensão (2):\n      refs: show --exclude failure with --branches/tags/remotes=glob\n      refs: fix some exclude patterns being ignored\n\nRalf Thielow (1):\n      git-rebase.sh: fix typos in error messages\n\nRamsay Jones (12):\n      Makefile: add a hdr-check target\n      json-writer.h: add missing include (hdr-check)\n      ewah/ewok_rlw.h: add missing include (hdr-check)\n      refs/ref-cache.h: add missing declarations (hdr-check)\n      refs/packed-backend.h: add missing declaration (hdr-check)\n      refs/refs-internal.h: add missing declarations (hdr-check)\n      midx.h: add missing forward declarations (hdr-check)\n      delta-islands.h: add missing forward declarations (hdr-check)\n      headers: normalize the spelling of some header guards\n      fetch-object.h: add missing declaration (hdr-check)\n      ewok_rlw.h: add missing 'inline' to function definition\n      commit-reach.h: add missing declarations (hdr-check)\n\nRasmus Villemoes (6):\n      help: redirect to aliased commands for \"git cmd --help\"\n      git.c: handle_alias: prepend alias info when first argument is -h\n      git-help.txt: document \"git help cmd\" vs \"git cmd --help\" for aliases\n      Documentation/git-send-email.txt: style fixes\n      send-email: only consider lines containing @ or <> for automatic Cc'ing\n      send-email: also pick up cc addresses from -by trailers\n\nRené Scharfe (12):\n      mailinfo: support format=flowed\n      fsck: add a performance test for skipList\n      fsck: use strbuf_getline() to read skiplist file\n      fsck: use oidset instead of oid_array for skipList\n      sequencer: use return value of oidset_insert()\n      grep: add -r/--[no-]recursive\n      fetch-pack: factor out is_unmatched_ref()\n      fetch-pack: load tip_oids eagerly iff needed\n      khash: factor out kh_release_*\n      oidset: use khash\n      oidset: uninline oidset_init()\n      commit-reach: fix cast in compare_commits_by_gen()\n\nRoger Strain (1):\n      subtree: performance improvement for finding unexpected parent commits\n\nSZEDER Gábor (17):\n      t1404: increase core.packedRefsTimeout to avoid occasional test failure\n      Documentation/git.txt: clarify that GIT_TRACE=/path appends\n      t3701-add-interactive: tighten the check of trace output\n      t1700-split-index: drop unnecessary 'grep'\n      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index\n      t1700-split-index: document why FSMONITOR is disabled in this test script\n      split-index: add tests to demonstrate the racy split index problem\n      t1700-split-index: date back files to avoid racy situations\n      split-index: count the number of deleted entries\n      split-index: don't compare cached data of entries already marked for split index\n      split-index: smudge and add racily clean cache entries to split index\n      split-index: BUG() when cache entry refers to non-existing shared entry\n      object_id.cocci: match only expressions of type 'struct object_id'\n      test-lib: introduce the '-V' short option for '--verbose-log'\n      travis-ci: install packages in 'ci/install-dependencies.sh'\n      coccicheck: introduce 'pending' semantic patches\n      ref-filter: don't look for objects when outside of a repository\n\nSam McKelvie (1):\n      rev-parse: --show-superproject-working-tree should work during a merge\n\nSaulius Gurklys (1):\n      doc: fix small typo in git show-branch\n\nSebastian Staudt (1):\n      travis-ci: no longer use containers\n\nShulhan (1):\n      builtin/remote: quote remote name on error to display empty name\n\nStefan Beller (25):\n      git-submodule.sh: align error reporting for update mode to use path\n      git-submodule.sh: rename unused variables\n      builtin/submodule--helper: factor out submodule updating\n      builtin/submodule--helper: store update_clone information in a struct\n      builtin/submodule--helper: factor out method to update a single submodule\n      submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree\n      submodule--helper: introduce new update-module-mode helper\n      test_decode_color: understand FAINT and ITALIC\n      t3206: add color test for range-diff --dual-color\n      diff.c: simplify caller of emit_line_0\n      diff.c: reorder arguments for emit_line_ws_markup\n      diff.c: add set_sign to emit_line_0\n      diff: use emit_line_0 once per line\n      diff.c: omit check for line prefix in emit_line_0\n      diff.c: rewrite emit_line_0 more understandably\n      diff.c: add --output-indicator-{new, old, context}\n      range-diff: make use of different output indicators\n      range-diff: indent special lines as context\n      refs.c: migrate internal ref iteration to pass thru repository argument\n      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback\n      string-list: remove unused function print_string_list\n      strbuf.h: format according to coding guidelines\n      diff.c: pass sign_index to emit_line_ws_markup\n      submodule helper: convert relative URL to absolute URL if needed\n      builtin/submodule--helper: remove debugging leftover tracing\n\nStephen P. Smith (10):\n      wt-status.c: move has_unmerged earlier in the file\n      wt-status: rename commitable to committable\n      t7501: add test of \"commit --dry-run --short\"\n      wt-status.c: set the committable flag in the collect phase\n      roll wt_status_state into wt_status and populate in the collect phase\n      t2000: rename and combine checkout clash tests\n      t7509: cleanup description and filename\n      t7502: rename commit test script to comply with naming convention\n      t7500: rename commit tests script to comply with naming convention\n      t7501: rename commit test to comply with naming convention\n\nSteve Hoelzer (1):\n      poll: use GetTickCount64() to avoid wrap-around issues\n\nSteven Fernandez (1):\n      git-completion.bash: add completion for stash list\n\nStrain, Roger L (4):\n      subtree: refactor split of a commit into standalone method\n      subtree: make --ignore-joins pay attention to adds\n      subtree: use commits before rejoins for splits\n      subtree: improve decision on merges kept in split\n\nTao Qingyun (3):\n      refs: docstring typo\n      builtin/branch.c: remove useless branch_get\n      branch: trivial style fix\n\nTaylor Blau (4):\n      transport.c: extract 'fill_alternate_refs_command'\n      transport.c: introduce core.alternateRefsCommand\n      transport.c: introduce core.alternateRefsPrefixes\n      Documentation/config.txt: fix typo in core.alternateRefsCommand\n\nThomas Gummerer (17):\n      rerere: unify error messages when read_cache fails\n      rerere: lowercase error messages\n      rerere: wrap paths in output in sq\n      rerere: mark strings for translation\n      rerere: add documentation for conflict normalization\n      rerere: fix crash with files rerere can't handle\n      rerere: only return whether a path has conflicts or not\n      rerere: factor out handle_conflict function\n      rerere: return strbuf from handle path\n      rerere: teach rerere to handle nested conflicts\n      rerere: recalculate conflict ID when unresolved conflict is committed\n      rerere: mention caveat about unmatched conflict markers\n      rerere: add note about files with existing conflict markers\n      .gitattributes: add conflict-marker-size for relevant files\n      linear-assignment: fix potential out of bounds memory access\n      t5551: move setup code inside test_expect blocks\n      t5551: compare sorted cookies files\n\nTim Schumacher (4):\n      Documentation/Makefile: make manpage-base-url.xsl generation quieter\n      alias: add support for aliases of an alias\n      alias: show the call history when an alias is looping\n      t0014: introduce an alias testing suite\n\nTodd Zullinger (1):\n      Documentation: build technical/multi-pack-index\n\nTorsten Bögershausen (4):\n      Make git_check_attr() a void function\n      path.c: char is not (always) signed\n      Upcast size_t variables to uintmax_t when printing\n      remote-curl.c: xcurl_off_t is not portable (on 32 bit platfoms)\n\nUwe Kleine-König (1):\n      howto/using-merge-subtree: mention --allow-unrelated-histories\n\nbrian m. carlson (26):\n      t: add test functions to translate hash-related values\n      t0000: use hash translation table\n      t0000: update tests for SHA-256\n      t0002: abstract away SHA-1 specific constants\n      t0064: make hash size independent\n      t1006: make hash size independent\n      t1400: switch hard-coded object ID to variable\n      t1405: make hash size independent\n      t1406: make hash-size independent\n      t1407: make hash size independent\n      editorconfig: provide editor settings for Git developers\n      editorconfig: indicate settings should be kept in sync\n      pack-bitmap-write: use GIT_MAX_RAWSZ for allocation\n      builtin/repack: replace hard-coded constants\n      builtin/mktree: remove hard-coded constant\n      builtin/fetch-pack: remove constants with parse_oid_hex\n      pack-revindex: express constants in terms of the_hash_algo\n      packfile: express constants in terms of the_hash_algo\n      refs/packed-backend: express constants using the_hash_algo\n      upload-pack: express constants in terms of the_hash_algo\n      transport: use parse_oid_hex instead of a constant\n      tag: express constant in terms of the_hash_algo\n      apply: replace hard-coded constants\n      apply: rename new_sha1_prefix and old_sha1_prefix\n      submodule: make zero-oid comparison hash function agnostic\n      rerere: convert to use the_hash_algo\n\nÆvar Arnfjörð Bjarmason (33):\n      fetch: change \"branch\" to \"reference\" in --force -h output\n      push tests: make use of unused $1 in test description\n      push tests: use spaces in interpolated string\n      fetch tests: add a test for clobbering tag behavior\n      push doc: remove confusing mention of remote merger\n      push doc: move mention of \"tag <tag>\" later in the prose\n      push doc: correct lies about how push refspecs work\n      fetch: document local ref updates with/without --force\n      fetch: stop clobbering existing tags without --force\n      fsck tests: setup of bogus commit object\n      fsck tests: add a test for no skipList input\n      fsck: document and test sorted skipList input\n      fsck: document and test commented & empty line skipList input\n      fsck: document that skipList input must be unabbreviated\n      fsck: add a performance test\n      fsck: support comments & empty lines in skipList\n      commit-graph write: add progress output\n      commit-graph verify: add progress output\n      config doc: add missing list separator for checkout.optimizeNewBranch\n      push doc: add spacing between two words\n      fetch doc: correct grammar in --force docs\n      gc: fix regression in 7b0f229222 impacting --quiet\n      gc doc: mention the commit-graph in the intro\n      pack-objects test: modernize style\n      pack-objects tests: don't leave test .git corrupt at end\n      index-pack tests: don't leave test repo dirty at end\n      i18n: make GETTEXT_POISON a runtime option\n      range-diff doc: add a section about output stability\n      range-diff: fix regression in passing along diff options\n      range-diff: make diff option behavior (e.g. --stat) consistent\n      rebase doc: document rebase.useBuiltin\n      tests: add a special setup where rebase.useBuiltin is off\n      read-cache: make the split index obey umask settings\n\nĐoàn Trần Công Danh (1):\n      git-compat-util: prefer poll.h to sys/poll.h\n\n"},{"id":"363906","messageId":"87ftvt14uw.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"xmqqmuq25ufc.fsf@gitster-ct.c.googlers.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-22T15:58:31Z","receivedAt":"2018-11-22T15:58:40Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 21 2018, Junio C Hamano wrote:\n\n>  * The \"--no-patch\" option, which can be used to get a high-level\n>    overview without the actual line-by-line patch difference shown, of\n>    the \"range-diff\" command was earlier broken, which has been\n>    corrected.\n\nThere's a regression related to this that I wanted to send a headsup\nfor, but don't have time to fix today. Now range-diff in format-patch\nincludes --stat output. See e.g. my\nhttps://public-inbox.org/git/20181122132823.9883-1-avarab@gmail.com/\n\nPreliminary patch:\n\n builtin/log.c         | 3 +++\n t/t3206-range-diff.sh | 2 ++\n 2 files changed, 5 insertions(+)\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 0fe6f9ba1e..fdaba480d2 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1094,9 +1094,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \t}\n\n \tif (rev->rdiff1) {\n+\t\tconst int oldfmt = rev->diffopt.output_format;\n \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n+\t\trev->diffopt.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n \t\t\t\trev->creation_factor, 1, &rev->diffopt);\n+\t\trev->diffopt.output_format = oldfmt;\n \t}\n }\n\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex e497c1358f..2e913542f3 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -248,8 +248,10 @@ test_expect_success 'dual-coloring' '\n for prev in topic master..topic\n do\n \ttest_expect_success \"format-patch --range-diff=$prev\" '\n+\t\tcat actual &&\n \t\tgit format-patch --stdout --cover-letter --range-diff=$prev \\\n \t\t\tmaster..unmodified >actual &&\n+\t\t! grep \"a => b\" actual &&\n \t\tgrep \"= 1: .* s/5/A\" actual &&\n \t\tgrep \"= 2: .* s/4/A\" actual &&\n \t\tgrep \"= 3: .* s/11/B\" actual &&\n"},{"id":"363924","messageId":"CAPig+cSzyT5N5=YeX+VgRq1t0VbWqXLHSB=g=V=O-nLdCWrE9g@mail.gmail.com","threadId":"49877","inReplyTo":"87ftvt14uw.fsf@evledraar.gmail.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-11-22T19:27:04Z","receivedAt":"2018-11-22T19:27:24Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Nov 22, 2018 at 10:58 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> There's a regression related to this that I wanted to send a headsup\n> for, but don't have time to fix today. Now range-diff in format-patch\n> includes --stat output. See e.g. my\n> https://public-inbox.org/git/20181122132823.9883-1-avarab@gmail.com/\n\nUmf. Unfortunate fallout from [1].\n\n> diff --git a/builtin/log.c b/builtin/log.c\n> @@ -1094,9 +1094,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>         if (rev->rdiff1) {\n> +               const int oldfmt = rev->diffopt.output_format;\n>                 fprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n> +               rev->diffopt.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n>                 show_range_diff(rev->rdiff1, rev->rdiff2,\n>                                 rev->creation_factor, 1, &rev->diffopt);\n> +               rev->diffopt.output_format = oldfmt;\n>         }\n>  }\n\nA few questions/observations:\n\nDoes this same \"fix\" need to be applied to the --interdiff case just\nabove this --range-diff block?\n\nDoes the same \"fix\" need to be applied to the --interdiff and\n--range-diff cases in log-tree.c:show_log()?\n\nAside from fixing the broken --no-patches option[2], a goal of the\nseries was to some day make --stat do something useful. Doesn't this\n\"fix\" go against that goal?\n\nThe way this change needs to be spread around at various locations is\nmaking it feel like a BandAid \"fix\" rather than a proper solution. It\nseems like it should be fixed at a different level, though I'm not\nsure yet if that level is higher (where the options get set) or lower\n(where they actually affect the operation).\n\nUntil we figure out the answers to these questions, I wonder if a more\nsensible short-term solution would be to back out [1] and just keep\n[2], which fixed the --no-patches regression.\n\n> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n> @@ -248,8 +248,10 @@ test_expect_success 'dual-coloring' '\n>  for prev in topic master..topic\n>  do\n>         test_expect_success \"format-patch --range-diff=$prev\" '\n> +               cat actual &&\n\nDebugging session gunk?\n\n>                 git format-patch --stdout --cover-letter --range-diff=$prev \\\n>                         master..unmodified >actual &&\n> +               ! grep \"a => b\" actual &&\n>                 grep \"= 1: .* s/5/A\" actual &&\n\n[1]: https://public-inbox.org/git/20181113185558.23438-4-avarab@gmail.com/\n[2]: https://public-inbox.org/git/20181113185558.23438-3-avarab@gmail.com/\n"},{"id":"363926","messageId":"20181122211248.24546-1-avarab@gmail.com","threadId":"49877","inReplyTo":"CAPig+cSzyT5N5=YeX+VgRq1t0VbWqXLHSB=g=V=O-nLdCWrE9g@mail.gmail.com","subject":"[PATCH 0/2] format-patch: pre-2.20 range-diff regression fix","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-22T21:12:46Z","receivedAt":"2018-11-22T21:13:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"[Dropping LKML & git-packagers from CC]\n\nOn Thu, Nov 22 2018, Eric Sunshine wrote:\n\n> On Thu, Nov 22, 2018 at 10:58 AM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>> There's a regression related to this that I wanted to send a headsup\n>> for, but don't have time to fix today. Now range-diff in format-patch\n>> includes --stat output. See e.g. my\n>> https://public-inbox.org/git/20181122132823.9883-1-avarab@gmail.com/\n>\n> Umf. Unfortunate fallout from [1].\n>\n>> diff --git a/builtin/log.c b/builtin/log.c\n>> @@ -1094,9 +1094,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>>         if (rev->rdiff1) {\n>> +               const int oldfmt = rev->diffopt.output_format;\n>>                 fprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n>> +               rev->diffopt.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n>>                 show_range_diff(rev->rdiff1, rev->rdiff2,\n>>                                 rev->creation_factor, 1, &rev->diffopt);\n>> +               rev->diffopt.output_format = oldfmt;\n>>         }\n>>  }\n>\n> A few questions/observations:\n>\n> Does this same \"fix\" need to be applied to the --interdiff case just\n> above this --range-diff block?\n>\n> Does the same \"fix\" need to be applied to the --interdiff and\n> --range-diff cases in log-tree.c:show_log()?\n\nNo, that seems to do the right thing, but perhaps tests are lacking\nthere too. I haven't looked.\n\n> Aside from fixing the broken --no-patches option[2], a goal of the\n> series was to some day make --stat do something useful. Doesn't this\n> \"fix\" go against that goal?\n\nThe goal was to fix the regression introduced in 73a834e9e2\n(\"range-diff: relieve callers of low-level configuration burden\",\n2018-07-22). One aspect of having fixed that is we might in the future\ndo stuff with --stat.\n\n> The way this change needs to be spread around at various locations is\n> making it feel like a BandAid \"fix\" rather than a proper solution. It\n> seems like it should be fixed at a different level, though I'm not\n> sure yet if that level is higher (where the options get set) or lower\n> (where they actually affect the operation).\n>\n> Until we figure out the answers to these questions, I wonder if a more\n> sensible short-term solution would be to back out [1] and just keep\n> [2], which fixed the --no-patches regression.\n\nI think that patch leaves range-diff itself in a good state without\nany bugs, and it would be a mistake to revert it.\n\nBut this interaction with format-patch --range-diff is another\nmatter. As noted in 2/2 I think in practice this series sweeps the\ncurrent bugs under the rug.\n\nBut as also noted there I think re-using what we get from\nsetup_revisions() in format-patch for the range-diff was a mistake,\nand is always going to lead to some confusion. It should be split up\nso we can supply those diff options independently.\n\n> [...]\n> [1]: https://public-inbox.org/git/20181113185558.23438-4-avarab@gmail.com/\n> [2]: https://public-inbox.org/git/20181113185558.23438-3-avarab@gmail.com/\n\nÆvar Arnfjörð Bjarmason (2):\n  format-patch: add a more exhaustive --range-diff test\n  format-patch: don't include --stat with --range-diff output\n\n builtin/log.c         |  7 ++++++-\n t/t3206-range-diff.sh | 15 ++++++++++-----\n 2 files changed, 16 insertions(+), 6 deletions(-)\n\n-- \n2.20.0.rc0.387.gc7a69e6b6c\n\n"},{"id":"363927","messageId":"20181122211248.24546-2-avarab@gmail.com","threadId":"49877","inReplyTo":"CAPig+cSzyT5N5=YeX+VgRq1t0VbWqXLHSB=g=V=O-nLdCWrE9g@mail.gmail.com","subject":"[PATCH 1/2] format-patch: add a more exhaustive --range-diff test","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-22T21:12:47Z","receivedAt":"2018-11-22T21:13:04Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the narrow test added in 31e2617a5f (\"format-patch: add\n--range-diff option to embed diff in cover letter\", 2018-07-22) to\ntest the full output. This test would have spotted a regression in the\noutput if it wasn't beating around the bush and tested the full\noutput, let's do that.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t3206-range-diff.sh | 27 ++++++++++++++++++++++-----\n 1 file changed, 22 insertions(+), 5 deletions(-)\n\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex e497c1358f..0235c038be 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -249,11 +249,28 @@ for prev in topic master..topic\n do\n \ttest_expect_success \"format-patch --range-diff=$prev\" '\n \t\tgit format-patch --stdout --cover-letter --range-diff=$prev \\\n-\t\t\tmaster..unmodified >actual &&\n-\t\tgrep \"= 1: .* s/5/A\" actual &&\n-\t\tgrep \"= 2: .* s/4/A\" actual &&\n-\t\tgrep \"= 3: .* s/11/B\" actual &&\n-\t\tgrep \"= 4: .* s/12/B\" actual\n+\t\t\tmaster..unmodified >actual.raw &&\n+\t\tsed -e \"s|^:||\" -e \"s|:$||\" >expect <<-\\EOF &&\n+\t\t:1:  4de457d = 1:  35b9b25 s/5/A/\n+\t\t:     a => b | 0\n+\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n+\t\t:    :\n+\t\t:2:  fccce22 = 2:  de345ab s/4/A/\n+\t\t:     a => b | 0\n+\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n+\t\t:    :\n+\t\t:3:  147e64e = 3:  9af6654 s/11/B/\n+\t\t:     a => b | 0\n+\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n+\t\t:    :\n+\t\t:4:  a63e992 = 4:  2901f77 s/12/B/\n+\t\t:     a => b | 0\n+\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n+\t\t:    :\n+\t\t:-- :\n+\t\tEOF\n+\t\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual &&\n+\t\ttest_cmp expect actual\n \t'\n done\n \n-- \n2.20.0.rc0.387.gc7a69e6b6c\n\n"},{"id":"363928","messageId":"20181122211248.24546-3-avarab@gmail.com","threadId":"49877","inReplyTo":"CAPig+cSzyT5N5=YeX+VgRq1t0VbWqXLHSB=g=V=O-nLdCWrE9g@mail.gmail.com","subject":"[PATCH 2/2] format-patch: don't include --stat with --range-diff output","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-22T21:12:48Z","receivedAt":"2018-11-22T21:13:06Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a regression introduced in my a48e12ef7a (\"range-diff: make diff\noption behavior (e.g. --stat) consistent\", 2018-11-13). Since the\nformat-patch setup code implicitly sets --stat --summary by default,\nwe started emitting the --stat output in the cover letter's\nrange-diff.\n\nAs noted in df569c3f31 (\"range-diff doc: add a section about output\nstability\", 2018-11-09) the --stat output is currently rather useless,\nand just adds noise.\n\nPerhaps we should detect if --stat or --summary were implicitly passed\nto format-patch, and then pass them along, but I think fixing it this\nway is fine. If our --stat output ever becomes useful in range-diff we\ncan revisit this.\n\nThere's still cases like e.g. --numstat triggering rather useless\nrange-diff output, but I think it's OK to just handle the default\ncase. Users are unlikely to produce a formatted patch with the likes\nof --numstat, or indeed any other custom diff option except -U<n> or\nmaybe -W. If they need weirder combinations of options they can always\nmanually produce the range-diff.\n\nThis whole situation comes about because we're assuming that when the\nuser passes along e.g. -U10 that they want that some 10-line context\nfor the range-diff as for the patches themselves. As noted in [1] I\nthink it's worth re-visiting this and making -U10 just apply to the\npatches, and e.g. --range-diff-U10 to the range-diff. But that's left\nas a topic for another series less close to a rc2.\n\n1. https://public-inbox.org/git/87d0ri7gbs.fsf@evledraar.gmail.com/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/log.c         |  7 ++++++-\n t/t3206-range-diff.sh | 12 ------------\n 2 files changed, 6 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 0fe6f9ba1e..7cd2db0be9 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1094,9 +1094,13 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \t}\n \n \tif (rev->rdiff1) {\n+\t\tstruct diff_options opts;\n+\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n+\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n+\n \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n-\t\t\t\trev->creation_factor, 1, &rev->diffopt);\n+\t\t\t\trev->creation_factor, 1, &opts);\n \t}\n }\n \n@@ -1697,6 +1701,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \tif (!use_patch_format &&\n \t\t(!rev.diffopt.output_format ||\n \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n+\t\t/* Needs to be mirrored in show_range_diff() invocation */\n \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n \tif (!rev.diffopt.stat_width)\n \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex 0235c038be..90def330bd 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -252,21 +252,9 @@ do\n \t\t\tmaster..unmodified >actual.raw &&\n \t\tsed -e \"s|^:||\" -e \"s|:$||\" >expect <<-\\EOF &&\n \t\t:1:  4de457d = 1:  35b9b25 s/5/A/\n-\t\t:     a => b | 0\n-\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n-\t\t:    :\n \t\t:2:  fccce22 = 2:  de345ab s/4/A/\n-\t\t:     a => b | 0\n-\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n-\t\t:    :\n \t\t:3:  147e64e = 3:  9af6654 s/11/B/\n-\t\t:     a => b | 0\n-\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n-\t\t:    :\n \t\t:4:  a63e992 = 4:  2901f77 s/12/B/\n-\t\t:     a => b | 0\n-\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n-\t\t:    :\n \t\t:-- :\n \t\tEOF\n \t\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual &&\n-- \n2.20.0.rc0.387.gc7a69e6b6c\n\n"},{"id":"363981","messageId":"xmqqa7lz43d8.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"20181122211248.24546-3-avarab@gmail.com","subject":"Re: [PATCH 2/2] format-patch: don't include --stat with --range-diff output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-24T02:26:59Z","receivedAt":"2018-11-24T02:27:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n>  \tif (rev->rdiff1) {\n> +\t\tstruct diff_options opts;\n> +\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n> +\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n> +\n>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n> -\t\t\t\trev->creation_factor, 1, &rev->diffopt);\n> +\t\t\t\trev->creation_factor, 1, &opts);\n\nI am not quite convinced if this shallow copy is a safe thing to do.\nQuite honestly at this late in the release cycle, as a band-aid, I'd\nrather see a simpler revert than a change like this that we have to\nworry about what happens if/when show_range_diff() _thinks_ it is\ndone with the opts and ends up discarding resources (e.g. \"FILE *\")\nthat are shared with rev->diffopt that would still have to be used\nlater.\n\n"},{"id":"363987","messageId":"xmqqo9af2jte.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"20181122211248.24546-2-avarab@gmail.com","subject":"Re: [PATCH 1/2] format-patch: add a more exhaustive --range-diff test","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-24T04:14:37Z","receivedAt":"2018-11-24T04:14:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Change the narrow test added in 31e2617a5f (\"format-patch: add\n> --range-diff option to embed diff in cover letter\", 2018-07-22) to\n> test the full output. This test would have spotted a regression in the\n> output if it wasn't beating around the bush and tested the full\n> output, let's do that.\n\nThis looks wrong, given that we are declaring that showing the\nbroken --stat in the output is wrong.  It makes us to expect a\nknown-wrong output from the command.\n\nIf the theme of the topic were \"what we are giving by default is a\nsensible output when --stat is asked for, but it is rather too noisy\nand our default should be quieter---let's tone it down\", then this\npatch in 1/2 and then a behaviour-change patch with updated\nexpectation would make sense, but I do not think that is what you\nare aiming for with this series.\n\nPerhaps squash this into the real \"fix\" to show what the desired\noutput should look like with the same patch?\n\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  t/t3206-range-diff.sh | 27 ++++++++++++++++++++++-----\n>  1 file changed, 22 insertions(+), 5 deletions(-)\n>\n> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n> index e497c1358f..0235c038be 100755\n> --- a/t/t3206-range-diff.sh\n> +++ b/t/t3206-range-diff.sh\n> @@ -249,11 +249,28 @@ for prev in topic master..topic\n>  do\n>  \ttest_expect_success \"format-patch --range-diff=$prev\" '\n>  \t\tgit format-patch --stdout --cover-letter --range-diff=$prev \\\n> -\t\t\tmaster..unmodified >actual &&\n> -\t\tgrep \"= 1: .* s/5/A\" actual &&\n> -\t\tgrep \"= 2: .* s/4/A\" actual &&\n> -\t\tgrep \"= 3: .* s/11/B\" actual &&\n> -\t\tgrep \"= 4: .* s/12/B\" actual\n> +\t\t\tmaster..unmodified >actual.raw &&\n> +\t\tsed -e \"s|^:||\" -e \"s|:$||\" >expect <<-\\EOF &&\n> +\t\t:1:  4de457d = 1:  35b9b25 s/5/A/\n> +\t\t:     a => b | 0\n> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n> +\t\t:    :\n> +\t\t:2:  fccce22 = 2:  de345ab s/4/A/\n> +\t\t:     a => b | 0\n> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n> +\t\t:    :\n> +\t\t:3:  147e64e = 3:  9af6654 s/11/B/\n> +\t\t:     a => b | 0\n> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n> +\t\t:    :\n> +\t\t:4:  a63e992 = 4:  2901f77 s/12/B/\n> +\t\t:     a => b | 0\n> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n> +\t\t:    :\n> +\t\t:-- :\n> +\t\tEOF\n> +\t\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual &&\n> +\t\ttest_cmp expect actual\n>  \t'\n>  done\n"},{"id":"363988","messageId":"xmqqk1l32jo2.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"xmqqa7lz43d8.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH 2/2] format-patch: don't include --stat with --range-diff output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-24T04:17:49Z","receivedAt":"2018-11-24T04:17:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>>  \tif (rev->rdiff1) {\n>> +\t\tstruct diff_options opts;\n>> +\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n>> +\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n>> +\n>>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n>>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n>> -\t\t\t\trev->creation_factor, 1, &rev->diffopt);\n>> +\t\t\t\trev->creation_factor, 1, &opts);\n>\n> I am not quite convinced if this shallow copy is a safe thing to do.\n> Quite honestly at this late in the release cycle, as a band-aid, I'd\n> rather see a simpler revert than a change like this that we have to\n> worry about what happens if/when show_range_diff() _thinks_ it is\n> done with the opts and ends up discarding resources (e.g. \"FILE *\")\n> that are shared with rev->diffopt that would still have to be used\n> later.\n\nWell, let's take it anyway as-is, at least for today, as I notice\nshow_range_diff() itself does another shallow copy, so we are not\nmaking anything dramatically worse.\n\nThanks.\n"},{"id":"363997","messageId":"87bm6e1yx5.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"xmqqo9af2jte.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH 1/2] format-patch: add a more exhaustive --range-diff test","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-24T11:45:58Z","receivedAt":"2018-11-24T11:46:05Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Sat, Nov 24 2018, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> Change the narrow test added in 31e2617a5f (\"format-patch: add\n>> --range-diff option to embed diff in cover letter\", 2018-07-22) to\n>> test the full output. This test would have spotted a regression in the\n>> output if it wasn't beating around the bush and tested the full\n>> output, let's do that.\n>\n> This looks wrong, given that we are declaring that showing the\n> broken --stat in the output is wrong.  It makes us to expect a\n> known-wrong output from the command.\n>\n> If the theme of the topic were \"what we are giving by default is a\n> sensible output when --stat is asked for, but it is rather too noisy\n> and our default should be quieter---let's tone it down\", then this\n> patch in 1/2 and then a behaviour-change patch with updated\n> expectation would make sense, but I do not think that is what you\n> are aiming for with this series.\n>\n> Perhaps squash this into the real \"fix\" to show what the desired\n> output should look like with the same patch?\n\nI see you did that in 'pu'. I don't mind, looks good to me.\n\nFWIW I split this up for ease of review, i.e. showing what the output\nwas before and what effect the code change had, but maybe that was\noverdoing it and it's simpler just to have this all in one go.\n\n>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> ---\n>>  t/t3206-range-diff.sh | 27 ++++++++++++++++++++++-----\n>>  1 file changed, 22 insertions(+), 5 deletions(-)\n>>\n>> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n>> index e497c1358f..0235c038be 100755\n>> --- a/t/t3206-range-diff.sh\n>> +++ b/t/t3206-range-diff.sh\n>> @@ -249,11 +249,28 @@ for prev in topic master..topic\n>>  do\n>>  \ttest_expect_success \"format-patch --range-diff=$prev\" '\n>>  \t\tgit format-patch --stdout --cover-letter --range-diff=$prev \\\n>> -\t\t\tmaster..unmodified >actual &&\n>> -\t\tgrep \"= 1: .* s/5/A\" actual &&\n>> -\t\tgrep \"= 2: .* s/4/A\" actual &&\n>> -\t\tgrep \"= 3: .* s/11/B\" actual &&\n>> -\t\tgrep \"= 4: .* s/12/B\" actual\n>> +\t\t\tmaster..unmodified >actual.raw &&\n>> +\t\tsed -e \"s|^:||\" -e \"s|:$||\" >expect <<-\\EOF &&\n>> +\t\t:1:  4de457d = 1:  35b9b25 s/5/A/\n>> +\t\t:     a => b | 0\n>> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n>> +\t\t:    :\n>> +\t\t:2:  fccce22 = 2:  de345ab s/4/A/\n>> +\t\t:     a => b | 0\n>> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n>> +\t\t:    :\n>> +\t\t:3:  147e64e = 3:  9af6654 s/11/B/\n>> +\t\t:     a => b | 0\n>> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n>> +\t\t:    :\n>> +\t\t:4:  a63e992 = 4:  2901f77 s/12/B/\n>> +\t\t:     a => b | 0\n>> +\t\t:     1 file changed, 0 insertions(+), 0 deletions(-)\n>> +\t\t:    :\n>> +\t\t:-- :\n>> +\t\tEOF\n>> +\t\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual &&\n>> +\t\ttest_cmp expect actual\n>>  \t'\n>>  done\n"},{"id":"364012","messageId":"877eh219ih.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"xmqqmuq25ufc.fsf@gitster-ct.c.googlers.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-24T20:54:46Z","receivedAt":"2018-11-24T20:54:51Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 21 2018, Junio C Hamano wrote:\n\n>  * \"git rebase\" and \"git rebase -i\" have been reimplemented in C.\n\nHere's another regression in the C version (and rc1), note: the\nsha1collisiondetection is just a stand in for \"some repo\":\n\n    (\n        rm -rf /tmp/repo &&\n        git init /tmp/repo &&\n        cd /tmp/repo &&\n        for c in 1 2\n        do\n            touch $c &&\n            git add $c &&\n            git commit -m\"add $c\"\n        done &&\n        git remote add origin https://github.com/cr-marcstevens/sha1collisiondetection.git &&\n        git fetch &&\n        git branch --set-upstream-to origin/master &&\n        git rebase -i\n    )\n\nThe C version will die with \"fatal: unable to read tree\n0000000000000000000000000000000000000000\". Running this with\nrebase.useBuiltin=false does the right thing and rebases as of the merge\nbase of the two (which here is the root of the history).\n\nI wasn't trying to stress test rebase. I was just wanting to rebase a\nhistory I was about to force-push after cleaning it up, hardly an\nobscure use-case. So [repeat last transmission in\nhttps://public-inbox.org/git/87y39w1wc2.fsf@evledraar.gmail.com/ ]\n"},{"id":"364016","messageId":"xmqq36rq2cp0.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"877eh219ih.fsf@evledraar.gmail.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-25T01:00:43Z","receivedAt":"2018-11-25T01:00:50Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n>>  * \"git rebase\" and \"git rebase -i\" have been reimplemented in C.\n>\n> Here's another regression in the C version (and rc1),...\n> I wasn't trying to stress test rebase. I was just wanting to rebase a\n> history I was about to force-push after cleaning it up, hardly an\n> obscure use-case. So [repeat last transmission in\n> https://public-inbox.org/git/87y39w1wc2.fsf@evledraar.gmail.com/ ]\n\nwhich, to those who are reading from sidelines:\n\n    Given that we're still finding regressions bugs in the rebase-in-C\n    version should we be considering reverting 5541bd5b8f (\"rebase: default\n    to using the builtin rebase\", 2018-08-08)?\n\n    I love the feature, but fear that the current list of known regressions\n    serve as a canary for a larger list which we'd discover if we held off\n    for another major release (and would re-enable rebase.useBuiltin=true in\n    master right after 2.20 is out the door).\n\nI am fine with the proposed flip, but I'll have to see the extent of\ndamage this late in the game so that I won't miss anything.  In\naddition to the one-liner below, we'd need to update the quoted\nrelease notes entry, and possibly adjust some tests (even though the\n\"reimplementation\" ought to be bug-to-bug compatible, it may not be).\n\ndiff --git b/builtin/rebase.c a/builtin/rebase.c\nindex 9dc8475cd3..60e357c735 100644\n--- b/builtin/rebase.c\n+++ a/builtin/rebase.c\n@@ -54,7 +54,7 @@ static int use_builtin_rebase(void)\n \tcp.git_cmd = 1;\n \tif (capture_command(&cp, &out, 6)) {\n \t\tstrbuf_release(&out);\n-\t\treturn 1;\n+\t\treturn 0;\n \t}\n \n \tstrbuf_trim(&out);\n"},{"id":"364055","messageId":"xmqq36roz7ve.fsf_-_@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"xmqq36rq2cp0.fsf@gitster-ct.c.googlers.com","subject":"[PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-26T06:10:45Z","receivedAt":"2018-11-26T06:10:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n>>>  * \"git rebase\" and \"git rebase -i\" have been reimplemented in C.\n>>\n>> Here's another regression in the C version (and rc1),...\n>> I wasn't trying to stress test rebase. I was just wanting to rebase a\n>> history I was about to force-push after cleaning it up, hardly an\n>> obscure use-case. So [repeat last transmission in\n>> https://public-inbox.org/git/87y39w1wc2.fsf@evledraar.gmail.com/ ]\n>\n> which, to those who are reading from sidelines:\n>\n>     Given that we're still finding regressions bugs in the rebase-in-C\n>     version should we be considering reverting 5541bd5b8f (\"rebase: default\n>     to using the builtin rebase\", 2018-08-08)?\n>\n>     I love the feature, but fear that the current list of known regressions\n>     serve as a canary for a larger list which we'd discover if we held off\n>     for another major release (and would re-enable rebase.useBuiltin=true in\n>     master right after 2.20 is out the door).\n>\n> I am fine with the proposed flip, but I'll have to see the extent of\n> damage this late in the game so that I won't miss anything.  In\n> addition to the one-liner below, we'd need to update the quoted\n> release notes entry, and possibly adjust some tests (even though the\n> \"reimplementation\" ought to be bug-to-bug compatible, it may not be).\n\nSo, in a more concrete form, what you want to see is something like\nthis in -rc2 and later?\n\n-- >8 --\nSubject: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature\n\nIt turns out to be a bit too early to unleash the reimplementation\nto the general public.  Let's rewrite some documentation and make it\nan opt-in feature.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/config/rebase.txt | 16 ++++++----------\n builtin/rebase.c                |  2 +-\n t/README                        |  4 ++--\n 3 files changed, 9 insertions(+), 13 deletions(-)\n\ndiff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt\nindex f079bf6b7e..af12623151 100644\n--- a/Documentation/config/rebase.txt\n+++ b/Documentation/config/rebase.txt\n@@ -1,16 +1,12 @@\n rebase.useBuiltin::\n-\tSet to `false` to use the legacy shellscript implementation of\n-\tlinkgit:git-rebase[1]. Is `true` by default, which means use\n-\tthe built-in rewrite of it in C.\n+\tSet to `true` to use the experimental reimplementation of\n+\tlinkgit:git-rebase[1] in C.  Defaults to `false`.\n +\n The C rewrite is first included with Git version 2.20. This option\n-serves an an escape hatch to re-enable the legacy version in case any\n-bugs are found in the rewrite. This option and the shellscript version\n-of linkgit:git-rebase[1] will be removed in some future release.\n-+\n-If you find some reason to set this option to `false` other than\n-one-off testing you should report the behavior difference as a bug in\n-git.\n+allows early adopters to opt into the experimental version to find\n+bugs in the rewritten version. This option and the shellscript version\n+of linkgit:git-rebase[1] will be removed in some future release once\n+the reimplementation becomes more stable.\n \n rebase.stat::\n \tWhether to show a diffstat of what changed upstream since the last\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 5b3e5baec8..19ad97b177 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -59,7 +59,7 @@ static int use_builtin_rebase(void)\n \tcp.git_cmd = 1;\n \tif (capture_command(&cp, &out, 6)) {\n \t\tstrbuf_release(&out);\n-\t\treturn 1;\n+\t\treturn 0;\n \t}\n \n \tstrbuf_trim(&out);\ndiff --git a/t/README b/t/README\nindex 28711cc508..7e925e5fea 100644\n--- a/t/README\n+++ b/t/README\n@@ -345,8 +345,8 @@ for the index version specified.  Can be set to any valid version\n GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path\n by overriding the minimum number of cache entries required per thread.\n \n-GIT_TEST_REBASE_USE_BUILTIN=<boolean>, when false, disables the\n-builtin version of git-rebase. See 'rebase.useBuiltin' in\n+GIT_TEST_REBASE_USE_BUILTIN=<boolean>, when true, forces the use of\n+builtin version of git-rebase in the test. See 'rebase.useBuiltin' in\n git-config(1).\n \n GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading\n-- \n2.20.0-rc1\n\n\n\n\n"},{"id":"364065","messageId":"xmqqd0qswau1.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"xmqqmuq25ufc.fsf@gitster-ct.c.googlers.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-26T07:35:02Z","receivedAt":"2018-11-26T07:35:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Unless I hear otherwise in the next 24 hours, I am planning to\nmerge the following topics to 'master' before cutting -rc2.  Please\nstop me on any of these topics.\n\n - jc/postpone-rebase-in-c\n\n   This may be the most controversial.  It demotes the C\n   reimplementation of \"git rebase\" to an experimental opt-in\n   feature that can only be enabled by setting rebase.useBuiltIn\n   configuration that defaults to false.\n\n   cf. <xmqq36roz7ve.fsf_-_@gitster-ct.c.googlers.com>\n\n\n - ab/format-patch-rangediff-not-stat\n\n   The \"--rangediff\" option recently added to \"format-patch\"\n   interspersed a bogus and useless \"--stat\" information by mistake,\n   which is being corrected.\n\n   cf. <xmqqa7lz43d8.fsf@gitster-ct.c.googlers.com>\n\n\nThe following three topics I do not need help in deciding; they are\nall good and will be merged before -rc2.\n\n - jk/t5562-perl-path-fix\n\n   This is to invoke a perl scriptlet with \"$PERL_PATH\" in one of\n   the new tests, instead of relying on (an incorrect) she-bang line\n   in the script file.\n\n - tb/clone-case-smashing-warning-test\n\n   This enables the test to see the behaviour of \"git clone\" after\n   cloning a project that has paths that are different only in case\n   on MINGW (earlier it wanted CASE_INSENSITIVE_FS prerequisite and\n   in addition not on MINGW).\n\n - nd/per-worktree-ref-iteration\n\n   This fixes a \"return function_that_returns_void(...)\" in a\n   function that returns void.\n\n\nThanks.\n"},{"id":"364077","messageId":"CABPp-BFY-BmfgphwJ6UrGL0+kS3soa_fM9ayMwPZXQ2zNULRyQ@mail.gmail.com","threadId":"49877","inReplyTo":"xmqqd0qswau1.fsf@gitster-ct.c.googlers.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2018-11-26T15:41:28Z","receivedAt":"2018-11-26T15:41:43Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sun, Nov 25, 2018 at 11:37 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Unless I hear otherwise in the next 24 hours, I am planning to\n> merge the following topics to 'master' before cutting -rc2.  Please\n> stop me on any of these topics.\n>\n>  - jc/postpone-rebase-in-c\n>\n>    This may be the most controversial.  It demotes the C\n>    reimplementation of \"git rebase\" to an experimental opt-in\n>    feature that can only be enabled by setting rebase.useBuiltIn\n>    configuration that defaults to false.\n>\n>    cf. <xmqq36roz7ve.fsf_-_@gitster-ct.c.googlers.com>\n\nIf we don't set rebase.useBuiltin to false, then there is also a minor\nregression in the error message printed by the built-in rebase we may\nwant to try to address.  I have a patch for it at\n<20181122044841.20993-2-newren@gmail.com>, but I don't know if that\npatch is acceptable as-is this close to a release since that'd not\ngive translators much time to update.\n"},{"id":"364103","messageId":"nycvar.QRO.7.76.6.1811262347360.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"877eh219ih.fsf@evledraar.gmail.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-26T22:52:22Z","receivedAt":"2018-11-26T22:52:45Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Sat, 24 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n\n> On Wed, Nov 21 2018, Junio C Hamano wrote:\n> \n> >  * \"git rebase\" and \"git rebase -i\" have been reimplemented in C.\n> \n> Here's another regression in the C version (and rc1), note: the\n> sha1collisiondetection is just a stand in for \"some repo\":\n> \n>     (\n>         rm -rf /tmp/repo &&\n>         git init /tmp/repo &&\n>         cd /tmp/repo &&\n>         for c in 1 2\n>         do\n>             touch $c &&\n>             git add $c &&\n>             git commit -m\"add $c\"\n>         done &&\n>         git remote add origin https://github.com/cr-marcstevens/sha1collisiondetection.git &&\n>         git fetch &&\n>         git branch --set-upstream-to origin/master &&\n>         git rebase -i\n>     )\n> \n> The C version will die with \"fatal: unable to read tree\n> 0000000000000000000000000000000000000000\". Running this with\n> rebase.useBuiltin=false does the right thing and rebases as of the merge\n> base of the two (which here is the root of the history).\n\nSorry, this bug does not reproduce here:\n\n$ git rebase -i\nSuccessfully rebased and updated refs/heads/master.\n\n> I wasn't trying to stress test rebase. I was just wanting to rebase a\n> history I was about to force-push after cleaning it up, hardly an\n> obscure use-case. So [repeat last transmission in\n> https://public-inbox.org/git/87y39w1wc2.fsf@evledraar.gmail.com/ ]\n\nMaybe you can give me the full details so that I can verify that this is\nindeed a bug in the builtin C and not just a regression caused by some\nrandom branches being merged together?\n\nIn short: please provide me with the exact URL and branch of your git.git\nfork to test. Then please make sure to specify the precise revision of the\nsha1collisiondetection/master rev, just in case that it matters.\n\nIdeally, you would reduce the problem to a proper test case, say, for\nt3412 (it seems that you try to rebase onto an unrelated history, so it is\n*vaguely* related to \"rebase-root\").\n\nCiao,\nDscho"},{"id":"364107","messageId":"nycvar.QRO.7.76.6.1811270008580.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811262347360.41@tvgsbejvaqbjf.bet","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-26T23:47:24Z","receivedAt":"2018-11-26T23:47:47Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Mon, 26 Nov 2018, Johannes Schindelin wrote:\n\n> On Sat, 24 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n> \n> > On Wed, Nov 21 2018, Junio C Hamano wrote:\n> > \n> > >  * \"git rebase\" and \"git rebase -i\" have been reimplemented in C.\n> > \n> > Here's another regression in the C version (and rc1), note: the\n> > sha1collisiondetection is just a stand in for \"some repo\":\n> > \n> >     (\n> >         rm -rf /tmp/repo &&\n> >         git init /tmp/repo &&\n> >         cd /tmp/repo &&\n> >         for c in 1 2\n> >         do\n> >             touch $c &&\n> >             git add $c &&\n> >             git commit -m\"add $c\"\n> >         done &&\n> >         git remote add origin https://github.com/cr-marcstevens/sha1collisiondetection.git &&\n> >         git fetch &&\n> >         git branch --set-upstream-to origin/master &&\n> >         git rebase -i\n> >     )\n> > \n> > The C version will die with \"fatal: unable to read tree\n> > 0000000000000000000000000000000000000000\". Running this with\n> > rebase.useBuiltin=false does the right thing and rebases as of the merge\n> > base of the two (which here is the root of the history).\n> \n> Sorry, this bug does not reproduce here:\n> \n> $ git rebase -i\n> Successfully rebased and updated refs/heads/master.\n> \n> > I wasn't trying to stress test rebase. I was just wanting to rebase a\n> > history I was about to force-push after cleaning it up, hardly an\n> > obscure use-case. So [repeat last transmission in\n> > https://public-inbox.org/git/87y39w1wc2.fsf@evledraar.gmail.com/ ]\n> \n> Maybe you can give me the full details so that I can verify that this is\n> indeed a bug in the builtin C and not just a regression caused by some\n> random branches being merged together?\n> \n> In short: please provide me with the exact URL and branch of your git.git\n> fork to test. Then please make sure to specify the precise revision of the\n> sha1collisiondetection/master rev, just in case that it matters.\n> \n> Ideally, you would reduce the problem to a proper test case, say, for\n> t3412 (it seems that you try to rebase onto an unrelated history, so it is\n> *vaguely* related to \"rebase-root\").\n\nSo I was getting spooked enough by your half-complete bug report that I\ndid more digging (it is really quite a bit frustrating to have so little\nhard evidence to go on, a wild goose chase is definitely not what I was\nlooking forward to after a day of fighting other fires, but you know,\nbuilt-in rebase is dear to me).\n\nThe error message you copied clearly comes from tree-walk.c, from\n`fill_tree_descriptor()` (the other \"unable to read tree\" messages enclose\nthe hash in parentheses).\n\nThere are exactly 3 calls to said function in the built-in rebase/rebase\n-i in the current `master`, a1598010f775 (Merge branch\n'nd/per-worktree-ref-iteration', 2018-11-26):\n\n$ git grep fill_tree_descriptor -- builtin/rebase*.c sequencer.[ch] rebase-interactive.[ch]\nbuiltin/rebase.c:       if (!reset_hard && !fill_tree_descriptor(&desc[nr++], &head_oid)) {\nbuiltin/rebase.c:       if (!fill_tree_descriptor(&desc[nr++], oid)) {\nsequencer.c:    if (!fill_tree_descriptor(&desc, &oid)) {\n\nThe last one of these is in `do_reset()`, i.e. handling a `reset` command\nwhich you did not ask for, as you passed `-i` to `git rebase`, not `-ir`.\n\nThe first two *both* are in `reset_head()`. The first of them uses\n`head_oid`, which is read directly via `get_oid(\"HEAD\", &head_oid)`, so if\nthis is all zeroes for you, then it's not rebase's fault.\n\nThe second one uses the parameter `oid` passed into `reset_head()`. The\nonly calls to that function that do not pass `NULL` as `oid` (which would\ntrigger `oid` to be replaced by `&head_oid`, i.e again not all zeroes\nunless your setup is broken) are:\n\n- in the `--abort` code path\n- in the `--autostash` code path\n- in the fast-forwarding code path\n- just after the \"First, rewinding head\" message in the *non*-interactive\n  rebase\n\nNone of these apply to your script snippet.\n\nUnder the assumption that you might have forgotten to talk about\nrebase.autostash=true and some dirty file, I tried to augment the script\nsnippet accordingly, but the built-in rebase as of current `master` still\nworks for me, plus: reading the autostash code path, it is hard to imagine\nthat the `lookup_commit_reference()` would return a pointer to a commit\nobject whose oid is all zeroes.\n\nIn short, even a thorough study of the code (keeping in mind the few\ntidbits of information provided by you) leaves me really wondering which\ncode you run, because it sure does not look like current `master` to me.\n\nAnd if it is not `master`, then I have to ask why you keep suggesting to\nturn off the built-in rebase by default in `master`.\n\nCiao,\nJohannes\n\nP.S.: Maybe you have a hook you forgot to mention?\n"},{"id":"364111","messageId":"xmqqftvnuzd5.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"CABPp-BFY-BmfgphwJ6UrGL0+kS3soa_fM9ayMwPZXQ2zNULRyQ@mail.gmail.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-27T00:40:22Z","receivedAt":"2018-11-27T00:40:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> If we don't set rebase.useBuiltin to false, then there is also a minor\n> regression in the error message printed by the built-in rebase we may\n> want to try to address.  I have a patch for it at\n> <20181122044841.20993-2-newren@gmail.com>, but I don't know if that\n> patch is acceptable as-is this close to a release since that'd not\n> give translators much time to update.\n\nFor this particular one, I'd rather ship \"rebase in C\" with known\nmessage glitch, with or without the \"mark it experimental and make\nit opt-in\" last-time change.  Of course, turning it off by default\nwould let us worry about these message glitches even less, but at\nthis point, I'd be worried more about bugs that can affect the\nactual operation and outcome recorded in the resulting history.\n"},{"id":"364183","messageId":"xmqq5zwhu9on.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811270008580.41@tvgsbejvaqbjf.bet","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-28T04:07:20Z","receivedAt":"2018-11-28T04:07:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> ...\n> In short, even a thorough study of the code (keeping in mind the few\n> tidbits of information provided by you) leaves me really wondering which\n> code you run, because it sure does not look like current `master` to me.\n>\n> And if it is not `master`, then I have to ask why you keep suggesting to\n> turn off the built-in rebase by default in `master`.\n>\n> Ciao,\n> Johannes\n>\n> P.S.: Maybe you have a hook you forgot to mention?\n\nAny response?  Or can I retract jc/postpone-rebase-in-c that was\nprepared as a reaction to this?\n"},{"id":"364187","messageId":"20181128043154.GA34163@google.com","threadId":"49877","inReplyTo":"xmqq36roz7ve.fsf_-_@gitster-ct.c.googlers.com","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2018-11-28T04:31:54Z","receivedAt":"2018-11-28T04:31:59Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nJunio C Hamano wrote:\n>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n>>> Given that we're still finding regressions bugs in the rebase-in-C\n>>> version should we be considering reverting 5541bd5b8f (\"rebase: default\n>>> to using the builtin rebase\", 2018-08-08)?\n>>>\n>>> I love the feature, but fear that the current list of known regressions\n>>> serve as a canary for a larger list which we'd discover if we held off\n>>> for another major release (and would re-enable rebase.useBuiltin=true in\n>>> master right after 2.20 is out the door).\n[...]\n> So, in a more concrete form, what you want to see is something like\n> this in -rc2 and later?\n>\n> -- >8 --\n> Subject: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature\n>\n> It turns out to be a bit too early to unleash the reimplementation\n> to the general public.  Let's rewrite some documentation and make it\n> an opt-in feature.\n>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  Documentation/config/rebase.txt | 16 ++++++----------\n>  builtin/rebase.c                |  2 +-\n>  t/README                        |  4 ++--\n>  3 files changed, 9 insertions(+), 13 deletions(-)\n\nI thought I should weigh in on how this would affect Debian's and\nGoogle's deployments.\n\nFirst of all, I've looked over the revert patch carefully and it is\nwell written and does what it says on the tin.\n\nAt https://bugs.debian.org/914695 is a report of a test regression in\nan outside project that is very likely to have been triggered by the\nnew faster rebase code.  The issue has not been triaged, so I don't\nknow yet whether it's a problem in rebase-in-c or a manifestation of a\nbug in the test.\n\nThat said, Google has been running with the new rebase since ~1 month\nago when it became the default, with no issues reported by users.  As\na result, I am confident that it can cope with what most users of\n\"next\" throw at it, which means that if we are to find more issues to\npolish it better, it will need all the exposure it can get.\n\nIn the Google deployment, we will keep using rebase-in-c even if it\ngets disabled by default, in order to help with that.\n\nFrom the Debian point of view, it's only a matter of time before\nrebase-in-c becomes the default: even if it's not the default in 2.20,\nit would presumably be so in 2.21 or 2.22.  That means the community's\nattention when resolving security and reliability bugs would be on the\nrebase-in-c implementation.  As a result, the Debian package will most\nlikely enable rebase-in-c by default even if upstream disables it, in\norder to increase the package's shelf life (i.e. to ease the\nmaintenance burden of supporting whichever version of the package ends\nup in the next Debian stable).\n\nSo with either hat on, it doesn't matter whether you apply this patch\nupstream.\n\nHaving two pretty different deployments end up with the same\nconclusion leads me to suspect that it's best for upstream not to\napply the revert patch, unless either\n\n  (a) we have a concrete regression to address and then try again, or\n  (b) we have a test or other plan to follow before trying again.\n\nThanks and hope that helps,\nJonathan\n"},{"id":"364202","messageId":"nycvar.QRO.7.76.6.1811281015360.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"20181128043154.GA34163@google.com","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-28T09:23:50Z","receivedAt":"2018-11-28T09:23:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Jonathan,\n\nOn Tue, 27 Nov 2018, Jonathan Nieder wrote:\n\n> At https://bugs.debian.org/914695 is a report of a test regression in\n> an outside project that is very likely to have been triggered by the\n> new faster rebase code.\n\nFrom looking through that log.gz (without having a clue where the test\ncode lives, so I cannot say what it is supposed to do, and also: this is\nthe first time I hear about dgit...), it would appear that this must be a\nregression in the reflog messages produced by `git rebase`.\n\n> The issue has not been triaged, so I don't know yet whether it's a\n> problem in rebase-in-c or a manifestation of a bug in the test.\n\nIt ends thusly:\n\n-- snip --\n[...]\n+ git reflog\n+ egrep 'debrebase new-upstream.*checkout'\n+ test 1 = 0\n+ t-report-failure\n+ set +x\nTEST FAILED\n-- snap --\n\nWhich makes me think that the reflog we produce in *some* code path that\noriginally called `git checkout` differs from the scripted rebase's\ngenerated reflog.\n\n> That said, Google has been running with the new rebase since ~1 month\n> ago when it became the default, with no issues reported by users.  As a\n> result, I am confident that it can cope with what most users of \"next\"\n> throw at it, which means that if we are to find more issues to polish it\n> better, it will need all the exposure it can get.\n\nRight. And there are a few weeks before the holidays, which should give me\ntime to fix whatever bugs are discovered (I only half mind being the only\none who fixes these bugs).\n\n> In the Google deployment, we will keep using rebase-in-c even if it\n> gets disabled by default, in order to help with that.\n> \n> From the Debian point of view, it's only a matter of time before\n> rebase-in-c becomes the default: even if it's not the default in 2.20,\n> it would presumably be so in 2.21 or 2.22.  That means the community's\n> attention when resolving security and reliability bugs would be on the\n> rebase-in-c implementation.  As a result, the Debian package will most\n> likely enable rebase-in-c by default even if upstream disables it, in\n> order to increase the package's shelf life (i.e. to ease the\n> maintenance burden of supporting whichever version of the package ends\n> up in the next Debian stable).\n> \n> So with either hat on, it doesn't matter whether you apply this patch\n> upstream.\n> \n> Having two pretty different deployments end up with the same\n> conclusion leads me to suspect that it's best for upstream not to\n> apply the revert patch, unless either\n> \n>   (a) we have a concrete regression to address and then try again, or\n>   (b) we have a test or other plan to follow before trying again.\n\nIn this instance, I am more a fan of the \"let's move fast and break\nthings, then move even faster fixing them\" approach.\n\nBesides, the bug that Ævar discovered was a bug already in the scripted\nrebase, but hidden by yet another bug (the missing error checking).\n\nI get the pretty firm impression that the common code paths are now pretty\nrobust, and only lesser-exercised features may expose a bug (or\nregression, as in the case of the reflogs, where one could argue that the\nexact reflog message is not something we promise not to fiddle with).\n\nCiao,\nDscho"},{"id":"364203","messageId":"nycvar.QRO.7.76.6.1811281026380.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"xmqq5zwhu9on.fsf@gitster-ct.c.googlers.com","subject":"Re: [ANNOUNCE] Git v2.20.0-rc1","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-28T09:30:24Z","receivedAt":"2018-11-28T09:30:32Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 28 Nov 2018, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > ...\n> > In short, even a thorough study of the code (keeping in mind the few\n> > tidbits of information provided by you) leaves me really wondering which\n> > code you run, because it sure does not look like current `master` to me.\n> >\n> > And if it is not `master`, then I have to ask why you keep suggesting to\n> > turn off the built-in rebase by default in `master`.\n> >\n> > Ciao,\n> > Johannes\n> >\n> > P.S.: Maybe you have a hook you forgot to mention?\n> \n> Any response?  Or can I retract jc/postpone-rebase-in-c that was\n> prepared as a reaction to this?\n\nI worked with Ævar via IRC and we figured out the root cause and I\nsubmitted https://public-inbox.org/git/pull.88.git.gitgitgadget@gmail.com/\nto fix it.\n\nGiven that this is a really obscure edge case (`git rebase --stat -v -i`\nonto an unrelated commit history, if you take away one of these, the bug\ndoes not trigger), and that it was only discovered to be a bug *because*\nof the built-in rebase (the scripted version had the same bug, but simply\nforgot to do proper error checking), I would not think that the reported\nbug is a strong argument in favor of turning off the built-in rebase by\ndefauly.\n\nIn other words, after understanding the bug I am even more confident than\nbefore that the built-in rebase is actually in a pretty good shape.\n\nI do not expect any major regressions, and if any happen: we do have that\nescape hatch for corner cases while I fix those bugs.\n\nCiao,\nDscho"},{"id":"364217","messageId":"87bm69z939.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811281015360.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-28T12:21:14Z","receivedAt":"2018-11-28T12:21:20Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 28 2018, Johannes Schindelin wrote:\n\n> Hi Jonathan,\n>\n> On Tue, 27 Nov 2018, Jonathan Nieder wrote:\n>\n>> At https://bugs.debian.org/914695 is a report of a test regression in\n>> an outside project that is very likely to have been triggered by the\n>> new faster rebase code.\n>\n> From looking through that log.gz (without having a clue where the test\n> code lives, so I cannot say what it is supposed to do, and also: this is\n> the first time I hear about dgit...), it would appear that this must be a\n> regression in the reflog messages produced by `git rebase`.\n>\n>> The issue has not been triaged, so I don't know yet whether it's a\n>> problem in rebase-in-c or a manifestation of a bug in the test.\n>\n> It ends thusly:\n>\n> -- snip --\n> [...]\n> + git reflog\n> + egrep 'debrebase new-upstream.*checkout'\n> + test 1 = 0\n> + t-report-failure\n> + set +x\n> TEST FAILED\n> -- snap --\n>\n> Which makes me think that the reflog we produce in *some* code path that\n> originally called `git checkout` differs from the scripted rebase's\n> generated reflog.\n>\n>> That said, Google has been running with the new rebase since ~1 month\n>> ago when it became the default, with no issues reported by users.  As a\n>> result, I am confident that it can cope with what most users of \"next\"\n>> throw at it, which means that if we are to find more issues to polish it\n>> better, it will need all the exposure it can get.\n>\n> Right. And there are a few weeks before the holidays, which should give me\n> time to fix whatever bugs are discovered (I only half mind being the only\n> one who fixes these bugs).\n>\n>> In the Google deployment, we will keep using rebase-in-c even if it\n>> gets disabled by default, in order to help with that.\n>>\n>> From the Debian point of view, it's only a matter of time before\n>> rebase-in-c becomes the default: even if it's not the default in 2.20,\n>> it would presumably be so in 2.21 or 2.22.  That means the community's\n>> attention when resolving security and reliability bugs would be on the\n>> rebase-in-c implementation.  As a result, the Debian package will most\n>> likely enable rebase-in-c by default even if upstream disables it, in\n>> order to increase the package's shelf life (i.e. to ease the\n>> maintenance burden of supporting whichever version of the package ends\n>> up in the next Debian stable).\n>>\n>> So with either hat on, it doesn't matter whether you apply this patch\n>> upstream.\n>>\n>> Having two pretty different deployments end up with the same\n>> conclusion leads me to suspect that it's best for upstream not to\n>> apply the revert patch, unless either\n>>\n>>   (a) we have a concrete regression to address and then try again, or\n>>   (b) we have a test or other plan to follow before trying again.\n>\n> In this instance, I am more a fan of the \"let's move fast and break\n> things, then move even faster fixing them\" approach.\n>\n> Besides, the bug that Ævar discovered was a bug already in the scripted\n> rebase, but hidden by yet another bug (the missing error checking).\n>\n> I get the pretty firm impression that the common code paths are now pretty\n> robust, and only lesser-exercised features may expose a bug (or\n> regression, as in the case of the reflogs, where one could argue that the\n> exact reflog message is not something we promise not to fiddle with).\n\nSince I raised this 'should we hold off?' I thought I'd chime in and say\nthat I'm fine with going along with what you suggest and having the\nbuiltin as the default in the final. IOW not merge\njc/postpone-rebase-in-c down.\n"},{"id":"364245","messageId":"20181128201852.9782-3-avarab@gmail.com","threadId":"49877","inReplyTo":"xmqqk1l32jo2.fsf@gitster-ct.c.googlers.com","subject":"[PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-28T20:18:52Z","receivedAt":"2018-11-28T20:24:20Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the semantics of the \"--range-diff\" option so that the regular\ndiff options can be provided separately for the range-diff and the\npatch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n\"format-patch\" to provide different context for the range-diff and the\npatch. This wasn't possible before.\n\nEver since the \"--range-diff\" option was added in\n31e2617a5f (\"format-patch: add --range-diff option to embed diff in\ncover letter\", 2018-07-22) the \"rev->diffopt\" we pass down to the diff\nmachinery has been the one we get from \"format-patch\"'s own\nsetup_revisions().\n\nThis sort of thing is unique among the log-like commands in\nbuiltin/log.c, no command than format-patch will embed the output of\nanother log-like command. Since the \"rev->diffopt\" is reused we need\nto munge it before we pass it to show_range_diff(). See\n43dafc4172 (\"format-patch: don't include --stat with --range-diff\noutput\", 2018-11-22) for a related regression fix which is being\nmostly reverted here.\n\nImplementation notes: 1) We're not bothering with the full teardown\naround die() and will leak memory, but it's too much boilerplate to do\nall the frees with/without the die() and not worth it. 2) We call\nrepo_init_revisions() for \"rd_rev\" even though we could get away with\na shallow copy like the code we're replacing (and which\nshow_range_diff() itself does). This is to make this code more easily\nunderstood.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-format-patch.txt | 10 ++++++-\n builtin/log.c                      | 42 +++++++++++++++++++++++-------\n t/t3206-range-diff.sh              | 41 +++++++++++++++++++++++++++++\n 3 files changed, 82 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex aba4c5febe..6c048f415f 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -24,7 +24,8 @@ SYNOPSIS\n \t\t   [--to=<email>] [--cc=<email>]\n \t\t   [--[no-]cover-letter] [--quiet] [--notes[=<ref>]]\n \t\t   [--interdiff=<previous>]\n-\t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n+\t\t   [--range-diff=<previous> [--creation-factor=<percent>]\n+\t\t      [--range-diff<common diff option>]]\n \t\t   [--progress]\n \t\t   [<common diff options>]\n \t\t   [ <since> | <revision range> ]\n@@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n \tfor details.\n \n+--range-diff<common diff option>::\n+\tOther options prefixed with `--range-diff` are stripped of\n+\tthat prefix and passed as-is to the diff machinery used to\n+\tgenerate the range-diff, e.g. `--range-diff-U0` and\n+\t`--range-diff--no-color`. This allows for adjusting the format\n+\tof the range-diff independently from the patch itself.\n+\n --notes[=<ref>]::\n \tAppend the notes (see linkgit:git-notes[1]) for the commit\n \tafter the three-dash line.\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 02d88fa233..7658e56ecc 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1023,7 +1023,8 @@ static void show_diffstat(struct rev_info *rev,\n \tfprintf(rev->diffopt.file, \"\\n\");\n }\n \n-static void make_cover_letter(struct rev_info *rev, int use_stdout,\n+static void make_cover_letter(struct rev_info *rev, struct rev_info *rd_rev,\n+\t\t\t      int use_stdout,\n \t\t\t      struct commit *origin,\n \t\t\t      int nr, struct commit **list,\n \t\t\t      const char *branch_name,\n@@ -1095,13 +1096,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \t}\n \n \tif (rev->rdiff1) {\n-\t\tstruct diff_options opts;\n-\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n-\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n-\n \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n-\t\t\t\trev->creation_factor, 1, &opts);\n+\t\t\t\trev->creation_factor, 1, &rd_rev->diffopt);\n \t}\n }\n \n@@ -1485,6 +1482,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \tstruct commit *commit;\n \tstruct commit **list = NULL;\n \tstruct rev_info rev;\n+\tstruct rev_info rd_rev;\n \tstruct setup_revision_opt s_r_opt;\n \tint nr = 0, total, i;\n \tint use_stdout = 0;\n@@ -1603,6 +1601,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \tinit_log_defaults();\n \tgit_config(git_format_config, NULL);\n \trepo_init_revisions(the_repository, &rev, prefix);\n+\trepo_init_revisions(the_repository, &rd_rev, prefix);\n \trev.commit_format = CMIT_FMT_EMAIL;\n \trev.expand_tabs_in_log_default = 0;\n \trev.verbose_header = 1;\n@@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \trev.preserve_subject = keep_subject;\n \n \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n-\tif (argc > 1)\n-\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n+\tif (argc > 1) {\n+\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n+\t\tconst char *prefix = \"--range-diff\";\n+\t\tint have_prefix = 0;\n+\n+\t\tfor (i = 0; i < argc; i++) {\n+\t\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\t\tchar *str;\n+\n+\t\t\tstrbuf_addstr(&sb, argv[i]);\n+\t\t\tif (starts_with(argv[i], prefix)) {\n+\t\t\t\thave_prefix = 1;\n+\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n+\t\t\t}\n+\t\t\tstr = strbuf_detach(&sb, NULL);\n+\t\t\tstrbuf_release(&sb);\n+\n+\t\t\targv_array_push(&args, str);\n+\t\t}\n+\n+\t\tif (!have_prefix)\n+\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n+\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n+\t\tif (argc > 1)\n+\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n+\t}\n \n \tif (rev.diffopt.output_format & DIFF_FORMAT_NAME)\n \t\tdie(_(\"--name-only does not make sense\"));\n@@ -1702,7 +1725,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \tif (!use_patch_format &&\n \t\t(!rev.diffopt.output_format ||\n \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n-\t\t/* Needs to be mirrored in show_range_diff() invocation */\n \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n \tif (!rev.diffopt.stat_width)\n \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\n@@ -1877,7 +1899,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \tif (cover_letter) {\n \t\tif (thread)\n \t\t\tgen_message_id(&rev, \"cover\");\n-\t\tmake_cover_letter(&rev, use_stdout,\n+\t\tmake_cover_letter(&rev, &rd_rev, use_stdout,\n \t\t\t\t  origin, nr, list, branch_name, quiet);\n \t\tprint_bases(&bases, rev.diffopt.file);\n \t\tprint_signature(rev.diffopt.file);\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex bc5facc1cd..6916103888 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -308,6 +308,35 @@ test_expect_success 'format-patch with <common diff option>' '\n \t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n \tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n \tsed -e \"s|:$||\" >expect <<-\\EOF &&\n+\t1:  a63e992 ! 1:  d966c5c s/12/B/\n+\t    @@ -8,7 +8,7 @@\n+\t     @@\n+\t      9\n+\t      10\n+\t    - B\n+\t    + BB\n+\t     -12\n+\t     +B\n+\t      13\n+\t-- :\n+\tEOF\n+\ttest_cmp expect actual.range-diff &&\n+\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n+\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n+\t--- a/file\n+\t+++ b/file\n+\t@@ -12 +12 @@ BB\n+\t-12\n+\t+B\n+\t-- :\n+\tEOF\n+\ttest_cmp expect actual.diff &&\n+\n+\t# -U0 & --range-diff-U0\n+\tgit format-patch --cover-letter --stdout -U0 --range-diff-U0 \\\n+\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n+\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n+\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n \t1:  a63e992 ! 1:  d966c5c s/12/B/\n \t    @@ -11 +11 @@\n \t    - B\n@@ -327,4 +356,16 @@ test_expect_success 'format-patch with <common diff option>' '\n \ttest_cmp expect actual.diff\n '\n \n+test_expect_success 'format-patch option parsing with --range-diff-*' '\n+\ttest_must_fail git format-patch --stdout --unknown \\\n+\t\tmaster..unmodified 2>stderr &&\n+\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr &&\n+\ttest_must_fail git format-patch --stdout --range-diff-unknown \\\n+\t\tmaster..unmodified 2>stderr &&\n+\ttest_i18ngrep \"unrecognized argument: --range-diff-unknown\" stderr &&\n+\ttest_must_fail git format-patch --stdout --unknown --range-diff-unknown \\\n+\t\tmaster..unmodified 2>stderr &&\n+\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr\n+'\n+\n test_done\n-- \n2.20.0.rc1.387.gf8505762e3\n\n"},{"id":"364246","messageId":"20181128201852.9782-1-avarab@gmail.com","threadId":"49877","inReplyTo":"xmqqk1l32jo2.fsf@gitster-ct.c.googlers.com","subject":"[PATCH 0/2] format-patch: fix root cause of recent regression","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-28T20:18:50Z","receivedAt":"2018-11-28T20:24:46Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"As noted in 2/2 this fixes the root cause of the bug I plastered over\nin\nhttps://public-inbox.org/git/20181122211248.24546-3-avarab@gmail.com/\n(that patch is sitting in 'next').\n\n1/2 is a test for existing behavior, to make it more easily understood\nwhat's being changed.\n\nJunio: I know it's late, but unless Eric has objections to this UI\nchange I'd really like to have this in 2.20 since this is a change to\na new command-line UI that's newly added in 2.20.\n\nAs noted in 2/2 the current implementation is inherently limited, you\ncan't tweak diff options for the range-diff in the cover-letter and\nthe patch independently, now you can, and the implementation is much\nless nasty now that we're not having to share diffopts across two\ndifferent modes of operation.\n\nÆvar Arnfjörð Bjarmason (2):\n  format-patch: add test for --range-diff diff output\n  format-patch: allow for independent diff & range-diff options\n\n Documentation/git-format-patch.txt |  10 ++-\n builtin/log.c                      |  42 +++++++++---\n t/t3206-range-diff.sh              | 101 +++++++++++++++++++++++++++++\n 3 files changed, 142 insertions(+), 11 deletions(-)\n\n-- \n2.20.0.rc1.387.gf8505762e3\n\n"},{"id":"364247","messageId":"20181128201852.9782-2-avarab@gmail.com","threadId":"49877","inReplyTo":"xmqqk1l32jo2.fsf@gitster-ct.c.googlers.com","subject":"[PATCH 1/2] format-patch: add test for --range-diff diff output","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-28T20:18:51Z","receivedAt":"2018-11-28T20:25:37Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"As noted in 43dafc4172 (\"format-patch: don't include --stat with\n--range-diff output\", 2018-11-22) the diff options provided on the\ncommand-line currently affect both the range-diff and the patch\noutput, but there was no test for checking this with output where we'd\nshow a patch diff. Let's add one.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t3206-range-diff.sh | 60 +++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 60 insertions(+)\n\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex 90def330bd..bc5facc1cd 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -267,4 +267,64 @@ test_expect_success 'format-patch --range-diff as commentary' '\n \ttest_i18ngrep \"^Range-diff:$\" actual\n '\n \n+test_expect_success 'format-patch with <common diff option>' '\n+\t# No diff options\n+\tgit format-patch --cover-letter --stdout --range-diff=topic~..topic \\\n+\t\tchanged~..changed >actual.raw &&\n+\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n+\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n+\t1:  a63e992 ! 1:  d966c5c s/12/B/\n+\t    @@ -8,7 +8,7 @@\n+\t     @@\n+\t      9\n+\t      10\n+\t    - B\n+\t    + BB\n+\t     -12\n+\t     +B\n+\t      13\n+\t-- :\n+\tEOF\n+\ttest_cmp expect actual.range-diff &&\n+\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n+\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n+\t--- a/file\n+\t+++ b/file\n+\t@@ -9,7 +9,7 @@ A\n+\t 9\n+\t 10\n+\t BB\n+\t-12\n+\t+B\n+\t 13\n+\t 14\n+\t 15\n+\t-- :\n+\tEOF\n+\ttest_cmp expect actual.diff &&\n+\n+\t# -U0\n+\tgit format-patch --cover-letter --stdout -U0 \\\n+\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n+\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n+\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n+\t1:  a63e992 ! 1:  d966c5c s/12/B/\n+\t    @@ -11 +11 @@\n+\t    - B\n+\t    + BB\n+\t-- :\n+\tEOF\n+\ttest_cmp expect actual.range-diff &&\n+\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n+\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n+\t--- a/file\n+\t+++ b/file\n+\t@@ -12 +12 @@ BB\n+\t-12\n+\t+B\n+\t-- :\n+\tEOF\n+\ttest_cmp expect actual.diff\n+'\n+\n test_done\n-- \n2.20.0.rc1.387.gf8505762e3\n\n"},{"id":"364281","messageId":"xmqq8t1cr3l2.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"20181128201852.9782-3-avarab@gmail.com","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-29T02:59:37Z","receivedAt":"2018-11-29T02:59:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> +\t\t      [--range-diff<common diff option>]]\n\nLet's make sure a random string thrown at this mechanism will\nproperly get noticed and diagnosed.\n\n> @@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n>  \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n>  \tfor details.\n>  \n> +--range-diff<common diff option>::\n> +\tOther options prefixed with `--range-diff` are stripped of\n> +\tthat prefix and passed as-is to the diff machinery used to\n> +\tgenerate the range-diff, e.g. `--range-diff-U0` and\n> +\t`--range-diff--no-color`. This allows for adjusting the format\n> +\tof the range-diff independently from the patch itself.\n\nTaking anything is of course the most general, but I am afraid if\nthis backfires if there are some options that do not make sense to\nbe different between the invocations of range-diff and format-patch.\n\n> @@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>  \trev.preserve_subject = keep_subject;\n>  \n>  \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n> -\tif (argc > 1)\n> -\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> +\tif (argc > 1) {\n> +\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n> +\t\tconst char *prefix = \"--range-diff\";\n\nPlease call that anything but \"prefix\" that hides the parameter to\nthe function.  \n\n\tconst char *range_diff_opt = \"--range-diff\";\n\nmight work OK, or it might not.  Let's read on.\n\n> +\t\tint have_prefix = 0;\n> +\n> +\t\tfor (i = 0; i < argc; i++) {\n> +\t\t\tstruct strbuf sb = STRBUF_INIT;\n> +\t\t\tchar *str;\n> +\n> +\t\t\tstrbuf_addstr(&sb, argv[i]);\n> +\t\t\tif (starts_with(argv[i], prefix)) {\n> +\t\t\t\thave_prefix = 1;\n> +\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n> +\t\t\t}\n> +\t\t\tstr = strbuf_detach(&sb, NULL);\n> +\t\t\tstrbuf_release(&sb);\n> +\n> +\t\t\targv_array_push(&args, str);\n> +\t\t}\n> +\n\nIs the body of the loop essentially this?\n\n\t\t\tchar *passopt = argv[i];\n\t\t\tif (!skip_prefix(passopt, range_diff_opt, &passopt))\n\t\t\t\tsaw_range_diff_opt = 1;\n\t\t\targv_array_push(&args, xstrdup(passopt));\n\nWe only use that \"prefix\" thing once, so we may not even need the\nvariable.\n\n> +\t\tif (!have_prefix)\n> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n\nSo we take normal options and check the leftover args; if there is\nno --range-diff<whatever> among the leftover bits, we pretend that\nwe stumbled while reading the first such leftover arg.\n\n> +\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n> +\t\tif (argc > 1)\n> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> +\t}\n\nOtherwise, we pass all the leftover bits, which is a random mixture\nbut guaranteed to have at least one meant for range-diff, to another\nsetup_revisions().  If it leaves a leftover arg, then that is\ndiagnosed here, so we'd be OK (iow, this is not a new \"attack\nvector\" to inject random string to command line parser).\n\nOne minor glitch I can see is \"format-patch --range-diffSilly\" would\nreport \"unrecognised arg: Silly\".  As we are pretending to be and\nreporting errors as format-patch, it would be better if we report\nthat --range-diffSilly was what we did not understand.\n\n> Junio: I know it's late, but unless Eric has objections to this UI\n> change I'd really like to have this in 2.20 since this is a change to\n> a new command-line UI that's newly added in 2.20.\n\nQuite honestly, I'd rather document \"driving range-diff from\nformat-patch is experimental and does silly things when given\nnon-standard options in this release\" and not touch the code at this\nlate stage in the game.  Would it be less intrusive a change to\n*not* support the --range-diff<whatever> option, still use rd_rev\nthat is separate from the main rev, and use a reasonable hardcoded\ndefault settings when preparing rd_rev?\n\n\n"},{"id":"364283","messageId":"xmqq4lc0qy2m.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"87bm69z939.fsf@evledraar.gmail.com","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-29T04:58:41Z","receivedAt":"2018-11-29T04:58:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> Since I raised this 'should we hold off?' I thought I'd chime in and say\n> that I'm fine with going along with what you suggest and having the\n> builtin as the default in the final. IOW not merge\n> jc/postpone-rebase-in-c down.\n\nOK.\n"},{"id":"364299","messageId":"nycvar.QRO.7.76.6.1811291103190.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"20181128201852.9782-3-avarab@gmail.com","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-29T10:07:58Z","receivedAt":"2018-11-29T10:08:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Wed, 28 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n\n> Change the semantics of the \"--range-diff\" option so that the regular\n> diff options can be provided separately for the range-diff and the\n> patch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n> \"format-patch\" to provide different context for the range-diff and the\n> patch. This wasn't possible before.\n\nI really, really dislike the `--range-diff-<random-thing>`. We have\nprecedent for passing optional arguments that are passed to some other\ncommand, so a much more logical and consistent convention would be to use\n`--range-diff[=<diff-option>..]`, allowing all of the diff options that\nyou might want to pass to the outer diff in one go rather than having a\nlengthy string of `--range-diff-this` and `--range-diff-that` options.\n\nI only had time to skim the patch, and I have to wonder why you pass\naround full-blown `rev_info` structs for range diff (and with that really\nawful name `rd_rev`) rather than just the `diff_options` that you\n*actually* care about?\n\nCiao,\nDscho\n\n> \n> Ever since the \"--range-diff\" option was added in\n> 31e2617a5f (\"format-patch: add --range-diff option to embed diff in\n> cover letter\", 2018-07-22) the \"rev->diffopt\" we pass down to the diff\n> machinery has been the one we get from \"format-patch\"'s own\n> setup_revisions().\n> \n> This sort of thing is unique among the log-like commands in\n> builtin/log.c, no command than format-patch will embed the output of\n> another log-like command. Since the \"rev->diffopt\" is reused we need\n> to munge it before we pass it to show_range_diff(). See\n> 43dafc4172 (\"format-patch: don't include --stat with --range-diff\n> output\", 2018-11-22) for a related regression fix which is being\n> mostly reverted here.\n> \n> Implementation notes: 1) We're not bothering with the full teardown\n> around die() and will leak memory, but it's too much boilerplate to do\n> all the frees with/without the die() and not worth it. 2) We call\n> repo_init_revisions() for \"rd_rev\" even though we could get away with\n> a shallow copy like the code we're replacing (and which\n> show_range_diff() itself does). This is to make this code more easily\n> understood.\n> \n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  Documentation/git-format-patch.txt | 10 ++++++-\n>  builtin/log.c                      | 42 +++++++++++++++++++++++-------\n>  t/t3206-range-diff.sh              | 41 +++++++++++++++++++++++++++++\n>  3 files changed, 82 insertions(+), 11 deletions(-)\n> \n> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n> index aba4c5febe..6c048f415f 100644\n> --- a/Documentation/git-format-patch.txt\n> +++ b/Documentation/git-format-patch.txt\n> @@ -24,7 +24,8 @@ SYNOPSIS\n>  \t\t   [--to=<email>] [--cc=<email>]\n>  \t\t   [--[no-]cover-letter] [--quiet] [--notes[=<ref>]]\n>  \t\t   [--interdiff=<previous>]\n> -\t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n> +\t\t   [--range-diff=<previous> [--creation-factor=<percent>]\n> +\t\t      [--range-diff<common diff option>]]\n>  \t\t   [--progress]\n>  \t\t   [<common diff options>]\n>  \t\t   [ <since> | <revision range> ]\n> @@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n>  \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n>  \tfor details.\n>  \n> +--range-diff<common diff option>::\n> +\tOther options prefixed with `--range-diff` are stripped of\n> +\tthat prefix and passed as-is to the diff machinery used to\n> +\tgenerate the range-diff, e.g. `--range-diff-U0` and\n> +\t`--range-diff--no-color`. This allows for adjusting the format\n> +\tof the range-diff independently from the patch itself.\n> +\n>  --notes[=<ref>]::\n>  \tAppend the notes (see linkgit:git-notes[1]) for the commit\n>  \tafter the three-dash line.\n> diff --git a/builtin/log.c b/builtin/log.c\n> index 02d88fa233..7658e56ecc 100644\n> --- a/builtin/log.c\n> +++ b/builtin/log.c\n> @@ -1023,7 +1023,8 @@ static void show_diffstat(struct rev_info *rev,\n>  \tfprintf(rev->diffopt.file, \"\\n\");\n>  }\n>  \n> -static void make_cover_letter(struct rev_info *rev, int use_stdout,\n> +static void make_cover_letter(struct rev_info *rev, struct rev_info *rd_rev,\n> +\t\t\t      int use_stdout,\n>  \t\t\t      struct commit *origin,\n>  \t\t\t      int nr, struct commit **list,\n>  \t\t\t      const char *branch_name,\n> @@ -1095,13 +1096,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>  \t}\n>  \n>  \tif (rev->rdiff1) {\n> -\t\tstruct diff_options opts;\n> -\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n> -\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n> -\n>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n> -\t\t\t\trev->creation_factor, 1, &opts);\n> +\t\t\t\trev->creation_factor, 1, &rd_rev->diffopt);\n>  \t}\n>  }\n>  \n> @@ -1485,6 +1482,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>  \tstruct commit *commit;\n>  \tstruct commit **list = NULL;\n>  \tstruct rev_info rev;\n> +\tstruct rev_info rd_rev;\n>  \tstruct setup_revision_opt s_r_opt;\n>  \tint nr = 0, total, i;\n>  \tint use_stdout = 0;\n> @@ -1603,6 +1601,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>  \tinit_log_defaults();\n>  \tgit_config(git_format_config, NULL);\n>  \trepo_init_revisions(the_repository, &rev, prefix);\n> +\trepo_init_revisions(the_repository, &rd_rev, prefix);\n>  \trev.commit_format = CMIT_FMT_EMAIL;\n>  \trev.expand_tabs_in_log_default = 0;\n>  \trev.verbose_header = 1;\n> @@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>  \trev.preserve_subject = keep_subject;\n>  \n>  \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n> -\tif (argc > 1)\n> -\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> +\tif (argc > 1) {\n> +\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n> +\t\tconst char *prefix = \"--range-diff\";\n> +\t\tint have_prefix = 0;\n> +\n> +\t\tfor (i = 0; i < argc; i++) {\n> +\t\t\tstruct strbuf sb = STRBUF_INIT;\n> +\t\t\tchar *str;\n> +\n> +\t\t\tstrbuf_addstr(&sb, argv[i]);\n> +\t\t\tif (starts_with(argv[i], prefix)) {\n> +\t\t\t\thave_prefix = 1;\n> +\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n> +\t\t\t}\n> +\t\t\tstr = strbuf_detach(&sb, NULL);\n> +\t\t\tstrbuf_release(&sb);\n> +\n> +\t\t\targv_array_push(&args, str);\n> +\t\t}\n> +\n> +\t\tif (!have_prefix)\n> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> +\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n> +\t\tif (argc > 1)\n> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> +\t}\n>  \n>  \tif (rev.diffopt.output_format & DIFF_FORMAT_NAME)\n>  \t\tdie(_(\"--name-only does not make sense\"));\n> @@ -1702,7 +1725,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>  \tif (!use_patch_format &&\n>  \t\t(!rev.diffopt.output_format ||\n>  \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n> -\t\t/* Needs to be mirrored in show_range_diff() invocation */\n>  \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n>  \tif (!rev.diffopt.stat_width)\n>  \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\n> @@ -1877,7 +1899,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>  \tif (cover_letter) {\n>  \t\tif (thread)\n>  \t\t\tgen_message_id(&rev, \"cover\");\n> -\t\tmake_cover_letter(&rev, use_stdout,\n> +\t\tmake_cover_letter(&rev, &rd_rev, use_stdout,\n>  \t\t\t\t  origin, nr, list, branch_name, quiet);\n>  \t\tprint_bases(&bases, rev.diffopt.file);\n>  \t\tprint_signature(rev.diffopt.file);\n> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n> index bc5facc1cd..6916103888 100755\n> --- a/t/t3206-range-diff.sh\n> +++ b/t/t3206-range-diff.sh\n> @@ -308,6 +308,35 @@ test_expect_success 'format-patch with <common diff option>' '\n>  \t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n>  \tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n>  \tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> +\t1:  a63e992 ! 1:  d966c5c s/12/B/\n> +\t    @@ -8,7 +8,7 @@\n> +\t     @@\n> +\t      9\n> +\t      10\n> +\t    - B\n> +\t    + BB\n> +\t     -12\n> +\t     +B\n> +\t      13\n> +\t-- :\n> +\tEOF\n> +\ttest_cmp expect actual.range-diff &&\n> +\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> +\t--- a/file\n> +\t+++ b/file\n> +\t@@ -12 +12 @@ BB\n> +\t-12\n> +\t+B\n> +\t-- :\n> +\tEOF\n> +\ttest_cmp expect actual.diff &&\n> +\n> +\t# -U0 & --range-diff-U0\n> +\tgit format-patch --cover-letter --stdout -U0 --range-diff-U0 \\\n> +\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n> +\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>  \t1:  a63e992 ! 1:  d966c5c s/12/B/\n>  \t    @@ -11 +11 @@\n>  \t    - B\n> @@ -327,4 +356,16 @@ test_expect_success 'format-patch with <common diff option>' '\n>  \ttest_cmp expect actual.diff\n>  '\n>  \n> +test_expect_success 'format-patch option parsing with --range-diff-*' '\n> +\ttest_must_fail git format-patch --stdout --unknown \\\n> +\t\tmaster..unmodified 2>stderr &&\n> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr &&\n> +\ttest_must_fail git format-patch --stdout --range-diff-unknown \\\n> +\t\tmaster..unmodified 2>stderr &&\n> +\ttest_i18ngrep \"unrecognized argument: --range-diff-unknown\" stderr &&\n> +\ttest_must_fail git format-patch --stdout --unknown --range-diff-unknown \\\n> +\t\tmaster..unmodified 2>stderr &&\n> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr\n> +'\n> +\n>  test_done\n> -- \n> 2.20.0.rc1.387.gf8505762e3\n> \n> "},{"id":"364302","messageId":"8736rkyy4h.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811291103190.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-29T10:30:22Z","receivedAt":"2018-11-29T10:30:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Nov 29 2018, Johannes Schindelin wrote:\n\n> Hi Ævar,\n>\n> On Wed, 28 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n>\n>> Change the semantics of the \"--range-diff\" option so that the regular\n>> diff options can be provided separately for the range-diff and the\n>> patch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n>> \"format-patch\" to provide different context for the range-diff and the\n>> patch. This wasn't possible before.\n>\n> I really, really dislike the `--range-diff-<random-thing>`. We have\n> precedent for passing optional arguments that are passed to some other\n> command, so a much more logical and consistent convention would be to use\n> `--range-diff[=<diff-option>..]`, allowing all of the diff options that\n> you might want to pass to the outer diff in one go rather than having a\n> lengthy string of `--range-diff-this` and `--range-diff-that` options.\n\nWhere do we pass those sorts of arguments?\n\nReasons I did it this way:\n\n a) Passing it as one option will require the user to double-quote those\n    options that take quoted arguments (e.g. --word-diff-regex), which I\n    thought sucked more than the prefix. On the implementation side we\n    couldn't leave the parsing of the command-line to the shell anymore.\n\n b) I think people will want to tweak this very rarely, much more rarely\n    than e.g. -U10 in format-patch itself, so having something long-ish\n    doesn't sound bad.\n\n> I only had time to skim the patch, and I have to wonder why you pass\n> around full-blown `rev_info` structs for range diff (and with that really\n> awful name `rd_rev`) rather than just the `diff_options` that you\n> *actually* care about?\n\nBecause setup_revisions() which does all the command-line parsing needs\na rev_info, so even if we only need the diffopt in the end we need to\ninitiate the whole thing.\n\nSuggestions for a better varibale name most welcome.\n\n> Ciao,\n> Dscho\n>\n>>\n>> Ever since the \"--range-diff\" option was added in\n>> 31e2617a5f (\"format-patch: add --range-diff option to embed diff in\n>> cover letter\", 2018-07-22) the \"rev->diffopt\" we pass down to the diff\n>> machinery has been the one we get from \"format-patch\"'s own\n>> setup_revisions().\n>>\n>> This sort of thing is unique among the log-like commands in\n>> builtin/log.c, no command than format-patch will embed the output of\n>> another log-like command. Since the \"rev->diffopt\" is reused we need\n>> to munge it before we pass it to show_range_diff(). See\n>> 43dafc4172 (\"format-patch: don't include --stat with --range-diff\n>> output\", 2018-11-22) for a related regression fix which is being\n>> mostly reverted here.\n>>\n>> Implementation notes: 1) We're not bothering with the full teardown\n>> around die() and will leak memory, but it's too much boilerplate to do\n>> all the frees with/without the die() and not worth it. 2) We call\n>> repo_init_revisions() for \"rd_rev\" even though we could get away with\n>> a shallow copy like the code we're replacing (and which\n>> show_range_diff() itself does). This is to make this code more easily\n>> understood.\n>>\n>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> ---\n>>  Documentation/git-format-patch.txt | 10 ++++++-\n>>  builtin/log.c                      | 42 +++++++++++++++++++++++-------\n>>  t/t3206-range-diff.sh              | 41 +++++++++++++++++++++++++++++\n>>  3 files changed, 82 insertions(+), 11 deletions(-)\n>>\n>> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n>> index aba4c5febe..6c048f415f 100644\n>> --- a/Documentation/git-format-patch.txt\n>> +++ b/Documentation/git-format-patch.txt\n>> @@ -24,7 +24,8 @@ SYNOPSIS\n>>  \t\t   [--to=<email>] [--cc=<email>]\n>>  \t\t   [--[no-]cover-letter] [--quiet] [--notes[=<ref>]]\n>>  \t\t   [--interdiff=<previous>]\n>> -\t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n>> +\t\t   [--range-diff=<previous> [--creation-factor=<percent>]\n>> +\t\t      [--range-diff<common diff option>]]\n>>  \t\t   [--progress]\n>>  \t\t   [<common diff options>]\n>>  \t\t   [ <since> | <revision range> ]\n>> @@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n>>  \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n>>  \tfor details.\n>>\n>> +--range-diff<common diff option>::\n>> +\tOther options prefixed with `--range-diff` are stripped of\n>> +\tthat prefix and passed as-is to the diff machinery used to\n>> +\tgenerate the range-diff, e.g. `--range-diff-U0` and\n>> +\t`--range-diff--no-color`. This allows for adjusting the format\n>> +\tof the range-diff independently from the patch itself.\n>> +\n>>  --notes[=<ref>]::\n>>  \tAppend the notes (see linkgit:git-notes[1]) for the commit\n>>  \tafter the three-dash line.\n>> diff --git a/builtin/log.c b/builtin/log.c\n>> index 02d88fa233..7658e56ecc 100644\n>> --- a/builtin/log.c\n>> +++ b/builtin/log.c\n>> @@ -1023,7 +1023,8 @@ static void show_diffstat(struct rev_info *rev,\n>>  \tfprintf(rev->diffopt.file, \"\\n\");\n>>  }\n>>\n>> -static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>> +static void make_cover_letter(struct rev_info *rev, struct rev_info *rd_rev,\n>> +\t\t\t      int use_stdout,\n>>  \t\t\t      struct commit *origin,\n>>  \t\t\t      int nr, struct commit **list,\n>>  \t\t\t      const char *branch_name,\n>> @@ -1095,13 +1096,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>>  \t}\n>>\n>>  \tif (rev->rdiff1) {\n>> -\t\tstruct diff_options opts;\n>> -\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n>> -\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n>> -\n>>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n>>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n>> -\t\t\t\trev->creation_factor, 1, &opts);\n>> +\t\t\t\trev->creation_factor, 1, &rd_rev->diffopt);\n>>  \t}\n>>  }\n>>\n>> @@ -1485,6 +1482,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>>  \tstruct commit *commit;\n>>  \tstruct commit **list = NULL;\n>>  \tstruct rev_info rev;\n>> +\tstruct rev_info rd_rev;\n>>  \tstruct setup_revision_opt s_r_opt;\n>>  \tint nr = 0, total, i;\n>>  \tint use_stdout = 0;\n>> @@ -1603,6 +1601,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>>  \tinit_log_defaults();\n>>  \tgit_config(git_format_config, NULL);\n>>  \trepo_init_revisions(the_repository, &rev, prefix);\n>> +\trepo_init_revisions(the_repository, &rd_rev, prefix);\n>>  \trev.commit_format = CMIT_FMT_EMAIL;\n>>  \trev.expand_tabs_in_log_default = 0;\n>>  \trev.verbose_header = 1;\n>> @@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>>  \trev.preserve_subject = keep_subject;\n>>\n>>  \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n>> -\tif (argc > 1)\n>> -\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> +\tif (argc > 1) {\n>> +\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n>> +\t\tconst char *prefix = \"--range-diff\";\n>> +\t\tint have_prefix = 0;\n>> +\n>> +\t\tfor (i = 0; i < argc; i++) {\n>> +\t\t\tstruct strbuf sb = STRBUF_INIT;\n>> +\t\t\tchar *str;\n>> +\n>> +\t\t\tstrbuf_addstr(&sb, argv[i]);\n>> +\t\t\tif (starts_with(argv[i], prefix)) {\n>> +\t\t\t\thave_prefix = 1;\n>> +\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n>> +\t\t\t}\n>> +\t\t\tstr = strbuf_detach(&sb, NULL);\n>> +\t\t\tstrbuf_release(&sb);\n>> +\n>> +\t\t\targv_array_push(&args, str);\n>> +\t\t}\n>> +\n>> +\t\tif (!have_prefix)\n>> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> +\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n>> +\t\tif (argc > 1)\n>> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> +\t}\n>>\n>>  \tif (rev.diffopt.output_format & DIFF_FORMAT_NAME)\n>>  \t\tdie(_(\"--name-only does not make sense\"));\n>> @@ -1702,7 +1725,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>>  \tif (!use_patch_format &&\n>>  \t\t(!rev.diffopt.output_format ||\n>>  \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n>> -\t\t/* Needs to be mirrored in show_range_diff() invocation */\n>>  \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n>>  \tif (!rev.diffopt.stat_width)\n>>  \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\n>> @@ -1877,7 +1899,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>>  \tif (cover_letter) {\n>>  \t\tif (thread)\n>>  \t\t\tgen_message_id(&rev, \"cover\");\n>> -\t\tmake_cover_letter(&rev, use_stdout,\n>> +\t\tmake_cover_letter(&rev, &rd_rev, use_stdout,\n>>  \t\t\t\t  origin, nr, list, branch_name, quiet);\n>>  \t\tprint_bases(&bases, rev.diffopt.file);\n>>  \t\tprint_signature(rev.diffopt.file);\n>> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n>> index bc5facc1cd..6916103888 100755\n>> --- a/t/t3206-range-diff.sh\n>> +++ b/t/t3206-range-diff.sh\n>> @@ -308,6 +308,35 @@ test_expect_success 'format-patch with <common diff option>' '\n>>  \t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n>>  \tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n>>  \tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> +\t1:  a63e992 ! 1:  d966c5c s/12/B/\n>> +\t    @@ -8,7 +8,7 @@\n>> +\t     @@\n>> +\t      9\n>> +\t      10\n>> +\t    - B\n>> +\t    + BB\n>> +\t     -12\n>> +\t     +B\n>> +\t      13\n>> +\t-- :\n>> +\tEOF\n>> +\ttest_cmp expect actual.range-diff &&\n>> +\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n>> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> +\t--- a/file\n>> +\t+++ b/file\n>> +\t@@ -12 +12 @@ BB\n>> +\t-12\n>> +\t+B\n>> +\t-- :\n>> +\tEOF\n>> +\ttest_cmp expect actual.diff &&\n>> +\n>> +\t# -U0 & --range-diff-U0\n>> +\tgit format-patch --cover-letter --stdout -U0 --range-diff-U0 \\\n>> +\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n>> +\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n>> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>>  \t1:  a63e992 ! 1:  d966c5c s/12/B/\n>>  \t    @@ -11 +11 @@\n>>  \t    - B\n>> @@ -327,4 +356,16 @@ test_expect_success 'format-patch with <common diff option>' '\n>>  \ttest_cmp expect actual.diff\n>>  '\n>>\n>> +test_expect_success 'format-patch option parsing with --range-diff-*' '\n>> +\ttest_must_fail git format-patch --stdout --unknown \\\n>> +\t\tmaster..unmodified 2>stderr &&\n>> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr &&\n>> +\ttest_must_fail git format-patch --stdout --range-diff-unknown \\\n>> +\t\tmaster..unmodified 2>stderr &&\n>> +\ttest_i18ngrep \"unrecognized argument: --range-diff-unknown\" stderr &&\n>> +\ttest_must_fail git format-patch --stdout --unknown --range-diff-unknown \\\n>> +\t\tmaster..unmodified 2>stderr &&\n>> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr\n>> +'\n>> +\n>>  test_done\n>> --\n>> 2.20.0.rc1.387.gf8505762e3\n>>\n>>\n"},{"id":"364307","messageId":"nycvar.QRO.7.76.6.1811291307070.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"8736rkyy4h.fsf@evledraar.gmail.com","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-29T12:12:02Z","receivedAt":"2018-11-29T12:12:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n\n> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n> \n> > On Wed, 28 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n> >\n> >> Change the semantics of the \"--range-diff\" option so that the regular\n> >> diff options can be provided separately for the range-diff and the\n> >> patch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n> >> \"format-patch\" to provide different context for the range-diff and the\n> >> patch. This wasn't possible before.\n> >\n> > I really, really dislike the `--range-diff-<random-thing>`. We have\n> > precedent for passing optional arguments that are passed to some other\n> > command, so a much more logical and consistent convention would be to use\n> > `--range-diff[=<diff-option>..]`, allowing all of the diff options that\n> > you might want to pass to the outer diff in one go rather than having a\n> > lengthy string of `--range-diff-this` and `--range-diff-that` options.\n> \n> Where do we pass those sorts of arguments?\n> \n> Reasons I did it this way:\n> \n>  a) Passing it as one option will require the user to double-quote those\n>     options that take quoted arguments (e.g. --word-diff-regex), which I\n>     thought sucked more than the prefix. On the implementation side we\n>     couldn't leave the parsing of the command-line to the shell anymore.\n> \n>  b) I think people will want to tweak this very rarely, much more rarely\n>     than e.g. -U10 in format-patch itself, so having something long-ish\n>     doesn't sound bad.\n\nHmm. I still don't like it. It sets a precedent, and we simply do not do\nit that way in other circumstances (most obvious would be the -X merge\noptions). The more divergent user interfaces for the same sort of thing\nare, the more brain cycles you force users to spend on navigating said\ninterfaces.\n\n> > I only had time to skim the patch, and I have to wonder why you pass\n> > around full-blown `rev_info` structs for range diff (and with that really\n> > awful name `rd_rev`) rather than just the `diff_options` that you\n> > *actually* care about?\n> \n> Because setup_revisions() which does all the command-line parsing needs\n> a rev_info, so even if we only need the diffopt in the end we need to\n> initiate the whole thing.\n> \n> Suggestions for a better varibale name most welcome.\n\n`range_diff_revs`\n\nAnd you do not need to pass around the whole thing. You can easily pass\n`&range_diff_revs.diffopt`.\n\nDon't pass around what you do not need to pass around.\n\nCiao,\nDscho\n\n> \n> > Ciao,\n> > Dscho\n> >\n> >>\n> >> Ever since the \"--range-diff\" option was added in\n> >> 31e2617a5f (\"format-patch: add --range-diff option to embed diff in\n> >> cover letter\", 2018-07-22) the \"rev->diffopt\" we pass down to the diff\n> >> machinery has been the one we get from \"format-patch\"'s own\n> >> setup_revisions().\n> >>\n> >> This sort of thing is unique among the log-like commands in\n> >> builtin/log.c, no command than format-patch will embed the output of\n> >> another log-like command. Since the \"rev->diffopt\" is reused we need\n> >> to munge it before we pass it to show_range_diff(). See\n> >> 43dafc4172 (\"format-patch: don't include --stat with --range-diff\n> >> output\", 2018-11-22) for a related regression fix which is being\n> >> mostly reverted here.\n> >>\n> >> Implementation notes: 1) We're not bothering with the full teardown\n> >> around die() and will leak memory, but it's too much boilerplate to do\n> >> all the frees with/without the die() and not worth it. 2) We call\n> >> repo_init_revisions() for \"rd_rev\" even though we could get away with\n> >> a shallow copy like the code we're replacing (and which\n> >> show_range_diff() itself does). This is to make this code more easily\n> >> understood.\n> >>\n> >> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> >> ---\n> >>  Documentation/git-format-patch.txt | 10 ++++++-\n> >>  builtin/log.c                      | 42 +++++++++++++++++++++++-------\n> >>  t/t3206-range-diff.sh              | 41 +++++++++++++++++++++++++++++\n> >>  3 files changed, 82 insertions(+), 11 deletions(-)\n> >>\n> >> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n> >> index aba4c5febe..6c048f415f 100644\n> >> --- a/Documentation/git-format-patch.txt\n> >> +++ b/Documentation/git-format-patch.txt\n> >> @@ -24,7 +24,8 @@ SYNOPSIS\n> >>  \t\t   [--to=<email>] [--cc=<email>]\n> >>  \t\t   [--[no-]cover-letter] [--quiet] [--notes[=<ref>]]\n> >>  \t\t   [--interdiff=<previous>]\n> >> -\t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n> >> +\t\t   [--range-diff=<previous> [--creation-factor=<percent>]\n> >> +\t\t      [--range-diff<common diff option>]]\n> >>  \t\t   [--progress]\n> >>  \t\t   [<common diff options>]\n> >>  \t\t   [ <since> | <revision range> ]\n> >> @@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n> >>  \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n> >>  \tfor details.\n> >>\n> >> +--range-diff<common diff option>::\n> >> +\tOther options prefixed with `--range-diff` are stripped of\n> >> +\tthat prefix and passed as-is to the diff machinery used to\n> >> +\tgenerate the range-diff, e.g. `--range-diff-U0` and\n> >> +\t`--range-diff--no-color`. This allows for adjusting the format\n> >> +\tof the range-diff independently from the patch itself.\n> >> +\n> >>  --notes[=<ref>]::\n> >>  \tAppend the notes (see linkgit:git-notes[1]) for the commit\n> >>  \tafter the three-dash line.\n> >> diff --git a/builtin/log.c b/builtin/log.c\n> >> index 02d88fa233..7658e56ecc 100644\n> >> --- a/builtin/log.c\n> >> +++ b/builtin/log.c\n> >> @@ -1023,7 +1023,8 @@ static void show_diffstat(struct rev_info *rev,\n> >>  \tfprintf(rev->diffopt.file, \"\\n\");\n> >>  }\n> >>\n> >> -static void make_cover_letter(struct rev_info *rev, int use_stdout,\n> >> +static void make_cover_letter(struct rev_info *rev, struct rev_info *rd_rev,\n> >> +\t\t\t      int use_stdout,\n> >>  \t\t\t      struct commit *origin,\n> >>  \t\t\t      int nr, struct commit **list,\n> >>  \t\t\t      const char *branch_name,\n> >> @@ -1095,13 +1096,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n> >>  \t}\n> >>\n> >>  \tif (rev->rdiff1) {\n> >> -\t\tstruct diff_options opts;\n> >> -\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n> >> -\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n> >> -\n> >>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n> >>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n> >> -\t\t\t\trev->creation_factor, 1, &opts);\n> >> +\t\t\t\trev->creation_factor, 1, &rd_rev->diffopt);\n> >>  \t}\n> >>  }\n> >>\n> >> @@ -1485,6 +1482,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >>  \tstruct commit *commit;\n> >>  \tstruct commit **list = NULL;\n> >>  \tstruct rev_info rev;\n> >> +\tstruct rev_info rd_rev;\n> >>  \tstruct setup_revision_opt s_r_opt;\n> >>  \tint nr = 0, total, i;\n> >>  \tint use_stdout = 0;\n> >> @@ -1603,6 +1601,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >>  \tinit_log_defaults();\n> >>  \tgit_config(git_format_config, NULL);\n> >>  \trepo_init_revisions(the_repository, &rev, prefix);\n> >> +\trepo_init_revisions(the_repository, &rd_rev, prefix);\n> >>  \trev.commit_format = CMIT_FMT_EMAIL;\n> >>  \trev.expand_tabs_in_log_default = 0;\n> >>  \trev.verbose_header = 1;\n> >> @@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >>  \trev.preserve_subject = keep_subject;\n> >>\n> >>  \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n> >> -\tif (argc > 1)\n> >> -\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> >> +\tif (argc > 1) {\n> >> +\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n> >> +\t\tconst char *prefix = \"--range-diff\";\n> >> +\t\tint have_prefix = 0;\n> >> +\n> >> +\t\tfor (i = 0; i < argc; i++) {\n> >> +\t\t\tstruct strbuf sb = STRBUF_INIT;\n> >> +\t\t\tchar *str;\n> >> +\n> >> +\t\t\tstrbuf_addstr(&sb, argv[i]);\n> >> +\t\t\tif (starts_with(argv[i], prefix)) {\n> >> +\t\t\t\thave_prefix = 1;\n> >> +\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n> >> +\t\t\t}\n> >> +\t\t\tstr = strbuf_detach(&sb, NULL);\n> >> +\t\t\tstrbuf_release(&sb);\n> >> +\n> >> +\t\t\targv_array_push(&args, str);\n> >> +\t\t}\n> >> +\n> >> +\t\tif (!have_prefix)\n> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> >> +\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n> >> +\t\tif (argc > 1)\n> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> >> +\t}\n> >>\n> >>  \tif (rev.diffopt.output_format & DIFF_FORMAT_NAME)\n> >>  \t\tdie(_(\"--name-only does not make sense\"));\n> >> @@ -1702,7 +1725,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >>  \tif (!use_patch_format &&\n> >>  \t\t(!rev.diffopt.output_format ||\n> >>  \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n> >> -\t\t/* Needs to be mirrored in show_range_diff() invocation */\n> >>  \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n> >>  \tif (!rev.diffopt.stat_width)\n> >>  \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\n> >> @@ -1877,7 +1899,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >>  \tif (cover_letter) {\n> >>  \t\tif (thread)\n> >>  \t\t\tgen_message_id(&rev, \"cover\");\n> >> -\t\tmake_cover_letter(&rev, use_stdout,\n> >> +\t\tmake_cover_letter(&rev, &rd_rev, use_stdout,\n> >>  \t\t\t\t  origin, nr, list, branch_name, quiet);\n> >>  \t\tprint_bases(&bases, rev.diffopt.file);\n> >>  \t\tprint_signature(rev.diffopt.file);\n> >> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n> >> index bc5facc1cd..6916103888 100755\n> >> --- a/t/t3206-range-diff.sh\n> >> +++ b/t/t3206-range-diff.sh\n> >> @@ -308,6 +308,35 @@ test_expect_success 'format-patch with <common diff option>' '\n> >>  \t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n> >>  \tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n> >>  \tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> >> +\t1:  a63e992 ! 1:  d966c5c s/12/B/\n> >> +\t    @@ -8,7 +8,7 @@\n> >> +\t     @@\n> >> +\t      9\n> >> +\t      10\n> >> +\t    - B\n> >> +\t    + BB\n> >> +\t     -12\n> >> +\t     +B\n> >> +\t      13\n> >> +\t-- :\n> >> +\tEOF\n> >> +\ttest_cmp expect actual.range-diff &&\n> >> +\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> >> +\t--- a/file\n> >> +\t+++ b/file\n> >> +\t@@ -12 +12 @@ BB\n> >> +\t-12\n> >> +\t+B\n> >> +\t-- :\n> >> +\tEOF\n> >> +\ttest_cmp expect actual.diff &&\n> >> +\n> >> +\t# -U0 & --range-diff-U0\n> >> +\tgit format-patch --cover-letter --stdout -U0 --range-diff-U0 \\\n> >> +\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n> >> +\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> >>  \t1:  a63e992 ! 1:  d966c5c s/12/B/\n> >>  \t    @@ -11 +11 @@\n> >>  \t    - B\n> >> @@ -327,4 +356,16 @@ test_expect_success 'format-patch with <common diff option>' '\n> >>  \ttest_cmp expect actual.diff\n> >>  '\n> >>\n> >> +test_expect_success 'format-patch option parsing with --range-diff-*' '\n> >> +\ttest_must_fail git format-patch --stdout --unknown \\\n> >> +\t\tmaster..unmodified 2>stderr &&\n> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr &&\n> >> +\ttest_must_fail git format-patch --stdout --range-diff-unknown \\\n> >> +\t\tmaster..unmodified 2>stderr &&\n> >> +\ttest_i18ngrep \"unrecognized argument: --range-diff-unknown\" stderr &&\n> >> +\ttest_must_fail git format-patch --stdout --unknown --range-diff-unknown \\\n> >> +\t\tmaster..unmodified 2>stderr &&\n> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr\n> >> +'\n> >> +\n> >>  test_done\n> >> --\n> >> 2.20.0.rc1.387.gf8505762e3\n> >>\n> >>\n> "},{"id":"364318","messageId":"nycvar.QRO.7.76.6.1811291516540.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811281015360.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-29T14:17:50Z","receivedAt":"2018-11-29T14:17:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Jonathan,\n\nif you could pry more information (or better information) out of that bug\nreporter, that would be nice. Apparently my email address is blacklisted\nby his mail provider, so he is unlikely to have received my previous mail\n(nor will he receive this one, I am sure).\n\nThanks,\nDscho\n\nOn Wed, 28 Nov 2018, Johannes Schindelin wrote:\n\n> Hi Jonathan,\n> \n> On Tue, 27 Nov 2018, Jonathan Nieder wrote:\n> \n> > At https://bugs.debian.org/914695 is a report of a test regression in\n> > an outside project that is very likely to have been triggered by the\n> > new faster rebase code.\n> \n> From looking through that log.gz (without having a clue where the test\n> code lives, so I cannot say what it is supposed to do, and also: this is\n> the first time I hear about dgit...), it would appear that this must be a\n> regression in the reflog messages produced by `git rebase`.\n> \n> > The issue has not been triaged, so I don't know yet whether it's a\n> > problem in rebase-in-c or a manifestation of a bug in the test.\n> \n> It ends thusly:\n> \n> -- snip --\n> [...]\n> + git reflog\n> + egrep 'debrebase new-upstream.*checkout'\n> + test 1 = 0\n> + t-report-failure\n> + set +x\n> TEST FAILED\n> -- snap --\n> \n> Which makes me think that the reflog we produce in *some* code path that\n> originally called `git checkout` differs from the scripted rebase's\n> generated reflog.\n> \n> > That said, Google has been running with the new rebase since ~1 month\n> > ago when it became the default, with no issues reported by users.  As a\n> > result, I am confident that it can cope with what most users of \"next\"\n> > throw at it, which means that if we are to find more issues to polish it\n> > better, it will need all the exposure it can get.\n> \n> Right. And there are a few weeks before the holidays, which should give me\n> time to fix whatever bugs are discovered (I only half mind being the only\n> one who fixes these bugs).\n> \n> > In the Google deployment, we will keep using rebase-in-c even if it\n> > gets disabled by default, in order to help with that.\n> > \n> > From the Debian point of view, it's only a matter of time before\n> > rebase-in-c becomes the default: even if it's not the default in 2.20,\n> > it would presumably be so in 2.21 or 2.22.  That means the community's\n> > attention when resolving security and reliability bugs would be on the\n> > rebase-in-c implementation.  As a result, the Debian package will most\n> > likely enable rebase-in-c by default even if upstream disables it, in\n> > order to increase the package's shelf life (i.e. to ease the\n> > maintenance burden of supporting whichever version of the package ends\n> > up in the next Debian stable).\n> > \n> > So with either hat on, it doesn't matter whether you apply this patch\n> > upstream.\n> > \n> > Having two pretty different deployments end up with the same\n> > conclusion leads me to suspect that it's best for upstream not to\n> > apply the revert patch, unless either\n> > \n> >   (a) we have a concrete regression to address and then try again, or\n> >   (b) we have a test or other plan to follow before trying again.\n> \n> In this instance, I am more a fan of the \"let's move fast and break\n> things, then move even faster fixing them\" approach.\n> \n> Besides, the bug that Ævar discovered was a bug already in the scripted\n> rebase, but hidden by yet another bug (the missing error checking).\n> \n> I get the pretty firm impression that the common code paths are now pretty\n> robust, and only lesser-exercised features may expose a bug (or\n> regression, as in the case of the reflogs, where one could argue that the\n> exact reflog message is not something we promise not to fiddle with).\n> \n> Ciao,\n> Dscho"},{"id":"364323","messageId":"871s74yms3.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811291307070.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-29T14:35:24Z","receivedAt":"2018-11-29T14:35:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Nov 29 2018, Johannes Schindelin wrote:\n\n> Hi Ævar,\n>\n> On Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n>\n>> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n>>\n>> > On Wed, 28 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n>> >\n>> >> Change the semantics of the \"--range-diff\" option so that the regular\n>> >> diff options can be provided separately for the range-diff and the\n>> >> patch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n>> >> \"format-patch\" to provide different context for the range-diff and the\n>> >> patch. This wasn't possible before.\n>> >\n>> > I really, really dislike the `--range-diff-<random-thing>`. We have\n>> > precedent for passing optional arguments that are passed to some other\n>> > command, so a much more logical and consistent convention would be to use\n>> > `--range-diff[=<diff-option>..]`, allowing all of the diff options that\n>> > you might want to pass to the outer diff in one go rather than having a\n>> > lengthy string of `--range-diff-this` and `--range-diff-that` options.\n>>\n>> Where do we pass those sorts of arguments?\n>>\n>> Reasons I did it this way:\n>>\n>>  a) Passing it as one option will require the user to double-quote those\n>>     options that take quoted arguments (e.g. --word-diff-regex), which I\n>>     thought sucked more than the prefix. On the implementation side we\n>>     couldn't leave the parsing of the command-line to the shell anymore.\n>>\n>>  b) I think people will want to tweak this very rarely, much more rarely\n>>     than e.g. -U10 in format-patch itself, so having something long-ish\n>>     doesn't sound bad.\n>\n> Hmm. I still don't like it. It sets a precedent, and we simply do not do\n> it that way in other circumstances (most obvious would be the -X merge\n> options). The more divergent user interfaces for the same sort of thing\n> are, the more brain cycles you force users to spend on navigating said\n> interfaces.\n\nYeah it sucks, I just think it sucks less than the alternative :)\nI.e. I'm not picky about --range-diff-* prefix the name, but I think\ndoing our own shell parsing would be nasty.\n\n>> > I only had time to skim the patch, and I have to wonder why you pass\n>> > around full-blown `rev_info` structs for range diff (and with that really\n>> > awful name `rd_rev`) rather than just the `diff_options` that you\n>> > *actually* care about?\n>>\n>> Because setup_revisions() which does all the command-line parsing needs\n>> a rev_info, so even if we only need the diffopt in the end we need to\n>> initiate the whole thing.\n>>\n>> Suggestions for a better varibale name most welcome.\n>\n> `range_diff_revs`\n>\n> And you do not need to pass around the whole thing. You can easily pass\n> `&range_diff_revs.diffopt`.\n>\n> Don't pass around what you do not need to pass around.\n\nAh, you mean internally in log.c, yes that makes sense. I thought you\nmeant just pass diffopt to setup_revisions() (which needs the containing\nstruct). Willdo.\n\n> Ciao,\n> Dscho\n>\n>>\n>> > Ciao,\n>> > Dscho\n>> >\n>> >>\n>> >> Ever since the \"--range-diff\" option was added in\n>> >> 31e2617a5f (\"format-patch: add --range-diff option to embed diff in\n>> >> cover letter\", 2018-07-22) the \"rev->diffopt\" we pass down to the diff\n>> >> machinery has been the one we get from \"format-patch\"'s own\n>> >> setup_revisions().\n>> >>\n>> >> This sort of thing is unique among the log-like commands in\n>> >> builtin/log.c, no command than format-patch will embed the output of\n>> >> another log-like command. Since the \"rev->diffopt\" is reused we need\n>> >> to munge it before we pass it to show_range_diff(). See\n>> >> 43dafc4172 (\"format-patch: don't include --stat with --range-diff\n>> >> output\", 2018-11-22) for a related regression fix which is being\n>> >> mostly reverted here.\n>> >>\n>> >> Implementation notes: 1) We're not bothering with the full teardown\n>> >> around die() and will leak memory, but it's too much boilerplate to do\n>> >> all the frees with/without the die() and not worth it. 2) We call\n>> >> repo_init_revisions() for \"rd_rev\" even though we could get away with\n>> >> a shallow copy like the code we're replacing (and which\n>> >> show_range_diff() itself does). This is to make this code more easily\n>> >> understood.\n>> >>\n>> >> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> >> ---\n>> >>  Documentation/git-format-patch.txt | 10 ++++++-\n>> >>  builtin/log.c                      | 42 +++++++++++++++++++++++-------\n>> >>  t/t3206-range-diff.sh              | 41 +++++++++++++++++++++++++++++\n>> >>  3 files changed, 82 insertions(+), 11 deletions(-)\n>> >>\n>> >> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n>> >> index aba4c5febe..6c048f415f 100644\n>> >> --- a/Documentation/git-format-patch.txt\n>> >> +++ b/Documentation/git-format-patch.txt\n>> >> @@ -24,7 +24,8 @@ SYNOPSIS\n>> >>  \t\t   [--to=<email>] [--cc=<email>]\n>> >>  \t\t   [--[no-]cover-letter] [--quiet] [--notes[=<ref>]]\n>> >>  \t\t   [--interdiff=<previous>]\n>> >> -\t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n>> >> +\t\t   [--range-diff=<previous> [--creation-factor=<percent>]\n>> >> +\t\t      [--range-diff<common diff option>]]\n>> >>  \t\t   [--progress]\n>> >>  \t\t   [<common diff options>]\n>> >>  \t\t   [ <since> | <revision range> ]\n>> >> @@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n>> >>  \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n>> >>  \tfor details.\n>> >>\n>> >> +--range-diff<common diff option>::\n>> >> +\tOther options prefixed with `--range-diff` are stripped of\n>> >> +\tthat prefix and passed as-is to the diff machinery used to\n>> >> +\tgenerate the range-diff, e.g. `--range-diff-U0` and\n>> >> +\t`--range-diff--no-color`. This allows for adjusting the format\n>> >> +\tof the range-diff independently from the patch itself.\n>> >> +\n>> >>  --notes[=<ref>]::\n>> >>  \tAppend the notes (see linkgit:git-notes[1]) for the commit\n>> >>  \tafter the three-dash line.\n>> >> diff --git a/builtin/log.c b/builtin/log.c\n>> >> index 02d88fa233..7658e56ecc 100644\n>> >> --- a/builtin/log.c\n>> >> +++ b/builtin/log.c\n>> >> @@ -1023,7 +1023,8 @@ static void show_diffstat(struct rev_info *rev,\n>> >>  \tfprintf(rev->diffopt.file, \"\\n\");\n>> >>  }\n>> >>\n>> >> -static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>> >> +static void make_cover_letter(struct rev_info *rev, struct rev_info *rd_rev,\n>> >> +\t\t\t      int use_stdout,\n>> >>  \t\t\t      struct commit *origin,\n>> >>  \t\t\t      int nr, struct commit **list,\n>> >>  \t\t\t      const char *branch_name,\n>> >> @@ -1095,13 +1096,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>> >>  \t}\n>> >>\n>> >>  \tif (rev->rdiff1) {\n>> >> -\t\tstruct diff_options opts;\n>> >> -\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n>> >> -\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n>> >> -\n>> >>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n>> >>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n>> >> -\t\t\t\trev->creation_factor, 1, &opts);\n>> >> +\t\t\t\trev->creation_factor, 1, &rd_rev->diffopt);\n>> >>  \t}\n>> >>  }\n>> >>\n>> >> @@ -1485,6 +1482,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >>  \tstruct commit *commit;\n>> >>  \tstruct commit **list = NULL;\n>> >>  \tstruct rev_info rev;\n>> >> +\tstruct rev_info rd_rev;\n>> >>  \tstruct setup_revision_opt s_r_opt;\n>> >>  \tint nr = 0, total, i;\n>> >>  \tint use_stdout = 0;\n>> >> @@ -1603,6 +1601,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >>  \tinit_log_defaults();\n>> >>  \tgit_config(git_format_config, NULL);\n>> >>  \trepo_init_revisions(the_repository, &rev, prefix);\n>> >> +\trepo_init_revisions(the_repository, &rd_rev, prefix);\n>> >>  \trev.commit_format = CMIT_FMT_EMAIL;\n>> >>  \trev.expand_tabs_in_log_default = 0;\n>> >>  \trev.verbose_header = 1;\n>> >> @@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >>  \trev.preserve_subject = keep_subject;\n>> >>\n>> >>  \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n>> >> -\tif (argc > 1)\n>> >> -\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> >> +\tif (argc > 1) {\n>> >> +\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n>> >> +\t\tconst char *prefix = \"--range-diff\";\n>> >> +\t\tint have_prefix = 0;\n>> >> +\n>> >> +\t\tfor (i = 0; i < argc; i++) {\n>> >> +\t\t\tstruct strbuf sb = STRBUF_INIT;\n>> >> +\t\t\tchar *str;\n>> >> +\n>> >> +\t\t\tstrbuf_addstr(&sb, argv[i]);\n>> >> +\t\t\tif (starts_with(argv[i], prefix)) {\n>> >> +\t\t\t\thave_prefix = 1;\n>> >> +\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n>> >> +\t\t\t}\n>> >> +\t\t\tstr = strbuf_detach(&sb, NULL);\n>> >> +\t\t\tstrbuf_release(&sb);\n>> >> +\n>> >> +\t\t\targv_array_push(&args, str);\n>> >> +\t\t}\n>> >> +\n>> >> +\t\tif (!have_prefix)\n>> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> >> +\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n>> >> +\t\tif (argc > 1)\n>> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> >> +\t}\n>> >>\n>> >>  \tif (rev.diffopt.output_format & DIFF_FORMAT_NAME)\n>> >>  \t\tdie(_(\"--name-only does not make sense\"));\n>> >> @@ -1702,7 +1725,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >>  \tif (!use_patch_format &&\n>> >>  \t\t(!rev.diffopt.output_format ||\n>> >>  \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n>> >> -\t\t/* Needs to be mirrored in show_range_diff() invocation */\n>> >>  \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n>> >>  \tif (!rev.diffopt.stat_width)\n>> >>  \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\n>> >> @@ -1877,7 +1899,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >>  \tif (cover_letter) {\n>> >>  \t\tif (thread)\n>> >>  \t\t\tgen_message_id(&rev, \"cover\");\n>> >> -\t\tmake_cover_letter(&rev, use_stdout,\n>> >> +\t\tmake_cover_letter(&rev, &rd_rev, use_stdout,\n>> >>  \t\t\t\t  origin, nr, list, branch_name, quiet);\n>> >>  \t\tprint_bases(&bases, rev.diffopt.file);\n>> >>  \t\tprint_signature(rev.diffopt.file);\n>> >> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n>> >> index bc5facc1cd..6916103888 100755\n>> >> --- a/t/t3206-range-diff.sh\n>> >> +++ b/t/t3206-range-diff.sh\n>> >> @@ -308,6 +308,35 @@ test_expect_success 'format-patch with <common diff option>' '\n>> >>  \t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n>> >>  \tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n>> >>  \tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> >> +\t1:  a63e992 ! 1:  d966c5c s/12/B/\n>> >> +\t    @@ -8,7 +8,7 @@\n>> >> +\t     @@\n>> >> +\t      9\n>> >> +\t      10\n>> >> +\t    - B\n>> >> +\t    + BB\n>> >> +\t     -12\n>> >> +\t     +B\n>> >> +\t      13\n>> >> +\t-- :\n>> >> +\tEOF\n>> >> +\ttest_cmp expect actual.range-diff &&\n>> >> +\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n>> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> >> +\t--- a/file\n>> >> +\t+++ b/file\n>> >> +\t@@ -12 +12 @@ BB\n>> >> +\t-12\n>> >> +\t+B\n>> >> +\t-- :\n>> >> +\tEOF\n>> >> +\ttest_cmp expect actual.diff &&\n>> >> +\n>> >> +\t# -U0 & --range-diff-U0\n>> >> +\tgit format-patch --cover-letter --stdout -U0 --range-diff-U0 \\\n>> >> +\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n>> >> +\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n>> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> >>  \t1:  a63e992 ! 1:  d966c5c s/12/B/\n>> >>  \t    @@ -11 +11 @@\n>> >>  \t    - B\n>> >> @@ -327,4 +356,16 @@ test_expect_success 'format-patch with <common diff option>' '\n>> >>  \ttest_cmp expect actual.diff\n>> >>  '\n>> >>\n>> >> +test_expect_success 'format-patch option parsing with --range-diff-*' '\n>> >> +\ttest_must_fail git format-patch --stdout --unknown \\\n>> >> +\t\tmaster..unmodified 2>stderr &&\n>> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr &&\n>> >> +\ttest_must_fail git format-patch --stdout --range-diff-unknown \\\n>> >> +\t\tmaster..unmodified 2>stderr &&\n>> >> +\ttest_i18ngrep \"unrecognized argument: --range-diff-unknown\" stderr &&\n>> >> +\ttest_must_fail git format-patch --stdout --unknown --range-diff-unknown \\\n>> >> +\t\tmaster..unmodified 2>stderr &&\n>> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr\n>> >> +'\n>> >> +\n>> >>  test_done\n>> >> --\n>> >> 2.20.0.rc1.387.gf8505762e3\n>> >>\n>> >>\n>>\n"},{"id":"364328","messageId":"23551.63504.876084.449440@chiark.greenend.org.uk","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811291516540.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2018-11-29T14:30:40Z","receivedAt":"2018-11-29T14:58:02Z","isPatch":true,"sender":{"key":"ijackson@chiark.greenend.org.uk","avatar":null},"body":"Johannes Schindelin writes (\"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)\"):\n> if you could pry more information (or better information) out of that bug\n> reporter, that would be nice. Apparently my email address is blacklisted\n> by his mail provider, so he is unlikely to have received my previous mail\n> (nor will he receive this one, I am sure).\n\n(I did receive this mail.  Sorry for the inconvenience, which sadly is\ninevitable occasionally in the modern email world.  FTR in future feel\nfree to send the bounce to postmaster@chiark and I will make a\nyou-shaped hole in my spamfilter.  Also with Debian bugs you can\nlaunder your messages by, eg, emailing 914695-submitter@bugs.)\n\n> > > At https://bugs.debian.org/914695 is a report of a test regression in\n> > > an outside project that is very likely to have been triggered by the\n> > > new faster rebase code.\n\nAs I wrote in the bug report last night:\n\n https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=914695#15\n\n I have investigated and the bug seems to be that git-rebase --onto now\n fails to honour GIT_REFLOG_ACTION for the initial checkout.\n\n In a successful run with older git I get a reflog like this:\n\n   4833d74 HEAD@{0}: rebase finished: returning to refs/heads/with-preexisting\n   4833d74 HEAD@{1}: debrebase new-upstream 2.1-1: rebase: Add another new upstream file\n   cabd5ec HEAD@{2}: debrebase new-upstream 2.1-1: rebase: Edit the .c file\n   0b362ce HEAD@{3}: debrebase new-upstream 2.1-1: rebase: Add a new upstream file\n   29653e5 HEAD@{4}: debrebase new-upstream 2.1-1: rebase: checkout 29653e5a17bee4ac23a68bba3e12bc1f52858ac3\n   85e0c46 HEAD@{5}: debrebase: launder for new upstream\n\n With a newer git I get this:\n\n   6d3fb91 HEAD@{0}: rebase finished: returning to refs/heads/master\n   6d3fb91 HEAD@{1}: debrebase new-upstream 2.1-1: rebase: Add another new upstream file\n   86c0721 HEAD@{2}: debrebase new-upstream 2.1-1: rebase: Edit the .c file\n   50ba56c HEAD@{3}: debrebase new-upstream 2.1-1: rebase: Add a new upstream file\n   8272825 HEAD@{4}: rebase: checkout 8272825bb4ff6eba89afa936e32b6460f963a36a\n   c78db55 HEAD@{5}: debrebase: launder for new upstream\n\n This breaks the test because my test suite is checking that I set\n GIT_REFLOG_ACTION appropriately.\n\n If you want I can provide a minimal test case but this should suffice\n to see the bug I hope...\n\nRegards\nIan.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.\n\nIf I emailed you from an address @fyvzl.net or @evade.org.uk, that is\na private address which bypasses my fierce spamfilter.\n"},{"id":"364337","messageId":"nycvar.QRO.7.76.6.1811291638400.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"23551.63504.876084.449440@chiark.greenend.org.uk","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-29T15:39:40Z","receivedAt":"2018-11-29T15:39:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ian,\n\nOn Thu, 29 Nov 2018, Ian Jackson wrote:\n\n> Johannes Schindelin writes (\"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)\"):\n> > if you could pry more information (or better information) out of that bug\n> > reporter, that would be nice. Apparently my email address is blacklisted\n> > by his mail provider, so he is unlikely to have received my previous mail\n> > (nor will he receive this one, I am sure).\n> \n> (I did receive this mail.  Sorry for the inconvenience, which sadly is\n> inevitable occasionally in the modern email world.  FTR in future feel\n> free to send the bounce to postmaster@chiark and I will make a\n> you-shaped hole in my spamfilter.  Also with Debian bugs you can\n> launder your messages by, eg, emailing 914695-submitter@bugs.)\n\nRight. I myself have plenty of email-related problems that seem to crop up\nthis year in particular.\n\n> > > > At https://bugs.debian.org/914695 is a report of a test regression in\n> > > > an outside project that is very likely to have been triggered by the\n> > > > new faster rebase code.\n> \n> As I wrote in the bug report last night:\n> \n>  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=914695#15\n> \n>  I have investigated and the bug seems to be that git-rebase --onto now\n>  fails to honour GIT_REFLOG_ACTION for the initial checkout.\n> \n>  In a successful run with older git I get a reflog like this:\n> \n>    4833d74 HEAD@{0}: rebase finished: returning to refs/heads/with-preexisting\n>    4833d74 HEAD@{1}: debrebase new-upstream 2.1-1: rebase: Add another new upstream file\n>    cabd5ec HEAD@{2}: debrebase new-upstream 2.1-1: rebase: Edit the .c file\n>    0b362ce HEAD@{3}: debrebase new-upstream 2.1-1: rebase: Add a new upstream file\n>    29653e5 HEAD@{4}: debrebase new-upstream 2.1-1: rebase: checkout 29653e5a17bee4ac23a68bba3e12bc1f52858ac3\n>    85e0c46 HEAD@{5}: debrebase: launder for new upstream\n> \n>  With a newer git I get this:\n> \n>    6d3fb91 HEAD@{0}: rebase finished: returning to refs/heads/master\n>    6d3fb91 HEAD@{1}: debrebase new-upstream 2.1-1: rebase: Add another new upstream file\n>    86c0721 HEAD@{2}: debrebase new-upstream 2.1-1: rebase: Edit the .c file\n>    50ba56c HEAD@{3}: debrebase new-upstream 2.1-1: rebase: Add a new upstream file\n>    8272825 HEAD@{4}: rebase: checkout 8272825bb4ff6eba89afa936e32b6460f963a36a\n>    c78db55 HEAD@{5}: debrebase: launder for new upstream\n> \n>  This breaks the test because my test suite is checking that I set\n>  GIT_REFLOG_ACTION appropriately.\n> \n>  If you want I can provide a minimal test case but this should suffice\n>  to see the bug I hope...\n\nThis should be plenty for me to get going. Thank you!\n\nCiao,\nJohannes\n\n> \n> Regards\n> Ian.\n> \n> -- \n> Ian Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.\n> \n> If I emailed you from an address @fyvzl.net or @evade.org.uk, that is\n> a private address which bypasses my fierce spamfilter.\n> \n"},{"id":"364338","messageId":"nycvar.QRO.7.76.6.1811291641090.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"871s74yms3.fsf@evledraar.gmail.com","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-29T15:41:50Z","receivedAt":"2018-11-29T15:41:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n\n> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n> \n> > On Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n> >\n> >> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n> >>\n> >> > On Wed, 28 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n> >> >\n> >> >> Change the semantics of the \"--range-diff\" option so that the regular\n> >> >> diff options can be provided separately for the range-diff and the\n> >> >> patch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n> >> >> \"format-patch\" to provide different context for the range-diff and the\n> >> >> patch. This wasn't possible before.\n> >> >\n> >> > I really, really dislike the `--range-diff-<random-thing>`. We have\n> >> > precedent for passing optional arguments that are passed to some other\n> >> > command, so a much more logical and consistent convention would be to use\n> >> > `--range-diff[=<diff-option>..]`, allowing all of the diff options that\n> >> > you might want to pass to the outer diff in one go rather than having a\n> >> > lengthy string of `--range-diff-this` and `--range-diff-that` options.\n> >>\n> >> Where do we pass those sorts of arguments?\n> >>\n> >> Reasons I did it this way:\n> >>\n> >>  a) Passing it as one option will require the user to double-quote those\n> >>     options that take quoted arguments (e.g. --word-diff-regex), which I\n> >>     thought sucked more than the prefix. On the implementation side we\n> >>     couldn't leave the parsing of the command-line to the shell anymore.\n> >>\n> >>  b) I think people will want to tweak this very rarely, much more rarely\n> >>     than e.g. -U10 in format-patch itself, so having something long-ish\n> >>     doesn't sound bad.\n> >\n> > Hmm. I still don't like it. It sets a precedent, and we simply do not do\n> > it that way in other circumstances (most obvious would be the -X merge\n> > options). The more divergent user interfaces for the same sort of thing\n> > are, the more brain cycles you force users to spend on navigating said\n> > interfaces.\n> \n> Yeah it sucks, I just think it sucks less than the alternative :)\n> I.e. I'm not picky about --range-diff-* prefix the name, but I think\n> doing our own shell parsing would be nasty.\n\nWhat prevents you from using `sq_dequote_to_argv()`?\n\n> >> > I only had time to skim the patch, and I have to wonder why you pass\n> >> > around full-blown `rev_info` structs for range diff (and with that really\n> >> > awful name `rd_rev`) rather than just the `diff_options` that you\n> >> > *actually* care about?\n> >>\n> >> Because setup_revisions() which does all the command-line parsing needs\n> >> a rev_info, so even if we only need the diffopt in the end we need to\n> >> initiate the whole thing.\n> >>\n> >> Suggestions for a better varibale name most welcome.\n> >\n> > `range_diff_revs`\n> >\n> > And you do not need to pass around the whole thing. You can easily pass\n> > `&range_diff_revs.diffopt`.\n> >\n> > Don't pass around what you do not need to pass around.\n> \n> Ah, you mean internally in log.c, yes that makes sense. I thought you\n> meant just pass diffopt to setup_revisions() (which needs the containing\n> struct). Willdo.\n\nThanks,\nDscho\n\n> \n> > Ciao,\n> > Dscho\n> >\n> >>\n> >> > Ciao,\n> >> > Dscho\n> >> >\n> >> >>\n> >> >> Ever since the \"--range-diff\" option was added in\n> >> >> 31e2617a5f (\"format-patch: add --range-diff option to embed diff in\n> >> >> cover letter\", 2018-07-22) the \"rev->diffopt\" we pass down to the diff\n> >> >> machinery has been the one we get from \"format-patch\"'s own\n> >> >> setup_revisions().\n> >> >>\n> >> >> This sort of thing is unique among the log-like commands in\n> >> >> builtin/log.c, no command than format-patch will embed the output of\n> >> >> another log-like command. Since the \"rev->diffopt\" is reused we need\n> >> >> to munge it before we pass it to show_range_diff(). See\n> >> >> 43dafc4172 (\"format-patch: don't include --stat with --range-diff\n> >> >> output\", 2018-11-22) for a related regression fix which is being\n> >> >> mostly reverted here.\n> >> >>\n> >> >> Implementation notes: 1) We're not bothering with the full teardown\n> >> >> around die() and will leak memory, but it's too much boilerplate to do\n> >> >> all the frees with/without the die() and not worth it. 2) We call\n> >> >> repo_init_revisions() for \"rd_rev\" even though we could get away with\n> >> >> a shallow copy like the code we're replacing (and which\n> >> >> show_range_diff() itself does). This is to make this code more easily\n> >> >> understood.\n> >> >>\n> >> >> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> >> >> ---\n> >> >>  Documentation/git-format-patch.txt | 10 ++++++-\n> >> >>  builtin/log.c                      | 42 +++++++++++++++++++++++-------\n> >> >>  t/t3206-range-diff.sh              | 41 +++++++++++++++++++++++++++++\n> >> >>  3 files changed, 82 insertions(+), 11 deletions(-)\n> >> >>\n> >> >> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n> >> >> index aba4c5febe..6c048f415f 100644\n> >> >> --- a/Documentation/git-format-patch.txt\n> >> >> +++ b/Documentation/git-format-patch.txt\n> >> >> @@ -24,7 +24,8 @@ SYNOPSIS\n> >> >>  \t\t   [--to=<email>] [--cc=<email>]\n> >> >>  \t\t   [--[no-]cover-letter] [--quiet] [--notes[=<ref>]]\n> >> >>  \t\t   [--interdiff=<previous>]\n> >> >> -\t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n> >> >> +\t\t   [--range-diff=<previous> [--creation-factor=<percent>]\n> >> >> +\t\t      [--range-diff<common diff option>]]\n> >> >>  \t\t   [--progress]\n> >> >>  \t\t   [<common diff options>]\n> >> >>  \t\t   [ <since> | <revision range> ]\n> >> >> @@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n> >> >>  \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n> >> >>  \tfor details.\n> >> >>\n> >> >> +--range-diff<common diff option>::\n> >> >> +\tOther options prefixed with `--range-diff` are stripped of\n> >> >> +\tthat prefix and passed as-is to the diff machinery used to\n> >> >> +\tgenerate the range-diff, e.g. `--range-diff-U0` and\n> >> >> +\t`--range-diff--no-color`. This allows for adjusting the format\n> >> >> +\tof the range-diff independently from the patch itself.\n> >> >> +\n> >> >>  --notes[=<ref>]::\n> >> >>  \tAppend the notes (see linkgit:git-notes[1]) for the commit\n> >> >>  \tafter the three-dash line.\n> >> >> diff --git a/builtin/log.c b/builtin/log.c\n> >> >> index 02d88fa233..7658e56ecc 100644\n> >> >> --- a/builtin/log.c\n> >> >> +++ b/builtin/log.c\n> >> >> @@ -1023,7 +1023,8 @@ static void show_diffstat(struct rev_info *rev,\n> >> >>  \tfprintf(rev->diffopt.file, \"\\n\");\n> >> >>  }\n> >> >>\n> >> >> -static void make_cover_letter(struct rev_info *rev, int use_stdout,\n> >> >> +static void make_cover_letter(struct rev_info *rev, struct rev_info *rd_rev,\n> >> >> +\t\t\t      int use_stdout,\n> >> >>  \t\t\t      struct commit *origin,\n> >> >>  \t\t\t      int nr, struct commit **list,\n> >> >>  \t\t\t      const char *branch_name,\n> >> >> @@ -1095,13 +1096,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n> >> >>  \t}\n> >> >>\n> >> >>  \tif (rev->rdiff1) {\n> >> >> -\t\tstruct diff_options opts;\n> >> >> -\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n> >> >> -\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n> >> >> -\n> >> >>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n> >> >>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n> >> >> -\t\t\t\trev->creation_factor, 1, &opts);\n> >> >> +\t\t\t\trev->creation_factor, 1, &rd_rev->diffopt);\n> >> >>  \t}\n> >> >>  }\n> >> >>\n> >> >> @@ -1485,6 +1482,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >> >>  \tstruct commit *commit;\n> >> >>  \tstruct commit **list = NULL;\n> >> >>  \tstruct rev_info rev;\n> >> >> +\tstruct rev_info rd_rev;\n> >> >>  \tstruct setup_revision_opt s_r_opt;\n> >> >>  \tint nr = 0, total, i;\n> >> >>  \tint use_stdout = 0;\n> >> >> @@ -1603,6 +1601,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >> >>  \tinit_log_defaults();\n> >> >>  \tgit_config(git_format_config, NULL);\n> >> >>  \trepo_init_revisions(the_repository, &rev, prefix);\n> >> >> +\trepo_init_revisions(the_repository, &rd_rev, prefix);\n> >> >>  \trev.commit_format = CMIT_FMT_EMAIL;\n> >> >>  \trev.expand_tabs_in_log_default = 0;\n> >> >>  \trev.verbose_header = 1;\n> >> >> @@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >> >>  \trev.preserve_subject = keep_subject;\n> >> >>\n> >> >>  \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n> >> >> -\tif (argc > 1)\n> >> >> -\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> >> >> +\tif (argc > 1) {\n> >> >> +\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n> >> >> +\t\tconst char *prefix = \"--range-diff\";\n> >> >> +\t\tint have_prefix = 0;\n> >> >> +\n> >> >> +\t\tfor (i = 0; i < argc; i++) {\n> >> >> +\t\t\tstruct strbuf sb = STRBUF_INIT;\n> >> >> +\t\t\tchar *str;\n> >> >> +\n> >> >> +\t\t\tstrbuf_addstr(&sb, argv[i]);\n> >> >> +\t\t\tif (starts_with(argv[i], prefix)) {\n> >> >> +\t\t\t\thave_prefix = 1;\n> >> >> +\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n> >> >> +\t\t\t}\n> >> >> +\t\t\tstr = strbuf_detach(&sb, NULL);\n> >> >> +\t\t\tstrbuf_release(&sb);\n> >> >> +\n> >> >> +\t\t\targv_array_push(&args, str);\n> >> >> +\t\t}\n> >> >> +\n> >> >> +\t\tif (!have_prefix)\n> >> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> >> >> +\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n> >> >> +\t\tif (argc > 1)\n> >> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n> >> >> +\t}\n> >> >>\n> >> >>  \tif (rev.diffopt.output_format & DIFF_FORMAT_NAME)\n> >> >>  \t\tdie(_(\"--name-only does not make sense\"));\n> >> >> @@ -1702,7 +1725,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >> >>  \tif (!use_patch_format &&\n> >> >>  \t\t(!rev.diffopt.output_format ||\n> >> >>  \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n> >> >> -\t\t/* Needs to be mirrored in show_range_diff() invocation */\n> >> >>  \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n> >> >>  \tif (!rev.diffopt.stat_width)\n> >> >>  \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\n> >> >> @@ -1877,7 +1899,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n> >> >>  \tif (cover_letter) {\n> >> >>  \t\tif (thread)\n> >> >>  \t\t\tgen_message_id(&rev, \"cover\");\n> >> >> -\t\tmake_cover_letter(&rev, use_stdout,\n> >> >> +\t\tmake_cover_letter(&rev, &rd_rev, use_stdout,\n> >> >>  \t\t\t\t  origin, nr, list, branch_name, quiet);\n> >> >>  \t\tprint_bases(&bases, rev.diffopt.file);\n> >> >>  \t\tprint_signature(rev.diffopt.file);\n> >> >> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n> >> >> index bc5facc1cd..6916103888 100755\n> >> >> --- a/t/t3206-range-diff.sh\n> >> >> +++ b/t/t3206-range-diff.sh\n> >> >> @@ -308,6 +308,35 @@ test_expect_success 'format-patch with <common diff option>' '\n> >> >>  \t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n> >> >>  \tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n> >> >>  \tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> >> >> +\t1:  a63e992 ! 1:  d966c5c s/12/B/\n> >> >> +\t    @@ -8,7 +8,7 @@\n> >> >> +\t     @@\n> >> >> +\t      9\n> >> >> +\t      10\n> >> >> +\t    - B\n> >> >> +\t    + BB\n> >> >> +\t     -12\n> >> >> +\t     +B\n> >> >> +\t      13\n> >> >> +\t-- :\n> >> >> +\tEOF\n> >> >> +\ttest_cmp expect actual.range-diff &&\n> >> >> +\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n> >> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> >> >> +\t--- a/file\n> >> >> +\t+++ b/file\n> >> >> +\t@@ -12 +12 @@ BB\n> >> >> +\t-12\n> >> >> +\t+B\n> >> >> +\t-- :\n> >> >> +\tEOF\n> >> >> +\ttest_cmp expect actual.diff &&\n> >> >> +\n> >> >> +\t# -U0 & --range-diff-U0\n> >> >> +\tgit format-patch --cover-letter --stdout -U0 --range-diff-U0 \\\n> >> >> +\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n> >> >> +\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n> >> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n> >> >>  \t1:  a63e992 ! 1:  d966c5c s/12/B/\n> >> >>  \t    @@ -11 +11 @@\n> >> >>  \t    - B\n> >> >> @@ -327,4 +356,16 @@ test_expect_success 'format-patch with <common diff option>' '\n> >> >>  \ttest_cmp expect actual.diff\n> >> >>  '\n> >> >>\n> >> >> +test_expect_success 'format-patch option parsing with --range-diff-*' '\n> >> >> +\ttest_must_fail git format-patch --stdout --unknown \\\n> >> >> +\t\tmaster..unmodified 2>stderr &&\n> >> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr &&\n> >> >> +\ttest_must_fail git format-patch --stdout --range-diff-unknown \\\n> >> >> +\t\tmaster..unmodified 2>stderr &&\n> >> >> +\ttest_i18ngrep \"unrecognized argument: --range-diff-unknown\" stderr &&\n> >> >> +\ttest_must_fail git format-patch --stdout --unknown --range-diff-unknown \\\n> >> >> +\t\tmaster..unmodified 2>stderr &&\n> >> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr\n> >> >> +'\n> >> >> +\n> >> >>  test_done\n> >> >> --\n> >> >> 2.20.0.rc1.387.gf8505762e3\n> >> >>\n> >> >>\n> >>\n> "},{"id":"364340","messageId":"23552.2773.538601.372248@chiark.greenend.org.uk","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811291638400.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2018-11-29T15:50:45Z","receivedAt":"2018-11-29T15:50:50Z","isPatch":true,"sender":{"key":"ijackson@chiark.greenend.org.uk","avatar":null},"body":"Johannes Schindelin writes (\"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)\"):\n> >  In a successful run with older git I get a reflog like this:\n> > \n> >    4833d74 HEAD@{0}: rebase finished: returning to refs/heads/with-preexisting\n> >    4833d74 HEAD@{1}: debrebase new-upstream 2.1-1: rebase: Add another new upstream file\n> >    cabd5ec HEAD@{2}: debrebase new-upstream 2.1-1: rebase: Edit the .c file\n> >    0b362ce HEAD@{3}: debrebase new-upstream 2.1-1: rebase: Add a new upstream file\n> >    29653e5 HEAD@{4}: debrebase new-upstream 2.1-1: rebase: checkout 29653e5a17bee4ac23a68bba3e12bc1f52858ac3\n> >    85e0c46 HEAD@{5}: debrebase: launder for new upstream\n...\n> >  This breaks the test because my test suite is checking that I set\n> >  GIT_REFLOG_ACTION appropriately.\n> > \n> >  If you want I can provide a minimal test case but this should suffice\n> >  to see the bug I hope...\n> \n> This should be plenty for me to get going. Thank you!\n\nHappy hunting.\n\nWhile you're looking at this, I observe that the fact that the `rebase\nfinished' message also does not honour GIT_REFLOG_ACTION appears to be\na pre-existing bug.\n\n(In general one often can't rely on GIT_REFLOG_ACTION still being set\nbecause the rebase might have been interrupted and restarted, which I\nthink is why my test case looks for it in the initial `checkout'\nmessage.)\n\nRegards,\nIan.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.\n\nIf I emailed you from an address @fyvzl.net or @evade.org.uk, that is\na private address which bypasses my fierce spamfilter.\n"},{"id":"364341","messageId":"87tvjzyiph.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811291641090.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-29T16:03:22Z","receivedAt":"2018-11-29T16:03:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Nov 29 2018, Johannes Schindelin wrote:\n\n> Hi Ævar,\n>\n> On Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n>\n>> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n>>\n>> > On Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n>> >\n>> >> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n>> >>\n>> >> > On Wed, 28 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n>> >> >\n>> >> >> Change the semantics of the \"--range-diff\" option so that the regular\n>> >> >> diff options can be provided separately for the range-diff and the\n>> >> >> patch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n>> >> >> \"format-patch\" to provide different context for the range-diff and the\n>> >> >> patch. This wasn't possible before.\n>> >> >\n>> >> > I really, really dislike the `--range-diff-<random-thing>`. We have\n>> >> > precedent for passing optional arguments that are passed to some other\n>> >> > command, so a much more logical and consistent convention would be to use\n>> >> > `--range-diff[=<diff-option>..]`, allowing all of the diff options that\n>> >> > you might want to pass to the outer diff in one go rather than having a\n>> >> > lengthy string of `--range-diff-this` and `--range-diff-that` options.\n>> >>\n>> >> Where do we pass those sorts of arguments?\n>> >>\n>> >> Reasons I did it this way:\n>> >>\n>> >>  a) Passing it as one option will require the user to double-quote those\n>> >>     options that take quoted arguments (e.g. --word-diff-regex), which I\n>> >>     thought sucked more than the prefix. On the implementation side we\n>> >>     couldn't leave the parsing of the command-line to the shell anymore.\n>> >>\n>> >>  b) I think people will want to tweak this very rarely, much more rarely\n>> >>     than e.g. -U10 in format-patch itself, so having something long-ish\n>> >>     doesn't sound bad.\n>> >\n>> > Hmm. I still don't like it. It sets a precedent, and we simply do not do\n>> > it that way in other circumstances (most obvious would be the -X merge\n>> > options). The more divergent user interfaces for the same sort of thing\n>> > are, the more brain cycles you force users to spend on navigating said\n>> > interfaces.\n>>\n>> Yeah it sucks, I just think it sucks less than the alternative :)\n>> I.e. I'm not picky about --range-diff-* prefix the name, but I think\n>> doing our own shell parsing would be nasty.\n>\n> What prevents you from using `sq_dequote_to_argv()`?\n\nI mean not just nasty in terms of implementation, yeah we could do it,\nbut also a nasty UX for things like --word-diff-regex. I.e. instead of:\n\n    --range-diff-word-diff-regex='[0-9\"]'\n\nYou need:\n\n    --range-diff-opts=\"--word-diff-regex='[0-9\\\"]'\"\n\nNow admittedly that in itself isn't very painful *in this case*, but in\nterms of precedent I really dislike that option, i.e. git having some\nmode where I need to work to escape input to pass to another command.\n\nNot saying that this --range-diff-* thing is what we should go for, but\nsurely we can find some way to do deal with this that doesn't involve\nthe user needing to escape stuff like this.\n\nIt also has other downstream effects in the UI, e.g. it's presumably\neasy to teach the bash completion that a --foo=XYZ option is also called\n--some-prefix--foo=XYZ and to enable completion for that, less so for\nmaking it smart enough to complete \"--some-prefix-opts=\"--foo=<TAB>\".\n\n>> >> > I only had time to skim the patch, and I have to wonder why you pass\n>> >> > around full-blown `rev_info` structs for range diff (and with that really\n>> >> > awful name `rd_rev`) rather than just the `diff_options` that you\n>> >> > *actually* care about?\n>> >>\n>> >> Because setup_revisions() which does all the command-line parsing needs\n>> >> a rev_info, so even if we only need the diffopt in the end we need to\n>> >> initiate the whole thing.\n>> >>\n>> >> Suggestions for a better varibale name most welcome.\n>> >\n>> > `range_diff_revs`\n>> >\n>> > And you do not need to pass around the whole thing. You can easily pass\n>> > `&range_diff_revs.diffopt`.\n>> >\n>> > Don't pass around what you do not need to pass around.\n>>\n>> Ah, you mean internally in log.c, yes that makes sense. I thought you\n>> meant just pass diffopt to setup_revisions() (which needs the containing\n>> struct). Willdo.\n>\n> Thanks,\n> Dscho\n>\n>>\n>> > Ciao,\n>> > Dscho\n>> >\n>> >>\n>> >> > Ciao,\n>> >> > Dscho\n>> >> >\n>> >> >>\n>> >> >> Ever since the \"--range-diff\" option was added in\n>> >> >> 31e2617a5f (\"format-patch: add --range-diff option to embed diff in\n>> >> >> cover letter\", 2018-07-22) the \"rev->diffopt\" we pass down to the diff\n>> >> >> machinery has been the one we get from \"format-patch\"'s own\n>> >> >> setup_revisions().\n>> >> >>\n>> >> >> This sort of thing is unique among the log-like commands in\n>> >> >> builtin/log.c, no command than format-patch will embed the output of\n>> >> >> another log-like command. Since the \"rev->diffopt\" is reused we need\n>> >> >> to munge it before we pass it to show_range_diff(). See\n>> >> >> 43dafc4172 (\"format-patch: don't include --stat with --range-diff\n>> >> >> output\", 2018-11-22) for a related regression fix which is being\n>> >> >> mostly reverted here.\n>> >> >>\n>> >> >> Implementation notes: 1) We're not bothering with the full teardown\n>> >> >> around die() and will leak memory, but it's too much boilerplate to do\n>> >> >> all the frees with/without the die() and not worth it. 2) We call\n>> >> >> repo_init_revisions() for \"rd_rev\" even though we could get away with\n>> >> >> a shallow copy like the code we're replacing (and which\n>> >> >> show_range_diff() itself does). This is to make this code more easily\n>> >> >> understood.\n>> >> >>\n>> >> >> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> >> >> ---\n>> >> >>  Documentation/git-format-patch.txt | 10 ++++++-\n>> >> >>  builtin/log.c                      | 42 +++++++++++++++++++++++-------\n>> >> >>  t/t3206-range-diff.sh              | 41 +++++++++++++++++++++++++++++\n>> >> >>  3 files changed, 82 insertions(+), 11 deletions(-)\n>> >> >>\n>> >> >> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n>> >> >> index aba4c5febe..6c048f415f 100644\n>> >> >> --- a/Documentation/git-format-patch.txt\n>> >> >> +++ b/Documentation/git-format-patch.txt\n>> >> >> @@ -24,7 +24,8 @@ SYNOPSIS\n>> >> >>  \t\t   [--to=<email>] [--cc=<email>]\n>> >> >>  \t\t   [--[no-]cover-letter] [--quiet] [--notes[=<ref>]]\n>> >> >>  \t\t   [--interdiff=<previous>]\n>> >> >> -\t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n>> >> >> +\t\t   [--range-diff=<previous> [--creation-factor=<percent>]\n>> >> >> +\t\t      [--range-diff<common diff option>]]\n>> >> >>  \t\t   [--progress]\n>> >> >>  \t\t   [<common diff options>]\n>> >> >>  \t\t   [ <since> | <revision range> ]\n>> >> >> @@ -257,6 +258,13 @@ feeding the result to `git send-email`.\n>> >> >>  \tcreation/deletion cost fudge factor. See linkgit:git-range-diff[1])\n>> >> >>  \tfor details.\n>> >> >>\n>> >> >> +--range-diff<common diff option>::\n>> >> >> +\tOther options prefixed with `--range-diff` are stripped of\n>> >> >> +\tthat prefix and passed as-is to the diff machinery used to\n>> >> >> +\tgenerate the range-diff, e.g. `--range-diff-U0` and\n>> >> >> +\t`--range-diff--no-color`. This allows for adjusting the format\n>> >> >> +\tof the range-diff independently from the patch itself.\n>> >> >> +\n>> >> >>  --notes[=<ref>]::\n>> >> >>  \tAppend the notes (see linkgit:git-notes[1]) for the commit\n>> >> >>  \tafter the three-dash line.\n>> >> >> diff --git a/builtin/log.c b/builtin/log.c\n>> >> >> index 02d88fa233..7658e56ecc 100644\n>> >> >> --- a/builtin/log.c\n>> >> >> +++ b/builtin/log.c\n>> >> >> @@ -1023,7 +1023,8 @@ static void show_diffstat(struct rev_info *rev,\n>> >> >>  \tfprintf(rev->diffopt.file, \"\\n\");\n>> >> >>  }\n>> >> >>\n>> >> >> -static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>> >> >> +static void make_cover_letter(struct rev_info *rev, struct rev_info *rd_rev,\n>> >> >> +\t\t\t      int use_stdout,\n>> >> >>  \t\t\t      struct commit *origin,\n>> >> >>  \t\t\t      int nr, struct commit **list,\n>> >> >>  \t\t\t      const char *branch_name,\n>> >> >> @@ -1095,13 +1096,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n>> >> >>  \t}\n>> >> >>\n>> >> >>  \tif (rev->rdiff1) {\n>> >> >> -\t\tstruct diff_options opts;\n>> >> >> -\t\tmemcpy(&opts, &rev->diffopt, sizeof(opts));\n>> >> >> -\t\topts.output_format &= ~(DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY);\n>> >> >> -\n>> >> >>  \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n>> >> >>  \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n>> >> >> -\t\t\t\trev->creation_factor, 1, &opts);\n>> >> >> +\t\t\t\trev->creation_factor, 1, &rd_rev->diffopt);\n>> >> >>  \t}\n>> >> >>  }\n>> >> >>\n>> >> >> @@ -1485,6 +1482,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >> >>  \tstruct commit *commit;\n>> >> >>  \tstruct commit **list = NULL;\n>> >> >>  \tstruct rev_info rev;\n>> >> >> +\tstruct rev_info rd_rev;\n>> >> >>  \tstruct setup_revision_opt s_r_opt;\n>> >> >>  \tint nr = 0, total, i;\n>> >> >>  \tint use_stdout = 0;\n>> >> >> @@ -1603,6 +1601,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >> >>  \tinit_log_defaults();\n>> >> >>  \tgit_config(git_format_config, NULL);\n>> >> >>  \trepo_init_revisions(the_repository, &rev, prefix);\n>> >> >> +\trepo_init_revisions(the_repository, &rd_rev, prefix);\n>> >> >>  \trev.commit_format = CMIT_FMT_EMAIL;\n>> >> >>  \trev.expand_tabs_in_log_default = 0;\n>> >> >>  \trev.verbose_header = 1;\n>> >> >> @@ -1689,8 +1688,32 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >> >>  \trev.preserve_subject = keep_subject;\n>> >> >>\n>> >> >>  \targc = setup_revisions(argc, argv, &rev, &s_r_opt);\n>> >> >> -\tif (argc > 1)\n>> >> >> -\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> >> >> +\tif (argc > 1) {\n>> >> >> +\t\tstruct argv_array args = ARGV_ARRAY_INIT;\n>> >> >> +\t\tconst char *prefix = \"--range-diff\";\n>> >> >> +\t\tint have_prefix = 0;\n>> >> >> +\n>> >> >> +\t\tfor (i = 0; i < argc; i++) {\n>> >> >> +\t\t\tstruct strbuf sb = STRBUF_INIT;\n>> >> >> +\t\t\tchar *str;\n>> >> >> +\n>> >> >> +\t\t\tstrbuf_addstr(&sb, argv[i]);\n>> >> >> +\t\t\tif (starts_with(argv[i], prefix)) {\n>> >> >> +\t\t\t\thave_prefix = 1;\n>> >> >> +\t\t\t\tstrbuf_remove(&sb, 0, strlen(prefix));\n>> >> >> +\t\t\t}\n>> >> >> +\t\t\tstr = strbuf_detach(&sb, NULL);\n>> >> >> +\t\t\tstrbuf_release(&sb);\n>> >> >> +\n>> >> >> +\t\t\targv_array_push(&args, str);\n>> >> >> +\t\t}\n>> >> >> +\n>> >> >> +\t\tif (!have_prefix)\n>> >> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> >> >> +\t\targc = setup_revisions(args.argc, args.argv, &rd_rev, NULL);\n>> >> >> +\t\tif (argc > 1)\n>> >> >> +\t\t\tdie(_(\"unrecognized argument: %s\"), argv[1]);\n>> >> >> +\t}\n>> >> >>\n>> >> >>  \tif (rev.diffopt.output_format & DIFF_FORMAT_NAME)\n>> >> >>  \t\tdie(_(\"--name-only does not make sense\"));\n>> >> >> @@ -1702,7 +1725,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >> >>  \tif (!use_patch_format &&\n>> >> >>  \t\t(!rev.diffopt.output_format ||\n>> >> >>  \t\t rev.diffopt.output_format == DIFF_FORMAT_PATCH))\n>> >> >> -\t\t/* Needs to be mirrored in show_range_diff() invocation */\n>> >> >>  \t\trev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;\n>> >> >>  \tif (!rev.diffopt.stat_width)\n>> >> >>  \t\trev.diffopt.stat_width = MAIL_DEFAULT_WRAP;\n>> >> >> @@ -1877,7 +1899,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>> >> >>  \tif (cover_letter) {\n>> >> >>  \t\tif (thread)\n>> >> >>  \t\t\tgen_message_id(&rev, \"cover\");\n>> >> >> -\t\tmake_cover_letter(&rev, use_stdout,\n>> >> >> +\t\tmake_cover_letter(&rev, &rd_rev, use_stdout,\n>> >> >>  \t\t\t\t  origin, nr, list, branch_name, quiet);\n>> >> >>  \t\tprint_bases(&bases, rev.diffopt.file);\n>> >> >>  \t\tprint_signature(rev.diffopt.file);\n>> >> >> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n>> >> >> index bc5facc1cd..6916103888 100755\n>> >> >> --- a/t/t3206-range-diff.sh\n>> >> >> +++ b/t/t3206-range-diff.sh\n>> >> >> @@ -308,6 +308,35 @@ test_expect_success 'format-patch with <common diff option>' '\n>> >> >>  \t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n>> >> >>  \tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n>> >> >>  \tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> >> >> +\t1:  a63e992 ! 1:  d966c5c s/12/B/\n>> >> >> +\t    @@ -8,7 +8,7 @@\n>> >> >> +\t     @@\n>> >> >> +\t      9\n>> >> >> +\t      10\n>> >> >> +\t    - B\n>> >> >> +\t    + BB\n>> >> >> +\t     -12\n>> >> >> +\t     +B\n>> >> >> +\t      13\n>> >> >> +\t-- :\n>> >> >> +\tEOF\n>> >> >> +\ttest_cmp expect actual.range-diff &&\n>> >> >> +\tsed -ne \"/^--- /,/^--/p\" <actual.raw >actual.diff &&\n>> >> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> >> >> +\t--- a/file\n>> >> >> +\t+++ b/file\n>> >> >> +\t@@ -12 +12 @@ BB\n>> >> >> +\t-12\n>> >> >> +\t+B\n>> >> >> +\t-- :\n>> >> >> +\tEOF\n>> >> >> +\ttest_cmp expect actual.diff &&\n>> >> >> +\n>> >> >> +\t# -U0 & --range-diff-U0\n>> >> >> +\tgit format-patch --cover-letter --stdout -U0 --range-diff-U0 \\\n>> >> >> +\t\t--range-diff=topic~..topic changed~..changed >actual.raw &&\n>> >> >> +\tsed -ne \"/^1:/,/^--/p\" <actual.raw >actual.range-diff &&\n>> >> >> +\tsed -e \"s|:$||\" >expect <<-\\EOF &&\n>> >> >>  \t1:  a63e992 ! 1:  d966c5c s/12/B/\n>> >> >>  \t    @@ -11 +11 @@\n>> >> >>  \t    - B\n>> >> >> @@ -327,4 +356,16 @@ test_expect_success 'format-patch with <common diff option>' '\n>> >> >>  \ttest_cmp expect actual.diff\n>> >> >>  '\n>> >> >>\n>> >> >> +test_expect_success 'format-patch option parsing with --range-diff-*' '\n>> >> >> +\ttest_must_fail git format-patch --stdout --unknown \\\n>> >> >> +\t\tmaster..unmodified 2>stderr &&\n>> >> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr &&\n>> >> >> +\ttest_must_fail git format-patch --stdout --range-diff-unknown \\\n>> >> >> +\t\tmaster..unmodified 2>stderr &&\n>> >> >> +\ttest_i18ngrep \"unrecognized argument: --range-diff-unknown\" stderr &&\n>> >> >> +\ttest_must_fail git format-patch --stdout --unknown --range-diff-unknown \\\n>> >> >> +\t\tmaster..unmodified 2>stderr &&\n>> >> >> +\ttest_i18ngrep \"unrecognized argument: --unknown\" stderr\n>> >> >> +'\n>> >> >> +\n>> >> >>  test_done\n>> >> >> --\n>> >> >> 2.20.0.rc1.387.gf8505762e3\n>> >> >>\n>> >> >>\n>> >>\n>>\n"},{"id":"364344","messageId":"nycvar.QRO.7.76.6.1811291713030.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"23552.2773.538601.372248@chiark.greenend.org.uk","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-29T16:14:54Z","receivedAt":"2018-11-29T16:15:05Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ian,\n\nOn Thu, 29 Nov 2018, Ian Jackson wrote:\n\n> Johannes Schindelin writes (\"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)\"):\n> > >  In a successful run with older git I get a reflog like this:\n> > > \n> > >    4833d74 HEAD@{0}: rebase finished: returning to refs/heads/with-preexisting\n> > >    4833d74 HEAD@{1}: debrebase new-upstream 2.1-1: rebase: Add another new upstream file\n> > >    cabd5ec HEAD@{2}: debrebase new-upstream 2.1-1: rebase: Edit the .c file\n> > >    0b362ce HEAD@{3}: debrebase new-upstream 2.1-1: rebase: Add a new upstream file\n> > >    29653e5 HEAD@{4}: debrebase new-upstream 2.1-1: rebase: checkout 29653e5a17bee4ac23a68bba3e12bc1f52858ac3\n> > >    85e0c46 HEAD@{5}: debrebase: launder for new upstream\n> ...\n> > >  This breaks the test because my test suite is checking that I set\n> > >  GIT_REFLOG_ACTION appropriately.\n> > > \n> > >  If you want I can provide a minimal test case but this should suffice\n> > >  to see the bug I hope...\n> > \n> > This should be plenty for me to get going. Thank you!\n> \n> Happy hunting.\n\nI'll have to take a (lengthy) dinner break now, but this is what I have so\nfar: a regression test that verifies the breakage (see the\n`fix-reflog-action` branch at https://github.com/dscho/git). I'll continue\nafter dinner and am confident that this bug will be fixed within the next\nfour hours.\n\n> While you're looking at this, I observe that the fact that the `rebase\n> finished' message also does not honour GIT_REFLOG_ACTION appears to be\n> a pre-existing bug.\n\nI noticed that, too, but at this point I am only fixing regressions. We\ncan try to fix this long-standing bug in the v2.20 cycle.\n\nCiao,\nJohannes\n\n> (In general one often can't rely on GIT_REFLOG_ACTION still being set\n> because the rebase might have been interrupted and restarted, which I\n> think is why my test case looks for it in the initial `checkout'\n> message.)\n> \n> Regards,\n> Ian.\n> \n> -- \n> Ian Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.\n> \n> If I emailed you from an address @fyvzl.net or @evade.org.uk, that is\n> a private address which bypasses my fierce spamfilter.\n> \n"},{"id":"364345","messageId":"23552.4898.603829.719325@chiark.greenend.org.uk","threadId":"49877","inReplyTo":"nycvar.QRO.7.76.6.1811291713030.41@tvgsbejvaqbjf.bet","subject":"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)","fromName":"Ian Jackson","fromEmail":"ijackson@chiark.greenend.org.uk","sentAt":"2018-11-29T16:26:10Z","receivedAt":"2018-11-29T16:26:15Z","isPatch":true,"sender":{"key":"ijackson@chiark.greenend.org.uk","avatar":null},"body":"Johannes Schindelin writes (\"Re: [PATCH] rebase: mark the C reimplementation as an experimental opt-in feature (was Re: [ANNOUNCE] Git v2.20.0-rc1)\"):\n> I'll have to take a (lengthy) dinner break now, but this is what I have so\n> far: a regression test that verifies the breakage (see the\n> `fix-reflog-action` branch at https://github.com/dscho/git). I'll continue\n> after dinner and am confident that this bug will be fixed within the next\n> four hours.\n\nThat seems super speedy to me!\n\nWhen you have a fix I will leave it up to the Debian git maintainers\nto decide whether they want to cherry pick your fix into their\npackage, or await an updated upstream branch with rc, or what.\n\n> [Ian:]\n> > While you're looking at this, I observe that the fact that the `rebase\n> > finished' message also does not honour GIT_REFLOG_ACTION appears to be\n> > a pre-existing bug.\n> \n> I noticed that, too, but at this point I am only fixing regressions. We\n> can try to fix this long-standing bug in the v2.20 cycle.\n\nRight.\n\nThanks,\nIan.\n\n-- \nIan Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.\n\nIf I emailed you from an address @fyvzl.net or @evade.org.uk, that is\na private address which bypasses my fierce spamfilter.\n"},{"id":"364349","messageId":"nycvar.QRO.7.76.6.1811291958500.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"87tvjzyiph.fsf@evledraar.gmail.com","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-29T19:03:51Z","receivedAt":"2018-11-29T19:04:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n\n> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n> \n> > On Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n> >\n> >> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n> >>\n> >> > On Thu, 29 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n> >> >\n> >> >> On Thu, Nov 29 2018, Johannes Schindelin wrote:\n> >> >>\n> >> >> > On Wed, 28 Nov 2018, Ævar Arnfjörð Bjarmason wrote:\n> >> >> >\n> >> >> >> Change the semantics of the \"--range-diff\" option so that the regular\n> >> >> >> diff options can be provided separately for the range-diff and the\n> >> >> >> patch. This allows for supplying e.g. --range-diff-U0 and -U1 to\n> >> >> >> \"format-patch\" to provide different context for the range-diff and the\n> >> >> >> patch. This wasn't possible before.\n> >> >> >\n> >> >> > I really, really dislike the `--range-diff-<random-thing>`. We have\n> >> >> > precedent for passing optional arguments that are passed to some other\n> >> >> > command, so a much more logical and consistent convention would be to use\n> >> >> > `--range-diff[=<diff-option>..]`, allowing all of the diff options that\n> >> >> > you might want to pass to the outer diff in one go rather than having a\n> >> >> > lengthy string of `--range-diff-this` and `--range-diff-that` options.\n> >> >>\n> >> >> Where do we pass those sorts of arguments?\n> >> >>\n> >> >> Reasons I did it this way:\n> >> >>\n> >> >>  a) Passing it as one option will require the user to double-quote those\n> >> >>     options that take quoted arguments (e.g. --word-diff-regex), which I\n> >> >>     thought sucked more than the prefix. On the implementation side we\n> >> >>     couldn't leave the parsing of the command-line to the shell anymore.\n> >> >>\n> >> >>  b) I think people will want to tweak this very rarely, much more rarely\n> >> >>     than e.g. -U10 in format-patch itself, so having something long-ish\n> >> >>     doesn't sound bad.\n> >> >\n> >> > Hmm. I still don't like it. It sets a precedent, and we simply do not do\n> >> > it that way in other circumstances (most obvious would be the -X merge\n> >> > options). The more divergent user interfaces for the same sort of thing\n> >> > are, the more brain cycles you force users to spend on navigating said\n> >> > interfaces.\n> >>\n> >> Yeah it sucks, I just think it sucks less than the alternative :)\n> >> I.e. I'm not picky about --range-diff-* prefix the name, but I think\n> >> doing our own shell parsing would be nasty.\n> >\n> > What prevents you from using `sq_dequote_to_argv()`?\n> \n> I mean not just nasty in terms of implementation, yeah we could do it,\n> but also a nasty UX for things like --word-diff-regex. I.e. instead of:\n> \n>     --range-diff-word-diff-regex='[0-9\"]'\n> \n> You need:\n> \n>     --range-diff-opts=\"--word-diff-regex='[0-9\\\"]'\"\n\nReally? I think that would not work. It would pass the single quotes as\npart of the regex to the diff machinery.\n\nOr maybe not. But the extra quotes do not strike me as necessary, as there\nis no shell script involved (thank deity!) after `git range-diff` parsed\nthe options.\n\n> Now admittedly that in itself isn't very painful *in this case*, but in\n> terms of precedent I really dislike that option, i.e. git having some\n> mode where I need to work to escape input to pass to another command.\n> \n> Not saying that this --range-diff-* thing is what we should go for, but\n> surely we can find some way to do deal with this that doesn't involve\n> the user needing to escape stuff like this.\n> \n> It also has other downstream effects in the UI, e.g. it's presumably\n> easy to teach the bash completion that a --foo=XYZ option is also called\n> --some-prefix--foo=XYZ and to enable completion for that, less so for\n> making it smart enough to complete \"--some-prefix-opts=\"--foo=<TAB>\".\n\nThese are all good points, and need proper discussion.\n\nSadly, all that time needed for a proper discussion is not left before\nv2.20.0 is supposed to come out.\n\nQuite honestly, I think what we will have to do is to describe in the\ndocumentation of `format-patch`'s `--range-diff` option that the exact\nuser interface how to pass diff options down to `range-diff` is in flux\nand not final.\n\nThat way, we can give your design the proper treatment, and work together\non making a user interface we all can be happy with.\n\nCiao,\nDscho"},{"id":"364378","messageId":"xmqq7egvmh54.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"87tvjzyiph.fsf@evledraar.gmail.com","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-30T02:30:15Z","receivedAt":"2018-11-30T02:30:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n>> What prevents you from using `sq_dequote_to_argv()`?\n>\n> I mean not just nasty in terms of implementation, yeah we could do it,\n> but also a nasty UX for things like --word-diff-regex. I.e. instead of:\n>\n>     --range-diff-word-diff-regex='[0-9\"]'\n>\n> You need:\n>\n>     --range-diff-opts=\"--word-diff-regex='[0-9\\\"]'\"\n>\n> Now admittedly that in itself isn't very painful *in this case*, but in\n> terms of precedent I really dislike that option, i.e. git having some\n> mode where I need to work to escape input to pass to another command.\n\nIn addition, sq_dequote are meant to be used on quoted string we\ninternally produce; I do not think we want to promise that it is\nsafe to use on a random string that comes from end users.\n\nIn any case, I tend to agree with the conclusion in the downthread\nby Dscho that we should just clearly mark that invocations of the\n\"format-patch --range-diff\" command with additional diff options is\nan experimental feature that may not do anything sensible in the\nupcoming release, and declare that the UI to pass diff options to\naffect only the range-diff part may later be invented.  IOW, I am\ncoming a bit stronger than Dscho's suggestion in that we should not\neven pretend that we aimed to make the options used for range-diff\ncustomizable when driven from format-patch in the upcoming release,\nor aimed to make --range-diff option compatible with other diff\noptions given to the format-patch command.\n\nI had to delay -rc2 to see these last minute tweaks come to some\nreasonable place to stop at, and I do not think we want to delay the\nfinal any longer or destablizing it further by piling last minute\nundercooked changes on top.\n"},{"id":"364380","messageId":"xmqqwoovkx5s.fsf_-_@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"xmqq7egvmh54.fsf@gitster-ct.c.googlers.com","subject":"[PATCH] format-patch: do not let its diff-options affect --range-diff (was Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-30T04:27:11Z","receivedAt":"2018-11-30T04:27:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> In any case, I tend to agree with the conclusion in the downthread\n> by Dscho that we should just clearly mark that invocations of the\n> \"format-patch --range-diff\" command with additional diff options is\n> an experimental feature that may not do anything sensible in the\n> upcoming release, and declare that the UI to pass diff options to\n> affect only the range-diff part may later be invented.  IOW, I am\n> coming a bit stronger than Dscho's suggestion in that we should not\n> even pretend that we aimed to make the options used for range-diff\n> customizable when driven from format-patch in the upcoming release,\n> or aimed to make --range-diff option compatible with other diff\n> options given to the format-patch command.\n>\n> I had to delay -rc2 to see these last minute tweaks come to some\n> reasonable place to stop at, and I do not think we want to delay the\n> final any longer or destablizing it further by piling last minute\n> undercooked changes on top.\n\nSo how about doing this on top of 'master' instead?  As this leaks\n*no* information wrt how range-diff machinery should behave from the\nformat-patch side by not passing any diffopt, as long as the new\ncode I added to show_range_diff() comes up with a reasonable default\ndiffopts (for which I really would appreciate extra sets of eyes to\nmake sure), this change by definition cannot be wrong (famous last\nwords).\n\n-- >8 --\nSubject: format-patch: do not let its diff-options affect --range-diff\n\nStop leaking how the primary output of format-patch is customized to\nthe range-diff machinery and instead let the latter use its own\n\"reasonable default\", in order to correct the breakage introduced by\na5170794 (\"Merge branch 'ab/range-diff-no-patch'\", 2018-11-18) on\nthe 'master' front.  \"git format-patch --range-diff...\" without any\nweird diff option started to include the \"range-diff --stat\" output,\nwhich is rather useless right now, that made the whole thing\nunusable and this is probably the least disruptive way to whip the\ncodebase into a shippable shape.\n\nWe may want to later make the range-diff driven by format-patch more\nconfigurable, but that would have to wait until we have a good\ndesign.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-format-patch.txt | 5 +++++\n builtin/log.c                      | 2 +-\n log-tree.c                         | 2 +-\n range-diff.c                       | 6 +++++-\n range-diff.h                       | 5 +++++\n 5 files changed, 17 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex aba4c5febe..27304428a1 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -250,6 +250,11 @@ feeding the result to `git send-email`.\n \tfeature/v2`), or a revision range if the two versions of the series are\n \tdisjoint (for example `git format-patch --cover-letter\n \t--range-diff=feature/v1~3..feature/v1 -3 feature/v2`).\n++\n+Note that diff options passed to the command affect how the primary\n+product of `format-patch` is generated, and they are not passed to\n+the underlying `range-diff` machinery used to generate the cover-letter\n+material (this may change in the future).\n \n --creation-factor=<percent>::\n \tUsed with `--range-diff`, tweak the heuristic which matches up commits\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 0fe6f9ba1e..5ac18e2848 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1096,7 +1096,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \tif (rev->rdiff1) {\n \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n-\t\t\t\trev->creation_factor, 1, &rev->diffopt);\n+\t\t\t\trev->creation_factor, 1, NULL);\n \t}\n }\n \ndiff --git a/log-tree.c b/log-tree.c\nindex 7a83e99250..b243779a0b 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -762,7 +762,7 @@ void show_log(struct rev_info *opt)\n \t\tnext_commentary_block(opt, NULL);\n \t\tfprintf_ln(opt->diffopt.file, \"%s\", opt->rdiff_title);\n \t\tshow_range_diff(opt->rdiff1, opt->rdiff2,\n-\t\t\t\topt->creation_factor, 1, &opt->diffopt);\n+\t\t\t\topt->creation_factor, 1, NULL);\n \n \t\tmemcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));\n \t}\ndiff --git a/range-diff.c b/range-diff.c\nindex 767af8c5bb..8e52a85c19 100644\n--- a/range-diff.c\n+++ b/range-diff.c\n@@ -460,7 +460,11 @@ int show_range_diff(const char *range1, const char *range2,\n \t\tstruct diff_options opts;\n \t\tstruct strbuf indent = STRBUF_INIT;\n \n-\t\tmemcpy(&opts, diffopt, sizeof(opts));\n+\t\tif (diffopt)\n+\t\t\tmemcpy(&opts, diffopt, sizeof(opts));\n+\t\telse\n+\t\t\trepo_diff_setup(the_repository, &opts);\n+\n \t\tif (!opts.output_format)\n \t\t\topts.output_format = DIFF_FORMAT_PATCH;\n \t\topts.flags.suppress_diff_headers = 1;\ndiff --git a/range-diff.h b/range-diff.h\nindex 190593f0c7..08a50b6e98 100644\n--- a/range-diff.h\n+++ b/range-diff.h\n@@ -5,6 +5,11 @@\n \n #define RANGE_DIFF_CREATION_FACTOR_DEFAULT 60\n \n+/*\n+ * Compare series of commmits in RANGE1 and RANGE2, and emit to the\n+ * standard output.  NULL can be passed to DIFFOPT to use the built-in\n+ * default.\n+ */\n int show_range_diff(const char *range1, const char *range2,\n \t\t    int creation_factor, int dual_color,\n \t\t    struct diff_options *diffopt);\n\n\n"},{"id":"364386","messageId":"xmqq36rjkkn7.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"xmqqwoovkx5s.fsf_-_@gitster-ct.c.googlers.com","subject":"Re: [PATCH] format-patch: do not let its diff-options affect --range-diff (was Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-30T08:57:32Z","receivedAt":"2018-11-30T08:57:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> I had to delay -rc2 to see these last minute tweaks come to some\n>> reasonable place to stop at, and I do not think we want to delay the\n>> final any longer or destablizing it further by piling last minute\n>> undercooked changes on top.\n>\n> So how about doing this on top of 'master' instead?  As this leaks\n> *no* information wrt how range-diff machinery should behave from the\n> format-patch side by not passing any diffopt, as long as the new\n> code I added to show_range_diff() comes up with a reasonable default\n> diffopts (for which I really would appreciate extra sets of eyes to\n> make sure), this change by definition cannot be wrong (famous last\n> words).\n\nAs listed in today's \"What's cooking\" report, I've merged this to\n'next' in today's pushout and planning to have it in the -rc2.  I am\nnot married to this exact implementation, and I'd welcome to have an\neven simpler and less disruptive solution if exists, but I am hoping\nthat this is a good-enough interim measure for the upcoming release,\nuntil we decide what to do with the customizability of range-diff\ndriven by format-patch.\n\nIn addition to this, I am planning the \"rebase --stat\" and \"reflog\nthat does not say 'rebase -i' but 'rebase'\" fixes merged to 'master'\nbefore cutting -rc2.\n\n"},{"id":"364388","messageId":"871s72x6iw.fsf@evledraar.gmail.com","threadId":"49877","inReplyTo":"xmqq36rjkkn7.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH] format-patch: do not let its diff-options affect --range-diff (was Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options)","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-30T09:24:07Z","receivedAt":"2018-11-30T09:24:13Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Nov 30 2018, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>>> I had to delay -rc2 to see these last minute tweaks come to some\n>>> reasonable place to stop at, and I do not think we want to delay the\n>>> final any longer or destablizing it further by piling last minute\n>>> undercooked changes on top.\n>>\n>> So how about doing this on top of 'master' instead?  As this leaks\n>> *no* information wrt how range-diff machinery should behave from the\n>> format-patch side by not passing any diffopt, as long as the new\n>> code I added to show_range_diff() comes up with a reasonable default\n>> diffopts (for which I really would appreciate extra sets of eyes to\n>> make sure), this change by definition cannot be wrong (famous last\n>> words).\n>\n> As listed in today's \"What's cooking\" report, I've merged this to\n> 'next' in today's pushout and planning to have it in the -rc2.  I am\n> not married to this exact implementation, and I'd welcome to have an\n> even simpler and less disruptive solution if exists, but I am hoping\n> that this is a good-enough interim measure for the upcoming release,\n> until we decide what to do with the customizability of range-diff\n> driven by format-patch.\n>\n> In addition to this, I am planning the \"rebase --stat\" and \"reflog\n> that does not say 'rebase -i' but 'rebase'\" fixes merged to 'master'\n> before cutting -rc2.\n\nThanks a lot, yeah having this wait looks good to me.\n"},{"id":"364389","messageId":"CAPig+cS4peHDOz0cK7RJEHb6ch0+czvau_aGTD1j6xM23G0-pQ@mail.gmail.com","threadId":"49877","inReplyTo":"xmqqwoovkx5s.fsf_-_@gitster-ct.c.googlers.com","subject":"Re: [PATCH] format-patch: do not let its diff-options affect --range-diff (was Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options)","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-11-30T09:31:46Z","receivedAt":"2018-11-30T09:32:00Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Nov 29, 2018 at 11:27 PM Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n> > In any case, I tend to agree with the conclusion in the downthread\n> > by Dscho that we should just clearly mark that invocations of the\n> > \"format-patch --range-diff\" command with additional diff options is\n> > an experimental feature that may not do anything sensible in the\n> > upcoming release, and declare that the UI to pass diff options to\n> > affect only the range-diff part may later be invented.  IOW, I am\n> > coming a bit stronger than Dscho's suggestion in that we should not\n> > even pretend that we aimed to make the options used for range-diff\n> > customizable when driven from format-patch in the upcoming release,\n> > or aimed to make --range-diff option compatible with other diff\n> > options given to the format-patch command.\n\nI agree that this way forward makes sense. It's clear that I\noverlooked how there could be unexpected interactions from passing\ngit-format-patch's own diff_options to show_range_diff(), so taking\ntime to think it through without the pressure of a looming release is\npreferable to rushing out some \"fixes\".\n\n> So how about doing this on top of 'master' instead?  As this leaks\n> *no* information wrt how range-diff machinery should behave from the\n> format-patch side by not passing any diffopt, as long as the new\n> code I added to show_range_diff() comes up with a reasonable default\n> diffopts (for which I really would appreciate extra sets of eyes to\n> make sure), this change by definition cannot be wrong (famous last\n> words).\n\nI, myself, was going to suggest this approach of leaking none of the\ngit-format-patch's options into range_diff(), so I think it is a good\none. Later, we can selectively pass certain _sensible_ options into\nshow_range_diff() once we figure out the correct UI (for instance,\n--range-diff-opts=nopatch,creation-factor:60).\n\nA couple comments on the patch itself...\n\n> diff --git a/range-diff.c b/range-diff.c\n> @@ -460,7 +460,11 @@ int show_range_diff(const char *range1, const char *range2,\n> -               memcpy(&opts, diffopt, sizeof(opts));\n> +               if (diffopt)\n> +                       memcpy(&opts, diffopt, sizeof(opts));\n> +               else\n> +                       repo_diff_setup(the_repository, &opts);\n\nThe first attempt at adding --range-diff to git-format-patch invoked\nthe git-range-diff command, so no diff_options were passed at all.\nAfter Dscho libified the range-diff machinery in one of his major\nre-rolls, I took advantage of that to avoid the subprocess invocation.\nAnother benefit of calling show_range_diff() directly is that when\n\"git format-patch --stdout --range-diff=...\" is sent to the terminal,\nthe range-diff gets colored output for free. I'm pleased to see that\nthat still works after this change.\n\n> diff --git a/range-diff.h b/range-diff.h\n> @@ -5,6 +5,11 @@\n> +/*\n> + * Compare series of commmits in RANGE1 and RANGE2, and emit to the\n> + * standard output.  NULL can be passed to DIFFOPT to use the built-in\n> + * default.\n> + */\n\nIt is more correct to say that the range-diff is emitted to\ndiffopt->file (which may be stdout).\n\nThanks for working on this.\n"},{"id":"364390","messageId":"CAPig+cQYbuySiWNbDevjRs7rvwy-HBXvfj2fkCWnV+JGkVD6pQ@mail.gmail.com","threadId":"49877","inReplyTo":"87tvjzyiph.fsf@evledraar.gmail.com","subject":"Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-11-30T09:58:05Z","receivedAt":"2018-11-30T09:58:18Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Nov 29, 2018 at 11:03 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> I mean not just nasty in terms of implementation, yeah we could do it,\n> but also a nasty UX for things like --word-diff-regex. I.e. instead of:\n>\n>     --range-diff-word-diff-regex='[0-9\"]'\n>\n> You need:\n>\n>     --range-diff-opts=\"--word-diff-regex='[0-9\\\"]'\"\n>\n> Now admittedly that in itself isn't very painful *in this case*, but in\n> terms of precedent I really dislike that option, i.e. git having some\n> mode where I need to work to escape input to pass to another command.\n>\n> Not saying that this --range-diff-* thing is what we should go for, but\n> surely we can find some way to do deal with this that doesn't involve\n> the user needing to escape stuff like this.\n\nI should mention that it was never the intention that\ngit-format-patch's --range-diff option would allow passing _all_\npossible options to git-range-diff, but only those most likely to be\ntweaked by the user (such as --creation-factor). It was understood\nfrom the start (and stated by me either in the cover letter to that\nseries or in discussion) that the user always has the escape hatch of\nrunning git-range-diff manually and copy/pasting its output into the\ncover letter.\n\nSo, I'm not convinced that we need this sort of flexibility in\ngit-format-patch's --range-diff option, but we certainly can add\nconvenience options (such as I did with --creation-factor) as people\ncomplain that their favorite option is missing. For a UI, I think we\nalready have sufficient precedent for\n\"--range-diff-opts=nopatch,creation-factor:60\" as a possibility.\n"},{"id":"364393","messageId":"nycvar.QRO.7.76.6.1811301331320.41@tvgsbejvaqbjf.bet","threadId":"49877","inReplyTo":"xmqq36rjkkn7.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH] format-patch: do not let its diff-options affect --range-diff (was Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-11-30T12:32:33Z","receivedAt":"2018-11-30T12:32:57Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Fri, 30 Nov 2018, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n> >> I had to delay -rc2 to see these last minute tweaks come to some\n> >> reasonable place to stop at, and I do not think we want to delay the\n> >> final any longer or destablizing it further by piling last minute\n> >> undercooked changes on top.\n> >\n> > So how about doing this on top of 'master' instead?  As this leaks\n> > *no* information wrt how range-diff machinery should behave from the\n> > format-patch side by not passing any diffopt, as long as the new\n> > code I added to show_range_diff() comes up with a reasonable default\n> > diffopts (for which I really would appreciate extra sets of eyes to\n> > make sure), this change by definition cannot be wrong (famous last\n> > words).\n> \n> As listed in today's \"What's cooking\" report, I've merged this to\n> 'next' in today's pushout and planning to have it in the -rc2.  I am\n> not married to this exact implementation, and I'd welcome to have an\n> even simpler and less disruptive solution if exists, but I am hoping\n> that this is a good-enough interim measure for the upcoming release,\n> until we decide what to do with the customizability of range-diff\n> driven by format-patch.\n> \n> In addition to this, I am planning the \"rebase --stat\" and \"reflog\n> that does not say 'rebase -i' but 'rebase'\" fixes merged to 'master'\n> before cutting -rc2.\n\nThank you for integrating them. That way, we have an -rc2 with no issues\nin the built-in rebase/rebase -i that we know of.\n\nCiao,\nDscho\n"},{"id":"364465","messageId":"CAN0heSrfH39-37KDU3XDhxiYs1_3eUMdjbdAm37cPAmnOYUZMA@mail.gmail.com","threadId":"49877","inReplyTo":"CAPig+cS4peHDOz0cK7RJEHb6ch0+czvau_aGTD1j6xM23G0-pQ@mail.gmail.com","subject":"Re: [PATCH] format-patch: do not let its diff-options affect --range-diff (was Re: [PATCH 2/2] format-patch: allow for independent diff & range-diff options)","fromName":"Martin Ågren","fromEmail":"martin.agren@gmail.com","sentAt":"2018-12-03T13:27:49Z","receivedAt":"2018-12-03T13:28:06Z","isPatch":true,"sender":{"key":"martin.agren@gmail.com","avatar":null},"body":"On Fri, 30 Nov 2018 at 10:32, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>\n> On Thu, Nov 29, 2018 at 11:27 PM Junio C Hamano <gitster@pobox.com> wrote:\n> > Junio C Hamano <gitster@pobox.com> writes:\n> > So how about doing this on top of 'master' instead?  As this leaks\n> > *no* information wrt how range-diff machinery should behave from the\n> > format-patch side by not passing any diffopt, as long as the new\n> > code I added to show_range_diff() comes up with a reasonable default\n> > diffopts (for which I really would appreciate extra sets of eyes to\n> > make sure), this change by definition cannot be wrong (famous last\n> > words).\n\n> Another benefit of calling show_range_diff() directly is that when\n> \"git format-patch --stdout --range-diff=...\" is sent to the terminal,\n> the range-diff gets colored output for free. I'm pleased to see that\n> that still works after this change.\n\n(If the patch below makes any sense to you and you know more about this\ndiff/color thing, the fourth bullet in the log message below might\ninterest you.)\n\n> > diff --git a/range-diff.h b/range-diff.h\n> > @@ -5,6 +5,11 @@\n> > +/*\n> > + * Compare series of commmits in RANGE1 and RANGE2, and emit to the\n> > + * standard output.  NULL can be passed to DIFFOPT to use the built-in\n> > + * default.\n> > + */\n>\n> It is more correct to say that the range-diff is emitted to\n> diffopt->file (which may be stdout).\n\nThis seems to be an important remark. There's a pretty bad regression\nhere since when `diffopt` is NULL, we've lost our original, intended\n`diffopt->file` and the range-diff ends up on stdout.\n\nHere's my whitespace-damaged WIP. I would be able to pick this up again\nin about 6h, but anyone is more than welcome to pick this up and run\nwith it in the meantime.\n\nThis is not a corner of the code that I'm particularly familiar with...\n\n-->8--\nSubject: [PATCH] range-diff: always pass at least minimal diff options\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\n\nCommit d8981c3f88 (\"format-patch: do not let its diff-options affect\n--range-diff\", 2018-11-30) taught `show_range_diff()` to accept a\nNULL-pointer as an indication that it should use its own \"reasonable\ndefault\". That fixed a regression from a5170794 (\"Merge branch\n'ab/range-diff-no-patch'\", 2018-11-18), but unfortunately it introduced\na regression of its own.\n\nIn particular, it means we forget the `file` member of the diff options,\nso rather than placing a range-diff in the cover-letter, we write it to\nstdout. In order to fix this, rewrite the two callers adjusted by\nd8981c3f88 to create a \"dummy\" set of diff options where they only fill\nin which file to use.\n\nA couple of remarks about this commit:\n\n  * No tests. The change in builtin/log.c has been tested manually, the\n    one in log-tree.c not at all, other than by running existing tests.\n\n  * I have not convinced myself 100% that there aren't other things that\n    are just as important as `file` to pass down.\n\n  * `show_range_diff()` can still take NULL, although that is now dead\n    code. If something like this here commit is deemed the proper fix\n    for this, that code path could also go, either as part of this\n    commit, or separately, once we've cut 2.20.\n\n  * The range-diff is written colored regardless of destination, i.e.,\n    when written to a file, it contains garbage.\n\nSigned-off-by: Martin Ågren <martin.agren@gmail.com>\n---\n builtin/log.c | 12 +++++++++++-\n log-tree.c    | 12 +++++++++++-\n 2 files changed, 22 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 5ac18e2848..0609e41ae5 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1094,9 +1094,19 @@ static void make_cover_letter(struct rev_info\n*rev, int use_stdout,\n     }\n\n     if (rev->rdiff1) {\n+        /**\n+         * (At least for now) we only want to pass down\n+         * the file handle where we want the range-diff\n+         * to appear. Avoid any other diff options until\n+         * we know how we want to handle them.\n+         */\n+        struct diff_options opts;\n+        diff_setup(&opts);\n+        opts.file = rev->diffopt.file;\n+        diff_setup_done(&opts);\n         fprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n         show_range_diff(rev->rdiff1, rev->rdiff2,\n-                rev->creation_factor, 1, NULL);\n+                rev->creation_factor, 1, &opts);\n     }\n }\n\ndiff --git a/log-tree.c b/log-tree.c\nindex b243779a0b..bc355a4e91 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -755,14 +755,24 @@ void show_log(struct rev_info *opt)\n\n     if (cmit_fmt_is_mail(ctx.fmt) && opt->rdiff1) {\n         struct diff_queue_struct dq;\n+        struct diff_options opts;\n\n         memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));\n         DIFF_QUEUE_CLEAR(&diff_queued_diff);\n\n         next_commentary_block(opt, NULL);\n         fprintf_ln(opt->diffopt.file, \"%s\", opt->rdiff_title);\n+        /**\n+         * (At least for now) we only want to pass down\n+         * the file handle where we want the range-diff\n+         * to appear. Avoid any other diff options until\n+         * we know how we want to handle them.\n+        */\n+        diff_setup(&opts);\n+        opts.file = opt->diffopt.file;\n+        diff_setup_done(&opts);\n         show_range_diff(opt->rdiff1, opt->rdiff2,\n-                opt->creation_factor, 1, NULL);\n+                opt->creation_factor, 1, &opts);\n\n         memcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));\n     }\n-- \n2.20.0.rc2\n"},{"id":"364475","messageId":"20181203200734.527341-1-martin.agren@gmail.com","threadId":"49877","inReplyTo":"CAN0heSrfH39-37KDU3XDhxiYs1_3eUMdjbdAm37cPAmnOYUZMA@mail.gmail.com","subject":"[PATCH v2] range-diff: always pass at least minimal diff options","fromName":"Martin Ågren","fromEmail":"martin.agren@gmail.com","sentAt":"2018-12-03T20:07:34Z","receivedAt":"2018-12-03T20:08:24Z","isPatch":true,"sender":{"key":"martin.agren@gmail.com","avatar":null},"body":"Commit d8981c3f88 (\"format-patch: do not let its diff-options affect\n--range-diff\", 2018-11-30) taught `show_range_diff()` to accept a\nNULL-pointer as an indication that it should use its own \"reasonable\ndefault\". That fixed a regression from a5170794 (\"Merge branch\n'ab/range-diff-no-patch'\", 2018-11-18), but unfortunately it introduced\na regression of its own.\n\nIn particular, it means we forget the `file` member of the diff options,\nso rather than placing a range-diff in the cover-letter, we write it to\nstdout. In order to fix this, rewrite the two callers adjusted by\nd8981c3f88 to instead create a \"dummy\" set of diff options where they\nonly fill in which file to use.\n\nPlus, turn off coloring to make sure we don't write any color codes.\nMaybe we could do `opts.use_color = opts.file != stdout`, but for now,\nI'd much rather always write uncolored output than write color codes\nwhere there shouldn't be any.\n\nModify and extend the existing tests to try and verify that the right\ncontents end up in the right place.\n\nDon't revert `show_range_diff()`, i.e., let it keep accepting NULL.\nRather than removing what is dead code and figuring out it isn't\nactually dead and we've broken 2.20, just leave it for now.\n\nSigned-off-by: Martin Ågren <martin.agren@gmail.com>\n---\nHere's another attempt at fixing this recent regression.\n\n t/t3206-range-diff.sh | 20 +++++++++++++-------\n builtin/log.c         | 13 ++++++++++++-\n log-tree.c            | 13 ++++++++++++-\n 3 files changed, 37 insertions(+), 9 deletions(-)\n\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex e497c1358f..048feaf6dd 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -248,18 +248,24 @@ test_expect_success 'dual-coloring' '\n for prev in topic master..topic\n do\n \ttest_expect_success \"format-patch --range-diff=$prev\" '\n-\t\tgit format-patch --stdout --cover-letter --range-diff=$prev \\\n+\t\tgit format-patch --cover-letter --range-diff=$prev \\\n \t\t\tmaster..unmodified >actual &&\n-\t\tgrep \"= 1: .* s/5/A\" actual &&\n-\t\tgrep \"= 2: .* s/4/A\" actual &&\n-\t\tgrep \"= 3: .* s/11/B\" actual &&\n-\t\tgrep \"= 4: .* s/12/B\" actual\n+\t\ttest_when_finished \"rm 000?-*\" &&\n+\t\ttest_line_count = 5 actual &&\n+\t\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\t\tgrep \"= 1: .* s/5/A\" 0000-* &&\n+\t\tgrep \"= 2: .* s/4/A\" 0000-* &&\n+\t\tgrep \"= 3: .* s/11/B\" 0000-* &&\n+\t\tgrep \"= 4: .* s/12/B\" 0000-*\n \t'\n done\n \n test_expect_success 'format-patch --range-diff as commentary' '\n-\tgit format-patch --stdout --range-diff=HEAD~1 HEAD~1 >actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" actual\n+\tgit format-patch --range-diff=HEAD~1 HEAD~1 >actual &&\n+\ttest_when_finished \"rm 0001-*\" &&\n+\ttest_line_count = 1 actual &&\n+\ttest_i18ngrep \"^Range-diff:$\" 0001-* &&\n+\tgrep \"> 1: .* new message\" 0001-*\n '\n \n test_done\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 5ac18e2848..e42487b46d 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1094,9 +1094,20 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \t}\n \n \tif (rev->rdiff1) {\n+\t\t/*\n+\t\t * (At least for now) we only want to pass down\n+\t\t * the file handle where we want the range-diff\n+\t\t * to appear. Avoid any other diff options until\n+\t\t * we know how we want to handle them.\n+\t\t */\n+\t\tstruct diff_options opts;\n+\t\tdiff_setup(&opts);\n+\t\topts.file = rev->diffopt.file;\n+\t\topts.use_color = 0;\n+\t\tdiff_setup_done(&opts);\n \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n-\t\t\t\trev->creation_factor, 1, NULL);\n+\t\t\t\trev->creation_factor, 1, &opts);\n \t}\n }\n \ndiff --git a/log-tree.c b/log-tree.c\nindex b243779a0b..fd79a3ec37 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -755,14 +755,25 @@ void show_log(struct rev_info *opt)\n \n \tif (cmit_fmt_is_mail(ctx.fmt) && opt->rdiff1) {\n \t\tstruct diff_queue_struct dq;\n+\t\tstruct diff_options opts;\n \n \t\tmemcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));\n \t\tDIFF_QUEUE_CLEAR(&diff_queued_diff);\n \n \t\tnext_commentary_block(opt, NULL);\n \t\tfprintf_ln(opt->diffopt.file, \"%s\", opt->rdiff_title);\n+\t\t/*\n+\t\t * (At least for now) we only want to pass down\n+\t\t * the file handle where we want the range-diff\n+\t\t * to appear. Avoid any other diff options until\n+\t\t * we know how we want to handle them.\n+\t\t */\n+\t\tdiff_setup(&opts);\n+\t\topts.file = opt->diffopt.file;\n+\t\topts.use_color = 0;\n+\t\tdiff_setup_done(&opts);\n \t\tshow_range_diff(opt->rdiff1, opt->rdiff2,\n-\t\t\t\topt->creation_factor, 1, NULL);\n+\t\t\t\topt->creation_factor, 1, &opts);\n \n \t\tmemcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));\n \t}\n-- \n2.20.0.rc2.1.gfcc5f94f1e\n\n"},{"id":"364485","messageId":"20181203212131.11299-1-sunshine@sunshineco.com","threadId":"49877","inReplyTo":"20181203200734.527341-1-martin.agren@gmail.com","subject":"[PATCH v3] range-diff: always pass at least minimal diff options","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-12-03T21:21:31Z","receivedAt":"2018-12-03T21:22:00Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"From: Martin Ågren <martin.agren@gmail.com>\n\nCommit d8981c3f88 (\"format-patch: do not let its diff-options affect\n--range-diff\", 2018-11-30) taught `show_range_diff()` to accept a\nNULL-pointer as an indication that it should use its own \"reasonable\ndefault\". That fixed a regression from a5170794 (\"Merge branch\n'ab/range-diff-no-patch'\", 2018-11-18), but unfortunately it introduced\na regression of its own.\n\nIn particular, it means we forget the `file` member of the diff options,\nso rather than placing a range-diff in the cover-letter, we write it to\nstdout. In order to fix this, rewrite the two callers adjusted by\nd8981c3f88 to instead create a \"dummy\" set of diff options where they\nonly fill in the fields we absolutely require, such as output file and\ncolor.\n\nModify and extend the existing tests to try and verify that the right\ncontents end up in the right place.\n\nDon't revert `show_range_diff()`, i.e., let it keep accepting NULL.\nRather than removing what is dead code and figuring out it isn't\nactually dead and we've broken 2.20, just leave it for now.\n\n[es: retain diff coloring when going to stdout]\n\nSigned-off-by: Martin Ågren <martin.agren@gmail.com>\nSigned-off-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n\nThis is a re-roll of Martin's v2[1]. The only difference from v2 is that\nit retains coloring when emitting to the terminal (plus an in-code\ncomment was simplified).\n\nThe regression introduced by d8981c3f88, in which the range-diff only\never gets emitted to the terminal, and never to the cover letter or\ncommentary section of a standalone patch, makes the --range-diff option\nrather useless, so this fix probably ought to be fast-tracked. An\nalternative would be to rip out all the recent \"--range-diff\"-related\nchanges and go with the --range-diff implementation which has been in\nuse for a few months, even if it is not perfect.\n\n[1]: https://public-inbox.org/git/20181203200734.527341-1-martin.agren@gmail.com/\n\nbuiltin/log.c         | 11 ++++++++++-\n log-tree.c            | 11 ++++++++++-\n t/t3206-range-diff.sh | 20 +++++++++++++-------\n 3 files changed, 33 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 5ac18e2848..e8e51068bd 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1094,9 +1094,18 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \t}\n \n \tif (rev->rdiff1) {\n+\t\t/*\n+\t\t * Pass minimum required diff-options to range-diff; others\n+\t\t * can be added later if deemed desirable.\n+\t\t */\n+\t\tstruct diff_options opts;\n+\t\tdiff_setup(&opts);\n+\t\topts.file = rev->diffopt.file;\n+\t\topts.use_color = rev->diffopt.use_color;\n+\t\tdiff_setup_done(&opts);\n \t\tfprintf_ln(rev->diffopt.file, \"%s\", rev->rdiff_title);\n \t\tshow_range_diff(rev->rdiff1, rev->rdiff2,\n-\t\t\t\trev->creation_factor, 1, NULL);\n+\t\t\t\trev->creation_factor, 1, &opts);\n \t}\n }\n \ndiff --git a/log-tree.c b/log-tree.c\nindex b243779a0b..10680c139e 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -755,14 +755,23 @@ void show_log(struct rev_info *opt)\n \n \tif (cmit_fmt_is_mail(ctx.fmt) && opt->rdiff1) {\n \t\tstruct diff_queue_struct dq;\n+\t\tstruct diff_options opts;\n \n \t\tmemcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));\n \t\tDIFF_QUEUE_CLEAR(&diff_queued_diff);\n \n \t\tnext_commentary_block(opt, NULL);\n \t\tfprintf_ln(opt->diffopt.file, \"%s\", opt->rdiff_title);\n+\t\t/*\n+\t\t * Pass minimum required diff-options to range-diff; others\n+\t\t * can be added later if deemed desirable.\n+\t\t */\n+\t\tdiff_setup(&opts);\n+\t\topts.file = opt->diffopt.file;\n+\t\topts.use_color = opt->diffopt.use_color;\n+\t\tdiff_setup_done(&opts);\n \t\tshow_range_diff(opt->rdiff1, opt->rdiff2,\n-\t\t\t\topt->creation_factor, 1, NULL);\n+\t\t\t\topt->creation_factor, 1, &opts);\n \n \t\tmemcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));\n \t}\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex e497c1358f..048feaf6dd 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -248,18 +248,24 @@ test_expect_success 'dual-coloring' '\n for prev in topic master..topic\n do\n \ttest_expect_success \"format-patch --range-diff=$prev\" '\n-\t\tgit format-patch --stdout --cover-letter --range-diff=$prev \\\n+\t\tgit format-patch --cover-letter --range-diff=$prev \\\n \t\t\tmaster..unmodified >actual &&\n-\t\tgrep \"= 1: .* s/5/A\" actual &&\n-\t\tgrep \"= 2: .* s/4/A\" actual &&\n-\t\tgrep \"= 3: .* s/11/B\" actual &&\n-\t\tgrep \"= 4: .* s/12/B\" actual\n+\t\ttest_when_finished \"rm 000?-*\" &&\n+\t\ttest_line_count = 5 actual &&\n+\t\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\t\tgrep \"= 1: .* s/5/A\" 0000-* &&\n+\t\tgrep \"= 2: .* s/4/A\" 0000-* &&\n+\t\tgrep \"= 3: .* s/11/B\" 0000-* &&\n+\t\tgrep \"= 4: .* s/12/B\" 0000-*\n \t'\n done\n \n test_expect_success 'format-patch --range-diff as commentary' '\n-\tgit format-patch --stdout --range-diff=HEAD~1 HEAD~1 >actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" actual\n+\tgit format-patch --range-diff=HEAD~1 HEAD~1 >actual &&\n+\ttest_when_finished \"rm 0001-*\" &&\n+\ttest_line_count = 1 actual &&\n+\ttest_i18ngrep \"^Range-diff:$\" 0001-* &&\n+\tgrep \"> 1: .* new message\" 0001-*\n '\n \n test_done\n-- \n2.20.0.rc2.403.gdbc3b29805\n\n"},{"id":"364516","messageId":"xmqqbm62gjl4.fsf@gitster-ct.c.googlers.com","threadId":"49877","inReplyTo":"20181203212131.11299-1-sunshine@sunshineco.com","subject":"Re: [PATCH v3] range-diff: always pass at least minimal diff options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-12-04T01:35:19Z","receivedAt":"2018-12-04T01:35:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> This is a re-roll of Martin's v2[1]. The only difference from v2 is that\n> it retains coloring when emitting to the terminal (plus an in-code\n> comment was simplified).\n>\n> The regression introduced by d8981c3f88, in which the range-diff only\n> ever gets emitted to the terminal, and never to the cover letter or\n> commentary section of a standalone patch, makes the --range-diff option\n> rather useless, so this fix probably ought to be fast-tracked.\n\nYup.  Thanks.  The only thing that makes me wonder is why any of the\nexisting tests (among which I think I saw range-diff driven from\nformat-patch) did not catch this rather obvious glitch.\n\n> diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\n> index e497c1358f..048feaf6dd 100755\n> --- a/t/t3206-range-diff.sh\n> +++ b/t/t3206-range-diff.sh\n> @@ -248,18 +248,24 @@ test_expect_success 'dual-coloring' '\n>  for prev in topic master..topic\n>  do\n>  \ttest_expect_success \"format-patch --range-diff=$prev\" '\n> -\t\tgit format-patch --stdout --cover-letter --range-diff=$prev \\\n> +\t\tgit format-patch --cover-letter --range-diff=$prev \\\n>  \t\t\tmaster..unmodified >actual &&\n\nAh, of course.  Then the \"actual\" file gets the names of the output\nfiles; we expect to see 5 of them.\n\nBut now we have lost all the range-diff tests run under \"--stdout\",\nso next time some other change regresses only that codepath, we will\nnot notice (which is fine for now but would want to be addressed\nbefore the end of the year around which time we certainly will all\nforget).\n\nThanks.\n\n> -\t\tgrep \"= 1: .* s/5/A\" actual &&\n> -\t\tgrep \"= 2: .* s/4/A\" actual &&\n> -\t\tgrep \"= 3: .* s/11/B\" actual &&\n> -\t\tgrep \"= 4: .* s/12/B\" actual\n> +\t\ttest_when_finished \"rm 000?-*\" &&\n> +\t\ttest_line_count = 5 actual &&\n> +\t\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n> +\t\tgrep \"= 1: .* s/5/A\" 0000-* &&\n> +\t\tgrep \"= 2: .* s/4/A\" 0000-* &&\n> +\t\tgrep \"= 3: .* s/11/B\" 0000-* &&\n> +\t\tgrep \"= 4: .* s/12/B\" 0000-*\n>  \t'\n>  done\n>  \n>  test_expect_success 'format-patch --range-diff as commentary' '\n> -\tgit format-patch --stdout --range-diff=HEAD~1 HEAD~1 >actual &&\n> -\ttest_i18ngrep \"^Range-diff:$\" actual\n> +\tgit format-patch --range-diff=HEAD~1 HEAD~1 >actual &&\n> +\ttest_when_finished \"rm 0001-*\" &&\n> +\ttest_line_count = 1 actual &&\n> +\ttest_i18ngrep \"^Range-diff:$\" 0001-* &&\n> +\tgrep \"> 1: .* new message\" 0001-*\n>  '\n>  \n>  test_done\n"},{"id":"364532","messageId":"CAN0heSr6wNnFF76ushBO4ErOPpLs3_aUkqkUvY7buK31Sf89Jg@mail.gmail.com","threadId":"49877","inReplyTo":"20181203212131.11299-1-sunshine@sunshineco.com","subject":"Re: [PATCH v3] range-diff: always pass at least minimal diff options","fromName":"Martin Ågren","fromEmail":"martin.agren@gmail.com","sentAt":"2018-12-04T05:40:42Z","receivedAt":"2018-12-04T05:40:55Z","isPatch":true,"sender":{"key":"martin.agren@gmail.com","avatar":null},"body":"On Mon, 3 Dec 2018 at 22:21, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> [es: retain diff coloring when going to stdout]\n>\n> Signed-off-by: Martin Ågren <martin.agren@gmail.com>\n> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>\n> ---\n>\n> This is a re-roll of Martin's v2[1]. The only difference from v2 is that\n> it retains coloring when emitting to the terminal (plus an in-code\n> comment was simplified).\n\nThank you so much for this.\n\n>         if (rev->rdiff1) {\n> +               /*\n> +                * Pass minimum required diff-options to range-diff; others\n> +                * can be added later if deemed desirable.\n> +                */\n\nAgreed.\n\n> +               struct diff_options opts;\n> +               diff_setup(&opts);\n> +               opts.file = rev->diffopt.file;\n> +               opts.use_color = rev->diffopt.use_color;\n\nAh, s/0/rev->diffopt.use_color/, well that's obvious.\n\nThanks!\n\nMartin\n"}]}