Re: [PATCH v4 3/9] t3422: new testcases for checking when incompatible options passed

2018-06-26 Thread Elijah Newren
On Tue, Jun 26, 2018 at 11:17 AM, Junio C Hamano  wrote:
> Elijah Newren  writes:
>
>> +# Rebase has lots of useful options like --whitepsace=fix, which are
>> +# actually all built in terms of flags to git-am.  Since neither
>> +# --merge nor --interactive (nor any options that imply those two) use
>> +# git-am, using them together will result in flags like --whitespace=fix
>> +# being ignored.  Make sure rebase warns the user and aborts instead.
>> +#
>> +
>> +test_rebase_am_only () {
>> + opt=$1
>> + shift
>> + test_expect_failure "$opt incompatible with --merge" "
>> + git checkout B^0 &&
>> + test_must_fail git rebase $opt --merge A
>> + "
>> +
>> + test_expect_failure "$opt incompatible with --strategy=ours" "
>> + git checkout B^0 &&
>> + test_must_fail git rebase $opt --strategy=ours A
>> + "
>> +
>> + test_expect_failure "$opt incompatible with --strategy-option=ours" "
>> + git checkout B^0 &&
>> + test_must_fail git rebase $opt --strategy=ours A
>
> This line is broken and it is carried over to later patches.  It
> needs to be -Xours (or --strategy-option=ours, if we really want ot
> be verbose).

Indeed; I'll fix that up and resubmit.  Thanks for catching it.

>> + "
>> +
>> + test_expect_failure "$opt incompatible with --interactive" "
>> + git checkout B^0 &&
>> + test_must_fail git rebase $opt --interactive A
>> + "
>> +
>> + test_expect_failure "$opt incompatible with --exec" "
>> + git checkout B^0 &&
>> + test_must_fail git rebase $opt --exec 'true' A
>> + "
>> +
>> +}
>
>> +
>> +test_rebase_am_only --whitespace=fix
>> +test_rebase_am_only --ignore-whitespace
>> +test_rebase_am_only --committer-date-is-author-date
>> +test_rebase_am_only -C4
>
> I was hesitant to hardcode what I perceive as limitations of non-am
> rebase implementations with a test like this, but once somebody
> fixes "rebase -i" for example to be capable of --whitespace=fix for
> example, then we can just drop one line from the above four (and
> write other tests for "rebase -i --whitespace=fix").  The
> test_rebase_am_only is to help us make sure what is (still) not
> supported by non-am rebases gets diagnosed as an error.

Yes, and I was thinking in particular that we could start by teaching
rebase -i to understand --ignore-space-change/--ignore-whitespace by
just transliterating it into -Xignore-space-change.  That is, after
https://public-inbox.org/git/20180607050845.19779-2-new...@gmail.com/
is picked up and eventually merged down.  Speaking of which, I need to
resubmit that.

> So my worry is totally unfounded, which is good.


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Eric Sunshine
On Wed, Jun 27, 2018 at 2:27 AM Johannes Sixt  wrote:
> Am 27.06.2018 um 04:15 schrieb Elijah Newren:
> > On Tue, Jun 26, 2018 at 2:01 PM, Jeff King  wrote:
> >> On Tue, Jun 26, 2018 at 04:46:18PM -0400, Eric Sunshine wrote:
> >>> Some of these dangers can be de-thoothed during the linting phase by
> >>> defining do-nothing shell functions:
> >>>  cp () { :; }
> >>> That, at least, makes the scariest case ("rm") much less so.
> >>
> >> Now that's an interesting idea. We can't catch every dangerous action
> >> (notably ">" would be hard to override), but it should be pretty cheap
> >> to cover some obvious ones.
> >
> > Crazy idea: maybe we could defang it a little more thoroughly with
> > something like the following (apologies in advance if gmail whitespace
> > damages this):
> >
> > -   if test "OK-117" != "$(test_eval_ "(exit 117) &&
> > $1${LF}${LF}echo OK-\$?" 3>&1)"
> > +   if test "OK-117" != "$(test_eval_ "cd() { return 0; }
> > && PATH=/dev/null && export PATH && (exit 117) && $1${LF}${LF}echo
> > OK-\$?" 3>&1)"

Interesting idea (coupled with Hannes's point below)...

> I'd define all these functions as { return 1; } because we want to stop
> any && chain as early as possible (and with an exit code that is not the
> sentinel value).

A very sensible suggestion.


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Johannes Sixt

Am 27.06.2018 um 04:15 schrieb Elijah Newren:

On Tue, Jun 26, 2018 at 2:01 PM, Jeff King  wrote:

On Tue, Jun 26, 2018 at 04:46:18PM -0400, Eric Sunshine wrote:



Some of these dangers can be de-thoothed during the linting phase by
defining do-nothing shell functions:

 cp () { :; }
 mv () { :; }
 ln () { :; }

That, at least, makes the scariest case ("rm") much less so.


Now that's an interesting idea. We can't catch every dangerous action
(notably ">" would be hard to override), but it should be pretty cheap
to cover some obvious ones.

-Peff


Crazy idea: maybe we could defang it a little more thoroughly with
something like the following (apologies in advance if gmail whitespace
damages this):

diff --git a/t/test-lib.sh b/t/test-lib.sh
index 28315706be..7fda08a90a 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -675,7 +675,7 @@ test_run_ () {
 trace=
 # 117 is magic because it is unlikely to match the exit
 # code of other programs
-   if test "OK-117" != "$(test_eval_ "(exit 117) &&
$1${LF}${LF}echo OK-\$?" 3>&1)"
+   if test "OK-117" != "$(test_eval_ "cd() { return 0; }
&& PATH=/dev/null && export PATH && (exit 117) && $1${LF}${LF}echo
OK-\$?" 3>&1)"
 then
 error "bug in the test script: broken &&-chain
or run-away HERE-DOC: $1"
 fi


I'd define all these functions as { return 1; } because we want to stop 
any && chain as early as possible (and with an exit code that is not the 
sentinel value).


-- Hannes


[PATCH] doc: substitute ETC_GIT(CONFIG|ATTRIBUTES) in generated docs

2018-06-26 Thread Todd Zullinger
Replace `$(prefix)/etc/gitconfig` and `$(prefix)/etc/gitattributes` in
generated documentation with the paths chosen when building.  Readers of
the documentation should not need to know how `$(prefix)` was defined.

It's also more consistent than sometimes using `$(prefix)/etc/gitconfig`
and other times using `/etc/gitconfig` to refer to the system-wide
config file.

Update the SYNOPSIS of gitattributes(5) to include the system-wide
config file as well.

Signed-off-by: Todd Zullinger 
---
I noticed this while looking to update gitattributes.txt to
note the system-wide config file.  I tested with and without
RUNTIME_PREFIX as well as make gitattributes.5 from within
Documentation.  I believe all methods do the right thing.

I couldn't figure out a good way to have asciidoc expand the
attributes inside of a "`" literal, so I changed to the "+"
form.  There might be a better way to do this, passing subs=
in asciidoc.conf, but I wasn't clear on where that would
fit.  I tested with asciidoc and not asciidoctor.

 Documentation/Makefile  | 13 +
 Documentation/config.txt|  4 ++--
 Documentation/git-config.txt| 10 +-
 Documentation/git.txt   |  4 ++--
 Documentation/gitattributes.txt |  4 ++--
 5 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/Documentation/Makefile b/Documentation/Makefile
index d079d7c73a..75af671798 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -95,6 +95,7 @@ DOC_MAN7 = $(patsubst %.txt,%.7,$(MAN7_TXT))
 
 prefix ?= $(HOME)
 bindir ?= $(prefix)/bin
+sysconfdir ?= $(prefix)/etc
 htmldir ?= $(prefix)/share/doc/git-doc
 infodir ?= $(prefix)/share/info
 pdfdir ?= $(prefix)/share/doc/git-doc
@@ -205,6 +206,18 @@ DEFAULT_EDITOR_SQ = $(subst ','\'',$(DEFAULT_EDITOR))
 ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)'
 endif
 
+ifndef ETC_GITCONFIG
+ETC_GITCONFIG = $(sysconfdir)/gitconfig
+endif
+ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG))
+ASCIIDOC_EXTRA += -a 'etc-gitconfig=$(ETC_GITCONFIG_SQ)'
+
+ifndef ETC_GITATTRIBUTES
+ETC_GITATTRIBUTES = $(sysconfdir)/gitattributes
+endif
+ETC_GITATTRIBUTES_SQ = $(subst ','\'',$(ETC_GITATTRIBUTES))
+ASCIIDOC_EXTRA += -a 'etc-gitattributes=$(ETC_GITATTRIBUTES_SQ)'
+
 QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
 QUIET_SUBDIR1  =
 
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 1cc18a828c..ed903b60bd 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -5,7 +5,7 @@ The Git configuration file contains a number of variables that 
affect
 the Git commands' behavior. The `.git/config` file in each repository
 is used to store the configuration for that repository, and
 `$HOME/.gitconfig` is used to store a per-user configuration as
-fallback values for the `.git/config` file. The file `/etc/gitconfig`
+fallback values for the `.git/config` file. The file +{etc-gitconfig}+
 can be used to store a system-wide default configuration.
 
 The configuration variables are used by both the Git plumbing
@@ -2815,7 +2815,7 @@ configuration files (e.g. `$HOME/.gitconfig`).
 
 Example:
 
-/etc/gitconfig
+{etc-gitconfig}
   push.pushoption = a
   push.pushoption = b
 
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 18ddc78f42..0d5ea5b58e 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -114,10 +114,10 @@ See also <>.
 
 --system::
For writing options: write to system-wide
-   `$(prefix)/etc/gitconfig` rather than the repository
+   +{etc-gitconfig}+ rather than the repository
`.git/config`.
 +
-For reading options: read only from system-wide `$(prefix)/etc/gitconfig`
+For reading options: read only from system-wide +{etc-gitconfig}+
 rather than from all available files.
 +
 See also <>.
@@ -263,7 +263,7 @@ FILES
 If not set explicitly with `--file`, there are four files where
 'git config' will search for configuration options:
 
-$(prefix)/etc/gitconfig::
+{etc-gitconfig}::
System-wide configuration file.
 
 $XDG_CONFIG_HOME/git/config::
@@ -310,11 +310,11 @@ ENVIRONMENT
 GIT_CONFIG::
Take the configuration from the given file instead of .git/config.
Using the "--global" option forces this to ~/.gitconfig. Using the
-   "--system" option forces this to $(prefix)/etc/gitconfig.
+   "--system" option forces this to {etc-gitconfig}.
 
 GIT_CONFIG_NOSYSTEM::
Whether to skip reading settings from the system-wide
-   $(prefix)/etc/gitconfig file. See linkgit:git[1] for details.
+   {etc-gitconfig} file. See linkgit:git[1] for details.
 
 See also <>.
 
diff --git a/Documentation/git.txt b/Documentation/git.txt
index dba7f0c18e..6a4646f991 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -567,10 +567,10 @@ for further details.
 
 `GIT_CONFIG_NOSYSTEM`::
Whether to skip reading settings from the system-wide
-   `$(prefix)/etc/gitconfig` file.  This environment var

[PATCH 1/2] gitignore.txt: clarify default core.excludesfile path

2018-06-26 Thread Todd Zullinger
The default core.excludesfile path is $XDG_CONFIG_HOME/git/ignore.
$HOME/.config/git/ignore is used if XDG_CONFIG_HOME is empty or unset,
as described later in the document.

Signed-off-by: Todd Zullinger 
---
 Documentation/gitignore.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index ff5d7f9ed6..d107daaffd 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -7,7 +7,7 @@ gitignore - Specifies intentionally untracked files to ignore
 
 SYNOPSIS
 
-$HOME/.config/git/ignore, $GIT_DIR/info/exclude, .gitignore
+$XDG_CONFIG_HOME/git/ignore, $GIT_DIR/info/exclude, .gitignore
 
 DESCRIPTION
 ---
-- 
2.18.0



[PATCH 2/2] dir.c: fix typos in core.excludesfile comment

2018-06-26 Thread Todd Zullinger
Make it easier to find references to core.excludesfile and the default
$XDG_CONFIG_HOME/git/ignore path.

Signed-off-by: Todd Zullinger 
---
I noticed the typo in core.excludesfile and $XDG_CONFIG_HOME while I was
verifing the previous change to clarify the documentation matched the code.
Fixing these minor issues in the comments will hopefully make it easier for
others to find the right places in the code in the future.

 dir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dir.c b/dir.c
