Re: [PATCH 0/1] rebase: understand -C again, refactor

2018-11-14 Thread Johannes Schindelin
Hi Peff,

On Wed, 14 Nov 2018, Jeff King wrote:

> On Tue, Nov 13, 2018 at 04:38:24AM -0800, Johannes Schindelin via 
> GitGitGadget wrote:
> 
> > Phillip Wood reported a problem where the built-in rebase did not understand
> > options like -C1, i.e. it did not expect the option argument.
> > 
> > While investigating how to address this best, I stumbled upon 
> > OPT_PASSTHRU_ARGV (which I was so far happily unaware of).
> 
> I was unaware of it, too.

Thanks, that makes me feel better ;-)

> Looking at the OPT_PASSTHRU and its ARGV counterpart, I think the
> original intent was that you'd pass through normal last-one-wins
> individual options with OPT_PASSTHRU, and then list-like options with
> OPT_PASSTHRU_ARGV. But here you've used the latter to pass sets of
> individual last-one-wins options.
> 
> That said, I think what you've done here is way simpler and more
> readable than using a bunch of OPT_PASSTHRUs would have been. And even
> if it was not the original intent of the ARGV variant, I can't see any
> reason to avoid doing it this way.

Thank you, that makes me feel *even* better ;-)

Together with the extra-early error checking for incorrect -C and
--whitespace options, I think we're in a much better place now.

Ciao,
Dscho


Re: [PATCH 1/1] rebase: really just passthru the `git am` options

2018-11-14 Thread Johannes Schindelin
Hi Phillip,

On Tue, 13 Nov 2018, Phillip Wood wrote:

> On 13/11/2018 19:21, Johannes Schindelin wrote:
> > Hi Phillip,
> > 
> > On Tue, 13 Nov 2018, Phillip Wood wrote:
> > 
> > > Thanks for looking at this. Unfortunately using OPT_PASSTHRU_ARGV seems to
> > > break the error reporting
> > >
> > > Running
> > >bin/wrappers/git rebase --onto @ @^^ -Cbad
> > >
> > > Gives
> > >git encountered an error while preparing the patches to replay
> > >these revisions:
> > >
> > >
> > > 67f673aa4a580b9e407b1ca505abf1f50510ec47...7c3e01a708856885e60bf4051586970e65dd326c
> > >
> > >As a result, git cannot rebase them.
> > >
> 
> git 2.19.1 gives
> 
> First, rewinding head to replay your work on top of it...
> Applying: Ninth batch for 2.20
> error: switch `C' expects a numerical value
> 
> So it has a clear message as to what the error is, this patch regresses that.
> It would be better if rebase detected the error before starting though.

I agree that that would make most sense: why start something when you can
know that it will fail later...

Let me try to add that test case that Junio wanted, and some early error
handling.

> > > If I do
> > >
> > >bin/wrappers/git rebase @^^ -Cbad
> > >
> > > I get no error, it just tells me that it does not need to rebase (which is
> > > true)
> > 
> > Hmm. Isn't this the same behavior as with the scripted version?
> 
> Ah you're right the script does not check if the option argument is valid.
> 
> > Also: are
> > we sure that we want to allow options to come *after* the ``
> > argument?
> 
> Maybe not but the scripted version does. I'm not sure if that is a good idea
> or not.

That behavior was never documented, though, was it?

Ciao,
Dscho

> 
> Best Wishes
> 
> Phillip
> 
> > Ciao,
> > Dscho
> > 
> > > Best Wishes
> > >
> > > Phillip
> > >
> > >
> > > On 13/11/2018 12:38, Johannes Schindelin via GitGitGadget wrote:
> > > > From: Johannes Schindelin 
> > > >
> > > > Currently, we parse the options intended for `git am` as if we wanted to
> > > > handle them in `git rebase`, and then reconstruct them painstakingly to
> > > > define the `git_am_opt` variable.
> > > >
> > > > However, there is a much better way (that I was unaware of, at the time
> > > > when I mentored Pratik to implement these options): OPT_PASSTHRU_ARGV.
> > > > It is intended for exactly this use case, where command-line options
> > > > want to be parsed into a separate `argv_array`.
> > > >
> > > > Let's use this feature.
> > > >
> > > > Incidentally, this also allows us to address a bug discovered by Phillip
> > > > Wood, where the built-in rebase failed to understand that the `-C`
> > > > option takes an optional argument.
> > > >
> > > > Signed-off-by: Johannes Schindelin 
> > > > ---
> > > >builtin/rebase.c | 98
> > > >+---
> > > >1 file changed, 35 insertions(+), 63 deletions(-)
> > > >
> > > > diff --git a/builtin/rebase.c b/builtin/rebase.c
> > > > index 0ee06aa363..96ffa80b71 100644
> > > > --- a/builtin/rebase.c
> > > > +++ b/builtin/rebase.c
> > > > @@ -87,7 +87,7 @@ struct rebase_options {
> > > >  REBASE_FORCE = 1<<3,
> > > >  REBASE_INTERACTIVE_EXPLICIT = 1<<4,
> > > > } flags;
> > > > -   struct strbuf git_am_opt;
> > > > +   struct argv_array git_am_opts;
> > > > const char *action;
> > > > int signoff;
> > > > int allow_rerere_autoupdate;
> > > > @@ -339,7 +339,7 @@ N_("Resolve all conflicts manually, mark them as
> > > > resolved with\n"
> > > >static int run_specific_rebase(struct rebase_options *opts)
> > > >{
> > > > const char *argv[] = { NULL, NULL };
> > > > -   struct strbuf script_snippet = STRBUF_INIT;
> > > > +   struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;
> > > > int status;
> > > > const char *backend, *backend_func;
> > > >@@ -433,7 +433,9 @@ static int run_specific_rebase(struct
> > > > rebase_options
> > > > *opts)
> > > > oid_t

Re: [PATCH 0/2] rebase.useBuiltin doc & test mode

2018-11-14 Thread Johannes Schindelin
Hi Ævar,

On Wed, 14 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> On Wed, Nov 14 2018, Stefan Beller wrote:
> 
> >> But maybe I'm being overly paranoid. What do those more familiar with
> >> this think?
> >
> > I am not too worried,
> > * as rebase is a main porcelain, that is even hard to use in a script.
> >   so any failures are not deep down in some automation,
> >   but when found exposed quickly (and hopefully reported).
> > * 5541bd5b8f was merged to next a month ago; internally we
> >distribute the next branch to Googlers (on a weekly basis)
> >and we have not had any bug reports regarding rebase.
> >(Maybe our environment is too strict for the wide range
> > of bugs reported)
> 
> I do the same at Booking.com (although at a more ad-hoc schedule) and
> got the report whose fix is now sitting in "pu" noted upthread.
> 
> I fear that these sorts of corporate environments, both Google's and
> Booking's, end up testing a relatively narrow featureset. Most people
> have similar enough workflows, e.g. just using "git pull --rebase",
> I'd be surprised if we have more than 2-3 internal users who ever use
> the --onto option for example.
> 
> > * Johannes reported that the rebase is used in GfW
> >
> > https://public-inbox.org/git/nycvar.qro.7.76.6.1808241320540...@tvgsbejvaqbjf.bet/
> >https://github.com/git-for-windows/git/pull/1800
> >and from my cursory reading it is part of
> >2.19.windows, which has a large user base.
> >
> >> (and would re-enable rebase.useBuiltin=true in
> >> master right after 2.20 is out the door).
> >
> > That would be fine with me as well, but I'd rather
> > document rebase.useBuiltin instead of flip-flopping
> > the switch around the release.
> >
> > Have there been any fixes that are only in
> > the C version (has the shell version already bitrotted)?
> 
> That's a good question, one which I don't think we knew the answer to
> before the following patches.

I pay close attention to `git rebase` bug reports and patches (obviously),
and there have not been any changes going into the built-in rebase/rebase
-i that necessitated changes also in the scripted version.

Ciao,
Dscho

> As it turns out no, we still run the tests without failures with
> GIT_TEST_REBASE_USE_BUILTIN=false.
> 
> Ævar Arnfjörð Bjarmason (2):
>   rebase doc: document rebase.useBuiltin
>   tests: add a special setup where rebase.useBuiltin is off
> 
>  Documentation/config/rebase.txt | 14 ++
>  builtin/rebase.c|  5 -
>  t/README|  3 +++
>  3 files changed, 21 insertions(+), 1 deletion(-)
> 
> -- 
> 2.19.1.1182.g4ecb1133ce
> 
> 

Re: [PATCH v4] commit: add a commit.allowEmpty config variable

2018-11-14 Thread Johannes Schindelin
Hi,

On Wed, 14 Nov 2018, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason  writes:
> 
> > Agreed. I'm happy to see the test for-loop gone as I noted in
> > https://public-inbox.org/git/87d0rm7zeo@evledraar.gmail.com/ but as
> > noted in that v3 feedback the whole "why would anyone want this?"
> > explanation is still missing, and this still smells like a workaround
> > for a bug we should be fixing elsewhere in the sequencing code.
> 
> Thanks.  I share the same impression that this is sweeping a bug
> under a wrong rug.

I agree that the scenario is under-explained. Of course, I have to say
that this is not Tanushree's problem; They only copied what is in
https://github.com/git-for-windows/git/issues/1854 and @chucklu did not
grace us with an explanation, either.

Based on historical context, I would wager a bet that the scenario is
that some commits that may or may not have been in a different SCM
originally and that may or may not have been empty and/or squashed in
`master` need to be cherry-picked.

But I agree that this should be clarified. I prodded the original
wish-haver.

Ciao,
Dscho

[PATCH v2 0/1] Some left-over add-on for bw/config-h

2018-11-14 Thread Johannes Schindelin via GitGitGadget
Back when bw/config-h was developed (and backported to Git for Windows), I
came up with a patch to use git_dir if commondir is NULL, and contributed
that as v1 of this patch. However, it was deemed a bug if that happens, so
let's instead detect that condition and report it.

Change since v1:

 * Be loud about this bug instead of papering over it.

Johannes Schindelin (1):
  config: report a bug if git_dir exists without commondir

 config.c | 2 ++
 1 file changed, 2 insertions(+)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-78%2Fdscho%2Fbw%2Fconfig-h-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-78/dscho/bw/config-h-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/78

Range-diff vs v1:

 1:  a3854e4ed8 ! 1:  0767f98378 do_git_config_sequence(): fall back to git_dir 
if commondir is NULL
 @@ -1,8 +1,9 @@
  Author: Johannes Schindelin 
  
 -do_git_config_sequence(): fall back to git_dir if commondir is NULL
 +config: report a bug if git_dir exists without commondir
  
 -Just some defensive programming.
 +This did happen at some stage, and was fixed relatively quickly. Make
 +sure that we detect very quickly, too, should that happen again.
  
  Signed-off-by: Johannes Schindelin 
  
 @@ -14,7 +15,7 @@
if (opts->commondir)
repo_config = mkpathdup("%s/config", opts->commondir);
  + else if (opts->git_dir)
 -+ repo_config = mkpathdup("%s/config", opts->git_dir);
 ++ BUG("git_dir without commondir");
else
repo_config = NULL;
   

-- 
gitgitgadget


[PATCH v2 1/1] config: report a bug if git_dir exists without commondir

2018-11-14 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

This did happen at some stage, and was fixed relatively quickly. Make
sure that we detect very quickly, too, should that happen again.

Signed-off-by: Johannes Schindelin 
---
 config.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/config.c b/config.c
index 4051e38823..db6b0167c6 100644
--- a/config.c
+++ b/config.c
@@ -1676,6 +1676,8 @@ static int do_git_config_sequence(const struct 
config_options *opts,
 
if (opts->commondir)
repo_config = mkpathdup("%s/config", opts->commondir);
+   else if (opts->git_dir)
+   BUG("git_dir without commondir");
else
repo_config = NULL;
 
-- 
gitgitgadget


Re: [PATCH v2 2/2] tests: add a special setup where rebase.useBuiltin is off

2018-11-14 Thread Johannes Schindelin
Hi Ævar,

On Wed, 14 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> Add a GIT_TEST_REBASE_USE_BUILTIN=false test mode which is equivalent
> to running with rebase.useBuiltin=false. This is needed to spot that
> we're not introducing any regressions in the legacy rebase version
> while we're carrying both it and the new builtin version.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason 
> ---
>  builtin/rebase.c | 5 -
>  t/README | 4 
>  2 files changed, 8 insertions(+), 1 deletion(-)

I am slightly surprised not to see any ci/ change in this diffstat. Did
you mean to add a test axis for Travis, or not?

Ciao,
Dscho

> 
> diff --git a/builtin/rebase.c b/builtin/rebase.c
> index 0ee06aa363..68ad8c1149 100644
> --- a/builtin/rebase.c
> +++ b/builtin/rebase.c
> @@ -48,7 +48,10 @@ static int use_builtin_rebase(void)
>  {
>   struct child_process cp = CHILD_PROCESS_INIT;
>   struct strbuf out = STRBUF_INIT;
> - int ret;
> + int ret, env = git_env_bool("GIT_TEST_REBASE_USE_BUILTIN", -1);
> +
> + if (env != -1)
> + return env;
>  
>   argv_array_pushl(,
>"config", "--bool", "rebase.usebuiltin", NULL);
> diff --git a/t/README b/t/README
> index 242497455f..3df5d12e46 100644
> --- a/t/README
> +++ b/t/README
> @@ -339,6 +339,10 @@ for the index version specified.  Can be set to any 
> valid version
>  GIT_TEST_PRELOAD_INDEX= exercises the preload-index code path
>  by overriding the minimum number of cache entries required per thread.
>  
> +GIT_TEST_REBASE_USE_BUILTIN=, when false, disables the
> +builtin version of git-rebase. See 'rebase.useBuiltin' in
> +git-config(1).
> +
>  GIT_TEST_INDEX_THREADS= enables exercising the multi-threaded loading
>  of the index for the whole test suite by bypassing the default number of
>  cache entries and thread minimums. Setting this to 1 will make the
> -- 
> 2.19.1.1182.g4ecb1133ce
> 
> 

Re: [PATCH v2 1/2] rebase doc: document rebase.useBuiltin

2018-11-14 Thread Johannes Schindelin
Hi Ævar,

On Wed, 14 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> The rebase.useBuiltin variable introduced in 55071ea248 ("rebase:
> start implementing it as a builtin", 2018-08-07) was turned on by
> default in 5541bd5b8f ("rebase: default to using the builtin rebase",
> 2018-08-08), but had no documentation.
> 
> Let's document it so that users who run into any stability issues with
> the C rewrite know there's an escape hatch[1], and make it clear that
> needing to turn off builtin rebase means you've found a bug in git.
> 
> 1. https://public-inbox.org/git/87y39w1wc2@evledraar.gmail.com/
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason 

Makes sense.

Thanks,
Dscho

> ---
>  Documentation/config/rebase.txt | 14 ++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt
> index 42e1ba7575..f079bf6b7e 100644
> --- a/Documentation/config/rebase.txt
> +++ b/Documentation/config/rebase.txt
> @@ -1,3 +1,17 @@
> +rebase.useBuiltin::
> + Set to `false` to use the legacy shellscript implementation of
> + linkgit:git-rebase[1]. Is `true` by default, which means use
> + the built-in rewrite of it in C.
> ++
> +The C rewrite is first included with Git version 2.20. This option
> +serves an an escape hatch to re-enable the legacy version in case any
> +bugs are found in the rewrite. This option and the shellscript version
> +of linkgit:git-rebase[1] will be removed in some future release.
> ++
> +If you find some reason to set this option to `false` other than
> +one-off testing you should report the behavior difference as a bug in
> +git.
> +
>  rebase.stat::
>   Whether to show a diffstat of what changed upstream since the last
>   rebase. False by default.
> -- 
> 2.19.1.1182.g4ecb1133ce
> 
> 

Re: [PATCH 4/5] tests: do not require Git to be built when testing an installed Git

2018-11-14 Thread Johannes Schindelin
Hi Peff,

On Wed, 14 Nov 2018, Jeff King wrote:

> On Mon, Nov 12, 2018 at 05:48:37AM -0800, Johannes Schindelin via 
> GitGitGadget wrote:
> 
> > diff --git a/t/test-lib.sh b/t/test-lib.sh
> > index 832ede5099..1ea20dc2dc 100644
> > --- a/t/test-lib.sh
> > +++ b/t/test-lib.sh
> > @@ -51,7 +51,7 @@ export LSAN_OPTIONS
> >  
> >  
> >  # It appears that people try to run tests without building...
> > -"$GIT_BUILD_DIR/git" >/dev/null
> > +test -n "$GIT_TEST_INSTALLED" || "$GIT_BUILD_DIR/git" >/dev/null ||
> >  if test $? != 1
> >  then
> > echo >&2 'error: you do not seem to have built git yet.'
> 
> The original runs the command independently and then checks $?. Your
> replacement chains the ||. I think it works, because the only case that
> is different is if running git returns 0 (in which case we currently
> complain, but the new code would quietly accept this).
> 
> That should never happen, but if it does we'd probably want to complain.
> And it's pretty subtle all around.  Maybe this would be a bit clearer:
> 
>   if test -n "$GIT_TEST_INSTALLED"
>   then
>   : assume installed git is OK
>   else
>   "$GIT_BUILD_DIR/git" >/dev/null
>   if test $? != 1
>   then
>   ... die ...
>   fi
>   fi
> 
> Though arguably we should be checking that there is a git in our path in
> the first instance. So maybe:
> 
>   if test -n "$GIT_TEST_INSTALLED"
>   "$GIT_TEST_INSTALLED/git" >/dev/null
>   else
>   "$GIT_BUILD_DIR/git" >/dev/null
>   fi
>   if test $? != 1 ...

You're right. I did it using `"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git"`
and I also adjust the error message now.

Will be fixed in the next iteration,
Dscho

> 
> -Peff
> 


Re: [PATCH 5/5] tests: explicitly use `git.exe` on Windows

2018-11-14 Thread Johannes Schindelin
Hi Junio,

On Wed, 14 Nov 2018, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" 
> writes:
> 
> > diff --git a/Makefile b/Makefile
> > index bbfbb4292d..5df0118ce9 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -2590,6 +2590,7 @@ GIT-BUILD-OPTIONS: FORCE
> > @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst 
> > ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
> > @echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+
> > @echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
> > +   @echo X=\'$(X)\' >>$@+
> 
> Made me wonder if a single letter $(X) is a bit too cute to expose
> to the outside world; as a narrowly confined local convention in
> this single Makefile, it was perfectly fine.  But it should do for
> now.  Its terseness is attractive, and our eyes (I do not speak for
> those new to our codebase and build structure) are already used to
> seeing $X suffix.  Somebody may later come and complain but I am OK
> to rename it to something like $EXE at that time, not now.
> 
> >  ifdef TEST_OUTPUT_DIRECTORY
> > @echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst 
> > ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+
> >  endif
> > diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> > index 801cc9b2ef..c167b2e1af 100644
> > --- a/t/test-lib-functions.sh
> > +++ b/t/test-lib-functions.sh
> > @@ -900,7 +900,7 @@ test_create_repo () {
> > mkdir -p "$repo"
> > (
> > cd "$repo" || error "Cannot setup test environment"
> > -   "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git" init \
> > +   "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
> 
> Good.
> 
> > "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
> > error "cannot run git init -- have you built things yet?"
> > mv .git/hooks .git/hooks-disabled
> > diff --git a/t/test-lib.sh b/t/test-lib.sh
> > index 1ea20dc2dc..3e2a9ce76d 100644
> > --- a/t/test-lib.sh
> > +++ b/t/test-lib.sh
> > @@ -49,18 +49,23 @@ export ASAN_OPTIONS
> >  : ${LSAN_OPTIONS=abort_on_error=1}
> >  export LSAN_OPTIONS
> >  
> > +if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
> > +then
> > +   echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).'
> > +   exit 1
> > +fi
> 
> OK, this tells us that we at least attempted to build git once, even
> under test-installed mode, and hopefully people won't run $(MAKE) and
> immediately ^C it only to fool us by leaving this file while keeping
> git binary and t/helpers/ binary unbuilt.
> 
> > +. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
> > +export PERL_PATH SHELL_PATH
> > +
> >  
> >  # It appears that people try to run tests without building...
> > -test -n "$GIT_TEST_INSTALLED" || "$GIT_BUILD_DIR/git" >/dev/null ||
> > +test -n "$GIT_TEST_INSTALLED" || "$GIT_BUILD_DIR/git$X" >/dev/null ||
> 
> The latter half of this change is a good one.  Given what the
> proposed log message of this patch says
> 
> Note also: the many, many calls to `git this` and `git that` are
> unaffected, as the regular PATH search will find the `.exe` files on
> Windows (and not be confused by a directory of the name `git` that is
> in one of the directories listed in the `PATH` variable), while
> `/path/to/git` would not, per se, know that it is looking for an
> executable and happily prefer such a directory.
> 
> which I read as "path-prefixed invocation, i.e. some/path/to/git, is
> bad, it must be spelled some/path/to/git.exe", I am surprised that
> tests ever worked on Windows without these five patches, as this
> line used to read like this:
> 
>   "$GIT_BUILD_DIR/git" >/dev/null
>   if test $? != 1
>   then
>   ...
> 
> Wouldn't "$GIT_BUILD_DIR/git" have failed (and "executable not
> found" hopefully won't produce exit code 1) and stopped the test
> suite from running even after you built git and not under the
> test-installed-git mode?

"$GIT_BUILD_DIR/git" did not fail until I regularly built with Visual
Studio (and my Visual Studio project generator generates a directory named
"git" to live alongside "git.exe").

And when it failed, I patched Git for Windows. Fast-forward, years later I
managed to contribute the patch we are discussing right now ;-)

So yes, it is primarily a concern when testing Git in specific setups
where a "git" directory can live next to the "git.exe" that we want to
test. Not necessarily a big deal for most developers on Windows.

Ciao,
Dscho

> 
> >  if test $? != 1
> >  then
> > echo >&2 'error: you do not seem to have built git yet.'
> > exit 1
> >  fi
> >  
> > -. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
> > -export PERL_PATH SHELL_PATH
> > -
> >  # if --tee was passed, write the output not only to the terminal, but
> >  # additionally to the file test-results/$BASENAME.out, too.
> >  case "$GIT_TEST_TEE_STARTED, $* " in
> 


Re: [PATCH 4/5] tests: do not require Git to be built when testing an installed Git

2018-11-14 Thread Johannes Schindelin
Hi Junio,

On Wed, 14 Nov 2018, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" 
> writes:
> 
> > From: Johannes Schindelin 
> >
> > We really only need the test helpers in that case, but that is not what
> > we test for. So let's skip the test for now when we know that we want to
> > test an installed Git.
> 
> True, but...  hopefully we are making sure t/helpers/ has been built
> in some other ways, though, right?

We do it implicitly, in the test cases that use the helpers.

However, t/test-lib.sh does not particularly verify that the test helpers
have been built.

And I think that is a good thing: we do have several test scripts, I would
think, that do not require any test helper to begin with. These scripts
can work pretty well without having to build anything (read: on a machine
where there is not even a toolchain available to build things).

Besides, it is pretty much only t/helper/test-tool these days, and it is
unlikely that anybody has a `test-tool` in their `PATH`. If they do,
they'll find out soon enough iff they test with `GIT_TEST_INSTALLED` and
iff they do not have the test helper(s) in t/helper/ ;-)

Ciao,
Dscho

> I do not offhand see how tests would work in a pristine checkout with
> "cd t && sh t-*.sh" as t/test-lib.sh is not running $(MAKE) itself
> (and the design of the test-lib.sh, as can be seen in the check this
> part of it makes, is to just abort if we cannot test) with this patch
> (and PATCH 1/5) under the test-installed mode, though.
> 
> > Signed-off-by: Johannes Schindelin 
> > ---
> >  t/test-lib.sh | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/t/test-lib.sh b/t/test-lib.sh
> > index 832ede5099..1ea20dc2dc 100644
> > --- a/t/test-lib.sh
> > +++ b/t/test-lib.sh
> > @@ -51,7 +51,7 @@ export LSAN_OPTIONS
> >  
> >  
> >  # It appears that people try to run tests without building...
> > -"$GIT_BUILD_DIR/git" >/dev/null
> > +test -n "$GIT_TEST_INSTALLED" || "$GIT_BUILD_DIR/git" >/dev/null ||
> >  if test $? != 1
> >  then
> > echo >&2 'error: you do not seem to have built git yet.'
> 


Re: [PATCH 2/5] tests: respect GIT_TEST_INSTALLED when initializing repositories

2018-11-14 Thread Johannes Schindelin
Hi Junio,

On Wed, 14 Nov 2018, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" 
> writes:
> 
> > From: Johannes Schindelin 
> >
> > It really makes very, very little sense to use a different git
> > executable than the one the caller indicated via setting the environment
> > variable GIT_TEST_INSTALLED.
> 
> Makes perfect sense.  Shouldn't we be asking where the template
> directory of the installed version is and using it instead of the
> freshly built one, no?

It would make sense, but we don't know how to get that information, do we?

$ git grep DEFAULT_GIT_TEMPLATE_DIR
Makefile:   -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"'
builtin/init-db.c:#ifndef DEFAULT_GIT_TEMPLATE_DIR
builtin/init-db.c:#define DEFAULT_GIT_TEMPLATE_DIR 
"/usr/share/git-core/templates"
builtin/init-db.c:  template_dir = to_free = 
system_path(DEFAULT_GIT_TEMPLATE_DIR);
contrib/vscode/init.sh: '-DDEFAULT_GIT_TEMPLATE_DIR="$(template_dir_SQ)"' \

In other words, the Makefile defines the DEFAULT_GIT_TEMPLATE_DIR, and the
only user in the code is init-db.c which uses it in copy_templates().

And changing the code *now* to let us query Git where it thinks its
templates should be won't work, as this patch is about using the installed
Git (at whatever pre-compiled version that might be).

Ciao,
Dscho

> >
> > Signed-off-by: Johannes Schindelin 
> > ---
> >  t/test-lib-functions.sh | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> > index 78d8c3783b..801cc9b2ef 100644
> > --- a/t/test-lib-functions.sh
> > +++ b/t/test-lib-functions.sh
> > @@ -900,7 +900,8 @@ test_create_repo () {
> > mkdir -p "$repo"
> > (
> > cd "$repo" || error "Cannot setup test environment"
> > -   "$GIT_EXEC_PATH/git-init" 
> > "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
> > +   "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git" init \
> > +   "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
> > error "cannot run git init -- have you built things yet?"
> > mv .git/hooks .git/hooks-disabled
> > ) || exit
> 


Re: [PATCH v4] commit: add a commit.allowEmpty config variable

2018-11-13 Thread Johannes Schindelin
Hi,

On Tue, 13 Nov 2018, Tanushree Tumane wrote:

> From: tanushree27 
> 
> when we cherrypick an existing commit it doesn't change anything and
> therefore it fails prompting to reset (skip commit) or commit using
> --allow-empty attribute and then continue.

This is a nice paragraph, but it might make sense to connect it to the
commit's oneline somehow. I, for one, was surprised to see the oneline
talk about `git commit` and the commit message about `git cherry-pick`.

I could imagine that an introductory paragraph, talking about why one
might want to commit empty commits, might be the best lead into the
subject, and the paragraph about `cherry-pick` could follow (and be
introduced by saying something along the lines that this config setting
has more reach than just `git commit`; it also affects `git cherry-pick`)?

Ciao,
Johannes

> 
> Add commit.allowEmpty configuration variable as a convenience to skip
> this process.
> 
> Add tests to check the behavior introduced by this commit.
> 
> This closes https://github.com/git-for-windows/git/issues/1854
> 
> Signed-off-by: tanushree27 
> Signed-off-by: Tanushree Tumane 
> ---
>  Documentation/config.txt |  5 +
>  Documentation/git-commit.txt |  3 ++-
>  builtin/commit.c |  8 
>  t/t3500-cherry.sh| 10 ++
>  4 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/config.txt b/Documentation/config.txt
> index c0727b7866..f3828518a5 100644
> --- a/Documentation/config.txt
> +++ b/Documentation/config.txt
> @@ -1467,6 +1467,11 @@ commit.verbose::
>   A boolean or int to specify the level of verbose with `git commit`.
>   See linkgit:git-commit[1].
>  
> +commit.allowEmpty::
> + A boolean to specify whether empty commits are allowed with `git
> + commit`. See linkgit:git-commit[1]. 
> + Defaults to false.
> +
>  credential.helper::
>   Specify an external helper to be called when a username or
>   password credential is needed; the helper may consult external
> diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
> index f970a43422..5d3bbf017a 100644
> --- a/Documentation/git-commit.txt
> +++ b/Documentation/git-commit.txt
> @@ -176,7 +176,8 @@ The `-m` option is mutually exclusive with `-c`, `-C`, 
> and `-F`.
>   Usually recording a commit that has the exact same tree as its
>   sole parent commit is a mistake, and the command prevents you
>   from making such a commit.  This option bypasses the safety, and
> - is primarily for use by foreign SCM interface scripts.
> + is primarily for use by foreign SCM interface scripts. See
> + `commit.allowEmpty` in linkgit:git-config[1].
>  
>  --allow-empty-message::
> Like --allow-empty this command is primarily for use by foreign
> diff --git a/builtin/commit.c b/builtin/commit.c
> index 67fa949204..4516309ac2 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -101,6 +101,7 @@ static int all, also, interactive, patch_interactive, 
> only, amend, signoff;
>  static int edit_flag = -1; /* unspecified */
>  static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
>  static int config_commit_verbose = -1; /* unspecified */
> +static int config_commit_allow_empty = -1; /* unspecified */
>  static int no_post_rewrite, allow_empty_message;
>  static char *untracked_files_arg, *force_date, *ignore_submodule_arg, 
> *ignored_arg;
>  static char *sign_commit;
> @@ -1435,6 +1436,10 @@ static int git_commit_config(const char *k, const char 
> *v, void *cb)
>   config_commit_verbose = git_config_bool_or_int(k, v, _bool);
>   return 0;
>   }
> + if (!strcmp(k, "commit.allowempty")) {
> + config_commit_allow_empty = git_config_bool(k, v);
> + return 0;
> + }
>  
>   status = git_gpg_config(k, v, NULL);
>   if (status)
> @@ -1556,6 +1561,9 @@ int cmd_commit(int argc, const char **argv, const char 
> *prefix)
>   if (verbose == -1)
>   verbose = (config_commit_verbose < 0) ? 0 : 
> config_commit_verbose;
>  
> + if (config_commit_allow_empty >= 0)  /* if allowEmpty is allowed in 
> config*/
> + allow_empty = config_commit_allow_empty;
> + 
>   if (dry_run)
>   return dry_run_commit(argc, argv, prefix, current_head, );
>   index_file = prepare_index(argc, argv, prefix, current_head, 0);
> diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh
> index f038f34b7c..11504e2d9f 100755
> --- a/t/t3500-cherry.sh
> +++ b/t/t3500-cherry.sh
> @@ -55,4 +55,14 @@ test_expect_success \
>   expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* - .*"
>  '
>  
> +
> +# Tests for commit.allowEmpty config
> +
> +test_expect_success 'cherry-pick existing commit with commit.allowEmpty' '
> +test_tick &&
> + test_commit "first" &&
> + test_commit "second" &&
> + git -c commit.allowEmpty=true cherry-pick HEAD~1
> +'
> +
>  

Re: [PATCH 1/1] rebase: really just passthru the `git am` options

2018-11-13 Thread Johannes Schindelin
Hi Phillip,

On Tue, 13 Nov 2018, Phillip Wood wrote:

> Thanks for looking at this. Unfortunately using OPT_PASSTHRU_ARGV seems to
> break the error reporting
> 
> Running
>   bin/wrappers/git rebase --onto @ @^^ -Cbad
> 
> Gives
>   git encountered an error while preparing the patches to replay
>   these revisions:
> 
> 
> 67f673aa4a580b9e407b1ca505abf1f50510ec47...7c3e01a708856885e60bf4051586970e65dd326c
> 
>   As a result, git cannot rebase them.
> 
> If I do
> 
>   bin/wrappers/git rebase @^^ -Cbad
> 
> I get no error, it just tells me that it does not need to rebase (which is
> true)

Hmm. Isn't this the same behavior as with the scripted version? Also: are
we sure that we want to allow options to come *after* the ``
argument?

Ciao,
Dscho

> Best Wishes
> 
> Phillip
> 
> 
> On 13/11/2018 12:38, Johannes Schindelin via GitGitGadget wrote:
> > From: Johannes Schindelin 
> > 
> > Currently, we parse the options intended for `git am` as if we wanted to
> > handle them in `git rebase`, and then reconstruct them painstakingly to
> > define the `git_am_opt` variable.
> > 
> > However, there is a much better way (that I was unaware of, at the time
> > when I mentored Pratik to implement these options): OPT_PASSTHRU_ARGV.
> > It is intended for exactly this use case, where command-line options
> > want to be parsed into a separate `argv_array`.
> > 
> > Let's use this feature.
> > 
> > Incidentally, this also allows us to address a bug discovered by Phillip
> > Wood, where the built-in rebase failed to understand that the `-C`
> > option takes an optional argument.
> > 
> > Signed-off-by: Johannes Schindelin 
> > ---
> >   builtin/rebase.c | 98 +---
> >   1 file changed, 35 insertions(+), 63 deletions(-)
> > 
> > diff --git a/builtin/rebase.c b/builtin/rebase.c
> > index 0ee06aa363..96ffa80b71 100644
> > --- a/builtin/rebase.c
> > +++ b/builtin/rebase.c
> > @@ -87,7 +87,7 @@ struct rebase_options {
> > REBASE_FORCE = 1<<3,
> > REBASE_INTERACTIVE_EXPLICIT = 1<<4,
> > } flags;
> > -   struct strbuf git_am_opt;
> > +   struct argv_array git_am_opts;
> >const char *action;
> >int signoff;
> >int allow_rerere_autoupdate;
> > @@ -339,7 +339,7 @@ N_("Resolve all conflicts manually, mark them as
> > resolved with\n"
> >   static int run_specific_rebase(struct rebase_options *opts)
> >   {
> > const char *argv[] = { NULL, NULL };
> > -   struct strbuf script_snippet = STRBUF_INIT;
> > +   struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;
> >int status;
> >const char *backend, *backend_func;
> >   @@ -433,7 +433,9 @@ static int run_specific_rebase(struct rebase_options
> > *opts)
> > oid_to_hex(>restrict_revision->object.oid) : NULL);
> >add_var(_snippet, "GIT_QUIET",
> > opts->flags & REBASE_NO_QUIET ? "" : "t");
> > -   add_var(_snippet, "git_am_opt", opts->git_am_opt.buf);
> > +   sq_quote_argv_pretty(, opts->git_am_opts.argv);
> > +   add_var(_snippet, "git_am_opt", buf.buf);
> > +   strbuf_release();
> >add_var(_snippet, "verbose",
> > opts->flags & REBASE_VERBOSE ? "t" : "");
> > add_var(_snippet, "diffstat",
> > @@ -756,7 +758,7 @@ int cmd_rebase(int argc, const char **argv, const char
> > *prefix)
> >struct rebase_options options = {
> > .type = REBASE_UNSPECIFIED,
> > .flags = REBASE_NO_QUIET,
> > -   .git_am_opt = STRBUF_INIT,
> > +   .git_am_opts = ARGV_ARRAY_INIT,
> > .allow_rerere_autoupdate  = -1,
> > .allow_empty_message = 1,
> > .git_format_patch_opt = STRBUF_INIT,
> > @@ -777,12 +779,7 @@ int cmd_rebase(int argc, const char **argv, const
> > char *prefix)
> > ACTION_EDIT_TODO,
> > ACTION_SHOW_CURRENT_PATCH,
> > } action = NO_ACTION;
> > -   int committer_date_is_author_date = 0;
> > -   int ignore_date = 0;
> > -   int ignore_whitespace = 0;
> > const char *gpg_sign = NULL;
> > -   int opt_c = -1;
> > -   struct string_list whitespace = STRING_LIST_INIT_NODUP;
> >struct string_list exec = STRING_LIST_INIT_NODUP;
> >const char *rebase_merges = NULL;
> >int fork_point = -1;
> > @@ -804,15 +801,20 @@ int cmd_rebase(int argc, const char **argv, const
> > char *prefix)
> > {OPTION_NEGBIT, 'n', "no-st

[PATCH 0/1] win32: modernize pthread_cond_*() shims

2018-11-13 Thread Johannes Schindelin via GitGitGadget
And yet another patch from Git for Windows' cache of treasures.

It was challenging to emulate the functions related to pthread_cond_t as
long as we tried to maintain support for Windows XP, which has nothing close
to that feature. Now that we require Windows Vista or later, we can make use
of the very nice functions associated with the CONDITION_VARIABLE data type.

Look at how much code this deletes, and how little it introduces. This is a
maintainer's dream.

Loo Rong Jie (1):
  win32: replace pthread_cond_*() with much simpler code

 compat/win32/pthread.c | 138 -
 compat/win32/pthread.h |  28 +++--
 2 files changed, 7 insertions(+), 159 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-80%2Fdscho%2Fmingw-modernize-pthread_cond_t-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-80/dscho/mingw-modernize-pthread_cond_t-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/80
-- 
gitgitgadget


[PATCH 0/1] bundle: fix issue when bundles would be empty

2018-11-13 Thread Johannes Schindelin via GitGitGadget
And yet another patch coming through Git for Windows...

Gaël Lhez (1):
  bundle: refuse to create empty bundle

 bundle.c| 7 ---
 t/t5607-clone-bundle.sh | 4 
 2 files changed, 8 insertions(+), 3 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-79%2Fdscho%2Fcreate-empty-bundle-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-79/dscho/create-empty-bundle-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/79
-- 
gitgitgadget


[PATCH 0/1] Some left-over add-on for bw/config-h

2018-11-13 Thread Johannes Schindelin via GitGitGadget
Back when bw/config-h was developed (and backported to Git for Windows), I
came up with this patch. It seems to not be strictly necessary, but I like
the safety of falling back to the Git directory when no common directory is
configured (for whatever reason).

Johannes Schindelin (1):
  do_git_config_sequence(): fall back to git_dir if commondir is NULL

 config.c | 2 ++
 1 file changed, 2 insertions(+)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-78%2Fdscho%2Fbw%2Fconfig-h-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-78/dscho/bw/config-h-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/78
-- 
gitgitgadget


[PATCH 1/1] do_git_config_sequence(): fall back to git_dir if commondir is NULL

2018-11-13 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

Just some defensive programming.

Signed-off-by: Johannes Schindelin 
---
 config.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/config.c b/config.c
index 4051e38823..279d0d7077 100644
--- a/config.c
+++ b/config.c
@@ -1676,6 +1676,8 @@ static int do_git_config_sequence(const struct 
config_options *opts,
 
if (opts->commondir)
repo_config = mkpathdup("%s/config", opts->commondir);
+   else if (opts->git_dir)
+   repo_config = mkpathdup("%s/config", opts->git_dir);
else
repo_config = NULL;
 
-- 
gitgitgadget


[PATCH 0/1] mingw: use CreateHardLink() directly

2018-11-13 Thread Johannes Schindelin via GitGitGadget
This is another tidbit from the stash of Git for Windows' patches: it avoids
loading the function address of CreateHardLink() at runtime. This was done
in case we were running on a Windows version that does not support that
function, but we no longer support any of these Windows versions.

Johannes Schindelin (1):
  mingw: use `CreateHardLink()` directly

 compat/mingw.c | 14 +-
 1 file changed, 1 insertion(+), 13 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-77%2Fdscho%2Fmingw-CreateHardLink-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-77/dscho/mingw-CreateHardLink-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/77
-- 
gitgitgadget


[PATCH 1/1] mingw: use `CreateHardLink()` directly

2018-11-13 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

The function `CreateHardLink()` is available in all supported Windows
versions (even since Windows XP), so there is no more need to resolve it
at runtime.

Helped-by: Max Kirillov 
Signed-off-by: Johannes Schindelin 
---
 compat/mingw.c | 14 +-
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index 3b44dd99d7..fdcf946275 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -2084,24 +2084,12 @@ int mingw_raise(int sig)
 
 int link(const char *oldpath, const char *newpath)
 {
-   typedef BOOL (WINAPI *T)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
-   static T create_hard_link = NULL;
wchar_t woldpath[MAX_PATH], wnewpath[MAX_PATH];
if (xutftowcs_path(woldpath, oldpath) < 0 ||
xutftowcs_path(wnewpath, newpath) < 0)
return -1;
 
-   if (!create_hard_link) {
-   create_hard_link = (T) GetProcAddress(
-   GetModuleHandle("kernel32.dll"), "CreateHardLinkW");
-   if (!create_hard_link)
-   create_hard_link = (T)-1;
-   }
-   if (create_hard_link == (T)-1) {
-   errno = ENOSYS;
-   return -1;
-   }
-   if (!create_hard_link(wnewpath, woldpath, NULL)) {
+   if (!CreateHardLinkW(wnewpath, woldpath, NULL)) {
errno = err_win_to_posix(GetLastError());
return -1;
}
-- 
gitgitgadget


Re: [PATCH 1/5] rebase -r: demonstrate bug with conflicting merges

2018-11-13 Thread Johannes Schindelin
Hi Junio,

On Tue, 13 Nov 2018, Junio C Hamano wrote:

> Johannes Schindelin  writes:
> 
> >> For a trivially small change/fix like this, it is OK and even
> >> preferrable to make 1+2 a single step, as applying t/ part only to
> >> try to see the breakage (or "am"ing everything and then "diff |
> >> apply -R" the part outside t/ for the same purpose) is easy enough.
> >
> > I disagree. It helps both development and porting to different branches to
> > be able to cherry-pick the regression test individually. Please do not ask
> > me to violate this hard-learned principle.
> 
> A trivially small change/fix like this, by definition (of "trivial"
> and "small" ness), it is trivial to develop and port to different
> branches a single patch, and test with just one half (either the
> test part or the code-change part) of the change reversed, to ensure
> that the codebase is broken without the code-change and to
> demonstrate that the code-change does fix the problem revealed by
> the test change.  And "porting" by cherry-picking a single patch is
> always easier than two patch series.
> 
> So you may disagree all you want in your project, but do not make
> reviewer's lives unnecessarily harder in this project.

You misunderstand. In this case it is crucial to read the regression test
first. The fix does not make much sense before one understands the
condition under which the order of the code statements matters.

By trying to force me to smoosh them together, you are trying to force me
to combine them in one patch where you would read the (now seemingly
non-sensical) fix first, and only then the test.

That's just really unhelpful. If I were a reviewer, I would want it
presented in the way it *was* presented. I firmly believe most reviewers
would.

Ciao,
Dscho


[PATCH 0/1] rebase: understand -C again, refactor

2018-11-13 Thread Johannes Schindelin via GitGitGadget
Phillip Wood reported a problem where the built-in rebase did not understand
options like -C1, i.e. it did not expect the option argument.

While investigating how to address this best, I stumbled upon 
OPT_PASSTHRU_ARGV (which I was so far happily unaware of).

Instead of just fixing the -C bug, I decided to simply convert all of the
options intended for git am (or, eventually, for git apply). This happens to
fix that bug, and does so much more: it simplifies the entire logic (and
removes more lines than it adds).

Johannes Schindelin (1):
  rebase: really just passthru the `git am` options

 builtin/rebase.c | 98 +---
 1 file changed, 35 insertions(+), 63 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-76%2Fdscho%2Frebase-Cn-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-76/dscho/rebase-Cn-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/76
-- 
gitgitgadget


[PATCH 1/1] rebase: really just passthru the `git am` options

2018-11-13 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

Currently, we parse the options intended for `git am` as if we wanted to
handle them in `git rebase`, and then reconstruct them painstakingly to
define the `git_am_opt` variable.

However, there is a much better way (that I was unaware of, at the time
when I mentored Pratik to implement these options): OPT_PASSTHRU_ARGV.
It is intended for exactly this use case, where command-line options
want to be parsed into a separate `argv_array`.

Let's use this feature.

Incidentally, this also allows us to address a bug discovered by Phillip
Wood, where the built-in rebase failed to understand that the `-C`
option takes an optional argument.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c | 98 +---
 1 file changed, 35 insertions(+), 63 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 0ee06aa363..96ffa80b71 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -87,7 +87,7 @@ struct rebase_options {
REBASE_FORCE = 1<<3,
REBASE_INTERACTIVE_EXPLICIT = 1<<4,
} flags;
-   struct strbuf git_am_opt;
+   struct argv_array git_am_opts;
const char *action;
int signoff;
int allow_rerere_autoupdate;
@@ -339,7 +339,7 @@ N_("Resolve all conflicts manually, mark them as resolved 
with\n"
 static int run_specific_rebase(struct rebase_options *opts)
 {
const char *argv[] = { NULL, NULL };
-   struct strbuf script_snippet = STRBUF_INIT;
+   struct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;
int status;
const char *backend, *backend_func;
 
@@ -433,7 +433,9 @@ static int run_specific_rebase(struct rebase_options *opts)
oid_to_hex(>restrict_revision->object.oid) : NULL);
add_var(_snippet, "GIT_QUIET",
opts->flags & REBASE_NO_QUIET ? "" : "t");
-   add_var(_snippet, "git_am_opt", opts->git_am_opt.buf);
+   sq_quote_argv_pretty(, opts->git_am_opts.argv);
+   add_var(_snippet, "git_am_opt", buf.buf);
+   strbuf_release();
add_var(_snippet, "verbose",
opts->flags & REBASE_VERBOSE ? "t" : "");
add_var(_snippet, "diffstat",
@@ -756,7 +758,7 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
struct rebase_options options = {
.type = REBASE_UNSPECIFIED,
.flags = REBASE_NO_QUIET,
-   .git_am_opt = STRBUF_INIT,
+   .git_am_opts = ARGV_ARRAY_INIT,
.allow_rerere_autoupdate  = -1,
.allow_empty_message = 1,
.git_format_patch_opt = STRBUF_INIT,
@@ -777,12 +779,7 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
ACTION_EDIT_TODO,
ACTION_SHOW_CURRENT_PATCH,
} action = NO_ACTION;
-   int committer_date_is_author_date = 0;
-   int ignore_date = 0;
-   int ignore_whitespace = 0;
const char *gpg_sign = NULL;
-   int opt_c = -1;
-   struct string_list whitespace = STRING_LIST_INIT_NODUP;
struct string_list exec = STRING_LIST_INIT_NODUP;
const char *rebase_merges = NULL;
int fork_point = -1;
@@ -804,15 +801,20 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
{OPTION_NEGBIT, 'n', "no-stat", , NULL,
N_("do not show diffstat of what changed upstream"),
PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },
-   OPT_BOOL(0, "ignore-whitespace", _whitespace,
-N_("passed to 'git apply'")),
OPT_BOOL(0, "signoff", ,
 N_("add a Signed-off-by: line to each commit")),
-   OPT_BOOL(0, "committer-date-is-author-date",
-_date_is_author_date,
-N_("passed to 'git am'")),
-   OPT_BOOL(0, "ignore-date", _date,
-N_("passed to 'git am'")),
+   OPT_PASSTHRU_ARGV(0, "ignore-whitespace", _am_opts,
+ NULL, N_("passed to 'git am'"),
+ PARSE_OPT_NOARG),
+   OPT_PASSTHRU_ARGV(0, "committer-date-is-author-date",
+ _am_opts, NULL,
+ N_("passed to 'git am'"), PARSE_OPT_NOARG),
+   OPT_PASSTHRU_ARGV(0, "ignore-date", _am_opts, NULL,
+ N_("passed to 'git am'"), PARSE_OPT_NOARG),
+   OPT_PASSTHRU_ARGV('C', NULL, _am_opts, N_("n"),
+ N_("passed to 'git apply'"), 0),
+

Re: [PATCH 1/2] refs: show --exclude failure with --branches/tags/remotes=glob

2018-11-13 Thread Johannes Schindelin
Hi Junio,

On Tue, 13 Nov 2018, Junio C Hamano wrote:

> Rafael Ascensão  writes:
> 
> > The documentation of `--exclude=` option from rev-list and rev-parse
> > explicitly states that exclude patterns *should not* start with 'refs/'
> > when used with `--branches`, `--tags` or `--remotes`.
> >
> > However, following this advice results in refereces not being excluded
> > if the next `--branches`, `--tags`, `--remotes` use the optional
> > inclusive glob.
> >
> > Demonstrate this failure.
> >
> > Signed-off-by: Rafael Ascensão 
> > ---
> >  t/t6018-rev-list-glob.sh | 60 ++--
> >  1 file changed, 57 insertions(+), 3 deletions(-)
> 
> For a trivially small change/fix like this (i.e. the real fix in 2/2
> is just 4 lines), it is OK and even preferrable to make 1+2 a single
> step, as applying t/ part only to try to see the breakage (or
> "am"ing everything and then "diff | apply -R" the part outside t/
> for the same purpose) is easy enough.

I wish you were not so adamant about this. I really consider it poor style
to smoosh those together, and there is nothing easy about disentangling
changes that have been thrown into the same commit. Please stop saying
that this is easy. It is as easy as maintaining Linux kernel development
using .tar files and patches. It is possible, yes, and Linus Torvalds did
it for years. It is also error-prone and the entire reason we have Git.
And nobody wants to go back anymore to .tar files and patches. Likewise, I
do not want to read anybody recommending some semi-understandable
diff|apply-R dance when the alternative would be a simple cherry-pick. I
do not even want to read such a recommendation from you. I respect you a
lot for what you do, and for your knowledge, but this is simply bad advice
and I would wish you stopped giving it.

Besides, we spent a decade trying to come up with clear-cut rules how to
organize commits, and we ended up pretty quickly with recommending
logically-separate changes belonging to separate commits. A typo fix
should not be thrown in with a regression fix, they are two different
things. Likewise, demonstrating a bug is a different thing from fixing it.

If you need more arguments to make the case, here is another one: it is
reflecting the reality a lot better if the regression test comes first,
and then the fix. This is how Rafael did it, too, according to what he
said on IRC. And reflecting this in the commit history is a good thing,
not a bad thing.

It goes further: obviously, Rafael had really good success with this
strategy, even figuring out part of the bug while trying to write the
regression test.

I, myself wrote a regression test yesterday that completely
short-circuited the bug hunt: originally, I thought the left-over
MERGE_HEAD files in the rebase -r stemmed from mere conflicts during a
`merge` command, and somehow `git commit` not cleaning it properly. But
when I wrote that regression test and ran it, it failed to show a
regression. So then I took my (rather lengthy: >200 todo commands)
real-world example, and condensed it into the regression test that you saw
yesterday. I would estimate that this saved me about 1-3 hours of
debugging in vain.

So it is a very, very good idea to start with the regression test, and
only then analyze the bug.

Reading the commit history this way makes therefore not only sense, but
also sets a good example for new contributors to follow.

For these reasons, and many more, I implore you to stop suggesting to
conflate the demonstration of a bug with the fix.

Instead, we should be happy to see good practices in action and encourage
more of the same.

Thank you,
Dscho


> Often the patch 2 with your method ends up showing only the test
> set-up part in the context by changing _failure to _success, without
> showing what end-user visible breakage the step fixed, which usually
> comes near the end of the added test piece.  For this particular
> test, s/_failure/_success/ shows everything in the verification
> phase, but the entire set-up for these tests cannot be seen while
> reviewing 2/2.  Unlike that, a single patch that gives tests that
> ought to succeed would not force the readers to switch between
> patches 1 and 2 while reading the fix.
> 
> Of course, the above would not apply for a more involved case where
> the actual fix to the code needs to span multiple patches.
> 
> > diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh
> > index 0bf10d0686..8e2b136356 100755
> > --- a/t/t6018-rev-list-glob.sh
> > +++ b/t/t6018-rev-list-glob.sh
> > @@ -36,7 +36,13 @@ test_expect_success 'setup' '
> > git tag foo/bar master &&
> > commit master3 &&
> > git update-ref refs/remotes/foo/baz master &&
> > -   commit master4
> > +   commit master4 &&
> > +   git update-ref refs/remotes/upstream/one subspace/one &&
> > +   git update-ref refs/remotes/upstream/two subspace/two &&
> > +   git update-ref refs/remotes/upstream/x subspace-x &&
> > +   git tag 

Re: [PATCH 4/5] built-in rebase --skip/--abort: clean up stale .git/ files

2018-11-13 Thread Johannes Schindelin
Hi Junio,

On Tue, 13 Nov 2018, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" 
> writes:
> 
> > From: Johannes Schindelin 
> >
> > The scripted version of the rebase used to execute `git reset --hard`
> > when skipping or aborting. When we ported this to C, we did update the
> > worktree and some reflogs, but we failed to imitate `git reset --hard`'s
> > behavior regarding files in .git/ such as MERGE_HEAD.
> >
> > Let's address this oversight.
> >
> > Signed-off-by: Johannes Schindelin 
> > ---
> >  builtin/rebase.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/builtin/rebase.c b/builtin/rebase.c
> > index 0ee06aa363..017dce1b50 100644
> > --- a/builtin/rebase.c
> > +++ b/builtin/rebase.c
> > @@ -23,6 +23,7 @@
> >  #include "revision.h"
> >  #include "commit-reach.h"
> >  #include "rerere.h"
> > +#include "branch.h"
> >  
> >  static char const * const builtin_rebase_usage[] = {
> > N_("git rebase [-i] [options] [--exec ] [--onto ] "
> > @@ -1002,6 +1003,7 @@ int cmd_rebase(int argc, const char **argv, const 
> > char *prefix)
> >  
> > if (reset_head(NULL, "reset", NULL, 0, NULL, NULL) < 0)
> > die(_("could not discard worktree changes"));
> > +   remove_branch_state();
> > if (read_basic_state())
> > exit(1);
> > goto run_rebase;
> > @@ -1019,6 +1021,7 @@ int cmd_rebase(int argc, const char **argv, const 
> > char *prefix)
> >options.head_name, 0, NULL, NULL) < 0)
> > die(_("could not move back to %s"),
> > oid_to_hex(_head));
> > +   remove_branch_state();
> 
> Hmph.  Among 5 or so callsites of reset_head(), only these two
> places need it, so reset_head() is clearly not a substitute for
> "reset --hard HEAD", and it sometimes used to switch branches or
> something?

Indeed. There is also the `git reset --hard` call in the scripted
version's autostash code path. But that definitely does not need to remove
the branch state, as it is not recovering from a merge or cherry-pick or
revert.

> Perhaps we may need to rename it to avoid confusion but it can wait
> until we actually decide to make it externally available.  Until then,
> it's OK as-is, I would think.

Okay.

Ciao,
Dscho

> 
> > ret = finish_rebase();
> > goto cleanup;
> > }
> 


Re: [PATCH 1/5] rebase -r: demonstrate bug with conflicting merges

2018-11-13 Thread Johannes Schindelin
Hi Junio,

On Tue, 13 Nov 2018, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" 
> writes:
> 
> > From: Johannes Schindelin 
> >
> > When calling `merge` on a branch that has already been merged, that
> > `merge` is skipped quietly, but currently a MERGE_HEAD file is being
> > left behind and will then be grabbed by the next `pick` (that did
> > not want to create a *merge* commit).
> >
> > Demonstrate this.
> >
> > Signed-off-by: Johannes Schindelin 
> > ---
> >  t/t3430-rebase-merges.sh | 16 
> >  1 file changed, 16 insertions(+)
> 
> For a trivially small change/fix like this, it is OK and even
> preferrable to make 1+2 a single step, as applying t/ part only to
> try to see the breakage (or "am"ing everything and then "diff |
> apply -R" the part outside t/ for the same purpose) is easy enough.

I disagree. It helps both development and porting to different branches to
be able to cherry-pick the regression test individually. Please do not ask
me to violate this hard-learned principle.

> Because the patch 2 with your method ends up showing only the test
> set-up part in the context by changing _failure to _success, without
> showing what end-user visible breakage the step fixed, which usually
> comes near the end of the added test piece.  A single patch that
> gives tests that ought to succeed would not force the readers to
> switch between patches 1 and 2 while reading the fix.

That is why I put in a verbose commit message, so that you do not have to
guess. And even the test title talks about this.

Seriously, I am very much opposed to changing the patches in the direction
you suggested. In my mind, they would make the story substantially worse.

Thank you for your review,
Dscho

> 
> Of course, the above would not apply for a more involved case where
> the actual fix to the code needs to span multiple patches.
> 
> Thanks.
> 
> > diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
> > index aa7bfc88ec..1f08a33687 100755
> > --- a/t/t3430-rebase-merges.sh
> > +++ b/t/t3430-rebase-merges.sh
> > @@ -396,4 +396,20 @@ test_expect_success 'with --autosquash and --exec' '
> > grep "G: +G" actual
> >  '
> >  
> > +test_expect_failure '--continue after resolving conflicts after a merge' '
> > +   git checkout -b already-has-g E &&
> > +   git cherry-pick E..G &&
> > +   test_commit H2 &&
> > +
> > +   git checkout -b conflicts-in-merge H &&
> > +   test_commit H2 H2.t conflicts H2-conflict &&
> > +   test_must_fail git rebase -r already-has-g &&
> > +   grep conflicts H2.t &&
> 
> Is this making sure that the above test_must_fail succeeded because
> of a conflict and not due to any other failure?  I would have used
> "ls-files -u H2.t" to see if the index is unmerged, which probably
> is a more direct way to test what this is trying to test, but if we
> are in the conflicted state, the one side of << == >> has this
> string (the other has "H2" in it, presumably?), so in practice this
> should be good enough.
> 
> > +   echo resolved >H2.t &&
> > +   git add -u &&
> 
> and we resolve to continue.
> 
> > +   git rebase --continue &&
> > +   test_must_fail git rev-parse --verify HEAD^2 &&
> 
> Even if we made an octopus by mistake, the above will catch it,
> which is good.
> 
> > +   test_path_is_missing .git/MERGE_HEAD
> > +'
> > +
> >  test_done
> 
> And from the proposed log message, I am reading that the last two
> things (i.e. resulting tip is a child with a single parent and there
> is no leftover MERGE_HEAD file) fail without the fix.  
> 
> This is enough material to convince me or anybody that the bug is
> worth fixing.  Thanks for being careful noticing a glitch during
> your real (and otherwise unrelated to the bug) work and following
> through.
> 


Re: Regression: rebase -C1 fails in master

2018-11-13 Thread Johannes Schindelin
Hi Phillip,

On Mon, 12 Nov 2018, Phillip Wood wrote:

> I've just tried running
> 
> bin-wrappers/git rebase -C1 @^
> 
> and I get
> 
> error: unknown switch `1'

Darn. I think this is the same problem as the `-S` switch problem, but in
reverse: the built-in rebase used to require an argument for `-S` (it
should be optional, fixed in the meantime), but `-C` also has an optional
argument.

Let me see whether I can fix this quickly.

Ciao,
Dscho

> usage: git rebase [-i] [options] [--exec ] [--onto ]
> [] []
>or: git rebase [-i] [options] [--exec ] [--onto ]
> --root []
>or: git rebase --continue | --abort | --skip | --edit-todo
> ...
> 
> bin-wrappers/git --version gives
> git version 2.19.1.856.g8858448bb4
> 
> Unfortunately I've not got time it investigate properly at the moment.
> 
> Best Wishes
> 
> Phillip
> 


Re: [PATCH v2 2/2] rebase: Implement --merge via git-rebase--interactive

2018-11-13 Thread Johannes Schindelin
Hi Phillip,

On Mon, 12 Nov 2018, Phillip Wood wrote:

> It's good to see these patches progressing, I've just got a couple of
> comments related to Johannes' points below
> 
> On 12/11/2018 16:21, Johannes Schindelin wrote:
> > Hi Elijah,
> > 
> > On Wed, 7 Nov 2018, Elijah Newren wrote:
> > 
> >> Interactive rebases are implemented in terms of cherry-pick rather than
> >> the merge-recursive builtin, but cherry-pick also calls into the recursive
> >> merge machinery by default and can accept special merge strategies and/or
> >> special strategy options.  As such, there really is not any need for
> >> having both git-rebase--merge and git-rebase--interactive anymore.
> >>
> >> Delete git-rebase--merge.sh and have the --merge option be implemented
> >> by the now built-in interactive machinery.
> > 
> > Okay.
> > 
> >> Note that this change fixes a few known test failures (see t3421).
> > 
> > Nice!
> > 
> >> testcase modification notes:
> >>   t3406: --interactive and --merge had slightly different progress output
> >>  while running; adjust a test to match
> >>   t3420: these test precise output while running, but rebase--am,
> >>  rebase--merge, and rebase--interactive all were built on very
> >>  different commands (am, merge-recursive, cherry-pick), so the
> >>  tests expected different output for each type.  Now we expect
> >>  --merge and --interactive to have the same output.
> >>   t3421: --interactive fixes some bugs in --merge!  Wahoo!
> >>   t3425: topology linearization was inconsistent across flavors of rebase,
> >>  as already noted in a TODO comment in the testcase.  This was not
> >>  considered a bug before, so getting a different linearization due
> >>  to switching out backends should not be considered a bug now.
> > 
> > Ideally, the test would be fixed, then. If it fails for other reasons than
> > a real regression, it is not a very good regression test, is it.
> > 
> >>   t5407: different rebase types varied slightly in how many times checkout
> >>  or commit or equivalents were called based on a quick comparison
> >>  of this tests and previous ones which covered different rebase
> >>  flavors.  I think this is just attributable to this difference.
> > 
> > This concerns me.
> > 
> > In bigger repositories (no, I am not talking about Linux kernel sized
> > ones, I consider those small-ish) there are a ton of files, and checkout
> > and commit (and even more so reset) sadly do not have a runtime complexity
> > growing with the number of modified files, but with the number of tracked
> > files (and some commands even with the number of worktree files).
> > 
> > So a larger number of commit/checkout operations makes me expect
> > performance regressions.
> > 
> > In this light, could you elaborate a bit on the differences you see
> > between rebase -i and rebase -m?
> > 
> >>   t9903: --merge uses the interactive backend so the prompt expected is
> >>  now REBASE-i.
> > 
> > We should be able to make that test pass, still, by writing out a special
> > file (e.g. $state_dir/opt_m) and testing for that. Users are oddly upset
> > when their expectations are broken... (and I actually agree with them.)
> > 
> >> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
> >> index 3407d835bd..35084f5681 100644
> >> --- a/Documentation/git-rebase.txt
> >> +++ b/Documentation/git-rebase.txt
> >> @@ -504,15 +504,7 @@ See also INCOMPATIBLE OPTIONS below.
> >>  INCOMPATIBLE OPTIONS
> >>  
> >>  
> >> -git-rebase has many flags that are incompatible with each other,
> >> -predominantly due to the fact that it has three different underlying
> >> -implementations:
> >> -
> >> - * one based on linkgit:git-am[1] (the default)
> >> - * one based on git-merge-recursive (merge backend)
> >> - * one based on linkgit:git-cherry-pick[1] (interactive backend)
> >> -
> > 
> > Could we retain this part, with `s/three/two/` and `/git-merge/d`? *Maybe*
> > `s/interactive backend/interactive\/merge backend/`
> 
> I was hoping we could get rid of that, I'm not sure how useful it is to
> users.

That's a good point. If the commit message makes the case for that (it is
an implementation detail that confuses users), I am fine with removing it,
too.

Thanks

Re: [PATCH 2/2] read-cache: use time_t instead of unsigned long

2018-11-13 Thread Johannes Schindelin
Hi,

On Mon, 12 Nov 2018, Carlo Marcelo Arenas Belón wrote:

> There are still some more possible improvements around this code but
> they are orthogonal to this change :
> 
> * migrate to approxidate_careful or parse_expiry_date
> * maybe make sure only approxidate are used for expiration
> 
> Changes in v2:
> * improved commit message as suggested by Eric
> * failsafe against time_t truncation as suggested by Junio
> 
> -- >8 --
> Subject: [PATCH v2 2/2] read-cache: use time specific types instead of
>  unsigned long
> 
> b968372279 ("read-cache: unlink old sharedindex files", 2017-03-06)
> introduced get_shared_index_expire_date using unsigned long to track
> the modification times of a shared index.
> 
> dddbad728c ("timestamp_t: a new data type for timestamps", 2017-04-26)
> shows why that might be problematic so move to timestamp_t/time_t.
> 
> if time_t can't represent a valid time keep the indexes for failsafe

Is this sentence incomplete? What are those "indexes"?

Thanks,
Johannes

