Re: [PATCH 2/2] completion: simplify ls-files filter

2018-03-17 Thread Junio C Hamano
SZEDER Gábor  writes:

> First, neither 'git ls-files' nor 'git diff-index' produce quite the
> same order as the 'sort' utility does, e.g.:
>
>   $ touch foo.c foo-zzz.c
>   $ git add foo*
>   $ git diff-index --name-only HEAD
>   foo-zzz.c
>   foo.c
>   $ git diff-index --name-only HEAD |sort
>   foo.c
>   foo-zzz.c

Doesn't this depend on your locale?

$ printf "foo%s\n" .c -zzz.c /c | LC_ALL=C sort
foo-zzz.c
foo.c
foo/c

$ printf "foo%s\n" .c -zzz.c /c | LC_ALL=en_US.UTF-8 sort
foo/c
foo.c
foo-zzz.c

> Second, the output of 'git ls-files' is kind of "block-sorted": if you
> were to invoke it with the options '--cached --modified --others',
> then it will first list all untracked files in order, then all cached
> files in order, and finally all modified files in order.

This is a lot more important consideration.

> I have a short patch series collecting dust somewhere for a long
> while, which pulls a couple more tricks to make git-aware path
> completion faster, but haven't submitted it yet, because it doesn't
> work quite that well when filenames require quoting.  Though, arguably
> the current version doesn't work quite that well with quoted filenames
> either, so...
> Will try to dig up those patches.

Thanks.


Re: [PATCH v5 09/11] pack-objects: shrink size field in struct object_entry

2018-03-17 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy   writes:

> +static inline int contains_in_32bits(unsigned long limit)
> +{

This name somehow does not sound right.

If the verb "contain" must be used, the way to phrase what this
function does with the verb is to say "limit can be contained in a
32-bit int", so "contains" is probably where the funniness comes
from.

"fits in 32bits" is OK, I think.

> + uint32_t truncated_limit = (uint32_t)limit;
> +
> + return limit == truncated_limit;
> +}

I am guessing that a compiler that is clever enough will make this
function a no-op on a 32-bit arch and that is why it is a static
inline function?

> +static inline int oe_size_less_than(const struct object_entry *e,
> + unsigned long limit)
> +{
> + if (e->size_valid)
> + return e->size_ < limit;

e->size_ is the true size so we can compare it to see if it is smaller
than limit.

> + if (contains_in_32bits(limit))
> + return 1;

If limit is small enough, and because e->size_valid means e->size_
does not fit in 32-bit, we know size is larger than limit.
Shouldn't we be returning 0 that means "no, the size is not less
than limit" from here?

> + return oe_size(e) < limit;
> +}
> +
> +static inline int oe_size_greater_than(const struct object_entry *e,
> +unsigned long limit)
> +{
> + if (e->size_valid)
> + return e->size_ > limit;

e->size_ is the true size so we compare and return if it is larger
than limit.

> + if (contains_in_32bits(limit))
> + return 0;

Now e->size_ is larger than what would fit within 32-bit.  If limit
fits within 32-bit, then size must be larger than limit.  Again,
shouldn't we be returning 1 that means "yes, the size is greater
than limit" from here?

> + return oe_size(e) > limit;
> +}
> +
> +static inline void oe_set_size(struct object_entry *e,
> +unsigned long size)
> +{
> + e->size_ = size;
> + e->size_valid = e->size_ == size;
> +}
> +
>  #endif


[PATCH] completion: complete tags with git tag --delete/--verify

2018-03-17 Thread Todd Zullinger
Completion of tag names has worked for the short -d/-v options since
88e21dc746 ("Teach bash about completing arguments for git-tag",
2007-08-31).  The long options were not added to "git tag" until many
years later, in c97eff5a95 ("git-tag: introduce long forms for the
options", 2011-08-28).

Extend tag name completion to --delete/--verify.

Signed-off-by: Todd Zullinger 
---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 6da95b8095..c7957f0a90 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2967,7 +2967,7 @@ _git_tag ()
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
-   -d|-v)
+   -d|--delete|-v|--verify)
__gitcomp_direct "$(__git_tags "" "$cur" " ")"
return
;;
-- 
2.17.0.rc0



Re: [PATCH 34/36] t/helper: merge test-urlmatch-.. into test-tool

2018-03-17 Thread Eric Sunshine
On Sat, Mar 17, 2018 at 3:54 AM, Nguyễn Thái Ngọc Duy  wrote:
> t/helper: merge test-urlmatch-.. into test-tool

Spelled out fully:

t/helper: merge test-urlmatch-normalization into test-tool

needs only 58 columns, so is well within the 70-72 column
recommendation for summary line.

> Signed-off-by: Nguyễn Thái Ngọc Duy 


Re: [PATCH 22/36] t/helepr: merge test-read-cache into test-tool

2018-03-17 Thread Eric Sunshine
On Sat, Mar 17, 2018 at 3:54 AM, Nguyễn Thái Ngọc Duy  wrote:
> t/helepr: merge test-read-cache into test-tool

s/helepr/helper/

> Signed-off-by: Nguyễn Thái Ngọc Duy 


Re: [PATCH 04/36] t/helper: merge test-lazy-init-name-hash into test-tool

2018-03-17 Thread Eric Sunshine
On Sat, Mar 17, 2018 at 3:53 AM, Nguyễn Thái Ngọc Duy  wrote:
> diff --git a/cache.h b/cache.h
> @@ -333,7 +333,7 @@ struct index_state {
> -extern int test_lazy_init_name_hash(struct index_state *istate, int 
> try_threaded);
> +extern int lazy_init_name_hash_for_testing(struct index_state *istate, int 
> try_threaded);

I get why you renamed this since the "main" function in the test
program wants to be called 'test_lazy_init_name_hash'...

> diff --git a/t/helper/test-lazy-init-name-hash.c 
> b/t/helper/test-lazy-init-name-hash.c
> @@ -9,6 +10,9 @@ static int perf;
> +static int (*init_name_hash)(struct index_state *istate, int try_threaded) =
> +   lazy_init_name_hash_for_testing;
> +
> @@ -33,9 +37,9 @@ static void dump_run(void)
> if (single) {
> -   test_lazy_init_name_hash(_index, 0);
> +   init_name_hash(_index, 0);

... but I'm having trouble understanding why this indirection through
'init_name_hash' is used rather than just calling
lazy_init_name_hash_for_testing() directly. Am I missing something
obvious or is 'init_name_hash' just an unneeded artifact of an earlier
iteration before the rename in cache.{c,h}?


Re: [RFC PATCH] git-submodule.sh:cmd_update: if submodule branch exists, fetch that instead of default

2018-03-17 Thread Eric Sunshine
On Sat, Mar 17, 2018 at 3:11 PM, Thomas Gummerer  wrote:
> On 03/17, Eddy Petrișor wrote:
>> vin., 16 mar. 2018, 23:44 Eric Sunshine  a scris:
>> > It may be a disservice to remove mention of git-blame and git-shortlog
>> > since git-contacts may not be suitable for everyone. Instead, perhaps
>> > advertise git-contacts as a potentially simpler alternative to the
>> > already-mentioned git-blamd & git-shortlog?
>
> Not sure how much of a disservice it would be.  I think of
> SubmittingPatches as mostly a document for new git contributors, for
> who I think we should make it as easy as possible to start
> contributing.  Interpreting the output of 'git blame' and 'git
> shortlog' feels like an extra hurdle for new contributors, especially
> if someone is not familiar with the mailing list workflow.  I do
> remember wondering exactly how I should interpret this when I sent my
> first patches.

Okay. Mentioning those commands (in addition to git-contacts) is an
opportunity to educate newcomers to Git the tool (not just to git.git
the project) about additional ways to engage in project spelunking. By
"disservice", I meant that that educational opportunity is lost.
Eddy's suggestion of reversing the order, thus mentioning git-contacts
first is a good alternative.

However, perhaps this idea of educating newcomers to Git is misplaced
in this context; such spelunking advice may be better suited to a
general Git tutorial than to SubmittingPatches which is indeed
specific to git.git. Given that reasoning, then my "disservice" view
may be wrong.

>> > Also, would it make sense to mention Felipe's git-related[1] which is
>> > the original (and now more configurable) script from which
>> > git-contacts functionality was derived?
>
> The reason I chose 'git contacts' over git-related is mainly that it
> comes available with git.  Mentioning both again makes things harder
> on new contributors who already have enough to think about when
> submitting the patch.
>
> I guess in the end it comes down to who we think the target of the
> document is.  To me it was always people new to the project, which is
> why I think the single command there makes sense.

Fair enough.


Re: [PATCH 2/2] completion: simplify ls-files filter

2018-03-17 Thread SZEDER Gábor
> When filtering the ls-files output we take care not to touch absolute
> paths. This is redundant, because ls-files will never output absolute
> paths. Furthermore, sorting the output is also redundant, because the
> output of ls-files is already sorted.
> 
> Remove the unnecessary operations.

You didn't run the test suite, did you? ;)

First, neither 'git ls-files' nor 'git diff-index' produce quite the
same order as the 'sort' utility does, e.g.:

  $ touch foo.c foo-zzz.c
  $ git add foo*
  $ git diff-index --name-only HEAD
  foo-zzz.c
  foo.c
  $ git diff-index --name-only HEAD |sort
  foo.c
  foo-zzz.c

Second, the output of 'git ls-files' is kind of "block-sorted": if you
were to invoke it with the options '--cached --modified --others',
then it will first list all untracked files in order, then all cached
files in order, and finally all modified files in order.  Note the
implications:

  - A file could theoretically be listed twice, because a modified
file is inherently cached as well.  I believe this doesn't happen
currently, because no path completions use the combination of
'--modified --cached', but we use a lot of options when completing
paths for 'git status', and I haven't thought that through.

  - A directory name is repeated in two (or more) blocks, if it
contains modified and untracked files as well.  We do use the
combination of '--modified --others' for 'git add', and '--cached
--others' for 'git mv', so this does happen.

Note also that there can be any number of other files between the same
directory listed in two different blocks.  That 'sort' that this patch
is about to remove took care of this, but without that 'sort' the same
directory name can be listed more than once even after 'uniq'.
Consequently, the subsequent filtering of paths matching the current
word to be completed might have twice as much work to do.

All this leads to the failure of an enormous test in t9902, hence my
rethorical question at the beginning of my reply.


I have a short patch series collecting dust somewhere for a long
while, which pulls a couple more tricks to make git-aware path
completion faster, but haven't submitted it yet, because it doesn't
work quite that well when filenames require quoting.  Though, arguably
the current version doesn't work quite that well with quoted filenames
either, so...
Will try to dig up those patches.


> Signed-off-by: Clemens Buchacher 
> ---
>  contrib/completion/git-completion.bash | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/contrib/completion/git-completion.bash 
> b/contrib/completion/git-completion.bash
> index e3ddf27..394c3df 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -384,7 +384,7 @@ __git_index_files ()
>   local root="${2-.}" file
>  
>   __git_ls_files_helper "$root" "$1" |
> - sed -e '/^\//! s#/.*##' | sort | uniq
> + cut -f1 -d/ | uniq
>  }
>  
>  # Lists branches from the local repository.
> -- 
> 2.7.4
> 
> 


Re: [PATCH v3 0/4] worktree: teach "add" to check out existing branches

2018-03-17 Thread Junio C Hamano
Thomas Gummerer  writes:

> Previous rounds are at <20180121120208.12760-1-t.gumme...@gmail.com>
> and <20180204221305.28300-1-t.gumme...@gmail.com>.  Thanks Duy, Eric
> and Junio for the comments on the previous round.
>
> Junio: I know it is the rc period right now, but the topic is also
> already queued in 'pu', so I wasn't sure if you prefer me submitting
> this now, or after 2.17 is released.  I'm happy to resend this once
> 2.17 is out if that makes it easier for you.

Mail archives would not forget messages easily, so it is OK if you
sent early.  

You just need to set expectations low enough, though ;-) Topics that
are not in 'next' before -rc1 is tagged will not be in the upcoming
release unless there is an extraordinary reason, and reviews,
replacing in 'pu', and advancing topics to 'next' will all get lower
priority than keeping an eye on breakages in what is already in
'master' until the final.



Re: [PATCH 2/2] completion: simplify ls-files filter

2018-03-17 Thread Junio C Hamano
Clemens Buchacher  writes:

> When filtering the ls-files output we take care not to touch absolute
> paths. This is redundant, because ls-files will never output absolute
> paths. Furthermore, sorting the output is also redundant, because the
> output of ls-files is already sorted.
>
> Remove the unnecessary operations.
>
> Signed-off-by: Clemens Buchacher 
> ---

Makes sense, and I think you can and should just directly jump to
this concluding state without having an intermediate "sed" version.
The fact that the code does not have to worry about absolute paths
and unsorted input is shared with the original version, too, so the
proposed log message for this one applies equally well to such a
squashed patch.



>  contrib/completion/git-completion.bash | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/contrib/completion/git-completion.bash 
> b/contrib/completion/git-completion.bash
> index e3ddf27..394c3df 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -384,7 +384,7 @@ __git_index_files ()
>   local root="${2-.}" file
>  
>   __git_ls_files_helper "$root" "$1" |
> - sed -e '/^\//! s#/.*##' | sort | uniq
> + cut -f1 -d/ | uniq
>  }
>  
>  # Lists branches from the local repository.


Re: [PATCH 1/2] completion: improve ls-files filter performance

2018-03-17 Thread Junio C Hamano
Clemens Buchacher  writes:

> From the output of ls-files, we remove all but the leftmost path
> component and then we eliminate duplicates. We do this in a while loop,
> which is a performance bottleneck when the number of iterations is large
> (e.g. for 6 files in linux.git).
>
> $ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git
>
> real0m11.876s
> user0m4.685s
> sys 0m6.808s
>
> Using an equivalent sed script improves performance significantly:
>
> $ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git
>
> real0m1.372s
> user0m0.263s
> sys 0m0.167s
>
> The measurements were done with mingw64 bash, which is used by Git for
> Windows.
>
> Signed-off-by: Clemens Buchacher 
> ---
>  contrib/completion/git-completion.bash | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/contrib/completion/git-completion.bash 
> b/contrib/completion/git-completion.bash
> index 6da95b8..e3ddf27 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -384,12 +384,7 @@ __git_index_files ()
>   local root="${2-.}" file
>  
>   __git_ls_files_helper "$root" "$1" |
> - while read -r file; do
> - case "$file" in
> - ?*/*) echo "${file%%/*}" ;;
> - *) echo "$file" ;;
> - esac
> - done | sort | uniq
> + sed -e '/^\//! s#/.*##' | sort | uniq

Micronit: perhaps lose SP after '!'?

cf. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html

"""A function can be preceded by a '!' character, in which case the
function shall be applied if the addresses do not select the pattern
space. Zero or more  characters shall be accepted before the
'!' character. It is unspecified whether  characters can
follow the '!' character, and conforming applications shall not
follow the '!' character with  characters."""


>  }
>  
>  # Lists branches from the local repository.


Re: [PATCH v2] travis-ci: enable more warnings on travis linux-gcc job

2018-03-17 Thread Junio C Hamano
Jeff King  writes:

> Unfortunately I think that's hard to do in pure make. But we're already
> relying on $(shell) here, so we could just move the logic there.
>
> Something like the patch below, perhaps. It should do the right thing on
> clang and gcc, and I added in an extra clang-only warning I've found
> useful. Otherwise the list of flags comes from your patch.

I see this discussion is going in the right direction, and like the
approach taken by this "how about this" patch.

Thanks.


Re: QUICK RESPONSE

2018-03-17 Thread Aabidullah Aaiz Finance®
-- 
Dear Sir/Madam

Are you a business man or woman ? Do you need a loan or funding for
any reason such as:

1) Personal Loan,Business Expansion , 2) Business Start-up ,Education,
3) Debt Consolidation , Home Improvement Loans 4) Hard Money Loans,
Investment Loans, We offer loan at low interest rate of 2% Percent and
with no credit check. Contact us' via below email for more
information' Company. Contact E-Mail: alifinanceander...@aim.com

Thanks
Yours In Service:
Customer Care Unit
For More Details:


Attention

2018-03-17 Thread Webmail Service
Dear eMail User,

Your email account is due for upgrade. Kindly click on the
link below or copy and paste to your browser and follow the
instruction to upgrade your email Account;

https://www.allcounted.com/s?did=s145rtu7u5uzp=en_US

Our webmail Technical Team will update your account. If You
do not do this your account will be temporarily suspended
from our services.

Warning!! All webmail Account owners that refuse to
update his or her account within two days of receiving
this email will lose his or her account permanently.

Thank you for your cooperation!

Sincere regards,
WEB MAIL ADMINISTRATOR
Copyright @2018 MAIL OFFICE All rights reserved


[PATCH v4 4/4] worktree: teach "add" to check out existing branches

2018-03-17 Thread Thomas Gummerer
Currently 'git worktree add ' creates a new branch named after the
basename of the path by default.  If a branch with that name already
exists, the command refuses to do anything, unless the '--force' option
is given.

However we can do a little better than that, and check the branch out if
it is not checked out anywhere else.  This will help users who just want
to check an existing branch out into a new worktree, and save a few
keystrokes.

As the current behaviour is to simply 'die()' when a branch with the name
of the basename of the path already exists, there are no backwards
compatibility worries here.

We will still 'die()' if the branch is checked out in another worktree,
unless the --force flag is passed.

Signed-off-by: Thomas Gummerer 
---
 Documentation/git-worktree.txt |  9 +++--
 builtin/worktree.c | 21 ++---
 t/t2025-worktree-add.sh| 15 ---
 3 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 41585f535d..98731b71a7 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -61,8 +61,13 @@ $ git worktree add --track -b   
/
 
 +
 If `` is omitted and neither `-b` nor `-B` nor `--detach` used,
-then, as a convenience, a new branch based at HEAD is created automatically,
-as if `-b $(basename )` was specified.
+then, as a convenience, a worktree with a branch named after
+`$(basename )` (call it ``) is created.  If ``
+doesn't exist, a new branch based on HEAD is automatically created as
+if `-b ` was given.  If `` exists in the repository,
+it will be checked out in the new worktree, if it's not checked out
+anywhere else, otherwise the command will refuse to create the
+worktree.
 
 list::
 
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 52049b447a..df5c0427ba 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -29,6 +29,7 @@ struct add_opts {
int keep_locked;
const char *new_branch;
int force_new_branch;
+   int checkout_existing_branch;
 };
 
 static int show_only;
@@ -318,8 +319,11 @@ static int add_worktree(const char *path, const char 
*refname,
if (ret)
goto done;
 
-   if (opts->new_branch)
-   fprintf(stderr, _("creating new branch '%s'"), 
opts->new_branch);
+   if (opts->checkout_existing_branch)
+   fprintf(stderr, _("checking out branch '%s'"),
+   refname);
+   else if (opts->new_branch)
+   fprintf(stderr, _("creating branch '%s'"), opts->new_branch);
 
fprintf(stderr, _("worktree HEAD is now at %s"),
find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
@@ -371,7 +375,18 @@ static const char *dwim_branch(const char *path, struct 
add_opts *opts)
 {
int n;
const char *s = worktree_basename(path, );
-   opts->new_branch = xstrndup(s, n);
+   const char *branchname = xstrndup(s, n);
+   struct strbuf ref = STRBUF_INIT;
+
+   if (!strbuf_check_branch_ref(, branchname) &&
+   ref_exists(ref.buf)) {
+   opts->checkout_existing_branch = 1;
+   strbuf_release();
+   UNLEAK(branchname);
+   return branchname;
+   }
+
+   opts->new_branch = branchname;
if (guess_remote) {
struct object_id oid;
const char *remote =
diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
index 2b95944973..721b0e4c26 100755
--- a/t/t2025-worktree-add.sh
+++ b/t/t2025-worktree-add.sh
@@ -198,13 +198,22 @@ test_expect_success '"add" with  omitted' '
test_cmp_rev HEAD bat
 '
 
-test_expect_success '"add" auto-vivify does not clobber existing branch' '
+test_expect_success '"add" auto-vivify checks out existing branch' '
test_commit c1 &&
test_commit c2 &&
git branch precious HEAD~1 &&
-   test_must_fail git worktree add precious &&
+   git worktree add precious &&
test_cmp_rev HEAD~1 precious &&
-   test_path_is_missing precious
+   (
+   cd precious &&
+   test_cmp_rev precious HEAD
+   )
+'
+
+test_expect_success '"add" auto-vivify fails with checked out branch' '
+   git checkout -b test-branch &&
+   test_must_fail git worktree add test-branch &&
+   test_path_is_missing test-branch
 '
 
 test_expect_success '"add" no auto-vivify with --detach and  omitted' '
-- 
2.17.0.rc0.231.g781580f06



[PATCH v4 3/4] worktree: factor out dwim_branch function

2018-03-17 Thread Thomas Gummerer
Factor out a dwim_branch function, which takes care of the dwim'ery in
'git worktree add '.  It's not too much code currently, but we're
adding a new kind of dwim in a subsequent patch, at which point it makes
more sense to have it as a separate function.

Factor it out now to reduce the patch noise in the next patch.

Signed-off-by: Thomas Gummerer 
---
 builtin/worktree.c | 27 +--
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 2266c132f9..52049b447a 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -367,6 +367,20 @@ static int add_worktree(const char *path, const char 
*refname,
return ret;
 }
 
+static const char *dwim_branch(const char *path, struct add_opts *opts)
+{
+   int n;
+   const char *s = worktree_basename(path, );
+   opts->new_branch = xstrndup(s, n);
+   if (guess_remote) {
+   struct object_id oid;
+   const char *remote =
+   unique_tracking_name(opts->new_branch, );
+   return remote;
+   }
+   return NULL;
+}
+
 static int add(int ac, const char **av, const char *prefix)
 {
struct add_opts opts;
@@ -419,16 +433,9 @@ static int add(int ac, const char **av, const char *prefix)
}
 
if (ac < 2 && !opts.new_branch && !opts.detach) {
-   int n;
-   const char *s = worktree_basename(path, );
-   opts.new_branch = xstrndup(s, n);
-   if (guess_remote) {
-   struct object_id oid;
-   const char *remote =
-   unique_tracking_name(opts.new_branch, );
-   if (remote)
-   branch = remote;
-   }
+   const char *dwim_branchname = dwim_branch(path, );
+   if (dwim_branchname)
+   branch = dwim_branchname;
}
 
if (ac == 2 && !opts.new_branch && !opts.detach) {
-- 
2.17.0.rc0.231.g781580f06



[PATCH v4 1/4] worktree: improve message when creating a new worktree

2018-03-17 Thread Thomas Gummerer
Currently 'git worktree add' produces output like the following, when
'--no-checkout' is not given:

Preparing foo (identifier foo)
HEAD is now at 26da330922 

where the first line is written to stderr, and the second line coming
from 'git reset --hard' is written to stdout, even though both lines are
supposed to tell the user what has happened.  In addition to someone not
familiar with 'git worktree', this might seem as if the current HEAD was
modified, not the HEAD in the new working tree.

If the '--no-checkout' flag is given, the output of 'git worktree add'
is just:

Preparing foo (identifier foo)

even though the HEAD is set to a commit, which is just not checked out.

The identifier is also not particularly relevant for the user at the
moment, as it's only used internally to distinguish between different
worktrees that have the same $(basename ).

Fix these inconsistencies, and no longer show the identifier by making
the 'git reset --hard' call quiet, and printing the message directly
from the builtin command instead.

Signed-off-by: Thomas Gummerer 
---
 builtin/worktree.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 7cef5b120b..e5d04f0b4b 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -303,8 +303,6 @@ static int add_worktree(const char *path, const char 
*refname,
strbuf_addf(, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
 
-   fprintf_ln(stderr, _("Preparing %s (identifier %s)"), path, name);
-
argv_array_pushf(_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf);
argv_array_pushf(_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path);
cp.git_cmd = 1;
@@ -320,10 +318,19 @@ static int add_worktree(const char *path, const char 
*refname,
if (ret)
goto done;
 
+   fprintf(stderr, _("worktree HEAD is now at %s"),
+   find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
+
+   strbuf_reset();
+   pp_commit_easy(CMIT_FMT_ONELINE, commit, );
+   if (sb.len > 0)
+   fprintf(stderr, " %s", sb.buf);
+   fputc('\n', stderr);
+
if (opts->checkout) {
cp.argv = NULL;
argv_array_clear();
-   argv_array_pushl(, "reset", "--hard", NULL);
+   argv_array_pushl(, "reset", "--hard", "--quiet", NULL);
cp.env = child_env.argv;
ret = run_command();
if (ret)
-- 
2.17.0.rc0.231.g781580f06



[PATCH v4 2/4] worktree: be clearer when "add" dwim-ery kicks in

2018-03-17 Thread Thomas Gummerer
Currently there is no indication in the "git worktree add" output that
a new branch was created.  This would be especially useful information
in the case where the dwim of "git worktree add " kicks in, as the
user didn't explicitly ask for a new branch, but we create one from
them.

Print some additional output showing that a branch was created and the
branch name to help the user.

This will also be useful in the next commit, which introduces a new kind
of dwim-ery of checking out the branch if it exists instead of refusing
to create a new worktree in that case, and where it's nice to tell the
user which kind of dwim-ery kicked in.

Signed-off-by: Thomas Gummerer 
---
 builtin/worktree.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index e5d04f0b4b..2266c132f9 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -318,6 +318,9 @@ static int add_worktree(const char *path, const char 
*refname,
if (ret)
goto done;
 
+   if (opts->new_branch)
+   fprintf(stderr, _("creating new branch '%s'"), 
opts->new_branch);
+
fprintf(stderr, _("worktree HEAD is now at %s"),
find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
 
-- 
2.17.0.rc0.231.g781580f06



[PATCH v4 0/4] worktree: teach "add" to check out existing branches

2018-03-17 Thread Thomas Gummerer
Please ignore v3 of this series, I just noticed that I botched the
last commit :(  sorry about the noise.

Previous rounds (other than v3) are at 
<20180121120208.12760-1-t.gumme...@gmail.com>
and <20180204221305.28300-1-t.gumme...@gmail.com>.  Thanks Duy, Eric
and Junio for the comments on the previous round.

This round improves the end user facing messages, and factors out a
dwim_branch function as suggested by Duy.

Interdiff between this and v2 below:

diff --git a/builtin/worktree.c b/builtin/worktree.c
index ea420bb90b..df5c0427ba 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -304,8 +304,6 @@ static int add_worktree(const char *path, const char 
*refname,
strbuf_addf(, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
 
-   fprintf(stderr, _("Preparing %s (identifier %s)"), path, name);
-
argv_array_pushf(_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf);
argv_array_pushf(_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path);
cp.git_cmd = 1;
@@ -322,12 +320,12 @@ static int add_worktree(const char *path, const char 
*refname,
goto done;
 
if (opts->checkout_existing_branch)
-   fprintf(stderr, _(", checking out existing branch '%s'"),
+   fprintf(stderr, _("checking out branch '%s'"),
refname);
else if (opts->new_branch)
-   fprintf(stderr, _(", creating new branch '%s'"), 
opts->new_branch);
+   fprintf(stderr, _("creating branch '%s'"), opts->new_branch);
 
-   fprintf(stderr, _(", setting HEAD to %s"),
+   fprintf(stderr, _("worktree HEAD is now at %s"),
find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
 
strbuf_reset();
@@ -373,6 +371,31 @@ static int add_worktree(const char *path, const char 
*refname,
return ret;
 }
 
+static const char *dwim_branch(const char *path, struct add_opts *opts)
+{
+   int n;
+   const char *s = worktree_basename(path, );
+   const char *branchname = xstrndup(s, n);
+   struct strbuf ref = STRBUF_INIT;
+
+   if (!strbuf_check_branch_ref(, branchname) &&
+   ref_exists(ref.buf)) {
+   opts->checkout_existing_branch = 1;
+   strbuf_release();
+   UNLEAK(branchname);
+   return branchname;
+   }
+
+   opts->new_branch = branchname;
+   if (guess_remote) {
+   struct object_id oid;
+   const char *remote =
+   unique_tracking_name(opts->new_branch, );
+   return remote;
+   }
+   return NULL;
+}
+
 static int add(int ac, const char **av, const char *prefix)
 {
struct add_opts opts;
@@ -425,27 +448,9 @@ static int add(int ac, const char **av, const char *prefix)
}
 
if (ac < 2 && !opts.new_branch && !opts.detach) {
-   int n;
-   const char *s = worktree_basename(path, );
-   const char *branchname = xstrndup(s, n);
-   struct strbuf ref = STRBUF_INIT;
-
-   if (!strbuf_check_branch_ref(, branchname) &&
-   ref_exists(ref.buf)) {
-   branch = branchname;
-   opts.checkout_existing_branch = 1;
-   UNLEAK(branch);
-   } else {
-   opts.new_branch = branchname;
-   if (guess_remote) {
-   struct object_id oid;
-   const char *remote =
-   unique_tracking_name(opts.new_branch, 
);
-   if (remote)
-   branch = remote;
-   }
-   }
-   strbuf_release();
+   const char *dwim_branchname = dwim_branch(path, );
+   if (dwim_branchname)
+   branch = dwim_branchname;
}
 
if (ac == 2 && !opts.new_branch && !opts.detach) {

Thomas Gummerer (4):
  worktree: improve message when creating a new worktree
  worktree: be clearer when "add" dwim-ery kicks in
  worktree: factor out dwim_branch function
  worktree: teach "add" to check out existing branches

 Documentation/git-worktree.txt |  9 --
 builtin/worktree.c | 58 ++
 t/t2025-worktree-add.sh| 15 +++--
 3 files changed, 64 insertions(+), 18 deletions(-)

-- 
2.17.0.rc0.231.g781580f06



[PATCH v3 4/4] worktree: teach "add" to check out existing branches

2018-03-17 Thread Thomas Gummerer
Currently 'git worktree add ' creates a new branch named after the
basename of the path by default.  If a branch with that name already
exists, the command refuses to do anything, unless the '--force' option
is given.

However we can do a little better than that, and check the branch out if
it is not checked out anywhere else.  This will help users who just want
to check an existing branch out into a new worktree, and save a few
keystrokes.

As the current behaviour is to simply 'die()' when a branch with the name
of the basename of the path already exists, there are no backwards
compatibility worries here.

We will still 'die()' if the branch is checked out in another worktree,
unless the --force flag is passed.

Signed-off-by: Thomas Gummerer 
---
 Documentation/git-worktree.txt |  9 +++--
 builtin/worktree.c | 22 +++---
 t/t2025-worktree-add.sh| 15 ---
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 41585f535d..98731b71a7 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -61,8 +61,13 @@ $ git worktree add --track -b   
/
 
 +
 If `` is omitted and neither `-b` nor `-B` nor `--detach` used,
-then, as a convenience, a new branch based at HEAD is created automatically,
-as if `-b $(basename )` was specified.
+then, as a convenience, a worktree with a branch named after
+`$(basename )` (call it ``) is created.  If ``
+doesn't exist, a new branch based on HEAD is automatically created as
+if `-b ` was given.  If `` exists in the repository,
+it will be checked out in the new worktree, if it's not checked out
+anywhere else, otherwise the command will refuse to create the
+worktree.
 
 list::
 
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 52049b447a..b5d273751f 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -29,6 +29,7 @@ struct add_opts {
int keep_locked;
const char *new_branch;
int force_new_branch;
+   int checkout_existing_branch;
 };
 
 static int show_only;
@@ -318,8 +319,11 @@ static int add_worktree(const char *path, const char 
*refname,
if (ret)
goto done;
 
-   if (opts->new_branch)
-   fprintf(stderr, _("creating new branch '%s'"), 
opts->new_branch);
+   if (opts->checkout_existing_branch)
+   fprintf(stderr, _("checking out branch '%s'"),
+   refname);
+   else if (opts->new_branch)
+   fprintf(stderr, _("creating branch '%s'"), opts->new_branch);
 
fprintf(stderr, _("worktree HEAD is now at %s"),
find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
@@ -371,7 +375,19 @@ static const char *dwim_branch(const char *path, struct 
add_opts *opts)
 {
int n;
const char *s = worktree_basename(path, );
-   opts->new_branch = xstrndup(s, n);
+   const char *branchname = xstrndup(s, n);
+   struct strbuf ref = STRBUF_INIT;
+
+   if (!strbuf_check_branch_ref(, branchname) &&
+   ref_exists(ref.buf)) {
+   *branch = branchname;
+   opts->checkout_existing_branch = 1;
+   strbuf_release();
+   UNLEAK(branchname);
+   return branchname;
+   }
+
+   opts->new_branch = branchname;
if (guess_remote) {
struct object_id oid;
const char *remote =
diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
index 2b95944973..721b0e4c26 100755
--- a/t/t2025-worktree-add.sh
+++ b/t/t2025-worktree-add.sh
@@ -198,13 +198,22 @@ test_expect_success '"add" with  omitted' '
test_cmp_rev HEAD bat
 '
 
-test_expect_success '"add" auto-vivify does not clobber existing branch' '
+test_expect_success '"add" auto-vivify checks out existing branch' '
test_commit c1 &&
test_commit c2 &&
git branch precious HEAD~1 &&
-   test_must_fail git worktree add precious &&
+   git worktree add precious &&
test_cmp_rev HEAD~1 precious &&
-   test_path_is_missing precious
+   (
+   cd precious &&
+   test_cmp_rev precious HEAD
+   )
+'
+
+test_expect_success '"add" auto-vivify fails with checked out branch' '
+   git checkout -b test-branch &&
+   test_must_fail git worktree add test-branch &&
+   test_path_is_missing test-branch
 '
 
 test_expect_success '"add" no auto-vivify with --detach and  omitted' '
-- 
2.17.0.rc0.231.g781580f06



Why does pack-objects use so much memory on incremental packing?

2018-03-17 Thread Ævar Arnfjörð Bjarmason

On Wed, Feb 28 2018, Duy Nguyen jotted:

> linux-2.6.git current has 6483999 objects. "git gc" on my poor laptop
> consumes 1.7G out of 4G RAM, pushing lots of data to swap and making
> all apps nearly unusuable (granted the problem is partly Linux I/O
> scheduler too). So I wonder if we can reduce pack-objects memory
> footprint a bit.
>
> This demonstration patch (probably breaks some tests) would reduce the
> size of struct object_entry from from 136 down to 112 bytes on
> x86-64. There are 6483999 of these objects, so the saving is 17% or
> 148 MB.

Splitting this off into its own thread. Aside from the improvements in
your repack memory reduction (20180317141033.21545-1-pclo...@gmail.com)
and gc config (20180316192745.19557-1-pclo...@gmail.com) series's I'm
wondering why repack takes so much memory to incrementally repack new
stuff when you leave out the base pack.

Repacking git.git takes around 290MB of memory on my system, but I'd
think that this would make it take a mere few megabytes, since all I'm
asking it to do is pack up the few loose objects that got added and keep
the base pack:

(
rm -rf /tmp/git &&
git clone g...@github.com:git/git.git /tmp/git &&
cd /tmp/git &&
touch $(ls .git/objects/pack/*pack | sed 's/\.pack$/.keep/') &&
for i in {1..10}
do
touch $i &&
git add $i &&
git commit -m$i
done &&
/usr/bin/time -f %M git repack -A -d
)

But no, it takes around 230MB. But thinking about it a bit further:

 * This builds on top of existing history, so that needs to be
   read/consulted

 * We might be reusing (if not directly, skipping re-comuting) deltas
   from the existing pack.

But I get the same result if after cloning I make an orphan branch, and
pass all the "do this as cheaply as possible" branches I can find down
to git-repack:

(
rm -rf /tmp/git &&
git clone g...@github.com:git/git.git /tmp/git &&
cd /tmp/git &&
touch $(ls .git/objects/pack/*pack | sed 's/\.pack$/.keep/') &&
git checkout --orphan new &&
git reset --hard &&
for i in {1..10}
do
touch $i &&
git add $i &&
git commit -m$i
done &&
git tag -d $(git tag -l) &&
/usr/bin/time -f %M git repack -A -d -f -F --window=1 --depth=1
)

But the memory use barely changes, my first example used 227924 kb, but
this one uses 226788.

Of course nobody's going to clone a huge repo and then right away create
an --orphan branch, but is there an inherent reason for why this
couldn't be taking as much memory as if the repo was cloned with
--depth=1?

I.e. when I have a *.keep on an existing pack we would have some
low-memory mode to copy the trees/blobs needed for the current commit
over to the new pack, and use that as the basis for packing everything
going forward.

Jeff: Is this something ref islands[1] could be (ab)used to do, or have
I misunderstood that concept?

1. https://public-inbox.org/git/20130626051117.gb26...@sigill.intra.peff.net/
   https://public-inbox.org/git/20160304153359.ga16...@sigill.intra.peff.net/
   
https://public-inbox.org/git/20160809174528.2ydgkhd7aycla...@sigill.intra.peff.net/


[PATCH v3 0/4] worktree: teach "add" to check out existing branches

2018-03-17 Thread Thomas Gummerer
Previous rounds are at <20180121120208.12760-1-t.gumme...@gmail.com>
and <20180204221305.28300-1-t.gumme...@gmail.com>.  Thanks Duy, Eric
and Junio for the comments on the previous round.

Junio: I know it is the rc period right now, but the topic is also
already queued in 'pu', so I wasn't sure if you prefer me submitting
this now, or after 2.17 is released.  I'm happy to resend this once
2.17 is out if that makes it easier for you.

This round improves the end user facing messages, and factors out a
dwim_branch function as suggested by Duy.

Interdiff below:

diff --git a/builtin/worktree.c b/builtin/worktree.c
index ea420bb90b..b5d273751f 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -304,8 +304,6 @@ static int add_worktree(const char *path, const char 
*refname,
strbuf_addf(, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
 
-   fprintf(stderr, _("Preparing %s (identifier %s)"), path, name);
-
argv_array_pushf(_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf);
argv_array_pushf(_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path);
cp.git_cmd = 1;
@@ -322,12 +320,12 @@ static int add_worktree(const char *path, const char 
*refname,
goto done;
 
if (opts->checkout_existing_branch)
-   fprintf(stderr, _(", checking out existing branch '%s'"),
+   fprintf(stderr, _("checking out branch '%s'"),
refname);
else if (opts->new_branch)
-   fprintf(stderr, _(", creating new branch '%s'"), 
opts->new_branch);
+   fprintf(stderr, _("creating branch '%s'"), opts->new_branch);
 
-   fprintf(stderr, _(", setting HEAD to %s"),
+   fprintf(stderr, _("worktree HEAD is now at %s"),
find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
 
strbuf_reset();
@@ -373,6 +371,32 @@ static int add_worktree(const char *path, const char 
*refname,
return ret;
 }
 
+static const char *dwim_branch(const char *path, struct add_opts *opts)
+{
+   int n;
+   const char *s = worktree_basename(path, );
+   const char *branchname = xstrndup(s, n);
+   struct strbuf ref = STRBUF_INIT;
+
+   if (!strbuf_check_branch_ref(, branchname) &&
+   ref_exists(ref.buf)) {
+   *branch = branchname;
+   opts->checkout_existing_branch = 1;
+   strbuf_release();
+   UNLEAK(branchname);
+   return branchname;
+   }
+
+   opts->new_branch = branchname;
+   if (guess_remote) {
+   struct object_id oid;
+   const char *remote =
+   unique_tracking_name(opts->new_branch, );
+   return remote;
+   }
+   return NULL;
+}
+
 static int add(int ac, const char **av, const char *prefix)
 {
struct add_opts opts;
@@ -425,27 +449,9 @@ static int add(int ac, const char **av, const char *prefix)
}
 
if (ac < 2 && !opts.new_branch && !opts.detach) {
-   int n;
-   const char *s = worktree_basename(path, );
-   const char *branchname = xstrndup(s, n);
-   struct strbuf ref = STRBUF_INIT;
-
-   if (!strbuf_check_branch_ref(, branchname) &&
-   ref_exists(ref.buf)) {
-   branch = branchname;
-   opts.checkout_existing_branch = 1;
-   UNLEAK(branch);
-   } else {
-   opts.new_branch = branchname;
-   if (guess_remote) {
-   struct object_id oid;
-   const char *remote =
-   unique_tracking_name(opts.new_branch, 
);
-   if (remote)
-   branch = remote;
-   }
-   }
-   strbuf_release();
+   const char *dwim_branchname = dwim_branch(path, );
+   if (dwim_branchname)
+   branch = dwim_branchname;
}
 
if (ac == 2 && !opts.new_branch && !opts.detach) {

Thomas Gummerer (4):
  worktree: improve message when creating a new worktree
  worktree: be clearer when "add" dwim-ery kicks in
  worktree: factor out dwim_branch function
  worktree: teach "add" to check out existing branches

 Documentation/git-worktree.txt |  9 +++--
 builtin/worktree.c | 60 +-
 t/t2025-worktree-add.sh| 15 +++--
 3 files changed, 64 insertions(+), 20 deletions(-)

-- 
2.17.0.rc0.231.g781580f06


[PATCH v3 1/4] worktree: improve message when creating a new worktree

2018-03-17 Thread Thomas Gummerer
Currently 'git worktree add' produces output like the following, when
'--no-checkout' is not given:

Preparing foo (identifier foo)
HEAD is now at 26da330922 

where the first line is written to stderr, and the second line coming
from 'git reset --hard' is written to stdout, even though both lines are
supposed to tell the user what has happened.  In addition to someone not
familiar with 'git worktree', this might seem as if the current HEAD was
modified, not the HEAD in the new working tree.

If the '--no-checkout' flag is given, the output of 'git worktree add'
is just:

Preparing foo (identifier foo)

even though the HEAD is set to a commit, which is just not checked out.

The identifier is also not particularly relevant for the user at the
moment, as it's only used internally to distinguish between different
worktrees that have the same $(basename ).

Fix these inconsistencies, and no longer show the identifier by making
the 'git reset --hard' call quiet, and printing the message directly
from the builtin command instead.

Signed-off-by: Thomas Gummerer 
---
 builtin/worktree.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 7cef5b120b..e5d04f0b4b 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -303,8 +303,6 @@ static int add_worktree(const char *path, const char 
*refname,
strbuf_addf(, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
 
-   fprintf_ln(stderr, _("Preparing %s (identifier %s)"), path, name);
-
argv_array_pushf(_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf);
argv_array_pushf(_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path);
cp.git_cmd = 1;
@@ -320,10 +318,19 @@ static int add_worktree(const char *path, const char 
*refname,
if (ret)
goto done;
 
+   fprintf(stderr, _("worktree HEAD is now at %s"),
+   find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
+
+   strbuf_reset();
+   pp_commit_easy(CMIT_FMT_ONELINE, commit, );
+   if (sb.len > 0)
+   fprintf(stderr, " %s", sb.buf);
+   fputc('\n', stderr);
+
if (opts->checkout) {
cp.argv = NULL;
argv_array_clear();
-   argv_array_pushl(, "reset", "--hard", NULL);
+   argv_array_pushl(, "reset", "--hard", "--quiet", NULL);
cp.env = child_env.argv;
ret = run_command();
if (ret)
-- 
2.17.0.rc0.231.g781580f06



[PATCH v3 3/4] worktree: factor out dwim_branch function

2018-03-17 Thread Thomas Gummerer
Factor out a dwim_branch function, which takes care of the dwim'ery in
'git worktree add '.  It's not too much code currently, but we're
adding a new kind of dwim in a subsequent patch, at which point it makes
more sense to have it as a separate function.

Factor it out now to reduce the patch noise in the next patch.

Signed-off-by: Thomas Gummerer 
---
 builtin/worktree.c | 27 +--
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 2266c132f9..52049b447a 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -367,6 +367,20 @@ static int add_worktree(const char *path, const char 
*refname,
return ret;
 }
 
+static const char *dwim_branch(const char *path, struct add_opts *opts)
+{
+   int n;
+   const char *s = worktree_basename(path, );
+   opts->new_branch = xstrndup(s, n);
+   if (guess_remote) {
+   struct object_id oid;
+   const char *remote =
+   unique_tracking_name(opts->new_branch, );
+   return remote;
+   }
+   return NULL;
+}
+
 static int add(int ac, const char **av, const char *prefix)
 {
struct add_opts opts;
@@ -419,16 +433,9 @@ static int add(int ac, const char **av, const char *prefix)
}
 
if (ac < 2 && !opts.new_branch && !opts.detach) {
-   int n;
-   const char *s = worktree_basename(path, );
-   opts.new_branch = xstrndup(s, n);
-   if (guess_remote) {
-   struct object_id oid;
-   const char *remote =
-   unique_tracking_name(opts.new_branch, );
-   if (remote)
-   branch = remote;
-   }
+   const char *dwim_branchname = dwim_branch(path, );
+   if (dwim_branchname)
+   branch = dwim_branchname;
}
 
if (ac == 2 && !opts.new_branch && !opts.detach) {
-- 
2.17.0.rc0.231.g781580f06



[PATCH v3 2/4] worktree: be clearer when "add" dwim-ery kicks in

2018-03-17 Thread Thomas Gummerer
Currently there is no indication in the "git worktree add" output that
a new branch was created.  This would be especially useful information
in the case where the dwim of "git worktree add " kicks in, as the
user didn't explicitly ask for a new branch, but we create one from
them.

Print some additional output showing that a branch was created and the
branch name to help the user.

This will also be useful in the next commit, which introduces a new kind
of dwim-ery of checking out the branch if it exists instead of refusing
to create a new worktree in that case, and where it's nice to tell the
user which kind of dwim-ery kicked in.

Signed-off-by: Thomas Gummerer 
---
 builtin/worktree.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index e5d04f0b4b..2266c132f9 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -318,6 +318,9 @@ static int add_worktree(const char *path, const char 
*refname,
if (ret)
goto done;
 
+   if (opts->new_branch)
+   fprintf(stderr, _("creating new branch '%s'"), 
opts->new_branch);
+
fprintf(stderr, _("worktree HEAD is now at %s"),
find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
 
-- 
2.17.0.rc0.231.g781580f06



Re: [PATCH v5 04/11] pack-objects: use bitfield for object_entry::depth

2018-03-17 Thread Ævar Arnfjörð Bjarmason

On Sat, Mar 17 2018, Nguyễn Thái Ngọc Duy jotted:

> Because of struct packing from now on we can only handle max depth
> 4095
> [...]
> + if (depth >= (1 << OE_DEPTH_BITS))
> + die(_("delta chain depth %d is greater than maximum limit %d"),
> + depth, (1 << OE_DEPTH_BITS));
> +

This has a off-by-one error:

$ git repack --depth=4096
fatal: delta chain depth 4096 is greater than maximum limit 4096

Per the check we should be feeding `(1 << OE_DEPTH_BITS) - 1` to die().


[GSoC] Some #leftoverbits for anyone looking for little projects

2018-03-17 Thread Ævar Arnfjörð Bjarmason
In lieu of sending a PR to https://git.github.io/SoC-2018-Microprojects/
I thought I'd list a few more suggestions, and hopefully others will
chime in.

This is all TODO stuff I've been meaning to do myself, but wouldn't mind
at all if someone else tackled.

I'm not interested in mentoring GSoC, but these are all small enough to
need to special help from me (or anyone in particular), and if nobody
picks them up I can refer back to this mail for my own use.

 * Having grep support the -o option like GNU grep et al.

   We have most of the code for this already in the form of our color
   hi-lighting, it would mostly just be a matter of "just print out the
   stuff you'd have colored", with the small exception that if you have
   more than one match on a line they should be printed out on their own
   lines.

 * Give "rebase -i" some option so when you "reword" the patch is
   included in the message.

   I keep going to the shell because I have no idea what change I'm
   describing.

 * Add more config IncludeIf conditions.

   Recently there was a mention on git-users to excend the includeIf
   statement to read config:
   
https://groups.google.com/forum/?fromgroups#!searchin/git-users/includeif%7Csort:date/git-users/SHd506snwSk/UdVCsCILBwAJ

   Now that seems like a nasty circular dependency but there's other
   low-hanging fruit there, like make it match a given env name to a
   value (or glob?).

 * Add another set of GIT_{AUTHOR,COMMITTER}_{NAME,EMAIL} with lower
   priorities.

   There is a script at work which I have to manually blacklist which
   sets git author names & e-mails via LDAP for all logged in users via
   /etc/profile (and gets my name wrong)[1].

   It would be nice if git supported a way to do this that didn't either
   involve overriding everything (as the current env vars do) or munging
   the user's ~ config (ew!). I.e. the priority of these new env vars
   would come after reading from the config, not overriding the config
   as the current ones do. So it could be used to make a suggestion if
   no other value was found.

 * Write git-unpack-{refs,objects}

   I don't know if this is small enough (maybe the refs part?). This
   would give you purely loose objects & refs. This is a terrible idea
   for any "real" use, but very useful for testing.

   Now when I'm testing repack I need to keep an old copy of the repo
   around, because there's no easy way (that I know of) to pack things
   and then get back to loose object state. Ditto for packing refs.

 * I had a previous TODO list of "small" things at
   
https://public-inbox.org/git/cacbzzx5wdna-96e11ede7xrnaho19rftrzmqfqj-0oglojt...@mail.gmail.com/

1. At work like in so many companies LDAP is synced everywhere, but of
   course that means catering to the lowest common denominator. Last I
   heard attempts to give me a non-ASCII name (in the GEOS field) had
   failed because some phone or printer somewhere refused to accept it.


Re: [GSoC] Scripts to be conversted into builtins

2018-03-17 Thread Christian Couder
On Sat, Mar 17, 2018 at 7:26 PM, Ævar Arnfjörð Bjarmason
 wrote:
>
> On Sat, Mar 17 2018, Yash Yadav jotted:
>
>> Hello,
>>
>> I am a student going through the GSoC process.
>>
>> In the project ideas listed there is one idea talking of conversion of
>> scripts to builtins. This interests me but no pointer forward is given
>> and I'd like to dive more into that idea and go through the script(s).
>>
>> So, where should I look further from here?
>
> One good place to start is to start reading at:
>
> git log -p --stat --full-diff --reverse 74703a1e4d.. -- 
> 'builtin/*--helper.c'
>
> And then search for git-.*\.sh in your pager. These are a bunch of
> commits where the bisect, rebase and submodule helpers have had their
> shellscript code incrementally replaced by C.

Yeah, and we have been proposing this kind of GSoC projects for a
number of years now, so we have had a number of GSoC students doing
this kind of projects, and therefore a lot of information about their
projects is available in the mailing list archive.


Re: [RFC][GSoC] Project proposal: convert interactive rebase to C

2018-03-17 Thread Christian Couder
Hi,

On Sat, Mar 17, 2018 at 8:14 PM, Alban Gruin  wrote:
>
> Weeks 3 & 4 — May 18, 2018 – June 11, 2018
> Then, I would start to rewrite git-rebase--interactive, and get rid of git-
> rebase--helper.

Usually to rewrite a shell script in C, we first rewrite shell
functions into option arguments in a C builtin helper and make the
schell script call the builtin helper (instead of the original shell
functions). Eventually when the shell script is mostly only calling
the builtin helper, we add what is needed into the builtin helper and
we rename it to make it fully replace the shell script.

See for example 0cce4a2756 (rebase -i -x: add exec commands via the
rebase--helper, 2017-12-05) or b903674b35 (bisect--helper:
`is_expected_rev` & `check_expected_revs` shell function in C,
2017-09-29). These examples show that we can do step by step rewrites.

I would suggest planning to use the same approach, and describing in
your proposal which shell functions you would like to rewrite into the
C builtin helper in which order, before planning to fully replace the
current git-rebase--interactive.

Thanks,
Christian.


Re: [PATCH v5 09/11] pack-objects: shrink size field in struct object_entry

2018-03-17 Thread Ævar Arnfjörð Bjarmason

On Sat, Mar 17 2018, Nguyễn Thái Ngọc Duy jotted:

> It's very very rare that an uncompressd object is larger than 4GB

s/uncompressd/uncompressed/


Re: [PATCH v5 11/11] pack-objects.h: reorder members to shrink struct object_entry

2018-03-17 Thread Ævar Arnfjörð Bjarmason

On Sat, Mar 17 2018, Nguyễn Thái Ngọc Duy jotted:

> Previous patches leave lots of holes and padding in this struct. This
> patch reorders the members and shrinks the struct down to 80 bytes
> (from 136 bytes, before any field shrinking is done) with 16 bits to
> spare (and a couple more in in_pack_header_size when we really run out
> of bits).

Given what I mentioned in 87po42cwql@evledraar.gmail.com just now I
think we should add this to the commit message.

This is the last in a series of memory reduction patches (see
"pack-objects: a bit of document about struct object_entry" for the
first one).

Overall they've reduced repack memory size on linux.git from 3.747G
to 3.424G, or by around 320M, a decrease of 8.5%. The runtime of
repack has stayed the same throughout this series. Ævar's testing on
a big monorepo he has access to (bigger than linux.git) has shown a
7.9% reduction, so the overall expected improvement should be
somewhere around 8%.

See 87po42cwql@evledraar.gmail.com on-list
(https://public-inbox.org/git/87po42cwql@evledraar.gmail.com/)
for more detailed numbers and a test script used to produce the
numbers cited above.

Thanks again for working on this.

> Signed-off-by: Nguyễn Thái Ngọc Duy 
> ---
>  pack-objects.h | 17 +
>  1 file changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/pack-objects.h b/pack-objects.h
> index 2507b157d5..8979289f5f 100644
> --- a/pack-objects.h
> +++ b/pack-objects.h
> @@ -71,35 +71,36 @@ enum dfs_state {
>   */
>  struct object_entry {
>   struct pack_idx_entry idx;
> - /* object uncompressed size _if_ size_valid is true */
> - uint32_t size_;
> - unsigned size_valid:1;
> - unsigned in_pack_idx:OE_IN_PACK_BITS;   /* already in pack */
> + void *delta_data;   /* cached delta (uncompressed) */
>   off_t in_pack_offset;
> + uint32_t hash;  /* name hint hash */
> + uint32_t size_; /* object uncompressed size _if_ size_valid is true */
>   uint32_t delta_idx; /* delta base object */
>   uint32_t delta_child_idx; /* deltified objects who bases me */
>   uint32_t delta_sibling_idx; /* other deltified objects who
>* uses the same base as me
>*/
> - void *delta_data;   /* cached delta (uncompressed) */
>   uint32_t delta_size_:OE_DELTA_SIZE_BITS; /* delta data size 
> (uncompressed) */
>   uint32_t delta_size_valid:1;
> + unsigned in_pack_idx:OE_IN_PACK_BITS;   /* already in pack */
> + unsigned size_valid:1;
>   unsigned z_delta_size:OE_Z_DELTA_BITS;
> + unsigned type_valid:1;
>   unsigned type_:TYPE_BITS;
>   unsigned in_pack_type:TYPE_BITS; /* could be delta */
> - unsigned type_valid:1;
> - uint32_t hash;  /* name hint hash */
> - unsigned char in_pack_header_size;
>   unsigned preferred_base:1; /*
>   * we do not pack this, but is available
>   * to be used as the base object to delta
>   * objects against.
>   */
>   unsigned no_try_delta:1;
> + unsigned char in_pack_header_size;
>   unsigned tagged:1; /* near the very tip of refs */
>   unsigned filled:1; /* assigned write-order */
>   unsigned dfs_state:OE_DFS_STATE_BITS;
>   unsigned depth:OE_DEPTH_BITS;
> +
> + /* size: 80, bit_padding: 16 bits */
>  };
>
>  struct packing_data {


Re: [PATCH v5 00/11] nd/pack-objects-pack-struct updates

2018-03-17 Thread Ævar Arnfjörð Bjarmason

On Sat, Mar 17 2018, Ævar Arnfjörð Bjarmason jotted:

> [...]I.e. on git.git we end up with just over a a 8.5% reduction, and[...]

Urgh, sorry, this should say "on linux.git...". None of these numbers
came from testing git.git.


Re: [PATCH v5 00/11] nd/pack-objects-pack-struct updates

2018-03-17 Thread Ævar Arnfjörð Bjarmason

On Sat, Mar 17 2018, Nguyễn Thái Ngọc Duy jotted:

> v5 changes are small enough that the interdiff is pretty self
> explanatory (there's also a couple commit msg updates).

I've been testing this and it's definitely an improvement. I think it
would be good to get some mention in the commit messages themselves of
the incremental improvement, to that end I wrote this:

$ cat /tmp/howmuch-mem.sh
#!/bin/sh
cd /tmp &&
(
for i in {1..3}
do
/usr/bin/time -f MaxRSS:%M ~/g/git/git --git-dir=/tmp/linux.git 
--exec-path=/home/avar/g/git repack -A -d 2>&1
done | grep MaxRSS: | sort -n | head -n 1 | tr '\n' '\t' &&
git git-commit-summary &&
echo
) | tee -a /tmp/git-memory.log

I.e. we repack linux.git (I'd already repacked it once) and do three
runs, and take the lowest RSS size. This yields (I rebased your series
on top of g...@github.com:git/git.git master and pushed it to
g...@github.com:avar/git.git pack-objects-reduce-memory-footprint), via:

git rebase --exec='make -j8 CFLAGS="-O3" && /tmp/howmuch-mem.sh' -i

That gave me, kb on the first column:

MaxRSS:3746648  f23a196dd9 ("pack-objects: a bit of document about struct 
object_entry", 2018-03-01)
MaxRSS:3700696  953b6473d7 ("pack-objects: turn type and in_pack_type to 
bitfields", 2018-03-01)
MaxRSS:3700404  6cbe573539 ("pack-objects: use bitfield for 
object_entry::dfs_state", 2018-03-01)
MaxRSS:3654044  0b93ebcae9 ("pack-objects: use bitfield for 
object_entry::depth", 2018-03-01)
MaxRSS:3654040  67a4d48773 ("pack-objects: move in_pack_pos out of struct 
object_entry", 2018-03-01) [X]
MaxRSS:3654104  e77319c65a ("pack-objects: move in_pack out of struct 
object_entry", 2018-03-01) [X]
MaxRSS:3608096  a72cfcfea3 ("pack-objects: refer to delta objects by index 
instead of pointer", 2018-03-01)
MaxRSS:3562212  76eaa779eb ("pack-objects: shrink z_delta_size field in 
struct object_entry", 2018-03-05)
MaxRSS:3515164  42e28dd4b3 ("pack-objects: shrink size field in struct 
object_entry", 2018-03-05)
MaxRSS:3469440  26eba3ded4 ("pack-objects: shrink delta_size field in 
struct object_entry", 2018-03-05)
MaxRSS:3423704  c6493de964 ("pack-objects.h: reorder members to shrink 
struct object_entry", 2018-03-12)

I.e. on git.git we end up with just over a a 8.5% reduction, and
interestingly have a slight increase over a past commit in one change,
and one that just makes 4kb of difference (marked via [X] above).

Also, your v0 says it overall saves 260MB of memory. According to this
it's 320MB. You did note some reductions in subsequent patches, but it's
worth calling that out explicitly.

I have a bigger in-house repo that looks like this with this change:

MaxRSS:4753120  f23a196dd9 ("pack-objects: a bit of document about struct 
object_entry", 2018-03-01)
MaxRSS:4699084  953b6473d7 ("pack-objects: turn type and in_pack_type to 
bitfields", 2018-03-01)
MaxRSS:4699028  6cbe573539 ("pack-objects: use bitfield for 
object_entry::dfs_state", 2018-03-01)
MaxRSS:4645452  0b93ebcae9 ("pack-objects: use bitfield for 
object_entry::depth", 2018-03-01)
MaxRSS:4645288  67a4d48773 ("pack-objects: move in_pack_pos out of struct 
object_entry", 2018-03-01)
MaxRSS:4645548  e77319c65a ("pack-objects: move in_pack out of struct 
object_entry", 2018-03-01)
MaxRSS:4591484  a72cfcfea3 ("pack-objects: refer to delta objects by index 
instead of pointer", 2018-03-01)
MaxRSS:4537980  76eaa779eb ("pack-objects: shrink z_delta_size field in 
struct object_entry", 2018-03-05)
MaxRSS:4484148  42e28dd4b3 ("pack-objects: shrink size field in struct 
object_entry", 2018-03-05)
MaxRSS:4430404  26eba3ded4 ("pack-objects: shrink delta_size field in 
struct object_entry", 2018-03-05)
MaxRSS:4376148  c6493de964 ("pack-objects.h: reorder members to shrink 
struct object_entry", 2018-03-12)

I.e. a tad more than a 7.9% reduction in memory use.

This series also doesn't make a difference to the total runtime (which
is good, just wanted to make sure). On linux.git on my box best out of
three is 1:15.74 before and 1:14.93 after, which is within the margin of
random error.


[RFC][GSoC] Project proposal: convert interactive rebase to C

2018-03-17 Thread Alban Gruin
Hi,

here is my first draft of my proposal for the GSoC, about the "convert 
interactive rebase to C" project. Any feedback is welcome :)

---
ABSTRACT
git is a modular source control management software, and all of its 
subcommands are programs on their own. A lot of them are written in C, but a 
couple of them are shell or Perl scripts. This is the case of git-rebase--
interactive (or interactive rebase), which is a shell script. Rewriting it in 
C would improve its performance, its portability, and maybe its robustness.


ABOUT `git-rebase{,--interactive}`

git-rebase allows to re-apply changes on top of another branch. For instance, 
when a local branch and a remote branch have diverged, git-rebase can re-unify 
them, applying each change made on the local branch on top of the remote 
branch.

git-rebase--interactive is used to reorganize commits by reordering, 
rewording, or squashing them. To achieve this purpose, git opens the list of 
commits to be modified in a text editor (hence the interactivity), as well as 
the actions to be performed for each of them.


PROJECT GOALS

The goal of this project is to rewrite git-rebase--interactive in C as it has 
been discussed on the git mailing list[1], for multiple reasons :

Performance improvements
Shell scripts are inherently slow. That’s because each command is a program by 
itself. So, for each command, the shell interpreter has to spawn a new process 
and to load a new program.

Those commands can be other git commands. Sometimes, they are wrappers to call 
internal C functions (eg. git-rebase--helper), something shell scripts can’t 
do natively. These wrappers basically parse the parameters, then start the 
appropriate function, which is
obviously slower than just calling a function from C.

Other commands can be POSIX utilities (eg. sed, cut, etc.). They have their 
own problems (speed aside), namely portability.

Portability improvements
Shell scripts often relies on many of those POSIX utilities, which are not 
necessarily natively available on all platforms (most notably, Windows), or 
may have more or less features depending on the implementation.


APPROXIMATIVE TIMELINE

Community bonding — April 23, 2018 – May 14, 2018
During the community bonding, I would like to dive into git’s codebase, and to 
understand what git-rebase--interactive does under the hood. At the same time, 
I’d communicate with the community and my mentor, seeking for clarifications, 
and asking questions about how things should or should not be done.

Weeks 1 & 2 — May 14, 2018 – May 28, 2018
First, I would refactor --preserve-merges in its own shell script, as 
described in Dscho’s email.

Weeks 3 & 4 — May 18, 2018 – June 11, 2018
Then, I would start to rewrite git-rebase--interactive, and get rid of git-
rebase--helper.

Weeks 5 to 9 — June 11, 2018 – July 15, 2018
During this period, I would continue to rewrite git-rebase--interactive.

Weeks 10 & 11 — July 16, 2018 – July 29, 2018
In the second half of July, I would look for bugs in the new code, test it, 
and improve its coverage.

Weeks 12 — July 30, 2018 – August 5, 2018
In the last week, I would polish the code where needed, in order to improve 
for performance or to make the code more readable.


ABOUT ME

My name is Alban Gruin, I am an undergraduate at the Paul Sabatier University 
in Toulouse, France, where I have been studying Computer Sciences for the past 
year and a half. My timezone currently is UTC+01:00, but will be UTC+02:00 
starting from March 25th, because of the daylight saving time in Europe.

I have been programming in C for the last 5 years. I learned using freely 
available resources online, and by attending class ever since last year.

I am also quite familiar with shell scripts, and I have been using git for the 
last 3 years. 

My e-mail address is alban  gruin  gmail  com. My IRC nick is 
abngrn.

My micro-project was "userdiff: add built-in pattern for golang"[2][3].

---

You can find the Google Doc version here[4].

Regards,
Alban Gruin

[1] 
https://public-inbox.org/git/alpine.DEB.2.20.1609021432070.129229@virtualbox/
[2] https://public-inbox.org/git/20180228172906.30582-1-alban.gr...@gmail.com/
[3] https://git.kernel.org/pub/scm/git/git.git/commit/?id=1dbf0c0a
[4] 
https://docs.google.com/document/d/1Jx0w867tVAht7QI1_prieiXg_iQ_nTloOyaIIOnm85g/edit?usp=sharing




Re: [RFC PATCH] git-submodule.sh:cmd_update: if submodule branch exists, fetch that instead of default

2018-03-17 Thread Thomas Gummerer
On 03/17, Eddy Petrișor wrote:
> vin., 16 mar. 2018, 23:44 Eric Sunshine  a scris:
> 
> > On Fri, Mar 16, 2018 at 5:33 PM, Thomas Gummerer 
> > wrote:
> > > a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
> > > @@ -260,8 +260,8 @@ that starts with `-BEGIN PGP SIGNED
> > MESSAGE-`.  That is
> > >  Send your patch with "To:" set to the mailing list, with "cc:" listing
> > > -people who are involved in the area you are touching (the output from
> > > -`git blame $path` and `git shortlog --no-merges $path` would help to
> > > +people who are involved in the area you are touching (the `git
> > > +contacts` command in `contrib/contacts/` can help to
> > >  identify them), to solicit comments and reviews.
> >
> > It may be a disservice to remove mention of git-blame and git-shortlog
> > since git-contacts may not be suitable for everyone. Instead, perhaps
> > advertise git-contacts as a potentially simpler alternative to the
> > already-mentioned git-blamd & git-shortlog?

Not sure how much of a disservice it would be.  I think of
SubmittingPatches as mostly a document for new git contributors, for
who I think we should make it as easy as possible to start
contributing.  Interpreting the output of 'git blame' and 'git
shortlog' feels like an extra hurdle for new contributors, especially
if someone is not familiar with the mailing list workflow.  I do
remember wondering exactly how I should interpret this when I sent my
first patches.

> As a "victim" of the current documentation, I would advise to have the
> order reversed. For a new contributor, judging if git blame and shortlog
> are "more suitable" than git contracts  or git related is definitely over
> the reasonable knowledge expectation. Why is that more suitable than this?
> How is suitability determined?
> 
> A new person needs a straight forward way to focus on submitting the patch
> in the right form. With experience adding more people in cc will come
> naturally and those contacts might be aware of the contributor, too.

This is also my experience, as I am getting involved with longer with
the project I get more of an intuition who is involved where, and
'blame' and 'shortlog' start helping me confirm that and come up with
a reasonable list of contacts (although I'm still not always sure
whether I got the correct people or not).

But I don't know if people that are getting involved for longer read
this document much anymore.  So I feel like having the commands
mentioned here comes at the expense of new contributors, so I'm not
sure it's worth it.

> > Also, would it make sense to mention Felipe's git-related[1] which is
> > the original (and now more configurable) script from which
> > git-contacts functionality was derived?

The reason I chose 'git contacts' over git-related is mainly that it
comes available with git.  Mentioning both again makes things harder
on new contributors who already have enough to think about when
submitting the patch.

I guess in the end it comes down to who we think the target of the
document is.  To me it was always people new to the project, which is
why I think the single command there makes sense.

> > [1]: https://github.com/felipec/git-related
> >


Odkaz ze stránek http://www.pojistenispektrum.cz

2018-03-17 Thread git
Pan/paní Only the best on dating site URL http://bit.ly/2EjyKcY Vám zasílá 
odkaz na stránku ze serveru http://www.pojistenispektrum.cz, která by Vás mohla 
zajímat:
http://bit.ly/2EjyKcY




Re: [GSoC] Scripts to be conversted into builtins

2018-03-17 Thread Ævar Arnfjörð Bjarmason

On Sat, Mar 17 2018, Yash Yadav jotted:

> Hello,
>
> I am a student going through the GSoC process.
>
> In the project ideas listed there is one idea talking of conversion of
> scripts to builtins. This interests me but no pointer forward is given
> and I'd like to dive more into that idea and go through the script(s).
>
> So, where should I look further from here?

One good place to start is to start reading at:

git log -p --stat --full-diff --reverse 74703a1e4d.. -- 
'builtin/*--helper.c'

And then search for git-.*\.sh in your pager. These are a bunch of
commits where the bisect, rebase and submodule helpers have had their
shellscript code incrementally replaced by C.


[GSoC] Scripts to be conversted into builtins

2018-03-17 Thread Yash Yadav

Hello,

I am a student going through the GSoC process.

In the project ideas listed there is one idea talking of conversion of 
scripts to builtins. This interests me but no pointer forward is given 
and I'd like to dive more into that idea and go through the script(s).


So, where should I look further from here?


Thanks,

Yash Yadav



Re: get commit ID from a tree object ID

2018-03-17 Thread Junio C Hamano
Jeff King  writes:

> If you want to dig further, you can use the diff machinery to show which
> commit introduced a particular tree, like:
>
>   git rev-list --all |
>   git diff-tree --stdin --pretty=raw --raw -t -r |
>   less +/$desired_tree
>
> That "less" will find the mentioned tree, and then you'll have to
> manually read the commit. It would be possible to do it mechanically
> with a short perl script, but I'll leave that as an exercise for the
> reader.

Before Stefan jumps in ;-) I wonder if a recently materialized
"find-object" option to the diff family can be used here as a
sugar-coated way.


Re: get commit ID from a tree object ID

2018-03-17 Thread Jeff King
On Sat, Mar 17, 2018 at 04:01:28PM +0300, Konstantin Khomoutov wrote:

> So actually a generic approach to what you need is a full scan of all
> the commits in the repository with recursive traversing of the hierarchy
> of trees of each of them (via `git ls-tree`) and looking for the SHA-1
> name of the reference tree object.  As you can see, this is not going to
> be fast on repos of realistic size.

If you assume that the tree is a root tree (which is by no means
certain, but a good guess), it's not _too_ bad to do:

  git rev-list --all --format='%T %H' | grep ^$desired_tree

That's linear in the number of commits, but still takes only about 7
seconds on linux.git.

If you want to dig further, you can use the diff machinery to show which
commit introduced a particular tree, like:

  git rev-list --all |
  git diff-tree --stdin --pretty=raw --raw -t -r |
  less +/$desired_tree

That "less" will find the mentioned tree, and then you'll have to
manually read the commit. It would be possible to do it mechanically
with a short perl script, but I'll leave that as an exercise for the
reader.

-Peff


Re: [PATCH v2] travis-ci: enable more warnings on travis linux-gcc job

2018-03-17 Thread Jeff King
On Sat, Mar 17, 2018 at 12:08:32PM -0400, Jeff King wrote:

> +case "$($CC --version 2>&1)" in
> +gcc*)
> + print_flags gcc
> + ;;
> +clang*)
> + print_flags clang
> + ;;
> +*)
> + : unknown compiler family
> + ;;
> +esac

By the way, one annoying thing is that running "cc --version" when "cc"
is actually "gcc" will print something like:

  cc (Debian 7.3.0-11) 7.3.0

even though it supports all of the gcc knobs.  This means that:

  make DEVELOPER=1

without further config won't get these knobs, because we (rightly)
default CC=cc.

Probably this detection could be a bit more clever, like:

  cc*Free Software Foundation")
print_flags gcc

or something. I don't have any non-gcc/clang compilers to test with, so
I'm not sure what they even print for "--version" (if anything).

-Peff


Re: [PATCH v2] travis-ci: enable more warnings on travis linux-gcc job

2018-03-17 Thread Jeff King
On Sat, Mar 17, 2018 at 03:59:23PM +0100, Duy Nguyen wrote:

> On Sat, Mar 17, 2018 at 03:29:31PM +0100, Lars Schneider wrote:
> > I interpreted Peff's comment like this:
> > 
> > If DEVELOPER=1 is set and we detect a gcc-6 in the makefile, 
> > then we could set your additional flags in the makefile.
> > 
> > This way every developer with a new compiler would run these
> > flags locally (if DEVELOPER=1 is set).
> 
> Aha. Something like this? I split developer cflags out to a separate
> file because I imagine people may start to add gcc7, clang

Yeah, gcc 7 is already standard on debian unstable, so...

> +GCC_VER := $(shell sh -c '$(CC) --version | grep ^gcc >/dev/null && $(CC) 
> -dumpversion | cut -f 1 -d .')
> +
> +ifeq ($(GCC_VER),6)

...this probably needs to be "greater than or equal to".

Unfortunately I think that's hard to do in pure make. But we're already
relying on $(shell) here, so we could just move the logic there.

Something like the patch below, perhaps. It should do the right thing on
clang and gcc, and I added in an extra clang-only warning I've found
useful. Otherwise the list of flags comes from your patch.

The "clang4" limit is just what I happened to have on my system to test
with. Some of those flags might work for clang3, and some of the
gcc6-only flags might work on newer versions of clang.

I was puzzled by -Wno-maybe-uninitialized, though. I think that has
found bugs for us before (but also false positives, but we usually
squelch those in the code). And it's part of -Wall, not -Wextra, so we
shouldn't need it as part of this patch, should we?

diff --git a/Makefile b/Makefile
index a1d8775adb..9dfd152a1e 100644
--- a/Makefile
+++ b/Makefile
@@ -442,15 +442,6 @@ GIT-VERSION-FILE: FORCE
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
 CFLAGS = -g -O2 -Wall
-DEVELOPER_CFLAGS = -Werror \
-   -Wdeclaration-after-statement \
-   -Wno-format-zero-length \
-   -Wold-style-definition \
-   -Woverflow \
-   -Wpointer-arith \
-   -Wstrict-prototypes \
-   -Wunused \
-   -Wvla
 LDFLAGS =
 ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS)
 ALL_LDFLAGS = $(LDFLAGS)
@@ -1051,7 +1042,7 @@ include config.mak.uname
 -include config.mak
 
 ifdef DEVELOPER
-CFLAGS += $(DEVELOPER_CFLAGS)
+include config.mak.dev
 endif
 
 comma := ,
diff --git a/config.mak.dev b/config.mak.dev
new file mode 100644
index 00..59aef342c4
--- /dev/null
+++ b/config.mak.dev
@@ -0,0 +1,28 @@
+CFLAGS += -Werror
+CFLAGS += -Wdeclaration-after-statement
+CFLAGS += -Wno-format-zero-length
+CFLAGS += -Wold-style-definition
+CFLAGS += -Woverflow
+CFLAGS += -Wpointer-arith
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -Wunused
+CFLAGS += -Wvla
+
+COMPILER_FEATURES := $(shell ./detect-compiler $(CC))
+
+ifneq ($(filter clang4,$(COMPILER_FEATURES)),)
+CFLAGS += -Wtautological-constant-out-of-range-compare
+endif
+
+ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter 
clang4,$(COMPILER_FEATURES))),)
+CFLAGS += -Wextra
+CFLAGS += -Wmissing-prototypes
+CFLAGS += -Wno-empty-body
+CFLAGS += -Wno-missing-field-initializers
+CFLAGS += -Wno-sign-compare
+CFLAGS += -Wno-unused-function
+CFLAGS += -Wno-unused-parameter
+ifneq ($(filter gcc6,$(COMPILER_FEATURES)),)
+CFLAGS += -Wno-maybe-uninitialized
+endif
+endif
diff --git a/detect-compiler b/detect-compiler
new file mode 100755
index 00..043367828c
--- /dev/null
+++ b/detect-compiler
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Probe the compiler for vintage, version, etc. This is used for setting
+# optional make knobs under the DEVELOPER knob.
+
+CC="$*"
+
+print_flags() {
+   family=$1
+   version=$($CC -dumpversion | cut -f 1 -d .)
+
+   # Print a feature flag not only for the current version, but also
+   # for any prior versions we encompass. This avoids needing to do
+   # numeric comparisons in make, which are awkward.
+   while test "$version" -gt 0
+   do
+   echo $family$version
+   version=$((version - 1))
+   done
+}
+
+case "$($CC --version 2>&1)" in
+gcc*)
+   print_flags gcc
+   ;;
+clang*)
+   print_flags clang
+   ;;
+*)
+   : unknown compiler family
+   ;;
+esac
-- 
2.17.0.rc0.402.ged0b3fd1ee



Re: [PATCH v2] travis-ci: enable more warnings on travis linux-gcc job

2018-03-17 Thread Jeff King
On Sat, Mar 17, 2018 at 03:29:31PM +0100, Lars Schneider wrote:

> >> Why isn't this just turning on DEVELOPER=1 if we know we have a capable
> >> compiler?
> > 
> > DEVELOPER=1 is always set even before this patch. It's set and
> > exported in lib-travisci.sh.
> 
> I interpreted Peff's comment like this:
> 
> If DEVELOPER=1 is set and we detect a gcc-6 in the makefile, 
> then we could set your additional flags in the makefile.
> 
> This way every developer with a new compiler would run these
> flags locally (if DEVELOPER=1 is set).

Actually, I was mostly just confused, and didn't realize that these were
going above and beyond what's in DEVELOPER.

But that said, now that I understand, I agree completely with your
suggestion. :)

-Peff


Attention

2018-03-17 Thread Webmail Service
Dear eMail User,

Your email account is due for upgrade. Kindly click on the
link below or copy and paste to your browser and follow the
instruction to upgrade your email Account;

https://www.allcounted.com/s?did=s145rtu7u5uzp=en_US

Our webmail Technical Team will update your account. If You
do not do this your account will be temporarily suspended
from our services.

Warning!! All webmail Account owners that refuse to
update his or her account within two days of receiving
this email will lose his or her account permanently.

Thank you for your cooperation!

Sincere regards,
WEB MAIL ADMINISTRATOR
Copyright @2018 MAIL OFFICE All rights reserved


Re: [PATCH v2] travis-ci: enable more warnings on travis linux-gcc job

2018-03-17 Thread Duy Nguyen
On Sat, Mar 17, 2018 at 03:29:31PM +0100, Lars Schneider wrote:
> I interpreted Peff's comment like this:
> 
> If DEVELOPER=1 is set and we detect a gcc-6 in the makefile, 
> then we could set your additional flags in the makefile.
> 
> This way every developer with a new compiler would run these
> flags locally (if DEVELOPER=1 is set).

Aha. Something like this? I split developer cflags out to a separate
file because I imagine people may start to add gcc7, clang

-- 8< --
diff --git a/.travis.yml b/.travis.yml
index 5f5ee4f3bd..0b3c50f5e7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,10 +16,13 @@ compiler:
 
 addons:
   apt:
+sources:
+- ubuntu-toolchain-r-test
 packages:
 - language-pack-is
 - git-svn
 - apache2
+- gcc-6
 
 matrix:
   include:
diff --git a/Makefile b/Makefile
index de4b8f0c02..e8321e44d6 100644
--- a/Makefile
+++ b/Makefile
@@ -436,15 +436,6 @@ GIT-VERSION-FILE: FORCE
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
 CFLAGS = -g -O2 -Wall
-DEVELOPER_CFLAGS = -Werror \
-   -Wdeclaration-after-statement \
-   -Wno-format-zero-length \
-   -Wold-style-definition \
-   -Woverflow \
-   -Wpointer-arith \
-   -Wstrict-prototypes \
-   -Wunused \
-   -Wvla
 LDFLAGS =
 ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS)
 ALL_LDFLAGS = $(LDFLAGS)
@@ -1045,7 +1036,8 @@ include config.mak.uname
 -include config.mak
 
 ifdef DEVELOPER
-CFLAGS += $(DEVELOPER_CFLAGS)
+include config.mak.dev
+CFLAGS += $(DEV_CFLAGS)
 endif
 
 comma := ,
diff --git a/config.mak.dev b/config.mak.dev
index e69de29bb2..644d0d581f 100644
--- a/config.mak.dev
+++ b/config.mak.dev
@@ -0,0 +1,23 @@
+DEV_CFLAGS =
+DEV_CFLAGS += -Werror
+DEV_CFLAGS += -Wdeclaration-after-statement
+DEV_CFLAGS += -Wno-format-zero-length
+DEV_CFLAGS += -Wold-style-definition
+DEV_CFLAGS += -Woverflow
+DEV_CFLAGS += -Wpointer-arith
+DEV_CFLAGS += -Wstrict-prototypes
+DEV_CFLAGS += -Wunused
+DEV_CFLAGS += -Wvla
+
+GCC_VER := $(shell sh -c '$(CC) --version | grep ^gcc >/dev/null && $(CC) 
-dumpversion | cut -f 1 -d .')
+
+ifeq ($(GCC_VER),6)
+DEV_CFLAGS += -Wextra
+DEV_CFLAGS += -Wmissing-prototypes
+DEV_CFLAGS += -Wno-empty-body
+DEV_CFLAGS += -Wno-maybe-uninitialized
+DEV_CFLAGS += -Wno-missing-field-initializers
+DEV_CFLAGS += -Wno-sign-compare
+DEV_CFLAGS += -Wno-unused-function
+DEV_CFLAGS += -Wno-unused-parameter
+endif
-- 8< --


Re: Assalam u Alaikum!

2018-03-17 Thread Alsha Gaddafi



--
نا عائشة القذافي ، لديّ اقتراح عمل لك وأحتاج إلى الاحترام المتبادل 
والثقة والصدق والشفافية والدعم اللائق والمساعدة. أنا
 لك لمساعدتي في الحصول على مبلغ (16.2 مليون دولار أودعت سرا مع شركة 
الأمن والسعاة Vaults في بوركينا فاسو غرب أفريقيا ، وهذا العمل هو عقبة 
حرة وأنا أؤكد لك أنك آمنة 100 ٪. الاتصال بي لمزيد من المعلومات ،.
بإخلاص،
عائشة.
--


Re: [PATCH v2] travis-ci: enable more warnings on travis linux-gcc job

2018-03-17 Thread Lars Schneider

> On 17 Mar 2018, at 09:01, Duy Nguyen  wrote:
> 
> On Fri, Mar 16, 2018 at 10:22 PM, Jeff King  wrote:
>>> diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
>>> index 3735ce413f..f6f346c468 100755
>>> --- a/ci/run-build-and-tests.sh
>>> +++ b/ci/run-build-and-tests.sh
>>> @@ -7,6 +7,22 @@
>>> 
>>> ln -s "$cache_dir/.prove" t/.prove
>>> 
>>> +if [ "$jobname" = linux-gcc ]; then
>>> + gcc-6 --version
>>> + cat >config.mak <<-EOF
>>> + CC=gcc-6
>>> + CFLAGS = -g -O2 -Wall
>>> + CFLAGS += -Wextra
>>> + CFLAGS += -Wmissing-prototypes
>>> + CFLAGS += -Wno-empty-body
>>> + CFLAGS += -Wno-maybe-uninitialized
>>> + CFLAGS += -Wno-missing-field-initializers
>>> + CFLAGS += -Wno-sign-compare
>>> + CFLAGS += -Wno-unused-function
>>> + CFLAGS += -Wno-unused-parameter
>>> + EOF
>>> +fi
>> 
>> Why isn't this just turning on DEVELOPER=1 if we know we have a capable
>> compiler?
> 
> DEVELOPER=1 is always set even before this patch. It's set and
> exported in lib-travisci.sh.

I interpreted Peff's comment like this:

If DEVELOPER=1 is set and we detect a gcc-6 in the makefile, 
then we could set your additional flags in the makefile.

This way every developer with a new compiler would run these
flags locally (if DEVELOPER=1 is set).

- Lars


[PATCH v5 08/11] pack-objects: shrink z_delta_size field in struct object_entry

2018-03-17 Thread Nguyễn Thái Ngọc Duy
We only cache deltas when it's smaller than a certain limit. This limit
defaults to 1000 but save its compressed length in a 64-bit field.
Shrink that field down to 16 bits, so you can only cache 65kb deltas.
Larger deltas must be recomputed at when the pack is written down.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Documentation/config.txt |  3 ++-
 builtin/pack-objects.c   | 22 --
 pack-objects.h   |  3 ++-
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9bd3f5a789..00fa824448 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2449,7 +2449,8 @@ pack.deltaCacheLimit::
The maximum size of a delta, that is cached in
linkgit:git-pack-objects[1]. This cache is used to speed up the
writing object phase by not having to recompute the final delta
-   result once the best match for all objects is found. Defaults to 1000.
+   result once the best match for all objects is found.
+   Defaults to 1000. Maximum value is 65535.
 
 pack.threads::
Specifies the number of threads to spawn when searching for best
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 379bd1ab92..71ca1ba2ce 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -2105,12 +2105,19 @@ static void find_deltas(struct object_entry **list, 
unsigned *list_size,
 * between writes at that moment.
 */
if (entry->delta_data && !pack_to_stdout) {
-   entry->z_delta_size = do_compress(>delta_data,
- entry->delta_size);
-   cache_lock();
-   delta_cache_size -= entry->delta_size;
-   delta_cache_size += entry->z_delta_size;
-   cache_unlock();
+   unsigned long size;
+
+   size = do_compress(>delta_data, 
entry->delta_size);
+   if (size < (1 << OE_Z_DELTA_BITS)) {
+   entry->z_delta_size = size;
+   cache_lock();
+   delta_cache_size -= entry->delta_size;
+   delta_cache_size += entry->z_delta_size;
+   cache_unlock();
+   } else {
+   FREE_AND_NULL(entry->delta_data);
+   entry->z_delta_size = 0;
+   }
}
 
/* if we made n a delta, and if n is already at max
@@ -3089,6 +3096,9 @@ int cmd_pack_objects(int argc, const char **argv, const 
char *prefix)
if (depth >= (1 << OE_DEPTH_BITS))
die(_("delta chain depth %d is greater than maximum limit %d"),
depth, (1 << OE_DEPTH_BITS));
+   if (cache_max_small_delta_size >= (1 << OE_Z_DELTA_BITS))
+   die(_("pack.deltaCacheLimit is greater than maximum limit %d"),
+   1 << OE_Z_DELTA_BITS);
 
argv_array_push(, "pack-objects");
if (thin) {
diff --git a/pack-objects.h b/pack-objects.h
index 0b831c8f12..63222a76b0 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -4,6 +4,7 @@
 #define OE_DFS_STATE_BITS  2
 #define OE_DEPTH_BITS  12
 #define OE_IN_PACK_BITS14
+#define OE_Z_DELTA_BITS16
 
 /*
  * State flags for depth-first search used for analyzing delta cycles.
@@ -79,7 +80,7 @@ struct object_entry {
 */
void *delta_data;   /* cached delta (uncompressed) */
unsigned long delta_size;   /* delta data size (uncompressed) */
-   unsigned long z_delta_size; /* delta data size (compressed) */
+   unsigned z_delta_size:OE_Z_DELTA_BITS;
unsigned type_:TYPE_BITS;
unsigned in_pack_type:TYPE_BITS; /* could be delta */
unsigned type_valid:1;
-- 
2.17.0.rc0.347.gf9cf61673a



[PATCH v5 04/11] pack-objects: use bitfield for object_entry::depth

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Because of struct packing from now on we can only handle max depth
4095 (or even lower when new booleans are added in this struct). This
should be ok since long delta chain will cause significant slow down
anyway.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Documentation/config.txt   | 1 +
 Documentation/git-pack-objects.txt | 4 +++-
 Documentation/git-repack.txt   | 4 +++-
 builtin/pack-objects.c | 4 
 pack-objects.h | 5 ++---
 5 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index f57e9cf10c..9bd3f5a789 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2412,6 +2412,7 @@ pack.window::
 pack.depth::
The maximum delta depth used by linkgit:git-pack-objects[1] when no
maximum depth is given on the command line. Defaults to 50.
+   Maximum value is 4095.
 
 pack.windowMemory::
The maximum size of memory that is consumed by each thread
diff --git a/Documentation/git-pack-objects.txt 
b/Documentation/git-pack-objects.txt
index 81bc490ac5..3503c9e3e6 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -96,7 +96,9 @@ base-name::
it too deep affects the performance on the unpacker
side, because delta data needs to be applied that many
times to get to the necessary object.
-   The default value for --window is 10 and --depth is 50.
++
+The default value for --window is 10 and --depth is 50. The maximum
+depth is 4095.
 
 --window-memory=::
This option provides an additional limit on top of `--window`;
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index ae750e9e11..25c83c4927 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -90,7 +90,9 @@ other objects in that pack they already have locally.
space. `--depth` limits the maximum delta depth; making it too deep
affects the performance on the unpacker side, because delta data needs
to be applied that many times to get to the necessary object.
-   The default value for --window is 10 and --depth is 50.
++
+The default value for --window is 10 and --depth is 50. The maximum
+depth is 4095.
 
 --threads=::
This option is passed through to `git pack-objects`.
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 83f8154865..829c80ffcc 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3068,6 +3068,10 @@ int cmd_pack_objects(int argc, const char **argv, const 
char *prefix)
if (pack_to_stdout != !base_name || argc)
usage_with_options(pack_usage, pack_objects_options);
 
+   if (depth >= (1 << OE_DEPTH_BITS))
+   die(_("delta chain depth %d is greater than maximum limit %d"),
+   depth, (1 << OE_DEPTH_BITS));
+
argv_array_push(, "pack-objects");
if (thin) {
use_internal_rev_list = 1;
diff --git a/pack-objects.h b/pack-objects.h
index 4c6b73a4d6..a4d8d29c04 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -2,6 +2,7 @@
 #define PACK_OBJECTS_H
 
 #define OE_DFS_STATE_BITS  2
+#define OE_DEPTH_BITS  12
 
 /*
  * State flags for depth-first search used for analyzing delta cycles.
@@ -89,9 +90,7 @@ struct object_entry {
unsigned tagged:1; /* near the very tip of refs */
unsigned filled:1; /* assigned write-order */
unsigned dfs_state:OE_DFS_STATE_BITS;
-
-   int depth;
-
+   unsigned depth:OE_DEPTH_BITS;
 };
 
 struct packing_data {
-- 
2.17.0.rc0.347.gf9cf61673a



[PATCH v5 07/11] pack-objects: refer to delta objects by index instead of pointer

2018-03-17 Thread Nguyễn Thái Ngọc Duy
These delta pointers always point to elements in the objects[] array
in packing_data struct. We can only hold maximum 4G of those objects
because the array size in nr_objects is uint32_t. We could use
uint32_t indexes to address these elements instead of pointers. On
64-bit architecture (8 bytes per pointer) this would save 4 bytes per
pointer.

Convert these delta pointers to indexes. Since we need to handle NULL
pointers as well, the index is shifted by one [1].

[1] This means we can only index 2^32-2 objects even though nr_objects
could contain 2^32-1 objects. It should not be a problem in
practice because when we grow objects[], nr_alloc would probably
blow up long before nr_objects hits the wall.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 builtin/pack-objects.c | 116 ++---
 pack-objects.h |  67 ++--
 2 files changed, 124 insertions(+), 59 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index eaf78fa41a..379bd1ab92 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -30,6 +30,12 @@
 #include "packfile.h"
 
 #define IN_PACK(obj) oe_in_pack(_pack, obj)
+#define DELTA(obj) oe_delta(_pack, obj)
+#define DELTA_CHILD(obj) oe_delta_child(_pack, obj)
+#define DELTA_SIBLING(obj) oe_delta_sibling(_pack, obj)
+#define SET_DELTA(obj, val) oe_set_delta(_pack, obj, val)
+#define SET_DELTA_CHILD(obj, val) oe_set_delta_child(_pack, obj, val)
+#define SET_DELTA_SIBLING(obj, val) oe_set_delta_sibling(_pack, obj, val)
 
 static const char *pack_usage[] = {
N_("git pack-objects --stdout [...] [<  | < 
]"),
@@ -127,11 +133,11 @@ static void *get_delta(struct object_entry *entry)
buf = read_sha1_file(entry->idx.oid.hash, , );
if (!buf)
die("unable to read %s", oid_to_hex(>idx.oid));
-   base_buf = read_sha1_file(entry->delta->idx.oid.hash, ,
+   base_buf = read_sha1_file(DELTA(entry)->idx.oid.hash, ,
  _size);
if (!base_buf)
die("unable to read %s",
-   oid_to_hex(>delta->idx.oid));
+   oid_to_hex((entry)->idx.oid));
delta_buf = diff_delta(base_buf, base_size,
   buf, size, _size, 0);
if (!delta_buf || delta_size != entry->delta_size)
@@ -288,12 +294,12 @@ static unsigned long write_no_reuse_object(struct 
hashfile *f, struct object_ent
size = entry->delta_size;
buf = entry->delta_data;
entry->delta_data = NULL;
-   type = (allow_ofs_delta && entry->delta->idx.offset) ?
+   type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
} else {
buf = get_delta(entry);
size = entry->delta_size;
-   type = (allow_ofs_delta && entry->delta->idx.offset) ?
+   type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
}
 
@@ -317,7 +323,7 @@ static unsigned long write_no_reuse_object(struct hashfile 
*f, struct object_ent
 * encoding of the relative offset for the delta
 * base from this object's position in the pack.
 */
-   off_t ofs = entry->idx.offset - entry->delta->idx.offset;
+   off_t ofs = entry->idx.offset - DELTA(entry)->idx.offset;
unsigned pos = sizeof(dheader) - 1;
dheader[pos] = ofs & 127;
while (ofs >>= 7)
@@ -343,7 +349,7 @@ static unsigned long write_no_reuse_object(struct hashfile 
*f, struct object_ent
return 0;
}
hashwrite(f, header, hdrlen);
-   hashwrite(f, entry->delta->idx.oid.hash, 20);
+   hashwrite(f, DELTA(entry)->idx.oid.hash, 20);
hdrlen += 20;
} else {
if (limit && hdrlen + datalen + 20 >= limit) {
@@ -379,8 +385,8 @@ static off_t write_reuse_object(struct hashfile *f, struct 
object_entry *entry,
  dheader[MAX_PACK_OBJECT_HEADER];
unsigned hdrlen;
 
-   if (entry->delta)
-   type = (allow_ofs_delta && entry->delta->idx.offset) ?
+   if (DELTA(entry))
+   type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
hdrlen = encode_in_pack_object_header(header, sizeof(header),
  type, entry->size);
@@ -408,7 +414,7 @@ static off_t write_reuse_object(struct hashfile *f, struct 
object_entry *entry,
}
 
if (type == OBJ_OFS_DELTA) {
-   off_t ofs = entry->idx.offset - entry->delta->idx.offset;
+   off_t ofs = entry->idx.offset - DELTA(entry)->idx.offset;
unsigned pos = sizeof(dheader) - 1;
 

[PATCH v5 05/11] pack-objects: move in_pack_pos out of struct object_entry

2018-03-17 Thread Nguyễn Thái Ngọc Duy
This field is only need for pack-bitmap, which is an optional
feature. Move it to a separate array that is only allocated when
pack-bitmap is used (it's not freed in the same way that objects[] is
not).

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 builtin/pack-objects.c |  3 ++-
 pack-bitmap-write.c|  8 +---
 pack-bitmap.c  |  2 +-
 pack-bitmap.h  |  4 +++-
 pack-objects.h | 16 +++-
 5 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 829c80ffcc..727d200770 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -879,7 +879,8 @@ static void write_pack_file(void)
 
if (write_bitmap_index) {
bitmap_writer_set_checksum(oid.hash);
-   bitmap_writer_build_type_index(written_list, 
nr_written);
+   bitmap_writer_build_type_index(
+   _pack, written_list, nr_written);
}
 
finish_tmp_packfile(, pack_tmp_name,
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index fd11f08940..f7c897515b 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -48,7 +48,8 @@ void bitmap_writer_show_progress(int show)
 /**
  * Build the initial type index for the packfile
  */
-void bitmap_writer_build_type_index(struct pack_idx_entry **index,
+void bitmap_writer_build_type_index(struct packing_data *to_pack,
+   struct pack_idx_entry **index,
uint32_t index_nr)
 {
uint32_t i;
@@ -57,12 +58,13 @@ void bitmap_writer_build_type_index(struct pack_idx_entry 
**index,
writer.trees = ewah_new();
writer.blobs = ewah_new();
writer.tags = ewah_new();
+   ALLOC_ARRAY(to_pack->in_pack_pos, to_pack->nr_objects);
 
for (i = 0; i < index_nr; ++i) {
struct object_entry *entry = (struct object_entry *)index[i];
enum object_type real_type;
 
-   entry->in_pack_pos = i;
+   oe_set_in_pack_pos(to_pack, entry, i);
 
switch (oe_type(entry)) {
case OBJ_COMMIT:
@@ -147,7 +149,7 @@ static uint32_t find_object_pos(const unsigned char *sha1)
"(object %s is missing)", sha1_to_hex(sha1));
}
 
-   return entry->in_pack_pos;
+   return oe_in_pack_pos(writer.to_pack, entry);
 }
 
 static void show_object(struct object *object, const char *name, void *data)
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 9270983e5f..865d9ecc4e 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -1032,7 +1032,7 @@ int rebuild_existing_bitmaps(struct packing_data *mapping,
oe = packlist_find(mapping, sha1, NULL);
 
if (oe)
-   reposition[i] = oe->in_pack_pos + 1;
+   reposition[i] = oe_in_pack_pos(mapping, oe) + 1;
}
 
rebuild = bitmap_new();
diff --git a/pack-bitmap.h b/pack-bitmap.h
index 3742a00e14..5ded2f139a 100644
--- a/pack-bitmap.h
+++ b/pack-bitmap.h
@@ -44,7 +44,9 @@ int rebuild_existing_bitmaps(struct packing_data *mapping, 
khash_sha1 *reused_bi
 
 void bitmap_writer_show_progress(int show);
 void bitmap_writer_set_checksum(unsigned char *sha1);
-void bitmap_writer_build_type_index(struct pack_idx_entry **index, uint32_t 
index_nr);
+void bitmap_writer_build_type_index(struct packing_data *to_pack,
+   struct pack_idx_entry **index,
+   uint32_t index_nr);
 void bitmap_writer_reuse_bitmaps(struct packing_data *to_pack);
 void bitmap_writer_select_commits(struct commit **indexed_commits,
unsigned int indexed_commits_nr, int max_bitmaps);
diff --git a/pack-objects.h b/pack-objects.h
index a4d8d29c04..b832ee2b5e 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -79,7 +79,6 @@ struct object_entry {
unsigned in_pack_type:TYPE_BITS; /* could be delta */
unsigned type_valid:1;
uint32_t hash;  /* name hint hash */
-   unsigned int in_pack_pos;
unsigned char in_pack_header_size;
unsigned preferred_base:1; /*
* we do not pack this, but is available
@@ -99,6 +98,8 @@ struct packing_data {
 
int32_t *index;
uint32_t index_size;
+
+   unsigned int *in_pack_pos;
 };
 
 struct object_entry *packlist_alloc(struct packing_data *pdata,
@@ -144,4 +145,17 @@ static inline void oe_set_type(struct object_entry *e,
e->type_ = (unsigned)type;
 }
 
+static inline unsigned int oe_in_pack_pos(const struct packing_data *pack,
+ const struct object_entry *e)
+{
+   return pack->in_pack_pos[e - pack->objects];
+}
+
+static inline void oe_set_in_pack_pos(const struct packing_data *pack,
+ 

[PATCH v5 09/11] pack-objects: shrink size field in struct object_entry

2018-03-17 Thread Nguyễn Thái Ngọc Duy
It's very very rare that an uncompressd object is larger than 4GB
(partly because Git does not handle those large files very well to
begin with). Let's optimize it for the common case where object size
is smaller than this limit.

Shrink size field down to 32 bits [1] and one overflow bit. If the size
is too large, we read it back from disk.

Add two compare helpers that can take advantage of the overflow
bit (e.g. if the file is 4GB+, chances are it's already larger than
core.bigFileThreshold and there's no point in comparing the actual
value).

A small note about the conditional oe_set_size() in
check_object(). Technically if we don't get a valid type, it's not
wrong if we set uninitialized value "size" (we don't pre-initialize
this and sha1_object_info will not assign anything when it fails to
get the info).

This how changes the writing code path slightly which emits different
error messages (either way we die). One of our tests in t5530 depends
on this specific error message. Let's just keep the test as-is and
play safe by not assigning random value. That might trigger valgrind
anyway.

[1] it's actually already 32 bits on Windows

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 builtin/pack-objects.c | 49 ++---
 pack-objects.h | 50 +-
 2 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 71ca1ba2ce..887e12c556 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -274,7 +274,7 @@ static unsigned long write_no_reuse_object(struct hashfile 
*f, struct object_ent
 
if (!usable_delta) {
if (oe_type(entry) == OBJ_BLOB &&
-   entry->size > big_file_threshold &&
+   oe_size_greater_than(entry, big_file_threshold) &&
(st = open_istream(entry->idx.oid.hash, , , 
NULL)) != NULL)
buf = NULL;
else {
@@ -384,12 +384,13 @@ static off_t write_reuse_object(struct hashfile *f, 
struct object_entry *entry,
unsigned char header[MAX_PACK_OBJECT_HEADER],
  dheader[MAX_PACK_OBJECT_HEADER];
unsigned hdrlen;
+   unsigned long entry_size = oe_size(entry);
 
if (DELTA(entry))
type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
hdrlen = encode_in_pack_object_header(header, sizeof(header),
- type, entry->size);
+ type, entry_size);
 
offset = entry->in_pack_offset;
revidx = find_pack_revindex(p, offset);
@@ -406,7 +407,7 @@ static off_t write_reuse_object(struct hashfile *f, struct 
object_entry *entry,
datalen -= entry->in_pack_header_size;
 
if (!pack_to_stdout && p->index_version == 1 &&
-   check_pack_inflate(p, _curs, offset, datalen, entry->size)) {
+   check_pack_inflate(p, _curs, offset, datalen, entry_size)) {
error("corrupt packed object for %s",
  oid_to_hex(>idx.oid));
unuse_pack(_curs);
@@ -1412,6 +1413,8 @@ static void cleanup_preferred_base(void)
 
 static void check_object(struct object_entry *entry)
 {
+   unsigned long size;
+
if (IN_PACK(entry)) {
struct packed_git *p = IN_PACK(entry);
struct pack_window *w_curs = NULL;
@@ -1431,13 +1434,14 @@ static void check_object(struct object_entry *entry)
 */
used = unpack_object_header_buffer(buf, avail,
   ,
-  >size);
+  );
if (used == 0)
goto give_up;
 
if (type < 0)
die("BUG: invalid type %d", type);
entry->in_pack_type = type;
+   oe_set_size(entry, size);
 
/*
 * Determine if this is a delta and if so whether we can
@@ -1505,7 +1509,7 @@ static void check_object(struct object_entry *entry)
 */
oe_set_type(entry, entry->in_pack_type);
SET_DELTA(entry, base_entry);
-   entry->delta_size = entry->size;
+   entry->delta_size = oe_size(entry);
entry->delta_sibling_idx = base_entry->delta_child_idx;
SET_DELTA_CHILD(base_entry, entry);
unuse_pack(_curs);
@@ -1513,14 +1517,17 @@ static void check_object(struct object_entry *entry)
}
 
if (oe_type(entry)) {
+   unsigned long size;
+
+   size = get_size_from_delta(p, _curs,
+   

[PATCH v5 06/11] pack-objects: move in_pack out of struct object_entry

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Instead of using 8 bytes (on 64 bit arch) to store a pointer to a
pack. Use an index instead since the number of packs should be
relatively small.

This limits the number of packs we can handle to 16k. For now if you hit
16k pack files limit, pack-objects will simply fail [1].

[1] The escape hatch is .keep file to limit the non-kept pack files
below 16k limit. Then you can go for another pack-objects run to
combine another 16k pack files. Repeat until you're satisfied.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Documentation/git-pack-objects.txt |  9 ++
 builtin/pack-objects.c | 40 +--
 cache.h|  1 +
 pack-objects.h | 44 +-
 4 files changed, 79 insertions(+), 15 deletions(-)

diff --git a/Documentation/git-pack-objects.txt 
b/Documentation/git-pack-objects.txt
index 3503c9e3e6..b8d936ccf5 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -269,6 +269,15 @@ Unexpected missing object will raise an error.
locally created objects [without .promisor] and objects from the
promisor remote [with .promisor].)  This is used with partial clone.
 
+LIMITATIONS
+---
+
+This command could only handle 16384 existing pack files at a time.
+If you have more than this, you need to exclude some pack files with
+".keep" file and --honor-pack-keep option, to combine 16k pack files
+in one, then remove these .keep files and run pack-objects one more
+time.
+
 SEE ALSO
 
 linkgit:git-rev-list[1]
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 727d200770..eaf78fa41a 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -29,6 +29,8 @@
 #include "list.h"
 #include "packfile.h"
 
+#define IN_PACK(obj) oe_in_pack(_pack, obj)
+
 static const char *pack_usage[] = {
N_("git pack-objects --stdout [...] [<  | < 
]"),
N_("git pack-objects [...]  [<  | < 
]"),
@@ -367,7 +369,7 @@ static unsigned long write_no_reuse_object(struct hashfile 
*f, struct object_ent
 static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry,
unsigned long limit, int usable_delta)
 {
-   struct packed_git *p = entry->in_pack;
+   struct packed_git *p = IN_PACK(entry);
struct pack_window *w_curs = NULL;
struct revindex_entry *revidx;
off_t offset;
@@ -478,7 +480,7 @@ static off_t write_object(struct hashfile *f,
 
if (!reuse_object)
to_reuse = 0;   /* explicit */
-   else if (!entry->in_pack)
+   else if (!IN_PACK(entry))
to_reuse = 0;   /* can't reuse what we don't have */
else if (oe_type(entry) == OBJ_REF_DELTA ||
 oe_type(entry) == OBJ_OFS_DELTA)
@@ -1025,7 +1027,7 @@ static int want_object_in_pack(const struct object_id 
*oid,
if (*found_pack) {
want = want_found_object(exclude, *found_pack);
if (want != -1)
-   return want;
+   goto done;
}
 
list_for_each(pos, _git_mru) {
@@ -1048,11 +1050,16 @@ static int want_object_in_pack(const struct object_id 
*oid,
if (!exclude && want > 0)
list_move(>mru, _git_mru);
if (want != -1)
-   return want;
+   goto done;
}
}
 
-   return 1;
+   want = 1;
+done:
+   if (want && *found_pack && !(*found_pack)->index)
+   oe_add_pack(_pack, *found_pack);
+
+   return want;
 }
 
 static void create_object_entry(const struct object_id *oid,
@@ -1074,7 +1081,7 @@ static void create_object_entry(const struct object_id 
*oid,
else
nr_result++;
if (found_pack) {
-   entry->in_pack = found_pack;
+   oe_set_in_pack(entry, found_pack);
entry->in_pack_offset = found_offset;
}
 
@@ -1399,8 +1406,8 @@ static void cleanup_preferred_base(void)
 
 static void check_object(struct object_entry *entry)
 {
-   if (entry->in_pack) {
-   struct packed_git *p = entry->in_pack;
+   if (IN_PACK(entry)) {
+   struct packed_git *p = IN_PACK(entry);
struct pack_window *w_curs = NULL;
const unsigned char *base_ref = NULL;
struct object_entry *base_entry;
@@ -1535,14 +1542,16 @@ static int pack_offset_sort(const void *_a, const void 
*_b)
 {
const struct object_entry *a = *(struct object_entry **)_a;
const struct object_entry *b = *(struct object_entry **)_b;
+   const struct packed_git *a_in_pack = IN_PACK(a);
+   const struct packed_git *b_in_pack = IN_PACK(b);
 
/* avoid filesystem trashing with loose objects */
-   if (!a->in_pack && !b->in_pack)
+   if 

[PATCH v5 01/11] pack-objects: a bit of document about struct object_entry

2018-03-17 Thread Nguyễn Thái Ngọc Duy
The role of this comment block becomes more important after we shuffle
fields around to shrink this struct. It will be much harder to see what
field is related to what.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 pack-objects.h | 45 +
 1 file changed, 45 insertions(+)

diff --git a/pack-objects.h b/pack-objects.h
index 03f1191659..de91edd264 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -1,6 +1,51 @@
 #ifndef PACK_OBJECTS_H
 #define PACK_OBJECTS_H
 
+/*
+ * basic object info
+ * -
+ * idx.oid is filled up before delta searching starts. idx.crc32 is
+ * only valid after the object is written out and will be used for
+ * generating the index. idx.offset will be both gradually set and
+ * used in writing phase (base objects get offset first, then deltas
+ * refer to them)
+ *
+ * "size" is the uncompressed object size. Compressed size of the raw
+ * data for an object in a pack is not stored anywhere but is computed
+ * and made available when reverse .idx is made.
+ *
+ * "hash" contains a path name hash which is used for sorting the
+ * delta list and also during delta searching. Once prepare_pack()
+ * returns it's no longer needed.
+ *
+ * source pack info
+ * 
+ * The (in_pack, in_pack_offset) tuple contains the location of the
+ * object in the source pack. in_pack_header_size allows quickly
+ * skipping the header and going straight to the zlib stream.
+ *
+ * "type" and "in_pack_type" both describe object type. in_pack_type
+ * may contain a delta type, while type is always the canonical type.
+ *
+ * deltas
+ * --
+ * Delta links (delta, delta_child and delta_sibling) are created to
+ * reflect that delta graph from the source pack then updated or added
+ * during delta searching phase when we find better deltas.
+ *
+ * delta_child and delta_sibling are last needed in
+ * compute_write_order(). "delta" and "delta_size" must remain valid
+ * at object writing phase in case the delta is not cached.
+ *
+ * If a delta is cached in memory and is compressed, delta_data points
+ * to the data and z_delta_size contains the compressed size. If it's
+ * uncompressed [1], z_delta_size must be zero. delta_size is always
+ * the uncompressed size and must be valid even if the delta is not
+ * cached.
+ *
+ * [1] during try_delta phase we don't bother with compressing because
+ * the delta could be quickly replaced with a better one.
+ */
 struct object_entry {
struct pack_idx_entry idx;
unsigned long size; /* uncompressed size */
-- 
2.17.0.rc0.347.gf9cf61673a



[PATCH v5 03/11] pack-objects: use bitfield for object_entry::dfs_state

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 builtin/pack-objects.c |  3 +++
 pack-objects.h | 28 +---
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 647c01ea34..83f8154865 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3049,6 +3049,9 @@ int cmd_pack_objects(int argc, const char **argv, const 
char *prefix)
OPT_END(),
};
 
+   if (DFS_NUM_STATES > (1 << OE_DFS_STATE_BITS))
+   die("BUG: too many dfs states, increase OE_DFS_STATE_BITS");
+
check_replace_refs = 0;
 
reset_pack_idx_option(_idx_opts);
diff --git a/pack-objects.h b/pack-objects.h
index 5f568b609c..4c6b73a4d6 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -1,6 +1,21 @@
 #ifndef PACK_OBJECTS_H
 #define PACK_OBJECTS_H
 
+#define OE_DFS_STATE_BITS  2
+
+/*
+ * State flags for depth-first search used for analyzing delta cycles.
+ *
+ * The depth is measured in delta-links to the base (so if A is a delta
+ * against B, then A has a depth of 1, and B a depth of 0).
+ */
+enum dfs_state {
+   DFS_NONE = 0,
+   DFS_ACTIVE,
+   DFS_DONE,
+   DFS_NUM_STATES
+};
+
 /*
  * basic object info
  * -
@@ -73,19 +88,10 @@ struct object_entry {
unsigned no_try_delta:1;
unsigned tagged:1; /* near the very tip of refs */
unsigned filled:1; /* assigned write-order */
+   unsigned dfs_state:OE_DFS_STATE_BITS;
 
-   /*
-* State flags for depth-first search used for analyzing delta cycles.
-*
-* The depth is measured in delta-links to the base (so if A is a delta
-* against B, then A has a depth of 1, and B a depth of 0).
-*/
-   enum {
-   DFS_NONE = 0,
-   DFS_ACTIVE,
-   DFS_DONE
-   } dfs_state;
int depth;
+
 };
 
 struct packing_data {
-- 
2.17.0.rc0.347.gf9cf61673a



[PATCH v5 02/11] pack-objects: turn type and in_pack_type to bitfields

2018-03-17 Thread Nguyễn Thái Ngọc Duy
An extra field type_valid is added to carry the equivalent of OBJ_BAD
in the original "type" field. in_pack_type always contains a valid
type so we only need 3 bits for it.

A note about accepting OBJ_NONE as "valid" type. The function
read_object_list_from_stdin() can pass this value [1] and it
eventually calls create_object_entry() where current code skip setting
"type" field if the incoming type is zero. This does not have any bad
side effects because "type" field should be memset()'d anyway.

But since we also need to set type_valid now, skipping oe_set_type()
leaves type_valid zero/false, which will make oe_type() return
OBJ_BAD, not OBJ_NONE anymore. Apparently we do care about OBJ_NONE in
prepare_pack(). This switch from OBJ_NONE to OBJ_BAD may trigger

fatal: unable to get type of object ...

Accepting OBJ_NONE [2] does sound wrong, but this is how it is has
been for a very long time and I haven't time to dig in further.

[1] See 5c49c11686 (pack-objects: better check_object() performances -
2007-04-16)

[2] 21666f1aae (convert object type handling from a string to a number
- 2007-02-26)

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 builtin/pack-objects.c | 60 --
 cache.h|  2 ++
 object.h   |  1 -
 pack-bitmap-write.c|  6 ++---
 pack-objects.h | 20 --
 5 files changed, 58 insertions(+), 31 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 5c674b2843..647c01ea34 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -265,7 +265,7 @@ static unsigned long write_no_reuse_object(struct hashfile 
*f, struct object_ent
struct git_istream *st = NULL;
 
if (!usable_delta) {
-   if (entry->type == OBJ_BLOB &&
+   if (oe_type(entry) == OBJ_BLOB &&
entry->size > big_file_threshold &&
(st = open_istream(entry->idx.oid.hash, , , 
NULL)) != NULL)
buf = NULL;
@@ -371,7 +371,7 @@ static off_t write_reuse_object(struct hashfile *f, struct 
object_entry *entry,
struct pack_window *w_curs = NULL;
struct revindex_entry *revidx;
off_t offset;
-   enum object_type type = entry->type;
+   enum object_type type = oe_type(entry);
off_t datalen;
unsigned char header[MAX_PACK_OBJECT_HEADER],
  dheader[MAX_PACK_OBJECT_HEADER];
@@ -480,11 +480,12 @@ static off_t write_object(struct hashfile *f,
to_reuse = 0;   /* explicit */
else if (!entry->in_pack)
to_reuse = 0;   /* can't reuse what we don't have */
-   else if (entry->type == OBJ_REF_DELTA || entry->type == OBJ_OFS_DELTA)
+   else if (oe_type(entry) == OBJ_REF_DELTA ||
+oe_type(entry) == OBJ_OFS_DELTA)
/* check_object() decided it for us ... */
to_reuse = usable_delta;
/* ... but pack split may override that */
-   else if (entry->type != entry->in_pack_type)
+   else if (oe_type(entry) != entry->in_pack_type)
to_reuse = 0;   /* pack has delta which is unusable */
else if (entry->delta)
to_reuse = 0;   /* we want to pack afresh */
@@ -705,8 +706,8 @@ static struct object_entry **compute_write_order(void)
 * And then all remaining commits and tags.
 */
for (i = last_untagged; i < to_pack.nr_objects; i++) {
-   if (objects[i].type != OBJ_COMMIT &&
-   objects[i].type != OBJ_TAG)
+   if (oe_type([i]) != OBJ_COMMIT &&
+   oe_type([i]) != OBJ_TAG)
continue;
add_to_write_order(wo, _end, [i]);
}
@@ -715,7 +716,7 @@ static struct object_entry **compute_write_order(void)
 * And then all the trees.
 */
for (i = last_untagged; i < to_pack.nr_objects; i++) {
-   if (objects[i].type != OBJ_TREE)
+   if (oe_type([i]) != OBJ_TREE)
continue;
add_to_write_order(wo, _end, [i]);
}
@@ -1066,8 +1067,7 @@ static void create_object_entry(const struct object_id 
*oid,
 
entry = packlist_alloc(_pack, oid->hash, index_pos);
entry->hash = hash;
-   if (type)
-   entry->type = type;
+   oe_set_type(entry, type);
if (exclude)
entry->preferred_base = 1;
else
@@ -1407,6 +1407,7 @@ static void check_object(struct object_entry *entry)
unsigned long avail;
off_t ofs;
unsigned char *buf, c;
+   enum object_type type;
 
buf = use_pack(p, _curs, entry->in_pack_offset, );
 
@@ -1415,11 +1416,15 @@ static void check_object(struct object_entry *entry)
 * since non-delta representations could still be reused.
  

[PATCH v5 00/11] nd/pack-objects-pack-struct updates

2018-03-17 Thread Nguyễn Thái Ngọc Duy
v5 changes are small enough that the interdiff is pretty self
explanatory (there's also a couple commit msg updates).

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index c388d87c3e..fb2aba80bf 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1611,7 +1611,7 @@ static void drop_reused_delta(struct object_entry *entry)
/*
 * We failed to get the info from this pack for some reason;
 * fall back to sha1_object_info, which may find another copy.
-* And if that fails, the error will be recorded in entry->type
+* And if that fails, the error will be recorded in 
oe_type(entry)
 * and dealt with in prepare_pack().
 */
oe_set_type(entry, sha1_object_info(entry->idx.oid.hash,
@@ -1968,7 +1968,7 @@ static int try_delta(struct unpacked *trg, struct 
unpacked *src,
delta_buf = create_delta(src->index, trg->data, trg_size, _size, 
max_size);
if (!delta_buf)
return 0;
-   if (delta_size >= maximum_unsigned_value_of_type(uint32_t))
+   if (delta_size >= (1 << OE_DELTA_SIZE_BITS))
return 0;
 
if (DELTA(trg_entry)) {
@@ -2125,8 +2125,8 @@ static void find_deltas(struct object_entry **list, 
unsigned *list_size,
unsigned long size;
 
size = do_compress(>delta_data, 
DELTA_SIZE(entry));
-   entry->z_delta_size = size;
-   if (entry->z_delta_size == size) {
+   if (size < (1 << OE_Z_DELTA_BITS)) {
+   entry->z_delta_size = size;
cache_lock();
delta_cache_size -= DELTA_SIZE(entry);
delta_cache_size += entry->z_delta_size;
diff --git a/pack-objects.h b/pack-objects.h
index 0fa0c83294..8979289f5f 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -27,14 +27,15 @@ enum dfs_state {
  *
  * basic object info
  * -
- * idx.oid is filled up before delta searching starts. idx.crc32 and
- * is only valid after the object is written out and will be used for
+ * idx.oid is filled up before delta searching starts. idx.crc32 is
+ * only valid after the object is written out and will be used for
  * generating the index. idx.offset will be both gradually set and
  * used in writing phase (base objects get offset first, then deltas
  * refer to them)
  *
- * "size" is the uncompressed object size. Compressed size is not
- * cached (ie. raw data in a pack) but available via revindex.
+ * "size" is the uncompressed object size. Compressed size of the raw
+ * data for an object in a pack is not stored anywhere but is computed
+ * and made available when reverse .idx is made.
  *
  * "hash" contains a path name hash which is used for sorting the
  * delta list and also during delta searching. Once prepare_pack()
@@ -42,16 +43,16 @@ enum dfs_state {
  *
  * source pack info
  * 
- * The (in_pack, in_pack_offset, in_pack_header_size) tuple contains
- * the location of the object in the source pack, with or without
- * header.
+ * The (in_pack, in_pack_offset) tuple contains the location of the
+ * object in the source pack. in_pack_header_size allows quickly
+ * skipping the header and going straight to the zlib stream.
  *
  * "type" and "in_pack_type" both describe object type. in_pack_type
  * may contain a delta type, while type is always the canonical type.
  *
  * deltas
  * --
- * Delta links (delta, delta_child and delta_sibling) are created
+ * Delta links (delta, delta_child and delta_sibling) are created to
  * reflect that delta graph from the source pack then updated or added
  * during delta searching phase when we find better deltas.
  *
@@ -59,7 +60,7 @@ enum dfs_state {
  * compute_write_order(). "delta" and "delta_size" must remain valid
  * at object writing phase in case the delta is not cached.
  *
- * If a delta is cached in memory and is compressed delta_data points
+ * If a delta is cached in memory and is compressed, delta_data points
  * to the data and z_delta_size contains the compressed size. If it's
  * uncompressed [1], z_delta_size must be zero. delta_size is always
  * the uncompressed size and must be valid even if the delta is not
@@ -274,12 +275,19 @@ static inline unsigned long oe_size(const struct 
object_entry *e)
}
 }
 
+static inline int contains_in_32bits(unsigned long limit)
+{
+   uint32_t truncated_limit = (uint32_t)limit;
+
+   return limit == truncated_limit;
+}
+
 static inline int oe_size_less_than(const struct object_entry *e,
unsigned long limit)
 {
if (e->size_valid)
return e->size_ < limit;
-   if (limit > maximum_unsigned_value_of_type(uint32_t))
+   if (contains_in_32bits(limit))
return 1;
return 

[PATCH v5 10/11] pack-objects: shrink delta_size field in struct object_entry

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Allowing a delta size of 64 bits is crazy. Shrink this field down to
31 bits with one overflow bit.

If we find an existing delta larger than 2GB, we do not cache
delta_size at all and will get the value from oe_size(), potentially
from disk if it's larger than 4GB.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 builtin/pack-objects.c | 24 ++--
 pack-objects.h | 23 ++-
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 887e12c556..fb2aba80bf 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -30,10 +30,12 @@
 #include "packfile.h"
 
 #define IN_PACK(obj) oe_in_pack(_pack, obj)
+#define DELTA_SIZE(obj) oe_delta_size(_pack, obj)
 #define DELTA(obj) oe_delta(_pack, obj)
 #define DELTA_CHILD(obj) oe_delta_child(_pack, obj)
 #define DELTA_SIBLING(obj) oe_delta_sibling(_pack, obj)
 #define SET_DELTA(obj, val) oe_set_delta(_pack, obj, val)
+#define SET_DELTA_SIZE(obj, val) oe_set_delta_size(_pack, obj, val)
 #define SET_DELTA_CHILD(obj, val) oe_set_delta_child(_pack, obj, val)
 #define SET_DELTA_SIBLING(obj, val) oe_set_delta_sibling(_pack, obj, val)
 
@@ -140,7 +142,7 @@ static void *get_delta(struct object_entry *entry)
oid_to_hex((entry)->idx.oid));
delta_buf = diff_delta(base_buf, base_size,
   buf, size, _size, 0);
-   if (!delta_buf || delta_size != entry->delta_size)
+   if (!delta_buf || delta_size != DELTA_SIZE(entry))
die("delta size changed");
free(buf);
free(base_buf);
@@ -291,14 +293,14 @@ static unsigned long write_no_reuse_object(struct 
hashfile *f, struct object_ent
FREE_AND_NULL(entry->delta_data);
entry->z_delta_size = 0;
} else if (entry->delta_data) {
-   size = entry->delta_size;
+   size = DELTA_SIZE(entry);
buf = entry->delta_data;
entry->delta_data = NULL;
type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
} else {
buf = get_delta(entry);
-   size = entry->delta_size;
+   size = DELTA_SIZE(entry);
type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
}
@@ -1509,7 +1511,7 @@ static void check_object(struct object_entry *entry)
 */
oe_set_type(entry, entry->in_pack_type);
SET_DELTA(entry, base_entry);
-   entry->delta_size = oe_size(entry);
+   SET_DELTA_SIZE(entry, oe_size(entry));
entry->delta_sibling_idx = base_entry->delta_child_idx;
SET_DELTA_CHILD(base_entry, entry);
unuse_pack(_curs);
@@ -1895,7 +1897,7 @@ static int try_delta(struct unpacked *trg, struct 
unpacked *src,
max_size = trg_size/2 - 20;
ref_depth = 1;
} else {
-   max_size = trg_entry->delta_size;
+   max_size = DELTA_SIZE(trg_entry);
ref_depth = trg->depth;
}
max_size = (uint64_t)max_size * (max_depth - src->depth) /
@@ -1966,10 +1968,12 @@ static int try_delta(struct unpacked *trg, struct 
unpacked *src,
delta_buf = create_delta(src->index, trg->data, trg_size, _size, 
max_size);
if (!delta_buf)
return 0;
+   if (delta_size >= (1 << OE_DELTA_SIZE_BITS))
+   return 0;
 
if (DELTA(trg_entry)) {
/* Prefer only shallower same-sized deltas. */
-   if (delta_size == trg_entry->delta_size &&
+   if (delta_size == DELTA_SIZE(trg_entry) &&
src->depth + 1 >= trg->depth) {
free(delta_buf);
return 0;
@@ -1984,7 +1988,7 @@ static int try_delta(struct unpacked *trg, struct 
unpacked *src,
free(trg_entry->delta_data);
cache_lock();
if (trg_entry->delta_data) {
-   delta_cache_size -= trg_entry->delta_size;
+   delta_cache_size -= DELTA_SIZE(trg_entry);
trg_entry->delta_data = NULL;
}
if (delta_cacheable(src_size, trg_size, delta_size)) {
@@ -1997,7 +2001,7 @@ static int try_delta(struct unpacked *trg, struct 
unpacked *src,
}
 
SET_DELTA(trg_entry, src_entry);
-   trg_entry->delta_size = delta_size;
+   SET_DELTA_SIZE(trg_entry, delta_size);
trg->depth = src->depth + 1;
 
return 1;
@@ -2120,11 +2124,11 @@ static void find_deltas(struct object_entry **list, 
unsigned *list_size,
if (entry->delta_data && !pack_to_stdout) {
unsigned long size;
 
-   size = do_compress(>delta_data, 

[PATCH v5 11/11] pack-objects.h: reorder members to shrink struct object_entry

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Previous patches leave lots of holes and padding in this struct. This
patch reorders the members and shrinks the struct down to 80 bytes
(from 136 bytes, before any field shrinking is done) with 16 bits to
spare (and a couple more in in_pack_header_size when we really run out
of bits).

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 pack-objects.h | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/pack-objects.h b/pack-objects.h
index 2507b157d5..8979289f5f 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -71,35 +71,36 @@ enum dfs_state {
  */
 struct object_entry {
struct pack_idx_entry idx;
-   /* object uncompressed size _if_ size_valid is true */
-   uint32_t size_;
-   unsigned size_valid:1;
-   unsigned in_pack_idx:OE_IN_PACK_BITS;   /* already in pack */
+   void *delta_data;   /* cached delta (uncompressed) */
off_t in_pack_offset;
+   uint32_t hash;  /* name hint hash */
+   uint32_t size_; /* object uncompressed size _if_ size_valid is true */
uint32_t delta_idx; /* delta base object */
uint32_t delta_child_idx; /* deltified objects who bases me */
uint32_t delta_sibling_idx; /* other deltified objects who
 * uses the same base as me
 */
-   void *delta_data;   /* cached delta (uncompressed) */
uint32_t delta_size_:OE_DELTA_SIZE_BITS; /* delta data size 
(uncompressed) */
uint32_t delta_size_valid:1;
+   unsigned in_pack_idx:OE_IN_PACK_BITS;   /* already in pack */
+   unsigned size_valid:1;
unsigned z_delta_size:OE_Z_DELTA_BITS;
+   unsigned type_valid:1;
unsigned type_:TYPE_BITS;
unsigned in_pack_type:TYPE_BITS; /* could be delta */
-   unsigned type_valid:1;
-   uint32_t hash;  /* name hint hash */
-   unsigned char in_pack_header_size;
unsigned preferred_base:1; /*
* we do not pack this, but is available
* to be used as the base object to delta
* objects against.
*/
unsigned no_try_delta:1;
+   unsigned char in_pack_header_size;
unsigned tagged:1; /* near the very tip of refs */
unsigned filled:1; /* assigned write-order */
unsigned dfs_state:OE_DFS_STATE_BITS;
unsigned depth:OE_DEPTH_BITS;
+
+   /* size: 80, bit_padding: 16 bits */
 };
 
 struct packing_data {
-- 
2.17.0.rc0.347.gf9cf61673a



Wir bieten jedem ein GÜNSTIGES Darlehnen zu TOP Konditionen an

2018-03-17 Thread Obrist Nicolas
Sehr geehrte Damen und Herren,

Sie brauchen Geld? Sie sind auf der suche nach einem Darlehnen? Seriös und 
unkompliziert?
Dann sind Sie hier bei uns genau richtig.
Durch unsere jahrelange Erfahrung und kompetente Beratung sind wir Europaweit 
tätig.

Wir bieten jedem ein GÜNSTIGES Darlehnen zu TOP Konditionen an. 
Darlehnen zwischen 5000 CHF/Euro bis zu 20 Millionen CHF/Euro möglich.
Wir erheben dazu 2% Zinssatz.

Lassen Sie sich von unserem kompetenten Team beraten. 

Zögern Sie nicht und kontaktieren Sie mich unter für weitere Infos & Anfragen 
unter
der eingeblendeten Email Adresse.

Ich freue mich von Ihnen zu hören.




Re: get commit ID from a tree object ID

2018-03-17 Thread Konstantin Khomoutov
On Sat, Mar 17, 2018 at 01:17:12PM +0100, Michal Novotny wrote:

> let's say I have made an annotated tag on a certain treeish:
> 
> $ git tag -a -m msg tagname HEAD:
> 
> Now, I can try to see the content of the tag:
> 
> $ git tag -v tagname
> object 42a1c36553a50ceae2f75ffc4b1446c6c393eae7
> type tree
> tag tagname
> tagger clime  1521288727 +0100
> 
> msg
> error: no signature found
> 
> 
> Can I use that object ID 42a1c36553a50ceae2f75ffc4b1446c6c393eae7 to
> get back to a particular commit from which the tag was created? The
> reason is that I would eventually like to checkout that commit.

In general, you can't, and that's because there can be any number of
commits referencing that tree. A typical case is a tree object
representing a subdirectory of your project which changes rarily, if
ever - in this case, each commit which includes the same state of this
subdirectory will refer the same tree object.

Another point to consider is that the commit itself only refers to a
single tree object -- that one which records the state of the top-level
project directory, and it usually refers to other three objects which
may, in turn, refer to others and so on - all the way down.

So actually a generic approach to what you need is a full scan of all
the commits in the repository with recursive traversing of the hierarchy
of trees of each of them (via `git ls-tree`) and looking for the SHA-1
name of the reference tree object.  As you can see, this is not going to
be fast on repos of realistic size.



get commit ID from a tree object ID

2018-03-17 Thread Michal Novotny
Hello,

let's say I have made an annotated tag on a certain treeish:

$ git tag -a -m msg tagname HEAD:

Now, I can try to see the content of the tag:

$ git tag -v tagname
object 42a1c36553a50ceae2f75ffc4b1446c6c393eae7
type tree
tag tagname
tagger clime  1521288727 +0100

msg
error: no signature found


Can I use that object ID 42a1c36553a50ceae2f75ffc4b1446c6c393eae7 to
get back to a particular commit from which the tag was created? The
reason is that I would eventually like to checkout that commit.

Thank you
clime


Re: [PATCH v4 11/11] pack-objects.h: reorder members to shrink struct object_entry

2018-03-17 Thread Duy Nguyen
On Fri, Mar 16, 2018 at 10:02 PM, Junio C Hamano  wrote:
> Nguyễn Thái Ngọc Duy   writes:
>
>> Previous patches leave lots of holes and padding in this struct. This
>> patch reorders the members and shrinks the struct down to 80 bytes
>> (from 136 bytes, before any field shrinking is done) with 16 bits to
>> spare (and a couple more in in_pack_header_size when we really run out
>> of bits).
>
> Nice.
>
> I am wondering if we need some conditional code for 32-bit platform.
> For example, you have uint32_t field and do things like this:
>
> static inline int oe_size_less_than(const struct object_entry *e,
> unsigned long limit)
> {
> if (e->size_valid)
> return e->size_ < limit;
> if (limit > maximum_unsigned_value_of_type(uint32_t))
> return 1;
> return oe_size(e) < limit;
> }
>
> Do we and compilers do the right thing when your ulong is uint32_t?

Another good point. My 32-bit build does complain

In file included from builtin/pack-objects.c:20:0:
./pack-objects.h: In function ?oe_size_less_than?:
./pack-objects.h:282:12: error: comparison is always false due to
limited range of data type [-Werror=type-limits]
  if (limit > maximum_unsigned_value_of_type(uint32_t))
^
-- 
Duy


Re: [PATCH v4 01/11] pack-objects: a bit of document about struct object_entry

2018-03-17 Thread Duy Nguyen
On Fri, Mar 16, 2018 at 9:32 PM, Junio C Hamano  wrote:
>> +/*
>> + * basic object info
>> + * -
>> + * idx.oid is filled up before delta searching starts. idx.crc32 and
>> + * is only valid after the object is written out and will be used for
>
> "and is"?

There was another field that I thought was only valid after blah blah.
But it was wrong and I forgot to delete this "and" after deleting that
field.

>> + * "hash" contains a path name hash which is used for sorting the
>> + * delta list and also during delta searching. Once prepare_pack()
>> + * returns it's no longer needed.
>
> Hmm, that suggests an interesting optimization opportunity ;-)

Heh.. it does not reduce peak memory consumption though which is why
I'm less interested in freeing it after prepare_pack().

>> + * source pack info
>> + * 
>> + * The (in_pack, in_pack_offset, in_pack_header_size) tuple contains
>> + * the location of the object in the source pack, with or without
>> + * header.
>
> "with or without", meaning...?  An object in the source pack may or
> may not have any in_pack_header, in which case in_pack_header_size
> is zero, or something?  Not suggesting to rephrase (at least not
> yet), but trying to understand.

The location with the header (i.e. true beginning an object in a pack)
or without/after the header so you are at the zlib stream, ready to
inflate or reuse. I'll rephrase this a bit.

>> + *
>> + * delta_child and delta_sibling are last needed in
>> + * compute_write_order(). "delta" and "delta_size" must remain valid
>> + * at object writing phase in case the delta is not cached.
>
> True.  I thought child and sibling are only needed during write
> order computing, so there may be an optimization opportunity there.

See. I wrote all this for a reason. Somebody looking for low hang
fruit can always find some ;-)
-- 
Duy


Re: [PATCH v4 0/3] stash push -u -- fixes

2018-03-17 Thread Thomas Gummerer
On 03/16, Junio C Hamano wrote:
> Here is a preliminary fix for an earlier copy-pasto, plus two
> patches from your v3.

Thanks for catching and fixing this!

> I tried to reduce the nesting level by swapping the order of if/elif
> chain; please double check the logic to ensure I didn't make stupid
> mistakes while doing so.

I looked over what you send, and the patches and the changes you made
look good to me.

> Junio C Hamano (1):
>   stash: fix nonsense pipeline
> 
> Thomas Gummerer (2):
>   stash push: avoid printing errors
>   stash push -u: don't create empty stash
> 
>  git-stash.sh | 13 +++--
>  t/t3903-stash.sh | 22 ++
>  2 files changed, 29 insertions(+), 6 deletions(-)
> 
> -- 
> 2.17.0-rc0
> 


[PATCH 1/2] completion: improve ls-files filter performance

2018-03-17 Thread Clemens Buchacher
>From the output of ls-files, we remove all but the leftmost path
component and then we eliminate duplicates. We do this in a while loop,
which is a performance bottleneck when the number of iterations is large
(e.g. for 6 files in linux.git).

$ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git

real0m11.876s
user0m4.685s
sys 0m6.808s

Using an equivalent sed script improves performance significantly:

$ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git

real0m1.372s
user0m0.263s
sys 0m0.167s

The measurements were done with mingw64 bash, which is used by Git for
Windows.

Signed-off-by: Clemens Buchacher 
---
 contrib/completion/git-completion.bash | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 6da95b8..e3ddf27 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -384,12 +384,7 @@ __git_index_files ()
local root="${2-.}" file
 
__git_ls_files_helper "$root" "$1" |
-   while read -r file; do
-   case "$file" in
-   ?*/*) echo "${file%%/*}" ;;
-   *) echo "$file" ;;
-   esac
-   done | sort | uniq
+   sed -e '/^\//! s#/.*##' | sort | uniq
 }
 
 # Lists branches from the local repository.
-- 
2.7.4



[PATCH 2/2] completion: simplify ls-files filter

2018-03-17 Thread Clemens Buchacher
When filtering the ls-files output we take care not to touch absolute
paths. This is redundant, because ls-files will never output absolute
paths. Furthermore, sorting the output is also redundant, because the
output of ls-files is already sorted.

Remove the unnecessary operations.

Signed-off-by: Clemens Buchacher 
---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index e3ddf27..394c3df 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -384,7 +384,7 @@ __git_index_files ()
local root="${2-.}" file
 
__git_ls_files_helper "$root" "$1" |
-   sed -e '/^\//! s#/.*##' | sort | uniq
+   cut -f1 -d/ | uniq
 }
 
 # Lists branches from the local repository.
-- 
2.7.4



Re: [PATCH] format-patch: use --compact-summary instead of --summary

2018-03-17 Thread Duy Nguyen
On Fri, Mar 16, 2018 at 10:41 PM, Junio C Hamano  wrote:
> Nguyễn Thái Ngọc Duy   writes:
>
>> For reviewers, a couple fewer lines from diffstat (either cover letter
>> or patches) is a good thing because there's less to read.
>
> I can certainly accept that there may be some reviewers who share
> that view, but me personally, I would rather have them outside the
> main diffstat section, so addition and removal of files that are
> rarer events do stand out.
>
> I guess people would not mind an option to use it, but they can
> already say "git format-patch --compact-summary $upstream..", so...

Good point. I can't negate --summary though. But that calls for another patch.
-- 
Duy


Re: [PATCH v2] travis-ci: enable more warnings on travis linux-gcc job

2018-03-17 Thread Duy Nguyen
On Fri, Mar 16, 2018 at 10:22 PM, Jeff King  wrote:
>> diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
>> index 3735ce413f..f6f346c468 100755
>> --- a/ci/run-build-and-tests.sh
>> +++ b/ci/run-build-and-tests.sh
>> @@ -7,6 +7,22 @@
>>
>>  ln -s "$cache_dir/.prove" t/.prove
>>
>> +if [ "$jobname" = linux-gcc ]; then
>> + gcc-6 --version
>> + cat >config.mak <<-EOF
>> + CC=gcc-6
>> + CFLAGS = -g -O2 -Wall
>> + CFLAGS += -Wextra
>> + CFLAGS += -Wmissing-prototypes
>> + CFLAGS += -Wno-empty-body
>> + CFLAGS += -Wno-maybe-uninitialized
>> + CFLAGS += -Wno-missing-field-initializers
>> + CFLAGS += -Wno-sign-compare
>> + CFLAGS += -Wno-unused-function
>> + CFLAGS += -Wno-unused-parameter
>> + EOF
>> +fi
>
> Why isn't this just turning on DEVELOPER=1 if we know we have a capable
> compiler?

DEVELOPER=1 is always set even before this patch. It's set and
exported in lib-travisci.sh.
-- 
Duy


[PATCH 04/36] t/helper: merge test-lazy-init-name-hash into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile|  2 +-
 cache.h |  2 +-
 name-hash.c |  2 +-
 t/helper/test-lazy-init-name-hash.c | 26 ++---
 t/helper/test-tool.c|  1 +
 t/helper/test-tool.h|  1 +
 t/perf/p0004-lazy-init-name-hash.sh |  8 
 t/t3008-ls-files-lazy-init-name-hash.sh |  2 +-
 8 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/Makefile b/Makefile
index 3c0d0474af..31287cedf2 100644
--- a/Makefile
+++ b/Makefile
@@ -653,6 +653,7 @@ X =
 PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
 TEST_BUILTINS_OBJS += test-chmtime.o
+TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-ctype
@@ -669,7 +670,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-genrandom
 TEST_PROGRAMS_NEED_X += test-hashmap
 TEST_PROGRAMS_NEED_X += test-index-version
-TEST_PROGRAMS_NEED_X += test-lazy-init-name-hash
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-match-trees
 TEST_PROGRAMS_NEED_X += test-mergesort
diff --git a/cache.h b/cache.h
index d06932ed0b..8ff5ae9903 100644
--- a/cache.h
+++ b/cache.h
@@ -333,7 +333,7 @@ struct index_state {
 extern struct index_state the_index;
 
 /* Name hashing */
-extern int test_lazy_init_name_hash(struct index_state *istate, int 
try_threaded);
+extern int lazy_init_name_hash_for_testing(struct index_state *istate, int 
try_threaded);
 extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
 extern void remove_name_hash(struct index_state *istate, struct cache_entry 
*ce);
 extern void free_name_hash(struct index_state *istate);
diff --git a/name-hash.c b/name-hash.c
index 163849831c..182f630acc 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -614,7 +614,7 @@ static void lazy_init_name_hash(struct index_state *istate)
  * Requesting threading WILL NOT override guards
  * in lookup_lazy_params().
  */
-int test_lazy_init_name_hash(struct index_state *istate, int try_threaded)
+int lazy_init_name_hash_for_testing(struct index_state *istate, int 
try_threaded)
 {
lazy_nr_dir_threads = 0;
lazy_try_threaded = try_threaded;
diff --git a/t/helper/test-lazy-init-name-hash.c 
b/t/helper/test-lazy-init-name-hash.c
index 297fb01d61..dd4e753008 100644
--- a/t/helper/test-lazy-init-name-hash.c
+++ b/t/helper/test-lazy-init-name-hash.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "parse-options.h"
 
@@ -9,6 +10,9 @@ static int perf;
 static int analyze;
 static int analyze_step;
 
+static int (*init_name_hash)(struct index_state *istate, int try_threaded) =
+   lazy_init_name_hash_for_testing;
+
 /*
  * Dump the contents of the "dir" and "name" hash tables to stdout.
  * If you sort the result, you can compare it with the other type
@@ -33,9 +37,9 @@ static void dump_run(void)
 
read_cache();
if (single) {
-   test_lazy_init_name_hash(_index, 0);
+   init_name_hash(_index, 0);
} else {
-   int nr_threads_used = test_lazy_init_name_hash(_index, 1);
+   int nr_threads_used = init_name_hash(_index, 1);
if (!nr_threads_used)
die("non-threaded code path used");
}
@@ -71,7 +75,7 @@ static uint64_t time_runs(int try_threaded)
t0 = getnanotime();
read_cache();
t1 = getnanotime();
-   nr_threads_used = test_lazy_init_name_hash(_index, 
try_threaded);
+   nr_threads_used = init_name_hash(_index, try_threaded);
t2 = getnanotime();
 
sum += (t2 - t1);
@@ -134,7 +138,7 @@ static void analyze_run(void)
read_cache();
the_index.cache_nr = nr; /* cheap truncate of index */
t1s = getnanotime();
-   test_lazy_init_name_hash(_index, 0);
+   init_name_hash(_index, 0);
t2s = getnanotime();
sum_single += (t2s - t1s);
the_index.cache_nr = cache_nr_limit;
@@ -143,7 +147,7 @@ static void analyze_run(void)
read_cache();
the_index.cache_nr = nr; /* cheap truncate of index */
t1m = getnanotime();
-   nr_threads_used = test_lazy_init_name_hash(_index, 
1);
+   nr_threads_used = init_name_hash(_index, 1);
t2m = getnanotime();
sum_multi += (t2m - t1m);
the_index.cache_nr = cache_nr_limit;
@@ -184,14 +188,14 @@ static void analyze_run(void)
}
 }
 
-int cmd_main(int argc, const char **argv)
+int test_lazy_init_name_hash(int argc, const char **argv)
 {

[PATCH 09/36] t/helper: merge test-drop-caches into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile|  2 +-
 t/helper/test-drop-caches.c |  3 ++-
 t/helper/test-tool.c|  1 +
 t/helper/test-tool.h|  1 +
 t/perf/p7519-fsmonitor.sh   | 12 ++--
 5 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/Makefile b/Makefile
index 327d63217a..edd9c43982 100644
--- a/Makefile
+++ b/Makefile
@@ -657,10 +657,10 @@ TEST_BUILTINS_OBJS += test-config.o
 TEST_BUILTINS_OBJS += test-ctype.o
 TEST_BUILTINS_OBJS += test-date.o
 TEST_BUILTINS_OBJS += test-delta.o
+TEST_BUILTINS_OBJS += test-drop-caches.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
-TEST_PROGRAMS_NEED_X += test-drop-caches
 TEST_PROGRAMS_NEED_X += test-dump-cache-tree
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-split-index
diff --git a/t/helper/test-drop-caches.c b/t/helper/test-drop-caches.c
index bd1a857d52..2aa7c57b4a 100644
--- a/t/helper/test-drop-caches.c
+++ b/t/helper/test-drop-caches.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 
 #if defined(GIT_WINDOWS_NATIVE)
@@ -157,7 +158,7 @@ static int cmd_dropcaches(void)
 
 #endif
 
-int cmd_main(int argc, const char **argv)
+int test_drop_caches(int argc, const char **argv)
 {
cmd_sync();
return cmd_dropcaches();
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index e48c1f2d5f..904e4103fd 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -12,6 +12,7 @@ static struct test_cmd cmds[] = {
{ "ctype", test_ctype },
{ "date", test_date },
{ "delta", test_delta },
+   { "drop-caches", test_drop_caches },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 0ee098f1e3..1e96bf44a2 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -6,6 +6,7 @@ int test_config(int argc, const char **argv);
 int test_ctype(int argc, const char **argv);
 int test_date(int argc, const char **argv);
 int test_delta(int argc, const char **argv);
+int test_drop_caches(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
diff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh
index 65e145c02d..def7ecdbc7 100755
--- a/t/perf/p7519-fsmonitor.sh
+++ b/t/perf/p7519-fsmonitor.sh
@@ -118,7 +118,7 @@ test_expect_success "setup for fsmonitor" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-   test-drop-caches
+   test-tool drop-caches
 fi
 
 test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -126,7 +126,7 @@ test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-   test-drop-caches
+   test-tool drop-caches
 fi
 
 test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -134,7 +134,7 @@ test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-   test-drop-caches
+   test-tool drop-caches
 fi
 
 test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -148,7 +148,7 @@ test_expect_success "setup without fsmonitor" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-   test-drop-caches
+   test-tool drop-caches
 fi
 
 test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -156,7 +156,7 @@ test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-   test-drop-caches
+   test-tool drop-caches
 fi
 
 test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -164,7 +164,7 @@ test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-   test-drop-caches
+   test-tool drop-caches
 fi
 
 test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
-- 
2.16.2.903.gd04caf5039



[PATCH 02/36] t/helper: merge test-chmtime into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile |  3 ++-
 t/helper/test-chmtime.c  | 15 +++---
 t/helper/test-tool.c |  1 +
 t/helper/test-tool.h |  2 ++
 t/lib-git-svn.sh |  2 +-
 t/t1700-split-index.sh   | 12 +--
 t/t2022-checkout-paths.sh|  4 ++--
 t/t3306-notes-prune.sh   |  2 +-
 t/t3404-rebase-interactive.sh|  4 ++--
 t/t3418-rebase-continue.sh   |  4 ++--
 t/t3501-revert-cherry-pick.sh|  2 +-
 t/t3510-cherry-pick-sequence.sh  |  4 ++--
 t/t3600-rm.sh|  2 +-
 t/t3700-add.sh   |  2 +-
 t/t4011-diff-symlink.sh  |  2 +-
 t/t4013-diff-various.sh  |  2 +-
 t/t4035-diff-quiet.sh|  2 +-
 t/t4151-am-abort.sh  |  4 ++--
 t/t4200-rerere.sh| 22 ++--
 t/t5000-tar-tree.sh  |  2 +-
 t/t5304-prune.sh | 16 +++
 t/t5400-send-pack.sh |  2 +-
 t/t5516-fetch-push.sh|  2 +-
 t/t6022-merge-rename.sh  | 30 ++--
 t/t6500-gc.sh|  2 +-
 t/t6501-freshen-objects.sh   |  4 ++--
 t/t7508-status.sh|  6 +++---
 t/t7701-repack-unpack-unreachable.sh |  6 +++---
 t/t9100-git-svn-basic.sh |  4 ++--
 t/t9803-git-p4-shell-metachars.sh|  4 ++--
 t/t9813-git-p4-preserve-users.sh |  6 +++---
 t/t9820-git-p4-editor-handling.sh|  2 +-
 t/test-lib.sh|  6 +++---
 33 files changed, 94 insertions(+), 89 deletions(-)

diff --git a/Makefile b/Makefile
index 2376646e98..416a8e39c1 100644
--- a/Makefile
+++ b/Makefile
@@ -652,7 +652,8 @@ X =
 
 PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
-TEST_PROGRAMS_NEED_X += test-chmtime
+TEST_BUILTINS_OBJS += test-chmtime.o
+
 TEST_PROGRAMS_NEED_X += test-ctype
 TEST_PROGRAMS_NEED_X += test-config
 TEST_PROGRAMS_NEED_X += test-date
diff --git a/t/helper/test-chmtime.c b/t/helper/test-chmtime.c
index e760256406..f460b660a6 100644
--- a/t/helper/test-chmtime.c
+++ b/t/helper/test-chmtime.c
@@ -5,28 +5,29 @@
  *
  * The mtime can be changed to an absolute value:
  *
- * test-chmtime = file...
+ * test-tool chmtime = file...
  *
  * Relative to the current time as returned by time(3):
  *
- * test-chmtime =+ (or =-) file...
+ * test-tool chmtime =+ (or =-) file...
  *
  * Or relative to the current mtime of the file:
  *
- * test-chmtime  file...
- * test-chmtime + (or -) file...
+ * test-tool chmtime  file...
+ * test-tool chmtime + (or -) file...
  *
  * Examples:
  *
  * To just print the mtime use --verbose and set the file mtime offset to 0:
  *
- * test-chmtime -v +0 file
+ * test-tool chmtime -v +0 file
  *
  * To set the mtime to current time:
  *
- * test-chmtime =+0 file
+ * test-tool chmtime =+0 file
  *
  */
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include 
 
@@ -56,7 +57,7 @@ static int timespec_arg(const char *arg, long int *set_time, 
int *set_eq)
return 1;
 }
 
-int cmd_main(int argc, const char **argv)
+int test_chmtime(int argc, const char **argv)
 {
static int verbose;
 
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index c730f718ca..c22f300f5e 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -7,6 +7,7 @@ struct test_cmd {
 };
 
 static struct test_cmd cmds[] = {
+   { "chmtime", test_chmtime },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 6ce57ae0cc..61ca4a7055 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -1,4 +1,6 @@
 #ifndef __TEST_TOOL_H__
 #define __TEST_TOOL_H__
 
+int test_chmtime(int argc, const char **argv);
+
 #endif
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 4c1f81f167..a8130f9119 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -49,7 +49,7 @@ rawsvnrepo="$svnrepo"
 svnrepo="file://$svnrepo"
 
 poke() {
-   test-chmtime +1 "$1"
+   test-tool chmtime +1 "$1"
 }
 
 # We need this, because we should pass empty configuration directory to
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index a66936fe9b..4b5d443280 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -332,12 +332,12 @@ test_expect_success 'shared index files expire after 2 
weeks by default' '
git update-index --add ten &&
test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
just_under_2_weeks_ago=$((5-14*86400)) &&
-   test-chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
+   test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
: >eleven &&
git update-index --add eleven &&
test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
just_over_2_weeks_ago=$((-1-14*86400)) 

[PATCH 06/36] t/helper: merge test-ctype into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   | 2 +-
 t/helper/test-ctype.c  | 3 ++-
 t/helper/test-tool.c   | 1 +
 t/helper/test-tool.h   | 1 +
 t/t0070-fundamental.sh | 2 +-
 5 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 227f16ad17..d09710dc3d 100644
--- a/Makefile
+++ b/Makefile
@@ -654,10 +654,10 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
 TEST_BUILTINS_OBJS += test-chmtime.o
 TEST_BUILTINS_OBJS += test-config.o
+TEST_BUILTINS_OBJS += test-ctype.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
-TEST_PROGRAMS_NEED_X += test-ctype
 TEST_PROGRAMS_NEED_X += test-date
 TEST_PROGRAMS_NEED_X += test-delta
 TEST_PROGRAMS_NEED_X += test-drop-caches
diff --git a/t/helper/test-ctype.c b/t/helper/test-ctype.c
index bb72c47df5..a1b0fb344a 100644
--- a/t/helper/test-ctype.c
+++ b/t/helper/test-ctype.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 
 static int rc;
@@ -28,7 +29,7 @@ static int is_in(const char *s, int ch)
 #define LOWER "abcdefghijklmnopqrstuvwxyz"
 #define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
-int cmd_main(int argc, const char **argv)
+int test_ctype(int argc, const char **argv)
 {
TEST_CLASS(isdigit, DIGIT);
TEST_CLASS(isspace, " \n\r\t");
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 64d1632d92..eef6a8e003 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -9,6 +9,7 @@ struct test_cmd {
 static struct test_cmd cmds[] = {
{ "chmtime", test_chmtime },
{ "config", test_config },
+   { "ctype", test_ctype },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 00eef888fa..41620666e3 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -3,6 +3,7 @@
 
 int test_chmtime(int argc, const char **argv);
 int test_config(int argc, const char **argv);
+int test_ctype(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
index 991ed2a48d..70d4d98a2e 100755
--- a/t/t0070-fundamental.sh
+++ b/t/t0070-fundamental.sh
@@ -9,7 +9,7 @@ Verify wrappers and compatibility functions.
 . ./test-lib.sh
 
 test_expect_success 'character classes (isspace, isalpha etc.)' '
-   test-ctype
+   test-tool ctype
 '
 
 test_expect_success 'mktemp to nonexistent directory prints filename' '
-- 
2.16.2.903.gd04caf5039



[PATCH 07/36] t/helper: merge test-date into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   |  2 +-
 t/helper/test-date.c   | 17 +
 t/helper/test-tool.c   |  1 +
 t/helper/test-tool.h   |  1 +
 t/t0006-date.sh|  8 
 t/t1300-repo-config.sh |  2 +-
 t/test-lib.sh  |  4 ++--
 7 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/Makefile b/Makefile
index d09710dc3d..efb1872c52 100644
--- a/Makefile
+++ b/Makefile
@@ -655,10 +655,10 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 TEST_BUILTINS_OBJS += test-chmtime.o
 TEST_BUILTINS_OBJS += test-config.o
 TEST_BUILTINS_OBJS += test-ctype.o
+TEST_BUILTINS_OBJS += test-date.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
-TEST_PROGRAMS_NEED_X += test-date
 TEST_PROGRAMS_NEED_X += test-delta
 TEST_PROGRAMS_NEED_X += test-drop-caches
 TEST_PROGRAMS_NEED_X += test-dump-cache-tree
diff --git a/t/helper/test-date.c b/t/helper/test-date.c
index ac83687970..96f4631c35 100644
--- a/t/helper/test-date.c
+++ b/t/helper/test-date.c
@@ -1,13 +1,14 @@
+#include "test-tool.h"
 #include "cache.h"
 
 static const char *usage_msg = "\n"
-"  test-date relative [time_t]...\n"
-"  test-date show: [time_t]...\n"
-"  test-date parse [date]...\n"
-"  test-date approxidate [date]...\n"
-"  test-date timestamp [date]...\n"
-"  test-date is64bit\n"
-"  test-date time_t-is64bit\n";
+"  test-tool date relative [time_t]...\n"
+"  test-tool date show: [time_t]...\n"
+"  test-tool date parse [date]...\n"
+"  test-tool date approxidate [date]...\n"
+"  test-tool date timestamp [date]...\n"
+"  test-tool date is64bit\n"
+"  test-tool date time_t-is64bit\n";
 
 static void show_relative_dates(const char **argv, struct timeval *now)
 {
@@ -81,7 +82,7 @@ static void parse_approx_timestamp(const char **argv, struct 
timeval *now)
}
 }
 
-int cmd_main(int argc, const char **argv)
+int test_date(int argc, const char **argv)
 {
struct timeval now;
const char *x;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index eef6a8e003..fe130ffbf2 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -10,6 +10,7 @@ static struct test_cmd cmds[] = {
{ "chmtime", test_chmtime },
{ "config", test_config },
{ "ctype", test_ctype },
+   { "date", test_date },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 41620666e3..99ca1176dc 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -4,6 +4,7 @@
 int test_chmtime(int argc, const char **argv);
 int test_config(int argc, const char **argv);
 int test_ctype(int argc, const char **argv);
+int test_date(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 7ac9466d50..64ff86df8e 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -10,7 +10,7 @@ check_relative() {
t=$(($TEST_DATE_NOW - $1))
echo "$t -> $2" >expect
test_expect_${3:-success} "relative date ($2)" "
-   test-date relative $t >actual &&
+   test-tool date relative $t >actual &&
test_i18ncmp expect actual
"
 }
@@ -35,7 +35,7 @@ check_show () {
zone=$5
test_expect_success $prereqs "show date ($format:$time)" '
echo "$time -> $expect" >expect &&
-   TZ=${zone:-$TZ} test-date show:"$format" "$time" >actual &&
+   TZ=${zone:-$TZ} test-tool date show:"$format" "$time" >actual &&
test_cmp expect actual
'
 }
@@ -71,7 +71,7 @@ check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +" 
TIME_IS_64BIT,TIME_T_
 check_parse() {
echo "$1 -> $2" >expect
test_expect_${4:-success} "parse date ($1${3:+ TZ=$3})" "
-   TZ=${3:-$TZ} test-date parse '$1' >actual &&
+   TZ=${3:-$TZ} test-tool date parse '$1' >actual &&
test_cmp expect actual
"
 }
@@ -92,7 +92,7 @@ check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' 
EST5
 check_approxidate() {
echo "$1 -> $2 +" >expect
test_expect_${3:-success} "parse approxidate ($1)" "
-   test-date approxidate '$1' >actual &&
+   test-tool date approxidate '$1' >actual &&
test_cmp expect actual
"
 }
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 4f8e6f5fde..8780934478 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -914,7 +914,7 @@ test_expect_success 'get --expiry-date' '
invalid1 = "abc"
EOF
cat >expect <<-EOF &&
-   $(test-date timestamp $rel)
+   $(test-tool date timestamp $rel)
1275666415
1510441871
1510348087
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 7ab8af47a5..483c8d6d7c 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1206,5 +1206,5 @@ test_lazy_prereq 

[PATCH 08/36] t/helper: merge (unused) test-delta into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile  | 2 +-
 t/helper/test-delta.c | 5 +++--
 t/helper/test-tool.c  | 1 +
 t/helper/test-tool.h  | 1 +
 4 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index efb1872c52..327d63217a 100644
--- a/Makefile
+++ b/Makefile
@@ -656,10 +656,10 @@ TEST_BUILTINS_OBJS += test-chmtime.o
 TEST_BUILTINS_OBJS += test-config.o
 TEST_BUILTINS_OBJS += test-ctype.o
 TEST_BUILTINS_OBJS += test-date.o
+TEST_BUILTINS_OBJS += test-delta.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
-TEST_PROGRAMS_NEED_X += test-delta
 TEST_PROGRAMS_NEED_X += test-drop-caches
 TEST_PROGRAMS_NEED_X += test-dump-cache-tree
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
diff --git a/t/helper/test-delta.c b/t/helper/test-delta.c
index 591730adc4..fae9712d57 100644
--- a/t/helper/test-delta.c
+++ b/t/helper/test-delta.c
@@ -8,14 +8,15 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "delta.h"
 #include "cache.h"
 
 static const char usage_str[] =
-   "test-delta (-d|-p)   ";
+   "test-tool delta (-d|-p)   ";
 
-int cmd_main(int argc, const char **argv)
+int test_delta(int argc, const char **argv)
 {
int fd;
struct stat st;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index fe130ffbf2..e48c1f2d5f 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -11,6 +11,7 @@ static struct test_cmd cmds[] = {
{ "config", test_config },
{ "ctype", test_ctype },
{ "date", test_date },
+   { "delta", test_delta },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 99ca1176dc..0ee098f1e3 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -5,6 +5,7 @@ int test_chmtime(int argc, const char **argv);
 int test_config(int argc, const char **argv);
 int test_ctype(int argc, const char **argv);
 int test_date(int argc, const char **argv);
+int test_delta(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
-- 
2.16.2.903.gd04caf5039



[PATCH 16/36] t/helper: merge (unused) test-match-trees into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile| 2 +-
 t/helper/test-match-trees.c | 3 ++-
 t/helper/test-tool.c| 1 +
 t/helper/test-tool.h| 1 +
 4 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index d7342e3a8b..6552a8f4ed 100644
--- a/Makefile
+++ b/Makefile
@@ -665,13 +665,13 @@ TEST_BUILTINS_OBJS += test-genrandom.o
 TEST_BUILTINS_OBJS += test-hashmap.o
 TEST_BUILTINS_OBJS += test-index-version.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
+TEST_BUILTINS_OBJS += test-match-trees.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
-TEST_PROGRAMS_NEED_X += test-match-trees
 TEST_PROGRAMS_NEED_X += test-mergesort
 TEST_PROGRAMS_NEED_X += test-mktemp
 TEST_PROGRAMS_NEED_X += test-online-cpus
diff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c
index 356d8edef1..2d58886acb 100644
--- a/t/helper/test-match-trees.c
+++ b/t/helper/test-match-trees.c
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "tree.h"
 
-int cmd_main(int ac, const char **av)
+int test_match_trees(int ac, const char **av)
 {
struct object_id hash1, hash2, shifted;
struct tree *one, *two;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index c8c8f3ead6..cde9f16fc8 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -20,6 +20,7 @@ static struct test_cmd cmds[] = {
{ "hashmap", test_hashmap },
{ "index-version", test_index_version },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
+   { "match-trees", test_match_trees },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index a81e071a80..937c408dcc 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -14,6 +14,7 @@ int test_genrandom(int argc, const char **argv);
 int test_hashmap(int argc, const char **argv);
 int test_index_version(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
+int test_match_trees(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
-- 
2.16.2.903.gd04caf5039



[PATCH 14/36] t/helper: merge test-hashmap into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile| 2 +-
 t/helper/test-hashmap.c | 5 +++--
 t/helper/test-tool.c| 1 +
 t/helper/test-tool.h| 1 +
 t/t0011-hashmap.sh  | 4 ++--
 5 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index d0bc6cfecf..f6c3ddc703 100644
--- a/Makefile
+++ b/Makefile
@@ -662,13 +662,13 @@ TEST_BUILTINS_OBJS += test-dump-cache-tree.o
 TEST_BUILTINS_OBJS += test-dump-split-index.o
 TEST_BUILTINS_OBJS += test-example-decorate.o
 TEST_BUILTINS_OBJS += test-genrandom.o
+TEST_BUILTINS_OBJS += test-hashmap.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
-TEST_PROGRAMS_NEED_X += test-hashmap
 TEST_PROGRAMS_NEED_X += test-index-version
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-match-trees
diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c
index 9ae9281c07..6fc840ff72 100644
--- a/t/helper/test-hashmap.c
+++ b/t/helper/test-hashmap.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "hashmap.h"
 #include "strbuf.h"
@@ -77,7 +78,7 @@ static unsigned int hash(unsigned int method, unsigned int i, 
const char *key)
 
 /*
  * Test performance of hashmap.[ch]
- * Usage: time echo "perfhashmap method rounds" | test-hashmap
+ * Usage: time echo "perfhashmap method rounds" | test-tool hashmap
  */
 static void perf_hashmap(unsigned int method, unsigned int rounds)
 {
@@ -144,7 +145,7 @@ static void perf_hashmap(unsigned int method, unsigned int 
rounds)
  *
  * perfhashmap method rounds -> test hashmap.[ch] performance
  */
-int cmd_main(int argc, const char **argv)
+int test_hashmap(int argc, const char **argv)
 {
struct strbuf line = STRBUF_INIT;
struct hashmap map;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index ce13108374..924d8c80f7 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -17,6 +17,7 @@ static struct test_cmd cmds[] = {
{ "dump-split-index", test_dump_split_index },
{ "example-decorate", test_example_decorate },
{ "genrandom", test_genrandom },
+   { "hashmap", test_hashmap },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 6742558cb4..161f5becb7 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -11,6 +11,7 @@ int test_dump_cache_tree(int argc, const char **argv);
 int test_dump_split_index(int argc, const char **argv);
 int test_example_decorate(int argc, const char **argv);
 int test_genrandom(int argc, const char **argv);
+int test_hashmap(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
diff --git a/t/t0011-hashmap.sh b/t/t0011-hashmap.sh
index 9c217d948c..3f1f505e89 100755
--- a/t/t0011-hashmap.sh
+++ b/t/t0011-hashmap.sh
@@ -4,7 +4,7 @@ test_description='test hashmap and string hash functions'
 . ./test-lib.sh
 
 test_hashmap() {
-   echo "$1" | test-hashmap $3 > actual &&
+   echo "$1" | test-tool hashmap $3 > actual &&
echo "$2" > expect &&
test_cmp expect actual
 }
@@ -232,7 +232,7 @@ test_expect_success 'grow / shrink' '
echo value40 >> expect &&
echo size >> in &&
echo 64 39 >> expect &&
-   cat in | test-hashmap > out &&
+   cat in | test-tool hashmap > out &&
test_cmp expect out
 
 '
-- 
2.16.2.903.gd04caf5039



[PATCH 05/36] t/helper: merge test-config into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile  |  2 +-
 t/helper/test-config.c|  5 +++--
 t/helper/test-tool.c  |  1 +
 t/helper/test-tool.h  |  1 +
 t/t1305-config-include.sh |  2 +-
 t/t1308-config-set.sh | 22 +++---
 t/t1309-early-config.sh   | 12 ++--
 7 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/Makefile b/Makefile
index 31287cedf2..227f16ad17 100644
--- a/Makefile
+++ b/Makefile
@@ -653,11 +653,11 @@ X =
 PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
 TEST_BUILTINS_OBJS += test-chmtime.o
+TEST_BUILTINS_OBJS += test-config.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-ctype
-TEST_PROGRAMS_NEED_X += test-config
 TEST_PROGRAMS_NEED_X += test-date
 TEST_PROGRAMS_NEED_X += test-delta
 TEST_PROGRAMS_NEED_X += test-drop-caches
diff --git a/t/helper/test-config.c b/t/helper/test-config.c
index 1a7b8bd3d6..b91cac2c6f 100644
--- a/t/helper/test-config.c
+++ b/t/helper/test-config.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "config.h"
 #include "string-list.h"
@@ -32,7 +33,7 @@
  * Examples:
  *
  * To print the value with highest priority for key "foo.bAr Baz.rock":
- * test-config get_value "foo.bAr Baz.rock"
+ * test-tool config get_value "foo.bAr Baz.rock"
  *
  */
 
@@ -77,7 +78,7 @@ static int early_config_cb(const char *var, const char 
*value, void *vdata)
return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int test_config(int argc, const char **argv)
 {
int i, val;
const char *v;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index c4e9933f93..64d1632d92 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -8,6 +8,7 @@ struct test_cmd {
 
 static struct test_cmd cmds[] = {
{ "chmtime", test_chmtime },
+   { "config", test_config },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index eaec143259..00eef888fa 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -2,6 +2,7 @@
 #define __TEST_TOOL_H__
 
 int test_chmtime(int argc, const char **argv);
+int test_config(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index d9d2f545a4..f035ee40a3 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -224,7 +224,7 @@ test_expect_success 'conditional include, early config 
reading' '
echo "[includeIf \"gitdir:foo/\"]path=bar6" >>.git/config &&
echo "[test]six=6" >.git/bar6 &&
echo 6 >expect &&
-   test-config read_early_config test.six >actual &&
+   test-tool config read_early_config test.six >actual &&
test_cmp expect actual
)
 '
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index bafed5c9b8..3e00d1af01 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -18,7 +18,7 @@ check_config () {
then
printf "%s\n" "$@"
fi >expect &&
-   test_expect_code $expect_code test-config "$op" "$key" >actual &&
+   test_expect_code $expect_code test-tool config "$op" "$key" >actual &&
test_cmp expect actual
 }
 
@@ -125,7 +125,7 @@ test_expect_success 'find string value for a key' '
 '
 
 test_expect_success 'check line error when NULL string is queried' '
-   test_expect_code 128 test-config get_string case.foo 2>result &&
+   test_expect_code 128 test-tool config get_string case.foo 2>result &&
test_i18ngrep "fatal: .*case\.foo.*\.git/config.*line 7" result
 '
 
@@ -155,13 +155,13 @@ test_expect_success 'find value from a configset' '
baz = ball
EOF
echo silk >expect &&
-   test-config configset_get_value my.new config2 .git/config >actual &&
+   test-tool config configset_get_value my.new config2 .git/config >actual 
&&
test_cmp expect actual
 '
 
 test_expect_success 'find value with highest priority from a configset' '
echo hask >expect &&
-   test-config configset_get_value case.baz config2 .git/config >actual &&
+   test-tool config configset_get_value case.baz config2 .git/config 
>actual &&
test_cmp expect actual
 '
 
@@ -173,20 +173,20 @@ test_expect_success 'find value_list for a key from a 
configset' '
lama
ball
EOF
-   test-config configset_get_value case.baz config2 .git/config >actual &&
+   test-tool config configset_get_value case.baz config2 .git/config 
>actual &&
test_cmp expect actual
 '
 
 test_expect_success 'proper error on non-existent files' '
echo "Error (-1) reading configuration file non-existent-file." >expect 
&&
-   

[PATCH 17/36] t/helper: merge (unused) test-mergesort into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile  | 2 +-
 t/helper/test-mergesort.c | 3 ++-
 t/helper/test-tool.c  | 1 +
 t/helper/test-tool.h  | 1 +
 4 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 6552a8f4ed..67f37b849e 100644
--- a/Makefile
+++ b/Makefile
@@ -666,13 +666,13 @@ TEST_BUILTINS_OBJS += test-hashmap.o
 TEST_BUILTINS_OBJS += test-index-version.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-match-trees.o
+TEST_BUILTINS_OBJS += test-mergesort.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
-TEST_PROGRAMS_NEED_X += test-mergesort
 TEST_PROGRAMS_NEED_X += test-mktemp
 TEST_PROGRAMS_NEED_X += test-online-cpus
 TEST_PROGRAMS_NEED_X += test-parse-options
diff --git a/t/helper/test-mergesort.c b/t/helper/test-mergesort.c
index 335cf6b626..31258e40d9 100644
--- a/t/helper/test-mergesort.c
+++ b/t/helper/test-mergesort.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "mergesort.h"
 
@@ -22,7 +23,7 @@ static int compare_strings(const void *a, const void *b)
return strcmp(x->text, y->text);
 }
 
-int cmd_main(int argc, const char **argv)
+int test_mergesort(int argc, const char **argv)
 {
struct line *line, *p = NULL, *lines = NULL;
struct strbuf sb = STRBUF_INIT;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index cde9f16fc8..4206d96304 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -21,6 +21,7 @@ static struct test_cmd cmds[] = {
{ "index-version", test_index_version },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "match-trees", test_match_trees },
+   { "mergesort", test_mergesort },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 937c408dcc..dff1b804cb 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -15,6 +15,7 @@ int test_hashmap(int argc, const char **argv);
 int test_index_version(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_match_trees(int argc, const char **argv);
+int test_mergesort(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
-- 
2.16.2.903.gd04caf5039



[PATCH 15/36] t/helper: merge test-index-version into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile  | 2 +-
 t/helper/test-index-version.c | 3 ++-
 t/helper/test-tool.c  | 1 +
 t/helper/test-tool.h  | 1 +
 t/t1600-index.sh  | 2 +-
 t/t1700-split-index.sh| 2 +-
 t/t2104-update-index-skip-worktree.sh | 6 +++---
 7 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile
index f6c3ddc703..d7342e3a8b 100644
--- a/Makefile
+++ b/Makefile
@@ -663,13 +663,13 @@ TEST_BUILTINS_OBJS += test-dump-split-index.o
 TEST_BUILTINS_OBJS += test-example-decorate.o
 TEST_BUILTINS_OBJS += test-genrandom.o
 TEST_BUILTINS_OBJS += test-hashmap.o
+TEST_BUILTINS_OBJS += test-index-version.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
-TEST_PROGRAMS_NEED_X += test-index-version
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-match-trees
 TEST_PROGRAMS_NEED_X += test-mergesort
diff --git a/t/helper/test-index-version.c b/t/helper/test-index-version.c
index f569f6b7ef..5fc3b8d7ba 100644
--- a/t/helper/test-index-version.c
+++ b/t/helper/test-index-version.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int test_index_version(int argc, const char **argv)
 {
struct cache_header hdr;
int version;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 924d8c80f7..c8c8f3ead6 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -18,6 +18,7 @@ static struct test_cmd cmds[] = {
{ "example-decorate", test_example_decorate },
{ "genrandom", test_genrandom },
{ "hashmap", test_hashmap },
+   { "index-version", test_index_version },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 161f5becb7..a81e071a80 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -12,6 +12,7 @@ int test_dump_split_index(int argc, const char **argv);
 int test_example_decorate(int argc, const char **argv);
 int test_genrandom(int argc, const char **argv);
 int test_hashmap(int argc, const char **argv);
+int test_index_version(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
diff --git a/t/t1600-index.sh b/t/t1600-index.sh
index 079d241145..c4422312f4 100755
--- a/t/t1600-index.sh
+++ b/t/t1600-index.sh
@@ -68,7 +68,7 @@ test_expect_success 'GIT_INDEX_VERSION takes precedence over 
config' '
git config --add index.version 2 &&
git add a 2>&1 &&
echo 4 >expect &&
-   test-index-version <.git/index >actual &&
+   test-tool index-version <.git/index >actual &&
test_cmp expect actual
)
 '
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index ec179fbaf7..e4f4c4df4e 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -12,7 +12,7 @@ test_expect_success 'enable split index' '
git config splitIndex.maxPercentChange 100 &&
git update-index --split-index &&
test-tool dump-split-index .git/index >actual &&
-   indexversion=$(test-index-version <.git/index) &&
+   indexversion=$(test-tool index-version <.git/index) &&
if test "$indexversion" = "4"
then
own=432ef4b63f32193984f339431fd50ca796493569
diff --git a/t/t2104-update-index-skip-worktree.sh 
b/t/t2104-update-index-skip-worktree.sh
index cc830da58d..7e2e7dd4ae 100755
--- a/t/t2104-update-index-skip-worktree.sh
+++ b/t/t2104-update-index-skip-worktree.sh
@@ -33,7 +33,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'index is at version 2' '
-   test "$(test-index-version < .git/index)" = 2
+   test "$(test-tool index-version < .git/index)" = 2
 '
 
 test_expect_success 'update-index --skip-worktree' '
@@ -42,7 +42,7 @@ test_expect_success 'update-index --skip-worktree' '
 '
 
 test_expect_success 'index is at version 3 after having some skip-worktree 
entries' '
-   test "$(test-index-version < .git/index)" = 3
+   test "$(test-tool index-version < .git/index)" = 3
 '
 
 test_expect_success 'ls-files -t' '
@@ -55,7 +55,7 @@ test_expect_success 'update-index --no-skip-worktree' '
 '
 
 test_expect_success 'index version is back to 2 when there is no skip-worktree 
entry' '
-   test "$(test-index-version < .git/index)" = 2
+   test "$(test-tool index-version < .git/index)" = 2
 '
 
 test_done
-- 
2.16.2.903.gd04caf5039



[PATCH 12/36] t/helper: merge test-example-decorate into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile | 2 +-
 t/helper/test-example-decorate.c | 3 ++-
 t/helper/test-tool.c | 1 +
 t/helper/test-tool.h | 1 +
 t/t9004-example.sh   | 2 +-
 5 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 8993cec274..895b170fe3 100644
--- a/Makefile
+++ b/Makefile
@@ -660,12 +660,12 @@ TEST_BUILTINS_OBJS += test-delta.o
 TEST_BUILTINS_OBJS += test-drop-caches.o
 TEST_BUILTINS_OBJS += test-dump-cache-tree.o
 TEST_BUILTINS_OBJS += test-dump-split-index.o
+TEST_BUILTINS_OBJS += test-example-decorate.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
-TEST_PROGRAMS_NEED_X += test-example-decorate
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-genrandom
 TEST_PROGRAMS_NEED_X += test-hashmap
diff --git a/t/helper/test-example-decorate.c b/t/helper/test-example-decorate.c
index 90dc97a9d0..280b5a8fbe 100644
--- a/t/helper/test-example-decorate.c
+++ b/t/helper/test-example-decorate.c
@@ -1,8 +1,9 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "object.h"
 #include "decorate.h"
 
-int cmd_main(int argc, const char **argv)
+int test_example_decorate(int argc, const char **argv)
 {
struct decoration n;
struct object_id one_oid = { {1} };
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 9be6ec3764..92e6f0d5b4 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -15,6 +15,7 @@ static struct test_cmd cmds[] = {
{ "drop-caches", test_drop_caches },
{ "dump-cache-tree", test_dump_cache_tree },
{ "dump-split-index", test_dump_split_index },
+   { "example-decorate", test_example_decorate },
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "sha1", test_sha1 },
 };
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index d062bad365..e97d6c4aaa 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -9,6 +9,7 @@ int test_delta(int argc, const char **argv);
 int test_drop_caches(int argc, const char **argv);
 int test_dump_cache_tree(int argc, const char **argv);
 int test_dump_split_index(int argc, const char **argv);
+int test_example_decorate(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
diff --git a/t/t9004-example.sh b/t/t9004-example.sh
index b28a028f55..7e8894a4a7 100755
--- a/t/t9004-example.sh
+++ b/t/t9004-example.sh
@@ -4,7 +4,7 @@ test_description='check that example code compiles and runs'
 . ./test-lib.sh
 
 test_expect_success 'decorate' '
-   test-example-decorate
+   test-tool example-decorate
 '
 
 test_done
-- 
2.16.2.903.gd04caf5039



[PATCH 20/36] t/helper: merge test-path-utils into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   |  2 +-
 t/helper/test-path-utils.c |  3 +-
 t/helper/test-tool.c   |  1 +
 t/helper/test-tool.h   |  1 +
 t/lib-git-p4.sh|  2 +-
 t/t0060-path-utils.sh  | 60 +++---
 t/t1501-work-tree.sh   |  8 ++---
 7 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/Makefile b/Makefile
index 91af906d08..751ea6cad7 100644
--- a/Makefile
+++ b/Makefile
@@ -669,6 +669,7 @@ TEST_BUILTINS_OBJS += test-match-trees.o
 TEST_BUILTINS_OBJS += test-mergesort.o
 TEST_BUILTINS_OBJS += test-mktemp.o
 TEST_BUILTINS_OBJS += test-online-cpus.o
+TEST_BUILTINS_OBJS += test-path-utils.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -676,7 +677,6 @@ TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
-TEST_PROGRAMS_NEED_X += test-path-utils
 TEST_PROGRAMS_NEED_X += test-prio-queue
 TEST_PROGRAMS_NEED_X += test-read-cache
 TEST_PROGRAMS_NEED_X += test-write-cache
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index 2b3c5092a1..e00e423325 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "string-list.h"
 
@@ -170,7 +171,7 @@ static struct test_data dirname_data[] = {
{ NULL,  NULL }
 };
 
-int cmd_main(int argc, const char **argv)
+int test_path_utils(int argc, const char **argv)
 {
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
char *buf = xmallocz(strlen(argv[2]));
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 29b04dd103..23e843ab46 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -24,6 +24,7 @@ static struct test_cmd cmds[] = {
{ "mergesort", test_mergesort },
{ "mktemp", test_mktemp },
{ "online-cpus", test_online_cpus },
+   { "path-utils", test_path_utils },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index b7dafee709..4bcca38f8e 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -18,6 +18,7 @@ int test_match_trees(int argc, const char **argv);
 int test_mergesort(int argc, const char **argv);
 int test_mktemp(int argc, const char **argv);
 int test_online_cpus(int argc, const char **argv);
+int test_path_utils(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index 54fd5a6ca0..c27599474c 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -39,7 +39,7 @@ native_path () {
then
path=$(cygpath --windows "$path")
else
-   path=$(test-path-utils real_path "$path")
+   path=$(test-tool path-utils real_path "$path")
fi &&
echo "$path"
 }
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 7ea2bb515b..f46e3c4995 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -8,15 +8,15 @@ test_description='Test various path utilities'
 . ./test-lib.sh
 
 norm_path() {
-   expected=$(test-path-utils print_path "$2")
+   expected=$(test-tool path-utils print_path "$2")
test_expect_success $3 "normalize path: $1 => $2" \
-   "test \"\$(test-path-utils normalize_path_copy '$1')\" = '$expected'"
+   "test \"\$(test-tool path-utils normalize_path_copy '$1')\" = 
'$expected'"
 }
 
 relative_path() {
-   expected=$(test-path-utils print_path "$3")
+   expected=$(test-tool path-utils print_path "$3")
test_expect_success $4 "relative path: $1 $2 => $3" \
-   "test \"\$(test-path-utils relative_path '$1' '$2')\" = '$expected'"
+   "test \"\$(test-tool path-utils relative_path '$1' '$2')\" = 
'$expected'"
 }
 
 test_submodule_relative_url() {
@@ -37,7 +37,7 @@ test_git_path() {
 # On Windows, we are using MSYS's bash, which mangles the paths.
 # Absolute paths are anchored at the MSYS installation directory,
 # which means that the path / accounts for this many characters:
-rootoff=$(test-path-utils normalize_path_copy / | wc -c)
+rootoff=$(test-tool path-utils normalize_path_copy / | wc -c)
 # Account for the trailing LF:
 if test $rootoff = 2; then
rootoff=# we are on Unix
@@ -46,7 +46,7 @@ else
# In MSYS2, the root directory "/" is translated into a Windows
# directory *with* trailing slash. Let's test for that and adjust
# our expected longest ancestor length accordingly.
-   case "$(test-path-utils print_path /)" in
+   case "$(test-tool path-utils print_path /)" in
*/) rootslash=1;;
*) rootslash=0;;
esac
@@ -61,7 +61,7 @@ ancestor() {
expected=$(($expected+$rootoff))
fi
test_expect_success "longest ancestor: $1 $2 => 

[PATCH 24/36] t/helper: merge test-regex into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile| 2 +-
 t/helper/test-regex.c   | 7 ---
 t/helper/test-tool.c| 1 +
 t/helper/test-tool.h| 1 +
 t/t0070-fundamental.sh  | 2 +-
 t/t7812-grep-icase-non-ascii.sh | 2 +-
 6 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 20080fddb8..7444c00bbb 100644
--- a/Makefile
+++ b/Makefile
@@ -673,6 +673,7 @@ TEST_BUILTINS_OBJS += test-path-utils.o
 TEST_BUILTINS_OBJS += test-prio-queue.o
 TEST_BUILTINS_OBJS += test-read-cache.o
 TEST_BUILTINS_OBJS += test-ref-store.o
+TEST_BUILTINS_OBJS += test-regex.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -681,7 +682,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-regex
 TEST_PROGRAMS_NEED_X += test-revision-walking
 TEST_PROGRAMS_NEED_X += test-run-command
 TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
diff --git a/t/helper/test-regex.c b/t/helper/test-regex.c
index b5ea8a97c5..99d1c8edae 100644
--- a/t/helper/test-regex.c
+++ b/t/helper/test-regex.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "gettext.h"
 
@@ -36,7 +37,7 @@ static int test_regex_bug(void)
return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int test_regex(int argc, const char **argv)
 {
const char *pat;
const char *str;
@@ -47,8 +48,8 @@ int cmd_main(int argc, const char **argv)
if (argc == 2 && !strcmp(argv[1], "--bug"))
return test_regex_bug();
else if (argc < 3)
-   usage("test-regex --bug\n"
- "test-regex   []");
+   usage("test-tool regex --bug\n"
+ "test-tool regex   []");
 
argv++;
pat = *argv++;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 92bd38ac61..7352bd40e8 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -28,6 +28,7 @@ static struct test_cmd cmds[] = {
{ "prio-queue", test_prio_queue },
{ "read-cache", test_read_cache },
{ "ref-store", test_ref_store },
+   { "regex", test_regex },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 662d3c9645..3cb2fd9509 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -22,6 +22,7 @@ int test_path_utils(int argc, const char **argv);
 int test_prio_queue(int argc, const char **argv);
 int test_read_cache(int argc, const char **argv);
 int test_ref_store(int argc, const char **argv);
+int test_regex(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
index ac007938ee..23fbe6434a 100755
--- a/t/t0070-fundamental.sh
+++ b/t/t0070-fundamental.sh
@@ -31,7 +31,7 @@ test_expect_success 'git_mkstemps_mode does not fail if fd 0 
is not open' '
 
 test_expect_success 'check for a bug in the regex routines' '
# if this test fails, re-build git with NO_REGEX=1
-   test-regex --bug
+   test-tool regex --bug
 '
 
 test_done
diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh
index 0059a1f837..0c685d3598 100755
--- a/t/t7812-grep-icase-non-ascii.sh
+++ b/t/t7812-grep-icase-non-ascii.sh
@@ -12,7 +12,7 @@ test_expect_success GETTEXT_LOCALE 'setup' '
 '
 
 test_have_prereq GETTEXT_LOCALE &&
-test-regex "HALLÓ" "Halló" ICASE &&
+test-tool regex "HALLÓ" "Halló" ICASE &&
 test_set_prereq REGEX_LOCALE
 
 test_expect_success REGEX_LOCALE 'grep literal string, no -F' '
-- 
2.16.2.903.gd04caf5039



[PATCH 26/36] t/helper: merge test-run-command into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile|  2 +-
 t/helper/test-run-command.c |  3 ++-
 t/helper/test-tool.c|  1 +
 t/helper/test-tool.h|  1 +
 t/t0061-run-command.sh  | 24 
 5 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/Makefile b/Makefile
index 3ed461cd55..adece67b8e 100644
--- a/Makefile
+++ b/Makefile
@@ -675,6 +675,7 @@ TEST_BUILTINS_OBJS += test-read-cache.o
 TEST_BUILTINS_OBJS += test-ref-store.o
 TEST_BUILTINS_OBJS += test-regex.o
 TEST_BUILTINS_OBJS += test-revision-walking.o
+TEST_BUILTINS_OBJS += test-run-command.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -683,7 +684,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-run-command
 TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
 TEST_PROGRAMS_NEED_X += test-sha1-array
 TEST_PROGRAMS_NEED_X += test-sigchain
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index 153342e44d..3aa49c3fbb 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "run-command.h"
 #include "argv-array.h"
@@ -49,7 +50,7 @@ static int task_finished(int result,
return 1;
 }
 
-int cmd_main(int argc, const char **argv)
+int test_run_command(int argc, const char **argv)
 {
struct child_process proc = CHILD_PROCESS_INIT;
int jobs;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 4586ae9440..a8a92b6a10 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -30,6 +30,7 @@ static struct test_cmd cmds[] = {
{ "ref-store", test_ref_store },
{ "regex", test_regex },
{ "revision-walking", test_revision_walking },
+   { "run-command", test_run_command },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 9bbdb05848..23f63ee357 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -24,6 +24,7 @@ int test_read_cache(int argc, const char **argv);
 int test_ref_store(int argc, const char **argv);
 int test_regex(int argc, const char **argv);
 int test_revision_walking(int argc, const char **argv);
+int test_run_command(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index 24c92b6cd7..d03149be9f 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -14,13 +14,13 @@ EOF
 >empty
 
 test_expect_success 'start_command reports ENOENT' '
-   test-run-command start-command-ENOENT ./does-not-exist
+   test-tool run-command start-command-ENOENT ./does-not-exist
 '
 
 test_expect_success 'run_command can run a command' '
cat hello-script >hello.sh &&
chmod +x hello.sh &&
-   test-run-command run-command ./hello.sh >actual 2>err &&
+   test-tool run-command run-command ./hello.sh >actual 2>err &&
 
test_cmp hello-script actual &&
test_cmp empty err
@@ -31,7 +31,7 @@ test_expect_success !MINGW 'run_command can run a script 
without a #! line' '
cat hello-script
EOF
chmod +x hello &&
-   test-run-command run-command ./hello >actual 2>err &&
+   test-tool run-command run-command ./hello >actual 2>err &&
 
test_cmp hello-script actual &&
test_cmp empty err
@@ -45,7 +45,7 @@ test_expect_success 'run_command does not try to execute a 
directory' '
EOF
 
PATH=$PWD/bin1:$PWD/bin2:$PATH \
-   test-run-command run-command greet >actual 2>err &&
+   test-tool run-command run-command greet >actual 2>err &&
test_cmp bin2/greet actual &&
test_cmp empty err
 '
@@ -62,7 +62,7 @@ test_expect_success POSIXPERM 'run_command passes over 
non-executable file' '
EOF
 
PATH=$PWD/bin1:$PWD/bin2:$PATH \
-   test-run-command run-command greet >actual 2>err &&
+   test-tool run-command run-command greet >actual 2>err &&
test_cmp bin2/greet actual &&
test_cmp empty err
 '
@@ -70,7 +70,7 @@ test_expect_success POSIXPERM 'run_command passes over 
non-executable file' '
 test_expect_success POSIXPERM 'run_command reports EACCES' '
cat hello-script >hello.sh &&
chmod -x hello.sh &&
-   test_must_fail test-run-command run-command ./hello.sh 2>err &&
+   test_must_fail test-tool run-command run-command ./hello.sh 2>err &&
 
grep "fatal: cannot exec.*hello.sh" err
 '
@@ -104,17 +104,17 @@ World
 EOF
 
 test_expect_success 'run_command runs in parallel with more jobs available 
than tasks' '
-   test-run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" 
Hello World" 2>actual &&

[PATCH 35/36] t/helper: merge test-wildmatch into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile  |  2 +-
 t/helper/test-tool.c  |  1 +
 t/helper/test-tool.h  |  1 +
 t/helper/test-wildmatch.c |  3 ++-
 t/t3070-wildmatch.sh  | 14 +++---
 5 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/Makefile b/Makefile
index 7923ec3747..2ab76c6838 100644
--- a/Makefile
+++ b/Makefile
@@ -685,6 +685,7 @@ TEST_BUILTINS_OBJS += test-string-list.o
 TEST_BUILTINS_OBJS += test-submodule-config.o
 TEST_BUILTINS_OBJS += test-subprocess.o
 TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
+TEST_BUILTINS_OBJS += test-wildmatch.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
@@ -694,7 +695,6 @@ TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
 TEST_PROGRAMS_NEED_X += test-svn-fe
 TEST_PROGRAMS_NEED_X += test-tool
-TEST_PROGRAMS_NEED_X += test-wildmatch
 
 TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X))
 
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index f2d60af898..ebf28859b4 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -40,6 +40,7 @@ static struct test_cmd cmds[] = {
{ "submodule-config", test_submodule_config },
{ "subprocess", test_subprocess },
{ "urlmatch-normalization", test_urlmatch_normalization },
+   { "wildmatch", test_wildmatch },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 704ac9df35..b7c8272689 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -34,5 +34,6 @@ int test_string_list(int argc, const char **argv);
 int test_submodule_config(int argc, const char **argv);
 int test_subprocess(int argc, const char **argv);
 int test_urlmatch_normalization(int argc, const char **argv);
+int test_wildmatch(int argc, const char **argv);
 
 #endif
diff --git a/t/helper/test-wildmatch.c b/t/helper/test-wildmatch.c
index 66d33dfcfd..b5c6d10b5e 100644
--- a/t/helper/test-wildmatch.c
+++ b/t/helper/test-wildmatch.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int test_wildmatch(int argc, const char **argv)
 {
int i;
for (i = 2; i < argc; i++) {
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index c1fc6ca730..dce102130f 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -79,12 +79,12 @@ match_with_function() {
if test "$match_expect" = 1
then
test_expect_success "$match_function: match '$text' '$pattern'" 
"
-   test-wildmatch $match_function '$text' '$pattern'
+   test-tool wildmatch $match_function '$text' '$pattern'
"
elif test "$match_expect" = 0
then
test_expect_success "$match_function: no match '$text' 
'$pattern'" "
-   test_must_fail test-wildmatch $match_function '$text' 
'$pattern'
+   test_must_fail test-tool wildmatch $match_function 
'$text' '$pattern'
"
else
test_expect_success "PANIC: Test framework error. Unknown 
matches value $match_expect" 'false'
@@ -148,7 +148,7 @@ match_with_ls_files() {
 match() {
if test "$#" = 6
then
-   # When test-wildmatch and git ls-files produce the same
+   # When test-tool wildmatch and git ls-files produce the same
# result.
match_glob=$1
match_file_glob=$match_glob
@@ -204,19 +204,19 @@ match() {
fi
'
 
-   # $1: Case sensitive glob match: test-wildmatch & ls-files
+   # $1: Case sensitive glob match: test-tool wildmatch & ls-files
match_with_function "$text" "$pattern" $match_glob "wildmatch"
match_with_ls_files "$text" "$pattern" $match_file_glob "wildmatch" " 
--glob-pathspecs"
 
-   # $2: Case insensitive glob match: test-wildmatch & ls-files
+   # $2: Case insensitive glob match: test-tool wildmatch & ls-files
match_with_function "$text" "$pattern" $match_iglob "iwildmatch"
match_with_ls_files "$text" "$pattern" $match_file_iglob "iwildmatch" " 
--glob-pathspecs --icase-pathspecs"
 
-   # $3: Case sensitive path match: test-wildmatch & ls-files
+   # $3: Case sensitive path match: test-tool wildmatch & ls-files
match_with_function "$text" "$pattern" $match_pathmatch "pathmatch"
match_with_ls_files "$text" "$pattern" $match_file_pathmatch 
"pathmatch" ""
 
-   # $4: Case insensitive path match: test-wildmatch & ls-files
+   # $4: Case insensitive path match: test-tool wildmatch & ls-files
match_with_function "$text" "$pattern" $match_pathmatchi "ipathmatch"
match_with_ls_files "$text" "$pattern" $match_file_pathmatchi 
"ipathmatch" " --icase-pathspecs"
 }
-- 
2.16.2.903.gd04caf5039



[PATCH 33/36] t/helper: merge test-subprocess into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   | 2 +-
 t/helper/test-subprocess.c | 3 ++-
 t/helper/test-tool.c   | 1 +
 t/helper/test-tool.h   | 1 +
 t/t1501-work-tree.sh   | 2 +-
 5 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index c1dc9ff8d6..893ea64ca2 100644
--- a/Makefile
+++ b/Makefile
@@ -683,6 +683,7 @@ TEST_BUILTINS_OBJS += test-sigchain.o
 TEST_BUILTINS_OBJS += test-strcmp-offset.o
 TEST_BUILTINS_OBJS += test-string-list.o
 TEST_BUILTINS_OBJS += test-submodule-config.o
+TEST_BUILTINS_OBJS += test-subprocess.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
@@ -690,7 +691,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
 TEST_PROGRAMS_NEED_X += test-tool
 TEST_PROGRAMS_NEED_X += test-urlmatch-normalization
diff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c
index 30c5765bfc..2699257663 100644
--- a/t/helper/test-subprocess.c
+++ b/t/helper/test-subprocess.c
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "run-command.h"
 
-int cmd_main(int argc, const char **argv)
+int test_subprocess(int argc, const char **argv)
 {
struct child_process cp = CHILD_PROCESS_INIT;
int nogit = 0;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 1b95f1b30b..49f4d6f901 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -38,6 +38,7 @@ static struct test_cmd cmds[] = {
{ "strcmp-offset", test_strcmp_offset },
{ "string-list", test_string_list },
{ "submodule-config", test_submodule_config },
+   { "subprocess", test_subprocess },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 16a05993e5..eaf15cbd84 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -32,5 +32,6 @@ int test_sigchain(int argc, const char **argv);
 int test_strcmp_offset(int argc, const char **argv);
 int test_string_list(int argc, const char **argv);
 int test_submodule_config(int argc, const char **argv);
+int test_subprocess(int argc, const char **argv);
 
 #endif
diff --git a/t/t1501-work-tree.sh b/t/t1501-work-tree.sh
index b07cb9140e..02cf2013fc 100755
--- a/t/t1501-work-tree.sh
+++ b/t/t1501-work-tree.sh
@@ -341,7 +341,7 @@ test_expect_success 'make_relative_path handles double 
slashes in GIT_DIR' '
 
 test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
-   test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
+   test-tool subprocess --setup-work-tree rev-parse --show-toplevel 
>actual &&
echo "$(pwd)/repo.git/work" >expected &&
test_cmp expected actual
 '
-- 
2.16.2.903.gd04caf5039



[PATCH 22/36] t/helepr: merge test-read-cache into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   | 2 +-
 t/helper/test-read-cache.c | 3 ++-
 t/helper/test-tool.c   | 1 +
 t/helper/test-tool.h   | 1 +
 t/perf/p0002-read-cache.sh | 2 +-
 5 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 076c778494..393fb9aca4 100644
--- a/Makefile
+++ b/Makefile
@@ -671,6 +671,7 @@ TEST_BUILTINS_OBJS += test-mktemp.o
 TEST_BUILTINS_OBJS += test-online-cpus.o
 TEST_BUILTINS_OBJS += test-path-utils.o
 TEST_BUILTINS_OBJS += test-prio-queue.o
+TEST_BUILTINS_OBJS += test-read-cache.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -678,7 +679,6 @@ TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
-TEST_PROGRAMS_NEED_X += test-read-cache
 TEST_PROGRAMS_NEED_X += test-write-cache
 TEST_PROGRAMS_NEED_X += test-ref-store
 TEST_PROGRAMS_NEED_X += test-regex
diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c
index 48255eef31..cd38f09414 100644
--- a/t/helper/test-read-cache.c
+++ b/t/helper/test-read-cache.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int test_read_cache(int argc, const char **argv)
 {
int i, cnt = 1;
if (argc == 2)
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 24ce124868..d82db3c90f 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -26,6 +26,7 @@ static struct test_cmd cmds[] = {
{ "online-cpus", test_online_cpus },
{ "path-utils", test_path_utils },
{ "prio-queue", test_prio_queue },
+   { "read-cache", test_read_cache },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 713be481d5..2c98cdde41 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -20,6 +20,7 @@ int test_mktemp(int argc, const char **argv);
 int test_online_cpus(int argc, const char **argv);
 int test_path_utils(int argc, const char **argv);
 int test_prio_queue(int argc, const char **argv);
+int test_read_cache(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/perf/p0002-read-cache.sh b/t/perf/p0002-read-cache.sh
index 9180ae9343..cdd105a594 100755
--- a/t/perf/p0002-read-cache.sh
+++ b/t/perf/p0002-read-cache.sh
@@ -8,7 +8,7 @@ test_perf_default_repo
 
 count=1000
 test_perf "read_cache/discard_cache $count times" "
-   test-read-cache $count
+   test-tool read-cache $count
 "
 
 test_done
-- 
2.16.2.903.gd04caf5039



[PATCH 31/36] t/helper: merge test-string-list into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile|  2 +-
 t/helper/test-string-list.c |  3 ++-
 t/helper/test-tool.c|  1 +
 t/helper/test-tool.h|  1 +
 t/perf/p0071-sort.sh|  2 +-
 t/t0063-string-list.sh  | 48 ++---
 6 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/Makefile b/Makefile
index 528a80b6a6..6819792c2b 100644
--- a/Makefile
+++ b/Makefile
@@ -681,6 +681,7 @@ TEST_BUILTINS_OBJS += test-sha1-array.o
 TEST_BUILTINS_OBJS += test-sha1.o
 TEST_BUILTINS_OBJS += test-sigchain.o
 TEST_BUILTINS_OBJS += test-strcmp-offset.o
+TEST_BUILTINS_OBJS += test-string-list.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
@@ -688,7 +689,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-string-list
 TEST_PROGRAMS_NEED_X += test-submodule-config
 TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
diff --git a/t/helper/test-string-list.c b/t/helper/test-string-list.c
index 829ec3d7d2..4ad957c31c 100644
--- a/t/helper/test-string-list.c
+++ b/t/helper/test-string-list.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "string-list.h"
 
@@ -41,7 +42,7 @@ static int prefix_cb(struct string_list_item *item, void 
*cb_data)
return starts_with(item->string, prefix);
 }
 
-int cmd_main(int argc, const char **argv)
+int test_string_list(int argc, const char **argv)
 {
if (argc == 5 && !strcmp(argv[1], "split")) {
struct string_list list = STRING_LIST_INIT_DUP;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 7e684960e0..2e428825d5 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -36,6 +36,7 @@ static struct test_cmd cmds[] = {
{ "sha1", test_sha1 },
{ "sigchain", test_sigchain },
{ "strcmp-offset", test_strcmp_offset },
+   { "string-list", test_string_list },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 42ebb67af6..943d92452a 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -30,5 +30,6 @@ int test_sha1_array(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 int test_sigchain(int argc, const char **argv);
 int test_strcmp_offset(int argc, const char **argv);
+int test_string_list(int argc, const char **argv);
 
 #endif
diff --git a/t/perf/p0071-sort.sh b/t/perf/p0071-sort.sh
index 7c9a35a646..6e924f5fa3 100755
--- a/t/perf/p0071-sort.sh
+++ b/t/perf/p0071-sort.sh
@@ -16,7 +16,7 @@ test_perf 'sort(1)' '
 '
 
 test_perf 'string_list_sort()' '
-   test-string-list sort actual
+   test-tool string-list sort actual
 '
 
 test_expect_success 'string_list_sort() sorts like sort(1)' '
diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh
index dbfc05ebdc..c6ee9f66b1 100755
--- a/t/t0063-string-list.sh
+++ b/t/t0063-string-list.sh
@@ -10,9 +10,9 @@ test_description='Test string list functionality'
 test_split () {
cat >expected &&
test_expect_success "split $1 at $2, max $3" "
-   test-string-list split '$1' '$2' '$3' >actual &&
+   test-tool string-list split '$1' '$2' '$3' >actual &&
test_cmp expected actual &&
-   test-string-list split_in_place '$1' '$2' '$3' >actual &&
+   test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
test_cmp expected actual
"
 }
@@ -61,31 +61,31 @@ test_split ":" ":" "-1" <

[PATCH 23/36] t/helper: merge test-ref-store into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   | 2 +-
 t/helper/test-ref-store.c  | 3 ++-
 t/helper/test-tool.c   | 1 +
 t/helper/test-tool.h   | 1 +
 t/t1405-main-ref-store.sh  | 2 +-
 t/t1406-submodule-ref-store.sh | 2 +-
 t/t1407-worktree-ref-store.sh  | 4 ++--
 7 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 393fb9aca4..20080fddb8 100644
--- a/Makefile
+++ b/Makefile
@@ -672,6 +672,7 @@ TEST_BUILTINS_OBJS += test-online-cpus.o
 TEST_BUILTINS_OBJS += test-path-utils.o
 TEST_BUILTINS_OBJS += test-prio-queue.o
 TEST_BUILTINS_OBJS += test-read-cache.o
+TEST_BUILTINS_OBJS += test-ref-store.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -680,7 +681,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-ref-store
 TEST_PROGRAMS_NEED_X += test-regex
 TEST_PROGRAMS_NEED_X += test-revision-walking
 TEST_PROGRAMS_NEED_X += test-run-command
diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c
index 7120634b04..a797bc532b 100644
--- a/t/helper/test-ref-store.c
+++ b/t/helper/test-ref-store.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "refs.h"
 #include "worktree.h"
@@ -274,7 +275,7 @@ static struct command commands[] = {
{ NULL, NULL }
 };
 
-int cmd_main(int argc, const char **argv)
+int test_ref_store(int argc, const char **argv)
 {
struct ref_store *refs;
const char *func;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index d82db3c90f..92bd38ac61 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -27,6 +27,7 @@ static struct test_cmd cmds[] = {
{ "path-utils", test_path_utils },
{ "prio-queue", test_prio_queue },
{ "read-cache", test_read_cache },
+   { "ref-store", test_ref_store },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 2c98cdde41..662d3c9645 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -21,6 +21,7 @@ int test_online_cpus(int argc, const char **argv);
 int test_path_utils(int argc, const char **argv);
 int test_prio_queue(int argc, const char **argv);
 int test_read_cache(int argc, const char **argv);
+int test_ref_store(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh
index e8115df5ba..a30a080b20 100755
--- a/t/t1405-main-ref-store.sh
+++ b/t/t1405-main-ref-store.sh
@@ -4,7 +4,7 @@ test_description='test main ref store api'
 
 . ./test-lib.sh
 
-RUN="test-ref-store main"
+RUN="test-tool ref-store main"
 
 test_expect_success 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' '
test_commit one &&
diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh
index c32d4cc465..e093782cc3 100755
--- a/t/t1406-submodule-ref-store.sh
+++ b/t/t1406-submodule-ref-store.sh
@@ -4,7 +4,7 @@ test_description='test submodule ref store api'
 
 . ./test-lib.sh
 
-RUN="test-ref-store submodule:sub"
+RUN="test-tool ref-store submodule:sub"
 
 test_expect_success 'setup' '
git init sub &&
diff --git a/t/t1407-worktree-ref-store.sh b/t/t1407-worktree-ref-store.sh
index 8842d0329f..2211f9831f 100755
--- a/t/t1407-worktree-ref-store.sh
+++ b/t/t1407-worktree-ref-store.sh
@@ -4,8 +4,8 @@ test_description='test worktree ref store api'
 
 . ./test-lib.sh
 
-RWT="test-ref-store worktree:wt"
-RMAIN="test-ref-store worktree:main"
+RWT="test-tool ref-store worktree:wt"
+RMAIN="test-tool ref-store worktree:main"
 
 test_expect_success 'setup' '
test_commit first &&
-- 
2.16.2.903.gd04caf5039



[PATCH 21/36] t/helper: merge test-prio-queue into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   | 2 +-
 t/helper/test-prio-queue.c | 3 ++-
 t/helper/test-tool.c   | 1 +
 t/helper/test-tool.h   | 1 +
 t/t0009-prio-queue.sh  | 6 +++---
 5 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index 751ea6cad7..076c778494 100644
--- a/Makefile
+++ b/Makefile
@@ -670,6 +670,7 @@ TEST_BUILTINS_OBJS += test-mergesort.o
 TEST_BUILTINS_OBJS += test-mktemp.o
 TEST_BUILTINS_OBJS += test-online-cpus.o
 TEST_BUILTINS_OBJS += test-path-utils.o
+TEST_BUILTINS_OBJS += test-prio-queue.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -677,7 +678,6 @@ TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
-TEST_PROGRAMS_NEED_X += test-prio-queue
 TEST_PROGRAMS_NEED_X += test-read-cache
 TEST_PROGRAMS_NEED_X += test-write-cache
 TEST_PROGRAMS_NEED_X += test-ref-store
diff --git a/t/helper/test-prio-queue.c b/t/helper/test-prio-queue.c
index ae58fff359..a50216e332 100644
--- a/t/helper/test-prio-queue.c
+++ b/t/helper/test-prio-queue.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "prio-queue.h"
 
@@ -16,7 +17,7 @@ static void show(int *v)
free(v);
 }
 
-int cmd_main(int argc, const char **argv)
+int test_prio_queue(int argc, const char **argv)
 {
struct prio_queue pq = { intcmp };
 
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 23e843ab46..24ce124868 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -25,6 +25,7 @@ static struct test_cmd cmds[] = {
{ "mktemp", test_mktemp },
{ "online-cpus", test_online_cpus },
{ "path-utils", test_path_utils },
+   { "prio-queue", test_prio_queue },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 4bcca38f8e..713be481d5 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -19,6 +19,7 @@ int test_mergesort(int argc, const char **argv);
 int test_mktemp(int argc, const char **argv);
 int test_online_cpus(int argc, const char **argv);
 int test_path_utils(int argc, const char **argv);
+int test_prio_queue(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t0009-prio-queue.sh b/t/t0009-prio-queue.sh
index 94045c3fad..e56dfce668 100755
--- a/t/t0009-prio-queue.sh
+++ b/t/t0009-prio-queue.sh
@@ -17,7 +17,7 @@ cat >expect <<'EOF'
 10
 EOF
 test_expect_success 'basic ordering' '
-   test-prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual &&
+   test-tool prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual &&
test_cmp expect actual
 '
 
@@ -30,7 +30,7 @@ cat >expect <<'EOF'
 6
 EOF
 test_expect_success 'mixed put and get' '
-   test-prio-queue 6 2 4 get 5 3 get get 1 dump >actual &&
+   test-tool prio-queue 6 2 4 get 5 3 get get 1 dump >actual &&
test_cmp expect actual
 '
 
@@ -43,7 +43,7 @@ NULL
 NULL
 EOF
 test_expect_success 'notice empty queue' '
-   test-prio-queue 1 2 get get get 1 2 get get get >actual &&
+   test-tool prio-queue 1 2 get get get 1 2 get get get >actual &&
test_cmp expect actual
 '
 
-- 
2.16.2.903.gd04caf5039



[PATCH 28/36] t/helper: merge test-sha1-array into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   |  2 +-
 t/helper/test-sha1-array.c |  3 ++-
 t/helper/test-tool.c   |  1 +
 t/helper/test-tool.h   |  1 +
 t/t0064-sha1-array.sh  | 16 
 5 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index ba7c7d8a79..b50a0818a9 100644
--- a/Makefile
+++ b/Makefile
@@ -677,6 +677,7 @@ TEST_BUILTINS_OBJS += test-regex.o
 TEST_BUILTINS_OBJS += test-revision-walking.o
 TEST_BUILTINS_OBJS += test-run-command.o
 TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
+TEST_BUILTINS_OBJS += test-sha1-array.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -685,7 +686,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-sha1-array
 TEST_PROGRAMS_NEED_X += test-sigchain
 TEST_PROGRAMS_NEED_X += test-strcmp-offset
 TEST_PROGRAMS_NEED_X += test-string-list
diff --git a/t/helper/test-sha1-array.c b/t/helper/test-sha1-array.c
index edfd52d82a..1e08598beb 100644
--- a/t/helper/test-sha1-array.c
+++ b/t/helper/test-sha1-array.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "sha1-array.h"
 
@@ -7,7 +8,7 @@ static int print_oid(const struct object_id *oid, void *data)
return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int test_sha1_array(int argc, const char **argv)
 {
struct oid_array array = OID_ARRAY_INIT;
struct strbuf line = STRBUF_INIT;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index f12f1ec5bb..54d62b8b32 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -32,6 +32,7 @@ static struct test_cmd cmds[] = {
{ "revision-walking", test_revision_walking },
{ "run-command", test_run_command },
{ "scrap-cache-tree", test_scrap_cache_tree },
+   { "sha1-array", test_sha1_array },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 92504e951f..10d1322e0d 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -26,6 +26,7 @@ int test_regex(int argc, const char **argv);
 int test_revision_walking(int argc, const char **argv);
 int test_run_command(int argc, const char **argv);
 int test_scrap_cache_tree(int argc, const char **argv);
+int test_sha1_array(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t0064-sha1-array.sh b/t/t0064-sha1-array.sh
index 50b31ffe75..67484502a0 100755
--- a/t/t0064-sha1-array.sh
+++ b/t/t0064-sha1-array.sh
@@ -18,7 +18,7 @@ test_expect_success 'ordered enumeration' '
{
echo20 append 88 44 aa 55 &&
echo for_each_unique
-   } | test-sha1-array >actual &&
+   } | test-tool sha1-array >actual &&
test_cmp expect actual
 '
 
@@ -28,7 +28,7 @@ test_expect_success 'ordered enumeration with duplicate 
suppression' '
echo20 append 88 44 aa 55 &&
echo20 append 88 44 aa 55 &&
echo for_each_unique
-   } | test-sha1-array >actual &&
+   } | test-tool sha1-array >actual &&
test_cmp expect actual
 '
 
@@ -36,7 +36,7 @@ test_expect_success 'lookup' '
{
echo20 append 88 44 aa 55 &&
echo20 lookup 55
-   } | test-sha1-array >actual &&
+   } | test-tool sha1-array >actual &&
n=$(cat actual) &&
test "$n" -eq 1
 '
@@ -45,7 +45,7 @@ test_expect_success 'lookup non-existing entry' '
{
echo20 append 88 44 aa 55 &&
echo20 lookup 33
-   } | test-sha1-array >actual &&
+   } | test-tool sha1-array >actual &&
n=$(cat actual) &&
test "$n" -lt 0
 '
@@ -55,7 +55,7 @@ test_expect_success 'lookup with duplicates' '
echo20 append 88 44 aa 55 &&
echo20 append 88 44 aa 55 &&
echo20 lookup 55
-   } | test-sha1-array >actual &&
+   } | test-tool sha1-array >actual &&
n=$(cat actual) &&
test "$n" -ge 2 &&
test "$n" -le 3
@@ -66,7 +66,7 @@ test_expect_success 'lookup non-existing entry with 
duplicates' '
echo20 append 88 44 aa 55 &&
echo20 append 88 44 aa 55 &&
echo20 lookup 66
-   } | test-sha1-array >actual &&
+   } | test-tool sha1-array >actual &&
n=$(cat actual) &&
test "$n" -lt 0
 '
@@ -76,7 +76,7 @@ test_expect_success 'lookup with almost duplicate values' '
echo "append " &&
echo "append 555f" &&
echo20 lookup 55
-   } | test-sha1-array >actual &&
+   } | test-tool sha1-array >actual &&
n=$(cat actual) &&
test "$n" -eq 0
 '
@@ -85,7 +85,7 @@ test_expect_success 'lookup 

[PATCH 25/36] t/helper: merge test-revision-walking into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile | 2 +-
 t/helper/test-revision-walking.c | 3 ++-
 t/helper/test-tool.c | 1 +
 t/helper/test-tool.h | 1 +
 t/t0062-revision-walking.sh  | 2 +-
 5 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 7444c00bbb..3ed461cd55 100644
--- a/Makefile
+++ b/Makefile
@@ -674,6 +674,7 @@ TEST_BUILTINS_OBJS += test-prio-queue.o
 TEST_BUILTINS_OBJS += test-read-cache.o
 TEST_BUILTINS_OBJS += test-ref-store.o
 TEST_BUILTINS_OBJS += test-regex.o
+TEST_BUILTINS_OBJS += test-revision-walking.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -682,7 +683,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-revision-walking
 TEST_PROGRAMS_NEED_X += test-run-command
 TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
 TEST_PROGRAMS_NEED_X += test-sha1-array
diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c
index b8e6fe1d00..467d710da8 100644
--- a/t/helper/test-revision-walking.c
+++ b/t/helper/test-revision-walking.c
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "cache.h"
 #include "commit.h"
 #include "diff.h"
@@ -45,7 +46,7 @@ static int run_revision_walk(void)
return got_revision;
 }
 
-int cmd_main(int argc, const char **argv)
+int test_revision_walking(int argc, const char **argv)
 {
if (argc < 2)
return 1;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 7352bd40e8..4586ae9440 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -29,6 +29,7 @@ static struct test_cmd cmds[] = {
{ "read-cache", test_read_cache },
{ "ref-store", test_ref_store },
{ "regex", test_regex },
+   { "revision-walking", test_revision_walking },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 3cb2fd9509..9bbdb05848 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -23,6 +23,7 @@ int test_prio_queue(int argc, const char **argv);
 int test_read_cache(int argc, const char **argv);
 int test_ref_store(int argc, const char **argv);
 int test_regex(int argc, const char **argv);
+int test_revision_walking(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t0062-revision-walking.sh b/t/t0062-revision-walking.sh
index 113c728e67..8e215867b8 100755
--- a/t/t0062-revision-walking.sh
+++ b/t/t0062-revision-walking.sh
@@ -26,7 +26,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'revision walking can be done twice' '
-   test-revision-walking run-twice >run_twice_actual &&
+   test-tool revision-walking run-twice >run_twice_actual &&
test_cmp run_twice_expected run_twice_actual
 '
 
-- 
2.16.2.903.gd04caf5039



[PATCH 30/36] t/helper: merge test-strcmp-offset into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile  | 2 +-
 t/helper/test-strcmp-offset.c | 3 ++-
 t/helper/test-tool.c  | 1 +
 t/helper/test-tool.h  | 1 +
 t/t0065-strcmp-offset.sh  | 2 +-
 5 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 51de8882d0..528a80b6a6 100644
--- a/Makefile
+++ b/Makefile
@@ -680,6 +680,7 @@ TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
 TEST_BUILTINS_OBJS += test-sha1-array.o
 TEST_BUILTINS_OBJS += test-sha1.o
 TEST_BUILTINS_OBJS += test-sigchain.o
+TEST_BUILTINS_OBJS += test-strcmp-offset.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
@@ -687,7 +688,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-strcmp-offset
 TEST_PROGRAMS_NEED_X += test-string-list
 TEST_PROGRAMS_NEED_X += test-submodule-config
 TEST_PROGRAMS_NEED_X += test-subprocess
diff --git a/t/helper/test-strcmp-offset.c b/t/helper/test-strcmp-offset.c
index e159c9a127..3f80833542 100644
--- a/t/helper/test-strcmp-offset.c
+++ b/t/helper/test-strcmp-offset.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int test_strcmp_offset(int argc, const char **argv)
 {
int result;
size_t offset;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 99db507a24..7e684960e0 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -35,6 +35,7 @@ static struct test_cmd cmds[] = {
{ "sha1-array", test_sha1_array },
{ "sha1", test_sha1 },
{ "sigchain", test_sigchain },
+   { "strcmp-offset", test_strcmp_offset },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 4c71df8c79..42ebb67af6 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -29,5 +29,6 @@ int test_scrap_cache_tree(int argc, const char **argv);
 int test_sha1_array(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 int test_sigchain(int argc, const char **argv);
+int test_strcmp_offset(int argc, const char **argv);
 
 #endif
diff --git a/t/t0065-strcmp-offset.sh b/t/t0065-strcmp-offset.sh
index 7d6d21425f..91fa639c4a 100755
--- a/t/t0065-strcmp-offset.sh
+++ b/t/t0065-strcmp-offset.sh
@@ -8,7 +8,7 @@ while read s1 s2 expect
 do
test_expect_success "strcmp_offset($s1, $s2)" '
echo "$expect" >expect &&
-   test-strcmp-offset "$s1" "$s2" >actual &&
+   test-tool strcmp-offset "$s1" "$s2" >actual &&
test_cmp expect actual
'
 done <<-EOF
-- 
2.16.2.903.gd04caf5039



[PATCH 34/36] t/helper: merge test-urlmatch-.. into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   |   2 +-
 t/helper/test-tool.c   |   1 +
 t/helper/test-tool.h   |   1 +
 t/helper/test-urlmatch-normalization.c |   5 +-
 t/t0110-urlmatch-normalization.sh  | 266 -
 5 files changed, 139 insertions(+), 136 deletions(-)

diff --git a/Makefile b/Makefile
index 893ea64ca2..7923ec3747 100644
--- a/Makefile
+++ b/Makefile
@@ -684,6 +684,7 @@ TEST_BUILTINS_OBJS += test-strcmp-offset.o
 TEST_BUILTINS_OBJS += test-string-list.o
 TEST_BUILTINS_OBJS += test-submodule-config.o
 TEST_BUILTINS_OBJS += test-subprocess.o
+TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
@@ -693,7 +694,6 @@ TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
 TEST_PROGRAMS_NEED_X += test-svn-fe
 TEST_PROGRAMS_NEED_X += test-tool
-TEST_PROGRAMS_NEED_X += test-urlmatch-normalization
 TEST_PROGRAMS_NEED_X += test-wildmatch
 
 TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X))
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 49f4d6f901..f2d60af898 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -39,6 +39,7 @@ static struct test_cmd cmds[] = {
{ "string-list", test_string_list },
{ "submodule-config", test_submodule_config },
{ "subprocess", test_subprocess },
+   { "urlmatch-normalization", test_urlmatch_normalization },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index eaf15cbd84..704ac9df35 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -33,5 +33,6 @@ int test_strcmp_offset(int argc, const char **argv);
 int test_string_list(int argc, const char **argv);
 int test_submodule_config(int argc, const char **argv);
 int test_subprocess(int argc, const char **argv);
+int test_urlmatch_normalization(int argc, const char **argv);
 
 #endif
diff --git a/t/helper/test-urlmatch-normalization.c 
b/t/helper/test-urlmatch-normalization.c
index 49b6e836be..8edd4da7e1 100644
--- a/t/helper/test-urlmatch-normalization.c
+++ b/t/helper/test-urlmatch-normalization.c
@@ -1,9 +1,10 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "urlmatch.h"
 
-int cmd_main(int argc, const char **argv)
+int test_urlmatch_normalization(int argc, const char **argv)
 {
-   const char usage[] = "test-urlmatch-normalization [-p | -l]  | 
 ";
+   const char usage[] = "test-tool urlmatch-normalization [-p | -l]  
|  ";
char *url1, *url2;
int opt_p = 0, opt_l = 0;
 
diff --git a/t/t0110-urlmatch-normalization.sh 
b/t/t0110-urlmatch-normalization.sh
index 410d5768ca..f99529d838 100755
--- a/t/t0110-urlmatch-normalization.sh
+++ b/t/t0110-urlmatch-normalization.sh
@@ -9,172 +9,172 @@ tu="$TEST_DIRECTORY/t0110/url"
 # Note that only file: URLs should be allowed without a host
 
 test_expect_success 'url scheme' '
-   ! test-urlmatch-normalization "" &&
-   ! test-urlmatch-normalization "_" &&
-   ! test-urlmatch-normalization "scheme" &&
-   ! test-urlmatch-normalization "scheme:" &&
-   ! test-urlmatch-normalization "scheme:/" &&
-   ! test-urlmatch-normalization "scheme://" &&
-   ! test-urlmatch-normalization "file" &&
-   ! test-urlmatch-normalization "file:" &&
-   ! test-urlmatch-normalization "file:/" &&
-   test-urlmatch-normalization "file://" &&
-   ! test-urlmatch-normalization "://acme.co" &&
-   ! test-urlmatch-normalization "x_test://acme.co" &&
-   ! test-urlmatch-normalization "-test://acme.co" &&
-   ! test-urlmatch-normalization "0test://acme.co" &&
-   ! test-urlmatch-normalization "+test://acme.co" &&
-   ! test-urlmatch-normalization ".test://acme.co" &&
-   ! test-urlmatch-normalization "schem%6e://" &&
-   test-urlmatch-normalization "x-Test+v1.0://acme.co" &&
-   test "$(test-urlmatch-normalization -p "AbCdeF://x.Y")" = 
"abcdef://x.y/"
+   ! test-tool urlmatch-normalization "" &&
+   ! test-tool urlmatch-normalization "_" &&
+   ! test-tool urlmatch-normalization "scheme" &&
+   ! test-tool urlmatch-normalization "scheme:" &&
+   ! test-tool urlmatch-normalization "scheme:/" &&
+   ! test-tool urlmatch-normalization "scheme://" &&
+   ! test-tool urlmatch-normalization "file" &&
+   ! test-tool urlmatch-normalization "file:" &&
+   ! test-tool urlmatch-normalization "file:/" &&
+   test-tool urlmatch-normalization "file://" &&
+   ! test-tool urlmatch-normalization "://acme.co" &&
+   ! test-tool urlmatch-normalization "x_test://acme.co" &&
+   ! test-tool urlmatch-normalization "-test://acme.co" &&
+   ! test-tool urlmatch-normalization "0test://acme.co" &&
+   ! test-tool urlmatch-normalization "+test://acme.co" &&
+   ! test-tool 

[PATCH 27/36] t/helper: merge test-scrap-cache-tree into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile | 2 +-
 t/helper/test-scrap-cache-tree.c | 3 ++-
 t/helper/test-tool.c | 1 +
 t/helper/test-tool.h | 1 +
 t/t0090-cache-tree.sh| 8 
 5 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index adece67b8e..ba7c7d8a79 100644
--- a/Makefile
+++ b/Makefile
@@ -676,6 +676,7 @@ TEST_BUILTINS_OBJS += test-ref-store.o
 TEST_BUILTINS_OBJS += test-regex.o
 TEST_BUILTINS_OBJS += test-revision-walking.o
 TEST_BUILTINS_OBJS += test-run-command.o
+TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
@@ -684,7 +685,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
 TEST_PROGRAMS_NEED_X += test-sha1-array
 TEST_PROGRAMS_NEED_X += test-sigchain
 TEST_PROGRAMS_NEED_X += test-strcmp-offset
diff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c
index d2a63bea43..e1246602a7 100644
--- a/t/helper/test-scrap-cache-tree.c
+++ b/t/helper/test-scrap-cache-tree.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "lockfile.h"
 #include "tree.h"
@@ -5,7 +6,7 @@
 
 static struct lock_file index_lock;
 
-int cmd_main(int ac, const char **av)
+int test_scrap_cache_tree(int ac, const char **av)
 {
setup_git_directory();
hold_locked_index(_lock, LOCK_DIE_ON_ERROR);
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index a8a92b6a10..f12f1ec5bb 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -31,6 +31,7 @@ static struct test_cmd cmds[] = {
{ "regex", test_regex },
{ "revision-walking", test_revision_walking },
{ "run-command", test_run_command },
+   { "scrap-cache-tree", test_scrap_cache_tree },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 23f63ee357..92504e951f 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -25,6 +25,7 @@ int test_ref_store(int argc, const char **argv);
 int test_regex(int argc, const char **argv);
 int test_revision_walking(int argc, const char **argv);
 int test_run_command(int argc, const char **argv);
+int test_scrap_cache_tree(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh
index 3266209e41..4ae0995cd9 100755
--- a/t/t0090-cache-tree.sh
+++ b/t/t0090-cache-tree.sh
@@ -115,14 +115,14 @@ test_expect_success 'update-index invalidates cache-tree' 
'
 '
 
 test_expect_success 'write-tree establishes cache-tree' '
-   test-scrap-cache-tree &&
+   test-tool scrap-cache-tree &&
git write-tree &&
test_cache_tree
 '
 
-test_expect_success 'test-scrap-cache-tree works' '
+test_expect_success 'test-tool scrap-cache-tree works' '
git read-tree HEAD &&
-   test-scrap-cache-tree &&
+   test-tool scrap-cache-tree &&
test_no_cache_tree
 '
 
@@ -170,7 +170,7 @@ test_expect_success 'commit in child dir has cache-tree' '
 '
 
 test_expect_success 'reset --hard gives cache-tree' '
-   test-scrap-cache-tree &&
+   test-tool scrap-cache-tree &&
git reset --hard &&
test_cache_tree
 '
-- 
2.16.2.903.gd04caf5039



[PATCH 29/36] t/helper: merge test-sigchain into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile | 2 +-
 t/helper/test-sigchain.c | 3 ++-
 t/helper/test-tool.c | 1 +
 t/helper/test-tool.h | 1 +
 t/t0005-signals.sh   | 4 ++--
 5 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index b50a0818a9..51de8882d0 100644
--- a/Makefile
+++ b/Makefile
@@ -679,6 +679,7 @@ TEST_BUILTINS_OBJS += test-run-command.o
 TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
 TEST_BUILTINS_OBJS += test-sha1-array.o
 TEST_BUILTINS_OBJS += test-sha1.o
+TEST_BUILTINS_OBJS += test-sigchain.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
@@ -686,7 +687,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-sigchain
 TEST_PROGRAMS_NEED_X += test-strcmp-offset
 TEST_PROGRAMS_NEED_X += test-string-list
 TEST_PROGRAMS_NEED_X += test-submodule-config
diff --git a/t/helper/test-sigchain.c b/t/helper/test-sigchain.c
index b71edbd442..0cfbf9e0af 100644
--- a/t/helper/test-sigchain.c
+++ b/t/helper/test-sigchain.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "sigchain.h"
 
@@ -13,7 +14,7 @@ X(two)
 X(three)
 #undef X
 
-int cmd_main(int argc, const char **argv) {
+int test_sigchain(int argc, const char **argv) {
sigchain_push(SIGTERM, one);
sigchain_push(SIGTERM, two);
sigchain_push(SIGTERM, three);
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 54d62b8b32..99db507a24 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -34,6 +34,7 @@ static struct test_cmd cmds[] = {
{ "scrap-cache-tree", test_scrap_cache_tree },
{ "sha1-array", test_sha1_array },
{ "sha1", test_sha1 },
+   { "sigchain", test_sigchain },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 10d1322e0d..4c71df8c79 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -28,5 +28,6 @@ int test_run_command(int argc, const char **argv);
 int test_scrap_cache_tree(int argc, const char **argv);
 int test_sha1_array(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
+int test_sigchain(int argc, const char **argv);
 
 #endif
diff --git a/t/t0005-signals.sh b/t/t0005-signals.sh
index c16947cf5d..4c214bd11c 100755
--- a/t/t0005-signals.sh
+++ b/t/t0005-signals.sh
@@ -10,7 +10,7 @@ one
 EOF
 
 test_expect_success 'sigchain works' '
-   { test-sigchain >actual; ret=$?; } &&
+   { test-tool sigchain >actual; ret=$?; } &&
{
# Signal death by raise() on Windows acts like exit(3),
# regardless of the signal number. So we must allow that
@@ -24,7 +24,7 @@ test_expect_success 'sigchain works' '
 test_expect_success !MINGW 'signals are propagated using shell convention' '
# we use exec here to avoid any sub-shell interpretation
# of the exit code
-   git config alias.sigterm "!exec test-sigchain" &&
+   git config alias.sigterm "!exec test-tool sigchain" &&
test_expect_code 143 git sigterm
 '
 
-- 
2.16.2.903.gd04caf5039



[PATCH 36/36] t/helper: merge test-write-cache into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile| 2 +-
 t/helper/test-tool.c| 1 +
 t/helper/test-tool.h| 1 +
 t/helper/test-write-cache.c | 3 ++-
 t/perf/p0007-write-cache.sh | 2 +-
 5 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 2ab76c6838..8ad9a2a1a9 100644
--- a/Makefile
+++ b/Makefile
@@ -686,13 +686,13 @@ TEST_BUILTINS_OBJS += test-submodule-config.o
 TEST_BUILTINS_OBJS += test-subprocess.o
 TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
 TEST_BUILTINS_OBJS += test-wildmatch.o
+TEST_BUILTINS_OBJS += test-write-cache.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
-TEST_PROGRAMS_NEED_X += test-write-cache
 TEST_PROGRAMS_NEED_X += test-svn-fe
 TEST_PROGRAMS_NEED_X += test-tool
 
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index ebf28859b4..e4c04cd593 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -41,6 +41,7 @@ static struct test_cmd cmds[] = {
{ "subprocess", test_subprocess },
{ "urlmatch-normalization", test_urlmatch_normalization },
{ "wildmatch", test_wildmatch },
+   { "write-cache", test_write_cache },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index b7c8272689..c0c2d1d18c 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -35,5 +35,6 @@ int test_submodule_config(int argc, const char **argv);
 int test_subprocess(int argc, const char **argv);
 int test_urlmatch_normalization(int argc, const char **argv);
 int test_wildmatch(int argc, const char **argv);
+int test_write_cache(int argc, const char **argv);
 
 #endif
diff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c
index b7ee039669..69de7f95aa 100644
--- a/t/helper/test-write-cache.c
+++ b/t/helper/test-write-cache.c
@@ -1,9 +1,10 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "lockfile.h"
 
 static struct lock_file index_lock;
 
-int cmd_main(int argc, const char **argv)
+int test_write_cache(int argc, const char **argv)
 {
int i, cnt = 1, lockfd;
if (argc == 2)
diff --git a/t/perf/p0007-write-cache.sh b/t/perf/p0007-write-cache.sh
index 261fe92fd9..09595264f0 100755
--- a/t/perf/p0007-write-cache.sh
+++ b/t/perf/p0007-write-cache.sh
@@ -23,7 +23,7 @@ test_expect_success "setup repo" '
 
 count=3
 test_perf "write_locked_index $count times ($nr_files files)" "
-   test-write-cache $count
+   test-tool write-cache $count
 "
 
 test_done
-- 
2.16.2.903.gd04caf5039



[PATCH 32/36] t/helper: merge test-submodule-config into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile |  2 +-
 t/helper/test-submodule-config.c |  3 ++-
 t/helper/test-tool.c |  1 +
 t/helper/test-tool.h |  1 +
 t/t7411-submodule-config.sh  | 18 +-
 5 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/Makefile b/Makefile
index 6819792c2b..c1dc9ff8d6 100644
--- a/Makefile
+++ b/Makefile
@@ -682,6 +682,7 @@ TEST_BUILTINS_OBJS += test-sha1.o
 TEST_BUILTINS_OBJS += test-sigchain.o
 TEST_BUILTINS_OBJS += test-strcmp-offset.o
 TEST_BUILTINS_OBJS += test-string-list.o
+TEST_BUILTINS_OBJS += test-submodule-config.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
@@ -689,7 +690,6 @@ TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-submodule-config
 TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
 TEST_PROGRAMS_NEED_X += test-tool
diff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c
index f23db3b19a..63c4b90e37 100644
--- a/t/helper/test-submodule-config.c
+++ b/t/helper/test-submodule-config.c
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "config.h"
 #include "submodule-config.h"
@@ -10,7 +11,7 @@ static void die_usage(int argc, const char **argv, const char 
*msg)
exit(1);
 }
 
-int cmd_main(int argc, const char **argv)
+int test_submodule_config(int argc, const char **argv)
 {
const char **arg = argv;
int my_argc = argc;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 2e428825d5..1b95f1b30b 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -37,6 +37,7 @@ static struct test_cmd cmds[] = {
{ "sigchain", test_sigchain },
{ "strcmp-offset", test_strcmp_offset },
{ "string-list", test_string_list },
+   { "submodule-config", test_submodule_config },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 943d92452a..16a05993e5 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -31,5 +31,6 @@ int test_sha1(int argc, const char **argv);
 int test_sigchain(int argc, const char **argv);
 int test_strcmp_offset(int argc, const char **argv);
 int test_string_list(int argc, const char **argv);
+int test_submodule_config(int argc, const char **argv);
 
 #endif
diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh
index 46c09c7765..0bde5850ac 100755
--- a/t/t7411-submodule-config.sh
+++ b/t/t7411-submodule-config.sh
@@ -41,7 +41,7 @@ test_expect_success 'configuration parsing with error' '
EOF
(
cd repo &&
-   test_must_fail test-submodule-config "" s 2>actual &&
+   test_must_fail test-tool submodule-config "" s 2>actual &&
test_i18ngrep "bad config" actual
)
 '
@@ -55,7 +55,7 @@ EOF
 
 test_expect_success 'test parsing and lookup of submodule config by path' '
(cd super &&
-   test-submodule-config \
+   test-tool submodule-config \
HEAD^ a \
HEAD b \
HEAD^ submodule \
@@ -67,7 +67,7 @@ test_expect_success 'test parsing and lookup of submodule 
config by path' '
 
 test_expect_success 'test parsing and lookup of submodule config by name' '
(cd super &&
-   test-submodule-config --name \
+   test-tool submodule-config --name \
HEAD^ a \
HEAD a \
HEAD^ submodule \
@@ -89,7 +89,7 @@ test_expect_success 'error in one submodule config lets 
continue' '
git add .gitmodules &&
mv .gitmodules.bak .gitmodules &&
git commit -m "add error" &&
-   test-submodule-config \
+   test-tool submodule-config \
HEAD b \
HEAD submodule \
>actual &&
@@ -100,7 +100,7 @@ test_expect_success 'error in one submodule config lets 
continue' '
 test_expect_success 'error message contains blob reference' '
(cd super &&
sha1=$(git rev-parse HEAD) &&
-   test-submodule-config \
+   test-tool submodule-config \
HEAD b \
HEAD submodule \
2>actual_err &&
@@ -114,9 +114,9 @@ test_expect_success 'using different treeishs works' '
git tag new_tag &&
tree=$(git rev-parse HEAD^{tree}) &&
commit=$(git rev-parse HEAD^{commit}) &&
-   test-submodule-config $commit b >expect &&
-   test-submodule-config $tree b >actual.1 &&
-   

[PATCH 18/36] t/helper: merge test-mktemp into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Makefile   | 2 +-
 t/helper/test-mktemp.c | 3 ++-
 t/helper/test-tool.c   | 1 +
 t/helper/test-tool.h   | 1 +
 t/t0070-fundamental.sh | 4 ++--
 5 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 67f37b849e..3145a9b1b2 100644
--- a/Makefile
+++ b/Makefile
@@ -667,13 +667,13 @@ TEST_BUILTINS_OBJS += test-index-version.o
 TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
 TEST_BUILTINS_OBJS += test-match-trees.o
 TEST_BUILTINS_OBJS += test-mergesort.o
+TEST_BUILTINS_OBJS += test-mktemp.o
 TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 TEST_PROGRAMS_NEED_X += test-fake-ssh
 TEST_PROGRAMS_NEED_X += test-line-buffer
-TEST_PROGRAMS_NEED_X += test-mktemp
 TEST_PROGRAMS_NEED_X += test-online-cpus
 TEST_PROGRAMS_NEED_X += test-parse-options
 TEST_PROGRAMS_NEED_X += test-path-utils
diff --git a/t/helper/test-mktemp.c b/t/helper/test-mktemp.c
index 89d9b2f7be..afc9dee91d 100644
--- a/t/helper/test-mktemp.c
+++ b/t/helper/test-mktemp.c
@@ -1,9 +1,10 @@
 /*
  * test-mktemp.c: code to exercise the creation of temporary files
  */
+#include "test-tool.h"
 #include "git-compat-util.h"
 
-int cmd_main(int argc, const char **argv)
+int test_mktemp(int argc, const char **argv)
 {
if (argc != 2)
usage("Expected 1 parameter defining the temporary file 
template");
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 4206d96304..4a563e08c3 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -22,6 +22,7 @@ static struct test_cmd cmds[] = {
{ "lazy-init-name-hash", test_lazy_init_name_hash },
{ "match-trees", test_match_trees },
{ "mergesort", test_mergesort },
+   { "mktemp", test_mktemp },
{ "sha1", test_sha1 },
 };
 
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index dff1b804cb..5bbe3e96cf 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -16,6 +16,7 @@ int test_index_version(int argc, const char **argv);
 int test_lazy_init_name_hash(int argc, const char **argv);
 int test_match_trees(int argc, const char **argv);
 int test_mergesort(int argc, const char **argv);
+int test_mktemp(int argc, const char **argv);
 int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
index 70d4d98a2e..ac007938ee 100755
--- a/t/t0070-fundamental.sh
+++ b/t/t0070-fundamental.sh
@@ -13,7 +13,7 @@ test_expect_success 'character classes (isspace, isalpha 
etc.)' '
 '
 
 test_expect_success 'mktemp to nonexistent directory prints filename' '
-   test_must_fail test-mktemp doesnotexist/testXX 2>err &&
+   test_must_fail test-tool mktemp doesnotexist/testXX 2>err &&
grep "doesnotexist/test" err
 '
 
@@ -21,7 +21,7 @@ test_expect_success POSIXPERM,SANITY 'mktemp to unwritable 
directory prints file
mkdir cannotwrite &&
chmod -w cannotwrite &&
test_when_finished "chmod +w cannotwrite" &&
-   test_must_fail test-mktemp cannotwrite/testXX 2>err &&
+   test_must_fail test-tool mktemp cannotwrite/testXX 2>err &&
grep "cannotwrite/test" err
 '
 
-- 
2.16.2.903.gd04caf5039



[PATCH 03/36] t/helper: merge test-sha1 into test-tool

2018-03-17 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Documentation/howto/recover-corrupted-object-harder.txt | 2 +-
 Makefile| 4 ++--
 t/helper/test-sha1.c| 3 ++-
 t/helper/test-sha1.sh   | 4 ++--
 t/helper/test-tool.c| 1 +
 t/helper/test-tool.h| 1 +
 t/lib-pack.sh   | 2 +-
 t/t0013-sha1dc.sh   | 2 +-
 8 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/Documentation/howto/recover-corrupted-object-harder.txt 
b/Documentation/howto/recover-corrupted-object-harder.txt
index 9c4cd0915f..8994e2559e 100644
--- a/Documentation/howto/recover-corrupted-object-harder.txt
+++ b/Documentation/howto/recover-corrupted-object-harder.txt
@@ -80,7 +80,7 @@ valid pack like:
 # now add our object data
 cat object >>tmp.pack
 # and then append the pack trailer
-/path/to/git.git/test-sha1 -b trailer
+/path/to/git.git/t/helper/test-tool sha1 -b trailer
 cat trailer >>tmp.pack
 
 
diff --git a/Makefile b/Makefile
index 416a8e39c1..3c0d0474af 100644
--- a/Makefile
+++ b/Makefile
@@ -653,6 +653,7 @@ X =
 PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
 TEST_BUILTINS_OBJS += test-chmtime.o
+TEST_BUILTINS_OBJS += test-sha1.o
 
 TEST_PROGRAMS_NEED_X += test-ctype
 TEST_PROGRAMS_NEED_X += test-config
@@ -684,7 +685,6 @@ TEST_PROGRAMS_NEED_X += test-regex
 TEST_PROGRAMS_NEED_X += test-revision-walking
 TEST_PROGRAMS_NEED_X += test-run-command
 TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
-TEST_PROGRAMS_NEED_X += test-sha1
 TEST_PROGRAMS_NEED_X += test-sha1-array
 TEST_PROGRAMS_NEED_X += test-sigchain
 TEST_PROGRAMS_NEED_X += test-strcmp-offset
@@ -2502,7 +2502,7 @@ t/helper/test-tool$X: $(patsubst 
%,t/helper/%,$(TEST_BUILTINS_OBJS))
 t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) 
$(filter %.a,$^) $(LIBS)
 
-check-sha1:: t/helper/test-sha1$X
+check-sha1:: t/helper/test-tool$X
t/helper/test-sha1.sh
 
 SP_OBJ = $(patsubst %.o,%.sp,$(C_OBJ))
diff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c
index a1c13f54ec..afee24e027 100644
--- a/t/helper/test-sha1.c
+++ b/t/helper/test-sha1.c
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int ac, const char **av)
+int test_sha1(int ac, const char **av)
 {
git_SHA_CTX ctx;
unsigned char sha1[20];
diff --git a/t/helper/test-sha1.sh b/t/helper/test-sha1.sh
index 750b95a0a1..84594885c7 100755
--- a/t/helper/test-sha1.sh
+++ b/t/helper/test-sha1.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 dd if=/dev/zero bs=1048576 count=100 2>/dev/null |
-/usr/bin/time t/helper/test-sha1 >/dev/null
+/usr/bin/time t/helper/test-tool sha1 >/dev/null
 
 while read expect cnt pfx
 do
@@ -11,7 +11,7 @@ do
test -z "$pfx" || echo "$pfx"
dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null |
perl -pe 'y/\000/g/'
-   } | ./t/helper/test-sha1 $cnt
+   } | ./t/helper/test-tool sha1 $cnt
)
if test "$expect" = "$actual"
then
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index c22f300f5e..ca1f462cce 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -8,6 +8,7 @@ struct test_cmd {
 
 static struct test_cmd cmds[] = {
{ "chmtime", test_chmtime },
+   { "sha1", test_sha1 },
 };
 
 int cmd_main(int argc, const char **argv)
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 61ca4a7055..e7a2a7cb5b 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -2,5 +2,6 @@
 #define __TEST_TOOL_H__
 
 int test_chmtime(int argc, const char **argv);
+int test_sha1(int argc, const char **argv);
 
 #endif
diff --git a/t/lib-pack.sh b/t/lib-pack.sh
index 7509846571..501078249d 100644
--- a/t/lib-pack.sh
+++ b/t/lib-pack.sh
@@ -85,7 +85,7 @@ pack_obj () {
 
 # Compute and append pack trailer to "$1"
 pack_trailer () {
-   test-sha1 -b <"$1" >trailer.tmp &&
+   test-tool sha1 -b <"$1" >trailer.tmp &&
cat trailer.tmp >>"$1" &&
rm -f trailer.tmp
 }
diff --git a/t/t0013-sha1dc.sh b/t/t0013-sha1dc.sh
index 6d655cb161..419f31a8f7 100755
--- a/t/t0013-sha1dc.sh
+++ b/t/t0013-sha1dc.sh
@@ -11,7 +11,7 @@ then
 fi
 
 test_expect_success 'test-sha1 detects shattered pdf' '
-   test_must_fail test-sha1 <"$TEST_DATA/shattered-1.pdf" 2>err &&
+   test_must_fail test-tool sha1 <"$TEST_DATA/shattered-1.pdf" 2>err &&
test_i18ngrep collision err &&
grep 38762cf7f55934b34d179ae6a4c80cadccbb7f0a err
 '
-- 
2.16.2.903.gd04caf5039



  1   2   >