index fe9bf58e4c..363a4837ae 100644
--- a/dir.c
+++ b/dir.c
@@ -2497,7 +2497,7 @@ void setup_standard_excludes(struct dir_struct *dir)
 {
dir->exclude_per_dir = ".gitignore";
 
-   /* core.excludefile defaulting to $XDG_HOME/git/ignore */
+   /* core.excludesfile defaulting to $XDG_CONFIG_HOME/git/ignore */
if (!excludes_file)
excludes_file = xdg_config_home("ignore");
if (excludes_file && !access_or_warn(excludes_file, R_OK, 0))
-- 
2.18.0



Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Elijah Newren
On Tue, Jun 26, 2018 at 2:01 PM, Jeff King  wrote:
> On Tue, Jun 26, 2018 at 04:46:18PM -0400, Eric Sunshine wrote:

>> Some of these dangers can be de-thoothed during the linting phase by
>> defining do-nothing shell functions:
>>
>> cp () { :; }
>> mv () { :; }
>> ln () { :; }
>>
>> That, at least, makes the scariest case ("rm") much less so.
>
> Now that's an interesting idea. We can't catch every dangerous action
> (notably ">" would be hard to override), but it should be pretty cheap
> to cover some obvious ones.
>
> -Peff

Crazy idea: maybe we could defang it a little more thoroughly with
something like the following (apologies in advance if gmail whitespace
damages this):

diff --git a/t/test-lib.sh b/t/test-lib.sh
index 28315706be..7fda08a90a 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -675,7 +675,7 @@ test_run_ () {
trace=
# 117 is magic because it is unlikely to match the exit
# code of other programs
-   if test "OK-117" != "$(test_eval_ "(exit 117) &&
$1${LF}${LF}echo OK-\$?" 3>&1)"
+   if test "OK-117" != "$(test_eval_ "cd() { return 0; }
&& PATH=/dev/null && export PATH && (exit 117) && $1${LF}${LF}echo
OK-\$?" 3>&1)"
then
error "bug in the test script: broken &&-chain
or run-away HERE-DOC: $1"
fi


Re: [PATCH 00/29] t: detect and fix broken &&-chains in subshells

2018-06-26 Thread Jonathan Nieder
Jun 26, 2018 at 03:31:11PM -0700, Junio C Hamano wrote:
> Eric Sunshine  writes:
>> On Tue, Jun 26, 2018 at 3:38 PM Junio C Hamano  wrote:

>>> I like these earlier changes that fix existing breakage, of course.
>>> I also like many of the changes that simplify and/or modernise the
>>> test scripts very much, but they are unusable as-is as long as their
>>> justification is "chain-lint will start barfing on these constructs".
>>
>> Sorry, I'm having difficulty understanding.
>>
>> Are you saying that you don't want patches which exist merely to
>> pacify --chain-lint? (For instance, 2/29 "t0001: use "{...}" block
>> around "||" expression rather than subshell".)
>
> Yes.
>
>> Or are you saying that you don't like how the commit messages are
>> worded, and that they should instead emphasize that the change is good
>> for its own sake, without mentioning --chain-lint?
>
> Yes, too.
>
> For example, 03/29 is a good clean-up, and its value is not
> diminished even if we reject the subprocess munging --chain-lint in
> 29/29.
>
> As opposed to 02/29 which mostly is about appeasing the "shell
> parser" in 29/29 (or you could justify it saying "one less fork and
> process" if that gives us a measurable benefit).

This is a lighter-weight example of the practice described at
https://lkml.kernel.org/r/alpine.LFD.2.00.1001251002430.3574@localhost.localdomain/.
In my opinion it's good advice, often worth repeating.

Thanks,
Jonathan


Sie da....

2018-06-26 Thread Post Mailer

Sie haben 5, OOO, OOO.OO EUR in das laufende Spendenprogramm der FIFA Fussball 
Weltmeisterschaft Russland 2018 gespendet. Bitte antworten Sie zurück für 
Ansprüche.



---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus



Re: [PATCH v2] filter-branch: skip commits present on --state-branch

2018-06-26 Thread Junio C Hamano
Ian Campbell  writes:

> On Mon, 2018-06-25 at 21:07 -0700, Michael Barabanov wrote:
>> The commits in state:filter.map have already been processed, so don't
>> filter them again. This makes incremental git filter-branch much
>> faster.
>> 
>> Also add tests for --state-branch option.
>> 
>> Signed-off-by: Michael Barabanov 
>
> Acked-by: Ian Campbell 

Thanks.

>
>> ---
>>  git-filter-branch.sh |  1 +
>>  t/t7003-filter-branch.sh | 15 +++
>>  2 files changed, 16 insertions(+)
>> 
>> diff --git a/git-filter-branch.sh b/git-filter-branch.sh
>> index ccceaf19a..5c5afa2b9 100755
>> --- a/git-filter-branch.sh
>> +++ b/git-filter-branch.sh
>> @@ -372,6 +372,7 @@ while read commit parents; do
>>  git_filter_branch__commit_count=$(($git_filter_branch__commi
>> t_count+1))
>>  
>>  report_progress
>> +test -f "$workdir"/../map/$commit && continue
>>  
>>  case "$filter_subdir" in
>>  "")
>> diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
>> index ec4b160dd..e23de7d0b 100755
>> --- a/t/t7003-filter-branch.sh
>> +++ b/t/t7003-filter-branch.sh
>> @@ -107,6 +107,21 @@ test_expect_success 'test that the directory was
>> renamed' '
>>  test dir/D = "$(cat diroh/D.t)"
>>  '
>>  
>> +V=$(git rev-parse HEAD)
>> +
>> +test_expect_success 'populate --state-branch' '
>> +git filter-branch --state-branch state -f --tree-filter
>> "touch file || :" HEAD
>> +'
>> +
>> +W=$(git rev-parse HEAD)
>> +
>> +test_expect_success 'using --state-branch to skip already rewritten
>> commits' '
>> +test_when_finished git reset --hard $V &&
>> +git reset --hard $V &&
>> +git filter-branch --state-branch state -f --tree-filter
>> "touch file || :" HEAD &&
>> +test_cmp_rev $W HEAD
>> +'
>> +
>>  git tag oldD HEAD~4
>>  test_expect_success 'rewrite one branch, keeping a side branch' '
>>  git branch modD oldD &&


Re: [PATCH v6 4/4] stash: convert pop to builtin

2018-06-26 Thread Johannes Schindelin
Hi Paul,

I think I had revewied these 4 patches before, and I'd wager a bet that
you addressed all of my suggestions, if any.

I had a look over patches 2-4, and want to take a little bit more time
tomorrow to pour over patch 1 (which is a little larger, as it lays a lot
of ground work), to make sure that I cannot find anything else to improve.

Well done so far!
Dscho


On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> From: Joel Teichroeb 
> 
> Add stash pop to the helper and delete the pop_stash, drop_stash,
> assert_stash_ref functions from the shell script now that they
> are no longer needed.
> 
> Signed-off-by: Joel Teichroeb 
> Signed-off-by: Paul-Sebastian Ungureanu 
> ---
>  builtin/stash--helper.c | 36 ++-
>  git-stash.sh| 47 ++---
>  2 files changed, 37 insertions(+), 46 deletions(-)
> 
> diff --git a/builtin/stash--helper.c b/builtin/stash--helper.c
> index fbf78249c..a38d6ae8a 100644
> --- a/builtin/stash--helper.c
> +++ b/builtin/stash--helper.c
> @@ -13,7 +13,7 @@
>  
>  static const char * const git_stash_helper_usage[] = {
>   N_("git stash--helper drop [-q|--quiet] []"),
> - N_("git stash--helper apply [--index] [-q|--quiet] []"),
> + N_("git stash--helper ( pop | apply ) [--index] [-q|--quiet] 
> []"),
>   N_("git stash--helper branch  []"),
>   N_("git stash--helper clear"),
>   NULL
> @@ -24,6 +24,11 @@ static const char * const git_stash_helper_drop_usage[] = {
>   NULL
>  };
>  
> +static const char * const git_stash_helper_pop_usage[] = {
> + N_("git stash--helper pop [--index] [-q|--quiet] []"),
> + NULL
> +};
> +
>  static const char * const git_stash_helper_apply_usage[] = {
>   N_("git stash--helper apply [--index] [-q|--quiet] []"),
>   NULL
> @@ -528,6 +533,33 @@ static int drop_stash(int argc, const char **argv, const 
> char *prefix)
>   return ret;
>  }
>  
> +static int pop_stash(int argc, const char **argv, const char *prefix)
> +{
> + int index = 0, ret;
> + struct stash_info info;
> + struct option options[] = {
> + OPT__QUIET(&quiet, N_("be quiet, only report errors")),
> + OPT_BOOL(0, "index", &index,
> + N_("attempt to recreate the index")),
> + OPT_END()
> + };
> +
> + argc = parse_options(argc, argv, prefix, options,
> +  git_stash_helper_pop_usage, 0);
> +
> + if (get_stash_info(&info, argc, argv))
> + return -1;
> +
> + assert_stash_ref(&info);
> + if ((ret = do_apply_stash(prefix, &info, index)))
> + printf_ln(_("The stash entry is kept in case you need it 
> again."));
> + else
> + ret = do_drop_stash(prefix, &info);
> +
> + free_stash_info(&info);
> + return ret;
> +}
> +
>  static int branch_stash(int argc, const char **argv, const char *prefix)
>  {
>   const char *branch = NULL;
> @@ -589,6 +621,8 @@ int cmd_stash__helper(int argc, const char **argv, const 
> char *prefix)
>   return !!clear_stash(argc, argv, prefix);
>   else if (!strcmp(argv[0], "drop"))
>   return !!drop_stash(argc, argv, prefix);
> + else if (!strcmp(argv[0], "pop"))
> + return !!pop_stash(argc, argv, prefix);
>   else if (!strcmp(argv[0], "branch"))
>   return !!branch_stash(argc, argv, prefix);
>  
> diff --git a/git-stash.sh b/git-stash.sh
> index 29d9f4425..8f2640fe9 100755
> --- a/git-stash.sh
> +++ b/git-stash.sh
> @@ -554,50 +554,6 @@ assert_stash_like() {
>   }
>  }
>  
> -is_stash_ref() {
> - is_stash_like "$@" && test -n "$IS_STASH_REF"
> -}
> -
> -assert_stash_ref() {
> - is_stash_ref "$@" || {
> - args="$*"
> - die "$(eval_gettext "'\$args' is not a stash reference")"
> - }
> -}
> -
> -apply_stash () {
> - cd "$START_DIR"
> - git stash--helper apply "$@"
> - res=$?
> - cd_to_toplevel
> - return $res
> -}
> -
> -pop_stash() {
> - assert_stash_ref "$@"
> -
> - if apply_stash "$@"
> - then
> - drop_stash "$@"
> - else
> - status=$?
> - say "$(gettext "The stash entry is kept in case you need it 
> again.")"
> - exit $status
> - fi
> -}
> -
> -drop_stash () {
> - assert_stash_ref "$@"
> -
> - git reflog delete --updateref --rewrite "${REV}" &&
> - say "$(eval_gettext "Dropped \${REV} (\$s)")" ||
> - die "$(eval_gettext "\${REV}: Could not drop stash entry")"
> -
> - # clear_stash if we just dropped the last stash entry
> - git rev-parse --verify --quiet "$ref_stash@{0}" >/dev/null ||
> - clear_stash
> -}
> -
>  test "$1" = "-p" && set "push" "$@"
>  
>  PARSE_CACHE='--not-parsed'
> @@ -655,7 +611,8 @@ drop)
>   ;;
>  pop)
>   shift
> - pop_stash "$@"
> + cd "$START_DIR"
> + git stash--helper pop "$@"
>   ;;
>  branch)
>   shift
> -- 

Re: [PATCH 00/29] t: detect and fix broken &&-chains in subshells

2018-06-26 Thread Junio C Hamano
Eric Sunshine  writes:

> On Tue, Jun 26, 2018 at 3:38 PM Junio C Hamano  wrote:
>> I first looked at 29/29 and got heavily inclined to reject that
>> step, and then continued reading from 1/29 to around 15/29.
>>
>> I like these earlier changes that fix existing breakage, of course.
>> I also like many of the changes that simplify and/or modernise the
>> test scripts very much, but they are unusable as-is as long as their
>> justification is "chain-lint will start barfing on these constructs".
>
> Sorry, I'm having difficulty understanding.
>
> Are you saying that you don't want patches which exist merely to
> pacify --chain-lint? (For instance, 2/29 "t0001: use "{...}" block
> around "||" expression rather than subshell".)

Yes.

> Or are you saying that you don't like how the commit messages are
> worded, and that they should instead emphasize that the change is good
> for its own sake, without mentioning --chain-lint?

Yes, too.

For example, 03/29 is a good clean-up, and its value is not
diminished even if we reject the subprocess munging --chain-lint in
29/29.

As opposed to 02/29 which mostly is about appeasing the "shell
parser" in 29/29 (or you could justify it saying "one less fork and
process" if that gives us a measurable benefit).


Re: [PATCH v6 3/4] stash: convert branch to builtin

2018-06-26 Thread Johannes Schindelin
Hi Paul,

On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> diff --git a/builtin/stash--helper.c b/builtin/stash--helper.c
> index 84a537f39..fbf78249c 100644
> --- a/builtin/stash--helper.c
> +++ b/builtin/stash--helper.c
> @@ -522,6 +528,41 @@ static int drop_stash(int argc, const char **argv, const 
> char *prefix)
>   return ret;
>  }
>  
> +static int branch_stash(int argc, const char **argv, const char *prefix)
> +{
> + const char *branch = NULL;
> + int ret;
> + struct argv_array args = ARGV_ARRAY_INIT;
> + struct stash_info info;
> + struct option options[] = {
> + OPT_END()
> + };
> +
> + argc = parse_options(argc, argv, prefix, options,
> +  git_stash_helper_branch_usage, 0);
> +
> + if (argc == 0)
> + return error(_("No branch name specified"));
> +
> + branch = argv[0];
> +
> + if (get_stash_info(&info, argc - 1, argv + 1))
> + return -1;
> +
> + argv_array_pushl(&args, "checkout", "-b", NULL);
> + argv_array_push(&args, branch);
> + argv_array_push(&args, oid_to_hex(&info.b_commit));

Why not combine these? _pushl() takes a NULL-terminated list:

argv_array_pushl(&args, "checkout", "-b", branch,
 oid_to_hex(&info.b_commit), NULL);

> + ret = cmd_checkout(args.argc, args.argv, prefix);

I guess it is okay to run that, but the cmd_() functions are not *really*
meant to be called this way... Personally, I would be more comfortable
with a `run_command()` here, i.e. with a spawned process, until the time
when checkout.c/checkout.h have learned enough API for a direct call.

Ciao,
Dscho


Re: [RFC PATCH v5] Implement --first-parent for git rev-list --bisect

2018-06-26 Thread Junio C Hamano
Christian Couder  writes:

> Obviousness is often not the same for everybody.

... which you just learned---what you thought obvious turns out to
be not so obvious after all, so you adjust to help your readers.

>> In this particular case it even feels as if this test is not even testing
>> what it should test at all:
>>
>> - it should verify that all of the commits in the first parent lineage are
>>   part of the list
>
> It does that.
>
>> - it should verify that none of the other commits are in the list
>
> It does that too.

But the point is it does a lot more by insisting exact output.  For
example, the version I reviewed had a two "expected output", and
said that the actual output must match either one of them.  I guess
it was because there were two entries with the same distance and we
cannot rely on which order they appear in the result?  If a test
history gained another entry with the same distance, then would we
need 6 possible expected output because we cannot rely on the order
in which these three come out?

That was the only thing I was complaining about.  Dscho gave me too
much credit and read a lot more good things than what I actually
meant to say ;-).

>> And that is really all there is to test.

Another is that "rev-list --bisect-all" promises that the entries
are ordered by the distance value.  So taking the above three
points, perhaps

cat >expect actual.sorted &&
sort expect >expect.sorted &&
test_cmp expect.sorted actual.sorted

# Make sure the entries are sorted in the dist order
sed -e 's/.*(dist=\([1-9]*[0-9]\)).*/\1/' actual >actual.dists &&
sort actual.dists >actual.dists.sorted &&
test_cmp actual.dists.sorted actual.dists

is what I would have expected.


Herzlichen Glückwunsch, Sie haben 650 000 €

2018-06-26 Thread Lacey Williams
Herzlichen Glückwunsch, Sie haben in den Euro Millions / Google 650.000 Euro 
gewonnen
Promo monatliche Auslosungen am 1. Juni 2018 statt.
Kontaktieren Sie unseren Schadenmakler mit den folgenden Informationen für 
Schäden
auf dieser E-Mail: johnlubos...@gmail.com

1. Vollständiger Name:
2. Adresse:
3. Geschlecht:
4. Alter:
5. Beruf:
6. Telefon:

Robert Avtandiltayn
Online-Koordinator


Re: [PATCH v6 2/4] stash: convert drop and clear to builtin

2018-06-26 Thread Johannes Schindelin
Hi Paul,

On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> diff --git a/builtin/stash--helper.c b/builtin/stash--helper.c
> index 1c4387b10..84a537f39 100644
> --- a/builtin/stash--helper.c
> +++ b/builtin/stash--helper.c
> @@ -414,6 +451,77 @@ static int apply_stash(int argc, const char **argv, 
> const char *prefix)
>   return ret;
>  }
>  
> +static int do_drop_stash(const char *prefix, struct stash_info *info)
> +{
> + struct argv_array args = ARGV_ARRAY_INIT;
> + struct child_process cp = CHILD_PROCESS_INIT;
> + int ret;
> +
> + /*
> +  * reflog does not provide a simple function for deleting refs. One will
> +  * need to be added to avoid implementing too much reflog code here
> +  */
> + argv_array_pushl(&args, "reflog", "delete", "--updateref", "--rewrite",
> +  NULL);
> + argv_array_push(&args, info->revision.buf);
> + ret = cmd_reflog(args.argc, args.argv, prefix);
> + if (!ret) {
> + if (!quiet)
> + printf(_("Dropped %s (%s)\n"), info->revision.buf,
> +oid_to_hex(&info->w_commit));
> + } else {
> + return error(_("%s: Could not drop stash entry"), 
> info->revision.buf);
> + }
> +
> + /*
> +  * This could easily be replaced by get_oid, but currently it will 
> throw a
> +  * fatal error when a reflog is empty, which we can not recover from
> +  */
> + cp.git_cmd = 1;
> + /* Even though --quiet is specified, rev-parse still outputs the hash */
> + cp.no_stdout = 1;
> + argv_array_pushl(&cp.args, "rev-parse", "--verify", "--quiet", NULL);
> + argv_array_pushf(&cp.args, "%s@{0}", ref_stash);
> + ret = run_command(&cp);

I thought you had introduced `get_oidf()` specifically so you could avoid
the `rev-parse` call... `get_oidf(&dummy_oid, "%s@{0}", ref_stash)` should
do this, right?

Ciao,
Dscho


Re: [PATCH v6 0/4] stash: Convert some `git stash` commands to a builtin

2018-06-26 Thread Johannes Schindelin
Hi Paul,

On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> This second series of patches contains commits to convert `apply`, `drop`,
> `clear`, `branch`, `pop` stash subcommands to builtins.
> 
> 
> Joel Teichroeb (4):
>   stash: convert apply to builtin
>   stash: convert drop and clear to builtin
>   stash: convert branch to builtin
>   stash: convert pop to builtin

Were there any changes since v5 in these patches?

Ciao,
Dscho


Re: [PATCH v6 4/4] stash: renamed test cases to be more descriptive

2018-06-26 Thread Johannes Schindelin
Hi Paul,

On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> Renamed some test cases' labels to be more descriptive and under 80
> characters per line.
> 
> Signed-off-by: Paul-Sebastian Ungureanu 

As I suggested this kind of change, I am obviously happy with this patch.

Apart from minor suggestions, I think this patch series is good to go.

Thank you!
Dscho


Re: [PATCH v6 3/4] stash: update test cases conform to coding guidelines

2018-06-26 Thread Johannes Schindelin
Hi Paul,

On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> Removed whitespaces after redirection operators.

That is accurate a description of what the patch does. Let's add the why
(and change the tense to present tense, as is the custom in our commit
messages):

This adjusts t3903-stash.sh to conform with our coding conventions
better, by removing whitespace between redirection operators and
their file names.

The patch does two more things, though: it breaks at least one long line,
and it renames at least two non-descriptive files to the much better name
`expected`. Maybe you want to mention that in the commit message, to?

Thanks,
Dscho


Re: [PATCH v6 1/4] sha1-name.c: added 'get_oidf', which acts like 'get_oid'

2018-06-26 Thread Johannes Schindelin
Hi Paul,

as a general rule, we try to keep the commit subjects in the imperative,
i.e.

sha1-name.c: add 'get_oidf', which acts like 'get_oid'

On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> Compared to 'get_oid', 'get_oidf' has as parameters a
> printf format string and the additional arguments. This
> will help simplify the code in subsequent commits.

Good. The patch is obviously correct, from my perspective.

Ciao,
Dscho


Re: [PATCH v6 0/4] stash: add new tests and introduce a new helper function

2018-06-26 Thread Johannes Schindelin
Hi,

On Mon, 25 Jun 2018, Paul-Sebastian Ungureanu wrote:

> This first series of patches does bring some changes and improvements to
> the test suite. One of the patches also introduces a new function
> `get_oidf()` which will be hepful for the incoming patches related to
> `git stash`.

For reviewers: it is *my* fault that this patch submission is a bit funny
with two 1/4 and one 1/6 patches... *I* suggested to not send a 14-strong
patch series but split it into three, and then I failed to explain the
correct invocation to do that from the command-line.

My sincere apologies,
Dscho


Re: [PATCH] rebase -i: Fix white space in comments

2018-06-26 Thread dana
On 26 Jun 2018, at 16:44, Johannes Schindelin  
wrote:
>There is of course one other way to fix this, and that is by rewriting
>this in C.
>
>Which Alban has done here ;-)
>
>http://public-inbox.org/git/20180626161643.31152-3-alban.gr...@gmail.com

Oh, i'm sorry, i didn't see that. That change does appear to solve the
same problem, so i'm happy to defer to it.

Thanks for looking!

dana



Re: [GSoC][PATCH 1/1] sequencer: print an error message if append_todo_help() fails

2018-06-26 Thread Johannes Schindelin
Hi Junio,

On Tue, 26 Jun 2018, Junio C Hamano wrote:

> Johannes Schindelin  writes:
> 
> > On Tue, 26 Jun 2018, Alban Gruin wrote:
> >
> >> This adds an error when append_todo_help() fails to write its message to
> >> the todo file.
> >> 
> >> Signed-off-by: Alban Gruin 
> >
> > ACK.
> >
> > We *may* want to fold that into the commit that adds `append_todo_help()`.
> 
> Absolutely.  This looks more like an "oops, I made a mess and here
> is a fix on top", and even worse, it does not make an effort to help
> readers where the mess was made (iow, which commit it goes on to
> of); it is better to be squashed in.
> 
> I do not know offhand who Alban's mentors are, but one thing I think
> is a good thing for them to teach is how to better organize the
> changes with readers in mind.  The author of a patch series knows
> his or her patches and how they relate to each other a lot better
> than the readers of patches, who are reading not just his or her
> patches but the ones from a lot wider set of contributors.  Even
> though append-todo-help and edit-todo may have been developed as
> separate steps in author's mind, it is criminal to send them as if
> they are completely separate topics that can independently applied,
> especially when one depends on the other.  It is a lot more helpful
> to the readers if they were sent as a larger single series, because
> doing so _will_ tell the readers which order the dependency goes.

Chris & Stefan are Alban's mentors, and I spend quite a bit of my time on
IRC, ready to help Alban when he has questions. Chris & Stephan mainly act
as first-line reviewers.

> > And, as I mentioned previously, I would love for that function to be
> > used as an excuse to introduce the long-overdue `interactive-rebase.c`
> 
> I am not sure if I like this direction.

Blame me, not Alban. I am pretty familiar with sequencer.c, and I know
that it is way too large.

> As newbies are often very bad at coming up with APIs and naming global
> functions, keeping everything as "static" inside a single sequencer.c
> tends to avoid contaminating the global namespace.

Then I just need to make sure to suggest good names that are safe for the
global namespace, don't I?

Seeing as sequencer.c is so long already, it is own little mega namespace
anyway, so we already have to be very careful *within* sequencer.c.

Ciao,
Dscho


[PATCH v3] Documentation: declare "core.ignorecase" as internal variable

2018-06-26 Thread Marc Strapetz

The current description of "core.ignoreCase" reads like an option which
is intended to be changed by the user while it's actually expected to
be set by Git on initialization only. Subsequently, Git relies on the
proper configuration of this variable, as noted by Bryan Turner [1]:

Git on a case-insensitive filesystem (APFS, HFS+, FAT32, exFAT,
vFAT, NTFS, etc.) is not designed to be run with anything other
than core.ignoreCase=true.

[1] https://marc.info/?l=git&m=152998665813997&w=2
mid:cagyf7-gee8jrgpkme9rhkptheq6p1+ebpmmwatmh01uo3bf...@mail.gmail.com

Signed-off-by: Marc Strapetz 
---
 Documentation/config.txt | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 1cc18a828..c70cfe956 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -390,16 +390,19 @@ core.hideDotFiles::
default mode is 'dotGitOnly'.

 core.ignoreCase::
-   If true, this option enables various workarounds to enable
+   Internal variable which enables various workarounds to enable
Git to work better on filesystems that are not case sensitive,
-   like FAT. For example, if a directory listing finds
-   "makefile" when Git expects "Makefile", Git will assume
+   like APFS, HFS+, FAT, NTFS, etc. For example, if a directory listing
+   finds "makefile" when Git expects "Makefile", Git will assume
it is really the same file, and continue to remember it as
"Makefile".
 +
 The default is false, except linkgit:git-clone[1] or linkgit:git-init[1]
 will probe and set core.ignoreCase true if appropriate when the repository
 is created.
++
+Git relies on the proper configuration of this variable for your operating
+and file system. Modifying this value may result in unexpected behavior.

 core.precomposeUnicode::
This option is only used by Mac OS implementation of Git.
--
2.17.0.rc0.3.gb1b5a51b2



Re: [GSoC][PATCH v3 2/2] rebase-interactive: rewrite the edit-todo functionality in C

2018-06-26 Thread Johannes Schindelin
Hi Alban,

On Tue, 26 Jun 2018, Alban Gruin wrote:

> This rewrites the edit-todo functionality from shell to C.
> 
> To achieve that, a new command mode, `edit-todo`, is added, and the
> `write-edit-todo` flag is removed, as the shell script does not need to
> write the edit todo help message to the todo list anymore.
> 
> The shell version is then stripped in favour of a call to the helper.
> 
> Signed-off-by: Alban Gruin 

Both patches are ACKed by me,
Dscho


Re: [GSoC][PATCH v3 0/2] rebase -i: rewrite the edit-todo functionality in C

2018-06-26 Thread Johannes Schindelin
Hi Alban,

On Tue, 26 Jun 2018, Alban Gruin wrote:

> This patch rewrites the edit-todo functionality from shell to C. This is
> part of the effort to rewrite interactive rebase in C.
> 
> This patch is based on the fourth iteration of my series rewriting
> append_todo_help() in C.
> 
> Changes since v2:
> 
>  - Moving edit_todo() from sequencer.c to interactive-rebase.c.

Excellent.

Thank you,
Dscho


Re: [PATCH] rebase -i: Fix white space in comments

2018-06-26 Thread Johannes Schindelin
Hi, me again,

On Tue, 26 Jun 2018, Johannes Schindelin wrote:

> On Tue, 26 Jun 2018, Johannes Schindelin wrote:
> 
> > On Tue, 26 Jun 2018, dana wrote:
> > 
> > > diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> > > index 299ded213..a31af6d4c 100644
> > > --- a/git-rebase--interactive.sh
> > > +++ b/git-rebase--interactive.sh
> > > @@ -222,9 +222,9 @@ $comment_char $(eval_ngettext \
> > >  EOF
> > >   append_todo_help
> > >   gettext "
> > > - However, if you remove everything, the rebase will be aborted.
> > > +However, if you remove everything, the rebase will be aborted.
> > >  
> > > - " | git stripspace --comment-lines >>"$todo"
> > > +" | git stripspace --comment-lines >>"$todo"
> > >  
> > >   if test -z "$keep_empty"
> > >   then
> 
> This does the job, and I am fine with this way of doing things, and there
> seems to be a lot of precedent doing it this way e.g. in git-bisect.sh.

There is of course one other way to fix this, and that is by rewriting
this in C.

Which Alban has done here ;-)

http://public-inbox.org/git/20180626161643.31152-3-alban.gr...@gmail.com

Ciao,
Johannes


Re: [GSoC][PATCH v4 2/2] rebase--interactive: rewrite append_todo_help() in C

2018-06-26 Thread Johannes Schindelin
Hi Alban,

On Tue, 26 Jun 2018, Alban Gruin wrote:

> This rewrites append_todo_help() from shell to C. It also incorporates
> some parts of initiate_action() and complete_action() that also write
> help texts to the todo file.
> 
> This also introduces the source file rebase-interactive.c. This file
> will contain functions necessary for interactive rebase that are too
> specific for the sequencer, and is part of libgit.a.
> 
> Two flags are added to rebase--helper.c: one to call
> append_todo_help() (`--append-todo-help`), and another one to tell
> append_todo_help() to write the help text suited for the edit-todo
> mode (`--write-edit-todo`).
> 
> Finally, append_todo_help() is removed from git-rebase--interactive.sh
> to use `rebase--helper --append-todo-help` instead.

Looks good!

Thanks,
Dscho


Re: [PATCH v5 7/8] fetch-pack: put shallow info in output parameter

2018-06-26 Thread Junio C Hamano
Brandon Williams  writes:

> Expand the transport fetch method signature, by adding an output
> parameter, to allow transports to return information about the refs they
> have fetched.  Then communicate shallow status information through this
> mechanism instead of by modifying the input list of refs.

Makes sense.  Would this mechanism also allow us to be more explicit
about the "tag following"?



Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 5:33 PM Elijah Newren  wrote:
> On Tue, Jun 26, 2018 at 1:22 PM, Jeff King  wrote:
> > Another option is to not enable this slightly-more-dangerous linting by
> > default. But that would probably rob it of its usefulness, since it
> > would just fall to some brave soul to later crank up the linting and fix
> > everybody else's mistakes.
>
> This may be a dumb question, but why can't we run under errexit?  If
> we could do that, we wouldn't need the &&-chaining, and bash would
> parse the shell for us and exit whenever one command failed.  (Is the
> reason for this documented somewhere?  I couldn't find it...)

I'm not sure if it's documented anywhere, but it has been discussed.
In particular, see [1], especially [2], and [3]. Peff summed up by
saying:

So I dunno. I think "set -e" is kind of a dangerous lure. It works
so well _most_ of the time that you start to rely on it, but it
really does have some funny corner cases (even on modern shells,
and for all I know, the behavior above is mandated by POSIX).

[1]: https://public-inbox.org/git/xmqq384zha6s@gitster.dls.corp.google.com/
[2]: https://public-inbox.org/git/20150320172406.ga15...@peff.net/
[3]: https://public-inbox.org/git/xmqqoannfu84@gitster.dls.corp.google.com/


Re: [GSoC][PATCH v4 1/2] sequencer: make two functions and an enum from sequencer.c public

2018-06-26 Thread Johannes Schindelin
Hi Alban,

On Tue, 26 Jun 2018, Alban Gruin wrote:

> diff --git a/sequencer.h b/sequencer.h
> index c5787c6b5..08397b0d1 100644
> --- a/sequencer.h
> +++ b/sequencer.h
> @@ -3,6 +3,7 @@
>  
>  const char *git_path_commit_editmsg(void);
>  const char *git_path_seq_dir(void);
> +const char *rebase_path_todo(void);
>  
>  #define APPEND_SIGNOFF_DEDUP (1u << 0)
>  
> @@ -57,6 +58,10 @@ struct replay_opts {
>  };
>  #define REPLAY_OPTS_INIT { .action = -1, .current_fixups = STRBUF_INIT }
>  
> +enum check_level {
> + CHECK_IGNORE = 0, CHECK_WARN, CHECK_ERROR
> +};
> +

While this is contained within scopes that include `sequencer.h`, it *is*
public now, so I am slightly uneasy about keeping this enum so generic.
Maybe we want to use

enum missing_commit_check_level {
MISSING_COMMIT_CHECK_IGNORE = 0,
MISSING_COMMIT_CHECK_WARN,
MISSING_COMMIT_CHECK_ERROR
};

instead?

Ciao,
Dscho


Re: [PATCH v5 6/8] fetch: refactor to make function args narrower

2018-06-26 Thread Junio C Hamano
Brandon Williams  writes:

> Refactor find_non_local_tags and get_ref_map to only take the
> information they need instead of the entire transport struct. Besides
> improving code clarity, this also improves their flexibility, allowing
> for a different set of refs to be used instead of relying on the ones
> stored in the transport struct.

Makes sense.  One can argue that the original has less risk of set
of refs used for calls to this function vs calls for others go out
of sync, but the objective of this series is to allow them to be
different ;-)

I am not sure if I understand/agree with the split of parameters
done to get_ref_map() at this step, but hopefully its benefit would
become obvious once I read later steps.



Re: [GSoC][PATCH v4 0/2] rebase -i: rewrite append_todo_help() in C

2018-06-26 Thread Johannes Schindelin
Hi Alban,

On Tue, 26 Jun 2018, Alban Gruin wrote:

> This patch rewrites append_todo_help() from shell to C. The C version
> covers a bit more than the old shell version. To achieve that, some
> parameters were added to rebase--helper.
> 
> This also introduce a new source file, rebase-interactive.c.
> 
> This is part of the effort to rewrite interactive rebase in C.
> 
> This is based on next, as of 2018-06-26.

Out of curiosity: which commits that are not yet in `master` are required?

> Changes since v3:
> 
>  - Show an error message when append_todo_help() fails to edit the todo
>list.
> 
>  - Introducing rebase-interactive.c to contain functions necessary for
>interactive rebase.

Thank you very much!
Dscho


Re: [PATCH] rebase -i: Fix white space in comments

2018-06-26 Thread Johannes Schindelin
Hi,

and now for the review...

On Tue, 26 Jun 2018, Johannes Schindelin wrote:

> On Tue, 26 Jun 2018, dana wrote:
> 
> > diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> > index 299ded213..a31af6d4c 100644
> > --- a/git-rebase--interactive.sh
> > +++ b/git-rebase--interactive.sh
> > @@ -222,9 +222,9 @@ $comment_char $(eval_ngettext \
> >  EOF
> > append_todo_help
> > gettext "
> > -   However, if you remove everything, the rebase will be aborted.
> > +However, if you remove everything, the rebase will be aborted.
> >  
> > -   " | git stripspace --comment-lines >>"$todo"
> > +" | git stripspace --comment-lines >>"$todo"
> >  
> > if test -z "$keep_empty"
> > then

This does the job, and I am fine with this way of doing things, and there
seems to be a lot of precedent doing it this way e.g. in git-bisect.sh.

If my ACK is welcome, you hereby have it.

Ciao,
Johannes


Re: [PATCH v5 3/8] upload-pack: test negotiation with changing repository

2018-06-26 Thread Junio C Hamano
Brandon Williams  writes:

> diff --git a/t/lib-httpd/one-time-sed.sh b/t/lib-httpd/one-time-sed.sh
> new file mode 100644
> index 0..8a9a5aca0
> --- /dev/null
> +++ b/t/lib-httpd/one-time-sed.sh
> @@ -0,0 +1,22 @@
> +#!/bin/sh
> +
> +# If "one-time-sed" exists in $HTTPD_ROOT_PATH, run sed on the HTTP response,
> +# using the contents of "one-time-sed" as the sed command to be run. If the
> +# response was modified as a result, delete "one-time-sed" so that subsequent
> +# HTTP responses are no longer modified.

;-) clever.

> +# 
> +# This can be used to simulate the effects of the repository changing in
> +# between HTTP request-response pairs.
> +if [ -e one-time-sed ]; then "$GIT_EXEC_PATH/git-http-backend" >out

Style (cf. Documentation/CodingGuidelines).

> +
> + sed "$(cat one-time-sed)" out_modified
> +
> + if diff out out_modified >/dev/null; then
> + cat out
> + else
> + cat out_modified
> + rm one-time-sed
> + fi
> +else
> + "$GIT_EXEC_PATH/git-http-backend"
> +fi

OK.  I was worried if the removal-after-use was about _this_ script
(in which case it is a bad hygiene), but this is not a one-time
script, but merely the mechanism to use the one-time sed script.

Perhaps rename this to t/lib-httpd/apply-one-time-sed.sh or something
to avoid confusion?

> diff --git a/t/t5703-upload-pack-ref-in-want.sh 
> b/t/t5703-upload-pack-ref-in-want.sh
> index 0ef182970..a4fe0e7e4 100755
> --- a/t/t5703-upload-pack-ref-in-want.sh
> +++ b/t/t5703-upload-pack-ref-in-want.sh
> @@ -150,4 +150,72 @@ test_expect_success 'want-ref with ref we already have 
> commit for' '
>   check_output
>  '
>  
> +. "$TEST_DIRECTORY"/lib-httpd.sh
> +start_httpd
> +
> +REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
> +LOCAL_PRISTINE="$(pwd)/local_pristine"
> +
> +test_expect_success 'setup repos for change-while-negotiating test' '
> + (
> + git init "$REPO" &&
> + cd "$REPO" &&
> + >.git/git-daemon-export-ok &&
> + test_commit m1 &&
> + git tag -d m1 &&
> +
> + # Local repo with many commits (so that negotiation will take
> + # more than 1 request/response pair)
> + git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo"; 
> "$LOCAL_PRISTINE" &&
> + cd "$LOCAL_PRISTINE" &&
> + git checkout -b side &&
> + for i in $(seq 1 33); do test_commit s$i; done &&
> +
> + # Add novel commits to upstream
> + git checkout master &&
> + cd "$REPO" &&
> + test_commit m2 &&
> + test_commit m3 &&
> + git tag -d m2 m3
> + ) &&
> + git -C "$LOCAL_PRISTINE" remote set-url origin 
> "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo"; &&
> + git -C "$LOCAL_PRISTINE" config protocol.version 2
> +'
> +
> +inconsistency() {

Style. "inconsistency () {"

> + # Simulate that the server initially reports $2 as the ref
> + # corresponding to $1, and after that, $1 as the ref corresponding to
> + # $1. This corresponds to the real-life situation where the server's
> + # repository appears to change during negotiation, for example, when
> + # different servers in a load-balancing arrangement serve (stateless)
> + # RPCs during a single negotiation.
> + printf "s/%s/%s/" \
> +$(git -C "$REPO" rev-parse $1 | tr -d "\n") \
> +$(git -C "$REPO" rev-parse $2 | tr -d "\n") \
> +>"$HTTPD_ROOT_PATH/one-time-sed"
> +}
> +
> +test_expect_success 'server is initially ahead - no ref in want' '
> + git -C "$REPO" config uploadpack.allowRefInWant false &&
> + rm -rf local &&
> + cp -r "$LOCAL_PRISTINE" local &&
> + inconsistency master 1234567890123456789012345678901234567890 &&
> + test_must_fail git -C local fetch 2>err &&
> + grep "ERR upload-pack: not our ref" err
> +'
> +
> +test_expect_success 'server is initially behind - no ref in want' '
> + git -C "$REPO" config uploadpack.allowRefInWant false &&
> + rm -rf local &&
> + cp -r "$LOCAL_PRISTINE" local &&
> + inconsistency master "master^" &&
> + git -C local fetch &&
> +
> + git -C "$REPO" rev-parse --verify "master^" >expected &&
> + git -C local rev-parse --verify refs/remotes/origin/master >actual &&
> + test_cmp expected actual
> +'
> +
> +stop_httpd
> +
>  test_done


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Elijah Newren
On Tue, Jun 26, 2018 at 1:22 PM, Jeff King  wrote:
> On Tue, Jun 26, 2018 at 04:17:08PM -0400, Jeff King wrote:
>
>> I'm not sure if there's a good solution, though. Even if you retained
>> the subshells and instead did a chain-lint inside each subshell, like
>> this:
>
> So obviously that means "I don't think there's a good solution with this
> approach".
>
> That whole final patch simultaneously impresses and nauseates me. Your
> commit message says "no attempt is made at properly parsing shell code",
> but we come pretty darn close. I almost wonder if we'd be better off
> just parsing some heuristic subset and making sure (via review or
> linting) that our tests conform.
>
> Another option is to not enable this slightly-more-dangerous linting by
> default. But that would probably rob it of its usefulness, since it
> would just fall to some brave soul to later crank up the linting and fix
> everybody else's mistakes.

This may be a dumb question, but why can't we run under errexit?  If
we could do that, we wouldn't need the &&-chaining, and bash would
parse the shell for us and exit whenever one command failed.  (Is the
reason for this documented somewhere?  I couldn't find it...)


Re: [PATCH] rebase -i: Fix white space in comments

2018-06-26 Thread Johannes Schindelin
Let's Cc: Wink, who authored the commit mentioned as culprit in the commit
message.


On Tue, 26 Jun 2018, dana wrote:

> Fix a trivial white-space issue introduced by commit d48f97aa8
> ("rebase: reindent function git_rebase__interactive", 2018-03-23). This
> affected the instructional comments displayed in the editor during an
> interactive rebase.
> 
> Signed-off-by: dana 
> ---
> 
> Sorry if i've done any of this wrong; i've never used this work-flow
> before. In any case, if it's not immediately obvious, this is the issue
> i mean to fix:
> 
> BEFORE (2.17.1):
> 
> # If you remove a line here THAT COMMIT WILL BE LOST.
> #
> # However, if you remove everything, the rebase will be aborted.
> #
> # Note that empty commits are commented out
> 
> AFTER (2.18.0):
> 
> # If you remove a line here THAT COMMIT WILL BE LOST.
> #
> # However, if you remove everything, the rebase will be aborted.
> #
> # 
> # Note that empty commits are commented out
> 
> The 2.18.0 version is particularly irritating because many editors
> highlight the trailing tab in the penultimate line as a white-space
> error.
> 
> Aside: It's not a new thing, but i've always felt like that last line
> should end in a full stop. Maybe i'll send a patch for that too.
> 
> Cheers,
> dana
> 
>  git-rebase--interactive.sh | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> index 299ded213..a31af6d4c 100644
> --- a/git-rebase--interactive.sh
> +++ b/git-rebase--interactive.sh
> @@ -222,9 +222,9 @@ $comment_char $(eval_ngettext \
>  EOF
>   append_todo_help
>   gettext "
> - However, if you remove everything, the rebase will be aborted.
> +However, if you remove everything, the rebase will be aborted.
>  
> - " | git stripspace --comment-lines >>"$todo"
> +" | git stripspace --comment-lines >>"$todo"
>  
>   if test -z "$keep_empty"
>   then
> -- 
> 2.18.0
> 
> 


Re: [PATCH v5 2/8] upload-pack: implement ref-in-want

2018-06-26 Thread Junio C Hamano
Brandon Williams  writes:

> +wanted-refs section
> + * This section is only included if the client has requested a
> +   ref using a 'want-ref' line and if a packfile section is also
> +   included in the response.
> +
> + * Always begins with the section header "wanted-refs".
> +
> + * The server will send a ref listing (" ") for
> +   each reference requested using 'want-ref' lines.
> +
> + * The server SHOULD NOT send any refs which were not requested
> +   using 'want-ref' lines and a client MUST ignore refs which
> +   weren't requested.

Just being curious, but the above feels the other way around.  Why
are we being more lenient to writers of broken server than writers
of broken clients?  The number of installations they need to take
back and replace is certainly lower for the former, which means
that, if exchanges of unsoliclited refs are unwanted, clients should
notice and barf (or warn) if the server misbehaves, and the server
should be forbidden from sending unsolicited refs, no?


> diff --git a/t/t5703-upload-pack-ref-in-want.sh 
> b/t/t5703-upload-pack-ref-in-want.sh
> new file mode 100755
> index 0..0ef182970
> --- /dev/null
> +++ b/t/t5703-upload-pack-ref-in-want.sh
> @@ -0,0 +1,153 @@
> +#!/bin/sh
> +
> +test_description='upload-pack ref-in-want'
> +
> +. ./test-lib.sh
> +
> +get_actual_refs() {

Style.  "get_actual_refs () {"

> + sed -n '/wanted-refs/,/0001/p'  unpack >actual_refs

Unnecessary piping of sed output into another sed invocation?

sed -n -e '/wanted-refs/,/0001/{
/wanted-refs/d
/0001/d
p
}'

or something like that?


Re: [PATCH 00/29] t: detect and fix broken &&-chains in subshells

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 3:38 PM Junio C Hamano  wrote:
> I first looked at 29/29 and got heavily inclined to reject that
> step, and then continued reading from 1/29 to around 15/29.
>
> I like these earlier changes that fix existing breakage, of course.
> I also like many of the changes that simplify and/or modernise the
> test scripts very much, but they are unusable as-is as long as their
> justification is "chain-lint will start barfing on these constructs".

Sorry, I'm having difficulty understanding.

Are you saying that you don't want patches which exist merely to
pacify --chain-lint? (For instance, 2/29 "t0001: use "{...}" block
around "||" expression rather than subshell".)

Or are you saying that you don't like how the commit messages are
worded, and that they should instead emphasize that the change is good
for its own sake, without mentioning --chain-lint?


Re: [RFC PATCH v5] Implement --first-parent for git rev-list --bisect

2018-06-26 Thread Johannes Schindelin
Hi Chris,

On Tue, 26 Jun 2018, Christian Couder wrote:

> On Tue, Jun 26, 2018 at 4:10 PM, Johannes Schindelin
>  wrote:
> >
> > The point, for me, is: if this test fails, at some stage in the
> > future, for any reason, it will be a major pain to even dissect what
> > the test is supposed to do.
> 
> I think the test is quite simple and there is an ascii picture, so it is
> not so difficult to understand.

So I tell you that I find it hard to understand and you try to refute this
review by... saying that it is quite simple to understand?

That's not really a basis for discussion there, if you do not even
acknowledge that both Junio and I pointed out a serious flaw in the patch.
I have no idea how you think we can reach consensus if you just deny that
there is a problem *when I just demonstrated that there is a
problem*?!?!?!

> I know that we should try to do better, but here I am mostly
> interested in moving forward a feature that people have requested for
> ages, not cleaning up those tests. If someone else like you or Junio
> thinks that it would be a good time to clean things up a bit, then I
> am ok with it, but that's not my main goal here.

This test is not good. It is not good because if even a long-time
contributor such as myself finds it too hard to understand.

So you cannot just force it forward.

> > - the graph is definitely written in an unnecessarily different format
> > than in the same test script!!!
> 
> Just above you complain about things that are similar to the previous
> tests and now you complain about things that are different...

You misunderstood. I complained that things are *not* similar to previous
tests. I said the exact opposite of what you understood.

> > - speaking of the graph: there is a perfectly fine commit graph already.
> >   Why on earth is it not reused?
> 
> Perhaps because it is more complex than needed to test this feature
> and/or to understand what happens.

What? Have you even *bothered* to look at the graphs?

If at all, the newly introduced is *less* complex (except for the
pointlessly confusing commit names). Both graphs have a branch point, a
tip commit, and a first-parent and a second-parent lineage.

So the new test introduces new commits for no good reason whatsoever, with
a diagram that is unnecessarily different from the one that is already in
the file (horizontal layout instead of vertical, and the horizontal layout
disagrees even with the existing other tests' horizontal graph diagram).

> > In this particular case it even feels as if this test is not even testing
> > what it should test at all:
> >
> > - it should verify that all of the commits in the first parent lineage are
> >   part of the list
> 
> It does that.

Yes, it does that, and you can verify that it does by, uhm, spending 10
minutes pouring over the diagram.

In my proposed test case, you see the same after reading the simple loop
and from the comment and the line count test, i.e. after spending 10
seconds.

So your "It does that" is a bit inappropriate. Of course your test does
that. In a very convoluted way. And I demonstrated that it does not have
to be convoluted at all.

> > - it should verify that none of the other commits are in the list
> 
> It does that too.

Same here. You miss the point. It is obvious in my proposed test case that
it does that. In your proposed test case it is everything but obvious.

> > And that is really all there is to test.
> 
> I don't agree. I think that when possible, especially when testing
> plumbing commands like rev-list, it is a good thing to test as many
> things as possible at once.

Then you do not understand the main purpose of regression tests, which is
to not only catch, but also to fix regressions. And your test code seems
to be designed to make the latter very, very hard. Just like your response
to my review almost appears to be designed to be defiant rather than
constructive.

If you want to accept my help in making your code better, we can continue.
Otherwise I am afraid that your patch is stuck in the "not good enough"
pile.

> > You can even write that in a much
> > easier way:
> >
> > -- snip --
> > test_expect_success '--first-parent --bisect-all lists correct revs' '
> > git rev-list --first-parent --bisect-all F..E >revs &&
> > # E and e1..e8 need to be shown, F and f1..f4 not
> > test_line_count = 9 revs &&
> > for rev in E e1 e2 e3 e4 e5 e6 e7 e8
> > do
> > grep "^$(git rev-parse $rev) " revs || {
> > echo "$rev not shown" >&2 &&
> > return 1
> > }
> > done
> > '
> > -- snap --
> >
> > To test more precisely for the order or the distance would be both
> > overkill and likely to be unreadable.
> 
> I don't think the previous version was either overkill or unreadable.

Okay, this is too tedious. Seriously, why do you make it so unpleasant to
help you improve the patch.

> Yeah it had other (potenti

Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 5:01 PM Jeff King  wrote:
> On Tue, Jun 26, 2018 at 04:46:18PM -0400, Eric Sunshine wrote:
> > Some of these dangers can be de-thoothed during the linting phase by
> > defining do-nothing shell functions:
> >
> > cp () { :; }
> > mv () { :; }
> > ln () { :; }
> >
> > That, at least, makes the scariest case ("rm") much less so.
>
> Now that's an interesting idea. We can't catch every dangerous action
> (notably ">" would be hard to override), but it should be pretty cheap
> to cover some obvious ones.

Taking the idea a bit further, the 'sed' script could also throw away
strings of "../" inside subshells, which would help defang the more
difficult cases, like "echo x >../git.c". There are pathological
cases, of course, which it wouldn't catch:

P=../git.c
test_expect_success 'foo' '
(
cd dir &&
echo x >$P
)
'

but it does help mitigate the issue for the most typical cases.


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Junio C Hamano
Jeff King  writes:

> One way this series might be worse in practice is that we tend not to
> change process state too much outside of the subshells.
> ...
> Whereas once you start collapsing subshells into the main logic chain,
> there's a very high chance that the subshell is doing a "cd", since
> that's typically the main reason for the subshell in the first place.

Exactly.  I should have mentioned this when I responded to save a
round-trip.



Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Jeff King
On Tue, Jun 26, 2018 at 04:46:18PM -0400, Eric Sunshine wrote:

> > I'm not sure if there's a good solution, though. Even if you retained
> > the subshells and instead did a chain-lint inside each subshell, like
> > this:
> >
> >   (exit 117) &&
> >   one &&
> >   (
> > (exit 117) &&
> > cd foo
> > two
> >   ) &&
> >   three
> 
> I thought of that too, but the inner (exit 117) doesn't even get
> invoked unless there is &&-chain breakage somewhere above that point
> (for instance, if "one" lacks "&&"), so the inner (exit 117) doesn't
> participate in the linting process at all.

Oh, right. Not only does it not fix the problem, it's totally
unworkable. :)

> Some of these dangers can be de-thoothed during the linting phase by
> defining do-nothing shell functions:
> 
> cp () { :; }
> mv () { :; }
> ln () { :; }
> 
> That, at least, makes the scariest case ("rm") much less so.

Now that's an interesting idea. We can't catch every dangerous action
(notably ">" would be hard to override), but it should be pretty cheap
to cover some obvious ones.

-Peff


Re: [PATCH 17/29] t: use test_must_fail() instead of checking exit code manually

2018-06-26 Thread Johannes Sixt

Am 26.06.2018 um 20:14 schrieb Eric Sunshine:

On Tue, Jun 26, 2018 at 2:06 PM Johannes Sixt  wrote:

Hence, these lines should actually be

 p4 help client &&
 ! p4 help nosuchcommand


Thanks for the comment; you're right, of course. I'll certainly make
this change if I have to re-roll for some other reason, but do you
feel that this itself is worth a re-roll?


Not worth a re-roll IMO.

-- Hannes


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 4:22 PM Jeff King  wrote:
> So obviously that means "I don't think there's a good solution with this
> approach".
>
> That whole final patch simultaneously impresses and nauseates me. Your
> commit message says "no attempt is made at properly parsing shell code",
> but we come pretty darn close. I almost wonder if we'd be better off
> just parsing some heuristic subset and making sure (via review or
> linting) that our tests conform.

I'm not sure I agree with "come pretty darn close", but your idea is
an interesting one. It would sidestep the concern with "rm -fr" and
friends (though it will probably still nauseate you). Let me cogitate
about it a bit...

> Another option is to not enable this slightly-more-dangerous linting by
> default. But that would probably rob it of its usefulness, since it
> would just fall to some brave soul to later crank up the linting and fix
> everybody else's mistakes.

I considered that, as well, and came to the same conclusion.


Re: [PATCH v2 5/6] submodule-config: pass repository as argument to config_from_gitmodules

2018-06-26 Thread Antonio Ospite
On Tue, 26 Jun 2018 13:15:33 -0700
Junio C Hamano  wrote:

> Antonio Ospite  writes:
> 
> > Generlize config_from_gitmodules to accept a repository as an argument.
> 
> generalize???
> 

Of course I was going to miss a typo in the first word of the commit
message :|

If this is the only change, I'd ask you to amend it when applying the
patch, if it's not too much trouble.

If instead I have to add also the comments about the new public
functions in submodule-config.c, as you asked for patch 2/6, I can send
a v3 and fix the typo there.

Thanks,
   Antonio

-- 
Antonio Ospite
https://ao2.it
https://twitter.com/ao2it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?


[PATCH v5 0/8] ref-in-want

2018-06-26 Thread Brandon Williams
Changes in v5:
* Added a comment explaining the one-time-sed.sh script
* Added a number of tests per reviewer feedback
* Fixed a typo in documentation

Brandon Williams (8):
  test-pkt-line: add unpack-sideband subcommand
  upload-pack: implement ref-in-want
  upload-pack: test negotiation with changing repository
  fetch: refactor the population of peer ref OIDs
  fetch: refactor fetch_refs into two functions
  fetch: refactor to make function args narrower
  fetch-pack: put shallow info in output parameter
  fetch-pack: implement ref-in-want

 Documentation/config.txt|   7 +
 Documentation/technical/protocol-v2.txt |  29 +-
 builtin/clone.c |   4 +-
 builtin/fetch.c | 135 +
 fetch-object.c  |   2 +-
 fetch-pack.c|  50 +++-
 remote.c|   1 +
 remote.h|   1 +
 t/helper/test-pkt-line.c|  33 +++
 t/lib-httpd.sh  |   1 +
 t/lib-httpd/apache.conf |   8 +
 t/lib-httpd/one-time-sed.sh |  22 ++
 t/t5703-upload-pack-ref-in-want.sh  | 351 
 transport-helper.c  |   6 +-
 transport-internal.h|   9 +-
 transport.c |  34 ++-
 transport.h |   3 +-
 upload-pack.c   |  66 +
 18 files changed, 687 insertions(+), 75 deletions(-)
 create mode 100644 t/lib-httpd/one-time-sed.sh
 create mode 100755 t/t5703-upload-pack-ref-in-want.sh

-- 
2.18.0.rc2.346.g013aa6912e-goog



Re: [PATCH v2 2/6] submodule-config: add helper function to get 'fetch' config from .gitmodules

2018-06-26 Thread Antonio Ospite
On Tue, 26 Jun 2018 13:11:40 -0700
Junio C Hamano  wrote:

> Antonio Ospite  writes:
> 
> > Add a helper function to make it clearer that retrieving 'fetch'
> > configuration from the .gitmodules file is a special case supported
> > solely for backward compatibility purposes.
> > ...
> 
> Then perhaps the new public function deserves a comment stating
> that?
>

Hi Junio,

a comment about that is added to submodule-config.h in patch 4/6 in
place of the comment about config_from_gitmodules.

I can add a note here as well if that one is not enough.

[...]
> > +void fetch_config_from_gitmodules(int *max_children, int 
> > *recurse_submodules)
> > +{
> > +   struct fetch_config config = {
> > +   .max_children = max_children,
> > +   .recurse_submodules = recurse_submodules
> > +   };
> 
> We started using designated initializers some time ago, and use of
> it improves readability of something like this ;-)
>

Ah, TBH I didn't even consider whether it was allowed in git code, I
just used the construct out of habit.

Ciao,
   Antonio

-- 
Antonio Ospite
https://ao2.it
https://twitter.com/ao2it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?


[PATCH v5 7/8] fetch-pack: put shallow info in output parameter

2018-06-26 Thread Brandon Williams
Expand the transport fetch method signature, by adding an output
parameter, to allow transports to return information about the refs they
have fetched.  Then communicate shallow status information through this
mechanism instead of by modifying the input list of refs.

This does require clients to sometimes generate the ref map twice: once
from the list of refs provided by the remote (as is currently done) and
potentially once from the new list of refs that the fetch mechanism
provides.

Signed-off-by: Brandon Williams 
---
 builtin/clone.c  |  4 ++--
 builtin/fetch.c  | 28 
 fetch-object.c   |  2 +-
 fetch-pack.c | 15 ---
 transport-helper.c   |  6 --
 transport-internal.h |  9 -
 transport.c  | 34 --
 transport.h  |  3 ++-
 8 files changed, 77 insertions(+), 24 deletions(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index 99e73dae8..8f86d99c5 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1155,7 +1155,7 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
}
 
if (!is_local && !complete_refs_before_fetch)
-   transport_fetch_refs(transport, mapped_refs);
+   transport_fetch_refs(transport, mapped_refs, NULL);
 
remote_head = find_ref_by_name(refs, "HEAD");
remote_head_points_at =
@@ -1197,7 +1197,7 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
if (is_local)
clone_local(path, git_dir);
else if (refs && complete_refs_before_fetch)
-   transport_fetch_refs(transport, mapped_refs);
+   transport_fetch_refs(transport, mapped_refs, NULL);
 
update_remote_refs(refs, mapped_refs, remote_head_points_at,
   branch_top.buf, reflog_msg.buf, transport,
diff --git a/builtin/fetch.c b/builtin/fetch.c
index bda00e826..0347cf016 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -946,11 +946,13 @@ static int quickfetch(struct ref *ref_map)
return check_connected(iterate_ref_map, &rm, &opt);
 }
 
-static int fetch_refs(struct transport *transport, struct ref *ref_map)
+static int fetch_refs(struct transport *transport, struct ref *ref_map,
+ struct ref **updated_remote_refs)
 {
int ret = quickfetch(ref_map);
if (ret)
-   ret = transport_fetch_refs(transport, ref_map);
+   ret = transport_fetch_refs(transport, ref_map,
+  updated_remote_refs);
if (!ret)
/*
 * Keep the new pack's ".keep" file around to allow the caller
@@ -1112,7 +1114,7 @@ static void backfill_tags(struct transport *transport, 
struct ref *ref_map)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, NULL);
transport_set_option(transport, TRANS_OPT_DEPTH, "0");
transport_set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, NULL);
-   if (!fetch_refs(transport, ref_map))
+   if (!fetch_refs(transport, ref_map, NULL))
consume_refs(transport, ref_map);
 
if (gsecondary) {
@@ -1128,6 +1130,7 @@ static int do_fetch(struct transport *transport,
int autotags = (transport->remote->fetch_tags == 1);
int retcode = 0;
const struct ref *remote_refs;
+   struct ref *updated_remote_refs = NULL;
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
if (tags == TAGS_DEFAULT) {
@@ -1178,7 +1181,24 @@ static int do_fetch(struct transport *transport,
   transport->url);
}
}
-   if (fetch_refs(transport, ref_map) || consume_refs(transport, ref_map)) 
{
+
+   if (fetch_refs(transport, ref_map, &updated_remote_refs)) {
+   free_refs(ref_map);
+   retcode = 1;
+   goto cleanup;
+   }
+   if (updated_remote_refs) {
+   /*
+* Regenerate ref_map using the updated remote refs.  This is
+* to account for additional information which may be provided
+* by the transport (e.g. shallow info).
+*/
+   free_refs(ref_map);
+   ref_map = get_ref_map(transport->remote, updated_remote_refs, 
rs,
+ tags, &autotags);
+   free_refs(updated_remote_refs);
+   }
+   if (consume_refs(transport, ref_map)) {
free_refs(ref_map);
retcode = 1;
goto cleanup;
diff --git a/fetch-object.c b/fetch-object.c
index 853624f81..48fe63dd6 100644
--- a/fetch-object.c
+++ b/fetch-object.c
@@ -19,7 +19,7 @@ static void fetch_refs(const char *remote_name, struct ref 
*ref)
 
transport_set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
transport_set_option(transport, TRANS_OPT_NO_DEPENDENTS, "1");

[PATCH v5 8/8] fetch-pack: implement ref-in-want

2018-06-26 Thread Brandon Williams
Implement ref-in-want on the client side so that when a server supports
the "ref-in-want" feature, a client will send "want-ref" lines for each
reference the client wants to fetch.  This feature allows clients to
tolerate inconsistencies that exist when a remote repository's refs
change during the course of negotiation.

This allows a client to request to request a particular ref without
specifying the OID of the ref.  This means that instead of hitting an
error when a ref no longer points at the OID it did at the beginning of
negotiation, negotiation can continue and the value of that ref will be
sent at the termination of negotiation, just before a packfile is sent.

More information on the ref-in-want feature can be found in
Documentation/technical/protocol-v2.txt.

Signed-off-by: Brandon Williams 
---
 fetch-pack.c   |  35 +++-
 remote.c   |   1 +
 remote.h   |   1 +
 t/t5703-upload-pack-ref-in-want.sh | 130 +
 4 files changed, 164 insertions(+), 3 deletions(-)

diff --git a/fetch-pack.c b/fetch-pack.c
index 73890b894..3a18f5bcd 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -1102,9 +1102,10 @@ static void add_shallow_requests(struct strbuf *req_buf,
 
 static void add_wants(const struct ref *wants, struct strbuf *req_buf)
 {
+   int use_ref_in_want = server_supports_feature("fetch", "ref-in-want", 
0);
+
for ( ; wants ; wants = wants->next) {
const struct object_id *remote = &wants->old_oid;
-   const char *remote_hex;
struct object *o;
 
/*
@@ -1122,8 +1123,10 @@ static void add_wants(const struct ref *wants, struct 
strbuf *req_buf)
continue;
}
 
-   remote_hex = oid_to_hex(remote);
-   packet_buf_write(req_buf, "want %s\n", remote_hex);
+   if (!use_ref_in_want || wants->exact_oid)
+   packet_buf_write(req_buf, "want %s\n", 
oid_to_hex(remote));
+   else
+   packet_buf_write(req_buf, "want-ref %s\n", wants->name);
}
 }
 
@@ -1334,6 +1337,29 @@ static void receive_shallow_info(struct fetch_pack_args 
*args,
args->deepen = 1;
 }
 
+static void receive_wanted_refs(struct packet_reader *reader, struct ref *refs)
+{
+   process_section_header(reader, "wanted-refs", 0);
+   while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
+   struct object_id oid;
+   const char *end;
+   struct ref *r = NULL;
+
+   if (parse_oid_hex(reader->line, &oid, &end) || *end++ != ' ')
+   die("expected wanted-ref, got '%s'", reader->line);
+
+   for (r = refs; r; r = r->next) {
+   if (!strcmp(end, r->name)) {
+   oidcpy(&r->old_oid, &oid);
+   break;
+   }
+   }
+   }
+
+   if (reader->status != PACKET_READ_DELIM)
+   die("error processing wanted refs: %d", reader->status);
+}
+
 enum fetch_state {
FETCH_CHECK_LOCAL = 0,
FETCH_SEND_REQUEST,
@@ -1408,6 +1434,9 @@ static struct ref *do_fetch_pack_v2(struct 
fetch_pack_args *args,
if (process_section_header(&reader, "shallow-info", 1))
receive_shallow_info(args, &reader);
 
+   if (process_section_header(&reader, "wanted-refs", 1))
+   receive_wanted_refs(&reader, ref);
+
/* get the pack */
process_section_header(&reader, "packfile", 0);
if (get_pack(args, fd, pack_lockfile))
diff --git a/remote.c b/remote.c
index abe80c139..2c2376fff 100644
--- a/remote.c
+++ b/remote.c
@@ -1735,6 +1735,7 @@ int get_fetch_map(const struct ref *remote_refs,
if (refspec->exact_sha1) {
ref_map = alloc_ref(name);
get_oid_hex(name, &ref_map->old_oid);
+   ref_map->exact_oid = 1;
} else {
ref_map = get_remote_ref(remote_refs, name);
}
diff --git a/remote.h b/remote.h
index 45ecc6cef..976292152 100644
--- a/remote.h
+++ b/remote.h
@@ -73,6 +73,7 @@ struct ref {
force:1,
forced_update:1,
expect_old_sha1:1,
+   exact_oid:1,
deletion:1;
 
enum {
diff --git a/t/t5703-upload-pack-ref-in-want.sh 
b/t/t5703-upload-pack-ref-in-want.sh
index a4fe0e7e4..392be4959 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -204,6 +204,18 @@ test_expect_success 'server is initially ahead - no ref in 
want' '
grep "ERR upload-pack: not our ref" err
 '
 
+test_expect_success 'server is initially ahead - ref in want' '
+   git -C "$RE

[PATCH v5 6/8] fetch: refactor to make function args narrower

2018-06-26 Thread Brandon Williams
Refactor find_non_local_tags and get_ref_map to only take the
information they need instead of the entire transport struct. Besides
improving code clarity, this also improves their flexibility, allowing
for a different set of refs to be used instead of relying on the ones
stored in the transport struct.

Signed-off-by: Brandon Williams 
---
 builtin/fetch.c | 52 -
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 2fabfed0e..bda00e826 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -254,9 +254,9 @@ static int will_fetch(struct ref **head, const unsigned 
char *sha1)
return 0;
 }
 
-static void find_non_local_tags(struct transport *transport,
-   struct ref **head,
-   struct ref ***tail)
+static void find_non_local_tags(const struct ref *refs,
+   struct ref **head,
+   struct ref ***tail)
 {
struct string_list existing_refs = STRING_LIST_INIT_DUP;
struct string_list remote_refs = STRING_LIST_INIT_NODUP;
@@ -264,7 +264,7 @@ static void find_non_local_tags(struct transport *transport,
struct string_list_item *item = NULL;
 
for_each_ref(add_existing, &existing_refs);
-   for (ref = transport_get_remote_refs(transport, NULL); ref; ref = 
ref->next) {
+   for (ref = refs; ref; ref = ref->next) {
if (!starts_with(ref->name, "refs/tags/"))
continue;
 
@@ -338,7 +338,8 @@ static void find_non_local_tags(struct transport *transport,
string_list_clear(&remote_refs, 0);
 }
 
-static struct ref *get_ref_map(struct transport *transport,
+static struct ref *get_ref_map(struct remote *remote,
+  const struct ref *remote_refs,
   struct refspec *rs,
   int tags, int *autotags)
 {
@@ -346,27 +347,11 @@ static struct ref *get_ref_map(struct transport 
*transport,
struct ref *rm;
struct ref *ref_map = NULL;
struct ref **tail = &ref_map;
-   struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
/* opportunistically-updated references: */
struct ref *orefs = NULL, **oref_tail = &orefs;
 
struct string_list existing_refs = STRING_LIST_INIT_DUP;
-   const struct ref *remote_refs;
-
-   if (rs->nr)
-   refspec_ref_prefixes(rs, &ref_prefixes);
-   else if (transport->remote && transport->remote->fetch.nr)
-   refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
-
-   if (ref_prefixes.argc &&
-   (tags == TAGS_SET || (tags == TAGS_DEFAULT && !rs->nr))) {
-   argv_array_push(&ref_prefixes, "refs/tags/");
-   }
-
-   remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
-
-   argv_array_clear(&ref_prefixes);
 
if (rs->nr) {
struct refspec *fetch_refspec;
@@ -403,7 +388,7 @@ static struct ref *get_ref_map(struct transport *transport,
if (refmap.nr)
fetch_refspec = &refmap;
else
-   fetch_refspec = &transport->remote->fetch;
+   fetch_refspec = &remote->fetch;
 
for (i = 0; i < fetch_refspec->nr; i++)
get_fetch_map(ref_map, &fetch_refspec->items[i], 
&oref_tail, 1);
@@ -411,7 +396,6 @@ static struct ref *get_ref_map(struct transport *transport,
die("--refmap option is only meaningful with command-line 
refspec(s).");
} else {
/* Use the defaults */
-   struct remote *remote = transport->remote;
struct branch *branch = branch_get(NULL);
int has_merge = branch_has_merge_config(branch);
if (remote &&
@@ -450,7 +434,7 @@ static struct ref *get_ref_map(struct transport *transport,
/* also fetch all tags */
get_fetch_map(remote_refs, tag_refspec, &tail, 0);
else if (tags == TAGS_DEFAULT && *autotags)
-   find_non_local_tags(transport, &ref_map, &tail);
+   find_non_local_tags(remote_refs, &ref_map, &tail);
 
/* Now append any refs to be updated opportunistically: */
*tail = orefs;
@@ -1143,6 +1127,8 @@ static int do_fetch(struct transport *transport,
struct ref *ref_map;
int autotags = (transport->remote->fetch_tags == 1);
int retcode = 0;
+   const struct ref *remote_refs;
+   struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
if (tags == TAGS_DEFAULT) {
if (transport->remote->fetch_tags == 2)
@@ -1158,7 +1144,21 @@ static int do_fetch(struct transport *transport,
goto cleanup;
}
 
-   ref_map = get_ref_map(transport, rs, tags, &autotags);
+   if (rs->nr)
+   refspec_ref_prefixe

[PATCH v5 3/8] upload-pack: test negotiation with changing repository

2018-06-26 Thread Brandon Williams
Add tests to check the behavior of fetching from a repository which
changes between rounds of negotiation (for example, when different
servers in a load-balancing agreement participate in the same stateless
RPC negotiation). This forms a baseline of comparison to the ref-in-want
functionality (which will be introduced to the client in subsequent
commits), and ensures that subsequent commits do not change existing
behavior.

As part of this effort, a mechanism to substitute strings in a single
HTTP response is added.

Signed-off-by: Brandon Williams 
---
 t/lib-httpd.sh |  1 +
 t/lib-httpd/apache.conf|  8 
 t/lib-httpd/one-time-sed.sh| 22 ++
 t/t5703-upload-pack-ref-in-want.sh | 68 ++
 4 files changed, 99 insertions(+)
 create mode 100644 t/lib-httpd/one-time-sed.sh

diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 435a37465..84f8efdd4 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -132,6 +132,7 @@ prepare_httpd() {
cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH"
install_script broken-smart-http.sh
install_script error.sh
+   install_script one-time-sed.sh
 
ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules"
 
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 724d9ae46..fe68d37bb 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -111,9 +111,14 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
 
+
+   SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+   SetEnv GIT_HTTP_EXPORT_ALL
+
 ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
 ScriptAlias /broken_smart/ broken-smart-http.sh/
 ScriptAlias /error/ error.sh/
+ScriptAliasMatch /one_time_sed/(.*) one-time-sed.sh/$1
 
Options FollowSymlinks
 
@@ -123,6 +128,9 @@ ScriptAlias /error/ error.sh/
 
   Options ExecCGI
 
+
+   Options ExecCGI
+
 
Options ExecCGI
 
diff --git a/t/lib-httpd/one-time-sed.sh b/t/lib-httpd/one-time-sed.sh
new file mode 100644
index 0..8a9a5aca0
--- /dev/null
+++ b/t/lib-httpd/one-time-sed.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# If "one-time-sed" exists in $HTTPD_ROOT_PATH, run sed on the HTTP response,
+# using the contents of "one-time-sed" as the sed command to be run. If the
+# response was modified as a result, delete "one-time-sed" so that subsequent
+# HTTP responses are no longer modified.
+# 
+# This can be used to simulate the effects of the repository changing in
+# between HTTP request-response pairs.
+if [ -e one-time-sed ]; then "$GIT_EXEC_PATH/git-http-backend" >out
+
+   sed "$(cat one-time-sed)" out_modified
+
+   if diff out out_modified >/dev/null; then
+   cat out
+   else
+   cat out_modified
+   rm one-time-sed
+   fi
+else
+   "$GIT_EXEC_PATH/git-http-backend"
+fi
diff --git a/t/t5703-upload-pack-ref-in-want.sh 
b/t/t5703-upload-pack-ref-in-want.sh
index 0ef182970..a4fe0e7e4 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -150,4 +150,72 @@ test_expect_success 'want-ref with ref we already have 
commit for' '
check_output
 '
 
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
+LOCAL_PRISTINE="$(pwd)/local_pristine"
+
+test_expect_success 'setup repos for change-while-negotiating test' '
+   (
+   git init "$REPO" &&
+   cd "$REPO" &&
+   >.git/git-daemon-export-ok &&
+   test_commit m1 &&
+   git tag -d m1 &&
+
+   # Local repo with many commits (so that negotiation will take
+   # more than 1 request/response pair)
+   git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo"; 
"$LOCAL_PRISTINE" &&
+   cd "$LOCAL_PRISTINE" &&
+   git checkout -b side &&
+   for i in $(seq 1 33); do test_commit s$i; done &&
+
+   # Add novel commits to upstream
+   git checkout master &&
+   cd "$REPO" &&
+   test_commit m2 &&
+   test_commit m3 &&
+   git tag -d m2 m3
+   ) &&
+   git -C "$LOCAL_PRISTINE" remote set-url origin 
"http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo"; &&
+   git -C "$LOCAL_PRISTINE" config protocol.version 2
+'
+
+inconsistency() {
+   # Simulate that the server initially reports $2 as the ref
+   # corresponding to $1, and after that, $1 as the ref corresponding to
+   # $1. This corresponds to the real-life situation where the server's
+   # repository appears to change during negotiation, for example, when
+   # different servers in a load-balancing arrangement serve (stateless)
+   # RPCs during a single negotiation.
+   printf "s/%s/%s/" \
+  $(git -C "$REPO" rev-parse $1 | tr -d "\n") \
+  $(git -C "$REPO" rev-parse $2 

[PATCH v5 2/8] upload-pack: implement ref-in-want

2018-06-26 Thread Brandon Williams
Currently, while performing packfile negotiation, clients are only
allowed to specify their desired objects using object ids.  This causes
a vulnerability to failure when an object turns non-existent during
negotiation, which may happen if, for example, the desired repository is
provided by multiple Git servers in a load-balancing arrangement and
there exists replication delay.

In order to eliminate this vulnerability, implement the ref-in-want
feature for the 'fetch' command in protocol version 2.  This feature
enables the 'fetch' command to support requests in the form of ref names
through a new "want-ref " parameter.  At the conclusion of
negotiation, the server will send a list of all of the wanted references
(as provided by "want-ref" lines) in addition to the generated packfile.

Signed-off-by: Brandon Williams 
---
 Documentation/config.txt|   7 ++
 Documentation/technical/protocol-v2.txt |  29 -
 t/t5703-upload-pack-ref-in-want.sh  | 153 
 upload-pack.c   |  66 ++
 4 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100755 t/t5703-upload-pack-ref-in-want.sh

diff --git a/Documentation/config.txt b/Documentation/config.txt
index ab641bf5a..fb1dd7428 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -3479,6 +3479,13 @@ Note that this configuration variable is ignored if it 
is seen in the
 repository-level config (this is a safety measure against fetching from
 untrusted repositories).
 
+uploadpack.allowRefInWant::
+   If this option is set, `upload-pack` will support the `ref-in-want`
+   feature of the protocol version 2 `fetch` command.  This feature
+   is intended for the benefit of load-balanced servers which may
+   not have the same view of what OIDs their refs point to due to
+   replication delay.
+
 url..insteadOf::
Any URL that starts with this value will be rewritten to
start, instead, with . In cases where some site serves a
diff --git a/Documentation/technical/protocol-v2.txt 
b/Documentation/technical/protocol-v2.txt
index 49bda76d2..b53cfc6ce 100644
--- a/Documentation/technical/protocol-v2.txt
+++ b/Documentation/technical/protocol-v2.txt
@@ -299,12 +299,21 @@ included in the client's request:
for use with partial clone and partial fetch operations. See
`rev-list` for possible "filter-spec" values.
 
+If the 'ref-in-want' feature is advertised, the following argument can
+be included in the client's request as well as the potential addition of
+the 'wanted-refs' section in the server's response as explained below.
+
+want-ref 
+   Indicates to the server that the client wants to retrieve a
+   particular ref, where  is the full name of a ref on the
+   server.
+
 The response of `fetch` is broken into a number of sections separated by
 delimiter packets (0001), with each section beginning with its section
 header.
 
 output = *section
-section = (acknowledgments | shallow-info | packfile)
+section = (acknowledgments | shallow-info | wanted-refs | packfile)
  (flush-pkt | delim-pkt)
 
 acknowledgments = PKT-LINE("acknowledgments" LF)
@@ -319,6 +328,10 @@ header.
 shallow = "shallow" SP obj-id
 unshallow = "unshallow" SP obj-id
 
+wanted-refs = PKT-LINE("wanted-refs" LF)
+ *PKT-LINE(wanted-ref LF)
+wanted-ref = obj-id SP refname
+
 packfile = PKT-LINE("packfile" LF)
   *PKT-LINE(%x01-03 *%x00-ff)
 
@@ -379,6 +392,20 @@ header.
* This section is only included if a packfile section is also
  included in the response.
 
+wanted-refs section
+   * This section is only included if the client has requested a
+ ref using a 'want-ref' line and if a packfile section is also
+ included in the response.
+
+   * Always begins with the section header "wanted-refs".
+
+   * The server will send a ref listing (" ") for
+ each reference requested using 'want-ref' lines.
+
+   * The server SHOULD NOT send any refs which were not requested
+ using 'want-ref' lines and a client MUST ignore refs which
+ weren't requested.
+
 packfile section
* This section is only included if the client has sent 'want'
  lines in its request and either requested that no more
diff --git a/t/t5703-upload-pack-ref-in-want.sh 
b/t/t5703-upload-pack-ref-in-want.sh
new file mode 100755
index 0..0ef182970
--- /dev/null
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -0,0 +1,153 @@
+#!/bin/sh
+
+test_description='upload-pack ref-in-want'
+
+. ./test-lib.sh
+
+get_actual_refs() {
+   sed -n '/wanted-refs/,/0001/p' actual_refs
+}
+
+get_actual_commits() {
+   sed -n '/packfile/,//p' o.pack &&
+   git index-pack o.pack &&
+   git verify-pack -v o.idx | grep commit | cut -c-40 | sort 
>actual_commits
+}
+
+check_output() {
+   get_actual_refs &&
+   tes

[PATCH v5 4/8] fetch: refactor the population of peer ref OIDs

2018-06-26 Thread Brandon Williams
Populate peer ref OIDs in get_ref_map instead of do_fetch. Besides
tightening scopes of variables in the code, this also prepares for
get_ref_map being able to be called multiple times within do_fetch.

Signed-off-by: Brandon Williams 
---
 builtin/fetch.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index ea5b9669a..545635448 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -351,6 +351,7 @@ static struct ref *get_ref_map(struct transport *transport,
/* opportunistically-updated references: */
struct ref *orefs = NULL, **oref_tail = &orefs;
 
+   struct string_list existing_refs = STRING_LIST_INIT_DUP;
const struct ref *remote_refs;
 
if (rs->nr)
@@ -458,7 +459,23 @@ static struct ref *get_ref_map(struct transport *transport,
tail = &rm->next;
}
 
-   return ref_remove_duplicates(ref_map);
+   ref_map = ref_remove_duplicates(ref_map);
+
+   for_each_ref(add_existing, &existing_refs);
+   for (rm = ref_map; rm; rm = rm->next) {
+   if (rm->peer_ref) {
+   struct string_list_item *peer_item =
+   string_list_lookup(&existing_refs,
+  rm->peer_ref->name);
+   if (peer_item) {
+   struct object_id *old_oid = peer_item->util;
+   oidcpy(&rm->peer_ref->old_oid, old_oid);
+   }
+   }
+   }
+   string_list_clear(&existing_refs, 1);
+
+   return ref_map;
 }
 
 #define STORE_REF_ERROR_OTHER 1
@@ -1110,14 +1127,10 @@ static void backfill_tags(struct transport *transport, 
struct ref *ref_map)
 static int do_fetch(struct transport *transport,
struct refspec *rs)
 {
-   struct string_list existing_refs = STRING_LIST_INIT_DUP;
struct ref *ref_map;
-   struct ref *rm;
int autotags = (transport->remote->fetch_tags == 1);
int retcode = 0;
 
-   for_each_ref(add_existing, &existing_refs);
-
if (tags == TAGS_DEFAULT) {
if (transport->remote->fetch_tags == 2)
tags = TAGS_SET;
@@ -1136,18 +1149,6 @@ static int do_fetch(struct transport *transport,
if (!update_head_ok)
check_not_current_branch(ref_map);
 
-   for (rm = ref_map; rm; rm = rm->next) {
-   if (rm->peer_ref) {
-   struct string_list_item *peer_item =
-   string_list_lookup(&existing_refs,
-  rm->peer_ref->name);
-   if (peer_item) {
-   struct object_id *old_oid = peer_item->util;
-   oidcpy(&rm->peer_ref->old_oid, old_oid);
-   }
-   }
-   }
-
if (tags == TAGS_DEFAULT && autotags)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
if (prune) {
@@ -1183,7 +1184,6 @@ static int do_fetch(struct transport *transport,
}
 
  cleanup:
-   string_list_clear(&existing_refs, 1);
return retcode;
 }
 
-- 
2.18.0.rc2.346.g013aa6912e-goog



[PATCH v5 5/8] fetch: refactor fetch_refs into two functions

2018-06-26 Thread Brandon Williams
Refactor the fetch_refs function into a function that does the fetching
of refs and another function that stores them.  This is in preparation
for allowing additional processing of the fetched refs before updating
the local ref store.

Signed-off-by: Brandon Williams 
---
 builtin/fetch.c | 23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 545635448..2fabfed0e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -968,9 +968,21 @@ static int fetch_refs(struct transport *transport, struct 
ref *ref_map)
if (ret)
ret = transport_fetch_refs(transport, ref_map);
if (!ret)
-   ret |= store_updated_refs(transport->url,
-   transport->remote->name,
-   ref_map);
+   /*
+* Keep the new pack's ".keep" file around to allow the caller
+* time to update refs to reference the new objects.
+*/
+   return 0;
+   transport_unlock_pack(transport);
+   return ret;
+}
+
+/* Update local refs based on the ref values fetched from a remote */
+static int consume_refs(struct transport *transport, struct ref *ref_map)
+{
+   int ret = store_updated_refs(transport->url,
+transport->remote->name,
+ref_map);
transport_unlock_pack(transport);
return ret;
 }
@@ -1116,7 +1128,8 @@ static void backfill_tags(struct transport *transport, 
struct ref *ref_map)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, NULL);
transport_set_option(transport, TRANS_OPT_DEPTH, "0");
transport_set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, NULL);
-   fetch_refs(transport, ref_map);
+   if (!fetch_refs(transport, ref_map))
+   consume_refs(transport, ref_map);
 
if (gsecondary) {
transport_disconnect(gsecondary);
@@ -1165,7 +1178,7 @@ static int do_fetch(struct transport *transport,
   transport->url);
}
}
-   if (fetch_refs(transport, ref_map)) {
+   if (fetch_refs(transport, ref_map) || consume_refs(transport, ref_map)) 
{
free_refs(ref_map);
retcode = 1;
goto cleanup;
-- 
2.18.0.rc2.346.g013aa6912e-goog



[PATCH v5 1/8] test-pkt-line: add unpack-sideband subcommand

2018-06-26 Thread Brandon Williams
Add an 'unpack-sideband' subcommand to the test-pkt-line helper to
enable unpacking packet line data sent multiplexed using a sideband.

Signed-off-by: Brandon Williams 
---
 t/helper/test-pkt-line.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c
index 0f19e53c7..30775f986 100644
--- a/t/helper/test-pkt-line.c
+++ b/t/helper/test-pkt-line.c
@@ -1,3 +1,4 @@
+#include "cache.h"
 #include "pkt-line.h"
 
 static void pack_line(const char *line)
@@ -48,6 +49,36 @@ static void unpack(void)
}
 }
 
+static void unpack_sideband(void)
+{
+   struct packet_reader reader;
+   packet_reader_init(&reader, 0, NULL, 0,
+  PACKET_READ_GENTLE_ON_EOF |
+  PACKET_READ_CHOMP_NEWLINE);
+
+   while (packet_reader_read(&reader) != PACKET_READ_EOF) {
+   int band;
+   int fd;
+
+   switch (reader.status) {
+   case PACKET_READ_EOF:
+   break;
+   case PACKET_READ_NORMAL:
+   band = reader.line[0] & 0xff;
+   if (band < 1 || band > 2)
+   die("unexpected side band %d", band);
+   fd = band;
+
+   write_or_die(fd, reader.line + 1, reader.pktlen - 1);
+   break;
+   case PACKET_READ_FLUSH:
+   return;
+   case PACKET_READ_DELIM:
+   break;
+   }
+   }
+}
+
 int cmd_main(int argc, const char **argv)
 {
if (argc < 2)
@@ -57,6 +88,8 @@ int cmd_main(int argc, const char **argv)
pack(argc - 2, argv + 2);
else if (!strcmp(argv[1], "unpack"))
unpack();
+   else if (!strcmp(argv[1], "unpack-sideband"))
+   unpack_sideband();
else
die("invalid argument '%s'", argv[1]);
 
-- 
2.18.0.rc2.346.g013aa6912e-goog



Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 4:17 PM Jeff King  wrote:
> On Tue, Jun 26, 2018 at 03:52:54PM -0400, Eric Sunshine wrote:
> > So, this isn't a new problem introduced by this series, though this
> > series may exacerbate it.
>
> Whereas once you start collapsing subshells into the main logic chain,
> there's a very high chance that the subshell is doing a "cd", since
> that's typically the main reason for the subshell in the first place.
> And with the current --chain-lint logic, that subshell is either
> executed or not executed as a unit.
>
> Obviously that's a bit of a hand-waving argument. If you've fixed all of
> the existing cases without accidentally deleting your home directory,
> then maybe it's not so likely to be a problem after all.

Indeed, it could be that the "rm -fr" worry is tending toward the
hypothetical. Seasoned developers tend to be pretty careful and
usually avoid indiscriminately loose "rm -fr" invocations, so I'm
somewhat less worried about them. I do share the concern, though, that
newcomers crafting or extending tests could shoot themselves in the
foot with this. However, newcomers are also the ones most likely to
use the "cd foo && bar && cd .." idiom, so they are already at risk.

(As for not blasting my home directory when fixing all the existing
tests, I did run into a few cases where one or two "foreign" files
were deposited into the "t/" directory, but nothing was deleted or
overwritten.)

> I'm not sure if there's a good solution, though. Even if you retained
> the subshells and instead did a chain-lint inside each subshell, like
> this:
>
>   (exit 117) &&
>   one &&
>   (
> (exit 117) &&
> cd foo
> two
>   ) &&
>   three

I thought of that too, but the inner (exit 117) doesn't even get
invoked unless there is &&-chain breakage somewhere above that point
(for instance, if "one" lacks "&&"), so the inner (exit 117) doesn't
participate in the linting process at all.

> that doesn't really help. The fundamental issue is that we may skip the
> "cd" inside the subshell. Whether it's in a subshell or not, that's
> dangerous. True, we don't run "three" in this case, which is slightly
> better. But it didn't expect to be in a different directory anyway. It's
> running "two" that is dangerous.

Just thinking aloud...

Aside from "rm -fr", there are numerous ways to clobber files
unexpectedly when the "cd" is skipped:

echo x >../git.c
cp x ../git.c
mv x ../git.c
ln [-s] x ../git.c
/bin/rm ../git.c
some-cmd -o ../git.c

Some of these dangers can be de-thoothed during the linting phase by
defining do-nothing shell functions:

cp () { :; }
mv () { :; }
ln () { :; }

That, at least, makes the scariest case ("rm") much less so.


Re: [PATCH v2 0/6] Restrict the usage of config_from_gitmodules to submodule-config

2018-06-26 Thread Junio C Hamano
Brandon Williams  writes:

>> Changes since v1:
>>   * Remove an extra space before an arrow operator in patch 2
>>   * Fix a typo in the commit message of patch 3: s/fetchobjs/fetchjobs
>>   * Add a note in the commit message of patch 6 about checking the
>> worktree before loading .gitmodules
>>   * Drop patch 7, it was meant as a cleanup but resulted in parsing the
>> .gitmodules file twice
>
> Thanks for making these changes, this version looks good to me!

Yup, thanks, both.


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Jeff King
On Tue, Jun 26, 2018 at 04:17:08PM -0400, Jeff King wrote:

> I'm not sure if there's a good solution, though. Even if you retained
> the subshells and instead did a chain-lint inside each subshell, like
> this:

So obviously that means "I don't think there's a good solution with this
approach".

That whole final patch simultaneously impresses and nauseates me. Your
commit message says "no attempt is made at properly parsing shell code",
but we come pretty darn close. I almost wonder if we'd be better off
just parsing some heuristic subset and making sure (via review or
linting) that our tests conform.

Another option is to not enable this slightly-more-dangerous linting by
default. But that would probably rob it of its usefulness, since it
would just fall to some brave soul to later crank up the linting and fix
everybody else's mistakes.

-Peff


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Jeff King
On Tue, Jun 26, 2018 at 03:52:54PM -0400, Eric Sunshine wrote:

> The existing --chain-lint already suffers the same shortcoming. Older
> (or even new poorly-written) tests, even without subshells, can fall
> victim already:
> 
> (exit $sentinel) &&
> mkdir -p a/b/c &&
> cd a/b/c
> rm -fr ../../* &&
> cd ../../.. &&
> statement4
> 
> As in your example, 'mkdir' and 'cd' are skipped, but 'rm -fr ../../*' is not.
> 
> This snippet from the commit message of bb79af9d09 (t/test-lib:
> introduce --chain-lint option, 2015-03-20):
> 
> When we encounter a failure of this check, we abort the test
> script entirely. For one thing, we have no clue which subset
> of the commands in the test snippet were actually run.
> 
> suggests that the issue was considered, in some form, even then
> (though, it doesn't say explicitly that Peff had the 'rm -fr' case in
> mind).
>
> So, this isn't a new problem introduced by this series, though this
> series may exacerbate it.

One way this series might be worse in practice is that we tend not to
change process state too much outside of the subshells. So if we skip
some early commands and execute a later "rm", for example, it tends to
be in the same directory (and I think as time goes on we have been
cleaning up old tests which did a "cd foo && bar && cd .." into using a
subshell).

Whereas once you start collapsing subshells into the main logic chain,
there's a very high chance that the subshell is doing a "cd", since
that's typically the main reason for the subshell in the first place.
And with the current --chain-lint logic, that subshell is either
executed or not executed as a unit.

Obviously that's a bit of a hand-waving argument. If you've fixed all of
the existing cases without accidentally deleting your home directory,
then maybe it's not so likely to be a problem after all.

I'm not sure if there's a good solution, though. Even if you retained
the subshells and instead did a chain-lint inside each subshell, like
this:

  (exit 117) &&
  one &&
  (
(exit 117) &&
cd foo
two
  ) &&
  three


that doesn't really help. The fundamental issue is that we may skip the
"cd" inside the subshell. Whether it's in a subshell or not, that's
dangerous. True, we don't run "three" in this case, which is slightly
better. But it didn't expect to be in a different directory anyway. It's
running "two" that is dangerous.

-Peff


Re: [PATCH v2 5/6] submodule-config: pass repository as argument to config_from_gitmodules

2018-06-26 Thread Junio C Hamano
Antonio Ospite  writes:

> Generlize config_from_gitmodules to accept a repository as an argument.

generalize???

>
> This is in preparation to reuse the function in repo_read_gitmodules in
> order to have a single point where the '.gitmodules' file is accessed.
>
> Signed-off-by: Antonio Ospite 
> ---
>  submodule-config.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/submodule-config.c b/submodule-config.c
> index cd1f1e06a..602c46af2 100644
> --- a/submodule-config.c
> +++ b/submodule-config.c
> @@ -680,10 +680,10 @@ void submodule_free(struct repository *r)
>   * Runs the provided config function on the '.gitmodules' file found in the
>   * working directory.
>   */
> -static void config_from_gitmodules(config_fn_t fn, void *data)
> +static void config_from_gitmodules(config_fn_t fn, struct repository *repo, 
> void *data)
>  {
> - if (the_repository->worktree) {
> - char *file = repo_worktree_path(the_repository, 
> GITMODULES_FILE);
> + if (repo->worktree) {
> + char *file = repo_worktree_path(repo, GITMODULES_FILE);
>   git_config_from_file(fn, file, data);
>   free(file);
>   }
> @@ -714,7 +714,7 @@ void fetch_config_from_gitmodules(int *max_children, int 
> *recurse_submodules)
>   .max_children = max_children,
>   .recurse_submodules = recurse_submodules
>   };
> - config_from_gitmodules(gitmodules_fetch_config, &config);
> + config_from_gitmodules(gitmodules_fetch_config, the_repository, 
> &config);
>  }
>  
>  static int gitmodules_update_clone_config(const char *var, const char *value,
> @@ -728,5 +728,5 @@ static int gitmodules_update_clone_config(const char 
> *var, const char *value,
>  
>  void update_clone_config_from_gitmodules(int *max_jobs)
>  {
> - config_from_gitmodules(gitmodules_update_clone_config, &max_jobs);
> + config_from_gitmodules(gitmodules_update_clone_config, the_repository, 
> &max_jobs);
>  }


Re: [PATCH v2 4/6] submodule-config: make 'config_from_gitmodules' private

2018-06-26 Thread Junio C Hamano
Antonio Ospite  writes:

> Now that 'config_from_gitmodules' is not used in the open, it can be
> marked as private.

Nice ;-)


Re: [PATCH v2 2/6] submodule-config: add helper function to get 'fetch' config from .gitmodules

2018-06-26 Thread Junio C Hamano
Antonio Ospite  writes:

> Add a helper function to make it clearer that retrieving 'fetch'
> configuration from the .gitmodules file is a special case supported
> solely for backward compatibility purposes.
> ...

Then perhaps the new public function deserves a comment stating
that?

> +struct fetch_config {
> + int *max_children;
> + int *recurse_submodules;
> +};
> +
> +static int gitmodules_fetch_config(const char *var, const char *value, void 
> *cb)
> +{
> + struct fetch_config *config = cb;
> + if (!strcmp(var, "submodule.fetchjobs")) {
> + *(config->max_children) = parse_submodule_fetchjobs(var, value);
> + return 0;
> + } else if (!strcmp(var, "fetch.recursesubmodules")) {
> + *(config->recurse_submodules) = 
> parse_fetch_recurse_submodules_arg(var, value);
> + return 0;
> + }
> +
> + return 0;
> +}
> +
> +void fetch_config_from_gitmodules(int *max_children, int *recurse_submodules)
> +{
> + struct fetch_config config = {
> + .max_children = max_children,
> + .recurse_submodules = recurse_submodules
> + };

We started using designated initializers some time ago, and use of
it improves readability of something like this ;-)

> + config_from_gitmodules(gitmodules_fetch_config, &config);
> +}
> diff --git a/submodule-config.h b/submodule-config.h
> index 5148801f4..cff297a75 100644
> --- a/submodule-config.h
> +++ b/submodule-config.h
> @@ -66,4 +66,6 @@ int check_submodule_name(const char *name);
>   */
>  extern void config_from_gitmodules(config_fn_t fn, void *data);
>  
> +extern void fetch_config_from_gitmodules(int *max_children, int 
> *recurse_submodules);
> +
>  #endif /* SUBMODULE_CONFIG_H */


Re: [PATCH 14/29] t: drop subshell with missing &&-chain in favor of simpler construct

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 3:31 PM Junio C Hamano  wrote:
> Eric Sunshine  writes:
> > These tests employ a noisy subshell (with missing &&-chain) to feed
> > input into Git commands:
> >
> > (echo a; echo b; echo c) | git some-command ...
> >
> > Drop the subshell in favor of a simple 'printf':
> >
> > printf "%s\n" a b c | git some-command ...
>
> That's called test_write_lines, I think.

Yep, that's better. Thanks.


Re: [BUG] url schemes should be case-insensitive

2018-06-26 Thread Jeff King
On Tue, Jun 26, 2018 at 02:27:39PM -0400, Jeff King wrote:

> So yeah, we would not want to allow EXT::"rm -rf /" to slip past the
> known-unsafe match. Any normalization should happen before then
> (probably right in transport_helper_init).
> 
> Come to think of it, that's already sort-of an issue now. If you have a
> case-insensitive filesystem, then EXT:: is going to pass this check, but
> still run git-remote-ext. We're saved there somewhat by the fact that
> the default is to reject unknown helpers in submodules (otherwise, we'd
> have that horrible submodule bug all over again).
> 
> That goes beyond just cases, too. On HFS+ I wonder if I could ask for
> "\u{0200}ext::" and run git-remote-ext.

That should be \u{200c}, of course, to get the correct sneaky character.
And the good news is that no, it doesn't work. We are protected by this
code in transport_get():

  /* maybe it is a foreign URL? */
  if (url) {
  const char *p = url;

  while (is_urlschemechar(p == url, *p))
  p++; 
  if (starts_with(p, "::"))
  helper = xstrndup(url, p - url);
  }

So we'll only allow remote-helper names with valid url characters, which
are basically [A-Za-z0-9+.-]. So I think we probably only have to worry
about true case issues, and not any kind of weird filesystem-specific
behaviors.

-Peff


Re: [GSoC][PATCH 1/1] sequencer: print an error message if append_todo_help() fails

2018-06-26 Thread Junio C Hamano
Johannes Schindelin  writes:

> Hi Alban,
>
> On Tue, 26 Jun 2018, Alban Gruin wrote:
>
>> This adds an error when append_todo_help() fails to write its message to
>> the todo file.
>> 
>> Signed-off-by: Alban Gruin 
>
> ACK.
>
> We *may* want to fold that into the commit that adds `append_todo_help()`.

Absolutely.  This looks more like an "oops, I made a mess and here
is a fix on top", and even worse, it does not make an effort to help
readers where the mess was made (iow, which commit it goes on to
of); it is better to be squashed in.

I do not know offhand who Alban's mentors are, but one thing I think
is a good thing for them to teach is how to better organize the
changes with readers in mind.  The author of a patch series knows
his or her patches and how they relate to each other a lot better
than the readers of patches, who are reading not just his or her
patches but the ones from a lot wider set of contributors.  Even
though append-todo-help and edit-todo may have been developed as
separate steps in author's mind, it is criminal to send them as if
they are completely separate topics that can independently applied,
especially when one depends on the other.  It is a lot more helpful
to the readers if they were sent as a larger single series, because
doing so _will_ tell the readers which order the dependency goes.

> And, as I mentioned previously, I would love for that function to be used
> as an excuse to introduce the long-overdue `interactive-rebase.c`

I am not sure if I like this direction.  

As newbies are often very bad at coming up with APIs and naming
global functions, keeping everything as "static" inside a single
sequencer.c tends to avoid contaminating the global namespace.


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 3:15 PM Junio C Hamano  wrote:
> so, with --chain-lint, we would transform this
>
> mkdir -p a/b/c &&
> (
> cd a/b/c
> rm -fr ../../*
> ) &&
> statement 4
>
> into this sequence
>
> (exit $sentinel) &&
> mkdir -p a/b/c &&
> cd a/b/c
> rm -fr ../../* &&
> statement 4
>
> and then rely on the non-zero exit to cancel all the remainder?
>
> We didn't create nor cd to the t/trash$num/a/b/c thanks to the &&
> chain, and end up running rm -fr ../../* from inside t/trash$num?

Yes, I did take that into account and, no, I don't have a good answer
to the issue.

The existing --chain-lint already suffers the same shortcoming. Older
(or even new poorly-written) tests, even without subshells, can fall
victim already:

(exit $sentinel) &&
mkdir -p a/b/c &&
cd a/b/c
rm -fr ../../* &&
cd ../../.. &&
statement4

As in your example, 'mkdir' and 'cd' are skipped, but 'rm -fr ../../*' is not.

This snippet from the commit message of bb79af9d09 (t/test-lib:
introduce --chain-lint option, 2015-03-20):

When we encounter a failure of this check, we abort the test
script entirely. For one thing, we have no clue which subset
of the commands in the test snippet were actually run.

suggests that the issue was considered, in some form, even then
(though, it doesn't say explicitly that Peff had the 'rm -fr' case in
mind).

So, this isn't a new problem introduced by this series, though this
series may exacerbate it.

Thanks for thinking critically about it.


Re: [PATCH 00/29] t: detect and fix broken &&-chains in subshells

2018-06-26 Thread Junio C Hamano
Eric Sunshine  writes:

> The --chain-lint[1] option detects breakage in the top-level &&-chain of
> tests. This series undertakes the more complex task of teaching it to
> also detect &&-chain breakage within subshells. See patch 29/29 for the
> gory details of how that's done.

I first looked at 29/29 and got heavily inclined to reject that
step, and then continued reading from 1/29 to around 15/29.  

I like these earlier changes that fix existing breakage, of course.
I also like many of the changes that simplify and/or modernise the
test scripts very much, but they are unusable as-is as long as their
justification is "chain-lint will start barfing on these constructs".


Re: git rerere and diff3

2018-06-26 Thread Nicolas Dechesne
On Tue, Jun 26, 2018 at 9:05 PM Junio C Hamano  wrote:
>
> Nicolas Dechesne  writes:
>
> > i have noticed that merge.conflictstyle has an impact on the rerere
> > resolution. looking briefly at the source code, it seems that git
> > tries to discard the common ancestor diff3 bits, but what I am seeing
> > is that if i do the following then it fails:
> >
> > 1. from a clean rr-cache state, with merge.conflictsytle=diff3, git
> > merge , resolve the conflicts, then commit
> > 2. undo the previous merge, remove merge.conflictstyle=diff3 (disable
> > diff3) and merge the *same* branch, then rerere won't fix the
> > conflicts
>
> It is possible that the conflict left when making the same merge are
> actually different when using these two conflict styles.  IOW, if
> the merge produces
>
> <<<
> side A
> |||
> common
> ===
> side B
> >>>
>
> when diff3 style is chosen, but if the same merge results in
>
> <<<
> side A'
> ===
> side B'
> >>>
>
> where side A' is not identical to side A (or B' and B are not
> identical), then we will fail to find the previously recorded
> resolution.

well, you're rigth.. that's what's happening...

=== with conflictstyle=merge
diff --cc arch/arm64/configs/defconfig
index 3cfa8ca26738,d53a1b00ad82..
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@@ -356,7 -334,7 +357,11 @@@ CONFIG_GPIO_PCA953X=
  CONFIG_GPIO_PCA953X_IRQ=y
  CONFIG_GPIO_MAX77620=y
  CONFIG_POWER_AVS=y
++<<< HEAD
 +CONFIG_ROCKCHIP_IODOMAIN=y
++===
+ CONFIG_QCOM_CPR=y
++>>> tracking-qcomlt-8016-dvfs
  CONFIG_POWER_RESET_MSM=y
  CONFIG_POWER_RESET_XGENE=y
  CONFIG_POWER_RESET_SYSCON=y

=== with conflictstyle=diff3
diff --cc arch/arm64/configs/defconfig
index 3cfa8ca26738,d53a1b00ad82..
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@@ -355,8 -333,8 +356,14 @@@ CONFIG_GPIO_XGENE_SB=
  CONFIG_GPIO_PCA953X=y
  CONFIG_GPIO_PCA953X_IRQ=y
  CONFIG_GPIO_MAX77620=y
++<<< HEAD
 +CONFIG_POWER_AVS=y
 +CONFIG_ROCKCHIP_IODOMAIN=y
++||| merged common ancestors
++===
+ CONFIG_POWER_AVS=y
+ CONFIG_QCOM_CPR=y
++>>> tracking-qcomlt-8016-dvfs
  CONFIG_POWER_RESET_MSM=y
  CONFIG_POWER_RESET_XGENE=y
  CONFIG_POWER_RESET_SYSCON=y

that explains it.. it was simpler than what I thought..

thanks!


Re: [PATCH 14/29] t: drop subshell with missing &&-chain in favor of simpler construct

2018-06-26 Thread Junio C Hamano
Eric Sunshine  writes:

> These tests employ a noisy subshell (with missing &&-chain) to feed
> input into Git commands:
>
> (echo a; echo b; echo c) | git some-command ...
>
> Drop the subshell in favor of a simple 'printf':
>
> printf "%s\n" a b c | git some-command ...

That's called test_write_lines, I think.


Re: [PATCH v2] filter-branch: skip commits present on --state-branch

2018-06-26 Thread Ian Campbell
On Mon, 2018-06-25 at 21:07 -0700, Michael Barabanov wrote:
> The commits in state:filter.map have already been processed, so don't
> filter them again. This makes incremental git filter-branch much
> faster.
> 
> Also add tests for --state-branch option.
> 
> Signed-off-by: Michael Barabanov 

Acked-by: Ian Campbell 

> ---
>  git-filter-branch.sh |  1 +
>  t/t7003-filter-branch.sh | 15 +++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/git-filter-branch.sh b/git-filter-branch.sh
> index ccceaf19a..5c5afa2b9 100755
> --- a/git-filter-branch.sh
> +++ b/git-filter-branch.sh
> @@ -372,6 +372,7 @@ while read commit parents; do
>   git_filter_branch__commit_count=$(($git_filter_branch__commi
> t_count+1))
>  
>   report_progress
> + test -f "$workdir"/../map/$commit && continue
>  
>   case "$filter_subdir" in
>   "")
> diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
> index ec4b160dd..e23de7d0b 100755
> --- a/t/t7003-filter-branch.sh
> +++ b/t/t7003-filter-branch.sh
> @@ -107,6 +107,21 @@ test_expect_success 'test that the directory was
> renamed' '
>   test dir/D = "$(cat diroh/D.t)"
>  '
>  
> +V=$(git rev-parse HEAD)
> +
> +test_expect_success 'populate --state-branch' '
> + git filter-branch --state-branch state -f --tree-filter
> "touch file || :" HEAD
> +'
> +
> +W=$(git rev-parse HEAD)
> +
> +test_expect_success 'using --state-branch to skip already rewritten
> commits' '
> + test_when_finished git reset --hard $V &&
> + git reset --hard $V &&
> + git filter-branch --state-branch state -f --tree-filter
> "touch file || :" HEAD &&
> + test_cmp_rev $W HEAD
> +'
> +
>  git tag oldD HEAD~4
>  test_expect_success 'rewrite one branch, keeping a side branch' '
>   git branch modD oldD &&


Re: [PATCH 29/29] t/test-lib: teach --chain-lint to detect broken &&-chains in subshells

2018-06-26 Thread Junio C Hamano
Eric Sunshine  writes:

> The --chain-lint option detects broken &&-chains by forcing the test to
> exit early (as the very first step) with a sentinel value. If that
> sentinel is the test's overall exit code, then the &&-chain is intact;
> if not, then the chain is broken. Unfortunately, this detection does not
> extend to &&-chains within subshells even when the subshell itself is
> properly linked into the outer &&-chain.
>
> Address this shortcoming by eliminating the subshell during the
> "linting" phase and incorporating its body directly into the surrounding
> &&-chain. To keep this transformation cheap, no attempt is made at
> properly parsing shell code. Instead, the manipulations are purely
> textual. For example:
>
> statement1 &&
> (
> statement2 &&
> statement3
> ) &&
> statement4
>
> is transformed to:
>
> statement1 &&
> statement2 &&
> statement3 &&
> statement4

so, with --chain-lint, we would transform this

mkdir -p a/b/c &&
(
cd a/b/c
rm -fr ../../*
) &&
statement 4

into this sequence

(exit $sentinel) &&
mkdir -p a/b/c &&
cd a/b/c
rm -fr ../../* &&
statement 4

and then rely on the non-zero exit to cancel all the remainder?

We didn't create nor cd to the t/trash$num/a/b/c thanks to the &&
chain, and end up running rm -fr ../../* from inside t/trash$num?

Hm


Re: git rerere and diff3

2018-06-26 Thread Junio C Hamano
Nicolas Dechesne  writes:

> i have noticed that merge.conflictstyle has an impact on the rerere
> resolution. looking briefly at the source code, it seems that git
> tries to discard the common ancestor diff3 bits, but what I am seeing
> is that if i do the following then it fails:
>
> 1. from a clean rr-cache state, with merge.conflictsytle=diff3, git
> merge , resolve the conflicts, then commit
> 2. undo the previous merge, remove merge.conflictstyle=diff3 (disable
> diff3) and merge the *same* branch, then rerere won't fix the
> conflicts

It is possible that the conflict left when making the same merge are
actually different when using these two conflict styles.  IOW, if
the merge produces

<<<
side A
|||
common
===
side B
>>>

when diff3 style is chosen, but if the same merge results in

<<<
side A'
===
side B'
>>>

where side A' is not identical to side A (or B' and B are not
identical), then we will fail to find the previously recorded
resolution.



Re: [PATCH] fetch-pack: support negotiation tip whitelist

2018-06-26 Thread Junio C Hamano
Jonathan Tan  writes:

> During negotiation, fetch-pack eventually reports as "have" lines all
> commits reachable from all refs. Allow the user to restrict the commits
> sent in this way by providing a whitelist of tips; only the tips
> themselves and their ancestors will be sent.
>
> This feature is only supported for protocols that support connect or
> stateless-connect (such as HTTP with protocol v2).
>
> This will speed up negotiation when the repository has multiple
> relatively independent branches (for example, when a repository
> interacts with multiple repositories, such as with linux-next [1] and
> torvalds/linux [2]), and the user knows which local branch is likely to
> have commits in common with the upstream branch they are fetching.
>
> [1] https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next/
> [2] https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/
>
> Signed-off-by: Jonathan Tan 
> ---
> This is based on jt/fetch-pack-negotiator, but if that branch is
> undesirable for whatever reason, I can port this to master.
> ---
>  builtin/fetch.c| 21 ++
>  fetch-pack.c   | 19 ++--
>  fetch-pack.h   |  7 ++
>  t/t5510-fetch.sh   | 55 ++
>  transport-helper.c |  3 +++
>  transport.c|  1 +
>  transport.h| 10 +
>  7 files changed, 114 insertions(+), 2 deletions(-)

What's the plan to expose this "feature" to end-users?  There is no
end-user facing documentation added by this patch, and in-code
comments only talk about what (mechanical) effect the option has,
but not when a user may want to use the feature, or how the user
would best decide the set of commits to pass to this new option.

Would something like this

git fetch $(git for-each-ref \
--format=--nego-tip="%(objectname)" \
refs/remotes/linux-next/) \
linux-next

be an expected typical way to pull from one remote, exposing only
the tips of refs we got from that remote and not the ones we
obtained from other places?


Re: [BUG] url schemes should be case-insensitive

2018-06-26 Thread Jeff King
On Tue, Jun 26, 2018 at 10:09:58AM -0700, Junio C Hamano wrote:

> > It may also interact in a funny way with our allowed-protocol code, if
> > "SSH" gets a pass as "ssh" under the default config, but actually runs
> > the otherwise-disallowed git-remote-SSH (though one would _hope_ if you
> > have such a git-remote-SSH that it behaves just like an ssh remote).
> 
> True.  I did not offhand recall how protocol whitelist matches the
> protocol name with config, but transport.c::get_protocol_config()
> seems to say that the  part of "protocol..allow" is case
> sensitive, and we match known-safe (and known-unsafe "ext::")
> protocols with strcmp() not strcasecmp().  We need to figure out the
> implications of allowing SSH:// not to error out but pretending as
> if it were ssh:// on those who have protocol.ssh.allow defined.

That function is actually a little tricky, because we feed it mostly
from string literals (so we end up in the ssh code path, and then feed
it "ssh"). But I think for remote-helpers we feed it literally from the
URL we got fed.

So yeah, we would not want to allow EXT::"rm -rf /" to slip past the
known-unsafe match. Any normalization should happen before then
(probably right in transport_helper_init).

Come to think of it, that's already sort-of an issue now. If you have a
case-insensitive filesystem, then EXT:: is going to pass this check, but
still run git-remote-ext. We're saved there somewhat by the fact that
the default is to reject unknown helpers in submodules (otherwise, we'd
have that horrible submodule bug all over again).

That goes beyond just cases, too. On HFS+ I wonder if I could ask for
"\u{0200}ext::" and run git-remote-ext.

> > I think it doesn't help much if the user does not know what a remote
> > helper is, or why Git is looking for one.
> 
> True.  
> 
>   $ git clone SSH://example.com/repo.git
>   fatal: unable to handle URL that begins with SSH://
> 
> would be clear enough, perhaps?  At least this line of change is a
> small first step that would improve the situation without potential
> to break anybody who has been abusing the case sensitivity loophole.

Yeah, certainly the advice is orthogonal to any behavior changes. The
original report complained of:

  $ git clone SSH://...
  fatal: 'remote-SSH' is not a git command. See 'git --help'.

but since 6b02de3b9d in 2010 we say:

  fatal: Unable to find remote helper for 'SSH'

So I actually wonder if there is something else going on. I find it hard
to believe the OP is using something older than Git v1.7.0. They did
appear to be on Windows, though. Is it possible our ENOENT detection
from start_command() is not accurate on Windows?

-Peff


Re: [PATCH v4 3/9] t3422: new testcases for checking when incompatible options passed

2018-06-26 Thread Junio C Hamano
Elijah Newren  writes:

> +# Rebase has lots of useful options like --whitepsace=fix, which are
> +# actually all built in terms of flags to git-am.  Since neither
> +# --merge nor --interactive (nor any options that imply those two) use
> +# git-am, using them together will result in flags like --whitespace=fix
> +# being ignored.  Make sure rebase warns the user and aborts instead.
> +#
> +
> +test_rebase_am_only () {
> + opt=$1
> + shift
> + test_expect_failure "$opt incompatible with --merge" "
> + git checkout B^0 &&
> + test_must_fail git rebase $opt --merge A
> + "
> +
> + test_expect_failure "$opt incompatible with --strategy=ours" "
> + git checkout B^0 &&
> + test_must_fail git rebase $opt --strategy=ours A
> + "
> +
> + test_expect_failure "$opt incompatible with --strategy-option=ours" "
> + git checkout B^0 &&
> + test_must_fail git rebase $opt --strategy=ours A

This line is broken and it is carried over to later patches.  It
needs to be -Xours (or --strategy-option=ours, if we really want ot
be verbose).

> + "
> +
> + test_expect_failure "$opt incompatible with --interactive" "
> + git checkout B^0 &&
> + test_must_fail git rebase $opt --interactive A
> + "
> +
> + test_expect_failure "$opt incompatible with --exec" "
> + git checkout B^0 &&
> + test_must_fail git rebase $opt --exec 'true' A
> + "
> +
> +}

> +
> +test_rebase_am_only --whitespace=fix
> +test_rebase_am_only --ignore-whitespace
> +test_rebase_am_only --committer-date-is-author-date
> +test_rebase_am_only -C4

I was hesitant to hardcode what I perceive as limitations of non-am
rebase implementations with a test like this, but once somebody
fixes "rebase -i" for example to be capable of --whitespace=fix for
example, then we can just drop one line from the above four (and
write other tests for "rebase -i --whitespace=fix").  The
test_rebase_am_only is to help us make sure what is (still) not
supported by non-am rebases gets diagnosed as an error.

So my worry is totally unfounded, which is good.

> +test_expect_success '--preserve-merges incompatible with --signoff' '
> + git checkout B^0 &&
> + test_must_fail git rebase --preserve-merges --signoff A
> +'
> +
> +test_expect_failure '--preserve-merges incompatible with --rebase-merges' '
> + git checkout B^0 &&
> + test_must_fail git rebase --preserve-merges --rebase-merges A
> +'
> +
> +test_expect_failure '--rebase-merges incompatible with --strategy' '
> + git checkout B^0 &&
> + test_must_fail git rebase --rebase-merges -s resolve A
> +'
> +
> +test_expect_failure '--rebase-merges incompatible with --strategy-option' '
> + git checkout B^0 &&
> + test_must_fail git rebase --rebase-merges -Xignore-space-change A
> +'
> +
> +test_done


Re: [PATCH 17/29] t: use test_must_fail() instead of checking exit code manually

2018-06-26 Thread Eric Sunshine
On Tue, Jun 26, 2018 at 2:06 PM Johannes Sixt  wrote:
> Am 26.06.2018 um 11:21 schrieb Eric Sunshine:
> >> On Tue, Jun 26, 2018 at 12:29 AM, Eric Sunshine  
> >> wrote:
> >>> +   p4 help client &&
> >>> +   test_must_fail p4 help nosuchcommand
> > [...] So, despite
> > the (somewhat) misleading test title, this test doesn't care about the
> > exact error code but rather cares only that "p4 help nosuchcommand"
> > errors out, period. Hence, test_must_fail() again agrees with the
> > spirit of the test.
>
> test_must_fail ensures that only "proper" failures are diagnosed as
> expected; failures due to signals such as SEGV are not expected failures.
>
> In the test suite we expect all programs that are not our "git" to work
> correctly; in particular, that they do not crash on anything that we ask
> them to operate on. Under this assumption, the protection given by
> test_must_fail is not needed.
>
> Hence, these lines should actually be
>
> p4 help client &&
> ! p4 help nosuchcommand

Thanks for the comment; you're right, of course. I'll certainly make
this change if I have to re-roll for some other reason, but do you
feel that this itself is worth a re-roll?


Re: [PATCH 17/29] t: use test_must_fail() instead of checking exit code manually

2018-06-26 Thread Johannes Sixt

Am 26.06.2018 um 11:21 schrieb Eric Sunshine:

On Tue, Jun 26, 2018 at 4:58 AM Elijah Newren  wrote:

On Tue, Jun 26, 2018 at 12:29 AM, Eric Sunshine  wrote:

+   p4 help client &&
+   test_must_fail p4 help nosuchcommand


same question?


Same answer. Not shown in this patch, but just above the context lines
you will find this comment in the file:

 # We rely on this behavior to detect for p4 move availability.

which means that the test is really interested in being able to
reliably detect if a sub-command is or is not available. So, despite
the (somewhat) misleading test title, this test doesn't care about the
exact error code but rather cares only that "p4 help nosuchcommand"
errors out, period. Hence, test_must_fail() again agrees with the
spirit of the test.


test_must_fail ensures that only "proper" failures are diagnosed as 
expected; failures due to signals such as SEGV are not expected failures.


In the test suite we expect all programs that are not our "git" to work 
correctly; in particular, that they do not crash on anything that we ask 
them to operate on. Under this assumption, the protection given by 
test_must_fail is not needed.


Hence, these lines should actually be

p4 help client &&
! p4 help nosuchcommand

-- Hannes


[PATCH] rebase -i: Fix white space in comments

2018-06-26 Thread dana
Fix a trivial white-space issue introduced by commit d48f97aa8
("rebase: reindent function git_rebase__interactive", 2018-03-23). This
affected the instructional comments displayed in the editor during an
interactive rebase.

Signed-off-by: dana 
---

Sorry if i've done any of this wrong; i've never used this work-flow
before. In any case, if it's not immediately obvious, this is the issue
i mean to fix:

BEFORE (2.17.1):

# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

AFTER (2.18.0):

# If you remove a line here THAT COMMIT WILL BE LOST.
#
#   However, if you remove everything, the rebase will be aborted.
#
#   
# Note that empty commits are commented out

The 2.18.0 version is particularly irritating because many editors
highlight the trailing tab in the penultimate line as a white-space
error.

Aside: It's not a new thing, but i've always felt like that last line
should end in a full stop. Maybe i'll send a patch for that too.

Cheers,
dana

 git-rebase--interactive.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 299ded213..a31af6d4c 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -222,9 +222,9 @@ $comment_char $(eval_ngettext \
 EOF
append_todo_help
gettext "
-   However, if you remove everything, the rebase will be aborted.
+However, if you remove everything, the rebase will be aborted.
 
-   " | git stripspace --comment-lines >>"$todo"
+" | git stripspace --comment-lines >>"$todo"
 
if test -z "$keep_empty"
then
-- 
2.18.0



Re: [PATCH] fetch-pack: support negotiation tip whitelist

2018-06-26 Thread Jonathan Nieder
Hi,

Jonathan Tan wrote:

> During negotiation, fetch-pack eventually reports as "have" lines all
> commits reachable from all refs. Allow the user to restrict the commits
> sent in this way by providing a whitelist of tips; only the tips
> themselves and their ancestors will be sent.
>
> This feature is only supported for protocols that support connect or
> stateless-connect (such as HTTP with protocol v2).
>
> This will speed up negotiation when the repository has multiple
> relatively independent branches (for example, when a repository
> interacts with multiple repositories, such as with linux-next [1] and
> torvalds/linux [2]), and the user knows which local branch is likely to
> have commits in common with the upstream branch they are fetching.
>
> [1] https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next/
> [2] https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/
>
> Signed-off-by: Jonathan Tan 
> ---

Very neat.  Thanks to Greg Thelen and Michel Lespinasse (cc-ed) for
this suggestion.

> This is based on jt/fetch-pack-negotiator, but if that branch is
> undesirable for whatever reason, I can port this to master.
>
>  builtin/fetch.c| 21 ++
>  fetch-pack.c   | 19 ++--
>  fetch-pack.h   |  7 ++
>  t/t5510-fetch.sh   | 55 ++
>  transport-helper.c |  3 +++
>  transport.c|  1 +
>  transport.h| 10 +
>  7 files changed, 114 insertions(+), 2 deletions(-)

Small nit: could this be documented in Documentation/fetch.txt as well?

Thanks,
Jonathan

Patch left unsnipped for reference.

> diff --git a/builtin/fetch.c b/builtin/fetch.c
> index ea5b9669a..12daec0f3 100644
> --- a/builtin/fetch.c
> +++ b/builtin/fetch.c
> @@ -63,6 +63,7 @@ static int shown_url = 0;
>  static struct refspec refmap = REFSPEC_INIT_FETCH;
>  static struct list_objects_filter_options filter_options;
>  static struct string_list server_options = STRING_LIST_INIT_DUP;
> +static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
>  
>  static int git_fetch_config(const char *k, const char *v, void *cb)
>  {
> @@ -174,6 +175,8 @@ static struct option builtin_fetch_options[] = {
>   TRANSPORT_FAMILY_IPV4),
>   OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
>   TRANSPORT_FAMILY_IPV6),
> + OPT_STRING_LIST(0, "negotiation-tip", &negotiation_tip, N_("revision"),
> + N_("report that we have only objects reachable from 
> this object")),
>   OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
>   OPT_END()
>  };
> @@ -1075,6 +1078,24 @@ static struct transport *prepare_transport(struct 
> remote *remote, int deepen)
>  filter_options.filter_spec);
>   set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
>   }
> + if (negotiation_tip.nr) {
> + struct oid_array *oids;
> + if (transport->smart_options) {
> + int i;
> + oids = xcalloc(1, sizeof(*oids));
> + for (i = 0; i < negotiation_tip.nr; i++) {
> + struct object_id oid;
> + if (get_oid(negotiation_tip.items[i].string,
> + &oid))
> + die("%s is not a valid object",
> + negotiation_tip.items[i].string);
> + oid_array_append(oids, &oid);
> + }
> + transport->smart_options->negotiation_tips = oids;
> + } else {
> + warning("Ignoring --negotiation-tip because the 
> protocol does not support it.");
> + }
> + }
>   return transport;
>  }
>  
> diff --git a/fetch-pack.c b/fetch-pack.c
> index ba12085c4..c66bd49bd 100644
> --- a/fetch-pack.c
> +++ b/fetch-pack.c
> @@ -213,6 +213,21 @@ static int next_flush(int stateless_rpc, int count)
>   return count;
>  }
>  
> +static void mark_tips(struct fetch_negotiator *negotiator,
> +   const struct oid_array *negotiation_tips)
> +{
> + int i;
> + if (!negotiation_tips) {
> + for_each_ref(rev_list_insert_ref_oid, negotiator);
> + return;
> + }
> +
> + for (i = 0; i < negotiation_tips->nr; i++)
> + rev_list_insert_ref(negotiator, NULL,
> + &negotiation_tips->oid[i]);
> + return;
> +}
> +
>  static int find_common(struct fetch_negotiator *negotiator,
>  struct fetch_pack_args *args,
>  int fd[2], struct object_id *result_oid,
> @@ -230,7 +245,7 @@ static int find_common(struct fetch_negotiator 
> *negotiator,
>   if (args->stateless_rpc && multi_ack == 1)
>   die(_("--stateless-rpc requires multi_ack_detailed"));
>  
> - for_each_ref(rev_lis

Re: [GSoC][PATCH v3 2/3] rebase -i: rewrite setup_reflog_action() in C

2018-06-26 Thread Junio C Hamano
Alban Gruin  writes:

 I do not think "base_commit" is a good name, either, though.  When I
 hear 'base' in the context of 'rebase', I would imagine that the
 speaker is talking about the bottom of the range of the commits to
 be rebased (i.e. "rebase --onto ONTO BASE BRANCH", which replays
 commits BASE..BRANCH on top of ONTO and then points BRANCH at the
 result), not the top of the range or the branch these commits are
 taken from.
>>> ...
> Now I really don’t know how to call this function.
> checkout_top_of_range(), perhaps?

If this is a straight rewrite of setup_reflog_action, i.e. the
division of labor between its caller and this function is such that
the caller blindly calls it without even checking if it got the
optional "branch to be rebased" argument and this function is
responsible to decide if the preparatory checkout of the named
branch is necessary, then any name that does not even hint that
checkout is done conditionally would not work well.

How about callilng it "prepare_branch_to_be_rebased()"?  This
function, at least the original setup_reflog_action, responds to

git rebase [--onto ONTO] UPSTREAM

by doing nothing (i.e. the result of preparation is to do nothing
because we are rebasing the commits between UPSTREAM and currently
checked out state on top of ONTO, or UPSTREAM if ONTO is not
given) and it responds to

git rebase [--onto ONTO] UPSTREAM BRANCH

by checking out BRANCH (most importantly, when given a concrete
branch name, it checks the branch out, and does not detach at the
commit at the tip of the branch), because that is the first
preparatory step to rebase the BRANCH.




Re: [GSoC][PATCH v4 2/3] rebase -i: rewrite checkout_onto() in C

2018-06-26 Thread Junio C Hamano
Alban Gruin  writes:

> This rewrites checkout_onto() from shell to C. The new version is called
> detach_onto(), given its role.

The name, given its role, may be good, but is the implementtaion
robust enough to fulfill the promise its name gives?

>   git rebase--helper --check-todo-list || {
>   ret=$?
> - checkout_onto
> + git rebase--helper --detach-onto "$onto_name" "$onto" \
> + "$orig_head" ${verbose:+--verbose}

Here, $onto_name is what the end-user gave us (e.g. it is
"master..." in "git rebase --onto=master... base"), while $onto is a
40-hex object name of the commit.  $orig_head is also a 40-hex
object name.

And this call shows how the above shell scriptlet calls into the
detach_onto() thing ...

> + if (command == DETACH_ONTO && argc == 4)
> + return !!detach_onto(&opts, argv[1], argv[2], argv[3], verbose);

... which is defined like so:

> +int detach_onto(struct replay_opts *opts,
> + const char *onto_name, const char *onto,
> + const char *orig_head, unsigned verbose)
> +{
> + struct object_id oid;
> + const char *action = reflog_message(opts, "start", "checkout %s", 
> onto_name);
> +
> + if (get_oid(orig_head, &oid))
> + return error(_("%s: not a valid OID"), orig_head);

Which means that this can be more strict to use get_oid_hex() to
catch possible mistakes in the caller.

> + if (run_git_checkout(opts, onto, verbose, action)) {

And this could be a bit problematic, as we can see below how the
"checkout" thing does not guarantee "detaching" at all ...

> + apply_autostash(opts);
> + sequencer_remove_state(opts);
> + return error(_("could not detach HEAD"));
> + }
> +
> + return update_ref(NULL, "ORIG_HEAD", &oid, NULL, 0, 
> UPDATE_REFS_MSG_ON_ERR);
> +}
> +

... which can be seen here ...

> +static int run_git_checkout(struct replay_opts *opts, const char *commit,
> + int verbose, const char *action)
> +{
> + struct child_process cmd = CHILD_PROCESS_INIT;
> +
> + cmd.git_cmd = 1;
> +
> + argv_array_push(&cmd.args, "checkout");
> + argv_array_push(&cmd.args, commit);
> + argv_array_pushf(&cmd.env_array, GIT_REFLOG_ACTION "=%s", action);
> +
> + if (verbose)
> + return run_command(&cmd);
> + else
> + return run_command_silent_on_success(&cmd);
> +}

This drives the external command "git checkout" with _any_ string
the caller passes in "commit".  If the variable happens to have
'master', for example, it would be "git checkout master" and if you
have a branch with that name, it will not detach but check out the
branch to build on it.  It is a caller's responsibility to give a
suitable "commit" if it wants to use this helper to detach.

So perhaps the caller of this function in detach_onto() should pass
"%s^0" or even do something like

struct object_id onto_oid;
char onto_hex[GIT_MAX_HEXSZ + 1];

if (get_oid(onto, &onto_oid) || oid_to_hex_r(onto_hex, &onto_oid))
return error(...);
if (run_git_checkout(opts, onto_hex, verbose, action)) {
...

to ensure that it keeps the promise its name gives.

I can hear "Oh, but it is a bug in the caller to give anything that
won't result in detaching in 'onto'" but that is not a valid excuse,
given that this _public_ function is called "detach_onto".  Making
sure detachment happens is its responsibility, not its callers'.

Or we could do a cop-out alternative of commenting the function in *.h
file to say "onto must be given as 40-hex", with a code to make sure
the caller really gave us a 40-hex and not a branch name.  That is a
less ideal but probably acceptable alternative.

>  static const char rescheduled_advice[] =
>  N_("Could not execute the todo command\n"
>  "\n"
> diff --git a/sequencer.h b/sequencer.h
> index 35730b13e..9f0ac5e75 100644
> --- a/sequencer.h
> +++ b/sequencer.h
> @@ -100,6 +100,10 @@ int update_head_with_reflog(const struct commit 
> *old_head,
>  void commit_post_rewrite(const struct commit *current_head,
>const struct object_id *new_head);
>  
> +int detach_onto(struct replay_opts *opts,
> + const char *onto_name, const char *onto,
> + const char *orig_head, unsigned verbose);
> +
>  #define SUMMARY_INITIAL_COMMIT   (1 << 0)
>  #define SUMMARY_SHOW_AUTHOR_DATE (1 << 1)
>  void print_commit_summary(const char *prefix, const struct object_id *oid,


Re: [BUG] url schemes should be case-insensitive

2018-06-26 Thread Junio C Hamano
Jeff King  writes:

>> > We seem to match url schemes case-sensitively:
>> >
>> >   $ git clone SSH://example.com/repo.git
>> >   Cloning into 'repo'...
>> >   fatal: Unable to find remote helper for 'SSH'
>> >
>> > whereas rfc3986 is clear that the scheme portion is case-insensitive.
>> > We probably ought to match at least our internal ones with strcasecmp.
>> 
>> That may break if somebody at DevToolGroup@$BIGCOMPANY got cute and
>> named their custom remote helper SSH:// that builds on top of the
>> normal ssh:// protocol with something extra and gave it to their
>> developers (and they named the http counterpart that has the same
>> extra HTTP://, of course).
>
> True, though I am on the fence whether that is a property worth
> maintaining. AFAIK it was not planned and is just a "this is how it
> happened to work" case that is (IMHO) doing the wrong thing.

FWIW, I fully agree with the assessment; sorry for not saying that
together with the devil's advocate comment to save a round-tip.

> It may also interact in a funny way with our allowed-protocol code, if
> "SSH" gets a pass as "ssh" under the default config, but actually runs
> the otherwise-disallowed git-remote-SSH (though one would _hope_ if you
> have such a git-remote-SSH that it behaves just like an ssh remote).

True.  I did not offhand recall how protocol whitelist matches the
protocol name with config, but transport.c::get_protocol_config()
seems to say that the  part of "protocol..allow" is case
sensitive, and we match known-safe (and known-unsafe "ext::")
protocols with strcmp() not strcasecmp().  We need to figure out the
implications of allowing SSH:// not to error out but pretending as
if it were ssh:// on those who have protocol.ssh.allow defined.

>> > We could probably also give an advise() message in the above output,
>> > suggesting that the problem is likely one of:
>> >
>> >   1. They misspelled the scheme.
>> >
>> >   2. They need to install the appropriate helper.
>> >
>> > This may be a good topic for somebody looking for low-hanging fruit to
>> > get involved in development (I'd maybe call it a #leftoverbits, but
>> > since I didn't start on it, I'm not sure if it counts as "left over" ;)).
>> [..]
>> It may probably be a good idea to do an advice, but I'd think
>> "Untable to find remote helper for 'SSH'" may be clear enough.  If
>> anything, perhaps saying "remote helper for 'SSH' protocol" would
>> make it even clear?  I dunno.
>
> I think it doesn't help much if the user does not know what a remote
> helper is, or why Git is looking for one.

True.  

$ git clone SSH://example.com/repo.git
fatal: unable to handle URL that begins with SSH://

would be clear enough, perhaps?  At least this line of change is a
small first step that would improve the situation without potential
to break anybody who has been abusing the case sensitivity loophole.



Re: [PATCH 10/29] t9001: fix broken "invoke hook" test

2018-06-26 Thread Jonathan Tan
> diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
> index e80eacbb1b..776769fe0d 100755
> --- a/t/t9001-send-email.sh
> +++ b/t/t9001-send-email.sh
> @@ -1966,11 +1966,11 @@ test_expect_success $PREREQ 'invoke hook' '
>  
>   # Verify error message when a patch is rejected by the hook
>   sed -e "s/add master/x/" ../0001-add-master.patch 
> >../another.patch &&
> - git send-email \
> + test_must_fail git send-email \
>   --from="Example " \
>   --to=nob...@example.com \
>   --smtp-server="$(pwd)/../fake.sendmail" \
> - ../another.patch 2>err
> + ../another.patch 2>err &&
>   test_i18ngrep "rejected by sendemail-validate hook" err

Thanks for catching this. Indeed, "git send-email" is supposed to fail
because the validate hook greps for the string "add master", which does
not exist in the e-mail to be sent. (Above this is a test that shows
that the same validate hook succeeds if the e-mail contains "add
master".) This looks correct to me.


Re: [PATCH v2 0/6] Restrict the usage of config_from_gitmodules to submodule-config

2018-06-26 Thread Brandon Williams
On 06/26, Antonio Ospite wrote:
> Hi,
> 
> this is version 2 of the series from
> https://public-inbox.org/git/20180622162656.19338-1-...@ao2.it/
> 
> The .gitmodules file is not meant for arbitrary configuration, it should
> be used only for submodules properties.
> 
> Plus, arbitrary git configuration should not be distributed with the
> repository, and .gitmodules might be a possible "vector" for that.
> 
> The series tries to alleviate both these issues by moving the
> 'config_from_gitmodules' function from config.[ch] to submodule-config.c
> and making it private.
> 
> This should discourage future code from using the function with
> arbitrary config callbacks which might turn .gitmodules into a mechanism
> to load arbitrary configuration stored in the repository.
> 
> Backward compatibility exceptions to the rules above are handled by
> ad-hoc helpers.
> 
> Finally (in patch 6) some duplication is removed by using
> 'config_from_gitmodules' to load the submodules configuration in
> 'repo_read_gitmodules'.
> 
> Changes since v1:
>   * Remove an extra space before an arrow operator in patch 2
>   * Fix a typo in the commit message of patch 3: s/fetchobjs/fetchjobs
>   * Add a note in the commit message of patch 6 about checking the
> worktree before loading .gitmodules
>   * Drop patch 7, it was meant as a cleanup but resulted in parsing the
> .gitmodules file twice

Thanks for making these changes, this version looks good to me!

-- 
Brandon Williams


Re: curious about wording in "man git-config", ENVIRONMENT

2018-06-26 Thread Robert P. J. Day
On Tue, 26 Jun 2018, Jeff King wrote:

> On Tue, Jun 26, 2018 at 06:18:26AM -0400, Robert P. J. Day wrote:
>
> >
> >   ENVIRONMENT
> > GIT_CONFIG
> >   Take the configuration from the given file instead of
> >   .git/config. Using the "--global" option forces this to
> >   ~/.gitconfig. Using the "--system" option forces this to
> >   $(prefix)/etc/gitconfig.
> >
> >   is the phrase "forces this to" really what you want to use here?
> > maybe i misunderstand what this option does, doesn't it simply mean
> > that it will use a different (specified) file from the default,
> > depending on the context (local, global, system)?
> >
> >   it just seems weird to say that the option "forces" the use of what
> > are clearly the default files. thoughts?
>
> I agree it's weird. I think it's trying to mean "behaves as if it
> was set to", but with the additional notion that the command-line
> argument would take precedence over the environment (which is our
> usual rule). But then we should just say those things explicitly.
>
> Just looking at mentions of GIT_CONFIG in that manpage and knowing
> the history, I think:

  ... snip ...

i'm just going to admit that i don't quite have the background to know
how to submit a patch to tidy things up based on Jeff's analysis, so
I'm going to leave this to someone higher up the food chain.

rday

-- 


Robert P. J. Day Ottawa, Ontario, CANADA
  http://crashcourse.ca/dokuwiki

Twitter:   http://twitter.com/rpjday
LinkedIn:   http://ca.linkedin.com/in/rpjday



Re: [PATCH v3 0/7] grep.c: teach --column to 'git-grep(1)'

2018-06-26 Thread Junio C Hamano
Taylor Blau  writes:

> On Mon, Jun 25, 2018 at 02:43:50PM -0400, Jeff King wrote:
>> On Fri, Jun 22, 2018 at 10:49:26AM -0500, Taylor Blau wrote:
>> > Since the last time, only a couple of things have changed at Peff's
>> > suggestions in [1]. The changes are summarized here, and an inter-diff
>> > is available below:
>> >
>> >   - Change "%zu" to PRIuMAX (and an appropriate cast into uintmax_t). I
>> > plan to send a follow-up patch to convert this back to "%zu" to see
>> > how people feel about it, but I wanted to keep that out of the
>> > present series in order to not hold things up.
>> ...
>> Jinxes aside, this interdiff looks good to me.
>
> Thanks; I hope that I haven't jinxed anything :-).
>
> I'm going to avoid sending the PRIuMAX -> "%zu" patch, since dscho
> points out that it's not available on Windows [1].

OK, so what I queued on 'pu' seems to be ready to advance, which is
good.  Keeping topics in flight on 'pu', unable to convince myself
that they are ready to advance to 'next', makes me feel uneasy and
unhappy, and having to worry about one less such topic is a good
news ;-)



Re: [PATCH 4/5] commit-graph: store graph in struct object_store

2018-06-26 Thread Junio C Hamano
Jonathan Tan  writes:

> As for whether both these functions are necessary in the first place, I
> think they are.

I do not mind their existence.  

I was wondering if they can share more implementation; such a design
would need s/the_commit_graph/the_repo->objstore->commit_graph/ only
once as a side effect.



[GSoC][PATCH v3 0/2] rebase -i: rewrite the edit-todo functionality in C

2018-06-26 Thread Alban Gruin
This patch rewrites the edit-todo functionality from shell to C. This is
part of the effort to rewrite interactive rebase in C.

This patch is based on the fourth iteration of my series rewriting
append_todo_help() in C.

Changes since v2:

 - Moving edit_todo() from sequencer.c to interactive-rebase.c.

Alban Gruin (2):
  editor: add a function to launch the sequence editor
  rebase-interactive: rewrite the edit-todo functionality in C

 builtin/rebase--helper.c   | 13 -
 cache.h|  1 +
 editor.c   | 27 +--
 git-rebase--interactive.sh | 11 +--
 rebase-interactive.c   | 31 +++
 rebase-interactive.h   |  1 +
 strbuf.h   |  2 ++
 7 files changed, 69 insertions(+), 17 deletions(-)

-- 
2.18.0



[GSoC][PATCH v3 1/2] editor: add a function to launch the sequence editor

2018-06-26 Thread Alban Gruin
As part of the rewrite of interactive rebase, the sequencer will need to
open the sequence editor to allow the user to edit the todo list.
Instead of duplicating the existing launch_editor() function, this
refactors it to a new function, launch_specified_editor(), which takes
the editor as a parameter, in addition to the path, the buffer and the
environment variables.  launch_sequence_editor() is then added to launch
the sequence editor.

Signed-off-by: Alban Gruin 
---
 cache.h  |  1 +
 editor.c | 27 +--
 strbuf.h |  2 ++
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/cache.h b/cache.h
index 8b447652a..d70ae49ca 100644
--- a/cache.h
+++ b/cache.h
@@ -1409,6 +1409,7 @@ extern const char *fmt_name(const char *name, const char 
*email);
 extern const char *ident_default_name(void);
 extern const char *ident_default_email(void);
 extern const char *git_editor(void);
+extern const char *git_sequence_editor(void);
 extern const char *git_pager(int stdout_is_tty);
 extern int is_terminal_dumb(void);
 extern int git_ident_config(const char *, const char *, void *);
diff --git a/editor.c b/editor.c
index 9a9b4e12d..c985eee1f 100644
--- a/editor.c
+++ b/editor.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "config.h"
 #include "strbuf.h"
 #include "run-command.h"
 #include "sigchain.h"
@@ -34,10 +35,21 @@ const char *git_editor(void)
return editor;
 }
 
-int launch_editor(const char *path, struct strbuf *buffer, const char *const 
*env)
+const char *git_sequence_editor(void)
 {
-   const char *editor = git_editor();
+   const char *editor = getenv("GIT_SEQUENCE_EDITOR");
+
+   if (!editor)
+   git_config_get_string_const("sequence.editor", &editor);
+   if (!editor)
+   editor = git_editor();
 
+   return editor;
+}
+
+static int launch_specified_editor(const char *editor, const char *path,
+  struct strbuf *buffer, const char *const 
*env)
+{
if (!editor)
return error("Terminal is dumb, but EDITOR unset");
 
@@ -95,3 +107,14 @@ int launch_editor(const char *path, struct strbuf *buffer, 
const char *const *en
return error_errno("could not read file '%s'", path);
return 0;
 }
+
+int launch_editor(const char *path, struct strbuf *buffer, const char *const 
*env)
+{
+   return launch_specified_editor(git_editor(), path, buffer, env);
+}
+
+int launch_sequence_editor(const char *path, struct strbuf *buffer,
+  const char *const *env)
+{
+   return launch_specified_editor(git_sequence_editor(), path, buffer, 
env);
+}
diff --git a/strbuf.h b/strbuf.h
index 60a35aef1..66da9822f 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -575,6 +575,8 @@ extern void strbuf_add_unique_abbrev(struct strbuf *sb,
  * file's contents are not read into the buffer upon completion.
  */
 extern int launch_editor(const char *path, struct strbuf *buffer, const char 
*const *env);
+extern int launch_sequence_editor(const char *path, struct strbuf *buffer,
+ const char *const *env);
 
 extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char 
*buf, size_t size);
 
-- 
2.18.0



[GSoC][PATCH v3 2/2] rebase-interactive: rewrite the edit-todo functionality in C

2018-06-26 Thread Alban Gruin
This rewrites the edit-todo functionality from shell to C.

To achieve that, a new command mode, `edit-todo`, is added, and the
`write-edit-todo` flag is removed, as the shell script does not need to
write the edit todo help message to the todo list anymore.

The shell version is then stripped in favour of a call to the helper.

Signed-off-by: Alban Gruin 
---
 builtin/rebase--helper.c   | 13 -
 git-rebase--interactive.sh | 11 +--
 rebase-interactive.c   | 31 +++
 rebase-interactive.h   |  1 +
 4 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c
index 05e73e71d..731a64971 100644
--- a/builtin/rebase--helper.c
+++ b/builtin/rebase--helper.c
@@ -13,12 +13,12 @@ static const char * const builtin_rebase_helper_usage[] = {
 int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
 {
struct replay_opts opts = REPLAY_OPTS_INIT;
-   unsigned flags = 0, keep_empty = 0, rebase_merges = 0, write_edit_todo 
= 0;
+   unsigned flags = 0, keep_empty = 0, rebase_merges = 0;
int abbreviate_commands = 0, rebase_cousins = -1;
enum {
CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS,
CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH,
-   ADD_EXEC, APPEND_TODO_HELP
+   ADD_EXEC, APPEND_TODO_HELP, EDIT_TODO
} command = 0;
struct option options[] = {
OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
@@ -28,8 +28,6 @@ int cmd_rebase__helper(int argc, const char **argv, const 
char *prefix)
OPT_BOOL(0, "rebase-merges", &rebase_merges, N_("rebase merge 
commits")),
OPT_BOOL(0, "rebase-cousins", &rebase_cousins,
 N_("keep original branch points of cousins")),
-   OPT_BOOL(0, "write-edit-todo", &write_edit_todo,
-N_("append the edit-todo message to the todo-list")),
OPT_CMDMODE(0, "continue", &command, N_("continue rebase"),
CONTINUE),
OPT_CMDMODE(0, "abort", &command, N_("abort rebase"),
@@ -50,6 +48,9 @@ int cmd_rebase__helper(int argc, const char **argv, const 
char *prefix)
N_("insert exec commands in todo list"), ADD_EXEC),
OPT_CMDMODE(0, "append-todo-help", &command,
N_("insert the help in the todo list"), 
APPEND_TODO_HELP),
+   OPT_CMDMODE(0, "edit-todo", &command,
+   N_("edit the todo list during an interactive 
rebase"),
+   EDIT_TODO),
OPT_END()
};
 
@@ -90,6 +91,8 @@ int cmd_rebase__helper(int argc, const char **argv, const 
char *prefix)
if (command == ADD_EXEC && argc == 2)
return !!sequencer_add_exec_commands(argv[1]);
if (command == APPEND_TODO_HELP && argc == 1)
-   return !!append_todo_help(write_edit_todo, keep_empty);
+   return !!append_todo_help(0, keep_empty);
+   if (command == EDIT_TODO && argc == 1)
+   return !!edit_todo_list(flags);
usage_with_options(builtin_rebase_helper_usage, options);
 }
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 94c23a7af..2defe607f 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -108,16 +108,7 @@ initiate_action () {
 --continue
;;
edit-todo)
-   git stripspace --strip-comments <"$todo" >"$todo".new
-   mv -f "$todo".new "$todo"
-   collapse_todo_ids
-   git rebase--helper --append-todo-help --write-edit-todo
-
-   git_sequence_editor "$todo" ||
-   die "$(gettext "Could not execute editor")"
-   expand_todo_ids
-
-   exit
+   exec git rebase--helper --edit-todo
;;
show-current-patch)
exec git show REBASE_HEAD --
diff --git a/rebase-interactive.c b/rebase-interactive.c
index c79c819b9..ace8e095b 100644
--- a/rebase-interactive.c
+++ b/rebase-interactive.c
@@ -66,3 +66,34 @@ int append_todo_help(unsigned edit_todo, unsigned keep_empty)
 
return ret;
 }
+
+int edit_todo_list(unsigned flags)
+{
+   struct strbuf buf = STRBUF_INIT;
+   const char *todo_file = rebase_path_todo();
+   FILE *todo;
+
+   if (strbuf_read_file(&buf, todo_file, 0) < 0)
+   return error_errno(_("could not read '%s'."), todo_file);
+
+   strbuf_stripspace(&buf, 1);
+   todo = fopen_or_warn(todo_file, "w");
+   if (!todo) {
+   strbuf_release(&buf);
+   return 1;
+   }
+
+   strbuf_write(&buf, todo);
+   fclose(todo);
+   strbuf_release(&buf);
+
+   transform_todos(flags | TODO_LIST_SHORTEN_IDS);
+   ap

[GSoC][PATCH v4 2/2] rebase--interactive: rewrite append_todo_help() in C

2018-06-26 Thread Alban Gruin
This rewrites append_todo_help() from shell to C. It also incorporates
some parts of initiate_action() and complete_action() that also write
help texts to the todo file.

This also introduces the source file rebase-interactive.c. This file
will contain functions necessary for interactive rebase that are too
specific for the sequencer, and is part of libgit.a.

Two flags are added to rebase--helper.c: one to call
append_todo_help() (`--append-todo-help`), and another one to tell
append_todo_help() to write the help text suited for the edit-todo
mode (`--write-edit-todo`).

Finally, append_todo_help() is removed from git-rebase--interactive.sh
to use `rebase--helper --append-todo-help` instead.

Signed-off-by: Alban Gruin 
---
 Makefile   |  1 +
 builtin/rebase--helper.c   | 11 --
 git-rebase--interactive.sh | 52 ++---
 rebase-interactive.c   | 68 ++
 rebase-interactive.h   |  6 
 5 files changed, 86 insertions(+), 52 deletions(-)
 create mode 100644 rebase-interactive.c
 create mode 100644 rebase-interactive.h

diff --git a/Makefile b/Makefile
index 0cb6590f2..a281139ef 100644
--- a/Makefile
+++ b/Makefile
@@ -922,6 +922,7 @@ LIB_OBJS += protocol.o
 LIB_OBJS += quote.o
 LIB_OBJS += reachable.o
 LIB_OBJS += read-cache.o
+LIB_OBJS += rebase-interactive.o
 LIB_OBJS += reflog-walk.o
 LIB_OBJS += refs.o
 LIB_OBJS += refs/files-backend.o
diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c
index f7c2a5fdc..05e73e71d 100644
--- a/builtin/rebase--helper.c
+++ b/builtin/rebase--helper.c
@@ -3,6 +3,7 @@
 #include "config.h"
 #include "parse-options.h"
 #include "sequencer.h"
+#include "rebase-interactive.h"
 
 static const char * const builtin_rebase_helper_usage[] = {
N_("git rebase--helper []"),
@@ -12,12 +13,12 @@ static const char * const builtin_rebase_helper_usage[] = {
 int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
 {
struct replay_opts opts = REPLAY_OPTS_INIT;
-   unsigned flags = 0, keep_empty = 0, rebase_merges = 0;
+   unsigned flags = 0, keep_empty = 0, rebase_merges = 0, write_edit_todo 
= 0;
int abbreviate_commands = 0, rebase_cousins = -1;
enum {
CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS,
CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH,
-   ADD_EXEC
+   ADD_EXEC, APPEND_TODO_HELP
} command = 0;
struct option options[] = {
OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
@@ -27,6 +28,8 @@ int cmd_rebase__helper(int argc, const char **argv, const 
char *prefix)
OPT_BOOL(0, "rebase-merges", &rebase_merges, N_("rebase merge 
commits")),
OPT_BOOL(0, "rebase-cousins", &rebase_cousins,
 N_("keep original branch points of cousins")),
+   OPT_BOOL(0, "write-edit-todo", &write_edit_todo,
+N_("append the edit-todo message to the todo-list")),
OPT_CMDMODE(0, "continue", &command, N_("continue rebase"),
CONTINUE),
OPT_CMDMODE(0, "abort", &command, N_("abort rebase"),
@@ -45,6 +48,8 @@ int cmd_rebase__helper(int argc, const char **argv, const 
char *prefix)
N_("rearrange fixup/squash lines"), REARRANGE_SQUASH),
OPT_CMDMODE(0, "add-exec-commands", &command,
N_("insert exec commands in todo list"), ADD_EXEC),
+   OPT_CMDMODE(0, "append-todo-help", &command,
+   N_("insert the help in the todo list"), 
APPEND_TODO_HELP),
OPT_END()
};
 
@@ -84,5 +89,7 @@ int cmd_rebase__helper(int argc, const char **argv, const 
char *prefix)
return !!rearrange_squash();
if (command == ADD_EXEC && argc == 2)
return !!sequencer_add_exec_commands(argv[1]);
+   if (command == APPEND_TODO_HELP && argc == 1)
+   return !!append_todo_help(write_edit_todo, keep_empty);
usage_with_options(builtin_rebase_helper_usage, options);
 }
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 299ded213..94c23a7af 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -39,38 +39,6 @@ comment_for_reflog () {
esac
 }
 
-append_todo_help () {
-   gettext "
-Commands:
-p, pick  = use commit
-r, reword  = use commit, but edit the commit message
-e, edit  = use commit, but stop for amending
-s, squash  = use commit, but meld into previous commit
-f, fixup  = like \"squash\", but discard this commit's log message
-x, exec  = run command (the rest of the line) using shell
-d, drop  = remove commit
-l, label  = label current HEAD with a name
-t, reset  = reset HEAD to a label
-m, merge [-C  | -c ]  [# ]
-.   create a merge commit using the original merge commit's
-.   messa

[GSoC][PATCH v4 1/2] sequencer: make two functions and an enum from sequencer.c public

2018-06-26 Thread Alban Gruin
This makes rebase_path_todo(), get_missign_commit_check_level() and the
enum check_level accessible outside sequencer.c.  This will be needed
for the rewrite of append_todo_help() from shell to C, as it will be in
a new library source file, rebase-interactive.c.

Signed-off-by: Alban Gruin 
---
 sequencer.c | 8 ++--
 sequencer.h | 6 ++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index 0a291c91f..881a4f7f4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -52,7 +52,7 @@ static GIT_PATH_FUNC(rebase_path, "rebase-merge")
  * the lines are processed, they are removed from the front of this
  * file and written to the tail of 'done'.
  */
-static GIT_PATH_FUNC(rebase_path_todo, "rebase-merge/git-rebase-todo")
+GIT_PATH_FUNC(rebase_path_todo, "rebase-merge/git-rebase-todo")
 /*
  * The rebase command lines that have already been processed. A line
  * is moved here when it is first handled, before any associated user
@@ -4223,11 +4223,7 @@ int transform_todos(unsigned flags)
return i;
 }
 
-enum check_level {
-   CHECK_IGNORE = 0, CHECK_WARN, CHECK_ERROR
-};
-
-static enum check_level get_missing_commit_check_level(void)
+enum check_level get_missing_commit_check_level(void)
 {
const char *value;
 
diff --git a/sequencer.h b/sequencer.h
index c5787c6b5..08397b0d1 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -3,6 +3,7 @@
 
 const char *git_path_commit_editmsg(void);
 const char *git_path_seq_dir(void);
+const char *rebase_path_todo(void);
 
 #define APPEND_SIGNOFF_DEDUP (1u << 0)
 
@@ -57,6 +58,10 @@ struct replay_opts {
 };
 #define REPLAY_OPTS_INIT { .action = -1, .current_fixups = STRBUF_INIT }
 
+enum check_level {
+   CHECK_IGNORE = 0, CHECK_WARN, CHECK_ERROR
+};
+
 /* Call this to setup defaults before parsing command line options */
 void sequencer_init_config(struct replay_opts *opts);
 int sequencer_pick_revisions(struct replay_opts *opts);
@@ -79,6 +84,7 @@ int sequencer_make_script(FILE *out, int argc, const char 
**argv,
 
 int sequencer_add_exec_commands(const char *command);
 int transform_todos(unsigned flags);
+enum check_level get_missing_commit_check_level(void);
 int check_todo_list(void);
 int skip_unnecessary_picks(void);
 int rearrange_squash(void);
-- 
2.18.0



[GSoC][PATCH v4 0/2] rebase -i: rewrite append_todo_help() in C

2018-06-26 Thread Alban Gruin
This patch rewrites append_todo_help() from shell to C. The C version
covers a bit more than the old shell version. To achieve that, some
parameters were added to rebase--helper.

This also introduce a new source file, rebase-interactive.c.

This is part of the effort to rewrite interactive rebase in C.

This is based on next, as of 2018-06-26.

Changes since v3:

 - Show an error message when append_todo_help() fails to edit the todo
   list.

 - Introducing rebase-interactive.c to contain functions necessary for
   interactive rebase.

Alban Gruin (2):
  sequencer: make two functions and an enum from sequencer.c public
  rebase--interactive: rewrite append_todo_help() in C

 Makefile   |  1 +
 builtin/rebase--helper.c   | 11 --
 git-rebase--interactive.sh | 52 ++---
 rebase-interactive.c   | 68 ++
 rebase-interactive.h   |  6 
 sequencer.c|  8 ++---
 sequencer.h|  6 
 7 files changed, 94 insertions(+), 58 deletions(-)
 create mode 100644 rebase-interactive.c
 create mode 100644 rebase-interactive.h

-- 
2.18.0



Re: [RFC PATCH v5] Implement --first-parent for git rev-list --bisect

2018-06-26 Thread Christian Couder
Hi Dscho,

On Tue, Jun 26, 2018 at 4:10 PM, Johannes Schindelin
 wrote:
>
> On Tue, 26 Jun 2018, Christian Couder wrote:
>
>> On Mon, Jun 25, 2018 at 7:33 PM, Junio C Hamano  wrote:
>>
>> > I hate to say this, but the above looks like a typical
>> > unmaintainable mess.
>> >
>> > What happens when you or somebody else later needs to update the
>> > graph to be tested to add one more commit (or even more)?  Would it
>> > be enough to add another "rev-parse" plus "dist=X" line in both
>> > expects?  Or do we see a trap for combinatorial explosion that
>> > requires us to add new expect$N?
>>
>> What about the following then:
>>
>> test_dist_order () {
>> file="$1"
>> n="$2"
>> while read -r hash dist
>> do
>> d=$(echo "$dist" | sed -e "s/(dist=\(.*\))/\1/")
>> case "$d" in
>> ''|*[!0-9]*) return 1 ;;
>> *) ;;
>> esac
>> test "$d" -le "$n" || return 1
>> n="$d"
>> done <"$file"
>> }
>>
>> test_expect_success "--bisect-all --first-parent" '
>> cat >expect <> $(git rev-parse CC) (dist=2)
>> $(git rev-parse EX) (dist=1)
>> $(git rev-parse D) (dist=1)
>> $(git rev-parse FX) (dist=0)
>> EOF
>> sort expect >expect_sorted &&
>> git rev-list --bisect-all --first-parent FX ^A >actual &&
>> sort actual >actual_sorted &&
>> test_cmp expect_sorted actual_sorted &&
>> test_dist_order actual 2
>> '
>>
>> This feels overkill to me, but it should scale if we ever make more
>> complex tests.
>
> I *think* that you misunderstand Junio. At least when I read this:
>
>> $(git rev-parse CC) (dist=2)
>> $(git rev-parse EX) (dist=1)
>> $(git rev-parse D) (dist=1)
>> $(git rev-parse FX) (dist=0)
>
> I go: Huh?!?!?!?!?!
>
> What's CC? Is it Christian Couder? Creative Commons? Crudely Complex?

I agree that the name of the commit could be improved.

> The point, for me, is: if this test fails, at some stage in the future,
> for any reason, it will be a major pain to even dissect what the test is
> supposed to do.

I think the test is quite simple and there is an ascii picture, so it
is not so difficult to understand.

> This is no good. And you can do better. A lot better. You
> can write the test in a way that the head of a reader does not hurt, and
> at the same time it is still obvious what it does, and obvious that it
> does the right thing.

Obviousness is often not the same for everybody.

> One thing that makes the brain stumble for certain is when you deviate
> from the conventions, especially when it is for no good reason at all. In
> this case (and I am not sure why you, as a long-time contributor, did not
> spot this before public review):

Please note that I never committed myself (like most of us who are not
maintainer actually) to reviewing everything bisect related (or
everything that Tiago works on).

> - the titles of the test cases leave a lot of room for improvement,
>
> - the lines are too long,
>
> - the convention to end the `test_expect_success` line with an opening
>   single quote is not heeded,

If you take a look at the beginning of the script you will see that
there are those problems there too.

I know that we should try to do better, but here I am mostly
interested in moving forward a feature that people have requested for
ages, not cleaning up those tests. If someone else like you or Junio
thinks that it would be a good time to clean things up a bit, then I
am ok with it, but that's not my main goal here.

> - the graph is definitely written in an unnecessarily different format
>   than in the same test script!!!

Just above you complain about things that are similar to the previous
tests and now you complain about things that are different...

> - speaking of the graph: there is a perfectly fine commit graph already.
>   Why on earth is it not reused?

Perhaps because it is more complex than needed to test this feature
and/or to understand what happens. And I don't think we require
everywhere only one commit graph per test script.

> In this particular case it even feels as if this test is not even testing
> what it should test at all:
>
> - it should verify that all of the commits in the first parent lineage are
>   part of the list

It does that.

> - it should verify that none of the other commits are in the list

It does that too.

> And that is really all there is to test.

I don't agree. I think that when possible, especially when testing
plumbing commands like rev-list, it is a good thing to test as many
things as possible at once.

> You can even write that in a much
> easier way:
>
> -- snip --
> test_expect_success '--first-parent --bisect-all lists correct revs' '
> git rev-list --first-parent --bisect-all F..E >revs &&
> # E and e1..e8 need to be shown, F and f1..f4 not
> test_line_count = 9 revs &&
> for rev in E e1 e2 e3 e4 e5 e6 e7 e8
> do
> grep "^$(git rev-parse $rev) " revs || {
> echo "$rev not shown"

Re: [PATCH 00/29] t: detect and fix broken &&-chains in subshells

2018-06-26 Thread Elijah Newren
Hi Eric,

On Tue, Jun 26, 2018, 2:31 AM Eric Sunshine  wrote:
>
> On Tue, Jun 26, 2018 at 5:20 AM Elijah Newren  wrote:
> > On Tue, Jun 26, 2018 at 12:29 AM, Eric Sunshine  
> > wrote:
> > > Aside from identifying a rather significant number of &&-chain breaks,
> > > repairing those broken chains uncovered genuine bugs in several tests
> > > which were hidden by missing &&-chain links. Those bugs are also fixed
> > > by this series. I would appreciate if the following people would
> > > double-check my fixes:
> > >
> > > Stefan Bellar - 8/29 "t7400" and (especially) 13/29 "lib-submodule-update"
> > > Jonathan Tan - 10/29 "t9001"
> > > Elijah Newren - 6/29 "t6036"
> >
> > Commented on the patch in question; 6/29 looks good.
> >
> > I also looked over the rest of the series.  Apart from the ones you
> > specifically called out as needing review by others besides me, and
> > the final patch which makes me feel like a sed neophyte, all but one
> > patch looked good to me.  I just have a small question for that
> > remaining patch, which I posted there.
>
> I guess you refer to your question[1] about whether test_must_fail()
> is the correct choice over test_expect_code(). I just responded[2]
> with a hopefully satisfactory answer.

Yes, it does.  Thanks!


Re: [RFC PATCH v5] Implement --first-parent for git rev-list --bisect

2018-06-26 Thread Johannes Schindelin
Hi Chris,

On Tue, 26 Jun 2018, Christian Couder wrote:

> On Mon, Jun 25, 2018 at 7:33 PM, Junio C Hamano  wrote:
> > Tiago Botelho  writes:
> >
> >> +test_expect_success "--bisect-all --first-parent" '
> >> +cat >expect1 < >> +$(git rev-parse CC) (dist=2)
> >> +$(git rev-parse EX) (dist=1)
> >> +$(git rev-parse D) (dist=1)
> >> +$(git rev-parse FX) (dist=0)
> >> +EOF
> >> +
> >> +cat >expect2 < >> +$(git rev-parse CC) (dist=2)
> >> +$(git rev-parse D) (dist=1)
> >> +$(git rev-parse EX) (dist=1)
> >> +$(git rev-parse FX) (dist=0)
> >> +EOF
> >> +
> >> +git rev-list --bisect-all --first-parent FX ^A >actual &&
> >> +  ( test_cmp expect1 actual || test_cmp expect2 actual )
> >> +'
> >
> > I hate to say this, but the above looks like a typical
> > unmaintainable mess.
> >
> > What happens when you or somebody else later needs to update the
> > graph to be tested to add one more commit (or even more)?  Would it
> > be enough to add another "rev-parse" plus "dist=X" line in both
> > expects?  Or do we see a trap for combinatorial explosion that
> > requires us to add new expect$N?
> 
> What about the following then:
> 
> test_dist_order () {
> file="$1"
> n="$2"
> while read -r hash dist
> do
> d=$(echo "$dist" | sed -e "s/(dist=\(.*\))/\1/")
> case "$d" in
> ''|*[!0-9]*) return 1 ;;
> *) ;;
> esac
> test "$d" -le "$n" || return 1
> n="$d"
> done <"$file"
> }
> 
> test_expect_success "--bisect-all --first-parent" '
> cat >expect < $(git rev-parse CC) (dist=2)
> $(git rev-parse EX) (dist=1)
> $(git rev-parse D) (dist=1)
> $(git rev-parse FX) (dist=0)
> EOF
> sort expect >expect_sorted &&
> git rev-list --bisect-all --first-parent FX ^A >actual &&
> sort actual >actual_sorted &&
> test_cmp expect_sorted actual_sorted &&
> test_dist_order actual 2
> '
> 
> This feels overkill to me, but it should scale if we ever make more
> complex tests.

I *think* that you misunderstand Junio. At least when I read this:

> $(git rev-parse CC) (dist=2)
> $(git rev-parse EX) (dist=1)
> $(git rev-parse D) (dist=1)
> $(git rev-parse FX) (dist=0)

I go: Huh?!?!?!?!?!

What's CC? Is it Christian Couder? Creative Commons? Crudely Complex?

The point, for me, is: if this test fails, at some stage in the future,
for any reason, it will be a major pain to even dissect what the test is
supposed to do. This is no good. And you can do better. A lot better. You
can write the test in a way that the head of a reader does not hurt, and
at the same time it is still obvious what it does, and obvious that it
does the right thing.

One thing that makes the brain stumble for certain is when you deviate
from the conventions, especially when it is for no good reason at all. In
this case (and I am not sure why you, as a long-time contributor, did not
spot this before public review):

- the titles of the test cases leave a lot of room for improvement,

- the lines are too long,

- the convention to end the `test_expect_success` line with an opening
  single quote is not heeded,

- the graph is definitely written in an unnecessarily different format
  than in the same test script!!!

- speaking of the graph: there is a perfectly fine commit graph already.
  Why on earth is it not reused?

In this particular case it even feels as if this test is not even testing
what it should test at all:

- it should verify that all of the commits in the first parent lineage are
  part of the list

- it should verify that none of the other commits are in the list

And that is really all there is to test. You can even write that in a much
easier way:

-- snip --
test_expect_success '--first-parent --bisect-all lists correct revs' '
git rev-list --first-parent --bisect-all F..E >revs &&
# E and e1..e8 need to be shown, F and f1..f4 not
test_line_count = 9 revs &&
for rev in E e1 e2 e3 e4 e5 e6 e7 e8
do
grep "^$(git rev-parse $rev) " revs || {
echo "$rev not shown" >&2 &&
return 1
}
done
'
-- snap --

To test more precisely for the order or the distance would be both
overkill and likely to be unreadable.

To test `--bisect-vars` here would be excessive, as the part that handles
that particular option is not even touched. All that is touched is the
logic in the bisect algorithm in conjunction with --first-parent. And that
is all that should be tested here.

With a test like the one I outlined above, I only have one more gripe
about the patch: the commit message does nothing to explain this part of
the diff:

+   if ((bisect_flags & BISECT_FIRST_PARENT)) {
+   if (weight(q) < 0)
+   q = NULL;
+   break;
+   }

And I would really, really like that to be explained in the comm

git rerere and diff3

2018-06-26 Thread Nicolas Dechesne
hi there,

i have noticed that merge.conflictstyle has an impact on the rerere
resolution. looking briefly at the source code, it seems that git
tries to discard the common ancestor diff3 bits, but what I am seeing
is that if i do the following then it fails:

1. from a clean rr-cache state, with merge.conflictsytle=diff3, git
merge , resolve the conflicts, then commit
2. undo the previous merge, remove merge.conflictstyle=diff3 (disable
diff3) and merge the *same* branch, then rerere won't fix the
conflicts

Is that the expected behavior? I am not familiar with git code, but
browsing rerere.c makes me think that it should have worked..

Of course, if I merge the same branch without modifying
merge.conflictstyle, then the merge conflicts are properly resolved by
rerere.

thanks!


Re: [GSoC][PATCH 1/1] sequencer: print an error message if append_todo_help() fails

2018-06-26 Thread Johannes Schindelin
Hi Alban,

On Tue, 26 Jun 2018, Alban Gruin wrote:

> This adds an error when append_todo_help() fails to write its message to
> the todo file.
> 
> Signed-off-by: Alban Gruin 

ACK.

We *may* want to fold that into the commit that adds `append_todo_help()`.
And, as I mentioned previously, I would love for that function to be used
as an excuse to introduce the long-overdue `interactive-rebase.c`
(`sequencer.c` is supposed to be the backend for cherry-pick and revert
and interactive rebase, but not a catch-all for *all* of those things, it
is already way too long to be readable, and I take blame for a large part
of that.)

Ciao,
Dscho


Re: curious about wording in "man git-config", ENVIRONMENT

2018-06-26 Thread Jeff King
On Tue, Jun 26, 2018 at 06:18:26AM -0400, Robert P. J. Day wrote:

> 
>   ENVIRONMENT
> GIT_CONFIG
>   Take the configuration from the given file instead of
>   .git/config. Using the "--global" option forces this to
>   ~/.gitconfig. Using the "--system" option forces this to
>   $(prefix)/etc/gitconfig.
> 
>   is the phrase "forces this to" really what you want to use here?
> maybe i misunderstand what this option does, doesn't it simply mean
> that it will use a different (specified) file from the default,
> depending on the context (local, global, system)?
> 
>   it just seems weird to say that the option "forces" the use of what
> are clearly the default files. thoughts?

I agree it's weird. I think it's trying to mean "behaves as if it was
set to", but with the additional notion that the command-line argument
would take precedence over the environment (which is our usual rule).
But then we should just say those things explicitly.

Just looking at mentions of GIT_CONFIG in that manpage and knowing the
history, I think:

 - the environment section should say something like:

 GIT_CONFIG
   If set and no other specific-file options are given, behaves as
   if `--file=$GIT_CONFIG` was provided on the command-line.

 - possibly the manpage should mention that GIT_CONFIG is historical and
   should not be used in new code (we could also consider an actual
   deprecation period and removal of the feature, though aside from
   documentation confusion I do not think it is hurting anyone)

 - the description of --file should not mention it at all. Instead it
   should reference the "FILES" section which describes the whole lookup
   sequence

 - mention of GIT_CONFIG should be dropped from the FILES section. We
   don't want to point people towards using it. And if they come across
   it in the wild, they can find it in the ENVIRONMENT section.

 - references to "--global" should stop mentioning ~/.gitconfig,
   since in a post-XDG world it could be elsewhere (they're better to
   refer to the "--global" description or the FILES section)

 - references to "--system" should stop mentioning $(prefix)/etc/gitconfig,
   since it can be configured separately from the prefix (and in most
   packaged builds which set prefix=/usr, $(sysconfdir) is not
   $(prefix)/etc).

-Peff


  1   2   >