> 
> Signed-off-by: Carlo Marcelo Arenas Belón 
> ---
>  read-cache.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/read-cache.c b/read-cache.c
> index 7b1354d759..7d322f11c8 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -2625,9 +2625,9 @@ static int write_split_index(struct index_state *istate,
>  
>  static const char *shared_index_expire = "2.weeks.ago";
>  
> -static unsigned long get_shared_index_expire_date(void)
> +static timestamp_t get_shared_index_expire_date(void)
>  {
> - static unsigned long shared_index_expire_date;
> + static timestamp_t shared_index_expire_date;
>   static int shared_index_expire_date_prepared;
>  
>   if (!shared_index_expire_date_prepared) {
> @@ -2643,12 +2643,12 @@ static unsigned long 
> get_shared_index_expire_date(void)
>  static int should_delete_shared_index(const char *shared_index_path)
>  {
>   struct stat st;
> - unsigned long expiration;
> + time_t expiration;
> + timestamp_t t = get_shared_index_expire_date();
>  
> - /* Check timestamp */
> - expiration = get_shared_index_expire_date();
> - if (!expiration)
> + if (!t || date_overflows(t))
>   return 0;
> + expiration = t;
>   if (stat(shared_index_path, ))
>   return error_errno(_("could not stat '%s'"), shared_index_path);
>   if (st.st_mtime > expiration)
> -- 
> 2.19.1.856.g8858448bb
> 
> 

[PATCH 2/5] rebase -r: do not write MERGE_HEAD unless needed

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

When we detect that a `merge` can be skipped because the merged commit
is already an ancestor of HEAD, we do not need to commit, therefore
writing the MERGE_HEAD file is useless.

It is actually worse than useless: a subsequent `git commit` will pick
it up and think that we want to merge that commit, still.

To avoid that, move the code that writes the MERGE_HEAD file to a
location where we already know that the `merge` cannot be skipped.

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

diff --git a/sequencer.c b/sequencer.c
index 9e1ab3a2a7..7a9cd81afb 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -3191,10 +3191,6 @@ static int do_merge(struct commit *commit, const char 
*arg, int arg_len,
}
 
merge_commit = to_merge->item;
-   write_message(oid_to_hex(_commit->object.oid), GIT_SHA1_HEXSZ,
- git_path_merge_head(the_repository), 0);
-   write_message("no-ff", 5, git_path_merge_mode(the_repository), 0);
-
bases = get_merge_bases(head_commit, merge_commit);
if (bases && oideq(_commit->object.oid,
   >item->object.oid)) {
@@ -3203,6 +3199,10 @@ static int do_merge(struct commit *commit, const char 
*arg, int arg_len,
goto leave_merge;
}
 
+   write_message(oid_to_hex(_commit->object.oid), GIT_SHA1_HEXSZ,
+ git_path_merge_head(the_repository), 0);
+   write_message("no-ff", 5, git_path_merge_mode(the_repository), 0);
+
for (j = bases; j; j = j->next)
commit_list_insert(j->item, );
free_commit_list(bases);
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 1f08a33687..cc5646836f 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -396,7 +396,7 @@ test_expect_success 'with --autosquash and --exec' '
grep "G: +G" actual
 '
 
-test_expect_failure '--continue after resolving conflicts after a merge' '
+test_expect_success '--continue after resolving conflicts after a merge' '
git checkout -b already-has-g E &&
git cherry-pick E..G &&
test_commit H2 &&
-- 
gitgitgadget



[PATCH 3/5] rebase -i: include MERGE_HEAD into files to clean up

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

Every once in a while, the interactive rebase makes sure that no stale
files are lying around. These days, we need to include MERGE_HEAD into
that set of files, as the `merge` command will generate them.

Signed-off-by: Johannes Schindelin 
---
 sequencer.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sequencer.c b/sequencer.c
index 7a9cd81afb..2f526390ac 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -3459,6 +3459,7 @@ static int pick_commits(struct todo_list *todo_list, 
struct replay_opts *opts)
unlink(rebase_path_author_script());
unlink(rebase_path_stopped_sha());
unlink(rebase_path_amend());
+   unlink(git_path_merge_head(the_repository));
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
 
if (item->command == TODO_BREAK)
@@ -3829,6 +3830,7 @@ static int commit_staged_changes(struct replay_opts *opts,
   opts, flags))
return error(_("could not commit staged changes."));
unlink(rebase_path_amend());
+   unlink(git_path_merge_head(the_repository));
if (final_fixup) {
unlink(rebase_path_fixup_msg());
unlink(rebase_path_squash_msg());
-- 
gitgitgadget



[PATCH 5/5] status: rebase and merge can be in progress at the same time

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

Since `git rebase -r` was introduced, that is possible. But our
machinery did not think that possible, and failed to say anything about
the rebase in progress when in the middle of a merge.

Let's work around that in the minimal fashion.

Signed-off-by: Johannes Schindelin 
---
 wt-status.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/wt-status.c b/wt-status.c
index 187568a112..a24711374c 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1559,6 +1559,7 @@ void wt_status_get_state(struct wt_status_state *state,
struct object_id oid;
 
if (!stat(git_path_merge_head(the_repository), )) {
+   wt_status_check_rebase(NULL, state);
state->merge_in_progress = 1;
} else if (wt_status_check_rebase(NULL, state)) {
;   /* all set */
@@ -1583,9 +1584,13 @@ static void wt_longstatus_print_state(struct wt_status 
*s)
const char *state_color = color(WT_STATUS_HEADER, s);
struct wt_status_state *state = >state;
 
-   if (state->merge_in_progress)
+   if (state->merge_in_progress) {
+   if (state->rebase_interactive_in_progress) {
+   show_rebase_information(s, state_color);
+   fputs("\n", s->fp);
+   }
show_merge_in_progress(s, state_color);
-   else if (state->am_in_progress)
+   } else if (state->am_in_progress)
show_am_in_progress(s, state_color);
else if (state->rebase_in_progress || 
state->rebase_interactive_in_progress)
show_rebase_in_progress(s, state_color);
-- 
gitgitgadget


[PATCH 1/5] rebase -r: demonstrate bug with conflicting merges

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

When calling `merge` on a branch that has already been merged, that
`merge` is skipped quietly, but currently a MERGE_HEAD file is being
left behind and will then be grabbed by the next `pick` (that did
not want to create a *merge* commit).

Demonstrate this.

Signed-off-by: Johannes Schindelin 
---
 t/t3430-rebase-merges.sh | 16 
 1 file changed, 16 insertions(+)

diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index aa7bfc88ec..1f08a33687 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -396,4 +396,20 @@ test_expect_success 'with --autosquash and --exec' '
grep "G: +G" actual
 '
 
+test_expect_failure '--continue after resolving conflicts after a merge' '
+   git checkout -b already-has-g E &&
+   git cherry-pick E..G &&
+   test_commit H2 &&
+
+   git checkout -b conflicts-in-merge H &&
+   test_commit H2 H2.t conflicts H2-conflict &&
+   test_must_fail git rebase -r already-has-g &&
+   grep conflicts H2.t &&
+   echo resolved >H2.t &&
+   git add -u &&
+   git rebase --continue &&
+   test_must_fail git rev-parse --verify HEAD^2 &&
+   test_path_is_missing .git/MERGE_HEAD
+'
+
 test_done
-- 
gitgitgadget



[PATCH 4/5] built-in rebase --skip/--abort: clean up stale .git/ files

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

The scripted version of the rebase used to execute `git reset --hard`
when skipping or aborting. When we ported this to C, we did update the
worktree and some reflogs, but we failed to imitate `git reset --hard`'s
behavior regarding files in .git/ such as MERGE_HEAD.

Let's address this oversight.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 0ee06aa363..017dce1b50 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -23,6 +23,7 @@
 #include "revision.h"
 #include "commit-reach.h"
 #include "rerere.h"
+#include "branch.h"
 
 static char const * const builtin_rebase_usage[] = {
N_("git rebase [-i] [options] [--exec ] [--onto ] "
@@ -1002,6 +1003,7 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
 
if (reset_head(NULL, "reset", NULL, 0, NULL, NULL) < 0)
die(_("could not discard worktree changes"));
+   remove_branch_state();
if (read_basic_state())
exit(1);
goto run_rebase;
@@ -1019,6 +1021,7 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
   options.head_name, 0, NULL, NULL) < 0)
die(_("could not move back to %s"),
oid_to_hex(_head));
+   remove_branch_state();
ret = finish_rebase();
goto cleanup;
}
-- 
gitgitgadget



[PATCH 0/5] Assorted fixes revolving around rebase and merges

2018-11-12 Thread Johannes Schindelin via GitGitGadget
I noticed a couple of weeks ago that I had bogus merge commits after my
rebases, where the original commits had been regular commits.

This set me out on the adventure that is reflected in this patch series.

Of course, the thing I wanted to fix is demonstrated by 1/5 and fixed in
2/5. But while at it, I ran into other issues and fixed them since I was at
it anyway.

Johannes Schindelin (5):
  rebase -r: demonstrate bug with conflicting merges
  rebase -r: do not write MERGE_HEAD unless needed
  rebase -i: include MERGE_HEAD into files to clean up
  built-in rebase --skip/--abort: clean up stale .git/ files
  status: rebase and merge can be in progress at the same time

 builtin/rebase.c |  3 +++
 sequencer.c  | 10 ++
 t/t3430-rebase-merges.sh | 16 
 wt-status.c  |  9 +++--
 4 files changed, 32 insertions(+), 6 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-75%2Fdscho%2Frebase-r-and-merge-head-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-75/dscho/rebase-r-and-merge-head-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/75
-- 
gitgitgadget


[PATCH 1/1] apply --recount: allow "no-op hunks"

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

When editing patches e.g. in `git add -e`, it is quite common that a
hunk ends up having no -/+ lines, i.e. it is now supposed to do nothing.

This use case was broken by ad6e8ed37bc1 (apply: reject a hunk that does
not do anything, 2015-06-01) with the good intention of catching a very
real, different issue in hand-edited patches.

So let's use the `--recount` option as the tell-tale whether the user
would actually be okay with no-op hunks.

Add a test case to make sure that this use case does not regress again.

Signed-off-by: Johannes Schindelin 
---
 apply.c|  2 +-
 t/t4136-apply-check.sh | 12 
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/apply.c b/apply.c
index 073d5f0451..76955afb00 100644
--- a/apply.c
+++ b/apply.c
@@ -1748,7 +1748,7 @@ static int parse_fragment(struct apply_state *state,
}
if (oldlines || newlines)
return -1;
-   if (!deleted && !added)
+   if (!patch->recount && !deleted && !added)
return -1;
 
fragment->leading = leading;
diff --git a/t/t4136-apply-check.sh b/t/t4136-apply-check.sh
index 6d92872318..4c3f264a63 100755
--- a/t/t4136-apply-check.sh
+++ b/t/t4136-apply-check.sh
@@ -29,6 +29,18 @@ test_expect_success 'apply exits non-zero with no-op patch' '
test_must_fail git apply --check input
 '
 
+test_expect_success '`apply --recount` allows no-op patch' '
+   echo 1 >1 &&
+   git apply --recount --check <<-\EOF
+   diff --get a/1 b/1
+   index 6696ea4..606eddd 100644
+   --- a/1
+   +++ b/1
+   @@ -1,1 +1,1 @@
+1
+   EOF
+'
+
 test_expect_success 'invalid combination: create and copy' '
test_must_fail git apply --check - <<-\EOF
diff --git a/1 b/2
-- 
gitgitgadget


[PATCH 0/1] Allow "no-op hunks" when editing the diff in git add -e

2018-11-12 Thread Johannes Schindelin via GitGitGadget
I use git add -e frequently. Often there are multiple hunks and I end up
deleting the + lines and converting the - lines to context lines, as I like
to stage massive changes in an incremental fashion (and commit those staged
changes incrementally, too).

Some time after I invented git add -e, this feature was broken, and I had to
start identifying and deleting those hunks with no changes.

I finally got around to find the regression, and to fix it. Here is the
outcome of this effort.

Johannes Schindelin (1):
  apply --recount: allow "no-op hunks"

 apply.c|  2 +-
 t/t4136-apply-check.sh | 12 
 2 files changed, 13 insertions(+), 1 deletion(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-74%2Fdscho%2Fapply-recount-empty-hunk-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-74/dscho/apply-recount-empty-hunk-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/74
-- 
gitgitgadget


Re: [RFC/PATCH 1/5] Makefile: move long inline shell loops in "install" into helper

2018-11-12 Thread Johannes Schindelin
Hi Ævar,

On Mon, 12 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> On Mon, Nov 12 2018, Johannes Schindelin wrote:
> 
> > On Fri, 2 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> >
> >> Move a 37 line for-loop mess out of "install" and into a helper
> >> script. This started out fairly innocent but over the years has grown
> >> into a hard-to-maintain monster, and my recent ad874608d8 ("Makefile:
> >> optionally symlink libexec/git-core binaries to bin/git", 2018-03-13)
> >> certainly didn't help.
> >>
> >> The shell code is ported pretty much as-is (with getopts added), it'll
> >> be fixed & prettified in subsequent commits.
> >>
> >> Signed-off-by: Ævar Arnfjörð Bjarmason 
> >> ---
> >>  Makefile | 52 
> >>  install_programs | 89 
> >>  2 files changed, 103 insertions(+), 38 deletions(-)
> >>  create mode 100755 install_programs
> >>
> >> diff --git a/Makefile b/Makefile
> >> index bbfbb4292d..aa6ca1fa68 100644
> >> --- a/Makefile
> >> +++ b/Makefile
> >> @@ -2808,44 +2808,20 @@ endif
> >>bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
> >>execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
> >>destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 
> >> 's|[^/][^/]*|..|g') && \
> >> -  { test "$$bindir/" = "$$execdir/" || \
> >> -for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); 
> >> do \
> >> -  $(RM) "$$execdir/$$p" && \
> >> -  test -n "$(INSTALL_SYMLINKS)" && \
> >> -  ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" 
> >> "$$execdir/$$p" || \
> >> -  { test -z 
> >> "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
> >> -ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \
> >> -cp "$$bindir/$$p" "$$execdir/$$p" || exit; } \
> >> -done; \
> >> -  } && \
> >> -  for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \
> >> -  $(RM) "$$bindir/$$p" && \
> >> -  test -n "$(INSTALL_SYMLINKS)" && \
> >> -  ln -s "git$X" "$$bindir/$$p" || \
> >> -  { test -z "$(NO_INSTALL_HARDLINKS)" && \
> >> -ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
> >> -ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
> >> -cp "$$bindir/git$X" "$$bindir/$$p" || exit; } \
> >> -  done && \
> >> -  for p in $(BUILT_INS); do \
> >> -  $(RM) "$$execdir/$$p" && \
> >> -  test -n "$(INSTALL_SYMLINKS)" && \
> >> -  ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/git$X" 
> >> "$$execdir/$$p" || \
> >> -  { test -z "$(NO_INSTALL_HARDLINKS)" && \
> >> -ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
> >> -ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
> >> -cp "$$execdir/git$X" "$$execdir/$$p" || exit; } \
> >> -  done && \
> >> -  remote_curl_aliases="$(REMOTE_CURL_ALIASES)" && \
> >> -  for p in $$remote_curl_aliases; do \
> >> -  $(RM) "$$execdir/$$p" && \
> >> -  test -n "$(INSTALL_SYMLINKS)" && \
> >> -  ln -s "git-remote-http$X" "$$execdir/$$p" || \
> >> -  { test -z "$(NO_INSTALL_HARDLINKS)" && \
> >> -ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null 
> >> || \
> >> -ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
> >> -cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; } \
> >> -  done && \
> >
> > This indeed looks like a mess...
> >
> >> +  ./install_programs \
> >> +  --X="$$X" \
> >> +   

Re: [PATCH v2 2/2] rebase: Implement --merge via git-rebase--interactive

2018-11-12 Thread Johannes Schindelin
Hi Elijah,

On Wed, 7 Nov 2018, Elijah Newren wrote:

> Interactive rebases are implemented in terms of cherry-pick rather than
> the merge-recursive builtin, but cherry-pick also calls into the recursive
> merge machinery by default and can accept special merge strategies and/or
> special strategy options.  As such, there really is not any need for
> having both git-rebase--merge and git-rebase--interactive anymore.
> 
> Delete git-rebase--merge.sh and have the --merge option be implemented
> by the now built-in interactive machinery.

Okay.

> Note that this change fixes a few known test failures (see t3421).

Nice!

> testcase modification notes:
>   t3406: --interactive and --merge had slightly different progress output
>  while running; adjust a test to match
>   t3420: these test precise output while running, but rebase--am,
>  rebase--merge, and rebase--interactive all were built on very
>  different commands (am, merge-recursive, cherry-pick), so the
>  tests expected different output for each type.  Now we expect
>  --merge and --interactive to have the same output.
>   t3421: --interactive fixes some bugs in --merge!  Wahoo!
>   t3425: topology linearization was inconsistent across flavors of rebase,
>  as already noted in a TODO comment in the testcase.  This was not
>  considered a bug before, so getting a different linearization due
>  to switching out backends should not be considered a bug now.

Ideally, the test would be fixed, then. If it fails for other reasons than
a real regression, it is not a very good regression test, is it.

>   t5407: different rebase types varied slightly in how many times checkout
>  or commit or equivalents were called based on a quick comparison
>  of this tests and previous ones which covered different rebase
>  flavors.  I think this is just attributable to this difference.

This concerns me.

In bigger repositories (no, I am not talking about Linux kernel sized
ones, I consider those small-ish) there are a ton of files, and checkout
and commit (and even more so reset) sadly do not have a runtime complexity
growing with the number of modified files, but with the number of tracked
files (and some commands even with the number of worktree files).

So a larger number of commit/checkout operations makes me expect
performance regressions.

In this light, could you elaborate a bit on the differences you see
between rebase -i and rebase -m?

>   t9903: --merge uses the interactive backend so the prompt expected is
>  now REBASE-i.

We should be able to make that test pass, still, by writing out a special
file (e.g. $state_dir/opt_m) and testing for that. Users are oddly upset
when their expectations are broken... (and I actually agree with them.)

> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
> index 3407d835bd..35084f5681 100644
> --- a/Documentation/git-rebase.txt
> +++ b/Documentation/git-rebase.txt
> @@ -504,15 +504,7 @@ See also INCOMPATIBLE OPTIONS below.
>  INCOMPATIBLE OPTIONS
>  
>  
> -git-rebase has many flags that are incompatible with each other,
> -predominantly due to the fact that it has three different underlying
> -implementations:
> -
> - * one based on linkgit:git-am[1] (the default)
> - * one based on git-merge-recursive (merge backend)
> - * one based on linkgit:git-cherry-pick[1] (interactive backend)
> -

Could we retain this part, with `s/three/two/` and `/git-merge/d`? *Maybe*
`s/interactive backend/interactive\/merge backend/`

> -Flags only understood by the am backend:
> +The following options:
>  
>   * --committer-date-is-author-date
>   * --ignore-date
> @@ -520,15 +512,12 @@ Flags only understood by the am backend:
>   * --ignore-whitespace
>   * -C
>  
> -Flags understood by both merge and interactive backends:
> +are incompatible with the following options:
>  
>   * --merge
>   * --strategy
>   * --strategy-option
>   * --allow-empty-message
> -
> -Flags only understood by the interactive backend:
> -
>   * --[no-]autosquash
>   * --rebase-merges
>   * --preserve-merges
> @@ -539,7 +528,7 @@ Flags only understood by the interactive backend:
>   * --edit-todo
>   * --root when used in combination with --onto
>  
> -Other incompatible flag pairs:
> +In addition, the following pairs of options are incompatible:
>  
>   * --preserve-merges and --interactive
>   * --preserve-merges and --signoff

The rest of the diff is funny to read, but the post image makes a lot of
sense.

> diff --git a/builtin/rebase.c b/builtin/rebase.c
> index be004406a6..d55bbb9eb9 100644
> --- a/builtin/rebase.c
> +++ b/builtin/rebase.c
> @@ -118,7 +118,7 @@ static void imply_interactive(struct rebase_options 
> *opts, const char *option)
>   case REBASE_PRESERVE_MERGES:
>   break;
>   case REBASE_MERGE:
> - /* we silently *upgrade* --merge to --interactive if needed */
> + 

Re: [PATCH v2 1/2] git-rebase, sequencer: extend --quiet option for the interactive machinery

2018-11-12 Thread Johannes Schindelin
Hi Elijah,

On Wed, 7 Nov 2018, Elijah Newren wrote:

> While 'quiet' and 'interactive' may sound like antonyms, the interactive
> machinery actually has logic that implements several
> interactive_rebase=implied cases (--exec, --keep-empty, --rebase-merges)
> which won't pop up an editor.  The rewrite of interactive rebase in C
> added a quiet option, though it only turns stats off.  Since we want to
> make the interactive machinery also take over for git-rebase--merge, it
> should fully implement the --quiet option.
> 
> git-rebase--interactive was already somewhat quieter than
> git-rebase--merge and git-rebase--am, possibly because cherry-pick has
> just traditionally been quieter.  As such, we only drop a few
> informational messages -- "Rebasing (n/m)" and "Succesfully rebased..."

Makes sense.

> Also, for simplicity, remove the differences in how quiet and verbose
> options were recorded.  Having one be signalled by the presence of a
> "verbose" file in the state_dir, while the other was signalled by the
> contents of a "quiet" file was just weirdly inconsistent.  (This
> inconsistency pre-dated the rewrite into C.)  Make them consistent by
> having them both key off the presence of the file.

I am slightly concerned that some creative power user could have written
scripts that rely on this behavior.

But only *slightly* concerned.

The patch looks correct.

Ciao,
Dscho

> 
> Signed-off-by: Elijah Newren 
> ---
>  builtin/rebase.c  |  5 +
>  git-legacy-rebase.sh  |  2 +-
>  git-rebase--common.sh |  2 +-
>  sequencer.c   | 23 +--
>  sequencer.h   |  1 +
>  5 files changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/builtin/rebase.c b/builtin/rebase.c
> index 0ee06aa363..be004406a6 100644
> --- a/builtin/rebase.c
> +++ b/builtin/rebase.c
> @@ -181,10 +181,7 @@ static int read_basic_state(struct rebase_options *opts)
>   if (get_oid(buf.buf, >orig_head))
>   return error(_("invalid orig-head: '%s'"), buf.buf);
>  
> - strbuf_reset();
> - if (read_one(state_dir_path("quiet", opts), ))
> - return -1;
> - if (buf.len)
> + if (file_exists(state_dir_path("quiet", opts)))
>   opts->flags &= ~REBASE_NO_QUIET;
>   else
>   opts->flags |= REBASE_NO_QUIET;
> diff --git a/git-legacy-rebase.sh b/git-legacy-rebase.sh
> index 75a08b2683..da27bfca5a 100755
> --- a/git-legacy-rebase.sh
> +++ b/git-legacy-rebase.sh
> @@ -113,7 +113,7 @@ read_basic_state () {
>   else
>   orig_head=$(cat "$state_dir"/head)
>   fi &&
> - GIT_QUIET=$(cat "$state_dir"/quiet) &&
> + test -f "$state_dir"/quiet && GIT_QUIET=t
>   test -f "$state_dir"/verbose && verbose=t
>   test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
>   test -f "$state_dir"/strategy_opts &&
> diff --git a/git-rebase--common.sh b/git-rebase--common.sh
> index 7e39d22871..dc18c682fa 100644
> --- a/git-rebase--common.sh
> +++ b/git-rebase--common.sh
> @@ -10,7 +10,7 @@ write_basic_state () {
>   echo "$head_name" > "$state_dir"/head-name &&
>   echo "$onto" > "$state_dir"/onto &&
>   echo "$orig_head" > "$state_dir"/orig-head &&
> - echo "$GIT_QUIET" > "$state_dir"/quiet &&
> + test t = "$GIT_QUIET" && : > "$state_dir"/quiet
>   test t = "$verbose" && : > "$state_dir"/verbose
>   test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
>   test -n "$strategy_opts" && echo "$strategy_opts" > \
> diff --git a/sequencer.c b/sequencer.c
> index 9e1ab3a2a7..bd8337dbf1 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -150,6 +150,7 @@ static GIT_PATH_FUNC(rebase_path_refs_to_delete, 
> "rebase-merge/refs-to-delete")
>  static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
>  static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
>  static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
> +static GIT_PATH_FUNC(rebase_path_quiet, "rebase-merge/quiet")
>  static GIT_PATH_FUNC(rebase_path_signoff, "rebase-merge/signoff")
>  static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
>  static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
> @@ -157,7 +158,6 @@ static GIT_PATH_FUNC(rebase_path_autostash, 
> "rebase-merge/autostash")
>  static GIT_PATH_FUNC(rebase_path_strategy, "rebase-merge/strategy")
>  static GIT_PATH_FUNC(rebase_path_strategy_opts, "rebase-merge/strategy_opts")
>  static GIT_PATH_FUNC(rebase_path_allow_rerere_autoupdate, 
> "rebase-merge/allow_rerere_autoupdate")
> -static GIT_PATH_FUNC(rebase_path_quiet, "rebase-merge/quiet")
>  
>  static int git_sequencer_config(const char *k, const char *v, void *cb)
>  {
> @@ -2307,6 +2307,9 @@ static int read_populate_opts(struct replay_opts *opts)
>   if (file_exists(rebase_path_verbose()))
>   opts->verbose = 1;
>  
> + if (file_exists(rebase_path_quiet()))
> + 

Re: [PATCH 2/2] read-cache: use time_t instead of unsigned long

2018-11-12 Thread Johannes Schindelin
Hi,

On Mon, 12 Nov 2018, Junio C Hamano wrote:

> Carlo Marcelo Arenas Belón   writes:
> 
> > b968372279 ("read-cache: unlink old sharedindex files", 2017-03-06)
> > introduced get_shared_index_expire_date using unsigned long to track
> > the modification times of a shared index.
> >
> > dddbad728c ("timestamp_t: a new data type for timestamps", 2017-04-26)
> > shows why that might problematic so move to time_t instead.
> >
> > Signed-off-by: Carlo Marcelo Arenas Belón 
> > ---
> >  read-cache.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/read-cache.c b/read-cache.c
> > index 7b1354d759..5525d8e679 100644
> > --- a/read-cache.c
> > +++ b/read-cache.c
> > @@ -2625,9 +2625,9 @@ static int write_split_index(struct index_state 
> > *istate,
> >  
> >  static const char *shared_index_expire = "2.weeks.ago";
> >  
> > -static unsigned long get_shared_index_expire_date(void)
> > +static time_t get_shared_index_expire_date(void)
> >  {
> > -   static unsigned long shared_index_expire_date;
> > +   static time_t shared_index_expire_date;
> > static int shared_index_expire_date_prepared;
> >  
> > if (!shared_index_expire_date_prepared) {
> 
> After this line, the post-context reads like this:
> 
>   git_config_get_expiry("splitindex.sharedindexexpire",
> _index_expire);
>   shared_index_expire_date = approxidate(shared_index_expire);
>   shared_index_expire_date_prepared = 1;
>   }
> 
>   return shared_index_expire_date;
> 
> Given that the function returns the value obtained from
> approxidate(), which is approxidate_careful() in disguise, time_t is
> not as appropriate as timestamp_t, no?
> 
> IOW, what if time_t were narrower than timestamp_t?

Rght. From the patch, I had assumed that the return type of
`approxidate()` is `time_t`, but it is `timestamp_t`.

Ciao,
Johannes

> 
> 
> > @@ -2643,7 +2643,7 @@ static unsigned long 
> > get_shared_index_expire_date(void)
> >  static int should_delete_shared_index(const char *shared_index_path)
> >  {
> > struct stat st;
> > -   unsigned long expiration;
> > +   time_t expiration;
> >  
> > /* Check timestamp */
> > expiration = get_shared_index_expire_date();
> 

Re: [PATCH v2 0/3] Fix built-in rebase perf regression

2018-11-12 Thread Johannes Schindelin
Hi,

On Mon, 12 Nov 2018, Johannes Schindelin via GitGitGadget wrote:

> In our tests with large repositories, we noticed a serious regression of the
> performance of git rebase when using the built-in vs the shell script
> version. It boils down to an incorrect conversion of a git checkout -q:
> instead of using a twoway_merge as git checkout does, we used a oneway_merge 
> as git reset does. The latter, however, calls lstat() on all files listed in
> the index, while the former essentially looks only at the files that are
> different between the given two revisions.
> 
> Let's reinstate the original behavior by introducing a flag to the 
> reset_head() function to indicate whether we want to emulate reset --hard 
> (in which case we use the oneway_merge, otherwise we use twoway_merge).
> 
> Johannes Schindelin (3):
>   rebase: consolidate clean-up code before leaving reset_head()
>   rebase: prepare reset_head() for more flags
>   built-in rebase: reinstate `checkout -q` behavior where appropriate
> 
>  builtin/rebase.c | 79 
>  1 file changed, 46 insertions(+), 33 deletions(-)

I forgot to specify the changes vs v1:

- More error paths are not consolidated via `goto leave_reset_head`.
- The `desc` array is not initialized to all-zero, to avoid bogus
  addresses being passed to `free()`.
- The `detach_head` and `reset_hard` parameters have been consolidated
  into a `flags` parameter.
- The `reset_head()` function once again only initializes `head_oid`
  when needed.

Sorry for the omission,
Johannes

> 
> 
> base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
> Published-As: 
> https://github.com/gitgitgadget/git/releases/tags/pr-72%2Fdscho%2Fbuiltin-rebase-perf-regression-v2
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
> pr-72/dscho/builtin-rebase-perf-regression-v2
> Pull-Request: https://github.com/gitgitgadget/git/pull/72
> 
> Range-diff vs v1:
> 
>  1:  64597fe827 ! 1:  28e24d98ab rebase: consolidate clean-up code before 
> leaving reset_head()
>  @@ -11,6 +11,33 @@
>   --- a/builtin/rebase.c
>   +++ b/builtin/rebase.c
>   @@
>  +if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
>  +BUG("Not a fully qualified branch: '%s'", 
> switch_to_branch);
>  + 
>  +-   if (hold_locked_index(, LOCK_REPORT_ON_ERROR) < 0)
>  +-   return -1;
>  ++   if (hold_locked_index(, LOCK_REPORT_ON_ERROR) < 0) {
>  ++   ret = -1;
>  ++   goto leave_reset_head;
>  ++   }
>  + 
>  +if (!oid) {
>  +if (get_oid("HEAD", _oid)) {
>  +-   rollback_lock_file();
>  +-   return error(_("could not determine HEAD 
> revision"));
>  ++   ret = error(_("could not determine HEAD 
> revision"));
>  ++   goto leave_reset_head;
>  +}
>  +oid = _oid;
>  +}
>  +@@
>  +unpack_tree_opts.reset = 1;
>  + 
>  +if (read_index_unmerged(the_repository->index) < 0) {
>  +-   rollback_lock_file();
>  +-   return error(_("could not read index"));
>  ++   ret = error(_("could not read index"));
>  ++   goto leave_reset_head;
>   }
>
>   if (!fill_tree_descriptor(, oid)) {
>  @@ -31,15 +58,17 @@
>   }
>
>   tree = parse_tree_indirect(oid);
>  -@@
>  +prime_cache_tree(the_repository->index, tree);
>
>  -if (write_locked_index(the_repository->index, , 
> COMMIT_LOCK) < 0)
>  +-   if (write_locked_index(the_repository->index, , 
> COMMIT_LOCK) < 0)
>  ++   if (write_locked_index(the_repository->index, , 
> COMMIT_LOCK) < 0) {
>   ret = error(_("could not write index"));
>   -   free((void *)desc.buffer);
>  - 
>  -if (ret)
>  +-
>  +-   if (ret)
>   -   return ret;
>   +   goto leave_reset_head;
>  ++   }
>
>   reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
>   strbuf_addf(, "%s: ", reflog_action ? reflog_action : 
> "rebase");
>  -:  -- > 2:  db963b2094 rebase: prepare reset_head() for more flags
>  2:  070092b430 ! 3:  a7360b856f built-in rebase: reinstate `checkout -q` 
> behav

Re: [RFC/PATCH 5/5] Makefile: Add a NO_INSTALL_BUILTIN_EXECDIR_ALIASES flag

2018-11-12 Thread Johannes Schindelin
Hi Ævar,

On Fri, 2 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> Back when git was initially written the likes of "git-add", "git-init"
> etc. were installed in the user's $PATH. A few years later everything,
> with a few exceptions like git-upload-pack and git-receive-pack, was
> expected to be invoked as "git $cmd".
> 
> Now something like a decade later we're still installing these old
> commands in gitexecdir. This is so someone with a shellscript that
> still targets e.g. "git-init" can add $(git --exec-path) to their
> $PATH and not have to change their script.
> 
> Let's add an option to break this backwards compatibility. Now with
> NO_INSTALL_BUILTIN_EXECDIR_ALIASES=YesPlease there's only 3 programs
> in the bindir that are hardlinked to "git" (receive-pack,
> upload-archive & upload-pack), and 3 in the
> gitexecdir (git-remote-{ftp,ftps,https} linked to git-remote-http).
> 
> There's no cross-directory links anymore, so the
> "NO_CROSS_DIRECTORY_HARDLINKS" flag becomes redundant under this new
> option.
> 
> 1. https://public-inbox.org/git/87woyfdkoi@evledraar.gmail.com/
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason 
> ---

I like the idea.

With my suggested refactoring that avoids the non-DRY code, this patch
would also become much simpler (as would 2/5 -- 4/5).

However, I would not call these "aliases". That's just confusing. Maybe
NO_INSTALL_DASHED_BUILTINS would be better? It certainly would not have
confused me.

Ciao,
Dscho

>  Makefile |  8 
>  install_programs | 36 +---
>  2 files changed, 29 insertions(+), 15 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index 07c8b74353..a849a7b6d1 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -346,6 +346,13 @@ all::
>  # INSTALL_SYMLINKS if you'd prefer not to have the install procedure
>  # fallack on hardlinking or copying if "ln -s" fails.
>  #
> +# Define NO_INSTALL_BUILTIN_EXECDIR_ALIASES if you'd like to skip
> +# installing legacy such as "git-init" and "git-add" in the
> +# gitexecdir. Unless you're on a system where "which git-init" is
> +# expected to returns something set this. Users have been expected to
> +# use the likes of "git init" for ages now, these programs were only
> +# provided for legacy compatibility.
> +#
>  # Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed
>  # programs as a tar, where bin/ and libexec/ might be on different file 
> systems.
>  #
> @@ -2823,6 +2830,7 @@ endif
>   --flag-no-install-hardlinks="$(NO_INSTALL_HARDLINKS)" \
>   
> --flag-no-cross-directory-hardlinks="$(NO_CROSS_DIRECTORY_HARDLINKS)" \
>   
> --flag-no-install-symlinks-fallback="$(NO_INSTALL_SYMLINKS_FALLBACK)" \
> + 
> --flag-no-install-builtin-execdir-aliases="$(NO_INSTALL_BUILTIN_EXECDIR_ALIASES)"
>  \
>   --list-bindir-standalone="git$X $(filter 
> $(install_bindir_programs),$(ALL_PROGRAMS))" \
>   --list-bindir-git-dashed="$(filter 
> $(install_bindir_programs),$(BUILT_INS))" \
>   --list-execdir-git-dashed="$(BUILT_INS)" \
> diff --git a/install_programs b/install_programs
> index 51e08019dd..8d89cd9984 100755
> --- a/install_programs
> +++ b/install_programs
> @@ -33,6 +33,9 @@ do
>   --flag-no-install-symlinks-fallback=*)
>   
> NO_INSTALL_SYMLINKS_FALLBACK="${1#--flag-no-install-symlinks-fallback=}"
>   ;;
> + --flag-no-install-builtin-execdir-aliases=*)
> + 
> NO_INSTALL_BUILTIN_EXECDIR_ALIASES="${1#--flag-no-install-builtin-execdir-aliases=}"
> + ;;
>   --list-bindir-standalone=*)
>   list_bindir_standalone="${1#--list-bindir-standalone=}"
>   ;;
> @@ -54,7 +57,7 @@ do
>   shift
>  done &&
>  
> -if test "$bindir/" != "$execdir/"
> +if test "$bindir/" != "$execdir/" -a -z "$NO_INSTALL_BUILTIN_EXECDIR_ALIASES"
>  then
>   for p in $list_bindir_standalone; do
>   $RM "$execdir/$p" &&
> @@ -87,20 +90,23 @@ do
>   fi
>  done &&
>  
> -for p in $list_execdir_git_dashed; do
> - $RM "$execdir/$p" &&
> - if test -n "$INSTALL_SYMLINKS" -a -n "$NO_INSTALL_SYMLINKS_FALLBACK"
> - then
> - ln -s "$destdir_from_execdir/$bindir_relative/git$X" 
> "$execdir/$p"
> - else
> - test -n "$INSTALL_SYMLINKS" &&
> - ln -s "$destdir_from_execdir/$bindir_relative/git$X" 
> "$execdir/$p" ||
> - { test -z "$NO_INSTALL_HARDLINKS" &&
> -   ln "$execdir/git$X" "$execdir/$p" ||
> -   ln -s "git$X" "$execdir/$p" ||
> -   cp "$execdir/git$X" "$execdir/$p" || exit; }
> - fi
> -done &&
> +if test -z "$NO_INSTALL_BUILTIN_EXECDIR_ALIASES"
> +then
> + for p in $list_execdir_git_dashed; do
> + $RM "$execdir/$p" &&
> + if test -n "$INSTALL_SYMLINKS" -a -n 
> "$NO_INSTALL_SYMLINKS_FALLBACK"
> + then
> + ln -s 

Re: [RFC/PATCH 1/5] Makefile: move long inline shell loops in "install" into helper

2018-11-12 Thread Johannes Schindelin
Hi,

On Fri, 2 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> Move a 37 line for-loop mess out of "install" and into a helper
> script. This started out fairly innocent but over the years has grown
> into a hard-to-maintain monster, and my recent ad874608d8 ("Makefile:
> optionally symlink libexec/git-core binaries to bin/git", 2018-03-13)
> certainly didn't help.
> 
> The shell code is ported pretty much as-is (with getopts added), it'll
> be fixed & prettified in subsequent commits.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason 
> ---
>  Makefile | 52 
>  install_programs | 89 
>  2 files changed, 103 insertions(+), 38 deletions(-)
>  create mode 100755 install_programs
> 
> diff --git a/Makefile b/Makefile
> index bbfbb4292d..aa6ca1fa68 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -2808,44 +2808,20 @@ endif
>   bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
>   execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
>   destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 
> 's|[^/][^/]*|..|g') && \
> - { test "$$bindir/" = "$$execdir/" || \
> -   for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); 
> do \
> - $(RM) "$$execdir/$$p" && \
> - test -n "$(INSTALL_SYMLINKS)" && \
> - ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" 
> "$$execdir/$$p" || \
> - { test -z 
> "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
> -   ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \
> -   cp "$$bindir/$$p" "$$execdir/$$p" || exit; } \
> -   done; \
> - } && \
> - for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \
> - $(RM) "$$bindir/$$p" && \
> - test -n "$(INSTALL_SYMLINKS)" && \
> - ln -s "git$X" "$$bindir/$$p" || \
> - { test -z "$(NO_INSTALL_HARDLINKS)" && \
> -   ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
> -   ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
> -   cp "$$bindir/git$X" "$$bindir/$$p" || exit; } \
> - done && \
> - for p in $(BUILT_INS); do \
> - $(RM) "$$execdir/$$p" && \
> - test -n "$(INSTALL_SYMLINKS)" && \
> - ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/git$X" 
> "$$execdir/$$p" || \
> - { test -z "$(NO_INSTALL_HARDLINKS)" && \
> -   ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
> -   ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
> -   cp "$$execdir/git$X" "$$execdir/$$p" || exit; } \
> - done && \
> - remote_curl_aliases="$(REMOTE_CURL_ALIASES)" && \
> - for p in $$remote_curl_aliases; do \
> - $(RM) "$$execdir/$$p" && \
> - test -n "$(INSTALL_SYMLINKS)" && \
> - ln -s "git-remote-http$X" "$$execdir/$$p" || \
> - { test -z "$(NO_INSTALL_HARDLINKS)" && \
> -   ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null 
> || \
> -   ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
> -   cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; } \
> - done && \

This indeed looks like a mess...

> + ./install_programs \
> + --X="$$X" \
> + --RM="$(RM)" \
> + --bindir="$$bindir" \
> + --bindir-relative="$(bindir_relative_SQ)" \
> + --execdir="$$execdir" \
> + --destdir-from-execdir="$$destdir_from_execdir_SQ" \
> + --flag-install-symlinks="$(INSTALL_SYMLINKS)" \
> + --flag-no-install-hardlinks="$(NO_INSTALL_HARDLINKS)" \
> + 
> --flag-no-cross-directory-hardlinks="$(NO_CROSS_DIRECTORY_HARDLINKS)" \
> + --list-bindir-standalone="git$X $(filter 
> $(install_bindir_programs),$(ALL_PROGRAMS))" \
> + --list-bindir-git-dashed="$(filter 
> $(install_bindir_programs),$(BUILT_INS))" \
> + --list-execdir-git-dashed="$(BUILT_INS)" \
> + --list-execdir-curl-aliases="$(REMOTE_CURL_ALIASES)" && \
>   ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
>  
>  .PHONY: install-gitweb install-doc install-man install-man-perl install-html 
> install-info install-pdf
> diff --git a/install_programs b/install_programs
> new file mode 100755
> index 00..e287108112
> --- /dev/null
> +++ b/install_programs
> @@ -0,0 +1,89 @@
> +#!/bin/sh
> +
> +while test $# != 0
> +do
> + case "$1" in
> + --X=*)
> + X="${1#--X=}"
> + ;;
> + --RM=*)
> + RM="${1#--RM=}"
> + ;;
> + --bindir=*)
> + bindir="${1#--bindir=}"
> + ;;
> + --bindir-relative=*)
> + bindir_relative="${1#--bindir-relative=}"
> + ;;
> + --execdir=*)
> + execdir="${1#--execdir=}"
> + 

[PATCH 4/5] tests: do not require Git to be built when testing an installed Git

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

We really only need the test helpers in that case, but that is not what
we test for. So let's skip the test for now when we know that we want to
test an installed Git.

Signed-off-by: Johannes Schindelin 
---
 t/test-lib.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/test-lib.sh b/t/test-lib.sh
index 832ede5099..1ea20dc2dc 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -51,7 +51,7 @@ export LSAN_OPTIONS
 
 
 # It appears that people try to run tests without building...
-"$GIT_BUILD_DIR/git" >/dev/null
+test -n "$GIT_TEST_INSTALLED" || "$GIT_BUILD_DIR/git" >/dev/null ||
 if test $? != 1
 then
echo >&2 'error: you do not seem to have built git yet.'
-- 
gitgitgadget



[PATCH 5/5] tests: explicitly use `git.exe` on Windows

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

In the bin-wrappers/* scripts, we already take pains to use `git.exe`
rather than `git`, as this could pick up the wrong thing on Windows
(i.e. if there exists a `git` file or directory in the build directory).

Now we do the same in the tests' start-up code.

This also helps when testing an installed Git, as there might be even
more likely some stray file or directory in the way.

Note: the only way we can record whether the `.exe` suffix is by writing
it to the `GIT-BUILD-OPTIONS` file and sourcing it at the beginning of
`t/test-lib.sh`. This is not a requirement introduced by this patch, but
we move the call to be able to use the `$X` variable that holds the file
extension, if any.

Note also: the many, many calls to `git this` and `git that` are
unaffected, as the regular PATH search will find the `.exe` files on
Windows (and not be confused by a directory of the name `git` that is
in one of the directories listed in the `PATH` variable), while
`/path/to/git` would not, per se, know that it is looking for an
executable and happily prefer such a directory.

Signed-off-by: Johannes Schindelin 
---
 Makefile|  1 +
 t/test-lib-functions.sh |  2 +-
 t/test-lib.sh   | 13 +
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index bbfbb4292d..5df0118ce9 100644
--- a/Makefile
+++ b/Makefile
@@ -2590,6 +2590,7 @@ GIT-BUILD-OPTIONS: FORCE
@echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst 
','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
@echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+
@echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
+   @echo X=\'$(X)\' >>$@+
 ifdef TEST_OUTPUT_DIRECTORY
@echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst 
','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+
 endif
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 801cc9b2ef..c167b2e1af 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -900,7 +900,7 @@ test_create_repo () {
mkdir -p "$repo"
(
cd "$repo" || error "Cannot setup test environment"
-   "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git" init \
+   "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 1ea20dc2dc..3e2a9ce76d 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -49,18 +49,23 @@ export ASAN_OPTIONS
 : ${LSAN_OPTIONS=abort_on_error=1}
 export LSAN_OPTIONS
 
+if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+then
+   echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).'
+   exit 1
+fi
+. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+export PERL_PATH SHELL_PATH
+
 
 # It appears that people try to run tests without building...
-test -n "$GIT_TEST_INSTALLED" || "$GIT_BUILD_DIR/git" >/dev/null ||
+test -n "$GIT_TEST_INSTALLED" || "$GIT_BUILD_DIR/git$X" >/dev/null ||
 if test $? != 1
 then
echo >&2 'error: you do not seem to have built git yet.'
exit 1
 fi
 
-. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
-export PERL_PATH SHELL_PATH
-
 # if --tee was passed, write the output not only to the terminal, but
 # additionally to the file test-results/$BASENAME.out, too.
 case "$GIT_TEST_TEE_STARTED, $* " in
-- 
gitgitgadget


[PATCH 3/5] t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

It makes very, very little sense to test the built git-sh-i18n when the
user asked specifically to test another one.

Signed-off-by: Johannes Schindelin 
---
 t/lib-gettext.sh | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index eec757f104..9eb160c997 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -10,7 +10,12 @@ GIT_TEXTDOMAINDIR="$GIT_BUILD_DIR/po/build/locale"
 GIT_PO_PATH="$GIT_BUILD_DIR/po"
 export GIT_TEXTDOMAINDIR GIT_PO_PATH
 
-. "$GIT_BUILD_DIR"/git-sh-i18n
+if test -n "$GIT_TEST_INSTALLED"
+then
+   . "$(git --exec-path)"/git-sh-i18n
+else
+   . "$GIT_BUILD_DIR"/git-sh-i18n
+fi
 
 if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON
 then
-- 
gitgitgadget



[PATCH 2/5] tests: respect GIT_TEST_INSTALLED when initializing repositories

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

It really makes very, very little sense to use a different git
executable than the one the caller indicated via setting the environment
variable GIT_TEST_INSTALLED.

Signed-off-by: Johannes Schindelin 
---
 t/test-lib-functions.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 78d8c3783b..801cc9b2ef 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -900,7 +900,8 @@ test_create_repo () {
mkdir -p "$repo"
(
cd "$repo" || error "Cannot setup test environment"
-   "$GIT_EXEC_PATH/git-init" 
"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
+   "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git" init \
+   "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
) || exit
-- 
gitgitgadget



[PATCH 1/5] tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

We really need to be able to find the test helpers... Really. This
change was forgotten when we moved the test helpers into t/helper/

Signed-off-by: Johannes Schindelin 
---
 t/test-lib.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/test-lib.sh b/t/test-lib.sh
index 47a99aa0ed..832ede5099 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -957,7 +957,7 @@ elif test -n "$GIT_TEST_INSTALLED"
 then
GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
error "Cannot run git from $GIT_TEST_INSTALLED."
-   PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH
+   PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH
GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
 else # normal case, use ../bin-wrappers only unless $with_dashes:
git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
-- 
gitgitgadget



[PATCH 0/5] tests: various improvements to the GIT_TEST_INSTALLED feature

2018-11-12 Thread Johannes Schindelin via GitGitGadget
By setting the GIT_TEST_INSTALLED variable to the path of an installed Git
executable, it is possible to run the test suite also on a specific
installed version (as opposed to a version built from scratch).

The only thing this needs that is unlikely to be installed is the test
helper(s).

However, there have been a few rough edges around that, identified in my
(still ongoing) work to support building Git in Visual Studio (where we do
not want to run GNU Make, and where we have no canonical way to create, say,
hard-linked copies of the built-in commands, and other work to let Git for
Windows play better with BusyBox.

Triggered by a comment of AEvar
[https://public-inbox.org/git/20181102223743.4331-1-ava...@gmail.com/], I
hereby contribute these assorted fixes for the GIT_TEST_INSTALLED feature.

Johannes Schindelin (5):
  tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/
  tests: respect GIT_TEST_INSTALLED when initializing repositories
  t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set
  tests: do not require Git to be built when testing an installed Git
  tests: explicitly use `git.exe` on Windows

 Makefile|  1 +
 t/lib-gettext.sh|  7 ++-
 t/test-lib-functions.sh |  3 ++-
 t/test-lib.sh   | 15 ++-
 4 files changed, 19 insertions(+), 7 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-73%2Fdscho%2Ftest-git-installed-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-73/dscho/test-git-installed-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/73
-- 
gitgitgadget


Re: [RFC/PATCH 0/5] stop installing old libexec aliases like "git-init"

2018-11-12 Thread Johannes Schindelin
Hi Ævar,

On Fri, 2 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

>  * GIT_TEST_INSTALLED breaks entirely under this, as early as the
>heuristic for "are we built?" being "do we have git-init in
>libexecdir?". I tried a bit to make this work, but there's a lot of
>dependencies there.

I have a couple of patches in the pipeline to improve
`GIT_TEST_INSTALLED`, as I needed it to work without hardlinked copies of
the built-ins. These patches might help this here isue.

>  * We still (and this is also true of my ad874608d8) hardlink
>everything in the build dir via a different part of the Makefile,
>ideally we should do exactly the same thing there so also normal
>tests and not just GIT_TEST_INSTALLED (if that worked) would test
>in the same mode.
> 
>I gave making that work a bit of a try and gave up in the Makefile
>jungle.

Yep.

Ciao,
Dscho

Re: [PATCH 0/2] avoid unsigned long for timestamps

2018-11-12 Thread Johannes Schindelin
Hi Carlo,

On Mon, 12 Nov 2018, Carlo Marcelo Arenas Belón wrote:

> specially problematic in Windows where unsigned long is only 32bit wide
> and therefore the assumption that a time_t would fit will lead to loss
> of precision in a 64bit OS.

Both patches look correct to me.

Thanks!
Dscho

> 
>  builtin/commit.c | 4 ++--
>  read-cache.c | 6 +++---
>  2 files changed, 5 insertions(+), 5 deletions(-)
> 
> 
> 

Re: [RFC PATCH 1/5] ref-filter: add objectsize:disk option

2018-11-12 Thread Johannes Schindelin
Hi,

On Mon, 12 Nov 2018, Junio C Hamano wrote:

> Olga Telezhnaya  writes:
> 
> > @@ -876,11 +882,13 @@ static void grab_common_values(struct atom_value 
> > *val, int deref, struct expand_
> > name++;
> > if (!strcmp(name, "objecttype"))
> > v->s = xstrdup(type_name(oi->type));
> > -   else if (!strcmp(name, "objectsize")) {
> > +   else if (!strcmp(name, "objectsize:disk")) {
> > +   v->value = oi->disk_size;
> > +   v->s = xstrfmt("%lld", (long long)oi->disk_size);
> 
> oi.disk_size is off_t; do we know "long long" 
> 
>(1) is available widely enough (I think it is from c99)?
> 
>(2) is sufficiently wide so that we can safely cast off_t to?
> 
>(3) will stay to be sufficiently wide as machines get larger
>together with standard types like off_t in the future?
> 
> I'd rather use intmax_t (as off_t is a signed integral type) so that
> we do not have to worry about these questions in the first place.

You mean something like

v->s = xstrfmt("%"PRIdMAX, (intmax_t)oi->disk_size);


If so, I agree.

Ciao,
Dscho

P.S.: I wondered whether we have precedent for PRIdMAX, as we used to use
only PRIuMAX, but yes: JeffH's json-writer uses PRIdMAX.

> 
> > +   } else if (!strcmp(name, "objectsize")) {
> > v->value = oi->size;
> > v->s = xstrfmt("%lu", oi->size);
> 
> This is not a suggestion but is a genuine question, but I wonder if
> two years down the road somebody who meets this API for the first
> time find the asymmetry between "objectsize" and "objectsize:disk" a
> tad strange and suggest the former to have "objectsize:real" or some
> synonym.  Or we can consider "objectsize" the primary thing (hence
> needing no colon-plus-modifier to clarify what kind of size we are
> asking) and leave these two deliberatly asymmetric.  I am leaning
> towards the latter myself.
> 
> > -   }
> > -   else if (deref)
> > +   } else if (deref)
> > grab_objectname(name, >oid, v, _atom[i]);
> > }
> >  }
> >
> > --
> > https://github.com/git/git/pull/552
> 


[PATCH v2 2/3] rebase: prepare reset_head() for more flags

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

Currently, we only accept the flag indicating whether the HEAD should be
detached not. In the next commit, we want to introduce another flag: to
toggle between emulating `reset --hard` vs `checkout -q`.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index e173654d56..074594cf10 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -522,10 +522,13 @@ finished_rebase:
 
 #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
 
+#define RESET_HEAD_DETACH (1<<0)
+
 static int reset_head(struct object_id *oid, const char *action,
- const char *switch_to_branch, int detach_head,
+ const char *switch_to_branch, unsigned flags,
  const char *reflog_orig_head, const char *reflog_head)
 {
+   unsigned detach_head = flags & RESET_HEAD_DETACH;
struct object_id head_oid;
struct tree_desc desc;
struct lock_file lock = LOCK_INIT;
@@ -1500,8 +1503,8 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
 "it...\n"));
 
strbuf_addf(, "rebase: checkout %s", options.onto_name);
-   if (reset_head(>object.oid, "checkout", NULL, 1,
-   NULL, msg.buf))
+   if (reset_head(>object.oid, "checkout", NULL,
+  RESET_HEAD_DETACH, NULL, msg.buf))
die(_("Could not detach HEAD"));
strbuf_release();
 
-- 
gitgitgadget



[PATCH v2 0/3] Fix built-in rebase perf regression

2018-11-12 Thread Johannes Schindelin via GitGitGadget
In our tests with large repositories, we noticed a serious regression of the
performance of git rebase when using the built-in vs the shell script
version. It boils down to an incorrect conversion of a git checkout -q:
instead of using a twoway_merge as git checkout does, we used a oneway_merge 
as git reset does. The latter, however, calls lstat() on all files listed in
the index, while the former essentially looks only at the files that are
different between the given two revisions.

Let's reinstate the original behavior by introducing a flag to the 
reset_head() function to indicate whether we want to emulate reset --hard 
(in which case we use the oneway_merge, otherwise we use twoway_merge).

Johannes Schindelin (3):
  rebase: consolidate clean-up code before leaving reset_head()
  rebase: prepare reset_head() for more flags
  built-in rebase: reinstate `checkout -q` behavior where appropriate

 builtin/rebase.c | 79 
 1 file changed, 46 insertions(+), 33 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-72%2Fdscho%2Fbuiltin-rebase-perf-regression-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-72/dscho/builtin-rebase-perf-regression-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/72

Range-diff vs v1:

 1:  64597fe827 ! 1:  28e24d98ab rebase: consolidate clean-up code before 
leaving reset_head()
 @@ -11,6 +11,33 @@
  --- a/builtin/rebase.c
  +++ b/builtin/rebase.c
  @@
 +  if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
 +  BUG("Not a fully qualified branch: '%s'", switch_to_branch);
 + 
 +- if (hold_locked_index(, LOCK_REPORT_ON_ERROR) < 0)
 +- return -1;
 ++ if (hold_locked_index(, LOCK_REPORT_ON_ERROR) < 0) {
 ++ ret = -1;
 ++ goto leave_reset_head;
 ++ }
 + 
 +  if (!oid) {
 +  if (get_oid("HEAD", _oid)) {
 +- rollback_lock_file();
 +- return error(_("could not determine HEAD revision"));
 ++ ret = error(_("could not determine HEAD revision"));
 ++ goto leave_reset_head;
 +  }
 +  oid = _oid;
 +  }
 +@@
 +  unpack_tree_opts.reset = 1;
 + 
 +  if (read_index_unmerged(the_repository->index) < 0) {
 +- rollback_lock_file();
 +- return error(_("could not read index"));
 ++ ret = error(_("could not read index"));
 ++ goto leave_reset_head;
}
   
if (!fill_tree_descriptor(, oid)) {
 @@ -31,15 +58,17 @@
}
   
tree = parse_tree_indirect(oid);
 -@@
 +  prime_cache_tree(the_repository->index, tree);
   
 -  if (write_locked_index(the_repository->index, , COMMIT_LOCK) < 0)
 +- if (write_locked_index(the_repository->index, , COMMIT_LOCK) < 0)
 ++ if (write_locked_index(the_repository->index, , COMMIT_LOCK) < 0) {
ret = error(_("could not write index"));
  - free((void *)desc.buffer);
 - 
 -  if (ret)
 +-
 +- if (ret)
  - return ret;
  + goto leave_reset_head;
 ++ }
   
reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
strbuf_addf(, "%s: ", reflog_action ? reflog_action : "rebase");
 -:  -- > 2:  db963b2094 rebase: prepare reset_head() for more flags
 2:  070092b430 ! 3:  a7360b856f built-in rebase: reinstate `checkout -q` 
behavior where appropriate
 @@ -20,15 +20,18 @@
  @@
   #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
   
 + #define RESET_HEAD_DETACH (1<<0)
 ++#define RESET_HEAD_HARD (1<<1)
 + 
   static int reset_head(struct object_id *oid, const char *action,
 --   const char *switch_to_branch, int detach_head,
 -+   const char *switch_to_branch,
 -+   int detach_head, int reset_hard,
 +const char *switch_to_branch, unsigned flags,
  const char *reflog_orig_head, const char *reflog_head)
   {
 +  unsigned detach_head = flags & RESET_HEAD_DETACH;
 ++ unsigned reset_hard = flags & RESET_HEAD_HARD;
struct object_id head_oid;
  - struct tree_desc desc;
 -+ struct tree_desc desc[2];
 ++ struct tree_desc desc[2] = { { NULL }, { NULL } };
struct lock_file lock = LOCK_INIT;
struct unpack_trees_options unpack_tree_opts;
struct tree *tree;
 @@ -42,18 +45,18 @@
if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
BUG("Not a fully qualified branch: '%s'", switch_to_branch

[PATCH v2 1/3] rebase: consolidate clean-up code before leaving reset_head()

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

The same clean-up code is repeated quite a few times; Let's DRY up the
code some.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 0ee06aa363..e173654d56 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -541,13 +541,15 @@ static int reset_head(struct object_id *oid, const char 
*action,
if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
BUG("Not a fully qualified branch: '%s'", switch_to_branch);
 
-   if (hold_locked_index(, LOCK_REPORT_ON_ERROR) < 0)
-   return -1;
+   if (hold_locked_index(, LOCK_REPORT_ON_ERROR) < 0) {
+   ret = -1;
+   goto leave_reset_head;
+   }
 
if (!oid) {
if (get_oid("HEAD", _oid)) {
-   rollback_lock_file();
-   return error(_("could not determine HEAD revision"));
+   ret = error(_("could not determine HEAD revision"));
+   goto leave_reset_head;
}
oid = _oid;
}
@@ -564,32 +566,27 @@ static int reset_head(struct object_id *oid, const char 
*action,
unpack_tree_opts.reset = 1;
 
if (read_index_unmerged(the_repository->index) < 0) {
-   rollback_lock_file();
-   return error(_("could not read index"));
+   ret = error(_("could not read index"));
+   goto leave_reset_head;
}
 
if (!fill_tree_descriptor(, oid)) {
-   error(_("failed to find tree of %s"), oid_to_hex(oid));
-   rollback_lock_file();
-   free((void *)desc.buffer);
-   return -1;
+   ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
+   goto leave_reset_head;
}
 
if (unpack_trees(1, , _tree_opts)) {
-   rollback_lock_file();
-   free((void *)desc.buffer);
-   return -1;
+   ret = -1;
+   goto leave_reset_head;
}
 
tree = parse_tree_indirect(oid);
prime_cache_tree(the_repository->index, tree);
 
-   if (write_locked_index(the_repository->index, , COMMIT_LOCK) < 0)
+   if (write_locked_index(the_repository->index, , COMMIT_LOCK) < 0) {
ret = error(_("could not write index"));
-   free((void *)desc.buffer);
-
-   if (ret)
-   return ret;
+   goto leave_reset_head;
+   }
 
reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
strbuf_addf(, "%s: ", reflog_action ? reflog_action : "rebase");
@@ -622,7 +619,10 @@ static int reset_head(struct object_id *oid, const char 
*action,
 UPDATE_REFS_MSG_ON_ERR);
}
 
+leave_reset_head:
strbuf_release();
+   rollback_lock_file();
+   free((void *)desc.buffer);
return ret;
 }
 
-- 
gitgitgadget



[PATCH v2 3/3] built-in rebase: reinstate `checkout -q` behavior where appropriate

2018-11-12 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

When we converted a `git checkout -q $onto^0` call to use
`reset_head()`, we inadvertently incurred a change from a twoway_merge
to a oneway_merge, as if we wanted a `git reset --hard` instead.

This has performance ramifications under certain, though, as the
oneway_merge needs to lstat() every single index entry whereas
twoway_merge does not.

So let's go back to the old behavior.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c | 40 +---
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 074594cf10..dc78c1497d 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -523,14 +523,16 @@ finished_rebase:
 #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
 
 #define RESET_HEAD_DETACH (1<<0)
+#define RESET_HEAD_HARD (1<<1)
 
 static int reset_head(struct object_id *oid, const char *action,
  const char *switch_to_branch, unsigned flags,
  const char *reflog_orig_head, const char *reflog_head)
 {
unsigned detach_head = flags & RESET_HEAD_DETACH;
+   unsigned reset_hard = flags & RESET_HEAD_HARD;
struct object_id head_oid;
-   struct tree_desc desc;
+   struct tree_desc desc[2] = { { NULL }, { NULL } };
struct lock_file lock = LOCK_INIT;
struct unpack_trees_options unpack_tree_opts;
struct tree *tree;
@@ -539,7 +541,7 @@ static int reset_head(struct object_id *oid, const char 
*action,
size_t prefix_len;
struct object_id *orig = NULL, oid_orig,
*old_orig = NULL, oid_old_orig;
-   int ret = 0;
+   int ret = 0, nr = 0;
 
if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
BUG("Not a fully qualified branch: '%s'", switch_to_branch);
@@ -549,20 +551,20 @@ static int reset_head(struct object_id *oid, const char 
*action,
goto leave_reset_head;
}
 
-   if (!oid) {
-   if (get_oid("HEAD", _oid)) {
-   ret = error(_("could not determine HEAD revision"));
-   goto leave_reset_head;
-   }
-   oid = _oid;
+   if ((!oid || !reset_hard) && get_oid("HEAD", _oid)) {
+   ret = error(_("could not determine HEAD revision"));
+   goto leave_reset_head;
}
 
+   if (!oid)
+   oid = _oid;
+
memset(_tree_opts, 0, sizeof(unpack_tree_opts));
setup_unpack_trees_porcelain(_tree_opts, action);
unpack_tree_opts.head_idx = 1;
unpack_tree_opts.src_index = the_repository->index;
unpack_tree_opts.dst_index = the_repository->index;
-   unpack_tree_opts.fn = oneway_merge;
+   unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
unpack_tree_opts.update = 1;
unpack_tree_opts.merge = 1;
if (!detach_head)
@@ -573,12 +575,17 @@ static int reset_head(struct object_id *oid, const char 
*action,
goto leave_reset_head;
}
 
-   if (!fill_tree_descriptor(, oid)) {
+   if (!reset_hard && !fill_tree_descriptor([nr++], _oid)) {
+   ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
+   goto leave_reset_head;
+   }
+
+   if (!fill_tree_descriptor([nr++], oid)) {
ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
goto leave_reset_head;
}
 
-   if (unpack_trees(1, , _tree_opts)) {
+   if (unpack_trees(nr, desc, _tree_opts)) {
ret = -1;
goto leave_reset_head;
}
@@ -625,7 +632,8 @@ static int reset_head(struct object_id *oid, const char 
*action,
 leave_reset_head:
strbuf_release();
rollback_lock_file();
-   free((void *)desc.buffer);
+   while (nr)
+   free((void *)desc[--nr].buffer);
return ret;
 }
 
@@ -1003,7 +1011,8 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
rerere_clear(_rr);
string_list_clear(_rr, 1);
 
-   if (reset_head(NULL, "reset", NULL, 0, NULL, NULL) < 0)
+   if (reset_head(NULL, "reset", NULL, RESET_HEAD_HARD,
+  NULL, NULL) < 0)
die(_("could not discard worktree changes"));
if (read_basic_state())
exit(1);
@@ -1019,7 +1028,8 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
if (read_basic_state())
exit(1);
if (reset_head(_head, "reset",
-  options.head_name, 0, NULL, NULL) < 0)
+  options.head_name, RES

Re: [PATCH 2/2] built-in rebase: reinstate `checkout -q` behavior where appropriate

2018-11-12 Thread Johannes Schindelin
Hi Junio,

On Mon, 12 Nov 2018, Junio C Hamano wrote:

> Johannes Schindelin  writes:
> 
> >> >  static int reset_head(struct object_id *oid, const char *action,
> >> > -  const char *switch_to_branch, int detach_head,
> >> > +  const char *switch_to_branch,
> >> > +  int detach_head, int reset_hard,
> >> 
> >> It might be worth switching to a single flag variable here. It would
> >> make calls like this:
> >> 
> >> > -if (reset_head(>object.oid, "checkout", NULL, 1,
> >> > +if (reset_head(>object.oid, "checkout", NULL, 1, 
> >> > 0,
> >> >  NULL, msg.buf))
> >> 
> >> a little more self-documenting (if a little more verbose).
> >
> > I thought about that, but for just two flags? Well, let me try it and see
> > whether I like the result ;-)
> 
> My rule of thumb is that repeating three times is definitely when we
> should consolidate separate ones into a single flag word, and twice
> is a borderline.
> 
> For two-time repetition, it is often worth fixing when somebody
> notices it during the review, as that is a sign that repetition,
> even a minor one, disturbed a reader enough to point out.

That's my thought exactly, hence I looked into it. The end result is
actually easier to read, in particular the commit that re-introduces the
`reset --hard` behavior: it no longer touches *all* callsites of
`reset_head()` but only the relevant ones.

> On the other hand, for a file-scope static that is likely to stay as a
> non-API function but a local helper, it may not be worth it.

Oh, do you think that `reset_head()` is likely to stay as non-API
function? I found myself in the need of repeating this tedious
unpack_trees() dance quite a few times over the past two years, and it is
*always* daunting because the API is *that* unintuitive.

So I *do* hope that `reset_head()` will actually be moved to reset.[ch]
eventually, and callsites e.g. in `sequencer.c` will be converted from
calling `unpack_trees()` to calling `reset_head()` instead.

v2 on the way,
Dscho

> So I am OK either way, slightly in favor of fixing it while we
> remember.
> 
> 
> >> This one could actually turn into:
> >> 
> >>   ret = error(...);
> >>   goto leave_reset_head;
> >> 
> >> now. We don't have to worry about an uninitialized desc.buffer anymore
> >> (as I mentioned in the previous email), because "nr" would be 0.
> >> 
> >> It doesn't save any lines, though (but maybe having a single
> >> cleanup/exit point would make things easier to read; I dunno).
> >
> > But you're right, of course. Consistency makes for easier-to-read code.
> 
> Yup, that does sound good.
> 
> Thanks.
> 


Re: [PATCH 2/2] built-in rebase: reinstate `checkout -q` behavior where appropriate

2018-11-12 Thread Johannes Schindelin
Hi Peff,

On Fri, 9 Nov 2018, Jeff King wrote:

> On Fri, Nov 09, 2018 at 06:21:41PM +0100, Johannes Schindelin wrote:
> 
> > Actually, you got me thinking about the desc.buffer. And I think there is
> > one corner case where it could cause a problem: `struct tree_desc desc[2]`
> > does not initialize the buffers to NULL. And what if
> > fill_tree_descriptor() function returns NULL? Then the buffer is still
> > uninitialized.
> > 
> > In practice, our *current* version of fill_tree_descriptor() never returns
> > NULL if the oid parameter is non-NULL. It would die() in the error case
> > instead (bad!). So to prepare for a less bad version, I'd rather
> > initialize the `desc` array and be on the safe (and easier to reason
> > about) side.
> 
> Yeah, I agree with all of that.
> 
> One solution would just be to increment only after success:
> 
>   if (fill_tree_descriptor([nr], ..) < 0)
>   goto error;
>   nr++; /* now we know it's valid! */
> 
> But there are lots of alternatives.  :)

True. I simply prefer to initialize it and be done with it. ;-)

Ciao,
Dscho


Re: [PATCH] p3400: replace calls to `git checkout -b' by `git checkout -B'

2018-11-10 Thread Johannes Schindelin
Hi Alban,

On Fri, 9 Nov 2018, Alban Gruin wrote:

> p3400 makes a copy of the current repository to test git-rebase
> performance, and creates new branches in the copy with `git checkout
> -b'.  If the original repository has branches with the same name as the
> script is trying to create, this operation will fail.
> 
> This replaces these calls by `git checkout -B' to force the creation and
> update of these branches.

Both the explanation and the patch make sense to me.

Thanks,
Dscho

> 
> Signed-off-by: Alban Gruin 
> ---
>  t/perf/p3400-rebase.sh | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/t/perf/p3400-rebase.sh b/t/perf/p3400-rebase.sh
> index ce271ca4c1..d202aaed06 100755
> --- a/t/perf/p3400-rebase.sh
> +++ b/t/perf/p3400-rebase.sh
> @@ -6,9 +6,9 @@ test_description='Tests rebase performance'
>  test_perf_default_repo
>  
>  test_expect_success 'setup rebasing on top of a lot of changes' '
> - git checkout -f -b base &&
> - git checkout -b to-rebase &&
> - git checkout -b upstream &&
> + git checkout -f -B base &&
> + git checkout -B to-rebase &&
> + git checkout -B upstream &&
>   for i in $(seq 100)
>   do
>   # simulate huge diffs
> @@ -35,8 +35,8 @@ test_perf 'rebase on top of a lot of unrelated changes' '
>  
>  test_expect_success 'setup rebasing many changes without split-index' '
>   git config core.splitIndex false &&
> - git checkout -b upstream2 to-rebase &&
> - git checkout -b to-rebase2 upstream
> + git checkout -B upstream2 to-rebase &&
> + git checkout -B to-rebase2 upstream
>  '
>  
>  test_perf 'rebase a lot of unrelated changes without split-index' '
> -- 
> 2.19.1
> 
> 


Re: [PATCH 2/2] built-in rebase: reinstate `checkout -q` behavior where appropriate

2018-11-09 Thread Johannes Schindelin
Hi Peff,

On Fri, 9 Nov 2018, Jeff King wrote:

> On Fri, Nov 09, 2018 at 01:34:19AM -0800, Johannes Schindelin via 
> GitGitGadget wrote:
> 
> > From: Johannes Schindelin 
> > 
> > When we converted a `git checkout -q $onto^0` call to use
> > `reset_head()`, we inadvertently incurred a change from a twoway_merge
> > to a oneway_merge, as if we wanted a `git reset --hard` instead.
> > 
> > This has performance ramifications under certain, though, as the
> > oneway_merge needs to lstat() every single index entry whereas
> > twoway_merge does not.
> > 
> > So let's go back to the old behavior.
> 
> Makes sense. I didn't think too hard about any possible gotchas with the
> twoway/oneway switch, but if that's what git-checkout was doing before,
> it seems obviously safe.

Right.

> > diff --git a/builtin/rebase.c b/builtin/rebase.c
> > index 6f6d7de156..c1cc50f3f8 100644
> > --- a/builtin/rebase.c
> > +++ b/builtin/rebase.c
> > @@ -523,11 +523,12 @@ finished_rebase:
> >  #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
> >  
> >  static int reset_head(struct object_id *oid, const char *action,
> > - const char *switch_to_branch, int detach_head,
> > + const char *switch_to_branch,
> > + int detach_head, int reset_hard,
> 
> It might be worth switching to a single flag variable here. It would
> make calls like this:
> 
> > -   if (reset_head(>object.oid, "checkout", NULL, 1,
> > +   if (reset_head(>object.oid, "checkout", NULL, 1, 0,
> > NULL, msg.buf))
> 
> a little more self-documenting (if a little more verbose).

I thought about that, but for just two flags? Well, let me try it and see
whether I like the result ;-)

> > -   if (!oid) {
> > -   if (get_oid("HEAD", _oid)) {
> > -   rollback_lock_file();
> > -   return error(_("could not determine HEAD revision"));
> > -   }
> > -   oid = _oid;
> > +   if (get_oid("HEAD", _oid)) {
> > +   rollback_lock_file();
> > +   return error(_("could not determine HEAD revision"));
> > }
> 
> This one could actually turn into:
> 
>   ret = error(...);
>   goto leave_reset_head;
> 
> now. We don't have to worry about an uninitialized desc.buffer anymore
> (as I mentioned in the previous email), because "nr" would be 0.
> 
> It doesn't save any lines, though (but maybe having a single
> cleanup/exit point would make things easier to read; I dunno).

But you're right, of course. Consistency makes for easier-to-read code.

> Take all my comments as observations, not objections. This looks OK to
> me either way.

Actually, you got me thinking about the desc.buffer. And I think there is
one corner case where it could cause a problem: `struct tree_desc desc[2]`
does not initialize the buffers to NULL. And what if
fill_tree_descriptor() function returns NULL? Then the buffer is still
uninitialized.

In practice, our *current* version of fill_tree_descriptor() never returns
NULL if the oid parameter is non-NULL. It would die() in the error case
instead (bad!). So to prepare for a less bad version, I'd rather
initialize the `desc` array and be on the safe (and easier to reason
about) side.

Thank you for your helpful review,
Dscho


Re: [PATCH 1/2] rebase: consolidate clean-up code before leaving reset_head()

2018-11-09 Thread Johannes Schindelin
Hi Peff,

On Fri, 9 Nov 2018, Jeff King wrote:

> On Fri, Nov 09, 2018 at 01:34:17AM -0800, Johannes Schindelin via 
> GitGitGadget wrote:
> 
> > diff --git a/builtin/rebase.c b/builtin/rebase.c
> > index 0ee06aa363..6f6d7de156 100644
> > --- a/builtin/rebase.c
> > +++ b/builtin/rebase.c
> > @@ -569,16 +569,13 @@ static int reset_head(struct object_id *oid, const 
> > char *action,
> > }
> >  
> > if (!fill_tree_descriptor(, oid)) {
> > -   error(_("failed to find tree of %s"), oid_to_hex(oid));
> > -   rollback_lock_file();
> > -   free((void *)desc.buffer);
> > -   return -1;
> > +   ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
> > +   goto leave_reset_head;
> > }
> 
> If fill_tree_descriptor() fails, what is left in desc.buffer? Looking at
> the implementation, I think it's always NULL or a valid buffer. But I
> think all code paths actually die() unless we pass a NULL oid (and in
> that case desc.buffer would be NULL, too).
> 
> So I think the original here that calls free() doesn't ever do anything
> but it did not hurt. After your patch, the leave_reset_head code would
> continue to call free(), and that's OK.

Right, that was my thinking, too.

> There are a few earlier conditionals in reset_head() that do only
> rollback_lock_file() that could similarly be converted to use the goto.
> But they would need desc.buffer to be initialized to NULL. I could go
> either way on converting them or not.

Whoops. I should have checked more carefully?

> > @@ -586,10 +583,9 @@ static int reset_head(struct object_id *oid, const 
> > char *action,
> >  
> > if (write_locked_index(the_repository->index, , COMMIT_LOCK) < 0)
> > ret = error(_("could not write index"));
> > -   free((void *)desc.buffer);
> >  
> > if (ret)
> > -   return ret;
> > +   goto leave_reset_head;
> >  
> > reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
> > strbuf_addf(, "%s: ", reflog_action ? reflog_action : "rebase");
> > @@ -622,7 +618,10 @@ static int reset_head(struct object_id *oid, const 
> > char *action,
> >  UPDATE_REFS_MSG_ON_ERR);
> > }
> >  
> > +leave_reset_head:
> > strbuf_release();
> > +   rollback_lock_file();
> > +   free((void *)desc.buffer);
> > return ret;
> 
> We get here on success, too. So we may call rollback_lock_file() on an
> already-committed lock. This is explicitly documented as a no-op by the
> lock code, so that's OK.

Indeed. I did not check the documentation, but the code, and came to the
same conclusion.

> So overall looks good to me.

Thanks!
Dscho


Re: [PATCH v4 0/3] range-diff fixes

2018-11-09 Thread Johannes Schindelin
Hi Ævar,

On Fri, 9 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> Addresses feedback on v3, especially Eric's suggestion to split out
> the behavior change (which I was not aware of) into a 3/3.

For the record, I am fine with this iteration, too.

Ciao,
Dscho

Re: Git Evolve

2018-11-09 Thread Johannes Schindelin
Hi,

On Tue, 2 Oct 2018, Ævar Arnfjörð Bjarmason wrote:

> On Tue, Oct 02 2018, Taylor Blau wrote:
> 
> > Hi Stefan,
> >
> > On Sat, Sep 29, 2018 at 04:00:04PM -0700, Stefan Xenos wrote:
> >> Hello, List!
> >>
> >> I'm interested in porting something like Mercurial's evolve command to
> >> Git.
> >
> > Welcome to Git :-). I think that the discussion in this thread is good,
> > but it's not why I'm replying. I have also wanted a Mercurial feature in
> > Git, but a different one than yours.
> >
> > Specifically, I've wanted the 'hg absorb' command. My understanding of
> > the commands functionality is that it builds a sort of flamegraph-esque
> > view of the blame, and then cascades downwards parts of a change. I am
> > sure that I'm not doing the command justice, so I'll defer to [1] where
> > it is explained in more detail.
> >
> > The benefit of this command is that it gives you a way to--without
> > ambiguity--absorb changes into earlier commits, and in fact, the
> > earliest commit that they make sense to belong to.
> >
> > This would simplify my workflow greatly when re-rolling patches, as I
> > often want to rewrite a part of an earlier commit. This is certainly
> > possible by a number of different `git rebase` invocations (e.g., (1)
> > create fixup commits, and then re-order them, or (2) mark points in your
> > history as 'edit', and rewrite them in a detached state, and I'm sure
> > many more).
> >
> > I'm curious if you or anyone else has thought about how this might work
> > in Git.
> 
> I've wanted a "git absorb" for a while, but have done no actual work on
> it, I just found out about it.
> 
> I think a combination of these two heuristics would probably do the
> trick:
> 
>  1. If a change in your "git diff" output has a hunk whose lines overlap
> with an earlier commit in the @{u}.. range, we do the equivalent of
> "git add -p", select that hunk, and "git commit --fixup  commit>". We fixup the most recent commit that matches (otherwise
> commit>we'd conflict).
> 
>  2. Have some mode where we fall back from #1 and consider changes to
> entire files, if that's unambiguous.
> 
> The neat thing about this would be that you could tweak how promiscuous
> #1 would be via the -U option to git-diff, and #2 would just be a
> special case of -U9 (we should really add a -Uinf...).
> 
> Then once you ran this you could run "git rebase -i --autosquash" to see
> how the TODO list would look, and optionally have some "git absorb
> --now" or whatever to do the "git add -p", "git commit --fixup" and "git
> rebase --autosquash" all in one go.

This is essentially what the script does that I sent to this here mailing
list back in May:
https://public-inbox.org/git/nycvar.qro.7.76.6.1805052220360...@tvgsbejvaqbjf.bet/

I used this quite a lot, but I still find it slow (especially on Windows),
so I am still in search for a better solution. And yes, I was intrigued by
`hg absorb` when it was presented at GitMerge last year, and wanted to
have the same.

In the meantime, what I often do is to call `git log -L :`
where  and  are taken from the hunk(s) of the current diff.
Actually, I have a script to do that, hidden behind a Git alias. Then I
inspect the diffs in that log and call `git commit --fixup` with the one I
deem most appropriate.

Note that it sometimes fails because of semantic dependencies. That is,
even if my current change overlaps with an earlier change, it may be too
early to be squashed in.

As an example: imagine that I moved a git_config() call from some function
into the cmd_() function. Only: I intended to move it, but in
fact, I just added the call to the latter function. Eventually, I figure
it out! So I want to make a fixup! commit. My script, as well as Ævar's
suggestion, as well as literally all the other attempts to solve this that
I am aware of, would try to squash this change into whichever commit
introduced the function that originally called git_config(). But that is
wrong. It should be squashed into the commit that added the git_config()
call to the cmd_() function.

Ciao,
Dscho

> 
> > [1]: http://files.lihdd.net/hgabsorb-note.pdf
> 

Re: GPG signing is bent on WIndows

2018-11-09 Thread Johannes Schindelin
Hi Jeff,

On Wed, 26 Sep 2018, Jeffrey Walton wrote:

> Several weeks ago I updated to the latest Git for Windows (when
> prompted by the version check). At the time I noticed:
> 
> $ git commit -S -am "Fix unset MAKE variable in test scripts"
> gpg: signing failed: No pinentry
> gpg: signing failed: No pinentry
> error: gpg failed to sign the data
> fatal: failed to write commit object
> 
> I got to look at it today. On Windows:
> 
> $ cat ~/.gnupg/gpg-agent.conf
> pinentry-program
> /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac

Git for Windows is partially based off of MSYS2, which upgraded GPG from
v1 to v2, and one of the consequences is that v2 handles interaction with
the user differently.

My guess is that you copied your config from a Mac, and the path is simply
incorrect. I would wager a bet that it starts working when you remove that
line with the incorrect path, as the default should work plenty fine for
you.

Ciao,
Johannes


Re: [GSoC][PATCH v8 14/20] stash: convert create to builtin

2018-11-09 Thread Johannes Schindelin
Hi Paul,

On Wed, 26 Sep 2018, Paul-Sebastian Ungureanu wrote:

> Sorry for the late reply. I had a lot on my plate for the last couple of
> weeks.

I understand. University can be busy times.

> > > +
> > > + git_config(git_diff_basic_config, NULL);
> > 
> > Is this not called in as part of `git_config(git_default_config, NULL);`
> > in cmd_stash() already?
> > 
> > *clicketyclick*
> > 
> > I guess not. But then, maybe it would make sense to run with
> > `git_diff_basic_config` from the get go, to avoid having to run
> > `git_config()` twice.
> 
> I am not sure I got it right, but if I did:
> 
> Running `git_config` with `git_diff_basic_config` from the
> beginning wouldn't be pointless when we would use any other
> command than `create`, `push` and `save`? Although it might
> confuse the reader a little bit, the stash should run without
> problems.

In my mind, this would simplify the code. Which is always easier on the
reader... ;-)

Ciao,
Dscho


Re: [GSoC][PATCH v8 18/20] stash: convert `stash--helper.c` into `stash.c`

2018-11-09 Thread Johannes Schindelin
Hi Paul,

On Wed, 26 Sep 2018, Paul-Sebastian Ungureanu wrote:

> Hi,
> 
> > >   @@ -1443,9 +1448,10 @@ static int push_stash(int argc, const char
> > > **argv, const char *prefix)
> > >   OPT_END()
> > >};
> > >   -   argc = parse_options(argc, argv, prefix, options,
> > > -  git_stash_helper_push_usage,
> > > -  0);
> > > + if (argc)
> > > + argc = parse_options(argc, argv, prefix, options,
> > > +  git_stash_push_usage,
> > > +  0);
> > 
> > Is this `if (argc)` guard necessary?
> 
> Yes because without it, there would be a seg fault when
> calling `git stash`. Why?
> 
> After spawning `git stash`, in `push_stash()`: `argc` would be
> 0 (and `argv` would be `NULL`).

I *think* what you want to do, then, is to pass PARSE_OPT_KEEP_ARGV0 in
the first parse_options() call. In general, this needs to be done any time
you might want to call `parse_options()` on the remaining options.

Looking forward to v10,
Dscho

> `parse_options()` calls `parse_options_start()` which does the following:
> 
>   ctx->argc = ctx->total = argc - 1;
>   ctx->argv = argv + 1;
> 
> So, `ctx->argc` would be `-1`. After we are back to `parse_options()`,
> `parse_options_step()` would be called. In `parse_options_step()`:
> 
>   for (; ctx->argc; ctx->argc--, ctx->argv++)
> 
> Which is an infinite loop, because `ctx->argc` is already -1.
> 
> This check is also done for `git notes list` (function `list()`
> inside `builtin/notes.c`). Now, that I relook at it, it seems to me
> that this is a bug. Probably a better solution would be to check at the
> beginning of `parse_options()` and return early if `argc` is less then one.
> 
> > > @@ -1536,7 +1544,44 @@ int cmd_stash__helper(int argc, const char **argv,
> > > const char *prefix)
> > >   return !!push_stash(argc, argv, prefix);
> > >else if (!strcmp(argv[0], "save"))
> > >   return !!save_stash(argc, argv, prefix);
> > > + else if (*argv[0] != '-')
> > > + usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
> > > +   git_stash_usage, options);
> > > +
> > > + if (strcmp(argv[0], "-p")) {
> > > + while (++i < argc && strcmp(argv[i], "--")) {
> > > + /*
> > > +  * `akpqu` is a string which contains all short
> > > options,
> > > +  * except `-m` which is verified separately.
> > > +  */
> > > + if ((strlen(argv[i]) == 2) && *argv[i] == '-' &&
> > > + strchr("akpqu", argv[i][1]))
> > 
> > I *think* this is missing the `n`.
> 
> I guess that by `n` you are referring to the short option of
> `--no-keep-index`, which is missing because it was also omitted
> in `stash.sh`. I am not sure whether it is worth adding it. In
> case `stash` will learn any other option starting with `n`, this
> might create confusion amongst users.
> 
> Best regards,
> Paul
> 


Re: [PATCH] travis-ci: install packages in 'ci/install-dependencies.sh'

2018-11-09 Thread Johannes Schindelin
Hi,

On Fri, 9 Nov 2018, Junio C Hamano wrote:

> SZEDER Gábor  writes:
> 
> >> > I'm not sure about the last paragraph, because:
> >> >
> >> >   - It talks about presumed benefits for a currently still
> >> > work-in-progress patch series of an other contributor, and I'm not
> >> > really sure that that's a good thing.  Perhaps I should have
> >> > rather put it below the '---'.
> >> >
> >> >   - I'm confused about the name of this Azure thing.  The cover letter
> >> > mentions "Azure Pipelines", the file is called
> >> > 'azure-pipelines.yml', but the relevant patch I link to talks
> >> > about "Azure DevOps" in the commit message.
> >> >
> >> > Anyway, keep that last paragraph or drop it as you see fit.
> >> 
> >> I hope we'll hear from Dscho in one or two revolutions of the Earth
> >> ;-)
> >
> > ... revolutions around what? :)
> 
> Originally I meant its own axis, but perhaps the moon.

I see, you had fun talking about a revolution [*1*]...

I am much in favor of this patch, as it indeed will simplify the
integration into Azure Pipelines.

As to the DevOps vs Pipelines thing: DevOps is the umbrella, it consists
of much more than just the automated builds (Pipelines), it also has
Boards, Packages, etc, but I don't think we will ever use that in the Git
project, as our workflow is based out of a mailing list.

Ciao,
Dscho


Footnote *1*: https://www.youtube.com/watch?v=Xv8FBjo1Y8I

Re: What's cooking in git.git (Nov 2018, #03; Wed, 7)

2018-11-09 Thread Johannes Schindelin
Hi Phillip,

On Thu, 8 Nov 2018, Phillip Wood wrote:

> On 07/11/2018 09:41, Junio C Hamano wrote:
> > Here are the topics that have been cooking.  Commits prefixed with
> > '-' are only in 'pu' (proposed updates) while commits prefixed with
> > '+' are in 'next'.  The ones marked with '.' do not appear in any of
> > the integration branches, but I am still holding onto them.
> > 
> > You can find the changes described here in the integration branches
> > of the repositories listed at
> > 
> >  http://git-blame.blogspot.com/p/git-public-repositories.html
> > 
> > --
> > 
> > * pw/add-p-select (2018-07-26) 4 commits
> >   - add -p: optimize line selection for short hunks
> >   - add -p: allow line selection to be inverted
> >   - add -p: select modified lines correctly
> >   - add -p: select individual hunk lines
> > 
> >   "git add -p" interactive interface learned to let users choose
> >   individual added/removed lines to be used in the operation, instead
> >   of accepting or rejecting a whole hunk.
> > 
> >   Will discard.
> >   No further feedbacks on the topic for quite some time.
> 
> Unfortunately I've not found time to work on this recently and don't see
> myself doing so before the new year so I think it makes sense to drop it.
> Hopefully I can come up with something next year, it would be nice for users
> to avoid having to edit patches where possible.

If I understand correctly, this patch series essentially imitates on the
console what you can do in Git GUI by selecting multiple lines in the diff
and then "Stage Selected Lines"?

If my understanding is correct, then yes, I would be very much in favor of
having this feature, too.

Thanks,
Dscho


[PATCH v2 0/1] Update .mailmap

2018-11-09 Thread Johannes Schindelin via GitGitGadget
I noticed that there were a couple of duplicate entries in git shortlog -nse
v2.19.1.., and then continued a bit to remove the duplicate entries even for
v2.10.0..

Changes relative to v1:

 * Fixed the commit message (it talked about the opposite commit range than
   intended).
 * Added a formerly missing space between the email addresses of Masaya.

Johannes Schindelin (1):
  Update .mailmap

 .mailmap | 13 +
 1 file changed, 13 insertions(+)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-71%2Fdscho%2Fmailmap-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-71/dscho/mailmap-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/71

Range-diff vs v1:

 1:  b590a9bebf ! 1:  c121ebc474 Update .mailmap
 @@ -2,7 +2,7 @@
  
  Update .mailmap
  
 -This patch makes the output of `git shortlog -nse v2.10.0`
 +This patch makes the output of `git shortlog -nse v2.10.0..master`
  duplicate-free.
  
  Signed-off-by: Johannes Schindelin 
 @@ -47,7 +47,7 @@
   Mark Rada 
   Martin Langhoff  
   Martin von Zweigbergk  

 -+Masaya Suzuki 
 ++Masaya Suzuki  
   Matt Draisey  
   Matt Kraai  
   Matt McCutchen  

-- 
gitgitgadget


[PATCH v2 1/1] Update .mailmap

2018-11-09 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

This patch makes the output of `git shortlog -nse v2.10.0..master`
duplicate-free.

Signed-off-by: Johannes Schindelin 
---
 .mailmap | 13 +
 1 file changed, 13 insertions(+)

diff --git a/.mailmap b/.mailmap
index bef3352b0d..eb7b5fc7b9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -21,6 +21,8 @@ Anders Kaseorg  
 Aneesh Kumar K.V 
 Amos Waterland  
 Amos Waterland  
+Ben Peart  
+Ben Peart  
 Ben Walton  
 Benoit Sigoure  
 Bernt Hansen  
@@ -32,6 +34,7 @@ Bryan Larsen  
 Cheng Renquan 
 Chris Shoemaker 
 Chris Wright  
+Christian Ludwig  
 Cord Seele  
 Christian Couder  
 Christian Stimming  
@@ -51,6 +54,7 @@ David Reiss  

 David S. Miller 
 David Turner  
 David Turner  
+Derrick Stolee  
 Deskin Miller 
 Dirk Süsserott 
 Eric Blake  
@@ -98,6 +102,7 @@ Jens Axboe  
 Jens Lindström  Jens Lindstrom 
 Jim Meyering  
 Joachim Berdal Haga 
+Joachim Jablon  
 Johannes Schindelin  
 Johannes Sixt  
 Johannes Sixt  
@@ -150,6 +155,7 @@ Mark Levedahl  
 Mark Rada 
 Martin Langhoff  
 Martin von Zweigbergk  
+Masaya Suzuki  
 Matt Draisey  
 Matt Kraai  
 Matt McCutchen  
@@ -157,6 +163,7 @@ Matthias Kestenholz  

 Matthias Rüster  Matthias Ruester
 Matthias Urlichs  
 Matthias Urlichs  
+Matthieu Moy  
 Michael Coleman 
 Michael J Gruber  
 Michael J Gruber  
@@ -180,7 +187,11 @@ Nick Stokoe  Nick Woolley 

 Nick Stokoe  Nick Woolley 
 Nicolas Morey-Chaisemartin  

 Nicolas Morey-Chaisemartin  

+Nicolas Morey-Chaisemartin  

+Nicolas Morey-Chaisemartin  

+Nicolas Morey-Chaisemartin  

 Nicolas Sebrecht  
+Orgad Shaneh  
 Paolo Bonzini  
 Pascal Obry  
 Pascal Obry  
@@ -200,6 +211,7 @@ Philipp A. Hartmann  
 Philippe Bruhat 
 Ralf Thielow  
 Ramsay Jones  
+Randall S. Becker  
 René Scharfe  
 René Scharfe  Rene Scharfe
 Richard Hansen  
@@ -238,6 +250,7 @@ Steven Walter  

 Sven Verdoolaege  
 Sven Verdoolaege  
 SZEDER Gábor  
+Tao Qingyun  <845767...@qq.com>
 Tay Ray Chuan 
 Ted Percival  
 Theodore Ts'o 
-- 
gitgitgadget


Re: [PATCH 1/1] Update .mailmap

2018-11-09 Thread Johannes Schindelin
Hi Junio,

On Fri, 9 Nov 2018, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" 
> writes:
> 
> > From: Johannes Schindelin 
> >
> > This patch makes the output of `git shortlog -nse v2.10.0`
> > duplicate-free.
> 
> Did you mean "v2.10.0..master" or did you really mean this covers
> authors recorded up to v2.10.0?  Judging from the cover letter, I
> think you meant the former.

D'oh. Yes, I meant v2.10.0..master.

> Can you say a bit more about how one among multiple addresses for
> each person was chosen in the log message?  E.g. "After asking each
> author which one is the preferred one", "Picked the one with the
> most recent committer timestamps", "There were two for each but one
> of them were bouncing", etc.

I looked at each of the authors' mails and tried to determine which one
was the preferred one. For example, Masaya sent a patch from their gmail
account but signed off using their google account, so I figured the latter
was preferable. Nicolas, on the other hand, already had a couple of
entries in .mailmap, so I picked the one that seemed to be preferred
judging by the .mailmap even if it was not in use lately.

For Christian, it was gmail vs googlemail, and I picked the former, as it
is more common these days.

For Ben and Stolee, I used their Microsoft accounts (preferring the one
Ben used originally).

For Joachim, Matthieu, Randall and Tao, I used the more personalized email
address.

For Orgad, I used his personal one rather than his work email.

> > @@ -150,6 +155,7 @@ Mark Levedahl  
> >  Mark Rada 
> >  Martin Langhoff  
> >  Martin von Zweigbergk  
> > 
> > +Masaya Suzuki 
> 
> It is a bit surprising that we can take an entry without SP in
> between two addresses and still behave sensibley, but it probably
> makes more sense to add one just to look similar to other entries.

Whoops. Thanks, fixed!

> Thanks for working on this.

You're welcome.

v2 about to be sent,
Dscho


[PATCH 0/2] Fix built-in rebase perf regression

2018-11-09 Thread Johannes Schindelin via GitGitGadget
In our tests with large repositories, we noticed a serious regression of the
performance of git rebase when using the built-in vs the shell script
version. It boils down to an incorrect conversion of a git checkout -q:
instead of using a twoway_merge as git checkout does, we used a oneway_merge 
as git reset does. The latter, however, calls lstat() on all files listed in
the index, while the former essentially looks only at the files that are
different between the given two revisions.

Let's reinstate the original behavior by introducing a flag to the 
reset_head() function to indicate whether we want to emulate reset --hard 
(in which case we use the oneway_merge, otherwise we use twoway_merge).

Johannes Schindelin (2):
  rebase: consolidate clean-up code before leaving reset_head()
  built-in rebase: reinstate `checkout -q` behavior where appropriate

 builtin/rebase.c | 60 ++--
 1 file changed, 33 insertions(+), 27 deletions(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-72%2Fdscho%2Fbuiltin-rebase-perf-regression-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-72/dscho/builtin-rebase-perf-regression-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/72
-- 
gitgitgadget


[PATCH 2/2] built-in rebase: reinstate `checkout -q` behavior where appropriate

2018-11-09 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

When we converted a `git checkout -q $onto^0` call to use
`reset_head()`, we inadvertently incurred a change from a twoway_merge
to a oneway_merge, as if we wanted a `git reset --hard` instead.

This has performance ramifications under certain, though, as the
oneway_merge needs to lstat() every single index entry whereas
twoway_merge does not.

So let's go back to the old behavior.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c | 45 ++---
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 6f6d7de156..c1cc50f3f8 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -523,11 +523,12 @@ finished_rebase:
 #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
 
 static int reset_head(struct object_id *oid, const char *action,
- const char *switch_to_branch, int detach_head,
+ const char *switch_to_branch,
+ int detach_head, int reset_hard,
  const char *reflog_orig_head, const char *reflog_head)
 {
struct object_id head_oid;
-   struct tree_desc desc;
+   struct tree_desc desc[2];
struct lock_file lock = LOCK_INIT;
struct unpack_trees_options unpack_tree_opts;
struct tree *tree;
@@ -536,7 +537,7 @@ static int reset_head(struct object_id *oid, const char 
*action,
size_t prefix_len;
struct object_id *orig = NULL, oid_orig,
*old_orig = NULL, oid_old_orig;
-   int ret = 0;
+   int ret = 0, nr = 0;
 
if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
BUG("Not a fully qualified branch: '%s'", switch_to_branch);
@@ -544,20 +545,20 @@ static int reset_head(struct object_id *oid, const char 
*action,
if (hold_locked_index(, LOCK_REPORT_ON_ERROR) < 0)
return -1;
 
-   if (!oid) {
-   if (get_oid("HEAD", _oid)) {
-   rollback_lock_file();
-   return error(_("could not determine HEAD revision"));
-   }
-   oid = _oid;
+   if (get_oid("HEAD", _oid)) {
+   rollback_lock_file();
+   return error(_("could not determine HEAD revision"));
}
 
+   if (!oid)
+   oid = _oid;
+
memset(_tree_opts, 0, sizeof(unpack_tree_opts));
setup_unpack_trees_porcelain(_tree_opts, action);
unpack_tree_opts.head_idx = 1;
unpack_tree_opts.src_index = the_repository->index;
unpack_tree_opts.dst_index = the_repository->index;
-   unpack_tree_opts.fn = oneway_merge;
+   unpack_tree_opts.fn = reset_hard ? oneway_merge : twoway_merge;
unpack_tree_opts.update = 1;
unpack_tree_opts.merge = 1;
if (!detach_head)
@@ -568,12 +569,17 @@ static int reset_head(struct object_id *oid, const char 
*action,
return error(_("could not read index"));
}
 
-   if (!fill_tree_descriptor(, oid)) {
+   if (!reset_hard && !fill_tree_descriptor([nr++], _oid)) {
+   ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
+   goto leave_reset_head;
+   }
+
+   if (!fill_tree_descriptor([nr++], oid)) {
ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
goto leave_reset_head;
}
 
-   if (unpack_trees(1, , _tree_opts)) {
+   if (unpack_trees(nr, desc, _tree_opts)) {
ret = -1;
goto leave_reset_head;
}
@@ -621,7 +627,8 @@ static int reset_head(struct object_id *oid, const char 
*action,
 leave_reset_head:
strbuf_release();
rollback_lock_file();
-   free((void *)desc.buffer);
+   while (nr)
+   free((void *)desc[--nr].buffer);
return ret;
 }
 
@@ -999,7 +1006,7 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
rerere_clear(_rr);
string_list_clear(_rr, 1);
 
-   if (reset_head(NULL, "reset", NULL, 0, NULL, NULL) < 0)
+   if (reset_head(NULL, "reset", NULL, 0, 1, NULL, NULL) < 0)
die(_("could not discard worktree changes"));
if (read_basic_state())
exit(1);
@@ -1015,7 +1022,7 @@ int cmd_rebase(int argc, const char **argv, const char 
*prefix)
if (read_basic_state())
exit(1);
if (reset_head(_head, "reset",
-  options.head_name, 0, NULL, NULL) < 0)
+  options.head_name, 0, 1, NULL, NULL) < 0)
die(_("could not move back to %s"),
oid_to_h

[PATCH 1/2] rebase: consolidate clean-up code before leaving reset_head()

2018-11-09 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

The same clean-up code is repeated quite a few times; Let's DRY up the
code some.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 0ee06aa363..6f6d7de156 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -569,16 +569,13 @@ static int reset_head(struct object_id *oid, const char 
*action,
}
 
if (!fill_tree_descriptor(, oid)) {
-   error(_("failed to find tree of %s"), oid_to_hex(oid));
-   rollback_lock_file();
-   free((void *)desc.buffer);
-   return -1;
+   ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
+   goto leave_reset_head;
}
 
if (unpack_trees(1, , _tree_opts)) {
-   rollback_lock_file();
-   free((void *)desc.buffer);
-   return -1;
+   ret = -1;
+   goto leave_reset_head;
}
 
tree = parse_tree_indirect(oid);
@@ -586,10 +583,9 @@ static int reset_head(struct object_id *oid, const char 
*action,
 
if (write_locked_index(the_repository->index, , COMMIT_LOCK) < 0)
ret = error(_("could not write index"));
-   free((void *)desc.buffer);
 
if (ret)
-   return ret;
+   goto leave_reset_head;
 
reflog_action = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
strbuf_addf(, "%s: ", reflog_action ? reflog_action : "rebase");
@@ -622,7 +618,10 @@ static int reset_head(struct object_id *oid, const char 
*action,
 UPDATE_REFS_MSG_ON_ERR);
}
 
+leave_reset_head:
strbuf_release();
+   rollback_lock_file();
+   free((void *)desc.buffer);
return ret;
 }
 
-- 
gitgitgadget



[PATCH 1/1] Update .mailmap

2018-11-08 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

This patch makes the output of `git shortlog -nse v2.10.0`
duplicate-free.

Signed-off-by: Johannes Schindelin 
---
 .mailmap | 13 +
 1 file changed, 13 insertions(+)

diff --git a/.mailmap b/.mailmap
index bef3352b0d..1d8310073a 100644
--- a/.mailmap
+++ b/.mailmap
@@ -21,6 +21,8 @@ Anders Kaseorg  
 Aneesh Kumar K.V 
 Amos Waterland  
 Amos Waterland  
+Ben Peart  
+Ben Peart  
 Ben Walton  
 Benoit Sigoure  
 Bernt Hansen  
@@ -32,6 +34,7 @@ Bryan Larsen  
 Cheng Renquan 
 Chris Shoemaker 
 Chris Wright  
+Christian Ludwig  
 Cord Seele  
 Christian Couder  
 Christian Stimming  
@@ -51,6 +54,7 @@ David Reiss  

 David S. Miller 
 David Turner  
 David Turner  
+Derrick Stolee  
 Deskin Miller 
 Dirk Süsserott 
 Eric Blake  
@@ -98,6 +102,7 @@ Jens Axboe  
 Jens Lindström  Jens Lindstrom 
 Jim Meyering  
 Joachim Berdal Haga 
+Joachim Jablon  
 Johannes Schindelin  
 Johannes Sixt  
 Johannes Sixt  
@@ -150,6 +155,7 @@ Mark Levedahl  
 Mark Rada 
 Martin Langhoff  
 Martin von Zweigbergk  
+Masaya Suzuki 
 Matt Draisey  
 Matt Kraai  
 Matt McCutchen  
@@ -157,6 +163,7 @@ Matthias Kestenholz  

 Matthias Rüster  Matthias Ruester
 Matthias Urlichs  
 Matthias Urlichs  
+Matthieu Moy  
 Michael Coleman 
 Michael J Gruber  
 Michael J Gruber  
@@ -180,7 +187,11 @@ Nick Stokoe  Nick Woolley 

 Nick Stokoe  Nick Woolley 
 Nicolas Morey-Chaisemartin  

 Nicolas Morey-Chaisemartin  

+Nicolas Morey-Chaisemartin  

+Nicolas Morey-Chaisemartin  

+Nicolas Morey-Chaisemartin  

 Nicolas Sebrecht  
+Orgad Shaneh  
 Paolo Bonzini  
 Pascal Obry  
 Pascal Obry  
@@ -200,6 +211,7 @@ Philipp A. Hartmann  
 Philippe Bruhat 
 Ralf Thielow  
 Ramsay Jones  
+Randall S. Becker  
 René Scharfe  
 René Scharfe  Rene Scharfe
 Richard Hansen  
@@ -238,6 +250,7 @@ Steven Walter  

 Sven Verdoolaege  
 Sven Verdoolaege  
 SZEDER Gábor  
+Tao Qingyun  <845767...@qq.com>
 Tay Ray Chuan 
 Ted Percival  
 Theodore Ts'o 
-- 
gitgitgadget


[PATCH 0/1] Update .mailmap

2018-11-08 Thread Johannes Schindelin via GitGitGadget
I noticed that there were a couple of duplicate entries in git shortlog -nse
v2.19.1.., and then continued a bit to remove the duplicate entries even for
v2.10.0..

Johannes Schindelin (1):
  Update .mailmap

 .mailmap | 13 +
 1 file changed, 13 insertions(+)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-71%2Fdscho%2Fmailmap-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-71/dscho/mailmap-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/71
-- 
gitgitgadget


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-08 Thread Johannes Schindelin
Hi Junio,

On Thu, 8 Nov 2018, Junio C Hamano wrote:

> Johannes Schindelin  writes:
> 
> > But now I have a really crazy idea: how about ~~/ssl/certs/ca-bundle.crt?
> > The `~` prefix is *already* a reserved character,...
> 
> We would need to prepare for a future where we need yet another
> special thing to be expanded, and it will quickly become cryptic if
> you said "~/ is HOME, ~USER/ is USER's HOME, ~~/ is runtime prefix,
> and ~~~/ is this new thing...".  ~runtime_prefix~/ (i.e. carve out
> the namespace for USERNAME by reserving any names that ends with a
> tilde) may be a viable way to do this, though.   It is just as good
> as your other idea, , in an earlier message.

Indeed. Your "cryptic" matches my "unintuitive".

Ciao,
Dscho


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-08 Thread Johannes Schindelin
Hi Duy,

On Thu, 8 Nov 2018, Duy Nguyen wrote:

> On Thu, Nov 8, 2018 at 2:14 PM Johannes Schindelin
>  wrote:
> >
> > On Wed, 7 Nov 2018, Jeff King wrote:
> >
> > > All that said, if we're just interested in allowing this for config,
> > > then we already have such a wrapper function: git_config_pathname().
> >
> > Good point. I agree that `git_config_pathname()` is a better home for this
> > feature than `expand_user_path()`.
> >
> > But now I have a really crazy idea: how about ~~/ssl/certs/ca-bundle.crt?
> > The `~` prefix is *already* a reserved character, and while it would
> > probably not be super intuitive to have `~~` be expanded to the runtime
> > prefix, at least it would be less ambiguous than `$RUNTIME_PREFIX` (which
> > *is* a valid directory name).
> 
> One thing I had in mind when proposing $VARIABLE is that it opens up a
> namespace for us to expand more things (*) for example $GIT_DIR (from
> ~/.gitconfig).
> 
> (*) but in a controlled way, it may look like an environment variable,
> but we only accept a selected few. And it's only expanded at the
> beginning of a path.

I understand that desire, and I even agree. But the fact that it looks
like an environment variable, but is not, is actually a point in favor of
*not* doing this. It would violate the principle of least astonishment.

The form `/abc/def` would not be confused with anything
that it is not, I would think. The only thing against this form (at least
that I can think of) is that some people use this way to talk about paths
that vary between different setups, with the implicit assumption that the
reader will "interpolate" this *before* applying. So for example, when I
tell a user to please edit their /config, I implicitly assume
that they know to not type out, literally,  but instead fill in
the correct path.

Ciao,
Dscho

> > Of course, `~~` is also a valid directory name, but then, so is `~` and we
> > do not have any way to specify *that* because `expand_user_path()` will
> > always expand it to the home directory. Or am I wrong? Do we have a way to
> > disable the expansion?
> >
> > Ciao,
> > Dscho
> 
> 
> 
> -- 
> Duy
> 


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-08 Thread Johannes Schindelin
Hi Junio,

On Thu, 8 Nov 2018, Junio C Hamano wrote:

> Johannes Schindelin  writes:
> 
> > On Thu, 8 Nov 2018, Junio C Hamano wrote:
> >
> >> I am tempted to say "///" might also be such a
> >> way, even in the POSIX world, but am not brave enough to do so, as I
> >> suspect that may have a fallout in the Windows world X-<.
> >
> > It does. //server/share is the way we refer to UNC paths (AKA network
> > drives).
> 
> Shucks.  That would mean the patch that started this thread would
> not be a good idea, as an end-user could already be writing
> "//server/share/some/path" and the code with the patch would see '/'
> that begins it, and start treating it differently than the code
> before the patch X-<.

Ouch. You're right!

> > Granted, this is a highly unlikely scenario, but I would feel a bit more
> > comfortable with something like
> >
> > /ssl/certs/ca-bundle.crt
> >
> > Of course, `` is *also* a perfectly valid directory name,
> > but I would argue that it is even less likely to exist than
> > `$RUNTIME_PREFIX` because the user would have to escape *two* characters
> > rather than one.
> 
> Yes, and it is naturally extensible by allowing 
> inside the special bra-ket pair (just like $OTHER_THINGS can be a
> way to extend the system if we used a special variable syntax).

True.

> >> Are there security implications if we started allowing references to
> >> environment varibables in strings we pass expand_user_path()?
> >
> > Probably. But then, the runtime prefix is not even available as
> > environment variable...
> 
> Ah, sorry. I thought it was clear that I would next be suggesting to
> add an environmet variable for it, _if_ the approach to allow env
> references turns out to be viable.

Of course, I should have assumed that. Sorry!

Ciao,
Dscho


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-08 Thread Johannes Schindelin
Hi Peff,

On Wed, 7 Nov 2018, Jeff King wrote:

> All that said, if we're just interested in allowing this for config,
> then we already have such a wrapper function: git_config_pathname().

Good point. I agree that `git_config_pathname()` is a better home for this
feature than `expand_user_path()`.

But now I have a really crazy idea: how about ~~/ssl/certs/ca-bundle.crt?
The `~` prefix is *already* a reserved character, and while it would
probably not be super intuitive to have `~~` be expanded to the runtime
prefix, at least it would be less ambiguous than `$RUNTIME_PREFIX` (which
*is* a valid directory name).

Of course, `~~` is also a valid directory name, but then, so is `~` and we
do not have any way to specify *that* because `expand_user_path()` will
always expand it to the home directory. Or am I wrong? Do we have a way to
disable the expansion?

Ciao,
Dscho


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-08 Thread Johannes Schindelin
Hi,

On Thu, 8 Nov 2018, Junio C Hamano wrote:

> I am tempted to say "///" might also be such a
> way, even in the POSIX world, but am not brave enough to do so, as I
> suspect that may have a fallout in the Windows world X-<.

It does. //server/share is the way we refer to UNC paths (AKA network
drives).

> An earlier suggestion by Duy in [*1*] to pretend as if we take
> $VARIABLE and define special variables might be a better direction.

My only qualm with this is that `$VARIABLE` is a perfectly allowed part of
a path. That is, you *could* create a directory called `$VARIABLE` and
reference that, and then the expand_user_path() function (or whatever name
we will give it) would always expand this, with no way to switch it off.

Granted, this is a highly unlikely scenario, but I would feel a bit more
comfortable with something like

/ssl/certs/ca-bundle.crt

Of course, `` is *also* a perfectly valid directory name,
but I would argue that it is even less likely to exist than
`$RUNTIME_PREFIX` because the user would have to escape *two* characters
rather than one.

> Are there security implications if we started allowing references to
> environment varibables in strings we pass expand_user_path()?

Probably. But then, the runtime prefix is not even available as
environment variable...

Ciao,
Dscho

> If we cannot convince ourselves that it is safe to allow access to any
> and all environment variables, then we probably can start by specific
> "pseudo variables" under our control, like GIT_EXEC_PATH and
> GIT_INSTALL_ROOT, that do not even have to be tied to environment
> variables, perhaps with further restriction to allow it only at the
> beginning of the string, or something like that, if necessary.
> 
> [References]
> 
> *1* 
> 


[PATCH 0/2] built-in rebase --autostash: fix regression

2018-11-07 Thread Johannes Schindelin via GitGitGadget
It was reported that the new, shiny built-in git rebase has a bug where it
would detach the HEAD when it was not even necessary to detach it.

Keeping with my fine tradition to first demonstrate what is the actual
problem (and making it easy to verify my claim), this patch series first
introduces the regression test, and then the (quite simple) fix.

AEvar, sorry for the ASCII-fication of your name, I still did not find the
time to look at the GitGitGadget bug closely where it does the wrong thing
when Cc:ing with non-ASCII names.

Johannes Schindelin (2):
  built-in rebase: demonstrate regression with --autostash
  built-in rebase --autostash: leave the current branch alone if
possible

 builtin/rebase.c| 3 ++-
 t/t3420-rebase-autostash.sh | 8 
 2 files changed, 10 insertions(+), 1 deletion(-)


base-commit: 8858448bb49332d353febc078ce4a3abcc962efe
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-70%2Fdscho%2Ffix-built-in-rebase-autostash-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-70/dscho/fix-built-in-rebase-autostash-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/70
-- 
gitgitgadget


[PATCH 1/2] built-in rebase: demonstrate regression with --autostash

2018-11-07 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

An unnamed colleague of Ævar Arnfjörð Bjarmason reported a breakage
where a `pull --rebase` (which did not really need to do anything but
stash, see that nothing was changed, and apply the stash again) also
detached the HEAD.

This patch adds a minimal reproducer for this regression.

Signed-off-by: Johannes Schindelin 
---
 t/t3420-rebase-autostash.sh | 8 
 1 file changed, 8 insertions(+)

diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index f355c6825a..d4e2520bcb 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -361,4 +361,12 @@ test_expect_success 'autostash with dirty submodules' '
git rebase -i --autostash HEAD
 '
 
+test_expect_failure 'branch is left alone when possible' '
+   git checkout -b unchanged-branch &&
+   echo changed >file0 &&
+   git rebase --autostash unchanged-branch &&
+   test changed = "$(cat file0)" &&
+   test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
+'
+
 test_done
-- 
gitgitgadget



[PATCH 2/2] built-in rebase --autostash: leave the current branch alone if possible

2018-11-07 Thread Johannes Schindelin via GitGitGadget
From: Johannes Schindelin 

When we converted a `git reset --hard` call in the original Unix shell
script to built-in code, we asked to reset the worktree and the index
and explicitly *not* to detach the HEAD. By mistake, though, we still
did. Let's fix this.

Signed-off-by: Johannes Schindelin 
---
 builtin/rebase.c| 3 ++-
 t/t3420-rebase-autostash.sh | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 0ee06aa363..4a608d0a78 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -613,7 +613,8 @@ static int reset_head(struct object_id *oid, const char 
*action,
reflog_head = msg.buf;
}
if (!switch_to_branch)
-   ret = update_ref(reflog_head, "HEAD", oid, orig, REF_NO_DEREF,
+   ret = update_ref(reflog_head, "HEAD", oid, orig,
+detach_head ? REF_NO_DEREF : 0,
 UPDATE_REFS_MSG_ON_ERR);
else {
ret = create_symref("HEAD", switch_to_branch, msg.buf);
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index d4e2520bcb..4c7494cc8f 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -361,7 +361,7 @@ test_expect_success 'autostash with dirty submodules' '
git rebase -i --autostash HEAD
 '
 
-test_expect_failure 'branch is left alone when possible' '
+test_expect_success 'branch is left alone when possible' '
git checkout -b unchanged-branch &&
echo changed >file0 &&
git rebase --autostash unchanged-branch &&
-- 
gitgitgadget


Re: Regression in rebase-in-C with rebase.autoStash=true

2018-11-07 Thread Johannes Schindelin
Hi Ævar,

On Tue, 6 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> 
> On Tue, Oct 23 2018, Johannes Schindelin via GitGitGadget wrote:
> 
> > Johannes Schindelin (2):
> >   rebase --autostash: demonstrate a problem with dirty submodules
> >   rebase --autostash: fix issue with dirty submodules
> >
> >  builtin/rebase.c|  2 +-
> >  t/t3420-rebase-autostash.sh | 10 ++
> >  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> There's another bug with rebase.autoStash in master (and next/pu) but
> not v2.19.0. I tried to bisect bit it just comes down to 5541bd5b8f
> ("rebase: default to using the builtin rebase", 2018-08-08).
> 
> Credit to a co-worker of mine who wishes to remain anonymous for
> discovering this. I narrowed down his test-case to (any repo will do):
> 
> (
> rm -rf /tmp/todo &&
> git clone --single-branch --no-tags --branch=todo 
> https://github.com/git/git.git /tmp/todo &&
> cd /tmp/todo &&
> rm Make &&
> git rev-parse --abbrev-ref HEAD &&
> git -c rebase.autoStash=true -c pull.rebase=true pull &&
> if test $(git rev-parse --abbrev-ref HEAD) != 'todo'
> then
> echo 'On detached head!' &&
> git status &&
> exit 1
> else
> echo 'We are still on our todo branch!'
> fi
> )

I found the culprit. Patch forthcoming,
Dscho

Re: [PATCH 1/1] Windows: force-recompile git.res for differing architectures

2018-11-07 Thread Johannes Schindelin
Hi,

On Wed, 7 Nov 2018, Junio C Hamano wrote:

> Johannes Sixt  writes:
> 
> > Am 07.11.18 um 02:32 schrieb Junio C Hamano:
> >> Johannes Sixt  writes:
> >>> On Linux, when I recompile for a different architecture, CFLAGS would
> >>> change, so I would have thought that GIT-CFLAGS were the natural
> >>> choice for a dependency. Don't they change in this case on Windows,
> >>> too?
> >>
> >> Depending on GIT-CFLAGS would have a better chance of being safe, I
> >> guess, even though it can at times be overly safe, than GIT-PREFIX,
> >> I suspect.  As a single user target in Makefile, which is only used
> >> by Dscho, who intends to stick to /mingw(32|64)/ convention til the
> >> end of time, I think the posted patch is OK, though.
> >
> > I think that it's not only Dscho who uses the target (my build
> > environment, for example, is different from Dscho's and compiles
> > git.res, too). But since the patch helps him most and doesn't hurt
> > others, it is good to go. No objection from my side.
> 
> Yeah, that was phrased poorly.  What I meant was by "only by Dscho"
> was "only by those who share the convention that GIT-PREFIX is
> changed if and only if targetting a different arch".
> 
> Anyway, I just wanted to say that GIT-PREFIX may not be precise
> enough but would give sufficient signal; GIT-CFLAGS may be a more
> cautious choice, but it may change a bit too often ;-).

I am fine with GIT-CFLAGS, too. Do you want me to "rick-roll" a v2?

Ciao,
Dscho


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-07 Thread Johannes Schindelin
Hi Hannes,

On Tue, 6 Nov 2018, Johannes Sixt wrote:

> Am 06.11.18 um 15:53 schrieb Johannes Schindelin via GitGitGadget:
> > From: Johannes Schindelin 
> > 
> > On Windows, an absolute POSIX path needs to be turned into a Windows
> > one.
> 
> If I were picky, I would say that in a pure Windows application there cannot
> be POSIX paths to begin with.
> 
> Even if a path looks like a POSIX paths, i.e. it starts with a directory
> separator, but not with drive-letter-colon, it still has a particular meaning,
> namely (as far as I know) that the path is anchored at the root of the drive
> of the current working directory.
> 
> If a user specifies such a path on Windows, and it must undergo
> expand_user_path(), then that is a user error, or the user knows what they are
> doing.
> 
> I think it is wrong to interpret such a path as relative to some random other
> directory, like this patch seems to do.

Okay, now we know everything you find wrong with the current patch. Do you
have any suggestion how to make it right? I.e. what would you suggest as a
way to specify in a gitconfig in a portable Git where the certificate
bundle is?

Thanks,
Dscho

> 
> > 
> > Signed-off-by: Johannes Schindelin 
> > ---
> >   path.c | 5 +
> >   1 file changed, 5 insertions(+)
> > 
> > diff --git a/path.c b/path.c
> > index 34f0f98349..a72abf0e1f 100644
> > --- a/path.c
> > +++ b/path.c
> > @@ -11,6 +11,7 @@
> >   #include "path.h"
> >   #include "packfile.h"
> >   #include "object-store.h"
> > +#include "exec-cmd.h"
> >   
> >   static int get_st_mode_bits(const char *path, int *mode)
> >   {
> > @@ -709,6 +710,10 @@ char *expand_user_path(const char *path, int real_home)
> >   
> >if (path == NULL)
> > goto return_null;
> > +#ifdef __MINGW32__
> > +   if (path[0] == '/')
> > +   return system_path(path + 1);
> > +#endif
> >if (path[0] == '~') {
> > const char *first_slash = strchrnul(path, '/');
> > const char *username = path + 1;
> > 
> 
> 
> 


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-07 Thread Johannes Schindelin
Hi,

On Tue, 6 Nov 2018, Duy Nguyen wrote:

> On Tue, Nov 6, 2018 at 3:55 PM Johannes Schindelin via GitGitGadget
>  wrote:
> >
> > From: Johannes Schindelin 
> >
> > On Windows, an absolute POSIX path needs to be turned into a Windows
> > one.
> >
> > Signed-off-by: Johannes Schindelin 
> > ---
> >  path.c | 5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/path.c b/path.c
> > index 34f0f98349..a72abf0e1f 100644
> > --- a/path.c
> > +++ b/path.c
> > @@ -11,6 +11,7 @@
> >  #include "path.h"
> >  #include "packfile.h"
> >  #include "object-store.h"
> > +#include "exec-cmd.h"
> >
> >  static int get_st_mode_bits(const char *path, int *mode)
> >  {
> > @@ -709,6 +710,10 @@ char *expand_user_path(const char *path, int real_home)
> >
> > if (path == NULL)
> > goto return_null;
> > +#ifdef __MINGW32__
> > +   if (path[0] == '/')
> > +   return system_path(path + 1);
> > +#endif
> 
> Should this behavior be documented somewhere, maybe in config.txt?

First we need to find a consensus how this should work.

Ciao,
Dscho

> 
> > if (path[0] == '~') {
> > const char *first_slash = strchrnul(path, '/');
> > const char *username = path + 1;
> > --
> > gitgitgadget
> -- 
> Duy
> 


Re: [PATCH 1/1] mingw: handle absolute paths in expand_user_path()

2018-11-07 Thread Johannes Schindelin
Hi,

On Wed, 7 Nov 2018, Junio C Hamano wrote:

> Ramsay Jones  writes:
> 
> > On 06/11/2018 14:53, Johannes Schindelin via GitGitGadget wrote:
> >> From: Johannes Schindelin 
> >> 
> >> On Windows, an absolute POSIX path needs to be turned into a Windows
> >> one.
> >> 
> >> Signed-off-by: Johannes Schindelin 
> >> ---
> >>  path.c | 5 +
> >>  1 file changed, 5 insertions(+)
> >> 
> >> diff --git a/path.c b/path.c
> >> index 34f0f98349..a72abf0e1f 100644
> >> --- a/path.c
> >> +++ b/path.c
> >> @@ -11,6 +11,7 @@
> >>  #include "path.h"
> >>  #include "packfile.h"
> >>  #include "object-store.h"
> >> +#include "exec-cmd.h"
> >>  
> >>  static int get_st_mode_bits(const char *path, int *mode)
> >>  {
> >> @@ -709,6 +710,10 @@ char *expand_user_path(const char *path, int 
> >> real_home)
> >>  
> >>if (path == NULL)
> >>goto return_null;
> >> +#ifdef __MINGW32__
> >> +  if (path[0] == '/')
> >> +  return system_path(path + 1);
> >> +#endif
> >
> > Hmm, this doesn't quite fit with the intended use of this
> > function! ;-) (even on windows!)
> >
> > I haven't looked very deeply, but doesn't this affect all
> > absolute paths in the config read by git_config_pathname(),
> > along with all 'included config' files?
> 
> I think so.  I have not thought things through to say if replacing a
> "full path in the current drive" with system_path() is a sensible
> thing to do in the first place, but I am getting the impression from
> review comments that it probably is not.
> 
> > I am pretty sure that I would not want the absolute paths
> > in my config file(s) magically 'moved' depending on whether
> > git has been compiled with 'runtime prefix' support or not!

The cute thing is: your absolute paths would not be moved because we are
talking about Windows. Therefore your absolute paths would not start with
a forward slash.

> In any case, the helper is about expanding ~/foo and ~who/foo to
> absolute paths, without touching other paths, so it is a wrong
> function to implement it in, even if the motivation were sensible.

It could be renamed. In any case, for this feature we would need to expand
a path that is not the final path, and this here location is the most
logical place to do so.

Ciao,
Dscho


Re: [PATCH v2] range-diff: add a --no-patch option to show a summary

2018-11-07 Thread Johannes Schindelin
Hi,

On Wed, 7 Nov 2018, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason   writes:
> 
> > diff --git a/builtin/range-diff.c b/builtin/range-diff.c
> > index f01a0be851..05d1f6b6b6 100644
> > --- a/builtin/range-diff.c
> > +++ b/builtin/range-diff.c
> > @@ -16,11 +16,14 @@ int cmd_range_diff(int argc, const char **argv, const 
> > char *prefix)
> > int creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT;
> > struct diff_options diffopt = { NULL };
> > int simple_color = -1;
> > +   int no_patch = 0;
> > struct option options[] = {
> > OPT_INTEGER(0, "creation-factor", _factor,
> > N_("Percentage by which creation is weighted")),
> > OPT_BOOL(0, "no-dual-color", _color,
> > N_("use simple diff colors")),
> > +   OPT_BOOL_F('s', "no-patch", _patch,
> > +N_("show patch output"), PARSE_OPT_NONEG),
> 
> As OPT_BOOL("patch") natively takes "--no-patch" to flip the bool
> off, an int variable "patch" that is initialized to 1 would make it
> more readable by avoiding double negation !no_patch like the one we
> see below.  I guess the reason behind the contortion you wanted to
> give the synonym --silent to it?

In light of my investigation that revealed that the original behavior
(which is still documented in the manual page of range-diff) was broken,
and I would much rather see that fixed than adding a workaround.

I would be fine with my patch being combined with the update to the manual
page and the regression test, as a v3.

Ciao,
Dscho

> 
> > @@ -92,7 +95,7 @@ int cmd_range_diff(int argc, const char **argv, const 
> > char *prefix)
> > }
> >  
> > res = show_range_diff(range1.buf, range2.buf, creation_factor,
> > - simple_color < 1, );
> > + simple_color < 1, !no_patch, );
> 
> > strbuf_release();
> > strbuf_release();
> 
> > @@ -7,6 +7,7 @@
> >  
> >  int show_range_diff(const char *range1, const char *range2,
> > int creation_factor, int dual_color,
> > +   int patch,
> > struct diff_options *diffopt);
> 
> Other than that small "Huh?", the code looks good to me.
> 
> > diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
> > index 6aae364171..27e071650b 100755
> > --- a/t/t3206-range-diff.sh
> > +++ b/t/t3206-range-diff.sh
> > @@ -122,6 +122,26 @@ test_expect_success 'changed commit' '
> > test_cmp expected actual
> >  '
> >  
> > +test_expect_success 'changed commit -p & --patch' '
> > +   git range-diff --no-color -p topic...changed >actual &&
> > +   test_cmp expected actual &&
> > +   git range-diff --no-color --patch topic...changed >actual &&
> > +   test_cmp expected actual
> 
> This makes sure that -p and --patch produces the same output as the
> default case?  I am not sure who in the parseopt API groks the
> single letter "-p" in this case offhand.  Care to explain how?
> 
> The other side of the test to see -s/--no-patch we see below also
> makes sense.
> 
> > +test_expect_success 'changed commit -s & --no-patch' '
> > +...
> > +   cat >expected <<-EOF &&
> 
> Quote EOF to allow readers skim the contents without looking for and
> worrying about $substitutions in there, unless there are tons of
> offending code in the same script already in which case we should
> leave the clean-up outside this primary change.
> 
> 

Re: [PATCH] range-diff: add a --no-patch option to show a summary

2018-11-07 Thread Johannes Schindelin
Me again,

On Wed, 7 Nov 2018, Johannes Schindelin wrote:

> On Wed, 7 Nov 2018, Johannes Schindelin wrote:
> 
> > On Wed, 7 Nov 2018, Johannes Schindelin wrote:
> > 
> > > On Tue, 6 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> > > 
> > > > On Tue, Nov 06 2018, Johannes Schindelin wrote:
> > > > 
> > > > > On Mon, 5 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> > > > >
> > > > >> On Mon, Nov 05 2018, Eric Sunshine wrote:
> > > > >>
> > > > >> > On Mon, Nov 5, 2018 at 3:07 PM Ævar Arnfjörð Bjarmason 
> > > > >> >  wrote:
> > > > >> >> Add a --no-patch option which shows which changes got removed, 
> > > > >> >> added
> > > > >> >> or moved etc., without showing the diff associated with them.
> > > > >> >
> > > > >> > This option existed in the very first version[1] of range-diff 
> > > > >> > (then
> > > > >> > called branch-diff) implemented by Dscho, although it was called
> > > > >> > --no-patches (with an "es"), which it inherited from tbdiff. I 
> > > > >> > think
> > > > >> > someone (possibly me) pointed out that --no-patch (sans "es") 
> > > > >> > would be
> > > > >> > more consistent with existing Git options. I don't recall why Dscho
> > > > >> > removed the option during the re-rolls, but the explanation may be 
> > > > >> > in
> > > > >> > that thread.
> > > > >>
> > > > >> Thanks for digging. Big thread, not going to re-read it now. I'd just
> > > > >> like to have this.
> > > > >
> > > > > In my hands, the well-documented `-s` option works (see e.g.
> > > > > https://git-scm.com/docs/git-diff#git-diff--s), although I have to 
> > > > > admit
> > > > > that the `git-range-diff` manual does not talk about the diff-options.
> > > > >
> > > > > And for the record, for me, `git range-diff A...B --no-patch` 
> > > > > *already*
> > > > > works.
> > > > 
> > > > Neither of those works for me without my patch. E.g.
> > > > 
> > > > ./git-range-diff -s 711aaa392f...a5ba8f2101
> > > > ./git-range-diff --no-patch 711aaa392f...a5ba8f2101
> > > >
> > > > This is on current next, 2.19.1.1182.g4ecb1133ce. What version are you
> > > > on?
> > > 
> > > I tried it with git version 2.19.0.windows.1.
> > > 
> > > To verify, I repeated this with `next` (git version
> > > 2.19.1.1215.g8438c0b2453a):
> > > 
> > > ./git range-diff -s 711aaa392f...a5ba8f2101
> > > fatal: unrecognized argument: --output-indicator-new=>
> > > error: could not parse log for 'a5ba8f2101..711aaa392f'
> > > 
> > > Which means that something broke rather dramatically between
> > > v2.19.0.windows.1 and 8438c0b2453a.
> > 
> > Nevermind, this was solved by passing `--exec-path=$PWD`. And *now* I can
> > reproduce your finding.
> 
> I've bisected this breakage down to 73a834e9e279 (range-diff: relieve
> callers of low-level configuration burden, 2018-07-22). Eric, that's one
> of your commits.

Okay, so I would really like to point you to this particular paragraph in
the manual page of `git range-diff` (just below
https://git-scm.com/docs/git-range-diff#git-range-diff-ltbasegtltrev1gtltrev2gt):

`git range-diff` also accepts the regular diff options (see
linkgit:git-diff[1]), most notably the `--color=[]` and
`--no-color` options. These options are used when generating the "diff
between patches", i.e. to compare the author, commit message and diff of
corresponding old/new commits. There is currently no means to tweak the
diff options passed to `git log` when generating those patches.

So this was quite intentional, in particular with an eye on `--no-patch`.
Note also the commit message of c8c5e43ac3f9 (range-diff: also show the
diff between patches, 2018-08-13):

Note also: while tbdiff accepts the `--no-patches` option to suppress
these diffs between patches, we prefer the `-s` (or `--no-patch`)
option that is automatically supported via our use of diff_opt_parse().

This was very, very intentional, as you can see, and it was pretty broken
by 73a834e. This here patch papers over that breakage, sadly I have too
much on my plate as it is, so I cannot wrap it up in a nice commit (nor
add a regression test, but you did that, nor investigate what else is
broken) and therefore I would be indebted if you could take this in your
custody:

diff --git a/range-diff.c b/range-diff.c
index 3dd2edda0176..014112ee401f 100644
--- a/range-diff.c
+++ b/range-diff.c
@@ -433,7 +433,8 @@ int show_range_diff(const char *range1, const char *range2,
struct strbuf indent = STRBUF_INIT;
 
memcpy(, diffopt, sizeof(opts));
-   opts.output_format = DIFF_FORMAT_PATCH;
+   if (!opts.output_format)
+   opts.output_format = DIFF_FORMAT_PATCH;
opts.flags.suppress_diff_headers = 1;
opts.flags.dual_color_diffed_diffs = dual_color;
opts.output_prefix = output_prefix_cb;

Ciao,
Dscho

Re: [PATCH] range-diff: add a --no-patch option to show a summary

2018-11-07 Thread Johannes Schindelin
Hi Ævar,

On Wed, 7 Nov 2018, Johannes Schindelin wrote:

> On Wed, 7 Nov 2018, Johannes Schindelin wrote:
> 
> > On Tue, 6 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> > 
> > > On Tue, Nov 06 2018, Johannes Schindelin wrote:
> > > 
> > > > On Mon, 5 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> > > >
> > > >> On Mon, Nov 05 2018, Eric Sunshine wrote:
> > > >>
> > > >> > On Mon, Nov 5, 2018 at 3:07 PM Ævar Arnfjörð Bjarmason 
> > > >> >  wrote:
> > > >> >> Add a --no-patch option which shows which changes got removed, added
> > > >> >> or moved etc., without showing the diff associated with them.
> > > >> >
> > > >> > This option existed in the very first version[1] of range-diff (then
> > > >> > called branch-diff) implemented by Dscho, although it was called
> > > >> > --no-patches (with an "es"), which it inherited from tbdiff. I think
> > > >> > someone (possibly me) pointed out that --no-patch (sans "es") would 
> > > >> > be
> > > >> > more consistent with existing Git options. I don't recall why Dscho
> > > >> > removed the option during the re-rolls, but the explanation may be in
> > > >> > that thread.
> > > >>
> > > >> Thanks for digging. Big thread, not going to re-read it now. I'd just
> > > >> like to have this.
> > > >
> > > > In my hands, the well-documented `-s` option works (see e.g.
> > > > https://git-scm.com/docs/git-diff#git-diff--s), although I have to admit
> > > > that the `git-range-diff` manual does not talk about the diff-options.
> > > >
> > > > And for the record, for me, `git range-diff A...B --no-patch` *already*
> > > > works.
> > > 
> > > Neither of those works for me without my patch. E.g.
> > > 
> > > ./git-range-diff -s 711aaa392f...a5ba8f2101
> > > ./git-range-diff --no-patch 711aaa392f...a5ba8f2101
> > >
> > > This is on current next, 2.19.1.1182.g4ecb1133ce. What version are you
> > > on?
> > 
> > I tried it with git version 2.19.0.windows.1.
> > 
> > To verify, I repeated this with `next` (git version
> > 2.19.1.1215.g8438c0b2453a):
> > 
> > ./git range-diff -s 711aaa392f...a5ba8f2101
> > fatal: unrecognized argument: --output-indicator-new=>
> > error: could not parse log for 'a5ba8f2101..711aaa392f'
> > 
> > Which means that something broke rather dramatically between
> > v2.19.0.windows.1 and 8438c0b2453a.
> 
> Nevermind, this was solved by passing `--exec-path=$PWD`. And *now* I can
> reproduce your finding.

I've bisected this breakage down to 73a834e9e279 (range-diff: relieve
callers of low-level configuration burden, 2018-07-22). Eric, that's one
of your commits.

Ciao,
Dscho

Re: [PATCH] range-diff: add a --no-patch option to show a summary

2018-11-07 Thread Johannes Schindelin
Hi Ævar,

On Wed, 7 Nov 2018, Johannes Schindelin wrote:

> On Tue, 6 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> 
> > On Tue, Nov 06 2018, Johannes Schindelin wrote:
> > 
> > > On Mon, 5 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> > >
> > >> On Mon, Nov 05 2018, Eric Sunshine wrote:
> > >>
> > >> > On Mon, Nov 5, 2018 at 3:07 PM Ævar Arnfjörð Bjarmason 
> > >> >  wrote:
> > >> >> Add a --no-patch option which shows which changes got removed, added
> > >> >> or moved etc., without showing the diff associated with them.
> > >> >
> > >> > This option existed in the very first version[1] of range-diff (then
> > >> > called branch-diff) implemented by Dscho, although it was called
> > >> > --no-patches (with an "es"), which it inherited from tbdiff. I think
> > >> > someone (possibly me) pointed out that --no-patch (sans "es") would be
> > >> > more consistent with existing Git options. I don't recall why Dscho
> > >> > removed the option during the re-rolls, but the explanation may be in
> > >> > that thread.
> > >>
> > >> Thanks for digging. Big thread, not going to re-read it now. I'd just
> > >> like to have this.
> > >
> > > In my hands, the well-documented `-s` option works (see e.g.
> > > https://git-scm.com/docs/git-diff#git-diff--s), although I have to admit
> > > that the `git-range-diff` manual does not talk about the diff-options.
> > >
> > > And for the record, for me, `git range-diff A...B --no-patch` *already*
> > > works.
> > 
> > Neither of those works for me without my patch. E.g.
> > 
> > ./git-range-diff -s 711aaa392f...a5ba8f2101
> > ./git-range-diff --no-patch 711aaa392f...a5ba8f2101
> >
> > This is on current next, 2.19.1.1182.g4ecb1133ce. What version are you
> > on?
> 
> I tried it with git version 2.19.0.windows.1.
> 
> To verify, I repeated this with `next` (git version
> 2.19.1.1215.g8438c0b2453a):
> 
> ./git range-diff -s 711aaa392f...a5ba8f2101
> fatal: unrecognized argument: --output-indicator-new=>
> error: could not parse log for 'a5ba8f2101..711aaa392f'
> 
> Which means that something broke rather dramatically between
> v2.19.0.windows.1 and 8438c0b2453a.

Nevermind, this was solved by passing `--exec-path=$PWD`. And *now* I can
reproduce your finding.

Ciao,
Dscho

Re: [PATCH] range-diff: add a --no-patch option to show a summary

2018-11-07 Thread Johannes Schindelin
Hi Ævar,

On Tue, 6 Nov 2018, Ævar Arnfjörð Bjarmason wrote:

> On Tue, Nov 06 2018, Johannes Schindelin wrote:
> 
> > On Mon, 5 Nov 2018, Ævar Arnfjörð Bjarmason wrote:
> >
> >> On Mon, Nov 05 2018, Eric Sunshine wrote:
> >>
> >> > On Mon, Nov 5, 2018 at 3:07 PM Ævar Arnfjörð Bjarmason 
> >> >  wrote:
> >> >> Add a --no-patch option which shows which changes got removed, added
> >> >> or moved etc., without showing the diff associated with them.
> >> >
> >> > This option existed in the very first version[1] of range-diff (then
> >> > called branch-diff) implemented by Dscho, although it was called
> >> > --no-patches (with an "es"), which it inherited from tbdiff. I think
> >> > someone (possibly me) pointed out that --no-patch (sans "es") would be
> >> > more consistent with existing Git options. I don't recall why Dscho
> >> > removed the option during the re-rolls, but the explanation may be in
> >> > that thread.
> >>
> >> Thanks for digging. Big thread, not going to re-read it now. I'd just
> >> like to have this.
> >
> > In my hands, the well-documented `-s` option works (see e.g.
> > https://git-scm.com/docs/git-diff#git-diff--s), although I have to admit
> > that the `git-range-diff` manual does not talk about the diff-options.
> >
> > And for the record, for me, `git range-diff A...B --no-patch` *already*
> > works.
> 
> Neither of those works for me without my patch. E.g.
> 
> ./git-range-diff -s 711aaa392f...a5ba8f2101
> ./git-range-diff --no-patch 711aaa392f...a5ba8f2101
>
> This is on current next, 2.19.1.1182.g4ecb1133ce. What version are you
> on?

I tried it with git version 2.19.0.windows.1.

To verify, I repeated this with `next` (git version
2.19.1.1215.g8438c0b2453a):

./git range-diff -s 711aaa392f...a5ba8f2101
fatal: unrecognized argument: --output-indicator-new=>
error: could not parse log for 'a5ba8f2101..711aaa392f'

Which means that something broke rather dramatically between
v2.19.0.windows.1 and 8438c0b2453a.

Ciao,
Dscho

> 
> >>
> >> > I was also wondering if --summarize or --summary-only might be a
> >> > better name, describing the behavior at a higher level, but since
> >> > there is precedent for --no-patch (or --no-patches in tbdiff), perhaps
> >> > the name is fine as is.
> >>
> >> I think we should aim to keep a 1=1 mapping between range-diff and
> >> log/show options when possible, even though the output might have a
> >> slightly different flavor as my 4th paragraph discussing a potential
> >> --stat talks about.
> >>
> >> E.g. I can imagine that range-diff --no-patch --stat --summary would not
> >> show the patch, but a stat as described there, plus e.g. a "create
> >> mode..." if applicable.
> >>
> >> This change implements only a tiny fraction of that, but it would be
> >> very neat if we supported more stuff, and showed it in range-diff-y way,
> >> e.g. some compact format showing:
> >>
> >> 1 file changed, 3->2 insertions(+), 10->9 deletions(-)
> >> create mode 100(6 -> 7)44 new-executable
> >>
> >> > The patch itself looks okay.
> >> >
> >> > [1]: 
> >> > https://public-inbox.org/git/8bc517e35d4842f8d9d98f3b99adb9475d6db2d2.1525361419.git.johannes.schinde...@gmx.de/
> >>
> 

[PATCH 0/1] Windows: force-recompile git.res for differing architectures

2018-11-06 Thread Johannes Schindelin via GitGitGadget
This is a patch designed to help maintaining Git for Windows better: when
the same source code is "cross-compiled" for i686 as well as x86_64, we want
to rebuild the whole thing, including the resource file git.res.

Note: regular C files are re-compiled appropriately, as the default prefix
in Git for Windows is /mingw32 or /mingw64 depending on the architecture,
and this difference is manifested in the CFLAGS (which, upon change, trigger
a complete rebuild).

As non-Windows platforms do not even compile these .res files, this patch
should have exactly no effect on non-Windows builds.

Johannes Schindelin (1):
  Windows: force-recompile git.res for differing architectures

 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


base-commit: cd69ec8cde54af1817630331fc441f493866f0d4
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-67%2Fdscho%2Fmingw-git.res-bitness-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-67/dscho/mingw-git.res-bitness-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/67
-- 
gitgitgadget


[PATCH 1/1] Windows: force-recompile git.res for differing architectures

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

When git.rc is compiled into git.res, the result is actually dependent
on the architecture. That is, you cannot simply link a 32-bit git.res
into a 64-bit git.exe.

Therefore, to allow 32-bit and 64-bit builds in the same directory, we
let git.res depend on GIT-PREFIX so that it gets recompiled when
compiling for a different architecture (this works because the exec path
changes based on the architecture: /mingw32/libexec/git-core for 32-bit
and /mingw64/libexec/git-core for 64-bit).

Signed-off-by: Johannes Schindelin 
---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index bbfbb4292d..8375736c32 100644
--- a/Makefile
+++ b/Makefile
@@ -2110,7 +2110,7 @@ $(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES
$(QUIET_GEN)$(cmd_munge_script) && \
mv $@+ $@
 
-git.res: git.rc GIT-VERSION-FILE
+git.res: git.rc GIT-VERSION-FILE GIT-PREFIX
$(QUIET_RC)$(RC) \
  $(join -DMAJOR= -DMINOR= -DMICRO= -DPATCHLEVEL=, $(wordlist 1, 4, \
$(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \
-- 
gitgitgadget


[PATCH 1/1] mingw: handle absolute paths in expand_user_path()

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

On Windows, an absolute POSIX path needs to be turned into a Windows
one.

Signed-off-by: Johannes Schindelin 
---
 path.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/path.c b/path.c
index 34f0f98349..a72abf0e1f 100644
--- a/path.c
+++ b/path.c
@@ -11,6 +11,7 @@
 #include "path.h"
 #include "packfile.h"
 #include "object-store.h"
+#include "exec-cmd.h"
 
 static int get_st_mode_bits(const char *path, int *mode)
 {
@@ -709,6 +710,10 @@ char *expand_user_path(const char *path, int real_home)
 
if (path == NULL)
goto return_null;
+#ifdef __MINGW32__
+   if (path[0] == '/')
+   return system_path(path + 1);
+#endif
if (path[0] == '~') {
const char *first_slash = strchrnul(path, '/');
const char *username = path + 1;
-- 
gitgitgadget


[PATCH 0/1] mingw: handle absolute paths in expand_user_path()

2018-11-06 Thread Johannes Schindelin via GitGitGadget
While this patch has been "in production" in Git for Windows for a good
while, this patch series is half meant as a request for comments.

The reason is this: something like this (make paths specified e.g. via 
http.sslCAInfo relative to the runtime prefix) is potentially useful also in
the non-Windows context, as long as Git was built with the runtime prefix
feature.

The main problem with non-Windows platforms is that paths starting with a
single slash are unambiguously absolute, whereas we can say with certainty
that they are not absolute Windows paths.

So maybe someone on this list has a clever idea how we could specify paths
(unambiguously, even on non-Windows platforms) that Git should interpret as
relative to the runtime prefix?

Johannes Schindelin (1):
  mingw: handle absolute paths in expand_user_path()

 path.c | 5 +
 1 file changed, 5 insertions(+)


base-commit: cd69ec8cde54af1817630331fc441f493866f0d4
Published-As: 
https://github.com/gitgitgadget/git/releases/tags/pr-66%2Fdscho%2Fmingw-expand-absolute-user-path-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git 
pr-66/dscho/mingw-expand-absolute-user-path-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/66
-- 
gitgitgadget


Re: [PATCH v2 1/1] diff-highlight: Use correct /dev/null for UNIX and Windows

2018-11-06 Thread Johannes Schindelin
List,

I have no idea why this mail made it to GitGitGadget's email account but
not to the Git mailing list... Sorry about that.

Ciao,
Johannes

On Wed, 31 Oct 2018, Chris. Webster via GitGitGadget wrote:

> From: "Chris. Webster" 
> 
> Use File::Spec->devnull() for output redirection to avoid messages
> when Windows version of Perl is first in path.  The message 'The
> system cannot find the path specified.' is displayed each time git is
> run to get colors.
> 
> Signed-off-by: Chris. Webster 
> ---
>  contrib/diff-highlight/DiffHighlight.pm | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/contrib/diff-highlight/DiffHighlight.pm 
> b/contrib/diff-highlight/DiffHighlight.pm
> index 536754583b..7440aa1c46 100644
> --- a/contrib/diff-highlight/DiffHighlight.pm
> +++ b/contrib/diff-highlight/DiffHighlight.pm
> @@ -4,6 +4,11 @@ use 5.008;
>  use warnings FATAL => 'all';
>  use strict;
>  
> +# Use the correct value for both UNIX and Windows (/dev/null vs nul)
> +use File::Spec;
> +
> +my $NULL = File::Spec->devnull();
> +
>  # Highlight by reversing foreground and background. You could do
>  # other things like bold or underline if you prefer.
>  my @OLD_HIGHLIGHT = (
> @@ -134,7 +139,7 @@ sub highlight_stdin {
>  # fallback, which means we will work even if git can't be run.
>  sub color_config {
>   my ($key, $default) = @_;
> - my $s = `git config --get-color $key 2>/dev/null`;
> + my $s = `git config --get-color $key 2>$NULL`;
>   return length($s) ? $s : $default;
>  }
>  
> -- 
> gitgitgadget
> 


<    1   2   3   4   5   6   7   8   9   10   >