* [RFC/PATCH 1/3] remote: use a local variable in match_push_refs()
From: Felipe Contreras @ 2012-02-17 19:12 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Jeff King, Felipe Contreras
In-Reply-To: <1329505957-24595-1-git-send-email-felipe.contreras@gmail.com>
So that we can reuse src later on.
Will be useful in next patches.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
remote.c | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/remote.c b/remote.c
index 73a3809..55d68d1 100644
--- a/remote.c
+++ b/remote.c
@@ -1157,7 +1157,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
int send_mirror = flags & MATCH_REFS_MIRROR;
int errs;
static const char *default_refspec[] = { ":", NULL };
- struct ref **dst_tail = tail_ref(dst);
+ struct ref *ref, **dst_tail = tail_ref(dst);
if (!nr_refspec) {
nr_refspec = 1;
@@ -1167,14 +1167,14 @@ int match_push_refs(struct ref *src, struct ref **dst,
errs = match_explicit_refs(src, *dst, &dst_tail, rs, nr_refspec);
/* pick the remainder */
- for ( ; src; src = src->next) {
+ for (ref = src; ref; ref = ref->next) {
struct ref *dst_peer;
const struct refspec *pat = NULL;
char *dst_name;
- if (src->peer_ref)
+ if (ref->peer_ref)
continue;
- pat = check_pattern_match(rs, nr_refspec, src);
+ pat = check_pattern_match(rs, nr_refspec, ref);
if (!pat)
continue;
@@ -1184,13 +1184,14 @@ int match_push_refs(struct ref *src, struct ref **dst,
* including refs outside refs/heads/ hierarchy, but
* that does not make much sense these days.
*/
- if (!send_mirror && prefixcmp(src->name, "refs/heads/"))
+ if (!send_mirror && prefixcmp(ref->name, "refs/heads/"))
continue;
- dst_name = xstrdup(src->name);
+ dst_name = xstrdup(ref->name);
+
} else {
const char *dst_side = pat->dst ? pat->dst : pat->src;
- if (!match_name_with_pattern(pat->src, src->name,
+ if (!match_name_with_pattern(pat->src, ref->name,
dst_side, &dst_name))
die("Didn't think it matches any more");
}
@@ -1211,9 +1212,9 @@ int match_push_refs(struct ref *src, struct ref **dst,
/* Create a new one and link it */
dst_peer = make_linked_ref(dst_name, &dst_tail);
- hashcpy(dst_peer->new_sha1, src->new_sha1);
+ hashcpy(dst_peer->new_sha1, ref->new_sha1);
}
- dst_peer->peer_ref = copy_ref(src);
+ dst_peer->peer_ref = copy_ref(ref);
dst_peer->force = pat->force;
free_name:
free(dst_name);
--
1.7.9.1
^ permalink raw reply related
* [RFC/PATCH 0/3] push: add 'prune' option
From: Felipe Contreras @ 2012-02-17 19:12 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Jeff King, Felipe Contreras
Hi,
As mentioned in a previous thread[1], git is lacking some functionality to
synchronize completely with remote repositories.
As an example I put my use-case; I want to backup *all* my local branches to a
personal repository, and I want to remove branches that I have removed from my
local repository. git push personal 'refs/heads/*' mostly does the job, but it
doesn't remove anything, and that's where 'prune' comes from.
Do not confuse the remote branches with the upstream ones; you could have two
repositories where you want to synchronize branches to:
% git push --prune --force backup1 'refs/heads/*'
% git push --prune --force backup2 'refs/heads/*'
I still think a 'git remote sync' would be tremendously useful, but it can
actually use this --prune option.
I know, documentation and testing are missing, but perhaps there will be
comments on the code itself.
Cheers.
[1] http://article.gmane.org/gmane.comp.version-control.git/184990
Felipe Contreras (3):
remote: use a local variable in match_push_refs()
remote: reorganize check_pattern_match()
push: add 'prune' option
builtin/push.c | 2 +
remote.c | 91 +++++++++++++++++++++++++++++++++++--------------------
remote.h | 3 +-
transport.c | 2 +
transport.h | 1 +
5 files changed, 65 insertions(+), 34 deletions(-)
--
1.7.9.1
^ permalink raw reply
* Re: How to use git attributes to configure server-side checks?
From: Michael Haggerty @ 2012-02-17 18:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git discussion list
In-Reply-To: <7vy5xh1whq.fsf@alter.siamese.dyndns.org>
On 09/21/2011 10:17 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>> I was thinking of using git attributes to configure a server-side
>> "update" hook that does some basic sanity checking before accepting a
>> push. I thought I could do something like
>> [...]
>> I see that there is an (undocumented) API involving
>> git_attr_set_direction() that seems to let gitattributes to be read out
>> of the index instead of the working tree. But I am still confused:
>
> The words "server side" automatically mean that there should be no working
> tree, and where there is no working tree there should be no index, so the
> direction should not make any difference. The attributes that are used to
> help whitespace checks should come from project.git/info/attributes in
> such a case [*...*].
I was just alerted by Scott Chacon's blog [1] to the fact that one can
set GIT_INDEX_FILE to an arbitrary filename, thereby causing the index
to be read/written from that file instead of $GIT_DIR/index. It
occurred to me that this feature, along with the addition of "git
check-attr --cached" in 1.7.8, can be used to give server-side access to
the gitattributes for an arbitrary commit:
GIT_INDEX_FILE="$(tempfile)"
export GIT_INDEX_FILE
git read-tree $COMMIT
git check-attr --cached attr -- pathname
...
rm "$GIT_INDEX_FILE"
Empirically it seems to work (and it is surprisingly fast). The use of
a temporary file prevents simultaneous accesses to the repository from
stepping on each other. This looks like a clean solution to my problem.
Or is there some hidden pitfall in this approach?
Michael
[1] http://progit.org/2010/04/11/environment.html
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Re: [PATCH] git-latexdiff: new command in contrib, to use latexdiff and Git
From: Jakub Narebski @ 2012-02-17 18:40 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Matthieu Moy, Tim Haga, git
In-Reply-To: <7vwr7ltlrj.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Aren't there LaTeX tools archives that would be a much better home for
> this tool?
There is CTAN: Comprehensive TeX Archive Network (http://ctan.org),
which hosts tools such like latexmk (cousin of the general make
utility), autolatex (generates Makefile), chktex, ite (interactive TeX
editor),... latexdiff itself is also there.
--
Jakub Narebski
^ permalink raw reply
* [PATCH] refresh_index: do not show unmerged path that is outside pathspec
From: Junio C Hamano @ 2012-02-17 18:27 UTC (permalink / raw)
To: git
When running "git add --refresh <pathspec>", we incorrectly showed the
path that is unmerged even if it is outside the specified pathspec, even
though we did honor pathspec and refreshed only the paths that matched.
Note that this cange does not affect "git update-index --refresh"; for
hysterical raisins, it does not take a pathspec (it takes real paths) and
more importantly itss command line options are parsed and executed one by
one as they are encountered, so "git update-index --refresh foo" means
"first refresh the index, and then update the entry 'foo' by hashing the
contents in file 'foo'", not "refresh only entry 'foo'".
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* I wondered if the "has_errors" that the caller can use to detect if
there are not-yet-added paths should be covered by the if (!filtered)
test as well. No caller that passes pathpec seems to use the return
value, so we probably should for the sake of consistency, but I didn't.
read-cache.c | 11 +++++++++--
t/t3700-add.sh | 15 +++++++++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index a51bba1..274e54b 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1120,11 +1120,16 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
struct cache_entry *ce, *new;
int cache_errno = 0;
int changed = 0;
+ int filtered = 0;
ce = istate->cache[i];
if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
continue;
+ if (pathspec &&
+ !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
+ filtered = 1;
+
if (ce_stage(ce)) {
while ((i < istate->cache_nr) &&
! strcmp(istate->cache[i]->name, ce->name))
@@ -1132,12 +1137,14 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
i--;
if (allow_unmerged)
continue;
- show_file(unmerged_fmt, ce->name, in_porcelain, &first, header_msg);
+ if (!filtered)
+ show_file(unmerged_fmt, ce->name, in_porcelain,
+ &first, header_msg);
has_errors = 1;
continue;
}
- if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
+ if (filtered)
continue;
new = refresh_cache_ent(istate, ce, options, &cache_errno, &changed);
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 575d950..874b3a6 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -179,6 +179,21 @@ test_expect_success 'git add --refresh' '
test -z "`git diff-index HEAD -- foo`"
'
+test_expect_success 'git add --refresh with pathspec' '
+ git reset --hard &&
+ echo >foo && echo >bar && echo >baz &&
+ git add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo &&
+ echo "100644 $H 3 foo" | git update-index --index-info &&
+ test-chmtime -60 bar baz &&
+ >expect &&
+ git add --refresh bar >actual &&
+ test_cmp expect actual &&
+
+ git diff-files --name-only >actual &&
+ ! grep bar actual&&
+ grep baz actual
+'
+
test_expect_success POSIXPERM,SANITY 'git add should fail atomically upon an unreadable file' '
git reset --hard &&
date >foo1 &&
--
1.7.9.1.265.g25f75
^ permalink raw reply related
* Re: [PATCH] git-latexdiff: new command in contrib, to use latexdiff and Git
From: Junio C Hamano @ 2012-02-17 17:25 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Tim Haga, git
In-Reply-To: <vpqobsx7d9s.fsf@bauges.imag.fr>
Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
>> Look at what we have in the contrib/ area. I think what is common among
>> them is that their primary benefit is to enrich user's Git experience.
>
> ... and many of them is to enrich the user experience using Git with
> another tool (shell, text editor, foreign VCS).
... where the amount of the benefit they get does not change regardless of
the payload. That is what makes them tool in Git users' toolbox, not
shell scripters' or p4 users' toolbox.
> Git's _core_ already has some code to show diff hunks for various
> languages,...
I would have to say that it is an oranges vs squirrels comparison. I do
not see a justification to reject an addition of an entry to an array that
adds a few strings of regexp to drive the mechanism that is already in
core, when it gets compiled in, and it is useless by itself outside Git.
Unless the language is something obscure, that is.
Read git-latexdiff that is a free-standing 200+ line script again
yourself. The use of Git in the script is not more than how you would
emulate what you would use "cp -r" in order to populate the old/ and new/
directories if the two versions were stored in the file system outside
Git. If you rip the part that deals with "the two versions happen to be
stored in Git" out, the remainder deals with parsing the command line,
interfacing with latex and reporting the result, none of which is in any
way Git specific. That is much larger part of the script, which I view as
a clear sign that it is an application to serve the need for LaTeX users
better, which happens to be written for the subset of LaTeX users who have
their contents in Git.
Aren't there LaTeX tools archives that would be a much better home for
this tool?
^ permalink raw reply
* Re: git status: small difference between stating whole repository and small subdirectory
From: Piotr Krukowiecki @ 2012-02-17 17:19 UTC (permalink / raw)
To: Jeff King; +Cc: Thomas Rast, Git Mailing List, Nguyen Thai Ngoc Duy
In-Reply-To: <20120216192001.GB4348@sigill.intra.peff.net>
On Thu, Feb 16, 2012 at 8:20 PM, Jeff King <peff@peff.net> wrote:
> On Thu, Feb 16, 2012 at 02:37:47PM +0100, Piotr Krukowiecki wrote:
>
>> >> $ time git status -- .
>> >> real 0m2.503s
>> >> user 0m0.160s
>> >> sys 0m0.096s
>> >>
>> >> $ time git status
>> >> real 0m9.663s
>> >> user 0m0.232s
>> >> sys 0m0.556s
>> >
>> > Did you drop caches here, too?
>>
>> Yes I did - with cache the status takes something like 0.1-0.3s on whole repo.
>
> OK, then that makes sense. It's pretty much just I/O on the filesystem
> and on the object db.
>
> You can break status down a little more to see which is which. Try "git
> update-index --refresh" to see just how expensive the lstat and index
> handling is.
"git update-index --refresh" with dropped cache took
real 0m3.726s
user 0m0.024s
sys 0m0.404s
while "git status" with dropped cache takes
real 0m13.578s
user 0m0.240s
sys 0m0.600s
I'm not sure why it takes more than the 9s reported before - IIRC I
did the previous test in single mode under bare shell and this time
I'm testing under gnome. This or it's the effect of running
update-index :/
Now status on subdir takes 9.5s. But still the
not-much-faster-status-on-subdir rule is true.
> And then try "git diff-index HEAD" for an idea of how expensive it is to
> just read the objects and compare to the index.
The diff-index after dropping cache takes
real 0m14.095s
user 0m0.268s
sys 0m0.564s
>> > Not really. You're showing an I/O problem, and repacking is git's way of
>> > reducing I/O.
>>
>> So if I understand correctly, the reason is because git must compare
>> workspace files with packed objects - and the problem is
>> reading/seeking/searching in the packs?
>
> Mostly reading (we keep a sorted index and access the packfiles via
> mmap, so we only touch the pages we need). But you're also paying to
> lstat() the directory tree, too. And you're paying to load (probably)
> the whole index into memory, although it's relatively compact compared
> to the actual file data.
If the index is the objects/pack/*.idx files than it's 21MB
>> Is there a way to make packs better? I think most operations are on
>> workdir files - so maybe it'd be possible to tell gc/repack/whatever
>> to optimize access to files which I currently have in workdir?
>
> It already does optimize for that case. If you can make it even better,
> I'm sure people would be happy to see the numbers.
If I understand correctly, you only need to compute sha1 on the
workdir files and compare it with sha1 files recorded in index/gitdir.
It seems that to get the sha1 from index/gitdir I need to read the
packfiles? Maybe it'd be possible to cache/index it somehow, for
example in separate and smaller file?
> Mostly I think it is just the case that disk I/O is slow, and the
> operation you're asking for has to do a certain amount of it. What kind
> of disk/filesystem are you pulling off of?
>
> It's not a fuse filesystem by any chance, is it? I have a repo on an
> encfs-mounted filesystem, and the lstat times are absolutely horrific.
No, it's ext4 and the disk Seagate Barracuda 7200.12 500GB, as it
reads on the cover :)
But IMO faster disk won't help with this - times will be smaller, but
you'll still have to read the same data, so the subdir times will be
just 2x faster than whole repo, won't it? So maybe in my case it will
go down to e.g. 2s on subdir, but for someone with larger repository
it will still be 10s...
--
Piotr Krukowiecki
^ permalink raw reply
* Re: [PATCH 0/2] api-config documentation leftovers
From: Junio C Hamano @ 2012-02-17 17:04 UTC (permalink / raw)
To: Jeff King; +Cc: git
In-Reply-To: <20120217081743.GA11389@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> Here they are, on top of what you have in jk/config-include. Squashing
> would involve breaking apart the second one into the "introduce
> git_config_with_options" part and the "and now it learns
> respect_includes" part. So it's probably not worth the effort.
>
> [1/2]: docs/api-config: minor clarifications
> [2/2]: docs/api-config: describe git_config_with_options
Thanks.
^ permalink raw reply
* Re: [PATCH v3 0/3]
From: Junio C Hamano @ 2012-02-17 17:03 UTC (permalink / raw)
To: Thomas Rast; +Cc: git
In-Reply-To: <cover.1329472405.git.trast@student.ethz.ch>
Thomas Rast <trast@student.ethz.ch> writes:
> There were actually more mistakes lurking :-( so I am resending the
> whole series.
Ok, will requeue. The diff you attached to this cover letter looked at
least halfway sane, compared to the previous round ;-), though it is not
exactly clear what goes to lib-test-functions and what goes to lib-test
(for example, you moved test_expect_success to 'test-functions', but it
calls test_ok_ that is in 'test-lib', and test_ok_ is directly used by
test_perf in the new 't/perf/perf-lib.sh'), making it harder for people to
decide where to put their additions to the test infrastructure from now
on. There needs a bit of description in the first patch to guide them.
I seem to be getting intermittent test failures, and every time the
failing tests are different, when these three are queued to 'pu'. I didn't
look for what goes wrong and how.
Thanks.
^ permalink raw reply
* Re: git status: small difference between stating whole repository and small subdirectory
From: Piotr Krukowiecki @ 2012-02-17 16:55 UTC (permalink / raw)
To: Thomas Rast; +Cc: Jeff King, Git Mailing List, Nguyen Thai Ngoc Duy
In-Reply-To: <87d39eswkx.fsf@thomas.inf.ethz.ch>
On Thu, Feb 16, 2012 at 3:05 PM, Thomas Rast <trast@inf.ethz.ch> wrote:
> Piotr Krukowiecki <piotr.krukowiecki@gmail.com> writes:
>
>> On Wed, Feb 15, 2012 at 8:03 PM, Jeff King <peff@peff.net> wrote:
>>> On Wed, Feb 15, 2012 at 09:57:29AM +0100, Piotr Krukowiecki wrote:
>>>>
>>> I notice that you're still I/O bound even after the repack:
>>>
>>>> $ time git status -- .
>>>> real 0m2.503s
>>>> user 0m0.160s
>>>> sys 0m0.096s
>>>>
>>>> $ time git status
>>>> real 0m9.663s
>>>> user 0m0.232s
>>>> sys 0m0.556s
>>>
>>> Did you drop caches here, too?
>>
>> Yes I did - with cache the status takes something like 0.1-0.3s on whole repo.
>
> So umm, I'm not sure that leaves anything to be improved.
But even with caches time on small directory is only half of time on whole repo:
0.15s vs 0.07s
> I looked at some strace dumps, and limiting the status to a subdirectory
> (in my case, '-- t' in git.git) does omit the lstat()s on uninteresting
> parts of the index-listed files, as well as the getdents() (i.e.,
> readdir()) for parts of the tree that are not interesting.
Same in my case.
I've run strace with -c which shows system calls times. As I
understand the results the time used by lstat() is very small. With
dropped caches:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
90.70 0.065108 3 25361 12 lstat
6.78 0.004869 1 6534 getdents
1.94 0.001392 0 6964 3238 open
0.27 0.000194 0 3726 close
> BTW, some other parts of git-status's display may be responsible for the
> amount of data it pulls from disk. In particular, the "Your branch is
> ahead" display requires computing the merge-base between HEAD and
> @{upstream}. If your @{upstream} is way ahead/behind, or points at a
> disjoint chunk of history, this may mean essentially pulling all of the
> involved history from disk. If my memory of pack organization serves
> right, the commit objects involved would essentially be spread across
> the whole pack (corresponding to "time") and thus this operation would
> more or less load the entire pack from disk.
I don't think this is the case - I'm using git-svn and thus have no
upstream in git meaning.
--
Piotr Krukowiecki
^ permalink raw reply
* Re: [PATCH v2] Add a setting to require a filter to be successful
From: Junio C Hamano @ 2012-02-17 15:35 UTC (permalink / raw)
To: Johannes Sixt; +Cc: jehan, gitster, git
In-Reply-To: <4F3DFCD0.6070002@viscovery.net>
Johannes Sixt <j.sixt@viscovery.net> writes:
> Am 2/17/2012 2:19, schrieb jehan@orb.com:
>> @@ -747,13 +753,19 @@ int convert_to_git(const char *path, const char *src, size_t len,
> ...
>> ret |= apply_filter(path, src, len, dst, filter);
>> + if (!ret && required)
>> + die("required filter '%s' failed", ca.drv->name);
>
> Wouldn't it be much more helpful if this were:
>
> die("%s: clean filter '%s' failed", path, ca.drv->name);
>
> Likewise (with s/clean/smudge/) in convert_to_working_tree_internal().
>
>> + ! git checkout -- test.fs
>
> test_must_fail git checkout -- test.fs
>
>> + ! git add test.fc
>
> test_must_fail git add test.fc
>
> -- Hannes
Thanks; I'll just squash these in in-place.
^ permalink raw reply
* git-completion bug for 'git remote show <TAB>'
From: Peng Yu @ 2012-02-17 14:41 UTC (permalink / raw)
To: git
Hi,
I got the following error when I try to complete after 'git remote
show'. Could anybody take a look what is the problem?
~/dvcs_src/cron/media$ git remote show -bash: words_: bad array subscript
-bash: words_: bad array subscript
--
Regards,
Peng
^ permalink raw reply
* Re: [PATCHv2 1/3] gitweb: Deal with HEAD pointing to unborn branch in "heads" view
From: Junio C Hamano @ 2012-02-17 14:28 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, rajesh boyapati
In-Reply-To: <201202171441.35618.jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> writes:
> On Fri, 17 Feb 2012, Junio C Hamano wrote:
>
>> But after trying to write a reroll myself, I have to wonder what would
>> happen if you have two branches pointing at the same commit as the one at
>> HEAD. Why isn't the use of current_head class controlled by comparison
>> between the name of the ref and the output from "symbolic-ref HEAD"?
>
> If there is more than one branch that points to HEAD commit, they all
> will be highlighted.
>
> Using "git symbolic-ref HEAD", or just reading '.git/HEAD' file or symlink
> is on my todo list. This will make gitweb highlight current branch
> correctly even if there is more than one branch that point to the same
> HEAD commit, and make it possible to support "detached HEAD" (which I think
> is not supported at all now).
You should be more honest and admit that showing unrelated branches that
happen to point at the same commit as the current HEAD does (this includes
the case where HEAD is detached) as if they are *ALL* current branch is
*NEITER* working *CORRECTLY* nor *SUPPORT*ing "detached HEAD" at all. It
may not be giving a runtime error, but instead it is showing AN INCORRECT
RESULT.
I'd grant you that this is not a new problem this patch introduces, and it
may not even be a bug you introduced long time ago. The patch gives the
same INCORRECT RESULT as it intended to do before the patch, and removes
one runtime error, so it is not worsening the situation, but that does not
change the fact that the code after the patch is still *WRONG*.
^ permalink raw reply
* [PATCH] Add --with-gcc-warnings configure option
From: Elia Pinto @ 2012-02-17 14:25 UTC (permalink / raw)
To: git; +Cc: jnareb, Elia Pinto
Introduce a new --with-gcc-warnings configure option
using a new autoconf macro that check if the compiler
know the option passed or not in a portable way.
Signed-off-by: Elia Pinto <gitter.spiros@gmail.com>
---
Makefile | 2 +-
config.mak.in | 1 +
configure.ac | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index a0de4e9..21bc8d4 100644
--- a/Makefile
+++ b/Makefile
@@ -310,7 +310,7 @@ endif
CFLAGS = -g -O2 -Wall
LDFLAGS =
-ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS)
+ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS) $(AM_CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip
diff --git a/config.mak.in b/config.mak.in
index b2ba710..5b7dbfd 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -2,6 +2,7 @@
# @configure_input@
CC = @CC@
+AM_CFLAGS = @GIT_CFLAGS@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
diff --git a/configure.ac b/configure.ac
index 24190de..92dc1a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,6 +14,34 @@ echo "# ${config_append}. Generated by configure." > "${config_append}"
## Definitions of macros
+# git_AS_VAR_APPEND(VAR, VALUE)
+# ----------------------------
+# Provide the functionality of AS_VAR_APPEND if Autoconf does not have it.
+m4_ifdef([AS_VAR_APPEND],
+[m4_copy([AS_VAR_APPEND], [git_AS_VAR_APPEND])],
+[m4_define([git_AS_VAR_APPEND],
+[AS_VAR_SET([$1], [AS_VAR_GET([$1])$2])])])
+
+# GIT_CFLAGS_ADD(PARAMETER, [VARIABLE = GIT_CFLAGS])
+# ------------------------------------------------
+# Adds parameter to GIT_CFLAGS if the compiler supports it. For example,
+# GIT_CFLAGS_ADD([-Wall],[GIT_CFLAGS]).
+AC_DEFUN([GIT_CFLAGS_ADD],
+[AS_VAR_PUSHDEF([git_my_cflags], [git_cv_warn_$1])dnl
+AC_CACHE_CHECK([whether compiler handles $1], [git_my_cflags], [
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="${CFLAGS} $1"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
+ [AS_VAR_SET([git_my_cflags], [yes])],
+ [AS_VAR_SET([git_my_cflags], [no])])
+ CFLAGS="$save_CFLAGS"
+])
+AS_VAR_PUSHDEF([git_cflags], m4_if([$2], [], [[GIT_CFLAGS]], [[$2]]))dnl
+AS_VAR_IF([git_my_cflags], [yes], [git_AS_VAR_APPEND([git_cflags], [" $1"])])
+AS_VAR_POPDEF([git_cflags])dnl
+AS_VAR_POPDEF([git_my_cflags])dnl
+m4_ifval([$2], [AS_LITERAL_IF([$2], [AC_SUBST([$2])], [])])dnl
+])
# GIT_CONF_APPEND_LINE(LINE)
# --------------------------
# Append LINE to file ${config_append}
@@ -158,6 +186,96 @@ if test -z "$lib"; then
lib=lib
fi
+# Turn gcc warning
+
+AC_ARG_ENABLE([gcc-warnings],
+ [AS_HELP_STRING([--enable-gcc-warnings],
+ [turn on GCC warnings (for developers)@<:@default=no@:>@])],
+ [case $enableval in
+ yes|no) ;;
+ *) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;;
+ esac
+ git_gcc_warnings=$enableval],
+ [git_gcc_warnings=no]
+)
+
+AS_IF([test "x$git_gcc_warnings" = xyes],
+ [ # Add/Delete as needed
+ MAX_STACK_SIZE=32768
+ GIT_CFLAGS_ADD([-Wall], [GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-pedantic], [GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wextra], [GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wformat-y2k], [GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-fdiagnostics-show-option],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-funit-at-a-time],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-fstrict-aliasing],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wstrict-overflow],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-fstrict-overflow],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wpointer-arith],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wundef],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wformat-security],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Winit-self],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmissing-include-dirs],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wunused],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wunknown-pragmas],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wstrict-aliasing],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wshadow],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wbad-function-cast],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wcast-align],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wwrite-strings],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wlogical-op],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Waggregate-return],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wstrict-prototypes],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wold-style-definition],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmissing-prototypes],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmissing-declarations],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmissing-noreturn],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmissing-format-attribute],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wredundant-decls],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wnested-externs],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Winline],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Winvalid-pch],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wvolatile-register-var],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wdisabled-optimization],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wbuiltin-macro-redefined],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmudflap],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wpacked-bitfield-compat],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wsync-nand],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wattributes],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wcoverage-mismatch],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmultichar],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wcpp],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wdeprecated-declarations],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wdiv-by-zero],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wdouble-promotion],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wendif-labels],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wformat-contains-nul],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wformat-extra-args],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wformat-zero-length],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wformat=2],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wmultichar],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wnormalized=nfc],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Woverflow],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wpointer-to-int-cast],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wpragmas],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wsuggest-attribute=const],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wsuggest-attribute=noreturn],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wsuggest-attribute=pure],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wtrampolines],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wno-missing-field-initializers],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wno-sign-compare],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wjump-misses-init],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wno-format-nonliteral],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wframe-larger-than=$MAX_STACK_SIZE],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-fstack-protector-all],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-fasynchronous-unwind-tables],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-fdiagnostics-show-option],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-funit-at-a-time],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-fipa-pure-const],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wno-aggregate-return],[GIT_CFLAGS])
+ GIT_CFLAGS_ADD([-Wno-redundant-decls],[GIT_CFLAGS])
+ AC_SUBST([GIT_CFLAGS])
+ ])
AC_ARG_ENABLE([pthreads],
[AS_HELP_STRING([--enable-pthreads=FLAGS],
[FLAGS is the value to pass to the compiler to enable POSIX Threads.]
--
1.7.8.rc3.31.g017d1
^ permalink raw reply related
* Re: [PATCH] git-latexdiff: new command in contrib, to use latexdiff and Git
From: Matthieu Moy @ 2012-02-17 14:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Tim Haga, git
In-Reply-To: <7vmx8hvb69.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
>
>> I agree that the next step may be to allow users of <whatever SCM
>> outside Git>, but I don't think the way to do that would be to make the
>> script generic. The script is a quick hack, and all the "clever" parts
>> of it are calls to Git.
>
> You are not suggesting me to take and carry any future request that wants
> to add any quick hack that is heavily specific to Git and not portable to
> other SCMs to the contrib/ area only because they depend on Git, are
> you?
I'm answering the remark you made:
| I have this suspicion that "this new version will help people who have
| their documents stored in Mercurial" would be much more realistic (and
| the end result being useful) than "this new version will help git users
| who do not write their documents in latex but in asciidoc".
I think the probability that a next version of git-latexdiff is to
support another SCM is 0, and I tried to explain that.
Do you think I failed to address this remark?
> Look at what we have in the contrib/ area. I think what is common among
> them is that their primary benefit is to enrich user's Git experience.
... and many of them is to enrich the user experience using Git with
another tool (shell, text editor, foreign VCS).
Without git-latexdiff, you can run "git diff" on LaTeX documents, while
with it, you can get a better view of the diff. To me, this is "enrich
user's experience" of users running "git diff".
Git's _core_ already has some code to show diff hunks for various
languages, and I don't think anyone would want to move these out because
they only benefit people tracking files in these languages.
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: [PATCHv2 1/3] gitweb: Deal with HEAD pointing to unborn branch in "heads" view
From: Jakub Narebski @ 2012-02-17 13:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, rajesh boyapati
In-Reply-To: <7vsjiawe74.fsf@alter.siamese.dyndns.org>
On Fri, 17 Feb 2012, Junio C Hamano wrote:
> But after trying to write a reroll myself, I have to wonder what would
> happen if you have two branches pointing at the same commit as the one at
> HEAD. Why isn't the use of current_head class controlled by comparison
> between the name of the ref and the output from "symbolic-ref HEAD"?
If there is more than one branch that points to HEAD commit, they all
will be highlighted.
Using "git symbolic-ref HEAD", or just reading '.git/HEAD' file or symlink
is on my todo list. This will make gitweb highlight current branch
correctly even if there is more than one branch that point to the same
HEAD commit, and make it possible to support "detached HEAD" (which I think
is not supported at all now).
Anyway the test is here to stay... :-)
> -- >8 --
> From: Jakub Narebski <jnareb@gmail.com>
> Date: Wed, 15 Feb 2012 16:36:41 +0100
> Subject: [PATCH] gitweb: Fix "heads" view when there is no current branch
>
> In a repository whose HEAD points to an unborn branch with no commits,
> "heads" view and "summary" view (which shows what is shown in "heads"
> view) compared the object names of commits at the tip of branches with the
> output from "git rev-parse HEAD", which caused comparison of a string with
> undef and resulted in a warning in the server log.
>
> This can happen if non-bare repository (with default 'master' branch)
> is updated not via committing but by other means like push to it, or
> Gerrit. It can happen also just after running "git checkout --orphan
> <new branch>" but before creating any new commit on this branch.
>
> Rewrite the comparison so that it also works when $head points at nothing;
> in such a case, no branch can be "the current branch", add a test for it.
>
> While at it rename local variable $head to $head_at, as it points to
> current commit rather than current branch name (HEAD contents).
>
> Reported-by: Rajesh Boyapati
> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
Thanks!
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH] git-latexdiff: new command in contrib, to use latexdiff and Git
From: Junio C Hamano @ 2012-02-17 13:31 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Tim Haga, git
In-Reply-To: <vpqty2px4l5.fsf@bauges.imag.fr>
Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
> I agree that the next step may be to allow users of <whatever SCM
> outside Git>, but I don't think the way to do that would be to make the
> script generic. The script is a quick hack, and all the "clever" parts
> of it are calls to Git.
You are not suggesting me to take and carry any future request that wants
to add any quick hack that is heavily specific to Git and not portable to
other SCMs to the contrib/ area only because they depend on Git, are you?
That would bloat the contrib/ area with stuff that do not belong there and
we need to draw a line somewhere. The criteria I use to draw it is by
answering "is this an application that merely happens to use git, or is it
a way to help people who use Git?" question.
Look at what we have in the contrib/ area. I think what is common among
them is that their primary benefit is to enrich user's Git experience.
Bash completion for example is dependent on bash and it may be useless for
Csh users, but if you are a bash user, your Git experience will be
infinitely better with it regardless of what kind of payload you are
tracking in your Git repository. And in my mind, "regardless of what you
are tracking" is the key part that defines "the enhancement is about
user's Git experience".
^ permalink raw reply
* Re: Git repository clonning
From: Jakub Narebski @ 2012-02-17 12:59 UTC (permalink / raw)
To: Martin Přecechtěl; +Cc: git
In-Reply-To: <4F3E384A.3040006@gmail.com>
Martin Přecechtěl <precechtel@gmail.com> writes:
> I have a problem and I would like to ask you for help. I need to
> somehow access the git repository over network and read files from
> it. In the concrete, only thing I need is to read some files from
> repository, where I have files needed for installation of
> computers. So on computer where installation takes place, I need to
> read from this repository some files needed for installation
> process.
Where this repository is? Is it on computer you control? If yes, why
not use some networking filesystem or just rsync checked out files?
> I tried command git clone <my_repository> but this command
> download the whole repository which size is now almost 8GB files + 4GB
> .git folder. This process is very slow. So I want to ask you if there
> is a way how to access my repository (read some files from it) but to
> significantly improve speed. Is there for example something what will
> somehow map the repository to folder and then dowload only thouse
> files which are accessed?
You can try to use shallow clone, which would download only tip of
history... but all the files:
$ git clone --depth=0 <URL>
If remote repository is configured correctly, and all the files are
inside one directory, you can try to use remote archive:
$ git archive --remote=<URL> --prefix=<dir>/ --output=<dir>.tar \
HEAD:<dir>
It wouldprobably not work.
If there is some web interface, like gitweb or GitHub, you can
download snapshots of some subdirectory from there.
HTH
--
Jakub Narębski
^ permalink raw reply
* [PATCH 1/2] docs/api-config: minor clarifications
From: Jeff King @ 2012-02-17 8:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20120217032325.GB5738@sigill.intra.peff.net>
The first change simply drops some parentheses to make a
statement more clear. The seconds clarifies that almost
nobody wants to call git_config_early.
Signed-off-by: Jeff King <peff@peff.net>
---
Documentation/technical/api-config.txt | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/Documentation/technical/api-config.txt b/Documentation/technical/api-config.txt
index c60b6b3..67984da 100644
--- a/Documentation/technical/api-config.txt
+++ b/Documentation/technical/api-config.txt
@@ -11,9 +11,9 @@ General Usage
Config files are parsed linearly, and each variable found is passed to a
caller-provided callback function. The callback function is responsible
for any actions to be taken on the config option, and is free to ignore
-some options (it is not uncommon for the configuration to be parsed
+some options. It is not uncommon for the configuration to be parsed
several times during the run of a git program, with different callbacks
-picking out different variables useful to themselves).
+picking out different variables useful to themselves.
A config callback function takes three parameters:
@@ -47,11 +47,12 @@ will first feed the user-wide one to the callback, and then the
repo-specific one; by overwriting, the higher-priority repo-specific
value is left at the end).
-There is a special version of `git_config` called `git_config_early`
-that takes an additional parameter to specify the repository config.
-This should be used early in a git program when the repository location
-has not yet been determined (and calling the usual lazy-evaluation
-lookup rules would yield an incorrect location).
+There is a special version of `git_config` called `git_config_early`.
+This version takes an additional parameter to specify the repository
+config, instead of having it looked up via `git_path`. This is useful
+early in a git program before the repository has been found. Unless
+you're working with early setup code, you probably don't want to use
+this.
Reading Specific Files
----------------------
--
1.7.9.9.gcf58
^ permalink raw reply related
* Re: [PATCH v2 2/3] Introduce a performance testing framework
From: Jeff King @ 2012-02-17 7:45 UTC (permalink / raw)
To: Thomas Rast; +Cc: git
In-Reply-To: <5e712370fcfe32832998c085fdf6b5a7c4e7d64b.1329428159.git.trast@student.ethz.ch>
On Thu, Feb 16, 2012 at 10:41:14PM +0100, Thomas Rast wrote:
> + if test $eval_ret = 0 || test -n "$expecting_failure"
> + then
> + test_eval_ "$test_cleanup"
> + source ./test_vars || error "failed to load updated environment"
> + fi
"source" is a bash-ism (actually, it is a csh-ism as far as I know, but
perhaps it predates even that). The correct POSIX spelling is ".".
After tweaking this line, the suite seems to run fine for me with dash
as /bin/sh. Patch is below for your convenience.
-Peff
---
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index 07e9b09..629d7d5 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -135,7 +135,7 @@ exit $ret' >&3 2>&4
if test $eval_ret = 0 || test -n "$expecting_failure"
then
test_eval_ "$test_cleanup"
- source ./test_vars || error "failed to load updated environment"
+ . ./test_vars || error "failed to load updated environment"
fi
if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
echo ""
^ permalink raw reply related
* [PATCH 2/2] docs/api-config: describe git_config_with_options
From: Jeff King @ 2012-02-17 8:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20120217032325.GB5738@sigill.intra.peff.net>
This function was added recently but not documented.
Signed-off-by: Jeff King <peff@peff.net>
---
Documentation/technical/api-config.txt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Documentation/technical/api-config.txt b/Documentation/technical/api-config.txt
index 67984da..3dbf9fd 100644
--- a/Documentation/technical/api-config.txt
+++ b/Documentation/technical/api-config.txt
@@ -47,6 +47,22 @@ will first feed the user-wide one to the callback, and then the
repo-specific one; by overwriting, the higher-priority repo-specific
value is left at the end).
+The `git_config_with_options` function lets the caller examine config
+while adjusting some of the default behavior of `git_config`. It should
+almost never be used by "regular" git code that is looking up
+configuration variables. It is intended for advanced callers like
+`git-config`, which are intentionally tweaking the normal config-lookup
+process. It takes two options:
+
+`filename`::
+If this parameter is non-NULL, it specifies the name of a file to
+parse for configuration, rather than looking in the usual files. Regular
+`git_config` defaults to `NULL`.
+
+`respect_includes`::
+Specify whether include directives should be followed in parsed files.
+Regular `git_config` defaults to `1`.
+
There is a special version of `git_config` called `git_config_early`.
This version takes an additional parameter to specify the repository
config, instead of having it looked up via `git_path`. This is useful
--
1.7.9.9.gcf58
^ permalink raw reply related
* [PATCH 0/2] api-config documentation leftovers
From: Jeff King @ 2012-02-17 8:17 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20120217032325.GB5738@sigill.intra.peff.net>
On Thu, Feb 16, 2012 at 10:23:25PM -0500, Jeff King wrote:
> > Since you are re-rolling, these are the documentation fixes I had
> > squashed in based on your earlier review (though come to think of it,
> > the new patches should now also describe `git_config_with_options`).
>
> Looks like you just reverted the "include" patch instead of the merge of
> the whole topic. I'll prepare a few documentation fixups on top, then.
Here they are, on top of what you have in jk/config-include. Squashing
would involve breaking apart the second one into the "introduce
git_config_with_options" part and the "and now it learns
respect_includes" part. So it's probably not worth the effort.
[1/2]: docs/api-config: minor clarifications
[2/2]: docs/api-config: describe git_config_with_options
-Peff
^ permalink raw reply
* Git repository clonning
From: Martin Přecechtěl @ 2012-02-17 11:21 UTC (permalink / raw)
To: git
To Whom It May Concern,
I have a problem and I would like to ask you for help. I need to somehow
access the git repositry over network and read files from it. In the
concrete, only thing I need is to read some files from repository, where
I have files needed for installation of computers. So on computer where
installation takes place, I need to read from this repository some files
needed for installation process. I tried command git clone
<my_repository> but this command download the whole repository which
size is now almost 8GB files + 4GB .git folder. This process is very
slow. So I want to ask you if there is a way how to access my repository
(read some files from it) but to significantly improve speed. Is there
for example something what will somehow map the repository to folder and
then dowload only thouse files which are accessed?
I would appreciate any help.
Thank you for your time,
Yours faithfully,
Martin Precechtel
^ permalink raw reply
* [PATCH v3 2/3] Introduce a performance testing framework
From: Thomas Rast @ 2012-02-17 10:25 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <cover.1329472405.git.trast@student.ethz.ch>
This introduces a performance testing framework under t/perf/. It
tries to be as close to the test-lib.sh infrastructure as possible,
and thus should be easy to get used to for git developers.
The following points were considered for the implementation:
1. You usually want to compare arbitrary revisions/build trees against
each other. They may not have the performance test under
consideration, or even the perf-lib.sh infrastructure.
To cope with this, the 'run' script lets you specify arbitrary
build dirs and revisions. It even automatically builds the revisions
if it doesn't have them at hand yet.
2. Usually you would not want to run all tests. It would take too
long anyway. The 'run' script lets you specify which tests to run;
or you can also do it manually. There is a Makefile for
discoverability and 'make clean', but it is not meant for
real-world use.
3. Creating test repos from scratch in every test is extremely
time-consuming, and shipping or downloading such large/weird repos
is out of the question.
We leave this decision to the user. Two different sizes of test
repos can be configured, and the scripts just copy one or more of
those (using hardlinks for the object store). By default it tries
to use the build tree's git.git repository.
This is fairly fast and versatile. Using a copy instead of a clone
preserves many properties that the user may want to test for, such
as lots of loose objects, unpacked refs, etc.
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
Makefile | 22 ++++-
t/Makefile | 43 ++++++++-
t/perf/.gitignore | 2 +
t/perf/Makefile | 15 +++
t/perf/README | 146 +++++++++++++++++++++++++++++
t/perf/aggregate.perl | 166 ++++++++++++++++++++++++++++++++
t/perf/min_time.perl | 21 +++++
t/perf/p0000-perf-lib-sanity.sh | 41 ++++++++
t/perf/p0001-rev-list.sh | 17 ++++
t/perf/perf-lib.sh | 198 +++++++++++++++++++++++++++++++++++++++
t/perf/run | 82 ++++++++++++++++
t/test-lib.sh | 26 ++++-
12 files changed, 774 insertions(+), 5 deletions(-)
create mode 100644 t/perf/.gitignore
create mode 100644 t/perf/Makefile
create mode 100644 t/perf/README
create mode 100755 t/perf/aggregate.perl
create mode 100755 t/perf/min_time.perl
create mode 100755 t/perf/p0000-perf-lib-sanity.sh
create mode 100755 t/perf/p0001-rev-list.sh
create mode 100644 t/perf/perf-lib.sh
create mode 100755 t/perf/run
diff --git a/Makefile b/Makefile
index a0de4e9..1fb1705 100644
--- a/Makefile
+++ b/Makefile
@@ -2361,6 +2361,10 @@ GIT-BUILD-OPTIONS: FORCE
@echo USE_LIBPCRE=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE)))'\' >>$@
@echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@
@echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@
+ @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@
+ifdef GIT_TEST_OPTS
+ @echo GIT_TEST_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_OPTS)))'\' >>$@
+endif
ifdef GIT_TEST_CMP
@echo GIT_TEST_CMP=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_CMP)))'\' >>$@
endif
@@ -2369,7 +2373,18 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
endif
@echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@
@echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@
- @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@
+ifdef GIT_PERF_REPEAT_COUNT
+ @echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@
+endif
+ifdef GIT_PERF_REPO
+ @echo GIT_PERF_REPO=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPO)))'\' >>$@
+endif
+ifdef GIT_PERF_LARGE_REPO
+ @echo GIT_PERF_LARGE_REPO=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_LARGE_REPO)))'\' >>$@
+endif
+ifdef GIT_PERF_MAKE_OPTS
+ @echo GIT_PERF_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_MAKE_OPTS)))'\' >>$@
+endif
### Detect Tck/Tk interpreter path changes
ifndef NO_TCLTK
@@ -2405,6 +2420,11 @@ export NO_SVN_TESTS
test: all
$(MAKE) -C t/ all
+perf: all
+ $(MAKE) -C t/perf/ all
+
+.PHONY: test perf
+
test-ctype$X: ctype.o
test-date$X: date.o ctype.o
diff --git a/t/Makefile b/t/Makefile
index b5048ab..6091211 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -73,4 +73,45 @@ gitweb-test:
valgrind:
$(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"
-.PHONY: pre-clean $(T) aggregate-results clean valgrind
+perf:
+ $(MAKE) -C perf/ all
+
+# Smoke testing targets
+-include ../GIT-VERSION-FILE
+uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo unknown')
+uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo unknown')
+
+test-results:
+ mkdir -p test-results
+
+test-results/git-smoke.tar.gz: test-results
+ $(PERL_PATH) ./harness \
+ --archive="test-results/git-smoke.tar.gz" \
+ $(T)
+
+smoke: test-results/git-smoke.tar.gz
+
+SMOKE_UPLOAD_FLAGS =
+ifdef SMOKE_USERNAME
+ SMOKE_UPLOAD_FLAGS += -F username="$(SMOKE_USERNAME)" -F password="$(SMOKE_PASSWORD)"
+endif
+ifdef SMOKE_COMMENT
+ SMOKE_UPLOAD_FLAGS += -F comments="$(SMOKE_COMMENT)"
+endif
+ifdef SMOKE_TAGS
+ SMOKE_UPLOAD_FLAGS += -F tags="$(SMOKE_TAGS)"
+endif
+
+smoke_report: smoke
+ curl \
+ -H "Expect: " \
+ -F project=Git \
+ -F architecture="$(uname_M)" \
+ -F platform="$(uname_S)" \
+ -F revision="$(GIT_VERSION)" \
+ -F report_file=@test-results/git-smoke.tar.gz \
+ $(SMOKE_UPLOAD_FLAGS) \
+ http://smoke.git.nix.is/app/projects/process_add_report/1 \
+ | grep -v ^Redirecting
+
+.PHONY: pre-clean $(T) aggregate-results clean valgrind perf
diff --git a/t/perf/.gitignore b/t/perf/.gitignore
new file mode 100644
index 0000000..50f5cc1
--- /dev/null
+++ b/t/perf/.gitignore
@@ -0,0 +1,2 @@
+build/
+test-results/
diff --git a/t/perf/Makefile b/t/perf/Makefile
new file mode 100644
index 0000000..8c47155
--- /dev/null
+++ b/t/perf/Makefile
@@ -0,0 +1,15 @@
+-include ../../config.mak
+export GIT_TEST_OPTIONS
+
+all: perf
+
+perf: pre-clean
+ ./run
+
+pre-clean:
+ rm -rf test-results
+
+clean:
+ rm -rf build "trash directory".* test-results
+
+.PHONY: all perf pre-clean clean
diff --git a/t/perf/README b/t/perf/README
new file mode 100644
index 0000000..fdf974a
--- /dev/null
+++ b/t/perf/README
@@ -0,0 +1,146 @@
+Git performance tests
+=====================
+
+This directory holds performance testing scripts for git tools. The
+first part of this document describes the various ways in which you
+can run them.
+
+When fixing the tools or adding enhancements, you are strongly
+encouraged to add tests in this directory to cover what you are
+trying to fix or enhance. The later part of this short document
+describes how your test scripts should be organized.
+
+
+Running Tests
+-------------
+
+The easiest way to run tests is to say "make". This runs all
+the tests on the current git repository.
+
+ === Running 2 tests in this tree ===
+ [...]
+ Test this tree
+ ---------------------------------------------------------
+ 0001.1: rev-list --all 0.54(0.51+0.02)
+ 0001.2: rev-list --all --objects 6.14(5.99+0.11)
+ 7810.1: grep worktree, cheap regex 0.16(0.16+0.35)
+ 7810.2: grep worktree, expensive regex 7.90(29.75+0.37)
+ 7810.3: grep --cached, cheap regex 3.07(3.02+0.25)
+ 7810.4: grep --cached, expensive regex 9.39(30.57+0.24)
+
+You can compare multiple repositories and even git revisions with the
+'run' script:
+
+ $ ./run . origin/next /path/to/git-tree p0001-rev-list.sh
+
+where . stands for the current git tree. The full invocation is
+
+ ./run [<revision|directory>...] [--] [<test-script>...]
+
+A '.' argument is implied if you do not pass any other
+revisions/directories.
+
+You can also manually test this or another git build tree, and then
+call the aggregation script to summarize the results:
+
+ $ ./p0001-rev-list.sh
+ [...]
+ $ GIT_BUILD_DIR=/path/to/other/git ./p0001-rev-list.sh
+ [...]
+ $ ./aggregate.perl . /path/to/other/git ./p0001-rev-list.sh
+
+aggregate.perl has the same invocation as 'run', it just does not run
+anything beforehand.
+
+You can set the following variables (also in your config.mak):
+
+ GIT_PERF_REPEAT_COUNT
+ Number of times a test should be repeated for best-of-N
+ measurements. Defaults to 5.
+
+ GIT_PERF_MAKE_OPTS
+ Options to use when automatically building a git tree for
+ performance testing. E.g., -j6 would be useful.
+
+ GIT_PERF_REPO
+ GIT_PERF_LARGE_REPO
+ Repositories to copy for the performance tests. The normal
+ repo should be at least git.git size. The large repo should
+ probably be about linux-2.6.git size for optimal results.
+ Both default to the git.git you are running from.
+
+You can also pass the options taken by ordinary git tests; the most
+useful one is:
+
+--root=<directory>::
+ Create "trash" directories used to store all temporary data during
+ testing under <directory>, instead of the t/ directory.
+ Using this option with a RAM-based filesystem (such as tmpfs)
+ can massively speed up the test suite.
+
+
+Naming Tests
+------------
+
+The performance test files are named as:
+
+ pNNNN-commandname-details.sh
+
+where N is a decimal digit. The same conventions for choosing NNNN as
+for normal tests apply.
+
+
+Writing Tests
+-------------
+
+The perf script starts much like a normal test script, except it
+sources perf-lib.sh:
+
+ #!/bin/sh
+ #
+ # Copyright (c) 2005 Junio C Hamano
+ #
+
+ test_description='xxx performance test'
+ . ./perf-lib.sh
+
+After that you will want to use some of the following:
+
+ test_perf_default_repo # sets up a "normal" repository
+ test_perf_large_repo # sets up a "large" repository
+
+ test_perf_default_repo sub # ditto, in a subdir "sub"
+
+ test_checkout_worktree # if you need the worktree too
+
+At least one of the first two is required!
+
+You can use test_expect_success as usual. For actual performance
+tests, use
+
+ test_perf 'descriptive string' '
+ command1 &&
+ command2
+ '
+
+test_perf spawns a subshell, for lack of better options. This means
+that
+
+* you _must_ export all variables that you need in the subshell
+
+* you _must_ flag all variables that you want to persist from the
+ subshell with 'test_export':
+
+ test_perf 'descriptive string' '
+ foo=$(git rev-parse HEAD) &&
+ test_export foo
+ '
+
+ The so-exported variables are automatically marked for export in the
+ shell executing the perf test. For your convenience, test_export is
+ the same as export in the main shell.
+
+ This feature relies on a bit of magic using 'set' and 'source'.
+ While we have tried to make sure that it can cope with embedded
+ whitespace and other special characters, it will not work with
+ multi-line data.
diff --git a/t/perf/aggregate.perl b/t/perf/aggregate.perl
new file mode 100755
index 0000000..15f7fc1
--- /dev/null
+++ b/t/perf/aggregate.perl
@@ -0,0 +1,166 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Git;
+
+sub get_times {
+ my $name = shift;
+ open my $fh, "<", $name or return undef;
+ my $line = <$fh>;
+ return undef if not defined $line;
+ close $fh or die "cannot close $name: $!";
+ $line =~ /^(?:(\d+):)?(\d+):(\d+(?:\.\d+)?) (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)$/
+ or die "bad input line: $line";
+ my $rt = ((defined $1 ? $1 : 0.0)*60+$2)*60+$3;
+ return ($rt, $4, $5);
+}
+
+sub format_times {
+ my ($r, $u, $s, $firstr) = @_;
+ if (!defined $r) {
+ return "<missing>";
+ }
+ my $out = sprintf "%.2f(%.2f+%.2f)", $r, $u, $s;
+ if (defined $firstr) {
+ if ($firstr > 0) {
+ $out .= sprintf " %+.1f%%", 100.0*($r-$firstr)/$firstr;
+ } elsif ($r == 0) {
+ $out .= " =";
+ } else {
+ $out .= " +inf";
+ }
+ }
+ return $out;
+}
+
+my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests);
+while (scalar @ARGV) {
+ my $arg = $ARGV[0];
+ my $dir;
+ last if -f $arg or $arg eq "--";
+ if (! -d $arg) {
+ my $rev = Git::command_oneline(qw(rev-parse --verify), $arg);
+ $dir = "build/".$rev;
+ } else {
+ $arg =~ s{/*$}{};
+ $dir = $arg;
+ $dirabbrevs{$dir} = $dir;
+ }
+ push @dirs, $dir;
+ $dirnames{$dir} = $arg;
+ my $prefix = $dir;
+ $prefix =~ tr/^a-zA-Z0-9/_/c;
+ $prefixes{$dir} = $prefix . '.';
+ shift @ARGV;
+}
+
+if (not @dirs) {
+ @dirs = ('.');
+}
+$dirnames{'.'} = $dirabbrevs{'.'} = "this tree";
+$prefixes{'.'} = '';
+
+shift @ARGV if scalar @ARGV and $ARGV[0] eq "--";
+
+@tests = @ARGV;
+if (not @tests) {
+ @tests = glob "p????-*.sh";
+}
+
+my @subtests;
+my %shorttests;
+for my $t (@tests) {
+ $t =~ s{(?:.*/)?(p(\d+)-[^/]+)\.sh$}{$1} or die "bad test name: $t";
+ my $n = $2;
+ my $fname = "test-results/$t.subtests";
+ open my $fp, "<", $fname or die "cannot open $fname: $!";
+ for (<$fp>) {
+ chomp;
+ /^(\d+)$/ or die "malformed subtest line: $_";
+ push @subtests, "$t.$1";
+ $shorttests{"$t.$1"} = "$n.$1";
+ }
+ close $fp or die "cannot close $fname: $!";
+}
+
+sub read_descr {
+ my $name = shift;
+ open my $fh, "<", $name or return "<error reading description>";
+ my $line = <$fh>;
+ close $fh or die "cannot close $name";
+ chomp $line;
+ return $line;
+}
+
+my %descrs;
+my $descrlen = 4; # "Test"
+for my $t (@subtests) {
+ $descrs{$t} = $shorttests{$t}.": ".read_descr("test-results/$t.descr");
+ $descrlen = length $descrs{$t} if length $descrs{$t}>$descrlen;
+}
+
+sub have_duplicate {
+ my %seen;
+ for (@_) {
+ return 1 if exists $seen{$_};
+ $seen{$_} = 1;
+ }
+ return 0;
+}
+sub have_slash {
+ for (@_) {
+ return 1 if m{/};
+ }
+ return 0;
+}
+
+my %newdirabbrevs = %dirabbrevs;
+while (!have_duplicate(values %newdirabbrevs)) {
+ %dirabbrevs = %newdirabbrevs;
+ last if !have_slash(values %dirabbrevs);
+ %newdirabbrevs = %dirabbrevs;
+ for (values %newdirabbrevs) {
+ s{^[^/]*/}{};
+ }
+}
+
+my %times;
+my @colwidth = ((0)x@dirs);
+for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ my $w = length (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+ $colwidth[$i] = $w if $w > $colwidth[$i];
+}
+for my $t (@subtests) {
+ my $firstr;
+ for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ $times{$prefixes{$d}.$t} = [get_times("test-results/$prefixes{$d}$t.times")];
+ my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
+ my $w = length format_times($r,$u,$s,$firstr);
+ $colwidth[$i] = $w if $w > $colwidth[$i];
+ $firstr = $r unless defined $firstr;
+ }
+}
+my $totalwidth = 3*@dirs+$descrlen;
+$totalwidth += $_ for (@colwidth);
+
+printf "%-${descrlen}s", "Test";
+for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ printf " %-$colwidth[$i]s", (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+}
+print "\n";
+print "-"x$totalwidth, "\n";
+for my $t (@subtests) {
+ printf "%-${descrlen}s", $descrs{$t};
+ my $firstr;
+ for my $i (0..$#dirs) {
+ my $d = $dirs[$i];
+ my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
+ printf " %-$colwidth[$i]s", format_times($r,$u,$s,$firstr);
+ $firstr = $r unless defined $firstr;
+ }
+ print "\n";
+}
diff --git a/t/perf/min_time.perl b/t/perf/min_time.perl
new file mode 100755
index 0000000..c1a2717
--- /dev/null
+++ b/t/perf/min_time.perl
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+
+my $minrt = 1e100;
+my $min;
+
+while (<>) {
+ # [h:]m:s.xx U.xx S.xx
+ /^(?:(\d+):)?(\d+):(\d+(?:\.\d+)?) (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)$/
+ or die "bad input line: $_";
+ my $rt = ((defined $1 ? $1 : 0.0)*60+$2)*60+$3;
+ if ($rt < $minrt) {
+ $min = $_;
+ $minrt = $rt;
+ }
+}
+
+if (!defined $min) {
+ die "no input found";
+}
+
+print $min;
diff --git a/t/perf/p0000-perf-lib-sanity.sh b/t/perf/p0000-perf-lib-sanity.sh
new file mode 100755
index 0000000..2ca4aac
--- /dev/null
+++ b/t/perf/p0000-perf-lib-sanity.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+test_description='Tests whether perf-lib facilities work'
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+test_perf 'test_perf_default_repo works' '
+ foo=$(git rev-parse HEAD) &&
+ test_export foo
+'
+
+test_checkout_worktree
+
+test_perf 'test_checkout_worktree works' '
+ wt=$(find . | wc -l) &&
+ idx=$(git ls-files | wc -l) &&
+ test $wt -gt $idx
+'
+
+baz=baz
+test_export baz
+
+test_expect_success 'test_export works' '
+ echo "$foo" &&
+ test "$foo" = "$(git rev-parse HEAD)" &&
+ echo "$baz" &&
+ test "$baz" = baz
+'
+
+test_perf 'export a weird var' '
+ bar="weird # variable" &&
+ test_export bar
+'
+
+test_expect_success 'test_export works with weird vars' '
+ echo "$bar" &&
+ test "$bar" = "weird # variable"
+'
+
+test_done
diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh
new file mode 100755
index 0000000..4f71a63
--- /dev/null
+++ b/t/perf/p0001-rev-list.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+test_description="Tests history walking performance"
+
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+test_perf 'rev-list --all' '
+ git rev-list --all >/dev/null
+'
+
+test_perf 'rev-list --all --objects' '
+ git rev-list --all --objects >/dev/null
+'
+
+test_done
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
new file mode 100644
index 0000000..07e9b09
--- /dev/null
+++ b/t/perf/perf-lib.sh
@@ -0,0 +1,198 @@
+#!/bin/bash
+#
+# Copyright (c) 2011 Thomas Rast
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# do the --tee work early; it otherwise confuses our careful
+# GIT_BUILD_DIR mangling
+case "$GIT_TEST_TEE_STARTED, $* " in
+done,*)
+ # do not redirect again
+ ;;
+*' --tee '*|*' --va'*)
+ mkdir -p test-results
+ BASE=test-results/$(basename "$0" .sh)
+ (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
+ echo $? > $BASE.exit) | tee $BASE.out
+ test "$(cat $BASE.exit)" = 0
+ exit
+ ;;
+esac
+
+TEST_DIRECTORY=$(pwd)/..
+TEST_OUTPUT_DIRECTORY=$(pwd)
+if test -z "$GIT_TEST_INSTALLED"; then
+ perf_results_prefix=
+else
+ perf_results_prefix=$(printf "%s" "${GIT_TEST_INSTALLED%/bin-wrappers}" | tr -c "[a-zA-Z0-9]" "[_*]")"."
+ # make the tested dir absolute
+ GIT_TEST_INSTALLED=$(cd "$GIT_TEST_INSTALLED" && pwd)
+fi
+
+TEST_NO_CREATE_REPO=t
+
+. ../test-lib.sh
+
+perf_results_dir=$TEST_OUTPUT_DIRECTORY/test-results
+mkdir -p "$perf_results_dir"
+rm -f "$perf_results_dir"/$(basename "$0" .sh).subtests
+
+if test -z "$GIT_PERF_REPEAT_COUNT"; then
+ GIT_PERF_REPEAT_COUNT=3
+fi
+die_if_build_dir_not_repo () {
+ if ! ( cd "$TEST_DIRECTORY/.." &&
+ git rev-parse --build-dir >/dev/null 2>&1 ); then
+ error "No $1 defined, and your build directory is not a repo"
+ fi
+}
+
+if test -z "$GIT_PERF_REPO"; then
+ die_if_build_dir_not_repo '$GIT_PERF_REPO'
+ GIT_PERF_REPO=$TEST_DIRECTORY/..
+fi
+if test -z "$GIT_PERF_LARGE_REPO"; then
+ die_if_build_dir_not_repo '$GIT_PERF_LARGE_REPO'
+ GIT_PERF_LARGE_REPO=$TEST_DIRECTORY/..
+fi
+
+test_perf_create_repo_from () {
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 parameters to test-create-repo"
+ repo="$1"
+ source="$2"
+ source_git=$source/$(cd "$source" && git rev-parse --git-dir)
+ mkdir -p "$repo/.git"
+ (
+ cd "$repo/.git" &&
+ { cp -Rl "$source_git/objects" . 2>/dev/null ||
+ cp -R "$source_git/objects" .; } &&
+ for stuff in "$source_git"/*; do
+ case "$stuff" in
+ */objects|*/hooks|*/config)
+ ;;
+ *)
+ cp -R "$stuff" . || break
+ ;;
+ esac
+ done &&
+ cd .. &&
+ git init -q &&
+ mv .git/hooks .git/hooks-disabled 2>/dev/null
+ ) || error "failed to copy repository '$source' to '$repo'"
+}
+
+# call at least one of these to establish an appropriately-sized repository
+test_perf_default_repo () {
+ test_perf_create_repo_from "${1:-$TRASH_DIRECTORY}" "$GIT_PERF_REPO"
+}
+test_perf_large_repo () {
+ if test "$GIT_PERF_LARGE_REPO" = "$GIT_BUILD_DIR"; then
+ echo "warning: \$GIT_PERF_LARGE_REPO is \$GIT_BUILD_DIR." >&2
+ echo "warning: This will work, but may not be a sufficiently large repo" >&2
+ echo "warning: for representative measurements." >&2
+ fi
+ test_perf_create_repo_from "${1:-$TRASH_DIRECTORY}" "$GIT_PERF_LARGE_REPO"
+}
+test_checkout_worktree () {
+ git checkout-index -u -a ||
+ error "git checkout-index failed"
+}
+
+# Performance tests should never fail. If they do, stop immediately
+immediate=t
+
+test_run_perf_ () {
+ test_cleanup=:
+ test_export_="test_cleanup"
+ export test_cleanup test_export_
+ /usr/bin/time -f "%E %U %S" -o test_time.$i "$SHELL" -c '
+. '"$TEST_DIRECTORY"/../test-lib-functions.sh'
+test_export () {
+ [ $# != 0 ] || return 0
+ test_export_="$test_export_\\|$1"
+ shift
+ test_export "$@"
+}
+'"$1"'
+ret=$?
+set | sed -n "s'"/'/'\\\\''/g"';s/^\\($test_export_\\)/export '"'&'"'/p" >test_vars
+exit $ret' >&3 2>&4
+ eval_ret=$?
+
+ if test $eval_ret = 0 || test -n "$expecting_failure"
+ then
+ test_eval_ "$test_cleanup"
+ source ./test_vars || error "failed to load updated environment"
+ fi
+ if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
+ echo ""
+ fi
+ return "$eval_ret"
+}
+
+
+test_perf () {
+ test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 or 3 parameters to test-expect-success"
+ export test_prereq
+ if ! test_skip "$@"
+ then
+ base=$(basename "$0" .sh)
+ echo "$test_count" >>"$perf_results_dir"/$base.subtests
+ echo "$1" >"$perf_results_dir"/$base.$test_count.descr
+ if test -z "$verbose"; then
+ echo -n "perf $test_count - $1:"
+ else
+ echo "perf $test_count - $1:"
+ fi
+ for i in $(seq 1 $GIT_PERF_REPEAT_COUNT); do
+ say >&3 "running: $2"
+ if test_run_perf_ "$2"
+ then
+ if test -z "$verbose"; then
+ echo -n " $i"
+ else
+ echo "* timing run $i/$GIT_PERF_REPEAT_COUNT:"
+ fi
+ else
+ test -z "$verbose" && echo
+ test_failure_ "$@"
+ break
+ fi
+ done
+ if test -z "$verbose"; then
+ echo " ok"
+ else
+ test_ok_ "$1"
+ fi
+ base="$perf_results_dir"/"$perf_results_prefix$(basename "$0" .sh)"."$test_count"
+ "$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".times
+ fi
+ echo >&3 ""
+}
+
+# We extend test_done to print timings at the end (./run disables this
+# and does it after running everything)
+test_at_end_hook_ () {
+ if test -z "$GIT_PERF_AGGREGATING_LATER"; then
+ ( cd "$TEST_DIRECTORY"/perf && ./aggregate.perl $(basename "$0") )
+ fi
+}
+
+test_export () {
+ export "$@"
+}
diff --git a/t/perf/run b/t/perf/run
new file mode 100755
index 0000000..cfd7012
--- /dev/null
+++ b/t/perf/run
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+case "$1" in
+ --help)
+ echo "usage: $0 [other_git_tree...] [--] [test_scripts]"
+ exit 0
+ ;;
+esac
+
+die () {
+ echo >&2 "error: $*"
+ exit 1
+}
+
+run_one_dir () {
+ if test $# -eq 0; then
+ set -- p????-*.sh
+ fi
+ echo "=== Running $# tests in ${GIT_TEST_INSTALLED:-this tree} ==="
+ for t in "$@"; do
+ ./$t $GIT_TEST_OPTS
+ done
+}
+
+unpack_git_rev () {
+ rev=$1
+ mkdir -p build/$rev
+ (cd "$(git rev-parse --show-cdup)" && git archive --format=tar $rev) |
+ (cd build/$rev && tar x)
+}
+build_git_rev () {
+ rev=$1
+ cp ../../config.mak build/$rev/config.mak
+ (cd build/$rev && make $GIT_PERF_MAKE_OPTS) ||
+ die "failed to build revision '$mydir'"
+}
+
+run_dirs_helper () {
+ mydir=${1%/}
+ shift
+ while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do
+ shift
+ done
+ if test $# -gt 0 -a "$1" = --; then
+ shift
+ fi
+ if [ ! -d "$mydir" ]; then
+ rev=$(git rev-parse --verify "$mydir" 2>/dev/null) ||
+ die "'$mydir' is neither a directory nor a valid revision"
+ if [ ! -d build/$rev ]; then
+ unpack_git_rev $rev
+ fi
+ build_git_rev $rev
+ mydir=build/$rev
+ fi
+ if test "$mydir" = .; then
+ unset GIT_TEST_INSTALLED
+ else
+ GIT_TEST_INSTALLED="$mydir/bin-wrappers"
+ export GIT_TEST_INSTALLED
+ fi
+ run_one_dir "$@"
+}
+
+run_dirs () {
+ while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do
+ run_dirs_helper "$@"
+ shift
+ done
+}
+
+GIT_PERF_AGGREGATING_LATER=t
+export GIT_PERF_AGGREGATING_LATER
+
+cd "$(dirname $0)"
+. ../../GIT-BUILD-OPTIONS
+
+if test $# = 0 -o "$1" = -- -o -f "$1"; then
+ set -- . "$@"
+fi
+run_dirs "$@"
+./aggregate.perl "$@"
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 1da3f40..d75766a 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -55,6 +55,7 @@ unset $(perl -e '
.*_TEST
PROVE
VALGRIND
+ PERF_AGGREGATING_LATER
));
my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
print join("\n", @vars);
@@ -98,6 +99,8 @@ _z40=0000000000000000000000000000000000000000
LF='
'
+export _x05 _x40 _z40 LF
+
# Each test should start with something like this, after copyright notices:
#
# test_description='Description of this test...
@@ -313,11 +316,16 @@ test_skip () {
esac
}
+# stub; perf-lib overrides it
+test_at_end_hook_ () {
+ :
+}
+
test_done () {
GIT_EXIT_OK=t
if test -z "$HARNESS_ACTIVE"; then
- test_results_dir="$TEST_DIRECTORY/test-results"
+ test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
test_results_path="$test_results_dir/${0%.sh}-$$.counts"
@@ -356,6 +364,8 @@ test_done () {
cd "$(dirname "$remove_trash")" &&
rm -rf "$(basename "$remove_trash")"
+ test_at_end_hook_
+
exit 0 ;;
*)
@@ -378,6 +388,12 @@ then
# itself.
TEST_DIRECTORY=$(pwd)
fi
+if test -z "$TEST_OUTPUT_DIRECTORY"
+then
+ # Similarly, override this to store the test-results subdir
+ # elsewhere
+ TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY
+fi
GIT_BUILD_DIR="$TEST_DIRECTORY"/..
if test -n "$valgrind"
@@ -513,7 +529,7 @@ test="trash directory.$(basename "$0" .sh)"
test -n "$root" && test="$root/$test"
case "$test" in
/*) TRASH_DIRECTORY="$test" ;;
- *) TRASH_DIRECTORY="$TEST_DIRECTORY/$test" ;;
+ *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$test" ;;
esac
test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY
rm -fr "$test" || {
@@ -525,7 +541,11 @@ rm -fr "$test" || {
HOME="$TRASH_DIRECTORY"
export HOME
-test_create_repo "$test"
+if test -z "$TEST_NO_CREATE_REPO"; then
+ test_create_repo "$test"
+else
+ mkdir -p "$test"
+fi
# Use -P to resolve symlinks in our working directory so that the cwd
# in subprocesses like git equals our $PWD (for pathname comparisons).
cd -P "$test" || exit 1
--
1.7.9.1.365.ge223f
^ permalink raw reply related
* [PATCH v3 3/3] Add a performance test for git-grep
From: Thomas Rast @ 2012-02-17 10:25 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <cover.1329472405.git.trast@student.ethz.ch>
The only catch is that we don't really know what our repo contains, so
we have to ignore any possible "not found" status from git-grep.
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
t/perf/p7810-grep.sh | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100755 t/perf/p7810-grep.sh
diff --git a/t/perf/p7810-grep.sh b/t/perf/p7810-grep.sh
new file mode 100755
index 0000000..9f4ade6
--- /dev/null
+++ b/t/perf/p7810-grep.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+test_description="git-grep performance in various modes"
+
+. ./perf-lib.sh
+
+test_perf_large_repo
+test_checkout_worktree
+
+test_perf 'grep worktree, cheap regex' '
+ git grep some_nonexistent_string || :
+'
+test_perf 'grep worktree, expensive regex' '
+ git grep "^.* *some_nonexistent_string$" || :
+'
+test_perf 'grep --cached, cheap regex' '
+ git grep --cached some_nonexistent_string || :
+'
+test_perf 'grep --cached, expensive regex' '
+ git grep --cached "^.* *some_nonexistent_string$" || :
+'
+
+test_done
--
1.7.9.1.365.ge223f
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox