merge(3p/git): Merge git subtree at v2.29.2

This also bumps the stable nixpkgs to 20.09 as of 2020-11-21, because
there is some breakage in the git build related to the netrc
credentials helper which someone has taken care of in nixpkgs.

The stable channel is not used for anything other than git, so this
should be fine.

Change-Id: I3575a19dab09e1e9556cf8231d717de9890484fb
This commit is contained in:
Vincent Ambo 2020-11-21 19:20:35 +01:00
parent 082c006c04
commit f4609b896f
1485 changed files with 241535 additions and 109418 deletions

View file

@ -1,7 +1,7 @@
Core GIT Tests
Core Git Tests
==============
This directory holds many test scripts for core GIT tools. The
This directory holds many test scripts for core Git tools. The
first part of this short document describes how to run the tests
and read their output.
@ -69,7 +69,8 @@ You can also run each test individually from command line, like this:
You can pass --verbose (or -v), --debug (or -d), and --immediate
(or -i) command line argument to the test, or by setting GIT_TEST_OPTS
appropriately before running "make".
appropriately before running "make". Short options can be bundled, i.e.
'-d -v' is the same as '-dv'.
-v::
--verbose::
@ -352,8 +353,8 @@ details.
GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
test suite. Accept any boolean values that are accepted by git-config.
GIT_TEST_PROTOCOL_VERSION=<n>, when set, overrides the
'protocol.version' setting to n if it is less than n.
GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version'
default to n.
GIT_TEST_FULL_IN_PACK_ARRAY=<boolean> exercises the uncommon
pack-objects code path where there are more than 1024 packs even if
@ -378,6 +379,11 @@ GIT_TEST_COMMIT_GRAPH=<boolean>, when true, forces the commit-graph to
be written after every 'git commit' command, and overrides the
'core.commitGraph' setting to true.
GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=<boolean>, when true, forces
commit-graph write to compute and write changed path Bloom filters for
every 'git commit-graph write', as if the `--changed-paths` option was
passed in.
GIT_TEST_FSMONITOR=$PWD/t7519/fsmonitor-all exercises the fsmonitor
code path for utilizing a file system monitor to speed up detecting
new or changed files.
@ -386,15 +392,15 @@ GIT_TEST_INDEX_VERSION=<n> exercises the index read/write code path
for the index version specified. Can be set to any valid version
(currently 2, 3, or 4).
GIT_TEST_PACK_SPARSE=<boolean> if enabled will default the pack-objects
builtin to use the sparse object walk. This can still be overridden by
the --no-sparse command-line argument.
GIT_TEST_PACK_SPARSE=<boolean> if disabled will default the pack-objects
builtin to use the non-sparse object walk. This can still be overridden by
the --sparse command-line argument.
GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
by overriding the minimum number of cache entries required per thread.
GIT_TEST_STASH_USE_BUILTIN=<boolean>, when false, disables the
built-in version of git-stash. See 'stash.useBuiltin' in
GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when true, enables the
built-in version of git add -i. See 'add.interactive.useBuiltin' in
git-config(1).
GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading
@ -415,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
the default when running tests), errors out when an abbreviated option
is used.
GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to
use in the test scripts. Recognized values for <hash-algo> are "sha1"
and "sha256".
Naming Tests
------------
@ -546,6 +556,41 @@ Here are the "do's:"
reports "ok" or "not ok" to the end user running the tests. Under
--verbose, they are shown to help debug the tests.
- Be careful when you loop
You may need to verify multiple things in a loop, but the
following does not work correctly:
test_expect_success 'test three things' '
for i in one two three
do
test_something "$i"
done &&
test_something_else
'
Because the status of the loop itself is the exit status of the
test_something in the last round, the loop does not fail when
"test_something" for "one" or "two" fails. This is not what you
want.
Instead, you can break out of the loop immediately when you see a
failure. Because all test_expect_* snippets are executed inside
a function, "return 1" can be used to fail the test immediately
upon a failure:
test_expect_success 'test three things' '
for i in one two three
do
test_something "$i" || return 1
done &&
test_something_else
'
Note that we still &&-chain the loop to propagate failures from
earlier commands.
And here are the "don'ts:"
- Don't exit() within a <script> part.
@ -978,6 +1023,15 @@ library for your script to use.
output to the downstream---unlike the real version, it generates
only up to 99 lines.
- test_bool_env <env-variable-name> <default-value>
Given the name of an environment variable with a bool value,
normalize its value to a 0 (true) or 1 (false or empty string)
return code. Return with code corresponding to the given default
value if the variable is unset.
Abort the test script if either the value of the variable or the
default are not valid bool values.
Prerequisites
-------------
@ -1067,21 +1121,21 @@ Tips for Writing Tests
As with any programming projects, existing programs are the best
source of the information. However, do _not_ emulate
t0000-basic.sh when writing your tests. The test is special in
that it tries to validate the very core of GIT. For example, it
that it tries to validate the very core of Git. For example, it
knows that there will be 256 subdirectories under .git/objects/,
and it knows that the object ID of an empty tree is a certain
40-byte string. This is deliberately done so in t0000-basic.sh
because the things the very basic core test tries to achieve is
to serve as a basis for people who are changing the GIT internal
to serve as a basis for people who are changing the Git internals
drastically. For these people, after making certain changes,
not seeing failures from the basic test _is_ a failure. And
such drastic changes to the core GIT that even changes these
such drastic changes to the core Git that even changes these
otherwise supposedly stable object IDs should be accompanied by
an update to t0000-basic.sh.
However, other tests that simply rely on basic parts of the core
GIT working properly should not have that level of intimate
knowledge of the core GIT internals. If all the test scripts
Git working properly should not have that level of intimate
knowledge of the core Git internals. If all the test scripts
hardcoded the object IDs like t0000-basic.sh does, that defeats
the purpose of t0000-basic.sh, which is to isolate that level of
validation in one place. Your test also ends up needing

View file

@ -117,7 +117,7 @@
/^[ ]*!*[ ]*(..*)[ ]*[0-9]*[<>|&]/boneline
# multi-line "(...\n...)"
/^[ ]*(/bsubshell
/^[ ]*(/bsubsh
# innocuous line -- print it and advance to next line
b
@ -130,11 +130,11 @@ b
}
b
:subshell
:subsh
# bare "(" line? -- stash for later printing
/^[ ]*([ ]*$/ {
h
bnextline
bnextln
}
# "(..." line -- split off and stash "(", then process "..." as its own line
x
@ -143,7 +143,7 @@ x
s/(//
bslurp
:nextline
:nextln
N
s/.*\n//
@ -151,10 +151,10 @@ s/.*\n//
# incomplete line "...\"
/\\$/bicmplte
# multi-line quoted string "...\n..."?
/"/bdqstring
/"/bdqstr
# multi-line quoted string '...\n...'? (but not contraction in string "it's")
/'/{
/"[^'"]*'[^'"]*"/!bsqstring
/"[^'"]*'[^'"]*"/!bsqstr
}
:folded
# here-doc -- swallow it
@ -163,8 +163,8 @@ s/.*\n//
# before closing ")", "done", "elsif", "else", or "fi" will need to be
# re-visited to drop "suspect" marking since final line of those constructs
# legitimately lacks "&&", so "suspect" mark must be removed
/^[ ]*#/bnextline
/^[ ]*$/bnextline
/^[ ]*#/bnextln
/^[ ]*$/bnextln
# in-line comment -- strip it (but not "#" in a string, Bash ${#...} array
# length, or Perforce "//depot/path#42" revision in filespec)
/[ ]#/{
@ -175,22 +175,22 @@ s/.*\n//
# multi-line "case ... esac"
/^[ ]*case[ ]..*[ ]in/bcase
# multi-line "for ... done" or "while ... done"
/^[ ]*for[ ]..*[ ]in/bcontinue
/^[ ]*while[ ]/bcontinue
/^[ ]*do[ ]/bcontinue
/^[ ]*do[ ]*$/bcontinue
/;[ ]*do/bcontinue
/^[ ]*for[ ]..*[ ]in/bcont
/^[ ]*while[ ]/bcont
/^[ ]*do[ ]/bcont
/^[ ]*do[ ]*$/bcont
/;[ ]*do/bcont
/^[ ]*done[ ]*&&[ ]*$/bdone
/^[ ]*done[ ]*$/bdone
/^[ ]*done[ ]*[<>|]/bdone
/^[ ]*done[ ]*)/bdone
/||[ ]*exit[ ]/bcontinue
/||[ ]*exit[ ]*$/bcontinue
/||[ ]*exit[ ]/bcont
/||[ ]*exit[ ]*$/bcont
# multi-line "if...elsif...else...fi"
/^[ ]*if[ ]/bcontinue
/^[ ]*then[ ]/bcontinue
/^[ ]*then[ ]*$/bcontinue
/;[ ]*then/bcontinue
/^[ ]*if[ ]/bcont
/^[ ]*then[ ]/bcont
/^[ ]*then[ ]*$/bcont
/;[ ]*then/bcont
/^[ ]*elif[ ]/belse
/^[ ]*elif[ ]*$/belse
/^[ ]*else[ ]/belse
@ -234,10 +234,10 @@ s/.*\n//
}
}
# line ends with pipe "...|" -- valid; not missing "&&"
/|[ ]*$/bcontinue
/|[ ]*$/bcont
# missing end-of-line "&&" -- mark suspect
/&&[ ]*$/!s/^/?!AMP?!/
:continue
:cont
# retrieve and print previous line
x
n
@ -250,7 +250,7 @@ s/\\\n//
bslurp
# check for multi-line double-quoted string "...\n..." -- fold to one line
:dqstring
:dqstr
# remove all quote pairs
s/"\([^"]*\)"/@!\1@!/g
# done if no dangling quote
@ -258,13 +258,13 @@ s/"\([^"]*\)"/@!\1@!/g
# otherwise, slurp next line and try again
N
s/\n//
bdqstring
bdqstr
:dqdone
s/@!/"/g
bfolded
# check for multi-line single-quoted string '...\n...' -- fold to one line
:sqstring
:sqstr
# remove all quote pairs
s/'\([^']*\)'/@!\1@!/g
# done if no dangling quote
@ -272,7 +272,7 @@ s/'\([^']*\)'/@!\1@!/g
# otherwise, slurp next line and try again
N
s/\n//
bsqstring
bsqstr
:sqdone
s/@!/'/g
bfolded
@ -282,11 +282,11 @@ bfolded
:heredoc
s/^\(.*\)<<[ ]*[-\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1<</
s/[ ]*<<//
:heredsub
:hdocsub
N
/^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{
s/\n.*$//
bheredsub
bhdocsub
}
s/^<[^>]*>//
s/\n.*$//
@ -305,7 +305,7 @@ bcase
x
s/?!AMP?!//
x
bcontinue
bcont
# found "done" closing for-loop or while-loop, or "fi" closing if-then -- drop
# "suspect" from final contained line since that line legitimately lacks "&&"
@ -321,10 +321,10 @@ bchkchn
# found nested multi-line "(...\n...)" -- pass through untouched
:nest
x
:nstslurp
:nstslrp
n
# closing ")" on own line -- stop nested slurp
/^[ ]*)/bnstclose
/^[ ]*)/bnstcl
# comment -- not closing ")" if in comment
/^[ ]*#/bnstcnt
# "$((...))" -- arithmetic expansion; not closing ")"
@ -332,11 +332,11 @@ n
# "$(...)" -- command substitution; not closing ")"
/\$([^)][^)]*)[^)]*$/bnstcnt
# closing "...)" -- stop nested slurp
/)/bnstclose
/)/bnstcl
:nstcnt
x
bnstslurp
:nstclose
bnstslrp
:nstcl
s/^/>>/
# is it "))" which closes nested and parent subshells?
/)[ ]*)/bslurp

View file

@ -46,7 +46,7 @@ while (<>) {
/(?:\$\(seq|^\s*seq\b)/ and err 'seq is not portable (use test_seq)';
/\bgrep\b.*--file\b/ and err 'grep --file FILE is not portable (use grep -f FILE)';
/\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)';
/^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
/^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
err '"FOO=bar shell_func" assignment extends beyond "shell_func"';
$line = '';
# this resets our $. for each file

View file

@ -58,10 +58,11 @@ gitweb_run () {
GATEWAY_INTERFACE='CGI/1.1'
HTTP_ACCEPT='*/*'
REQUEST_METHOD='GET'
QUERY_STRING=""$1""
PATH_INFO=""$2""
QUERY_STRING=$1
PATH_INFO=$2
REQUEST_URI=/gitweb.cgi$PATH_INFO
export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD \
QUERY_STRING PATH_INFO
QUERY_STRING PATH_INFO REQUEST_URI
GITWEB_CONFIG=$(pwd)/gitweb_config.perl
export GITWEB_CONFIG

View file

@ -1,5 +1,2 @@
*
!*.sh
!*.[ch]
!*.gitignore
/test-tool
/test-fake-ssh

22
third_party/git/t/helper/test-advise.c vendored Normal file
View file

@ -0,0 +1,22 @@
#include "test-tool.h"
#include "cache.h"
#include "advice.h"
#include "config.h"
int cmd__advise_if_enabled(int argc, const char **argv)
{
if (argc != 2)
die("usage: %s <advice>", argv[0]);
setup_git_directory();
git_config(git_default_config, NULL);
/*
* Any advice type can be used for testing, but NESTED_TAG was
* selected here and in t0018 where this command is being
* executed.
*/
advise_if_enabled(ADVICE_NESTED_TAG, argv[1]);
return 0;
}

97
third_party/git/t/helper/test-bloom.c vendored Normal file
View file

@ -0,0 +1,97 @@
#include "git-compat-util.h"
#include "bloom.h"
#include "test-tool.h"
#include "commit.h"
static struct bloom_filter_settings settings = DEFAULT_BLOOM_FILTER_SETTINGS;
static void add_string_to_filter(const char *data, struct bloom_filter *filter) {
struct bloom_key key;
int i;
fill_bloom_key(data, strlen(data), &key, &settings);
printf("Hashes:");
for (i = 0; i < settings.num_hashes; i++){
printf("0x%08x|", key.hashes[i]);
}
printf("\n");
add_key_to_filter(&key, filter, &settings);
}
static void print_bloom_filter(struct bloom_filter *filter) {
int i;
if (!filter) {
printf("No filter.\n");
return;
}
printf("Filter_Length:%d\n", (int)filter->len);
printf("Filter_Data:");
for (i = 0; i < filter->len; i++) {
printf("%02x|", filter->data[i]);
}
printf("\n");
}
static void get_bloom_filter_for_commit(const struct object_id *commit_oid)
{
struct commit *c;
struct bloom_filter *filter;
setup_git_directory();
c = lookup_commit(the_repository, commit_oid);
filter = get_or_compute_bloom_filter(the_repository, c, 1,
&settings,
NULL);
print_bloom_filter(filter);
}
static const char *bloom_usage = "\n"
" test-tool bloom get_murmur3 <string>\n"
" test-tool bloom generate_filter <string> [<string>...]\n"
" test-tool get_filter_for_commit <commit-hex>\n";
int cmd__bloom(int argc, const char **argv)
{
setup_git_directory();
if (argc < 2)
usage(bloom_usage);
if (!strcmp(argv[1], "get_murmur3")) {
uint32_t hashed;
if (argc < 3)
usage(bloom_usage);
hashed = murmur3_seeded(0, argv[2], strlen(argv[2]));
printf("Murmur3 Hash with seed=0:0x%08x\n", hashed);
}
if (!strcmp(argv[1], "generate_filter")) {
struct bloom_filter filter;
int i = 2;
filter.len = (settings.bits_per_entry + BITS_PER_WORD - 1) / BITS_PER_WORD;
filter.data = xcalloc(filter.len, sizeof(unsigned char));
if (argc - 1 < i)
usage(bloom_usage);
while (argv[i]) {
add_string_to_filter(argv[i], &filter);
i++;
}
print_bloom_filter(&filter);
}
if (!strcmp(argv[1], "get_filter_for_commit")) {
struct object_id oid;
const char *end;
if (argc < 3)
usage(bloom_usage);
if (parse_oid_hex(argv[2], &oid, &end))
die("cannot parse oid '%s'", argv[2]);
init_bloom_filters();
get_bloom_filter_for_commit(&oid);
}
return 0;
}

View file

@ -37,21 +37,6 @@
*
*/
static const char *scope_name(enum config_scope scope)
{
switch (scope) {
case CONFIG_SCOPE_SYSTEM:
return "system";
case CONFIG_SCOPE_GLOBAL:
return "global";
case CONFIG_SCOPE_REPO:
return "repo";
case CONFIG_SCOPE_CMDLINE:
return "cmdline";
default:
return "unknown";
}
}
static int iterate_cb(const char *var, const char *value, void *data)
{
static int nr;
@ -63,7 +48,8 @@ static int iterate_cb(const char *var, const char *value, void *data)
printf("value=%s\n", value ? value : "(null)");
printf("origin=%s\n", current_config_origin_type());
printf("name=%s\n", current_config_name());
printf("scope=%s\n", scope_name(current_config_scope()));
printf("lno=%d\n", current_config_line());
printf("scope=%s\n", config_scope_name(current_config_scope()));
return 0;
}
@ -140,7 +126,7 @@ int cmd__config(int argc, const char **argv)
goto exit1;
}
} else if (argc == 3 && !strcmp(argv[1], "get_string")) {
if (!git_config_get_string_const(argv[2], &v)) {
if (!git_config_get_string_tmp(argv[2], &v)) {
printf("%s\n", v);
goto exit0;
} else {

View file

@ -12,13 +12,13 @@ static const char *usage_msg = "\n"
" test-tool date is64bit\n"
" test-tool date time_t-is64bit\n";
static void show_relative_dates(const char **argv, struct timeval *now)
static void show_relative_dates(const char **argv)
{
struct strbuf buf = STRBUF_INIT;
for (; *argv; argv++) {
time_t t = atoi(*argv);
show_date_relative(t, now, &buf);
show_date_relative(t, &buf);
printf("%s -> %s\n", *argv, buf.buf);
}
strbuf_release(&buf);
@ -74,20 +74,20 @@ static void parse_dates(const char **argv)
strbuf_release(&result);
}
static void parse_approxidate(const char **argv, struct timeval *now)
static void parse_approxidate(const char **argv)
{
for (; *argv; argv++) {
timestamp_t t;
t = approxidate_relative(*argv, now);
t = approxidate_relative(*argv);
printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(ISO8601)));
}
}
static void parse_approx_timestamp(const char **argv, struct timeval *now)
static void parse_approx_timestamp(const char **argv)
{
for (; *argv; argv++) {
timestamp_t t;
t = approxidate_relative(*argv, now);
t = approxidate_relative(*argv);
printf("%s -> %"PRItime"\n", *argv, t);
}
}
@ -103,22 +103,13 @@ static void getnanos(const char **argv)
int cmd__date(int argc, const char **argv)
{
struct timeval now;
const char *x;
x = getenv("GIT_TEST_DATE_NOW");
if (x) {
now.tv_sec = atoi(x);
now.tv_usec = 0;
}
else
gettimeofday(&now, NULL);
argv++;
if (!*argv)
usage(usage_msg);
if (!strcmp(*argv, "relative"))
show_relative_dates(argv+1, &now);
show_relative_dates(argv+1);
else if (!strcmp(*argv, "human"))
show_human_dates(argv+1);
else if (skip_prefix(*argv, "show:", &x))
@ -126,9 +117,9 @@ int cmd__date(int argc, const char **argv)
else if (!strcmp(*argv, "parse"))
parse_dates(argv+1);
else if (!strcmp(*argv, "approxidate"))
parse_approxidate(argv+1, &now);
parse_approxidate(argv+1);
else if (!strcmp(*argv, "timestamp"))
parse_approx_timestamp(argv+1, &now);
parse_approx_timestamp(argv+1);
else if (!strcmp(*argv, "getnanos"))
getnanos(argv+1);
else if (!strcmp(*argv, "is64bit"))

View file

@ -8,18 +8,21 @@ static int cmd_sync(void)
{
char Buffer[MAX_PATH];
DWORD dwRet;
char szVolumeAccessPath[] = "\\\\.\\X:";
char szVolumeAccessPath[] = "\\\\.\\XXXX:";
HANDLE hVolWrite;
int success = 0;
int success = 0, dos_drive_prefix;
dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
if ((0 == dwRet) || (dwRet > MAX_PATH))
return error("Error getting current directory");
if (!has_dos_drive_prefix(Buffer))
dos_drive_prefix = has_dos_drive_prefix(Buffer);
if (!dos_drive_prefix)
return error("'%s': invalid drive letter", Buffer);
szVolumeAccessPath[4] = Buffer[0];
memcpy(szVolumeAccessPath, Buffer, dos_drive_prefix);
szVolumeAccessPath[dos_drive_prefix] = '\0';
hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == hVolWrite)

View file

@ -13,7 +13,7 @@ int cmd__dump_fsmonitor(int ac, const char **av)
printf("no fsmonitor\n");
return 0;
}
printf("fsmonitor last update %"PRIuMAX"\n", (uintmax_t)istate->fsmonitor_last_update);
printf("fsmonitor last update %s\n", istate->fsmonitor_last_update);
for (i = 0; i < istate->cache_nr; i++)
printf((istate->cache[i]->ce_flags & CE_FSMONITOR_VALID) ? "+" : "-");

View file

@ -13,6 +13,8 @@ int cmd__dump_split_index(int ac, const char **av)
struct split_index *si;
int i;
setup_git_directory();
do_read_index(&the_index, av[1], 1);
printf("own %s\n", oid_to_hex(&the_index.oid));
si = the_index.split_index;

View file

@ -5,6 +5,7 @@
struct test_entry
{
int padding; /* hashmap entry no longer needs to be the first member */
struct hashmap_entry ent;
/* key and value as two \0-terminated strings */
char key[FLEX_ARRAY];
@ -16,15 +17,17 @@ static const char *get_value(const struct test_entry *e)
}
static int test_entry_cmp(const void *cmp_data,
const void *entry,
const void *entry_or_key,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
{
const int ignore_case = cmp_data ? *((int *)cmp_data) : 0;
const struct test_entry *e1 = entry;
const struct test_entry *e2 = entry_or_key;
const struct test_entry *e1, *e2;
const char *key = keydata;
e1 = container_of(eptr, const struct test_entry, ent);
e2 = container_of(entry_or_key, const struct test_entry, ent);
if (ignore_case)
return strcasecmp(e1->key, key ? key : e2->key);
else
@ -37,7 +40,7 @@ static struct test_entry *alloc_test_entry(unsigned int hash,
size_t klen = strlen(key);
size_t vlen = strlen(value);
struct test_entry *entry = xmalloc(st_add4(sizeof(*entry), klen, vlen, 2));
hashmap_entry_init(entry, hash);
hashmap_entry_init(&entry->ent, hash);
memcpy(entry->key, key, klen + 1);
memcpy(entry->key + klen + 1, value, vlen + 1);
return entry;
@ -103,11 +106,11 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
/* add entries */
for (i = 0; i < TEST_SIZE; i++) {
hashmap_entry_init(entries[i], hashes[i]);
hashmap_add(&map, entries[i]);
hashmap_entry_init(&entries[i]->ent, hashes[i]);
hashmap_add(&map, &entries[i]->ent);
}
hashmap_free(&map, 0);
hashmap_free(&map);
}
} else {
/* test map lookups */
@ -116,8 +119,8 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
/* fill the map (sparsely if specified) */
j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
for (i = 0; i < j; i++) {
hashmap_entry_init(entries[i], hashes[i]);
hashmap_add(&map, entries[i]);
hashmap_entry_init(&entries[i]->ent, hashes[i]);
hashmap_add(&map, &entries[i]->ent);
}
for (j = 0; j < rounds; j++) {
@ -127,7 +130,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
}
}
hashmap_free(&map, 0);
hashmap_free(&map);
}
}
@ -179,7 +182,7 @@ int cmd__hashmap(int argc, const char **argv)
entry = alloc_test_entry(hash, p1, p2);
/* add to hashmap */
hashmap_add(&map, entry);
hashmap_add(&map, &entry->ent);
} else if (!strcmp("put", cmd) && p1 && p2) {
@ -187,43 +190,44 @@ int cmd__hashmap(int argc, const char **argv)
entry = alloc_test_entry(hash, p1, p2);
/* add / replace entry */
entry = hashmap_put(&map, entry);
entry = hashmap_put_entry(&map, entry, ent);
/* print and free replaced entry, if any */
puts(entry ? get_value(entry) : "NULL");
free(entry);
} else if (!strcmp("get", cmd) && p1) {
/* lookup entry in hashmap */
entry = hashmap_get_from_hash(&map, hash, p1);
entry = hashmap_get_entry_from_hash(&map, hash, p1,
struct test_entry, ent);
/* print result */
if (!entry)
puts("NULL");
while (entry) {
hashmap_for_each_entry_from(&map, entry, ent)
puts(get_value(entry));
entry = hashmap_get_next(&map, entry);
}
} else if (!strcmp("remove", cmd) && p1) {
/* setup static key */
struct hashmap_entry key;
struct hashmap_entry *rm;
hashmap_entry_init(&key, hash);
/* remove entry from hashmap */
entry = hashmap_remove(&map, &key, p1);
rm = hashmap_remove(&map, &key, p1);
entry = rm ? container_of(rm, struct test_entry, ent)
: NULL;
/* print result and free entry*/
puts(entry ? get_value(entry) : "NULL");
free(entry);
} else if (!strcmp("iterate", cmd)) {
struct hashmap_iter iter;
hashmap_iter_init(&map, &iter);
while ((entry = hashmap_iter_next(&iter)))
hashmap_for_each_entry(&map, &iter, entry,
ent /* member name */)
printf("%s %s\n", entry->key, get_value(entry));
} else if (!strcmp("size", cmd)) {
@ -258,6 +262,6 @@ int cmd__hashmap(int argc, const char **argv)
}
strbuf_release(&line);
hashmap_free(&map, 1);
hashmap_free_entries(&map, struct test_entry, ent);
return 0;
}

View file

@ -41,17 +41,13 @@ static void dump_run(void)
die("non-threaded code path used");
}
dir = hashmap_iter_first(&the_index.dir_hash, &iter_dir);
while (dir) {
hashmap_for_each_entry(&the_index.dir_hash, &iter_dir, dir,
ent /* member name */)
printf("dir %08x %7d %s\n", dir->ent.hash, dir->nr, dir->name);
dir = hashmap_iter_next(&iter_dir);
}
ce = hashmap_iter_first(&the_index.name_hash, &iter_cache);
while (ce) {
hashmap_for_each_entry(&the_index.name_hash, &iter_cache, ce,
ent /* member name */)
printf("name %08x %s\n", ce->ent.hash, ce->name);
ce = hashmap_iter_next(&iter_cache);
}
discard_cache();
}

View file

@ -1,81 +0,0 @@
/*
* test-line-buffer.c: code to exercise the svn importer's input helper
*/
#include "git-compat-util.h"
#include "strbuf.h"
#include "vcs-svn/line_buffer.h"
static uint32_t strtouint32(const char *s)
{
char *end;
uintmax_t n = strtoumax(s, &end, 10);
if (*s == '\0' || *end != '\0')
die("invalid count: %s", s);
return (uint32_t) n;
}
static void handle_command(const char *command, const char *arg, struct line_buffer *buf)
{
if (starts_with(command, "binary ")) {
struct strbuf sb = STRBUF_INIT;
strbuf_addch(&sb, '>');
buffer_read_binary(buf, &sb, strtouint32(arg));
fwrite(sb.buf, 1, sb.len, stdout);
strbuf_release(&sb);
} else if (starts_with(command, "copy ")) {
buffer_copy_bytes(buf, strtouint32(arg));
} else if (starts_with(command, "skip ")) {
buffer_skip_bytes(buf, strtouint32(arg));
} else {
die("unrecognized command: %s", command);
}
}
static void handle_line(const char *line, struct line_buffer *stdin_buf)
{
const char *arg = strchr(line, ' ');
if (!arg)
die("no argument in line: %s", line);
handle_command(line, arg + 1, stdin_buf);
}
int cmd_main(int argc, const char **argv)
{
struct line_buffer stdin_buf = LINE_BUFFER_INIT;
struct line_buffer file_buf = LINE_BUFFER_INIT;
struct line_buffer *input = &stdin_buf;
const char *filename;
char *s;
if (argc == 1)
filename = NULL;
else if (argc == 2)
filename = argv[1];
else
usage("test-line-buffer [file | &fd] < script");
if (buffer_init(&stdin_buf, NULL))
die_errno("open error");
if (filename) {
if (*filename == '&') {
if (buffer_fdinit(&file_buf, strtouint32(filename + 1)))
die_errno("error opening fd %s", filename + 1);
} else {
if (buffer_init(&file_buf, filename))
die_errno("error opening %s", filename);
}
input = &file_buf;
}
while ((s = buffer_read_line(&stdin_buf)))
handle_line(s, input);
if (filename && buffer_deinit(&file_buf))
die("error reading from %s", filename);
if (buffer_deinit(&stdin_buf))
die("input error");
if (ferror(stdout))
die("output error");
return 0;
}

View file

@ -1,6 +1,6 @@
#include "test-tool.h"
#include "cache.h"
#include "sha1-array.h"
#include "oid-array.h"
static int print_oid(const struct object_id *oid, void *data)
{
@ -8,10 +8,13 @@ static int print_oid(const struct object_id *oid, void *data)
return 0;
}
int cmd__sha1_array(int argc, const char **argv)
int cmd__oid_array(int argc, const char **argv)
{
struct oid_array array = OID_ARRAY_INIT;
struct strbuf line = STRBUF_INIT;
int nongit_ok;
setup_git_directory_gently(&nongit_ok);
while (strbuf_getline(&line, stdin) != EOF) {
const char *arg;
@ -19,11 +22,11 @@ int cmd__sha1_array(int argc, const char **argv)
if (skip_prefix(line.buf, "append ", &arg)) {
if (get_oid_hex(arg, &oid))
die("not a hexadecimal SHA1: %s", arg);
die("not a hexadecimal oid: %s", arg);
oid_array_append(&array, &oid);
} else if (skip_prefix(line.buf, "lookup ", &arg)) {
if (get_oid_hex(arg, &oid))
die("not a hexadecimal SHA1: %s", arg);
die("not a hexadecimal oid: %s", arg);
printf("%d\n", oid_array_lookup(&array, &oid));
} else if (!strcmp(line.buf, "clear"))
oid_array_clear(&array);

View file

@ -121,6 +121,8 @@ int cmd__parse_options(int argc, const char **argv)
OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
OPT_MAGNITUDE('m', "magnitude", &magnitude, "get a magnitude"),
OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
OPT_CMDMODE(0, "mode1", &integer, "set integer to 1 (cmdmode option)", 1),
OPT_CMDMODE(0, "mode2", &integer, "set integer to 2 (cmdmode option)", 2),
OPT_CALLBACK('L', "length", &integer, "str",
"get length of <str>", length_callback),
OPT_FILENAME('F', "file", &file, "set file to <file>"),

View file

@ -0,0 +1,33 @@
#include "test-tool.h"
#include "parse-options.h"
#include "pathspec.h"
#include "gettext.h"
int cmd__parse_pathspec_file(int argc, const char **argv)
{
struct pathspec pathspec;
const char *pathspec_from_file = NULL;
int pathspec_file_nul = 0, i;
static const char *const usage[] = {
"test-tool parse-pathspec-file --pathspec-from-file [--pathspec-file-nul]",
NULL
};
struct option options[] = {
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
OPT_END()
};
parse_options(argc, argv, NULL, options, usage, 0);
parse_pathspec_file(&pathspec, 0, 0, NULL, pathspec_from_file,
pathspec_file_nul);
for (i = 0; i < pathspec.nr; i++)
printf("%s\n", pathspec.items[i].original);
clear_pathspec(&pathspec);
return 0;
}

View file

@ -185,6 +185,99 @@ static int cmp_by_st_size(const void *a, const void *b)
return x > y ? -1 : (x < y ? +1 : 0);
}
/*
* A very simple, reproducible pseudo-random generator. Copied from
* `test-genrandom.c`.
*/
static uint64_t my_random_value = 1234;
static uint64_t my_random(void)
{
my_random_value = my_random_value * 1103515245 + 12345;
return my_random_value;
}
/*
* A fast approximation of the square root, without requiring math.h.
*
* It uses Newton's method to approximate the solution of 0 = x^2 - value.
*/
static double my_sqrt(double value)
{
const double epsilon = 1e-6;
double x = value;
if (value == 0)
return 0;
for (;;) {
double delta = (value / x - x) / 2;
if (delta < epsilon && delta > -epsilon)
return x + delta;
x += delta;
}
}
static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
{
size_t i, j, nr, min_len = 3, max_len = 20;
char **names;
int repetitions = 15, file_mode = 0100644;
uint64_t begin, end;
double m[3][2], v[3][2];
uint64_t cumul;
double cumul2;
if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) {
file_mode = 0120000;
argc--;
argv++;
}
nr = argc > 1 ? strtoul(argv[1], NULL, 0) : 1000000;
ALLOC_ARRAY(names, nr);
if (argc > 2) {
min_len = strtoul(argv[2], NULL, 0);
if (argc > 3)
max_len = strtoul(argv[3], NULL, 0);
if (min_len > max_len)
die("min_len > max_len");
}
for (i = 0; i < nr; i++) {
size_t len = min_len + (my_random() % (max_len + 1 - min_len));
names[i] = xmallocz(len);
while (len > 0)
names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' ')));
}
for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) {
cumul = 0;
cumul2 = 0;
for (i = 0; i < repetitions; i++) {
begin = getnanotime();
for (j = 0; j < nr; j++)
verify_path(names[j], file_mode);
end = getnanotime();
printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6);
cumul += end - begin;
cumul2 += (end - begin) * (end - begin);
}
m[protect_ntfs][protect_hfs] = cumul / (double)repetitions;
v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]);
printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6);
}
for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
for (protect_hfs = 0; protect_hfs < 2; protect_hfs++)
printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]);
return 0;
}
int cmd__path_utils(int argc, const char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@ -197,11 +290,14 @@ int cmd__path_utils(int argc, const char **argv)
}
if (argc >= 2 && !strcmp(argv[1], "real_path")) {
struct strbuf realpath = STRBUF_INIT;
while (argc > 2) {
puts(real_path(argv[2]));
strbuf_realpath(&realpath, argv[2], 1);
puts(realpath.buf);
argc--;
argv++;
}
strbuf_release(&realpath);
return 0;
}
@ -355,6 +451,26 @@ int cmd__path_utils(int argc, const char **argv)
return !!res;
}
if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs"))
return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1);
if (argc > 1 && !strcmp(argv[1], "is_valid_path")) {
int res = 0, expect = 1, i;
for (i = 2; i < argc; i++)
if (!strcmp("--not", argv[i]))
expect = 0;
else if (expect != is_valid_path(argv[i]))
res = error("'%s' is%s a valid path",
argv[i], expect ? " not" : "");
else
fprintf(stderr,
"'%s' is%s a valid path\n",
argv[i], expect ? "" : " not");
return !!res;
}
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;

View file

@ -46,6 +46,9 @@ static void unpack(void)
case PACKET_READ_DELIM:
printf("0001\n");
break;
case PACKET_READ_RESPONSE_END:
printf("0002\n");
break;
}
}
}
@ -67,7 +70,7 @@ static void unpack_sideband(void)
case PACKET_READ_NORMAL:
band = reader.line[0] & 0xff;
if (band < 1 || band > 2)
die("unexpected side band %d", band);
continue; /* skip non-sideband packets */
fd = band;
write_or_die(fd, reader.line + 1, reader.pktlen - 1);
@ -75,6 +78,7 @@ static void unpack_sideband(void)
case PACKET_READ_FLUSH:
return;
case PACKET_READ_DELIM:
case PACKET_READ_RESPONSE_END:
break;
}
}

View file

@ -0,0 +1,176 @@
#include "cache.h"
#include "connect.h"
#include "parse-options.h"
#include "pkt-line.h"
#include "sigchain.h"
#include "test-tool.h"
static const char *proc_receive_usage[] = {
"test-tool proc-receive [<options>...]",
NULL
};
static int die_version;
static int die_readline;
static int no_push_options;
static int use_atomic;
static int use_push_options;
static int verbose;
static int version = 1;
static struct string_list returns = STRING_LIST_INIT_NODUP;
struct command {
struct command *next;
const char *error_string;
unsigned int skip_update:1,
did_not_exist:1;
int index;
struct object_id old_oid;
struct object_id new_oid;
char ref_name[FLEX_ARRAY]; /* more */
};
static void proc_receive_verison(struct packet_reader *reader) {
int server_version = 0;
for (;;) {
int linelen;
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
break;
if (reader->pktlen > 8 && starts_with(reader->line, "version=")) {
server_version = atoi(reader->line+8);
linelen = strlen(reader->line);
if (linelen < reader->pktlen) {
const char *feature_list = reader->line + linelen + 1;
if (parse_feature_request(feature_list, "atomic"))
use_atomic= 1;
if (parse_feature_request(feature_list, "push-options"))
use_push_options = 1;
}
}
}
if (server_version != 1 || die_version)
die("bad protocol version: %d", server_version);
packet_write_fmt(1, "version=%d%c%s\n",
version, '\0',
use_push_options && !no_push_options ? "push-options": "");
packet_flush(1);
}
static void proc_receive_read_commands(struct packet_reader *reader,
struct command **commands)
{
struct command **tail = commands;
for (;;) {
struct object_id old_oid, new_oid;
struct command *cmd;
const char *refname;
const char *p;
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
break;
if (parse_oid_hex(reader->line, &old_oid, &p) ||
*p++ != ' ' ||
parse_oid_hex(p, &new_oid, &p) ||
*p++ != ' ' ||
die_readline)
die("protocol error: expected 'old new ref', got '%s'",
reader->line);
refname = p;
FLEX_ALLOC_STR(cmd, ref_name, refname);
oidcpy(&cmd->old_oid, &old_oid);
oidcpy(&cmd->new_oid, &new_oid);
*tail = cmd;
tail = &cmd->next;
}
}
static void proc_receive_read_push_options(struct packet_reader *reader,
struct string_list *options)
{
if (no_push_options || !use_push_options)
return;
while (1) {
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
break;
string_list_append(options, reader->line);
}
}
int cmd__proc_receive(int argc, const char **argv)
{
int nongit_ok = 0;
struct packet_reader reader;
struct command *commands = NULL;
struct string_list push_options = STRING_LIST_INIT_DUP;
struct string_list_item *item;
struct option options[] = {
OPT_BOOL(0, "no-push-options", &no_push_options,
"disable push options"),
OPT_BOOL(0, "die-version", &die_version,
"die during version negotiation"),
OPT_BOOL(0, "die-readline", &die_readline,
"die when readline"),
OPT_STRING_LIST('r', "return", &returns, "old/new/ref/status/msg",
"return of results"),
OPT__VERBOSE(&verbose, "be verbose"),
OPT_INTEGER('V', "version", &version,
"use this protocol version number"),
OPT_END()
};
setup_git_directory_gently(&nongit_ok);
argc = parse_options(argc, argv, "test-tools", options, proc_receive_usage, 0);
if (argc > 0)
usage_msg_opt("Too many arguments.", proc_receive_usage, options);
packet_reader_init(&reader, 0, NULL, 0,
PACKET_READ_CHOMP_NEWLINE |
PACKET_READ_DIE_ON_ERR_PACKET);
sigchain_push(SIGPIPE, SIG_IGN);
proc_receive_verison(&reader);
proc_receive_read_commands(&reader, &commands);
proc_receive_read_push_options(&reader, &push_options);
if (verbose) {
struct command *cmd;
if (use_push_options || use_atomic)
fprintf(stderr, "proc-receive:%s%s\n",
use_atomic? " atomic": "",
use_push_options ? " push_options": "");
for (cmd = commands; cmd; cmd = cmd->next)
fprintf(stderr, "proc-receive< %s %s %s\n",
oid_to_hex(&cmd->old_oid),
oid_to_hex(&cmd->new_oid),
cmd->ref_name);
if (push_options.nr > 0)
for_each_string_list_item(item, &push_options)
fprintf(stderr, "proc-receive< %s\n", item->string);
if (returns.nr)
for_each_string_list_item(item, &returns)
fprintf(stderr, "proc-receive> %s\n", item->string);
}
if (returns.nr)
for_each_string_list_item(item, &returns)
packet_write_fmt(1, "%s\n", item->string);
packet_flush(1);
sigchain_pop(SIGPIPE);
return 0;
}

View file

@ -0,0 +1,74 @@
/*
* A test helper to exercise the progress display.
*
* Reads instructions from standard input, one instruction per line:
*
* "progress <items>" - Call display_progress() with the given item count
* as parameter.
* "throughput <bytes> <millis> - Call display_throughput() with the given
* byte count as parameter. The 'millis'
* specify the time elapsed since the
* start_progress() call.
* "update" - Set the 'progress_update' flag.
*
* See 't0500-progress-display.sh' for examples.
*/
#define GIT_TEST_PROGRESS_ONLY
#include "test-tool.h"
#include "gettext.h"
#include "parse-options.h"
#include "progress.h"
#include "strbuf.h"
int cmd__progress(int argc, const char **argv)
{
int total = 0;
const char *title;
struct strbuf line = STRBUF_INIT;
struct progress *progress;
const char *usage[] = {
"test-tool progress [--total=<n>] <progress-title>",
NULL
};
struct option options[] = {
OPT_INTEGER(0, "total", &total, "total number of items"),
OPT_END(),
};
argc = parse_options(argc, argv, NULL, options, usage, 0);
if (argc != 1)
die("need a title for the progress output");
title = argv[0];
progress_testing = 1;
progress = start_progress(title, total);
while (strbuf_getline(&line, stdin) != EOF) {
char *end;
if (skip_prefix(line.buf, "progress ", (const char **) &end)) {
uint64_t item_count = strtoull(end, &end, 10);
if (*end != '\0')
die("invalid input: '%s'\n", line.buf);
display_progress(progress, item_count);
} else if (skip_prefix(line.buf, "throughput ",
(const char **) &end)) {
uint64_t byte_count, test_ms;
byte_count = strtoull(end, &end, 10);
if (*end != ' ')
die("invalid input: '%s'\n", line.buf);
test_ms = strtoull(end + 1, &end, 10);
if (*end != '\0')
die("invalid input: '%s'\n", line.buf);
progress_test_ns = test_ms * 1000 * 1000;
display_throughput(progress, byte_count);
} else if (!strcmp(line.buf, "update"))
progress_test_force_update();
else
die("invalid input: '%s'\n", line.buf);
}
stop_progress(&progress);
return 0;
}

View file

@ -67,7 +67,7 @@ int cmd__reach(int ac, const char **av)
die("failed to load commit for input %s resulting in oid %s\n",
buf.buf, oid_to_hex(&oid));
c = object_as_type(r, peeled, OBJ_COMMIT, 0);
c = object_as_type(peeled, OBJ_COMMIT, 0);
if (!c)
die("failed to load commit for input %s resulting in oid %s\n",
@ -107,8 +107,10 @@ int cmd__reach(int ac, const char **av)
printf("%s(A,B):%d\n", av[1], ref_newer(&oid_A, &oid_B));
else if (!strcmp(av[1], "in_merge_bases"))
printf("%s(A,B):%d\n", av[1], in_merge_bases(A, B));
else if (!strcmp(av[1], "in_merge_bases_many"))
printf("%s(A,X):%d\n", av[1], in_merge_bases_many(A, X_nr, X_array));
else if (!strcmp(av[1], "is_descendant_of"))
printf("%s(A,X):%d\n", av[1], is_descendant_of(A, X));
printf("%s(A,X):%d\n", av[1], repo_is_descendant_of(r, A, X));
else if (!strcmp(av[1], "get_merge_bases_many")) {
struct commit_list *list = get_merge_bases_many(A, X_nr, X_array);
printf("%s(A,X):\n", av[1]);

View file

@ -4,11 +4,10 @@
int cmd__read_cache(int argc, const char **argv)
{
int i, cnt = 1, namelen;
int i, cnt = 1;
const char *name = NULL;
if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) {
namelen = strlen(name);
argc--;
argv++;
}
@ -24,7 +23,7 @@ int cmd__read_cache(int argc, const char **argv)
refresh_index(&the_index, REFRESH_QUIET,
NULL, NULL, NULL);
pos = index_name_pos(&the_index, name, namelen);
pos = index_name_pos(&the_index, name, strlen(name));
if (pos < 0)
die("%s not in index", name);
printf("%s is%s up to date\n", name,

View file

@ -0,0 +1,47 @@
#include "test-tool.h"
#include "cache.h"
#include "commit-graph.h"
#include "repository.h"
#include "object-store.h"
int cmd__read_graph(int argc, const char **argv)
{
struct commit_graph *graph = NULL;
struct object_directory *odb;
setup_git_directory();
odb = the_repository->objects->odb;
prepare_repo_settings(the_repository);
graph = read_commit_graph_one(the_repository, odb);
if (!graph)
return 1;
printf("header: %08x %d %d %d %d\n",
ntohl(*(uint32_t*)graph->data),
*(unsigned char*)(graph->data + 4),
*(unsigned char*)(graph->data + 5),
*(unsigned char*)(graph->data + 6),
*(unsigned char*)(graph->data + 7));
printf("num_commits: %u\n", graph->num_commits);
printf("chunks:");
if (graph->chunk_oid_fanout)
printf(" oid_fanout");
if (graph->chunk_oid_lookup)
printf(" oid_lookup");
if (graph->chunk_commit_data)
printf(" commit_metadata");
if (graph->chunk_extra_edges)
printf(" extra_edges");
if (graph->chunk_bloom_indexes)
printf(" bloom_indexes");
if (graph->chunk_bloom_data)
printf(" bloom_data");
printf("\n");
UNLEAK(graph);
return 0;
}

View file

@ -7,14 +7,18 @@
static int read_midx_file(const char *object_dir)
{
uint32_t i;
struct multi_pack_index *m = load_multi_pack_index(object_dir, 1);
struct multi_pack_index *m;
setup_git_directory();
m = load_multi_pack_index(object_dir, 1);
if (!m)
return 1;
printf("header: %08x %d %d %d\n",
printf("header: %08x %d %d %d %d\n",
m->signature,
m->version,
m->hash_len,
m->num_chunks,
m->num_packs);

View file

@ -37,7 +37,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
*refs = get_submodule_ref_store(gitdir);
} else if (skip_prefix(argv[0], "worktree:", &gitdir)) {
struct worktree **p, **worktrees = get_worktrees(0);
struct worktree **p, **worktrees = get_worktrees();
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;

View file

@ -1,5 +1,4 @@
#include "test-tool.h"
#include "git-compat-util.h"
#include "gettext.h"
struct reg_flag {
@ -8,12 +7,13 @@ struct reg_flag {
};
static struct reg_flag reg_flags[] = {
{ "EXTENDED", REG_EXTENDED },
{ "NEWLINE", REG_NEWLINE },
{ "ICASE", REG_ICASE },
{ "NOTBOL", REG_NOTBOL },
{ "EXTENDED", REG_EXTENDED },
{ "NEWLINE", REG_NEWLINE },
{ "ICASE", REG_ICASE },
{ "NOTBOL", REG_NOTBOL },
{ "NOTEOL", REG_NOTEOL },
#ifdef REG_STARTEND
{ "STARTEND", REG_STARTEND },
{ "STARTEND", REG_STARTEND },
#endif
{ NULL, 0 }
};
@ -41,36 +41,74 @@ int cmd__regex(int argc, const char **argv)
{
const char *pat;
const char *str;
int flags = 0;
int ret, silent = 0, flags = 0;
regex_t r;
regmatch_t m[1];
if (argc == 2 && !strcmp(argv[1], "--bug"))
return test_regex_bug();
else if (argc < 3)
usage("test-tool regex --bug\n"
"test-tool regex <pattern> <string> [<options>]");
char errbuf[64];
argv++;
pat = *argv++;
str = *argv++;
while (*argv) {
struct reg_flag *rf;
for (rf = reg_flags; rf->name; rf++)
if (!strcmp(*argv, rf->name)) {
flags |= rf->flag;
break;
}
if (!rf->name)
die("do not recognize %s", *argv);
argc--;
if (!argc)
goto usage;
if (!strcmp(*argv, "--bug")) {
if (argc == 1)
return test_regex_bug();
else
goto usage;
}
if (!strcmp(*argv, "--silent")) {
silent = 1;
argv++;
argc--;
}
if (!argc)
goto usage;
pat = *argv++;
if (argc == 1)
str = NULL;
else {
str = *argv++;
while (*argv) {
struct reg_flag *rf;
for (rf = reg_flags; rf->name; rf++)
if (!strcmp(*argv, rf->name)) {
flags |= rf->flag;
break;
}
if (!rf->name)
die("do not recognize flag %s", *argv);
argv++;
}
}
git_setup_gettext();
if (regcomp(&r, pat, flags))
die("failed regcomp() for pattern '%s'", pat);
if (regexec(&r, str, 1, m, 0))
return 1;
ret = regcomp(&r, pat, flags);
if (ret) {
if (silent)
return ret;
regerror(ret, &r, errbuf, sizeof(errbuf));
die("failed regcomp() for pattern '%s' (%s)", pat, errbuf);
}
if (!str)
return 0;
ret = regexec(&r, str, 1, m, 0);
if (ret) {
if (silent || ret == REG_NOMATCH)
return ret;
regerror(ret, &r, errbuf, sizeof(errbuf));
die("failed regexec() for subject '%s' (%s)", str, errbuf);
}
return 0;
usage:
usage("\ttest-tool regex --bug\n"
"\ttest-tool regex [--silent] <pattern>\n"
"\ttest-tool regex [--silent] <pattern> <string> [<options>]");
return -1;
}

View file

@ -19,12 +19,11 @@ static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
memset(the_repository, 0, sizeof(*the_repository));
/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");
repo_set_hash_algo(the_repository, hash_algo_by_ptr(r.hash_algo));
c = lookup_commit(&r, commit_oid);
if (!parse_commit_in_graph(&r, c))
@ -50,12 +49,11 @@ static void test_get_commit_tree_in_graph(const char *gitdir,
memset(the_repository, 0, sizeof(*the_repository));
/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");
repo_set_hash_algo(the_repository, hash_algo_by_ptr(r.hash_algo));
c = lookup_commit(&r, commit_oid);
/*
@ -75,6 +73,10 @@ static void test_get_commit_tree_in_graph(const char *gitdir,
int cmd__repository(int argc, const char **argv)
{
int nongit_ok = 0;
setup_git_directory_gently(&nongit_ok);
if (argc < 2)
die("must have at least 2 arguments");
if (!strcmp(argv[1], "parse_commit_in_graph")) {

View file

@ -10,11 +10,16 @@
#include "test-tool.h"
#include "git-compat-util.h"
#include "cache.h"
#include "run-command.h"
#include "argv-array.h"
#include "strvec.h"
#include "strbuf.h"
#include <string.h>
#include <errno.h>
#include "parse-options.h"
#include "string-list.h"
#include "thread-utils.h"
#include "wildmatch.h"
#include "gettext.h"
#include "parse-options.h"
static int number_callbacks;
static int parallel_next(struct child_process *cp,
@ -26,7 +31,7 @@ static int parallel_next(struct child_process *cp,
if (number_callbacks >= 4)
return 0;
argv_array_pushv(&cp->args, d->argv);
strvec_pushv(&cp->args, d->argv);
strbuf_addstr(err, "preloaded output of a child\n");
number_callbacks++;
return 1;
@ -50,17 +55,343 @@ static int task_finished(int result,
return 1;
}
struct testsuite {
struct string_list tests, failed;
int next;
int quiet, immediate, verbose, verbose_log, trace, write_junit_xml;
};
#define TESTSUITE_INIT \
{ STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, -1, 0, 0, 0, 0, 0, 0 }
static int next_test(struct child_process *cp, struct strbuf *err, void *cb,
void **task_cb)
{
struct testsuite *suite = cb;
const char *test;
if (suite->next >= suite->tests.nr)
return 0;
test = suite->tests.items[suite->next++].string;
strvec_pushl(&cp->args, "sh", test, NULL);
if (suite->quiet)
strvec_push(&cp->args, "--quiet");
if (suite->immediate)
strvec_push(&cp->args, "-i");
if (suite->verbose)
strvec_push(&cp->args, "-v");
if (suite->verbose_log)
strvec_push(&cp->args, "-V");
if (suite->trace)
strvec_push(&cp->args, "-x");
if (suite->write_junit_xml)
strvec_push(&cp->args, "--write-junit-xml");
strbuf_addf(err, "Output of '%s':\n", test);
*task_cb = (void *)test;
return 1;
}
static int test_finished(int result, struct strbuf *err, void *cb,
void *task_cb)
{
struct testsuite *suite = cb;
const char *name = (const char *)task_cb;
if (result)
string_list_append(&suite->failed, name);
strbuf_addf(err, "%s: '%s'\n", result ? "FAIL" : "SUCCESS", name);
return 0;
}
static int test_failed(struct strbuf *out, void *cb, void *task_cb)
{
struct testsuite *suite = cb;
const char *name = (const char *)task_cb;
string_list_append(&suite->failed, name);
strbuf_addf(out, "FAILED TO START: '%s'\n", name);
return 0;
}
static const char * const testsuite_usage[] = {
"test-run-command testsuite [<options>] [<pattern>...]",
NULL
};
static int testsuite(int argc, const char **argv)
{
struct testsuite suite = TESTSUITE_INIT;
int max_jobs = 1, i, ret;
DIR *dir;
struct dirent *d;
struct option options[] = {
OPT_BOOL('i', "immediate", &suite.immediate,
"stop at first failed test case(s)"),
OPT_INTEGER('j', "jobs", &max_jobs, "run <N> jobs in parallel"),
OPT_BOOL('q', "quiet", &suite.quiet, "be terse"),
OPT_BOOL('v', "verbose", &suite.verbose, "be verbose"),
OPT_BOOL('V', "verbose-log", &suite.verbose_log,
"be verbose, redirected to a file"),
OPT_BOOL('x', "trace", &suite.trace, "trace shell commands"),
OPT_BOOL(0, "write-junit-xml", &suite.write_junit_xml,
"write JUnit-style XML files"),
OPT_END()
};
memset(&suite, 0, sizeof(suite));
suite.tests.strdup_strings = suite.failed.strdup_strings = 1;
argc = parse_options(argc, argv, NULL, options,
testsuite_usage, PARSE_OPT_STOP_AT_NON_OPTION);
if (max_jobs <= 0)
max_jobs = online_cpus();
dir = opendir(".");
if (!dir)
die("Could not open the current directory");
while ((d = readdir(dir))) {
const char *p = d->d_name;
if (*p != 't' || !isdigit(p[1]) || !isdigit(p[2]) ||
!isdigit(p[3]) || !isdigit(p[4]) || p[5] != '-' ||
!ends_with(p, ".sh"))
continue;
/* No pattern: match all */
if (!argc) {
string_list_append(&suite.tests, p);
continue;
}
for (i = 0; i < argc; i++)
if (!wildmatch(argv[i], p, 0)) {
string_list_append(&suite.tests, p);
break;
}
}
closedir(dir);
if (!suite.tests.nr)
die("No tests match!");
if (max_jobs > suite.tests.nr)
max_jobs = suite.tests.nr;
fprintf(stderr, "Running %d tests (%d at a time)\n",
suite.tests.nr, max_jobs);
ret = run_processes_parallel(max_jobs, next_test, test_failed,
test_finished, &suite);
if (suite.failed.nr > 0) {
ret = 1;
fprintf(stderr, "%d tests failed:\n\n", suite.failed.nr);
for (i = 0; i < suite.failed.nr; i++)
fprintf(stderr, "\t%s\n", suite.failed.items[i].string);
}
string_list_clear(&suite.tests, 0);
string_list_clear(&suite.failed, 0);
return !!ret;
}
static uint64_t my_random_next = 1234;
static uint64_t my_random(void)
{
uint64_t res = my_random_next;
my_random_next = my_random_next * 1103515245 + 12345;
return res;
}
static int quote_stress_test(int argc, const char **argv)
{
/*
* We are running a quote-stress test.
* spawn a subprocess that runs quote-stress with a
* special option that echoes back the arguments that
* were passed in.
*/
char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a";
int i, j, k, trials = 100, skip = 0, msys2 = 0;
struct strbuf out = STRBUF_INIT;
struct strvec args = STRVEC_INIT;
struct option options[] = {
OPT_INTEGER('n', "trials", &trials, "Number of trials"),
OPT_INTEGER('s', "skip", &skip, "Skip <n> trials"),
OPT_BOOL('m', "msys2", &msys2, "Test quoting for MSYS2's sh"),
OPT_END()
};
const char * const usage[] = {
"test-tool run-command quote-stress-test <options>",
NULL
};
argc = parse_options(argc, argv, NULL, options, usage, 0);
setenv("MSYS_NO_PATHCONV", "1", 0);
for (i = 0; i < trials; i++) {
struct child_process cp = CHILD_PROCESS_INIT;
size_t arg_count, arg_offset;
int ret = 0;
strvec_clear(&args);
if (msys2)
strvec_pushl(&args, "sh", "-c",
"printf %s\\\\0 \"$@\"", "skip", NULL);
else
strvec_pushl(&args, "test-tool", "run-command",
"quote-echo", NULL);
arg_offset = args.nr;
if (argc > 0) {
trials = 1;
arg_count = argc;
for (j = 0; j < arg_count; j++)
strvec_push(&args, argv[j]);
} else {
arg_count = 1 + (my_random() % 5);
for (j = 0; j < arg_count; j++) {
char buf[20];
size_t min_len = 1;
size_t arg_len = min_len +
(my_random() % (ARRAY_SIZE(buf) - min_len));
for (k = 0; k < arg_len; k++)
buf[k] = special[my_random() %
ARRAY_SIZE(special)];
buf[arg_len] = '\0';
strvec_push(&args, buf);
}
}
if (i < skip)
continue;
cp.argv = args.v;
strbuf_reset(&out);
if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0)
return error("Failed to spawn child process");
for (j = 0, k = 0; j < arg_count; j++) {
const char *arg = args.v[j + arg_offset];
if (strcmp(arg, out.buf + k))
ret = error("incorrectly quoted arg: '%s', "
"echoed back as '%s'",
arg, out.buf + k);
k += strlen(out.buf + k) + 1;
}
if (k != out.len)
ret = error("got %d bytes, but consumed only %d",
(int)out.len, (int)k);
if (ret) {
fprintf(stderr, "Trial #%d failed. Arguments:\n", i);
for (j = 0; j < arg_count; j++)
fprintf(stderr, "arg #%d: '%s'\n",
(int)j, args.v[j + arg_offset]);
strbuf_release(&out);
strvec_clear(&args);
return ret;
}
if (i && (i % 100) == 0)
fprintf(stderr, "Trials completed: %d\n", (int)i);
}
strbuf_release(&out);
strvec_clear(&args);
return 0;
}
static int quote_echo(int argc, const char **argv)
{
while (argc > 1) {
fwrite(argv[1], strlen(argv[1]), 1, stdout);
fputc('\0', stdout);
argv++;
argc--;
}
return 0;
}
static int inherit_handle(const char *argv0)
{
struct child_process cp = CHILD_PROCESS_INIT;
char path[PATH_MAX];
int tmp;
/* First, open an inheritable handle */
xsnprintf(path, sizeof(path), "out-XXXXXX");
tmp = xmkstemp(path);
strvec_pushl(&cp.args,
"test-tool", argv0, "inherited-handle-child", NULL);
cp.in = -1;
cp.no_stdout = cp.no_stderr = 1;
if (start_command(&cp) < 0)
die("Could not start child process");
/* Then close it, and try to delete it. */
close(tmp);
if (unlink(path))
die("Could not delete '%s'", path);
if (close(cp.in) < 0 || finish_command(&cp) < 0)
die("Child did not finish");
return 0;
}
static int inherit_handle_child(void)
{
struct strbuf buf = STRBUF_INIT;
if (strbuf_read(&buf, 0, 0) < 0)
die("Could not read stdin");
printf("Received %s\n", buf.buf);
strbuf_release(&buf);
return 0;
}
int cmd__run_command(int argc, const char **argv)
{
struct child_process proc = CHILD_PROCESS_INIT;
int jobs;
if (argc > 1 && !strcmp(argv[1], "testsuite"))
exit(testsuite(argc - 1, argv + 1));
if (!strcmp(argv[1], "inherited-handle"))
exit(inherit_handle(argv[0]));
if (!strcmp(argv[1], "inherited-handle-child"))
exit(inherit_handle_child());
if (argc >= 2 && !strcmp(argv[1], "quote-stress-test"))
return !!quote_stress_test(argc - 1, argv + 1);
if (argc >= 2 && !strcmp(argv[1], "quote-echo"))
return !!quote_echo(argc - 1, argv + 1);
if (argc < 3)
return 1;
while (!strcmp(argv[1], "env")) {
if (!argv[2])
die("env specifier without a value");
argv_array_push(&proc.env_array, argv[2]);
strvec_push(&proc.env_array, argv[2]);
argv += 2;
argc -= 2;
}

View file

@ -1,7 +1,7 @@
#include "test-tool.h"
#include "submodule-config.h"
static void die_usage(int argc, const char **argv, const char *msg)
static void die_usage(const char **argv, const char *msg)
{
fprintf(stderr, "%s\n", msg);
fprintf(stderr, "Usage: %s <submodulepath> <config name>\n", argv[0]);
@ -14,13 +14,13 @@ int cmd__submodule_nested_repo_config(int argc, const char **argv)
const struct submodule *sub;
if (argc < 3)
die_usage(argc, argv, "Wrong number of arguments.");
die_usage(argv, "Wrong number of arguments.");
setup_git_directory();
sub = submodule_from_path(the_repository, &null_oid, argv[1]);
if (repo_submodule_init(&subrepo, the_repository, sub)) {
die_usage(argc, argv, "Submodule not found.");
die_usage(argv, "Submodule not found.");
}
/* Read the config of _child_ submodules. */

View file

@ -1,52 +0,0 @@
/*
* test-svn-fe: Code to exercise the svn import lib
*/
#include "git-compat-util.h"
#include "vcs-svn/svndump.h"
#include "vcs-svn/svndiff.h"
#include "vcs-svn/sliding_window.h"
#include "vcs-svn/line_buffer.h"
static const char test_svnfe_usage[] =
"test-svn-fe (<dumpfile> | [-d] <preimage> <delta> <len>)";
static int apply_delta(int argc, const char **argv)
{
struct line_buffer preimage = LINE_BUFFER_INIT;
struct line_buffer delta = LINE_BUFFER_INIT;
struct sliding_view preimage_view = SLIDING_VIEW_INIT(&preimage, -1);
if (argc != 5)
usage(test_svnfe_usage);
if (buffer_init(&preimage, argv[2]))
die_errno("cannot open preimage");
if (buffer_init(&delta, argv[3]))
die_errno("cannot open delta");
if (svndiff0_apply(&delta, (off_t) strtoumax(argv[4], NULL, 0),
&preimage_view, stdout))
return 1;
if (buffer_deinit(&preimage))
die_errno("cannot close preimage");
if (buffer_deinit(&delta))
die_errno("cannot close delta");
strbuf_release(&preimage_view.buf);
return 0;
}
int cmd_main(int argc, const char **argv)
{
if (argc == 2) {
if (svndump_init(argv[1]))
return 1;
svndump_read(NULL, "refs/heads/master", "refs/notes/svn/revs");
svndump_deinit();
svndump_reset();
return 0;
}
if (argc >= 2 && !strcmp(argv[1], "-d"))
return apply_delta(argc, argv);
usage(test_svnfe_usage);
}

View file

@ -14,6 +14,8 @@ struct test_cmd {
};
static struct test_cmd cmds[] = {
{ "advise", cmd__advise_if_enabled },
{ "bloom", cmd__bloom },
{ "chmtime", cmd__chmtime },
{ "config", cmd__config },
{ "ctype", cmd__ctype },
@ -36,14 +38,19 @@ static struct test_cmd cmds[] = {
{ "match-trees", cmd__match_trees },
{ "mergesort", cmd__mergesort },
{ "mktemp", cmd__mktemp },
{ "oid-array", cmd__oid_array },
{ "oidmap", cmd__oidmap },
{ "online-cpus", cmd__online_cpus },
{ "parse-options", cmd__parse_options },
{ "parse-pathspec-file", cmd__parse_pathspec_file },
{ "path-utils", cmd__path_utils },
{ "pkt-line", cmd__pkt_line },
{ "prio-queue", cmd__prio_queue },
{ "proc-receive", cmd__proc_receive},
{ "progress", cmd__progress },
{ "reach", cmd__reach },
{ "read-cache", cmd__read_cache },
{ "read-graph", cmd__read_graph },
{ "read-midx", cmd__read_midx },
{ "ref-store", cmd__ref_store },
{ "regex", cmd__regex },
@ -53,7 +60,6 @@ static struct test_cmd cmds[] = {
{ "scrap-cache-tree", cmd__scrap_cache_tree },
{ "serve-v2", cmd__serve_v2 },
{ "sha1", cmd__sha1 },
{ "sha1-array", cmd__sha1_array },
{ "sha256", cmd__sha256 },
{ "sigchain", cmd__sigchain },
{ "strcmp-offset", cmd__strcmp_offset },
@ -108,6 +114,7 @@ int cmd_main(int argc, const char **argv)
argc--;
trace2_cmd_name(cmds[i].name);
trace2_cmd_list_config();
trace2_cmd_list_env_vars();
return cmds[i].fn(argc, argv);
}
}

View file

@ -4,6 +4,8 @@
#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "git-compat-util.h"
int cmd__advise_if_enabled(int argc, const char **argv);
int cmd__bloom(int argc, const char **argv);
int cmd__chmtime(int argc, const char **argv);
int cmd__config(int argc, const char **argv);
int cmd__ctype(int argc, const char **argv);
@ -29,11 +31,15 @@ int cmd__mktemp(int argc, const char **argv);
int cmd__oidmap(int argc, const char **argv);
int cmd__online_cpus(int argc, const char **argv);
int cmd__parse_options(int argc, const char **argv);
int cmd__parse_pathspec_file(int argc, const char** argv);
int cmd__path_utils(int argc, const char **argv);
int cmd__pkt_line(int argc, const char **argv);
int cmd__prio_queue(int argc, const char **argv);
int cmd__proc_receive(int argc, const char **argv);
int cmd__progress(int argc, const char **argv);
int cmd__reach(int argc, const char **argv);
int cmd__read_cache(int argc, const char **argv);
int cmd__read_graph(int argc, const char **argv);
int cmd__read_midx(int argc, const char **argv);
int cmd__ref_store(int argc, const char **argv);
int cmd__regex(int argc, const char **argv);
@ -43,7 +49,7 @@ int cmd__run_command(int argc, const char **argv);
int cmd__scrap_cache_tree(int argc, const char **argv);
int cmd__serve_v2(int argc, const char **argv);
int cmd__sha1(int argc, const char **argv);
int cmd__sha1_array(int argc, const char **argv);
int cmd__oid_array(int argc, const char **argv);
int cmd__sha256(int argc, const char **argv);
int cmd__sigchain(int argc, const char **argv);
int cmd__strcmp_offset(int argc, const char **argv);

View file

@ -1,6 +1,6 @@
#include "test-tool.h"
#include "cache.h"
#include "argv-array.h"
#include "strvec.h"
#include "run-command.h"
#include "exec-cmd.h"
#include "config.h"

View file

@ -19,7 +19,7 @@ int cmd__windows_named_pipe(int argc, const char **argv)
if (argc < 2)
goto print_usage;
filename = argv[1];
if (strchr(filename, '/') || strchr(filename, '\\'))
if (strpbrk(filename, "/\\"))
goto print_usage;
strbuf_addf(&pathname, "//./pipe/%s", filename);

View file

@ -2,10 +2,12 @@
# to run under Bash; primarily intended for tests of the completion
# script.
if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then
if test -n "$BASH" && test -z "$POSIXLY_CORRECT"
then
# we are in full-on bash mode
true
elif type bash >/dev/null 2>&1; then
elif type bash >/dev/null 2>&1
then
# execute in full-on bash mode
unset POSIXLY_CORRECT
exec bash "$0" "$@"

5
third_party/git/t/lib-credential.sh vendored Executable file → Normal file
View file

@ -1,4 +1,5 @@
#!/bin/sh
# Shell library for testing credential handling including helpers. See t0302
# for an example of testing a specific helper.
# Try a set of credential helpers; the expected stdin,
# stdout and stderr should be provided on stdin,
@ -19,7 +20,7 @@ check() {
false
fi &&
test_cmp expect-stdout stdout &&
test_cmp expect-stderr stderr
test_i18ncmp expect-stderr stderr
}
read_chunk() {

View file

@ -15,7 +15,7 @@
#
# test_done
if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON
if ! test_bool_env GIT_TEST_GIT_DAEMON true
then
skip_all="git-daemon testing disabled (unset GIT_TEST_GIT_DAEMON to enable)"
test_done

View file

@ -175,7 +175,7 @@ stop_and_cleanup_p4d () {
cleanup_git () {
retry_until_success rm -r "$git"
test_must_fail test -d "$git" &&
test_path_is_missing "$git" &&
retry_until_success mkdir "$git"
}

View file

@ -69,7 +69,7 @@ svn_cmd () {
maybe_start_httpd () {
loc=${1-svn}
if git env--helper --type=bool --default=false --exit-code GIT_TEST_HTTPD
if test_bool_env GIT_TEST_SVN_HTTPD false
then
. "$TEST_DIRECTORY"/lib-httpd.sh
LIB_HTTPD_SVN="$loc"
@ -78,21 +78,24 @@ maybe_start_httpd () {
}
convert_to_rev_db () {
perl -w -- - "$@" <<\EOF
perl -w -- - "$(test_oid rawsz)" "$@" <<\EOF
use strict;
my $oidlen = shift;
@ARGV == 2 or die "usage: convert_to_rev_db <input> <output>";
my $record_size = $oidlen + 4;
my $hexlen = $oidlen * 2;
open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]";
open my $rd, '<', $ARGV[0] or die "$!: couldn't open: $ARGV[0]";
my $size = (stat($rd))[7];
($size % 24) == 0 or die "Inconsistent size: $size";
while (sysread($rd, my $buf, 24) == 24) {
my ($r, $c) = unpack('NH40', $buf);
my $offset = $r * 41;
($size % $record_size) == 0 or die "Inconsistent size: $size";
while (sysread($rd, my $buf, $record_size) == $record_size) {
my ($r, $c) = unpack("NH$hexlen", $buf);
my $offset = $r * ($hexlen + 1);
seek $wr, 0, 2 or die $!;
my $pos = tell $wr;
if ($pos < $offset) {
for (1 .. (($offset - $pos) / 41)) {
print $wr (('0' x 40),"\n") or die $!;
for (1 .. (($offset - $pos) / ($hexlen + 1))) {
print $wr (('0' x $hexlen),"\n") or die $!;
}
}
seek $wr, $offset, 0 or die $!;
@ -104,7 +107,7 @@ EOF
}
require_svnserve () {
if ! git env--helper --type=bool --default=false --exit-code GIT_TEST_SVNSERVE
if ! test_bool_env GIT_TEST_SVNSERVE false
then
skip_all='skipping svnserve test. (set $GIT_TEST_SVNSERVE to enable)'
test_done

110
third_party/git/t/lib-gpg.sh vendored Executable file → Normal file
View file

@ -1,14 +1,25 @@
#!/bin/sh
# We always set GNUPGHOME, even if no usable GPG was found, as
#
# - It does not hurt, and
#
# - we cannot set global environment variables in lazy prereqs because they are
# executed in an eval'ed subshell that changes the working directory to a
# temporary one.
GNUPGHOME="$PWD/gpghome"
export GNUPGHOME
test_lazy_prereq GPG '
gpg_version=$(gpg --version 2>&1)
test $? != 127 || exit 1
gpg_version=$(gpg --version 2>&1)
if test $? != 127
then
# As said here: http://www.gnupg.org/documentation/faqs.html#q6.19
# the gpg version 1.0.6 didn't parse trust packets correctly, so for
# the gpg version 1.0.6 did not parse trust packets correctly, so for
# that version, creation of signed tags using the generated key fails.
case "$gpg_version" in
'gpg (GnuPG) 1.0.6'*)
"gpg (GnuPG) 1.0.6"*)
say "Your version of gpg (1.0.6) is too buggy for testing"
exit 1
;;
*)
# Available key info:
@ -27,55 +38,54 @@ then
# To export ownertrust:
# gpg --homedir /tmp/gpghome --export-ownertrust \
# > lib-gpg/ownertrust
mkdir ./gpghome &&
chmod 0700 ./gpghome &&
GNUPGHOME="$(pwd)/gpghome" &&
export GNUPGHOME &&
(gpgconf --kill gpg-agent >/dev/null 2>&1 || : ) &&
gpg --homedir "${GNUPGHOME}" 2>/dev/null --import \
mkdir "$GNUPGHOME" &&
chmod 0700 "$GNUPGHOME" &&
(gpgconf --kill gpg-agent || : ) &&
gpg --homedir "${GNUPGHOME}" --import \
"$TEST_DIRECTORY"/lib-gpg/keyring.gpg &&
gpg --homedir "${GNUPGHOME}" 2>/dev/null --import-ownertrust \
gpg --homedir "${GNUPGHOME}" --import-ownertrust \
"$TEST_DIRECTORY"/lib-gpg/ownertrust &&
gpg --homedir "${GNUPGHOME}" </dev/null >/dev/null 2>&1 \
--sign -u committer@example.com &&
test_set_prereq GPG &&
# Available key info:
# * see t/lib-gpg/gpgsm-gen-key.in
# To generate new certificate:
# * no passphrase
# gpgsm --homedir /tmp/gpghome/ \
# -o /tmp/gpgsm.crt.user \
# --generate-key \
# --batch t/lib-gpg/gpgsm-gen-key.in
# To import certificate:
# gpgsm --homedir /tmp/gpghome/ \
# --import /tmp/gpgsm.crt.user
# To export into a .p12 we can later import:
# gpgsm --homedir /tmp/gpghome/ \
# -o t/lib-gpg/gpgsm_cert.p12 \
# --export-secret-key-p12 "committer@example.com"
echo | gpgsm --homedir "${GNUPGHOME}" 2>/dev/null \
--passphrase-fd 0 --pinentry-mode loopback \
--import "$TEST_DIRECTORY"/lib-gpg/gpgsm_cert.p12 &&
gpgsm --homedir "${GNUPGHOME}" 2>/dev/null -K |
grep fingerprint: |
cut -d" " -f4 |
tr -d '\n' >"${GNUPGHOME}/trustlist.txt" &&
echo " S relax" >>"${GNUPGHOME}/trustlist.txt" &&
echo hello | gpgsm --homedir "${GNUPGHOME}" >/dev/null \
-u committer@example.com -o /dev/null --sign - 2>&1 &&
test_set_prereq GPGSM
gpg --homedir "${GNUPGHOME}" </dev/null >/dev/null \
--sign -u committer@example.com
;;
esac
fi
'
if test_have_prereq GPG &&
echo | gpg --homedir "${GNUPGHOME}" -b --rfc1991 >/dev/null 2>&1
then
test_set_prereq RFC1991
fi
test_lazy_prereq GPGSM '
test_have_prereq GPG &&
# Available key info:
# * see t/lib-gpg/gpgsm-gen-key.in
# To generate new certificate:
# * no passphrase
# gpgsm --homedir /tmp/gpghome/ \
# -o /tmp/gpgsm.crt.user \
# --generate-key \
# --batch t/lib-gpg/gpgsm-gen-key.in
# To import certificate:
# gpgsm --homedir /tmp/gpghome/ \
# --import /tmp/gpgsm.crt.user
# To export into a .p12 we can later import:
# gpgsm --homedir /tmp/gpghome/ \
# -o t/lib-gpg/gpgsm_cert.p12 \
# --export-secret-key-p12 "committer@example.com"
echo | gpgsm --homedir "${GNUPGHOME}" \
--passphrase-fd 0 --pinentry-mode loopback \
--import "$TEST_DIRECTORY"/lib-gpg/gpgsm_cert.p12 &&
gpgsm --homedir "${GNUPGHOME}" -K |
grep fingerprint: |
cut -d" " -f4 |
tr -d "\\n" >"${GNUPGHOME}/trustlist.txt" &&
echo " S relax" >>"${GNUPGHOME}/trustlist.txt" &&
echo hello | gpgsm --homedir "${GNUPGHOME}" >/dev/null \
-u committer@example.com -o /dev/null --sign -
'
test_lazy_prereq RFC1991 '
test_have_prereq GPG &&
echo | gpg --homedir "${GNUPGHOME}" -b --rfc1991 >/dev/null
'
sanitize_pgp() {
perl -ne '

View file

@ -41,7 +41,7 @@ then
test_done
fi
if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_HTTPD
if ! test_bool_env GIT_TEST_HTTPD true
then
skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)"
test_done
@ -129,10 +129,12 @@ install_script () {
prepare_httpd() {
mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH"
cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH"
install_script incomplete-length-upload-pack-v2-http.sh
install_script incomplete-body-upload-pack-v2-http.sh
install_script broken-smart-http.sh
install_script error-smart-http.sh
install_script error.sh
install_script apply-one-time-sed.sh
install_script apply-one-time-perl.sh
ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules"

View file

@ -113,19 +113,27 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
</LocationMatch>
<LocationMatch /one_time_sed/>
<LocationMatch /one_time_perl/>
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
</LocationMatch>
ScriptAlias /smart/incomplete_length/git-upload-pack incomplete-length-upload-pack-v2-http.sh/
ScriptAlias /smart/incomplete_body/git-upload-pack incomplete-body-upload-pack-v2-http.sh/
ScriptAliasMatch /error_git_upload_pack/(.*)/git-upload-pack error.sh/
ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
ScriptAlias /broken_smart/ broken-smart-http.sh/
ScriptAlias /error_smart/ error-smart-http.sh/
ScriptAlias /error/ error.sh/
ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1
ScriptAliasMatch /one_time_perl/(.*) apply-one-time-perl.sh/$1
<Directory ${GIT_EXEC_PATH}>
Options FollowSymlinks
</Directory>
<Files incomplete-length-upload-pack-v2-http.sh>
Options ExecCGI
</Files>
<Files incomplete-body-upload-pack-v2-http.sh>
Options ExecCGI
</Files>
<Files broken-smart-http.sh>
Options ExecCGI
</Files>
@ -135,7 +143,7 @@ ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1
<Files error.sh>
Options ExecCGI
</Files>
<Files apply-one-time-sed.sh>
<Files apply-one-time-perl.sh>
Options ExecCGI
</Files>
<Files ${GIT_EXEC_PATH}/git-http-backend>

View file

@ -0,0 +1,27 @@
#!/bin/sh
# If "one-time-perl" exists in $HTTPD_ROOT_PATH, run perl on the HTTP response,
# using the contents of "one-time-perl" as the perl command to be run. If the
# response was modified as a result, delete "one-time-perl" so that subsequent
# HTTP responses are no longer modified.
#
# This can be used to simulate the effects of the repository changing in
# between HTTP request-response pairs.
if test -f one-time-perl
then
LC_ALL=C
export LC_ALL
"$GIT_EXEC_PATH/git-http-backend" >out
perl -pe "$(cat one-time-perl)" out >out_modified
if cmp -s out out_modified
then
cat out
else
cat out_modified
rm one-time-perl
fi
else
"$GIT_EXEC_PATH/git-http-backend"
fi

View file

@ -1,22 +0,0 @@
#!/bin/sh
# If "one-time-sed" exists in $HTTPD_ROOT_PATH, run sed on the HTTP response,
# using the contents of "one-time-sed" as the sed command to be run. If the
# response was modified as a result, delete "one-time-sed" so that subsequent
# HTTP responses are no longer modified.
#
# This can be used to simulate the effects of the repository changing in
# between HTTP request-response pairs.
if [ -e one-time-sed ]; then
"$GIT_EXEC_PATH/git-http-backend" >out
sed "$(cat one-time-sed)" <out >out_modified
if diff out out_modified >/dev/null; then
cat out
else
cat out_modified
rm one-time-sed
fi
else
"$GIT_EXEC_PATH/git-http-backend"
fi

View file

@ -0,0 +1,3 @@
printf "Content-Type: text/%s\n" "application/x-git-upload-pack-result"
echo
printf "%s%s" "0079" "45"

View file

@ -0,0 +1,3 @@
printf "Content-Type: text/%s\n" "application/x-git-upload-pack-result"
echo
printf "%s" "00"

28
third_party/git/t/lib-log-graph.sh vendored Normal file
View file

@ -0,0 +1,28 @@
# Helps shared by the test scripts for comparing log graphs.
sanitize_log_output () {
sed -e 's/ *$//' \
-e 's/commit [0-9a-f]*$/commit COMMIT_OBJECT_NAME/' \
-e 's/Merge: [ 0-9a-f]*$/Merge: MERGE_PARENTS/' \
-e 's/Merge tag.*/Merge HEADS DESCRIPTION/' \
-e 's/Merge commit.*/Merge HEADS DESCRIPTION/' \
-e 's/index [0-9a-f]*\.\.[0-9a-f]*/index BEFORE..AFTER/'
}
lib_test_cmp_graph () {
git log --graph "$@" >output &&
sed 's/ *$//' >output.sanitized <output &&
test_i18ncmp expect output.sanitized
}
lib_test_cmp_short_graph () {
git log --graph --pretty=short "$@" >output &&
sanitize_log_output >output.sanitized <output &&
test_i18ncmp expect output.sanitized
}
lib_test_cmp_colored_graph () {
git log --graph --color=always "$@" >output.colors.raw &&
test_decode_color <output.colors.raw | sed "s/ *\$//" >output.colors &&
test_cmp expect.colors output.colors
}

View file

@ -37,7 +37,7 @@ pack_header () {
pack_obj () {
case "$1" in
# empty blob
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)
$EMPTY_BLOB)
case "$2" in
'')
printf '\060\170\234\003\0\0\0\0\1'
@ -47,7 +47,7 @@ pack_obj () {
;;
# blob containing "\7\76"
e68fe8129b546b101aee9510c5328e7f21ca1d18)
$(test_oid packlib_7_76))
case "$2" in
'')
printf '\062\170\234\143\267\3\0\0\116\0\106'
@ -59,11 +59,18 @@ pack_obj () {
printf '\234\143\142\142\142\267\003\0\0\151\0\114'
return
;;
37c8e2c15bb22b912e59b43fd51a4f7e9465ed0b5084c5a1411d991cbe630683)
printf '\165\67\310\342\301\133\262\53\221\56\131' &&
printf '\264\77\325\32\117\176\224\145\355\13\120' &&
printf '\204\305\241\101\35\231\34\276\143\6\203\170' &&
printf '\234\143\142\142\142\267\003\0\0\151\0\114'
return
;;
esac
;;
# blob containing "\7\0"
01d7713666f4de822776c7622c10f1b07de280dc)
$(test_oid packlib_7_0))
case "$2" in
'')
printf '\062\170\234\143\147\0\0\0\20\0\10'
@ -75,8 +82,23 @@ pack_obj () {
printf '\143\142\142\142\147\0\0\0\53\0\16'
return
;;
5d8e6fc40f2dab00e6983a48523fe57e621f46434cb58dbd4422fba03380d886)
printf '\165\135\216\157\304\17\55\253\0\346\230\72' &&
printf '\110\122\77\345\176\142\37\106\103\114\265' &&
printf '\215\275\104\42\373\240\63\200\330\206\170\234' &&
printf '\143\142\142\142\147\0\0\0\53\0\16'
return
;;
esac
;;
# blob containing "\3\326"
471819e8c52bf11513f100b2810a8aa0622d5cd3d1c913758a071dd4b3bad8fe)
case "$2" in
'')
printf '\062\170\234\143\276\006\000\000\336\000\332'
return
;;
esac
esac
# If it's not a delta, we can convince pack-objects to generate a pack
@ -86,7 +108,7 @@ pack_obj () {
then
echo "$1" | git pack-objects --stdout >pack_obj.tmp &&
size=$(wc -c <pack_obj.tmp) &&
dd if=pack_obj.tmp bs=1 count=$((size - 20 - 12)) skip=12 &&
dd if=pack_obj.tmp bs=1 count=$((size - $(test_oid rawsz) - 12)) skip=12 &&
rm -f pack_obj.tmp
return
fi
@ -97,7 +119,7 @@ pack_obj () {
# Compute and append pack trailer to "$1"
pack_trailer () {
test-tool sha1 -b <"$1" >trailer.tmp &&
test-tool $(test_oid algo) -b <"$1" >trailer.tmp &&
cat trailer.tmp >>"$1" &&
rm -f trailer.tmp
}
@ -108,3 +130,11 @@ pack_trailer () {
clear_packs () {
rm -f .git/objects/pack/*
}
test_oid_cache <<-EOF
packlib_7_0 sha1:01d7713666f4de822776c7622c10f1b07de280dc
packlib_7_0 sha256:37c8e2c15bb22b912e59b43fd51a4f7e9465ed0b5084c5a1411d991cbe630683
packlib_7_76 sha1:e68fe8129b546b101aee9510c5328e7f21ca1d18
packlib_7_76 sha256:5d8e6fc40f2dab00e6983a48523fe57e621f46434cb58dbd4422fba03380d886
EOF

View file

@ -44,10 +44,10 @@ set_fake_editor () {
rm -f "$1"
echo 'rebase -i script before editing:'
cat "$1".tmp
action=pick
action=\&
for line in $FAKE_LINES; do
case $line in
pick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)
pick|p|squash|s|fixup|f|edit|e|reword|r|drop|d|label|l|reset|r|merge|m)
action="$line";;
exec_*|x_*|break|b)
echo "$line" | sed 's/_/ /g' >> "$1";;
@ -58,11 +58,12 @@ set_fake_editor () {
bad)
action="badcmd";;
fakesha)
test \& != "$action" || action=pick
echo "$action XXXXXXX False commit" >> "$1"
action=pick;;
*)
sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
action=pick;;
sed -n "${line}s/^[a-z][a-z]*/$action/p" < "$1".tmp >> "$1"
action=\&;;
esac
done
echo 'rebase -i script after editing:'
@ -118,3 +119,31 @@ make_empty () {
git commit --allow-empty -m "$1" &&
git tag "$1"
}
# Call this (inside test_expect_success) at the end of a test file to
# check that no tests have changed editor related environment
# variables or config settings
test_editor_unchanged () {
# We're only interested in exported variables hence 'sh -c'
sh -c 'cat >actual <<-EOF
EDITOR=$EDITOR
FAKE_COMMIT_AMEND=$FAKE_COMMIT_AMEND
FAKE_COMMIT_MESSAGE=$FAKE_COMMIT_MESSAGE
FAKE_LINES=$FAKE_LINES
GIT_EDITOR=$GIT_EDITOR
GIT_SEQUENCE_EDITOR=$GIT_SEQUENCE_EDITOR
core.editor=$(git config core.editor)
sequence.editor=$(git config sequence.editor)
EOF'
cat >expect <<-\EOF
EDITOR=:
FAKE_COMMIT_AMEND=
FAKE_COMMIT_MESSAGE=
FAKE_LINES=
GIT_EDITOR=
GIT_SEQUENCE_EDITOR=
core.editor=
sequence.editor=
EOF
test_cmp expect actual
}

144
third_party/git/t/lib-submodule-update.sh vendored Executable file → Normal file
View file

@ -183,7 +183,7 @@ test_git_directory_is_unchanged () {
)
}
test_git_directory_exists() {
test_git_directory_exists () {
test -e ".git/modules/$1" &&
if test -f sub1/.git
then
@ -196,7 +196,6 @@ test_git_directory_exists() {
# the submodule repo if it doesn't exist and configures the most problematic
# settings for diff.ignoreSubmodules.
prolog () {
test_oid_init &&
(test -d submodule_update_repo || create_lib_submodule_repo) &&
test_config_global diff.ignoreSubmodules all &&
test_config diff.ignoreSubmodules all
@ -297,19 +296,23 @@ test_submodule_content () {
# - Directory containing tracked files replaced by submodule
# - Submodule replaced by tracked files in directory
# - Submodule replaced by tracked file with the same name
# - tracked file replaced by submodule
# - Tracked file replaced by submodule
#
# The default is that submodule contents aren't changed until "git submodule
# update" is run. And even then that command doesn't delete the work tree of
# a removed submodule.
#
# The first argument of the callback function will be the name of the submodule.
#
# Removing a submodule containing a .git directory must fail even when forced
# to protect the history!
# to protect the history! If we are testing this case, the second argument of
# the callback function will be 'test_must_fail', else it will be the empty
# string.
#
# Internal function; use test_submodule_switch() or
# test_submodule_forced_switch() instead.
test_submodule_switch_common() {
# Internal function; use test_submodule_switch_func(), test_submodule_switch(),
# or test_submodule_forced_switch() instead.
test_submodule_switch_common () {
command="$1"
######################### Appearing submodule #########################
# Switching to a commit letting a submodule appear creates empty dir ...
@ -443,7 +446,7 @@ test_submodule_switch_common() {
(
cd submodule_update &&
git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
test_must_fail $command replace_sub1_with_directory &&
$command replace_sub1_with_directory test_must_fail &&
test_superproject_content origin/add_sub1 &&
test_submodule_content sub1 origin/add_sub1
)
@ -456,7 +459,7 @@ test_submodule_switch_common() {
cd submodule_update &&
git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
replace_gitfile_with_git_dir sub1 &&
test_must_fail $command replace_sub1_with_directory &&
$command replace_sub1_with_directory test_must_fail &&
test_superproject_content origin/add_sub1 &&
test_git_directory_is_unchanged sub1 &&
test_submodule_content sub1 origin/add_sub1
@ -470,7 +473,7 @@ test_submodule_switch_common() {
(
cd submodule_update &&
git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
test_must_fail $command replace_sub1_with_file &&
$command replace_sub1_with_file test_must_fail &&
test_superproject_content origin/add_sub1 &&
test_submodule_content sub1 origin/add_sub1
)
@ -484,7 +487,7 @@ test_submodule_switch_common() {
cd submodule_update &&
git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
replace_gitfile_with_git_dir sub1 &&
test_must_fail $command replace_sub1_with_file &&
$command replace_sub1_with_file test_must_fail &&
test_superproject_content origin/add_sub1 &&
test_git_directory_is_unchanged sub1 &&
test_submodule_content sub1 origin/add_sub1
@ -559,15 +562,28 @@ test_submodule_switch_common() {
# conditions, set the appropriate KNOWN_FAILURE_* variable used in the tests
# below to 1.
#
# Use as follows:
# The first argument of the callback function will be the name of the submodule.
#
# Removing a submodule containing a .git directory must fail even when forced
# to protect the history! If we are testing this case, the second argument of
# the callback function will be 'test_must_fail', else it will be the empty
# string.
#
# The following example uses `git some-command` as an example command to be
# tested. It updates the worktree and index to match a target, but not any
# submodule directories.
#
# my_func () {
# target=$1
# # Do something here that updates the worktree and index to match target,
# # but not any submodule directories.
# ...prepare for `git some-command` to be run...
# $2 git some-command "$1" &&
# if test -n "$2"
# then
# return
# fi &&
# ...check the state after git some-command is run...
# }
# test_submodule_switch "my_func"
test_submodule_switch () {
# test_submodule_switch_func "my_func"
test_submodule_switch_func () {
command="$1"
test_submodule_switch_common "$command"
@ -580,17 +596,33 @@ test_submodule_switch () {
cd submodule_update &&
git branch -t add_sub1 origin/add_sub1 &&
>sub1 &&
test_must_fail $command add_sub1 &&
$command add_sub1 test_must_fail &&
test_superproject_content origin/no_submodule &&
test_must_be_empty sub1
)
'
}
# Ensures that the that the arg either contains "test_must_fail" or is empty.
may_only_be_test_must_fail () {
test -z "$1" || test "$1" = test_must_fail || die
}
git_test_func () {
may_only_be_test_must_fail "$2" &&
$2 git $gitcmd "$1"
}
test_submodule_switch () {
gitcmd="$1"
test_submodule_switch_func "git_test_func"
}
# Same as test_submodule_switch(), except that throwing away local changes in
# the superproject is allowed.
test_submodule_forced_switch () {
command="$1"
gitcmd="$1"
command="git_test_func"
KNOWN_FAILURE_FORCED_SWITCH_TESTS=1
test_submodule_switch_common "$command"
@ -621,16 +653,18 @@ test_submodule_forced_switch () {
# - Directory containing tracked files replaced by submodule
# - Submodule replaced by tracked files in directory
# - Submodule replaced by tracked file with the same name
# - tracked file replaced by submodule
# - Tracked file replaced by submodule
#
# New test cases
# - Removing a submodule with a git directory absorbs the submodules
# git directory first into the superproject.
# - Switching from no submodule to nested submodules
# - Switching from nested submodules to no submodule
# Internal function; use test_submodule_switch_recursing_with_args() or
# test_submodule_forced_switch_recursing_with_args() instead.
test_submodule_recursing_with_args_common() {
command="$1"
test_submodule_recursing_with_args_common () {
command="$1 --recurse-submodules"
######################### Appearing submodule #########################
# Switching to a commit letting a submodule appear checks it out ...
@ -658,22 +692,6 @@ test_submodule_recursing_with_args_common() {
test_submodule_content sub1 origin/add_sub1
)
'
test_expect_success "$command: submodule branch is not changed, detach HEAD instead" '
prolog &&
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
git -C sub1 checkout -b keep_branch &&
git -C sub1 rev-parse HEAD >expect &&
git branch -t modify_sub1 origin/modify_sub1 &&
$command modify_sub1 &&
test_superproject_content origin/modify_sub1 &&
test_submodule_content sub1 origin/modify_sub1 &&
git -C sub1 rev-parse keep_branch >actual &&
test_cmp expect actual &&
test_must_fail git -C sub1 symbolic-ref HEAD
)
'
# Replacing a tracked file with a submodule produces a checked out submodule
test_expect_success "$command: replace tracked file with submodule checks out submodule" '
@ -699,6 +717,19 @@ test_submodule_recursing_with_args_common() {
test_submodule_content sub1 origin/replace_directory_with_sub1
)
'
# Switching to a commit with nested submodules recursively checks them out
test_expect_success "$command: nested submodules are checked out" '
prolog &&
reset_work_tree_to_interested no_submodule &&
(
cd submodule_update &&
git branch -t modify_sub1_recursively origin/modify_sub1_recursively &&
$command modify_sub1_recursively &&
test_superproject_content origin/modify_sub1_recursively &&
test_submodule_content sub1 origin/modify_sub1_recursively &&
test_submodule_content -C sub1 sub2 origin/modify_sub1_recursively
)
'
######################## Disappearing submodule #######################
# Removing a submodule removes its work tree ...
@ -762,6 +793,21 @@ test_submodule_recursing_with_args_common() {
)
'
# Switching to a commit without nested submodules removes their worktrees
test_expect_success "$command: worktrees of nested submodules are removed" '
prolog &&
reset_work_tree_to_interested add_nested_sub &&
(
cd submodule_update &&
git branch -t no_submodule origin/no_submodule &&
$command no_submodule &&
test_superproject_content origin/no_submodule &&
! test_path_is_dir sub1 &&
test_must_fail git config -f .git/modules/sub1/config core.worktree &&
test_must_fail git config -f .git/modules/sub1/modules/sub2/config core.worktree
)
'
########################## Modified submodule #########################
# Updating a submodule sha1 updates the submodule's work tree
test_expect_success "$command: modified submodule updates submodule work tree" '
@ -789,6 +835,23 @@ test_submodule_recursing_with_args_common() {
test_submodule_content sub1 origin/add_sub1
)
'
# Updating a submodule does not touch the currently checked out branch in the submodule
test_expect_success "$command: submodule branch is not changed, detach HEAD instead" '
prolog &&
reset_work_tree_to_interested add_sub1 &&
(
cd submodule_update &&
git -C sub1 checkout -b keep_branch &&
git -C sub1 rev-parse HEAD >expect &&
git branch -t modify_sub1 origin/modify_sub1 &&
$command modify_sub1 &&
test_superproject_content origin/modify_sub1 &&
test_submodule_content sub1 origin/modify_sub1 &&
git -C sub1 rev-parse keep_branch >actual &&
test_cmp expect actual &&
test_must_fail git -C sub1 symbolic-ref HEAD
)
'
}
# Declares and invokes several tests that, in various situations, checks that
@ -809,7 +872,7 @@ test_submodule_recursing_with_args_common() {
# test_submodule_switch_recursing_with_args "$GIT_COMMAND"
test_submodule_switch_recursing_with_args () {
cmd_args="$1"
command="git $cmd_args --recurse-submodules"
command="git $cmd_args"
test_submodule_recursing_with_args_common "$command"
RESULTDS=success
@ -908,7 +971,6 @@ test_submodule_switch_recursing_with_args () {
)
'
# recursing deeper than one level doesn't work yet.
test_expect_success "$command: modified submodule updates submodule recursively" '
prolog &&
reset_work_tree_to_interested add_nested_sub &&
@ -927,7 +989,7 @@ test_submodule_switch_recursing_with_args () {
# away local changes in the superproject is allowed.
test_submodule_forced_switch_recursing_with_args () {
cmd_args="$1"
command="git $cmd_args --recurse-submodules"
command="git $cmd_args"
test_submodule_recursing_with_args_common "$command"
RESULT=success

View file

@ -1,7 +1,5 @@
: included from 6002 and others
mkdir -p .git/refs/tags
>sed.script
# Answer the sha1 has associated with the tag. The tag must exist under refs/tags
@ -26,7 +24,8 @@ save_tag () {
_tag=$1
test -n "$_tag" || error "usage: save_tag tag commit-args ..."
shift 1
"$@" >".git/refs/tags/$_tag"
git update-ref "refs/tags/$_tag" $("$@")
echo "s/$(tag $_tag)/$_tag/g" >sed.script.tmp
cat sed.script >>sed.script.tmp

View file

@ -6,3 +6,12 @@ hexsz sha256:64
zero sha1:0000000000000000000000000000000000000000
zero sha256:0000000000000000000000000000000000000000000000000000000000000000
algo sha1:sha1
algo sha256:sha256
empty_blob sha1:e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
empty_blob sha256:473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813
empty_tree sha1:4b825dc642cb6eb9a060e54bf8d69288fbee4904
empty_tree sha256:6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321

View file

@ -84,6 +84,15 @@ You can set the following variables (also in your config.mak):
probably be about linux.git size for optimal results.
Both default to the git.git you are running from.
GIT_PERF_EXTRA
Boolean to enable additional tests. Most test scripts are
written to detect regressions between two versions of Git, and
the output will compare timings for individual tests between
those versions. Some scripts have additional tests which are not
run by default, that show patterns within a single version of
Git (e.g., performance of index-pack as the number of threads
changes). These can be enabled with GIT_PERF_EXTRA.
You can also pass the options taken by ordinary git tests; the most
useful one is:

View file

@ -4,7 +4,6 @@ use lib '../../perl/build/lib';
use strict;
use warnings;
use Getopt::Long;
use Git;
use Cwd qw(realpath);
sub get_times {
@ -85,6 +84,11 @@ sub format_size {
return $out;
}
sub sane_backticks {
open(my $fh, '-|', @_);
return <$fh>;
}
my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests,
$codespeed, $sortby, $subsection, $reponame);
@ -102,7 +106,8 @@ while (scalar @ARGV) {
my $prefix = '';
last if -f $arg or $arg eq "--";
if (! -d $arg) {
my $rev = Git::command_oneline(qw(rev-parse --verify), $arg);
my $rev = sane_backticks(qw(git rev-parse --verify), $arg);
chomp $rev;
$dir = "build/".$rev;
} elsif ($arg eq '.') {
$dir = '.';
@ -219,13 +224,7 @@ sub print_default_results {
for my $i (0..$#dirs) {
my $d = $dirs[$i];
my $base = "$resultsdir/$prefixes{$d}$t";
$times{$prefixes{$d}.$t} = [];
foreach my $type (qw(times size)) {
if (-e "$base.$type") {
$times{$prefixes{$d}.$t} = [get_times("$base.$type")];
last;
}
}
$times{$prefixes{$d}.$t} = [get_times("$base.result")];
my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
my $w = length format_times($r,$u,$s,$firstr);
$colwidth[$i] = $w if $w > $colwidth[$i];
@ -267,7 +266,7 @@ sub print_sorted_results {
my ($prevr, $prevu, $prevs, $prevrev);
for my $i (0..$#dirs) {
my $d = $dirs[$i];
my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times");
my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.result");
if ($i > 0 and defined $r and defined $prevr and $prevr > 0) {
my $percent = 100.0 * ($r - $prevr) / $prevr;
push @evolutions, { "percent" => $percent,
@ -327,7 +326,7 @@ sub print_codespeed_results {
my $commitid = $prefixes{$d};
$commitid =~ s/^build_//;
$commitid =~ s/\.$//;
my ($result_value, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times");
my ($result_value, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.result");
my %vals = (
"commitid" => $commitid,

View file

@ -51,7 +51,7 @@ oldtime=$(echo "$oldtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/')
newtime=$(echo "$newtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/')
test $(echo "$newtime" "$oldtime" | awk '{ print ($1 > $2) }') = 1 ||
die "New time '$newtime' shoud be greater than old time '$oldtime'"
die "New time '$newtime' should be greater than old time '$oldtime'"
tmpdir=$(mktemp -d -t bisect_regression_XXXXXX) || die "Failed to create temp directory"
echo "$oldtime" >"$tmpdir/oldtime" || die "Failed to write to '$tmpdir/oldtime'"

39
third_party/git/t/perf/p1400-update-ref.sh vendored Executable file
View file

@ -0,0 +1,39 @@
#!/bin/sh
test_description="Tests performance of update-ref"
. ./perf-lib.sh
test_perf_fresh_repo
test_expect_success "setup" '
git init --bare target-repo.git &&
test_commit PRE &&
test_commit POST &&
printf "create refs/heads/%d PRE\n" $(test_seq 1000) >create &&
printf "update refs/heads/%d POST PRE\n" $(test_seq 1000) >update &&
printf "delete refs/heads/%d POST\n" $(test_seq 1000) >delete &&
git update-ref --stdin <create
'
test_perf "update-ref" '
for i in $(test_seq 1000)
do
git update-ref refs/heads/branch PRE &&
git update-ref refs/heads/branch POST PRE &&
git update-ref -d refs/heads/branch
done
'
test_perf "update-ref --stdin" '
git update-ref --stdin <update &&
git update-ref --stdin <delete &&
git update-ref --stdin <create
'
test_perf "nonatomic push" '
git push ./target-repo.git $(test_seq 1000) &&
git push --delete ./target-repo.git $(test_seq 1000)
'
test_done

View file

@ -13,35 +13,36 @@ test_expect_success 'repack' '
export PACK
'
test_perf 'index-pack 0 threads' '
# Rather than counting up and doubling each time, count down from the endpoint,
# halving each time. That ensures that our final test uses as many threads as
# CPUs, even if it isn't a power of 2.
test_expect_success 'set up thread-counting tests' '
t=$(test-tool online-cpus) &&
threads= &&
while test $t -gt 0
do
threads="$t $threads"
t=$((t / 2))
done
'
test_perf PERF_EXTRA 'index-pack 0 threads' '
rm -rf repo.git &&
git init --bare repo.git &&
GIT_DIR=repo.git git index-pack --threads=1 --stdin < $PACK
'
test_perf 'index-pack 1 thread ' '
rm -rf repo.git &&
git init --bare repo.git &&
GIT_DIR=repo.git GIT_FORCE_THREADS=1 git index-pack --threads=1 --stdin < $PACK
'
test_perf 'index-pack 2 threads' '
rm -rf repo.git &&
git init --bare repo.git &&
GIT_DIR=repo.git git index-pack --threads=2 --stdin < $PACK
'
test_perf 'index-pack 4 threads' '
rm -rf repo.git &&
git init --bare repo.git &&
GIT_DIR=repo.git git index-pack --threads=4 --stdin < $PACK
'
test_perf 'index-pack 8 threads' '
rm -rf repo.git &&
git init --bare repo.git &&
GIT_DIR=repo.git git index-pack --threads=8 --stdin < $PACK
'
for t in $threads
do
THREADS=$t
export THREADS
test_perf PERF_EXTRA "index-pack $t threads" '
rm -rf repo.git &&
git init --bare repo.git &&
GIT_DIR=repo.git GIT_FORCE_THREADS=1 \
git index-pack --threads=$THREADS --stdin <$PACK
'
done
test_perf 'index-pack default number of threads' '
rm -rf repo.git &&

View file

@ -73,10 +73,15 @@ do
git rev-list --objects --all >/dev/null
'
test_perf "abbrev-commit ($nr_packs)" '
git rev-list --abbrev-commit HEAD >/dev/null
'
# This simulates the interesting part of the repack, which is the
# actual pack generation, without smudging the on-disk setup
# between trials.
test_perf "repack ($nr_packs)" '
GIT_TEST_FULL_IN_PACK_ARRAY=1 \
git pack-objects --keep-true-parents \
--honor-pack-keep --non-empty --all \
--reflog --indexed-objects --delta-base-offset \
@ -84,4 +89,22 @@ do
'
done
# Measure pack loading with 10,000 packs.
test_expect_success 'generate lots of packs' '
for i in $(test_seq 10000); do
echo "blob"
echo "data <<EOF"
echo "blob $i"
echo "EOF"
echo "checkpoint"
done |
git -c fastimport.unpackLimit=0 fast-import
'
# The purpose of this test is to evaluate load time for a large number
# of packs while doing as little other work as possible.
test_perf "load 10,000 packs" '
git rev-parse --verify "HEAD^{commit}"
'
test_done

View file

@ -31,14 +31,37 @@ test_perf 'simulated fetch' '
} | git pack-objects --revs --stdout >/dev/null
'
test_perf 'pack to file' '
git pack-objects --all pack1 </dev/null >/dev/null
'
test_perf 'pack to file (bitmap)' '
git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null
'
test_perf 'rev-list (commits)' '
git rev-list --all --use-bitmap-index >/dev/null
'
test_perf 'rev-list (objects)' '
git rev-list --all --use-bitmap-index --objects >/dev/null
'
test_perf 'rev-list count with blob:none' '
git rev-list --use-bitmap-index --count --objects --all \
--filter=blob:none >/dev/null
'
test_perf 'rev-list count with blob:limit=1k' '
git rev-list --use-bitmap-index --count --objects --all \
--filter=blob:limit=1k >/dev/null
'
test_perf 'rev-list count with tree:0' '
git rev-list --use-bitmap-index --count --objects --all \
--filter=tree:0 >/dev/null
'
test_perf 'simulated partial clone' '
git pack-objects --stdout --all --filter=blob:none </dev/null >/dev/null
'
test_expect_success 'create partial bitmap state' '
# pick a commit to represent the repo tip in the past
cutoff=$(git rev-list HEAD~100 -1) &&
@ -68,4 +91,9 @@ test_perf 'pack to file (partial bitmap)' '
git pack-objects --use-bitmap-index --all pack2b </dev/null >/dev/null
'
test_perf 'rev-list with tree filter (partial bitmap)' '
git rev-list --use-bitmap-index --count --objects --all \
--filter=tree:0 >/dev/null
'
test_done

View file

@ -0,0 +1,23 @@
#!/bin/sh
test_description='test fast-import and fast-export performance'
. ./perf-lib.sh
test_perf_default_repo
# Use --no-data here to produce a vastly smaller export file.
# This is much cheaper to work with but should still exercise
# fast-import pretty well (we'll still process all commits and
# trees, which account for 60% or more of objects in most repos).
#
# Use --reencode to avoid the default of aborting on non-utf8 commits,
# which lets this test run against a wider variety of sample repos.
test_perf 'export (no-blobs)' '
git fast-export --reencode=yes --no-data HEAD >export
'
test_perf 'import (no-blobs)' '
git fast-import --force <export
'
test_done

View file

@ -214,7 +214,7 @@ test_perf_ () {
else
test_ok_ "$1"
fi
"$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".times
"$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".result
}
test_perf () {
@ -223,7 +223,7 @@ test_perf () {
test_size_ () {
say >&3 "running: $2"
if test_eval_ "$2" 3>"$base".size; then
if test_eval_ "$2" 3>"$base".result; then
test_ok_ "$1"
else
test_failure_ "$@"
@ -245,3 +245,5 @@ test_at_end_hook_ () {
test_export () {
export "$@"
}
test_lazy_prereq PERF_EXTRA 'test_bool_env GIT_PERF_EXTRA false'

View file

@ -20,9 +20,9 @@ modification *should* take notice and update the test vectors here.
. ./test-lib.sh
try_local_x () {
local x="local" &&
echo "$x"
try_local_xy () {
local x="local" y="alsolocal" &&
echo "$x $y"
}
# Check whether the shell supports the "local" keyword. "local" is not
@ -35,11 +35,12 @@ try_local_x () {
# relying on "local".
test_expect_success 'verify that the running shell supports "local"' '
x="notlocal" &&
echo "local" >expected1 &&
try_local_x >actual1 &&
y="alsonotlocal" &&
echo "local alsolocal" >expected1 &&
try_local_xy >actual1 &&
test_cmp expected1 actual1 &&
echo "notlocal" >expected2 &&
echo "$x" >actual2 &&
echo "notlocal alsonotlocal" >expected2 &&
echo "$x $y" >actual2 &&
test_cmp expected2 actual2
'
@ -76,9 +77,7 @@ _run_sub_test_lib_test_common () {
# the sub-test.
sane_unset HARNESS_ACTIVE &&
cd "$name" &&
cat >"$name.sh" <<-EOF &&
#!$SHELL_PATH
write_script "$name.sh" "$TEST_SHELL_PATH" <<-EOF &&
test_description='$descr (run in sub test-lib)
This is run in a sub test-lib so that we do not get incorrect
@ -93,15 +92,15 @@ _run_sub_test_lib_test_common () {
. "\$TEST_DIRECTORY"/test-lib.sh
EOF
cat >>"$name.sh" &&
chmod +x "$name.sh" &&
export TEST_DIRECTORY &&
TEST_OUTPUT_DIRECTORY=$(pwd) &&
export TEST_OUTPUT_DIRECTORY &&
sane_unset GIT_TEST_FAIL_PREREQS &&
if test -z "$neg"
then
./"$name.sh" "$@" >out 2>err
else
! ./"$name.sh" "$@" >out 2>err
! ./"$name.sh" "$@" >out 2>err
fi
)
}
@ -126,7 +125,7 @@ check_sub_test_lib_test () {
check_sub_test_lib_test_err () {
name="$1" # stdin is the expected output from the test
# expected error output is in descriptior 3
# expected error output is in descriptor 3
(
cd "$name" &&
sed -e 's/^> //' -e 's/Z$//' >expect.out &&
@ -154,7 +153,7 @@ test_expect_success 'pretend we have a fully passing test suite' "
"
test_expect_success 'pretend we have a partially passing test suite' "
test_must_fail run_sub_test_lib_test \
run_sub_test_lib_test_err \
partial-pass '2/3 tests passing' <<-\\EOF &&
test_expect_success 'passing test #1' 'true'
test_expect_success 'failing test #2' 'false'
@ -218,7 +217,7 @@ test_expect_success 'pretend we have fixed one of two known breakages (run in su
"
test_expect_success 'pretend we have a pass, fail, and known breakage' "
test_must_fail run_sub_test_lib_test \
run_sub_test_lib_test_err \
mixed-results1 'mixed results #1' <<-\\EOF &&
test_expect_success 'passing test' 'true'
test_expect_success 'failing test' 'false'
@ -237,7 +236,7 @@ test_expect_success 'pretend we have a pass, fail, and known breakage' "
"
test_expect_success 'pretend we have a mix of all possible results' "
test_must_fail run_sub_test_lib_test \
run_sub_test_lib_test_err \
mixed-results2 'mixed results #2' <<-\\EOF &&
test_expect_success 'passing test' 'true'
test_expect_success 'passing test' 'true'
@ -273,24 +272,24 @@ test_expect_success 'pretend we have a mix of all possible results' "
"
test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
test_must_fail run_sub_test_lib_test \
test-verbose "test verbose" --verbose <<-\EOF &&
run_sub_test_lib_test_err \
t1234-verbose "test verbose" --verbose <<-\EOF &&
test_expect_success "passing test" true
test_expect_success "test with output" "echo foo"
test_expect_success "failing test" false
test_done
EOF
mv test-verbose/out test-verbose/out+ &&
grep -v "^Initialized empty" test-verbose/out+ >test-verbose/out &&
check_sub_test_lib_test test-verbose <<-\EOF
> expecting success: true
mv t1234-verbose/out t1234-verbose/out+ &&
grep -v "^Initialized empty" t1234-verbose/out+ >t1234-verbose/out &&
check_sub_test_lib_test t1234-verbose <<-\EOF
> expecting success of 1234.1 '\''passing test'\'': true
> ok 1 - passing test
> Z
> expecting success: echo foo
> expecting success of 1234.2 '\''test with output'\'': echo foo
> foo
> ok 2 - test with output
> Z
> expecting success: false
> expecting success of 1234.3 '\''failing test'\'': false
> not ok 3 - failing test
> # false
> Z
@ -300,18 +299,18 @@ test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
'
test_expect_success 'test --verbose-only' '
test_must_fail run_sub_test_lib_test \
test-verbose-only-2 "test verbose-only=2" \
run_sub_test_lib_test_err \
t2345-verbose-only-2 "test verbose-only=2" \
--verbose-only=2 <<-\EOF &&
test_expect_success "passing test" true
test_expect_success "test with output" "echo foo"
test_expect_success "failing test" false
test_done
EOF
check_sub_test_lib_test test-verbose-only-2 <<-\EOF
check_sub_test_lib_test t2345-verbose-only-2 <<-\EOF
> ok 1 - passing test
> Z
> expecting success: echo foo
> expecting success of 2345.2 '\''test with output'\'': echo foo
> foo
> ok 2 - test with output
> Z
@ -391,6 +390,44 @@ test_expect_success 'GIT_SKIP_TESTS sh pattern' "
)
"
test_expect_success 'GIT_SKIP_TESTS entire suite' "
(
GIT_SKIP_TESTS='git' && export GIT_SKIP_TESTS &&
run_sub_test_lib_test git-skip-tests-entire-suite \
'GIT_SKIP_TESTS entire suite' <<-\\EOF &&
for i in 1 2 3
do
test_expect_success \"passing test #\$i\" 'true'
done
test_done
EOF
check_sub_test_lib_test git-skip-tests-entire-suite <<-\\EOF
> 1..0 # SKIP skip all tests in git
EOF
)
"
test_expect_success 'GIT_SKIP_TESTS does not skip unmatched suite' "
(
GIT_SKIP_TESTS='notgit' && export GIT_SKIP_TESTS &&
run_sub_test_lib_test git-skip-tests-unmatched-suite \
'GIT_SKIP_TESTS does not skip unmatched suite' <<-\\EOF &&
for i in 1 2 3
do
test_expect_success \"passing test #\$i\" 'true'
done
test_done
EOF
check_sub_test_lib_test git-skip-tests-unmatched-suite <<-\\EOF
> ok 1 - passing test #1
> ok 2 - passing test #2
> ok 3 - passing test #3
> # passed all 3 test(s)
> 1..3
EOF
)
"
test_expect_success '--run basic' "
run_sub_test_lib_test run-basic \
'--run basic' --run='1 3 5' <<-\\EOF &&
@ -794,8 +831,21 @@ then
exit 1
fi
test_expect_success 'lazy prereqs do not turn off tracing' "
run_sub_test_lib_test lazy-prereq-and-tracing \
'lazy prereqs and -x' -v -x <<-\\EOF &&
test_lazy_prereq LAZY true
test_expect_success lazy 'test_have_prereq LAZY && echo trace'
test_done
EOF
grep 'echo trace' lazy-prereq-and-tracing/err
"
test_expect_success 'tests clean up even on failures' "
test_must_fail run_sub_test_lib_test \
run_sub_test_lib_test_err \
failing-cleanup 'Failing tests with cleanup commands' <<-\\EOF &&
test_expect_success 'tests clean up even after a failure' '
touch clean-after-failure &&
@ -824,7 +874,7 @@ test_expect_success 'tests clean up even on failures' "
"
test_expect_success 'test_atexit is run' "
test_must_fail run_sub_test_lib_test \
run_sub_test_lib_test_err \
atexit-cleanup 'Run atexit commands' -i <<-\\EOF &&
test_expect_success 'tests clean up even after a failure' '
> ../../clean-atexit &&
@ -841,10 +891,6 @@ test_expect_success 'test_atexit is run' "
test_path_is_missing also-clean-atexit
"
test_expect_success 'test_oid setup' '
test_oid_init
'
test_expect_success 'test_oid provides sane info by default' '
test_oid zero >actual &&
grep "^00*\$" actual &&
@ -878,6 +924,51 @@ test_expect_success 'test_oid can look up data for SHA-256' '
test "$hexsz" -eq 64
'
test_expect_success 'test_oid can look up data for a specified algorithm' '
rawsz="$(test_oid --hash=sha1 rawsz)" &&
hexsz="$(test_oid --hash=sha1 hexsz)" &&
test "$rawsz" -eq 20 &&
test "$hexsz" -eq 40 &&
rawsz="$(test_oid --hash=sha256 rawsz)" &&
hexsz="$(test_oid --hash=sha256 hexsz)" &&
test "$rawsz" -eq 32 &&
test "$hexsz" -eq 64
'
test_expect_success 'test_bool_env' '
(
sane_unset envvar &&
test_bool_env envvar true &&
! test_bool_env envvar false &&
envvar= &&
export envvar &&
! test_bool_env envvar true &&
! test_bool_env envvar false &&
envvar=true &&
test_bool_env envvar true &&
test_bool_env envvar false &&
envvar=false &&
! test_bool_env envvar true &&
! test_bool_env envvar false &&
envvar=invalid &&
# When encountering an invalid bool value, test_bool_env
# prints its error message to the original stderr of the
# test script, hence the redirection of fd 7, and aborts
# with "exit 1", hence the subshell.
! ( test_bool_env envvar true ) 7>err &&
grep "error: test_bool_env requires bool values" err &&
envvar=true &&
! ( test_bool_env envvar invalid ) 7>err &&
grep "error: test_bool_env requires bool values" err
)
'
################################################################
# Basics of the basics
@ -1187,4 +1278,22 @@ test_expect_success 'very long name in the index handled sanely' '
test $len = 4098
'
test_expect_success 'test_must_fail on a failing git command' '
test_must_fail git notacommand
'
test_expect_success 'test_must_fail on a failing git command with env' '
test_must_fail env var1=a var2=b git notacommand
'
test_expect_success 'test_must_fail rejects a non-git command' '
! test_must_fail grep ^$ notafile 2>err &&
grep -F "test_must_fail: only '"'"'git'"'"' is allowed" err
'
test_expect_success 'test_must_fail rejects a non-git command with env' '
! test_must_fail env var1=a var2=b grep ^$ notafile 2>err &&
grep -F "test_must_fail: only '"'"'git'"'"' is allowed" err
'
test_done

View file

@ -316,6 +316,28 @@ test_expect_success 'init with separate gitdir' '
test_path_is_dir realgitdir/refs
'
test_expect_success 'explicit bare & --separate-git-dir incompatible' '
test_must_fail git init --bare --separate-git-dir goop.git bare.git 2>err &&
test_i18ngrep "mutually exclusive" err
'
test_expect_success 'implicit bare & --separate-git-dir incompatible' '
test_when_finished "rm -rf bare.git" &&
mkdir -p bare.git &&
test_must_fail env GIT_DIR=. \
git -C bare.git init --separate-git-dir goop.git 2>err &&
test_i18ngrep "incompatible" err
'
test_expect_success 'bare & --separate-git-dir incompatible within worktree' '
test_when_finished "rm -rf bare.git linkwt seprepo" &&
test_commit gumby &&
git clone --bare . bare.git &&
git -C bare.git worktree add --detach ../linkwt &&
test_must_fail git -C linkwt init --separate-git-dir seprepo 2>err &&
test_i18ngrep "incompatible" err
'
test_lazy_prereq GETCWD_IGNORES_PERMS '
base=GETCWD_TEST_BASE_DIR &&
mkdir -p $base/dir &&
@ -392,13 +414,25 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' '
test_path_is_dir realgitdir/refs
'
# Tests for the hidden file attribute on windows
is_hidden () {
# Use the output of `attrib`, ignore the absolute path
case "$(attrib "$1")" in *H*?:*) return 0;; esac
return 1
sep_git_dir_worktree () {
test_when_finished "rm -rf mainwt linkwt seprepo" &&
git init mainwt &&
test_commit -C mainwt gumby &&
git -C mainwt worktree add --detach ../linkwt &&
git -C "$1" init --separate-git-dir ../seprepo &&
git -C mainwt rev-parse --git-common-dir >expect &&
git -C linkwt rev-parse --git-common-dir >actual &&
test_cmp expect actual
}
test_expect_success 're-init to move gitdir with linked worktrees' '
sep_git_dir_worktree mainwt
'
test_expect_success 're-init to move gitdir within linked worktree' '
sep_git_dir_worktree linkwt
'
test_expect_success MINGW '.git hidden' '
rm -rf newdir &&
(
@ -406,7 +440,7 @@ test_expect_success MINGW '.git hidden' '
mkdir newdir &&
cd newdir &&
git init &&
is_hidden .git
test_path_is_hidden .git
) &&
check_config newdir/.git false unset
'
@ -448,6 +482,39 @@ test_expect_success 're-init from a linked worktree' '
)
'
test_expect_success 'init honors GIT_DEFAULT_HASH' '
GIT_DEFAULT_HASH=sha1 git init sha1 &&
git -C sha1 rev-parse --show-object-format >actual &&
echo sha1 >expected &&
test_cmp expected actual &&
GIT_DEFAULT_HASH=sha256 git init sha256 &&
git -C sha256 rev-parse --show-object-format >actual &&
echo sha256 >expected &&
test_cmp expected actual
'
test_expect_success 'init honors --object-format' '
git init --object-format=sha1 explicit-sha1 &&
git -C explicit-sha1 rev-parse --show-object-format >actual &&
echo sha1 >expected &&
test_cmp expected actual &&
git init --object-format=sha256 explicit-sha256 &&
git -C explicit-sha256 rev-parse --show-object-format >actual &&
echo sha256 >expected &&
test_cmp expected actual
'
test_expect_success 'extensions.objectFormat is not allowed with repo version 0' '
git init --object-format=sha256 explicit-v0 &&
git -C explicit-v0 config core.repositoryformatversion 0 &&
test_must_fail git -C explicit-v0 rev-parse --show-object-format
'
test_expect_success 'init rejects attempts to initialize with different hash' '
test_must_fail git -C sha1 init --object-format=sha256 &&
test_must_fail git -C sha256 init --object-format=sha1
'
test_expect_success MINGW 'core.hidedotfiles = false' '
git config --global core.hidedotfiles false &&
rm -rf newdir &&
@ -471,4 +538,30 @@ test_expect_success MINGW 'redirect std handles' '
grep "Needed a single revision" output.txt
'
test_expect_success '--initial-branch' '
git init --initial-branch=hello initial-branch-option &&
git -C initial-branch-option symbolic-ref HEAD >actual &&
echo refs/heads/hello >expect &&
test_cmp expect actual &&
: re-initializing should not change the branch name &&
git init --initial-branch=ignore initial-branch-option 2>err &&
test_i18ngrep "ignored --initial-branch" err &&
git -C initial-branch-option symbolic-ref HEAD >actual &&
grep hello actual
'
test_expect_success 'overridden default initial branch name (config)' '
test_config_global init.defaultBranch nmb &&
git init initial-branch-config &&
git -C initial-branch-config symbolic-ref HEAD >actual &&
grep nmb actual
'
test_expect_success 'invalid default branch name' '
test_config_global init.defaultBranch "with space" &&
test_must_fail git init initial-branch-invalid 2>err &&
test_i18ngrep "invalid branch name" err
'
test_done

View file

@ -62,7 +62,7 @@ test_expect_success 'check commit-tree' '
'
test_expect_success 'check rev-list' '
echo $SHA >"$REAL/HEAD" &&
git update-ref "HEAD" "$SHA" &&
test "$SHA" = "$(git rev-list HEAD)"
'

View file

@ -5,19 +5,16 @@ test_description=gitattributes
. ./test-lib.sh
attr_check () {
path="$1" expect="$2"
path="$1" expect="$2" git_opts="$3" &&
git $3 check-attr test -- "$path" >actual 2>err &&
echo "$path: test: $2" >expect &&
git $git_opts check-attr test -- "$path" >actual 2>err &&
echo "$path: test: $expect" >expect &&
test_cmp expect actual &&
test_line_count = 0 err
test_must_be_empty err
}
attr_check_quote () {
path="$1"
quoted_path="$2"
expect="$3"
path="$1" quoted_path="$2" expect="$3" &&
git check-attr test -- "$path" >actual &&
echo "\"$quoted_path\": test: $expect" >expect &&
@ -27,7 +24,7 @@ attr_check_quote () {
test_expect_success 'open-quoted pathname' '
echo "\"a test=a" >.gitattributes &&
test_must_fail attr_check a a
attr_check a unspecified
'
@ -112,20 +109,20 @@ test_expect_success 'attribute test' '
test_expect_success 'attribute matching is case sensitive when core.ignorecase=0' '
test_must_fail attr_check F f "-c core.ignorecase=0" &&
test_must_fail attr_check a/F f "-c core.ignorecase=0" &&
test_must_fail attr_check a/c/F f "-c core.ignorecase=0" &&
test_must_fail attr_check a/G a/g "-c core.ignorecase=0" &&
test_must_fail attr_check a/B/g a/b/g "-c core.ignorecase=0" &&
test_must_fail attr_check a/b/G a/b/g "-c core.ignorecase=0" &&
test_must_fail attr_check a/b/H a/b/h "-c core.ignorecase=0" &&
test_must_fail attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=0" &&
test_must_fail attr_check oNoFf unset "-c core.ignorecase=0" &&
test_must_fail attr_check oFfOn set "-c core.ignorecase=0" &&
attr_check F unspecified "-c core.ignorecase=0" &&
attr_check a/F unspecified "-c core.ignorecase=0" &&
attr_check a/c/F unspecified "-c core.ignorecase=0" &&
attr_check a/G unspecified "-c core.ignorecase=0" &&
attr_check a/B/g a/g "-c core.ignorecase=0" &&
attr_check a/b/G unspecified "-c core.ignorecase=0" &&
attr_check a/b/H unspecified "-c core.ignorecase=0" &&
attr_check a/b/D/g a/g "-c core.ignorecase=0" &&
attr_check oNoFf unspecified "-c core.ignorecase=0" &&
attr_check oFfOn unspecified "-c core.ignorecase=0" &&
attr_check NO unspecified "-c core.ignorecase=0" &&
test_must_fail attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
attr_check a/b/D/NO unspecified "-c core.ignorecase=0" &&
attr_check a/b/d/YES a/b/d/* "-c core.ignorecase=0" &&
test_must_fail attr_check a/E/f "A/e/F" "-c core.ignorecase=0"
attr_check a/E/f f "-c core.ignorecase=0"
'
@ -149,8 +146,8 @@ test_expect_success 'attribute matching is case insensitive when core.ignorecase
'
test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
attr_check a/B/D/g a/g "-c core.ignorecase=0" &&
attr_check A/B/D/NO unspecified "-c core.ignorecase=0" &&
attr_check A/b/h a/b/h "-c core.ignorecase=1" &&
attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" &&
attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1"
@ -244,7 +241,7 @@ EOF
git check-attr foo -- "a/b/f" >>actual 2>>err &&
git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
test_cmp expect actual &&
test_line_count = 0 err
test_must_be_empty err
'
test_expect_success '"**" with no slashes test' '
@ -265,7 +262,7 @@ EOF
git check-attr foo -- "a/b/f" >>actual 2>>err &&
git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
test_cmp expect actual &&
test_line_count = 0 err
test_must_be_empty err
'
test_expect_success 'using --git-dir and --work-tree' '

View file

@ -83,6 +83,11 @@ check_parse 2008-02 bad
check_parse 2008-02-14 bad
check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 +0000'
check_parse '2008-02-14 20:30:45 -0500' '2008-02-14 20:30:45 -0500'
check_parse '2008.02.14 20:30:45 -0500' '2008-02-14 20:30:45 -0500'
check_parse '20080214T203045-04:00' '2008-02-14 20:30:45 -0400'
check_parse '20080214T203045 -04:00' '2008-02-14 20:30:45 -0400'
check_parse '20080214T203045.019-04:00' '2008-02-14 20:30:45 -0400'
check_parse '2008-02-14 20:30:45.019-04:00' '2008-02-14 20:30:45 -0400'
check_parse '2008-02-14 20:30:45 -0015' '2008-02-14 20:30:45 -0015'
check_parse '2008-02-14 20:30:45 -5' '2008-02-14 20:30:45 +0000'
check_parse '2008-02-14 20:30:45 -5:' '2008-02-14 20:30:45 +0000'
@ -105,6 +110,7 @@ check_approxidate 5.seconds.ago '2009-08-30 19:19:55'
check_approxidate 10.minutes.ago '2009-08-30 19:10:00'
check_approxidate yesterday '2009-08-29 19:20:00'
check_approxidate 3.days.ago '2009-08-27 19:20:00'
check_approxidate '12:34:56.3.days.ago' '2009-08-27 12:34:56'
check_approxidate 3.weeks.ago '2009-08-09 19:20:00'
check_approxidate 3.months.ago '2009-05-30 19:20:00'
check_approxidate 2.years.3.months.ago '2007-05-30 19:20:00'

View file

@ -17,7 +17,7 @@ test_expect_success 'get GIT_COMMITTER_IDENT' '
test_cmp expect actual
'
test_expect_success !FAIL_PREREQS,!AUTOIDENT 'requested identites are strict' '
test_expect_success !FAIL_PREREQS,!AUTOIDENT 'requested identities are strict' '
(
sane_unset GIT_COMMITTER_NAME &&
sane_unset GIT_COMMITTER_EMAIL &&

View file

@ -424,9 +424,24 @@ test_expect_success 'local ignore inside a sub-directory with --verbose' '
)
'
test_expect_success_multi 'nested include' \
'a/b/.gitignore:8:!on* a/b/one' '
test_check_ignore "a/b/one"
test_expect_success 'nested include of negated pattern' '
expect "" &&
test_check_ignore "a/b/one" 1
'
test_expect_success 'nested include of negated pattern with -q' '
expect "" &&
test_check_ignore "-q a/b/one" 1
'
test_expect_success 'nested include of negated pattern with -v' '
expect "a/b/.gitignore:8:!on* a/b/one" &&
test_check_ignore "-v a/b/one" 0
'
test_expect_success 'nested include of negated pattern with -v -n' '
expect "a/b/.gitignore:8:!on* a/b/one" &&
test_check_ignore "-v -n a/b/one" 0
'
############################################################################
@ -460,7 +475,6 @@ test_expect_success 'cd to ignored sub-directory' '
expect_from_stdin <<-\EOF &&
foo
twoooo
../one
seven
../../one
EOF
@ -543,7 +557,6 @@ test_expect_success 'global ignore' '
globalthree
a/globalthree
a/per-repo
globaltwo
EOF
test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
'
@ -586,17 +599,7 @@ EOF
cat <<-\EOF >expected-default
one
a/one
a/b/on
a/b/one
a/b/one one
a/b/one two
"a/b/one\"three"
a/b/two
a/b/twooo
globaltwo
a/globaltwo
a/b/globaltwo
b/globaltwo
EOF
cat <<-EOF >expected-verbose
.gitignore:1:one one
@ -696,8 +699,12 @@ cat <<-EOF >expected-all
$global_excludes:2:!globaltwo ../b/globaltwo
:: c/not-ignored
EOF
cat <<-EOF >expected-default
../one
one
b/twooo
EOF
grep -v '^:: ' expected-all >expected-verbose
sed -e 's/.* //' expected-verbose >expected-default
broken_c_unquote stdin >stdin0

View file

@ -37,4 +37,11 @@ test_expect_success 'looping aliases - internal execution' '
# test_i18ngrep "^fatal: alias loop detected: expansion of" output
#'
test_expect_success 'run-command formats empty args properly' '
test_must_fail env GIT_TRACE=1 git frotz a "" b " " c 2>actual.raw &&
sed -ne "/run_command:/s/.*trace: run_command: //p" actual.raw >actual &&
echo "git-frotz a '\'''\'' b '\'' '\'' c" >expect &&
test_cmp expect actual
'
test_done

32
third_party/git/t/t0018-advice.sh vendored Executable file
View file

@ -0,0 +1,32 @@
#!/bin/sh
test_description='Test advise_if_enabled functionality'
. ./test-lib.sh
test_expect_success 'advice should be printed when config variable is unset' '
cat >expect <<-\EOF &&
hint: This is a piece of advice
hint: Disable this message with "git config advice.nestedTag false"
EOF
test-tool advise "This is a piece of advice" 2>actual &&
test_i18ncmp expect actual
'
test_expect_success 'advice should be printed when config variable is set to true' '
cat >expect <<-\EOF &&
hint: This is a piece of advice
hint: Disable this message with "git config advice.nestedTag false"
EOF
test_config advice.nestedTag true &&
test-tool advise "This is a piece of advice" 2>actual &&
test_i18ncmp expect actual
'
test_expect_success 'advice should not be printed when config variable is set to false' '
test_config advice.nestedTag false &&
test-tool advise "This is a piece of advice" 2>actual &&
test_must_be_empty actual
'
test_done

View file

@ -159,8 +159,8 @@ test_expect_success 'checkout with autocrlf=input' '
rm -f tmp one dir/two three &&
git config core.autocrlf input &&
git read-tree --reset -u HEAD &&
test_must_fail has_cr one &&
test_must_fail has_cr dir/two &&
! has_cr one &&
! has_cr dir/two &&
git update-index -- one dir/two &&
test "$one" = $(git hash-object --stdin <one) &&
test "$two" = $(git hash-object --stdin <dir/two) &&
@ -237,9 +237,9 @@ test_expect_success '.gitattributes says two is binary' '
git config core.autocrlf true &&
git read-tree --reset -u HEAD &&
test_must_fail has_cr dir/two &&
! has_cr dir/two &&
verbose has_cr one &&
test_must_fail has_cr three
! has_cr three
'
test_expect_success '.gitattributes says two is input' '
@ -248,7 +248,7 @@ test_expect_success '.gitattributes says two is input' '
echo "two crlf=input" >.gitattributes &&
git read-tree --reset -u HEAD &&
test_must_fail has_cr dir/two
! has_cr dir/two
'
test_expect_success '.gitattributes says two and three are text' '
@ -270,7 +270,7 @@ test_expect_success 'in-tree .gitattributes (1)' '
rm -rf tmp one dir .gitattributes patch.file three &&
git read-tree --reset -u HEAD &&
test_must_fail has_cr one &&
! has_cr one &&
verbose has_cr three
'
@ -280,7 +280,7 @@ test_expect_success 'in-tree .gitattributes (2)' '
git read-tree --reset HEAD &&
git checkout-index -f -q -u -a &&
test_must_fail has_cr one &&
! has_cr one &&
verbose has_cr three
'
@ -291,7 +291,7 @@ test_expect_success 'in-tree .gitattributes (3)' '
git checkout-index -u .gitattributes &&
git checkout-index -u one dir/two three &&
test_must_fail has_cr one &&
! has_cr one &&
verbose has_cr three
'
@ -302,7 +302,7 @@ test_expect_success 'in-tree .gitattributes (4)' '
git checkout-index -u one dir/two three &&
git checkout-index -u .gitattributes &&
test_must_fail has_cr one &&
! has_cr one &&
verbose has_cr three
'

View file

@ -35,7 +35,7 @@ filter_git () {
# Compare two files and ensure that `clean` and `smudge` respectively are
# called at least once if specified in the `expect` file. The actual
# invocation count is not relevant because their number can vary.
# c.f. http://public-inbox.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
# c.f. http://lore.kernel.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
test_cmp_count () {
expect=$1
actual=$2
@ -50,7 +50,7 @@ test_cmp_count () {
# Compare two files but exclude all `clean` invocations because Git can
# call `clean` zero or more times.
# c.f. http://public-inbox.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
# c.f. http://lore.kernel.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/
test_cmp_exclude_clean () {
expect=$1
actual=$2
@ -364,6 +364,10 @@ test_expect_success PERL 'required process filter should filter data' '
S=$(file_size test.r) &&
S2=$(file_size test2.r) &&
S3=$(file_size "testsubdir/test3 '\''sq'\'',\$x=.r") &&
M=$(git hash-object test.r) &&
M2=$(git hash-object test2.r) &&
M3=$(git hash-object "testsubdir/test3 '\''sq'\'',\$x=.r") &&
EMPTY=$(git hash-object /dev/null) &&
filter_git add . &&
cat >expected.log <<-EOF &&
@ -378,18 +382,23 @@ test_expect_success PERL 'required process filter should filter data' '
test_cmp_count expected.log debug.log &&
git commit -m "test commit 2" &&
MASTER=$(git rev-parse --verify master) &&
META="ref=refs/heads/master treeish=$MASTER" &&
rm -f test2.r "testsubdir/test3 '\''sq'\'',\$x=.r" &&
filter_git checkout --quiet --no-progress . &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $S3 [OK] -- OUT: $S3 . [OK]
IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
# Make sure that the file appears dirty, so checkout below has to
# run the configured filter.
touch test.r &&
filter_git checkout --quiet --no-progress empty-branch &&
cat >expected.log <<-EOF &&
START
@ -403,10 +412,10 @@ test_expect_success PERL 'required process filter should filter data' '
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test.r $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r 0 [OK] -- OUT: 0 [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $S3 [OK] -- OUT: $S3 . [OK]
IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@ -417,6 +426,117 @@ test_expect_success PERL 'required process filter should filter data' '
)
'
test_expect_success PERL 'required process filter should filter data for various subcommands' '
test_config_global filter.protocol.process "rot13-filter.pl debug.log clean smudge" &&
test_config_global filter.protocol.required true &&
(
cd repo &&
S=$(file_size test.r) &&
S2=$(file_size test2.r) &&
S3=$(file_size "testsubdir/test3 '\''sq'\'',\$x=.r") &&
M=$(git hash-object test.r) &&
M2=$(git hash-object test2.r) &&
M3=$(git hash-object "testsubdir/test3 '\''sq'\'',\$x=.r") &&
EMPTY=$(git hash-object /dev/null) &&
MASTER=$(git rev-parse --verify master) &&
cp "$TEST_ROOT/test.o" test5.r &&
git add test5.r &&
git commit -m "test commit 3" &&
git checkout empty-branch &&
filter_git rebase --onto empty-branch master^^ master &&
MASTER2=$(git rev-parse --verify master) &&
META="ref=refs/heads/master treeish=$MASTER2" &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
git reset --hard empty-branch &&
filter_git reset --hard $MASTER &&
META="treeish=$MASTER" &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
git branch old-master $MASTER &&
git reset --hard empty-branch &&
filter_git reset --hard old-master &&
META="ref=refs/heads/old-master treeish=$MASTER" &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
git checkout -b merge empty-branch &&
git branch -f master $MASTER2 &&
filter_git merge master &&
META="treeish=$MASTER2" &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
filter_git archive master >/dev/null &&
META="ref=refs/heads/master treeish=$MASTER2" &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
TREE="$(git rev-parse $MASTER2^{tree})" &&
filter_git archive $TREE >/dev/null &&
META="treeish=$TREE" &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
IN: smudge test5.r $META blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log
)
'
test_expect_success PERL 'required process filter takes precedence' '
test_config_global filter.protocol.clean false &&
test_config_global filter.protocol.process "rot13-filter.pl debug.log clean" &&
@ -516,17 +636,22 @@ test_expect_success PERL 'required process filter should process multiple packet
EOF
test_cmp_count expected.log debug.log &&
rm -f *.file &&
M1="blob=$(git hash-object 1pkt_1__.file)" &&
M2="blob=$(git hash-object 2pkt_1+1.file)" &&
M3="blob=$(git hash-object 2pkt_2-1.file)" &&
M4="blob=$(git hash-object 2pkt_2__.file)" &&
M5="blob=$(git hash-object 3pkt_2+1.file)" &&
rm -f *.file debug.log &&
filter_git checkout --quiet --no-progress -- *.file &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge 1pkt_1__.file $(($S )) [OK] -- OUT: $(($S )) . [OK]
IN: smudge 2pkt_1+1.file $(($S +1)) [OK] -- OUT: $(($S +1)) .. [OK]
IN: smudge 2pkt_2-1.file $(($S*2-1)) [OK] -- OUT: $(($S*2-1)) .. [OK]
IN: smudge 2pkt_2__.file $(($S*2 )) [OK] -- OUT: $(($S*2 )) .. [OK]
IN: smudge 3pkt_2+1.file $(($S*2+1)) [OK] -- OUT: $(($S*2+1)) ... [OK]
IN: smudge 1pkt_1__.file $M1 $(($S )) [OK] -- OUT: $(($S )) . [OK]
IN: smudge 2pkt_1+1.file $M2 $(($S +1)) [OK] -- OUT: $(($S +1)) .. [OK]
IN: smudge 2pkt_2-1.file $M3 $(($S*2-1)) [OK] -- OUT: $(($S*2-1)) .. [OK]
IN: smudge 2pkt_2__.file $M4 $(($S*2 )) [OK] -- OUT: $(($S*2 )) .. [OK]
IN: smudge 3pkt_2+1.file $M5 $(($S*2+1)) [OK] -- OUT: $(($S*2+1)) ... [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@ -575,6 +700,10 @@ test_expect_success PERL 'process filter should restart after unexpected write f
S=$(file_size test.r) &&
S2=$(file_size test2.r) &&
SF=$(file_size smudge-write-fail.r) &&
M=$(git hash-object test.r) &&
M2=$(git hash-object test2.r) &&
MF=$(git hash-object smudge-write-fail.r) &&
rm -f debug.log &&
git add . &&
rm -f *.r &&
@ -588,11 +717,11 @@ test_expect_success PERL 'process filter should restart after unexpected write f
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge smudge-write-fail.r $SF [OK] -- [WRITE FAIL]
IN: smudge smudge-write-fail.r blob=$MF $SF [OK] -- [WRITE FAIL]
START
init handshake complete
IN: smudge test.r $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge test.r blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@ -626,6 +755,10 @@ test_expect_success PERL 'process filter should not be restarted if it signals a
S=$(file_size test.r) &&
S2=$(file_size test2.r) &&
SE=$(file_size error.r) &&
M=$(git hash-object test.r) &&
M2=$(git hash-object test2.r) &&
ME=$(git hash-object error.r) &&
rm -f debug.log &&
git add . &&
rm -f *.r &&
@ -634,9 +767,9 @@ test_expect_success PERL 'process filter should not be restarted if it signals a
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge error.r $SE [OK] -- [ERROR]
IN: smudge test.r $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
IN: smudge error.r blob=$ME $SE [OK] -- [ERROR]
IN: smudge test.r blob=$M $S [OK] -- OUT: $S . [OK]
IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@ -662,18 +795,21 @@ test_expect_success PERL 'process filter abort stops processing of all further f
echo "error this blob and all future blobs" >abort.o &&
cp abort.o abort.r &&
M="blob=$(git hash-object abort.r)" &&
rm -f debug.log &&
SA=$(file_size abort.r) &&
git add . &&
rm -f *.r &&
# Note: This test assumes that Git filters files in alphabetical
# order ("abort.r" before "test.r").
filter_git checkout --quiet --no-progress . &&
cat >expected.log <<-EOF &&
START
init handshake complete
IN: smudge abort.r $SA [OK] -- [ABORT]
IN: smudge abort.r $M $SA [OK] -- [ABORT]
STOP
EOF
test_cmp_exclude_clean expected.log debug.log &&
@ -724,27 +860,29 @@ test_expect_success PERL 'delayed checkout in process filter' '
) &&
S=$(file_size "$TEST_ROOT/test.o") &&
PM="ref=refs/heads/master treeish=$(git -C repo rev-parse --verify master) " &&
M="${PM}blob=$(git -C repo rev-parse --verify master:test.a)" &&
cat >a.exp <<-EOF &&
START
init handshake complete
IN: smudge test.a $S [OK] -- OUT: $S . [OK]
IN: smudge test-delay10.a $S [OK] -- [DELAYED]
IN: smudge test-delay11.a $S [OK] -- [DELAYED]
IN: smudge test-delay20.a $S [OK] -- [DELAYED]
IN: smudge test.a $M $S [OK] -- OUT: $S . [OK]
IN: smudge test-delay10.a $M $S [OK] -- [DELAYED]
IN: smudge test-delay11.a $M $S [OK] -- [DELAYED]
IN: smudge test-delay20.a $M $S [OK] -- [DELAYED]
IN: list_available_blobs test-delay10.a test-delay11.a [OK]
IN: smudge test-delay10.a 0 [OK] -- OUT: $S . [OK]
IN: smudge test-delay11.a 0 [OK] -- OUT: $S . [OK]
IN: smudge test-delay10.a $M 0 [OK] -- OUT: $S . [OK]
IN: smudge test-delay11.a $M 0 [OK] -- OUT: $S . [OK]
IN: list_available_blobs test-delay20.a [OK]
IN: smudge test-delay20.a 0 [OK] -- OUT: $S . [OK]
IN: smudge test-delay20.a $M 0 [OK] -- OUT: $S . [OK]
IN: list_available_blobs [OK]
STOP
EOF
cat >b.exp <<-EOF &&
START
init handshake complete
IN: smudge test-delay10.b $S [OK] -- [DELAYED]
IN: smudge test-delay10.b $M $S [OK] -- [DELAYED]
IN: list_available_blobs test-delay10.b [OK]
IN: smudge test-delay10.b 0 [OK] -- OUT: $S . [OK]
IN: smudge test-delay10.b $M 0 [OK] -- OUT: $S . [OK]
IN: list_available_blobs [OK]
STOP
EOF
@ -764,8 +902,11 @@ test_expect_success PERL 'delayed checkout in process filter' '
rm *.a *.b &&
filter_git checkout . &&
test_cmp_count ../a.exp a.log &&
test_cmp_count ../b.exp b.log &&
# We are not checking out a ref here, so filter out ref metadata.
sed -e "s!$PM!!" ../a.exp >a.exp.filtered &&
sed -e "s!$PM!!" ../b.exp >b.exp.filtered &&
test_cmp_count a.exp.filtered a.log &&
test_cmp_count b.exp.filtered b.log &&
test_cmp_committed_rot13 "$TEST_ROOT/test.o" test.a &&
test_cmp_committed_rot13 "$TEST_ROOT/test.o" test-delay10.a &&
@ -792,7 +933,6 @@ test_expect_success PERL 'missing file in delayed checkout' '
rm -rf repo-cloned &&
test_must_fail git clone repo repo-cloned 2>git-stderr.log &&
cat git-stderr.log &&
grep "error: .missing-delay\.a. was not filtered properly" git-stderr.log
'

View file

@ -135,7 +135,13 @@ while (1) {
if ( exists $DELAY{$pathname} and $DELAY{$pathname}{"requested"} == 0 ) {
$DELAY{$pathname}{"requested"} = 1;
}
} elsif ($buffer =~ /^(ref|treeish|blob)=/) {
print $debug " $buffer";
} else {
# In general, filters need to be graceful about
# new metadata, since it's documented that we
# can pass any key-value pairs, but for tests,
# let's be a little stricter.
die "Unknown message '$buffer'";
}

View file

@ -215,7 +215,7 @@ stats_ascii () {
}
# contruct the attr/ returned by git ls-files --eol
# construct the attr/ returned by git ls-files --eol
# Take none (=empty), one or two args
# convert.c: eol=XX overrides text=auto
attr_ascii () {

View file

@ -17,7 +17,7 @@ test_lazy_prereq NO_UTF32_BOM '
write_utf16 () {
if test_have_prereq NO_UTF16_BOM
then
printf '\xfe\xff'
printf '\376\377'
fi &&
iconv -f UTF-8 -t UTF-16
}
@ -25,7 +25,7 @@ write_utf16 () {
write_utf32 () {
if test_have_prereq NO_UTF32_BOM
then
printf '\x00\x00\xfe\xff'
printf '\0\0\376\377'
fi &&
iconv -f UTF-8 -t UTF-32
}
@ -40,7 +40,7 @@ test_expect_success 'setup test files' '
printf "$text" | write_utf16 >test.utf16.raw &&
printf "$text" | write_utf32 >test.utf32.raw &&
printf "\377\376" >test.utf16lebom.raw &&
printf "$text" | iconv -f UTF-8 -t UTF-32LE >>test.utf16lebom.raw &&
printf "$text" | iconv -f UTF-8 -t UTF-16LE >>test.utf16lebom.raw &&
# Line ending tests
printf "one\ntwo\nthree\n" >lf.utf8.raw &&
@ -280,4 +280,43 @@ test_expect_success ICONV_SHIFT_JIS 'check roundtrip encoding' '
git reset
'
# $1: checkout encoding
# $2: test string
# $3: binary test string in checkout encoding
test_commit_utf8_checkout_other () {
encoding="$1"
orig_string="$2"
expect_bytes="$3"
test_expect_success "Commit UTF-8, checkout $encoding" '
test_when_finished "git checkout HEAD -- .gitattributes" &&
test_ext="commit_utf8_checkout_$encoding" &&
test_file="test.$test_ext" &&
# Commit as UTF-8
echo "*.$test_ext text working-tree-encoding=UTF-8" >.gitattributes &&
printf "$orig_string" >$test_file &&
git add $test_file &&
git commit -m "Test data" &&
# Checkout in tested encoding
rm $test_file &&
echo "*.$test_ext text working-tree-encoding=$encoding" >.gitattributes &&
git checkout HEAD -- $test_file &&
# Test
printf $expect_bytes >$test_file.raw &&
test_cmp_bin $test_file.raw $test_file
'
}
test_commit_utf8_checkout_other "UTF-8" "Test Тест" "\124\145\163\164\040\320\242\320\265\321\201\321\202"
test_commit_utf8_checkout_other "UTF-16LE" "Test Тест" "\124\000\145\000\163\000\164\000\040\000\042\004\065\004\101\004\102\004"
test_commit_utf8_checkout_other "UTF-16BE" "Test Тест" "\000\124\000\145\000\163\000\164\000\040\004\042\004\065\004\101\004\102"
test_commit_utf8_checkout_other "UTF-16LE-BOM" "Test Тест" "\377\376\124\000\145\000\163\000\164\000\040\000\042\004\065\004\101\004\102\004"
test_commit_utf8_checkout_other "UTF-16BE-BOM" "Test Тест" "\376\377\000\124\000\145\000\163\000\164\000\040\004\042\004\065\004\101\004\102"
test_commit_utf8_checkout_other "UTF-32LE" "Test Тест" "\124\000\000\000\145\000\000\000\163\000\000\000\164\000\000\000\040\000\000\000\042\004\000\000\065\004\000\000\101\004\000\000\102\004\000\000"
test_commit_utf8_checkout_other "UTF-32BE" "Test Тест" "\000\000\000\124\000\000\000\145\000\000\000\163\000\000\000\164\000\000\000\040\000\000\004\042\000\000\004\065\000\000\004\101\000\000\004\102"
test_done

View file

@ -23,6 +23,8 @@ usage: test-tool parse-options <options>
-j <n> get a integer, too
-m, --magnitude <n> get a magnitude
--set23 set integer to 23
--mode1 set integer to 1 (cmdmode option)
--mode2 set integer to 2 (cmdmode option)
-L, --length <str> get length of <str>
-F, --file <file> set file to <file>
@ -42,7 +44,7 @@ Magic arguments
--no-ambiguous negative ambiguity
Standard options
--abbrev[=<n>] use <n> digits to display SHA-1s
--abbrev[=<n>] use <n> digits to display object names
-v, --verbose be verbose
-n, --dry-run dry run
-q, --quiet be quiet
@ -52,7 +54,7 @@ Alias
-A, --alias-source <string>
get a string
-Z, --alias-target <string>
get a string
alias of --alias-source
EOF
@ -242,7 +244,7 @@ test_expect_success 'Alias options do not contribute to abbreviation' '
'
cat >typo.err <<\EOF
error: did you mean `--boolean` (with two dashes ?)
error: did you mean `--boolean` (with two dashes)?
EOF
test_expect_success 'detect possible typos' '
@ -252,7 +254,7 @@ test_expect_success 'detect possible typos' '
'
cat >typo.err <<\EOF
error: did you mean `--ambiguous` (with two dashes ?)
error: did you mean `--ambiguous` (with two dashes)?
EOF
test_expect_success 'detect possible typos' '
@ -324,6 +326,22 @@ test_expect_success 'OPT_NEGBIT() works' '
test-tool parse-options --expect="boolean: 6" -bb --no-neg-or4
'
test_expect_success 'OPT_CMDMODE() works' '
test-tool parse-options --expect="integer: 1" --mode1
'
test_expect_success 'OPT_CMDMODE() detects incompatibility' '
test_must_fail test-tool parse-options --mode1 --mode2 >output 2>output.err &&
test_must_be_empty output &&
test_i18ngrep "incompatible with --mode" output.err
'
test_expect_success 'OPT_CMDMODE() detects incompatibility with something else' '
test_must_fail test-tool parse-options --set23 --mode2 >output 2>output.err &&
test_must_be_empty output &&
test_i18ngrep "incompatible with something else" output.err
'
test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' '
test-tool parse-options --expect="boolean: 6" + + + + + +
'
@ -399,4 +417,11 @@ test_expect_success 'GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS works' '
test-tool parse-options --ye
'
test_expect_success '--end-of-options treats remainder as args' '
test-tool parse-options \
--expect="verbose: -1" \
--expect="arg 00: --verbose" \
--end-of-options --verbose
'
test_done

View file

@ -131,4 +131,24 @@ $test_unicode 'merge (silent unicode normalization)' '
git merge topic
'
test_expect_success CASE_INSENSITIVE_FS 'checkout with no pathspec and a case insensitive fs' '
git init repo &&
(
cd repo &&
>Gitweb &&
git add Gitweb &&
git commit -m "add Gitweb" &&
git checkout --orphan todo &&
git reset --hard &&
mkdir -p gitweb/subdir &&
>gitweb/subdir/file &&
git add gitweb &&
git commit -m "add gitweb/subdir/file" &&
git checkout master
)
'
test_done

View file

@ -165,6 +165,15 @@ test_expect_success 'absolute path rejects the empty string' '
test_must_fail test-tool path-utils absolute_path ""
'
test_expect_success MINGW '<drive-letter>:\\abc is an absolute path' '
for letter in : \" C Z 1 ä
do
path=$letter:\\abc &&
absolute="$(test-tool path-utils absolute_path "$path")" &&
test "$path" = "$absolute" || return 1
done
'
test_expect_success 'real path rejects the empty string' '
test_must_fail test-tool path-utils real_path ""
'
@ -285,9 +294,13 @@ test_git_path GIT_OBJECT_DIRECTORY=foo objects/foo foo/foo
test_git_path GIT_OBJECT_DIRECTORY=foo objects2 .git/objects2
test_expect_success 'setup common repository' 'git --git-dir=bar init'
test_git_path GIT_COMMON_DIR=bar index .git/index
test_git_path GIT_COMMON_DIR=bar index.lock .git/index.lock
test_git_path GIT_COMMON_DIR=bar HEAD .git/HEAD
test_git_path GIT_COMMON_DIR=bar logs/HEAD .git/logs/HEAD
test_git_path GIT_COMMON_DIR=bar logs/HEAD.lock .git/logs/HEAD.lock
test_git_path GIT_COMMON_DIR=bar logs/refs/bisect/foo .git/logs/refs/bisect/foo
test_git_path GIT_COMMON_DIR=bar logs/refs bar/logs/refs
test_git_path GIT_COMMON_DIR=bar logs/refs/ bar/logs/refs/
test_git_path GIT_COMMON_DIR=bar logs/refs/bisec/foo bar/logs/refs/bisec/foo
test_git_path GIT_COMMON_DIR=bar logs/refs/bisec bar/logs/refs/bisec
test_git_path GIT_COMMON_DIR=bar logs/refs/bisectfoo bar/logs/refs/bisectfoo
@ -423,6 +436,9 @@ test_expect_success 'match .gitmodules' '
~1000000 \
~9999999 \
\
.gitmodules:\$DATA \
"gitmod~4 . :\$DATA" \
\
--not \
".gitmodules x" \
".gitmodules .x" \
@ -447,7 +463,36 @@ test_expect_success 'match .gitmodules' '
\
GI7EB~1 \
GI7EB~01 \
GI7EB~1X
GI7EB~1X \
\
.gitmodules,:\$DATA
'
test_expect_success MINGW 'is_valid_path() on Windows' '
test-tool path-utils is_valid_path \
win32 \
"win32 x" \
../hello.txt \
C:\\git \
comm \
conout.c \
com0.c \
lptN \
\
--not \
"win32 " \
"win32 /x " \
"win32." \
"win32 . ." \
.../hello.txt \
colon:test \
"AUX.c" \
"abc/conOut\$ .xyz/test" \
lpt8 \
com9.c \
"lpt*" \
Nul \
"PRN./abc"
'
test_done

View file

@ -12,6 +12,10 @@ cat >hello-script <<-EOF
cat hello-script
EOF
test_expect_success MINGW 'subprocess inherits only std handles' '
test-tool run-command inherited-handle
'
test_expect_success 'start_command reports ENOENT (slash)' '
test-tool run-command start-command-ENOENT ./does-not-exist 2>err &&
test_i18ngrep "\./does-not-exist" err
@ -210,10 +214,23 @@ test_expect_success MINGW 'verify curlies are quoted properly' '
test_cmp expect actual
'
test_expect_success MINGW 'can spawn with argv[0] containing spaces' '
cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" ./ &&
test_must_fail "$PWD/test-fake-ssh$X" 2>err &&
grep TRASH_DIRECTORY err
test_expect_success MINGW 'can spawn .bat with argv[0] containing spaces' '
bat="$TRASH_DIRECTORY/bat with spaces in name.bat" &&
# Every .bat invocation will log its arguments to file "out"
rm -f out &&
echo "echo %* >>out" >"$bat" &&
# Ask git to invoke .bat; clone will fail due to fake SSH helper
test_must_fail env GIT_SSH="$bat" git clone myhost:src ssh-clone &&
# Spawning .bat can fail if there are two quoted cmd.exe arguments.
# .bat itself is first (due to spaces in name), so just one more is
# needed to verify. GIT_SSH will invoke .bat multiple times:
# 1) -G myhost
# 2) myhost "git-upload-pack src"
# First invocation will always succeed. Test the second one.
grep "git-upload-pack" out
'
test_done

View file

@ -18,7 +18,7 @@ test_expect_success 'ordered enumeration' '
{
echoid append 88 44 aa 55 &&
echo for_each_unique
} | test-tool sha1-array >actual &&
} | test-tool oid-array >actual &&
test_cmp expect actual
'
@ -28,7 +28,7 @@ test_expect_success 'ordered enumeration with duplicate suppression' '
echoid append 88 44 aa 55 &&
echoid append 88 44 aa 55 &&
echo for_each_unique
} | test-tool sha1-array >actual &&
} | test-tool oid-array >actual &&
test_cmp expect actual
'
@ -36,7 +36,7 @@ test_expect_success 'lookup' '
{
echoid append 88 44 aa 55 &&
echoid lookup 55
} | test-tool sha1-array >actual &&
} | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -eq 1
'
@ -45,7 +45,7 @@ test_expect_success 'lookup non-existing entry' '
{
echoid append 88 44 aa 55 &&
echoid lookup 33
} | test-tool sha1-array >actual &&
} | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -lt 0
'
@ -55,7 +55,7 @@ test_expect_success 'lookup with duplicates' '
echoid append 88 44 aa 55 &&
echoid append 88 44 aa 55 &&
echoid lookup 55
} | test-tool sha1-array >actual &&
} | test-tool oid-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' '
echoid append 88 44 aa 55 &&
echoid append 88 44 aa 55 &&
echoid lookup 66
} | test-tool sha1-array >actual &&
} | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -lt 0
'
@ -81,7 +81,7 @@ test_expect_success 'lookup with almost duplicate values' '
echo "append $id1" &&
echo "append $id2" &&
echoid lookup 55
} | test-tool sha1-array >actual &&
} | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -eq 0
'
@ -90,7 +90,7 @@ test_expect_success 'lookup with single duplicate value' '
{
echoid append 55 55 &&
echoid lookup 55
} | test-tool sha1-array >actual &&
} | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -ge 0 &&
test "$n" -le 1

108
third_party/git/t/t0067-parse_pathspec_file.sh vendored Executable file
View file

@ -0,0 +1,108 @@
#!/bin/sh
test_description='Test parse_pathspec_file()'
. ./test-lib.sh
test_expect_success 'one item from stdin' '
cat >expect <<-\EOF &&
fileA.t
EOF
echo fileA.t |
test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
test_cmp expect actual
'
test_expect_success 'one item from file' '
cat >expect <<-\EOF &&
fileA.t
EOF
echo fileA.t >list &&
test-tool parse-pathspec-file --pathspec-from-file=list >actual &&
test_cmp expect actual
'
test_expect_success 'NUL delimiters' '
cat >expect <<-\EOF &&
fileA.t
fileB.t
EOF
printf "fileA.t\0fileB.t\0" |
test-tool parse-pathspec-file --pathspec-from-file=- --pathspec-file-nul >actual &&
test_cmp expect actual
'
test_expect_success 'LF delimiters' '
cat >expect <<-\EOF &&
fileA.t
fileB.t
EOF
printf "fileA.t\nfileB.t\n" |
test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
test_cmp expect actual
'
test_expect_success 'no trailing delimiter' '
cat >expect <<-\EOF &&
fileA.t
fileB.t
EOF
printf "fileA.t\nfileB.t" |
test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
test_cmp expect actual
'
test_expect_success 'CRLF delimiters' '
cat >expect <<-\EOF &&
fileA.t
fileB.t
EOF
printf "fileA.t\r\nfileB.t\r\n" |
test-tool parse-pathspec-file --pathspec-from-file=- >actual &&
test_cmp expect actual
'
test_expect_success 'quotes' '
cat >expect <<-\EOF &&
fileA.t
EOF
cat >list <<-\EOF &&
"file\101.t"
EOF
test-tool parse-pathspec-file --pathspec-from-file=list >actual &&
test_cmp expect actual
'
test_expect_success '--pathspec-file-nul takes quotes literally' '
# Note: there is an extra newline because --pathspec-file-nul takes
# input \n literally, too
cat >expect <<-\EOF &&
"file\101.t"
EOF
cat >list <<-\EOF &&
"file\101.t"
EOF
test-tool parse-pathspec-file --pathspec-from-file=list --pathspec-file-nul >actual &&
test_cmp expect actual
'
test_done

View file

@ -1,90 +0,0 @@
#!/bin/sh
test_description="Test the svn importer's input handling routines.
These tests provide some simple checks that the line_buffer API
behaves as advertised.
While at it, check that input of newlines and null bytes are handled
correctly.
"
. ./test-lib.sh
test_expect_success 'hello world' '
echo ">HELLO" >expect &&
test-line-buffer <<-\EOF >actual &&
binary 6
HELLO
EOF
test_cmp expect actual
'
test_expect_success '0-length read, send along greeting' '
echo ">HELLO" >expect &&
test-line-buffer <<-\EOF >actual &&
binary 0
copy 6
HELLO
EOF
test_cmp expect actual
'
test_expect_success !MINGW 'read from file descriptor' '
rm -f input &&
echo hello >expect &&
echo hello >input &&
echo copy 6 |
test-line-buffer "&4" 4<input >actual &&
test_cmp expect actual
'
test_expect_success 'skip, copy null byte' '
echo Q | q_to_nul >expect &&
q_to_nul <<-\EOF | test-line-buffer >actual &&
skip 2
Q
copy 2
Q
EOF
test_cmp expect actual
'
test_expect_success 'read null byte' '
echo ">QhelloQ" | q_to_nul >expect &&
q_to_nul <<-\EOF | test-line-buffer >actual &&
binary 8
QhelloQ
EOF
test_cmp expect actual
'
test_expect_success 'long reads are truncated' '
echo ">foo" >expect &&
test-line-buffer <<-\EOF >actual &&
binary 5
foo
EOF
test_cmp expect actual
'
test_expect_success 'long copies are truncated' '
printf "%s\n" ">" foo >expect &&
test-line-buffer <<-\EOF >actual &&
binary 1
copy 5
foo
EOF
test_cmp expect actual
'
test_expect_success 'long binary reads are truncated' '
echo ">foo" >expect &&
test-line-buffer <<-\EOF >actual &&
binary 5
foo
EOF
test_cmp expect actual
'
test_done

View file

@ -21,9 +21,10 @@ generate_expected_cache_tree_rec () {
parent="$2" &&
# ls-files might have foo/bar, foo/bar/baz, and foo/bar/quux
# We want to count only foo because it's the only direct child
subtrees=$(git ls-files|grep /|cut -d / -f 1|uniq) &&
git ls-files >files &&
subtrees=$(grep / files|cut -d / -f 1|uniq) &&
subtree_count=$(echo "$subtrees"|awk -v c=0 '$1 != "" {++c} END {print c}') &&
entries=$(git ls-files|wc -l) &&
entries=$(wc -l <files) &&
printf "SHA $dir (%d entries, %d subtrees)\n" "$entries" "$subtree_count" &&
for subtree in $subtrees
do

76
third_party/git/t/t0091-bugreport.sh vendored Executable file
View file

@ -0,0 +1,76 @@
#!/bin/sh
test_description='git bugreport'
. ./test-lib.sh
# Headers "[System Info]" will be followed by a non-empty line if we put some
# information there; we can make sure all our headers were followed by some
# information to check if the command was successful.
HEADER_PATTERN="^\[.*\]$"
check_all_headers_populated () {
while read -r line
do
if test "$(grep "$HEADER_PATTERN" "$line")"
then
echo "$line"
read -r nextline
if test -z "$nextline"; then
return 1;
fi
fi
done
}
test_expect_success 'creates a report with content in the right places' '
test_when_finished rm git-bugreport-check-headers.txt &&
git bugreport -s check-headers &&
check_all_headers_populated <git-bugreport-check-headers.txt
'
test_expect_success 'dies if file with same name as report already exists' '
test_when_finished rm git-bugreport-duplicate.txt &&
>>git-bugreport-duplicate.txt &&
test_must_fail git bugreport --suffix duplicate
'
test_expect_success '--output-directory puts the report in the provided dir' '
test_when_finished rm -fr foo/ &&
git bugreport -o foo/ &&
test_path_is_file foo/git-bugreport-*
'
test_expect_success 'incorrect arguments abort with usage' '
test_must_fail git bugreport --false 2>output &&
test_i18ngrep usage output &&
test_path_is_missing git-bugreport-*
'
test_expect_success 'runs outside of a git dir' '
test_when_finished rm non-repo/git-bugreport-* &&
nongit git bugreport
'
test_expect_success 'can create leading directories outside of a git dir' '
test_when_finished rm -fr foo/bar/baz &&
nongit git bugreport -o foo/bar/baz
'
test_expect_success 'indicates populated hooks' '
test_when_finished rm git-bugreport-hooks.txt &&
test_when_finished rm -fr .git/hooks &&
rm -fr .git/hooks &&
mkdir .git/hooks &&
for hook in applypatch-msg prepare-commit-msg.sample
do
write_script ".git/hooks/$hook" <<-EOF || return 1
echo "hook $hook exists"
EOF
done &&
git bugreport -s hooks &&
grep applypatch-msg git-bugreport-hooks.txt &&
! grep prepare-commit-msg git-bugreport-hooks.txt
'
test_done

117
third_party/git/t/t0095-bloom.sh vendored Executable file
View file

@ -0,0 +1,117 @@
#!/bin/sh
test_description='Testing the various Bloom filter computations in bloom.c'
. ./test-lib.sh
test_expect_success 'compute unseeded murmur3 hash for empty string' '
cat >expect <<-\EOF &&
Murmur3 Hash with seed=0:0x00000000
EOF
test-tool bloom get_murmur3 "" >actual &&
test_cmp expect actual
'
test_expect_success 'compute unseeded murmur3 hash for test string 1' '
cat >expect <<-\EOF &&
Murmur3 Hash with seed=0:0x627b0c2c
EOF
test-tool bloom get_murmur3 "Hello world!" >actual &&
test_cmp expect actual
'
test_expect_success 'compute unseeded murmur3 hash for test string 2' '
cat >expect <<-\EOF &&
Murmur3 Hash with seed=0:0x2e4ff723
EOF
test-tool bloom get_murmur3 "The quick brown fox jumps over the lazy dog" >actual &&
test_cmp expect actual
'
test_expect_success 'compute bloom key for empty string' '
cat >expect <<-\EOF &&
Hashes:0x5615800c|0x5b966560|0x61174ab4|0x66983008|0x6c19155c|0x7199fab0|0x771ae004|
Filter_Length:2
Filter_Data:11|11|
EOF
test-tool bloom generate_filter "" >actual &&
test_cmp expect actual
'
test_expect_success 'compute bloom key for whitespace' '
cat >expect <<-\EOF &&
Hashes:0xf178874c|0x5f3d6eb6|0xcd025620|0x3ac73d8a|0xa88c24f4|0x16510c5e|0x8415f3c8|
Filter_Length:2
Filter_Data:51|55|
EOF
test-tool bloom generate_filter " " >actual &&
test_cmp expect actual
'
test_expect_success 'compute bloom key for test string 1' '
cat >expect <<-\EOF &&
Hashes:0xb270de9b|0x1bb6f26e|0x84fd0641|0xee431a14|0x57892de7|0xc0cf41ba|0x2a15558d|
Filter_Length:2
Filter_Data:92|6c|
EOF
test-tool bloom generate_filter "Hello world!" >actual &&
test_cmp expect actual
'
test_expect_success 'compute bloom key for test string 2' '
cat >expect <<-\EOF &&
Hashes:0x20ab385b|0xf5237fe2|0xc99bc769|0x9e140ef0|0x728c5677|0x47049dfe|0x1b7ce585|
Filter_Length:2
Filter_Data:a5|4a|
EOF
test-tool bloom generate_filter "file.txt" >actual &&
test_cmp expect actual
'
test_expect_success 'get bloom filters for commit with no changes' '
git init &&
git commit --allow-empty -m "c0" &&
cat >expect <<-\EOF &&
Filter_Length:1
Filter_Data:00|
EOF
test-tool bloom get_filter_for_commit "$(git rev-parse HEAD)" >actual &&
test_cmp expect actual
'
test_expect_success 'get bloom filter for commit with 10 changes' '
rm actual &&
rm expect &&
mkdir smallDir &&
for i in $(test_seq 0 9)
do
echo $i >smallDir/$i
done &&
git add smallDir &&
git commit -m "commit with 10 changes" &&
cat >expect <<-\EOF &&
Filter_Length:14
Filter_Data:02|b3|c4|a0|34|e7|fe|eb|cb|47|fe|a0|e8|72|
EOF
test-tool bloom get_filter_for_commit "$(git rev-parse HEAD)" >actual &&
test_cmp expect actual
'
test_expect_success EXPENSIVE 'get bloom filter for commit with 513 changes' '
rm actual &&
rm expect &&
mkdir bigDir &&
for i in $(test_seq 0 511)
do
echo $i >bigDir/$i
done &&
git add bigDir &&
git commit -m "commit with 513 changes" &&
cat >expect <<-\EOF &&
Filter_Length:1
Filter_Data:ff|
EOF
test-tool bloom get_filter_for_commit "$(git rev-parse HEAD)" >actual &&
test_cmp expect actual
'
test_done

View file

@ -130,11 +130,11 @@ test_expect_success 'perf stream, child processes' '
d0|main|version|||||$V
d0|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 004child test-tool trace2 001return 0
d0|main|cmd_name|||||trace2 (trace2)
d0|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 004child test-tool trace2 001return 0
d0|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 004child test-tool trace2 001return 0]
d1|main|version|||||$V
d1|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 001return 0
d1|main|cmd_name|||||trace2 (trace2/trace2)
d1|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 001return 0
d1|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 001return 0]
d2|main|version|||||$V
d2|main|start||_T_ABS_|||_EXE_ trace2 001return 0
d2|main|cmd_name|||||trace2 (trace2/trace2/trace2)

View file

@ -199,6 +199,43 @@ test_expect_success JSON_PP 'event stream, list config' '
test_cmp expect actual
'
# Test listing of all "interesting" environment variables.
test_expect_success JSON_PP 'event stream, list env vars' '
test_when_finished "rm trace.event actual expect" &&
GIT_TRACE2_EVENT="$(pwd)/trace.event" \
GIT_TRACE2_ENV_VARS="A_VAR,OTHER_VAR,MISSING" \
A_VAR=1 OTHER_VAR="hello world" test-tool trace2 001return 0 &&
perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual &&
sed -e "s/^|//" >expect <<-EOF &&
|VAR1 = {
| "_SID0_":{
| "argv":[
| "_EXE_",
| "trace2",
| "001return",
| "0"
| ],
| "exit_code":0,
| "hierarchy":"trace2",
| "name":"trace2",
| "params":[
| {
| "param":"A_VAR",
| "value":"1"
| },
| {
| "param":"OTHER_VAR",
| "value":"hello world"
| }
| ],
| "version":"$V"
| }
|};
EOF
test_cmp expect actual
'
test_expect_success JSON_PP 'basic trace2_data' '
test_when_finished "rm trace.event actual expect" &&
GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 &&
@ -265,4 +302,23 @@ test_expect_success JSON_PP 'using global config, event stream, error event' '
test_cmp expect actual
'
test_expect_success 'discard traces when there are too many files' '
mkdir trace_target_dir &&
test_when_finished "rm -r trace_target_dir" &&
(
GIT_TRACE2_MAX_FILES=5 &&
export GIT_TRACE2_MAX_FILES &&
cd trace_target_dir &&
test_seq $GIT_TRACE2_MAX_FILES >../expected_filenames.txt &&
xargs touch <../expected_filenames.txt &&
cd .. &&
GIT_TRACE2_EVENT="$(pwd)/trace_target_dir" test-tool trace2 001return 0
) &&
echo git-trace2-discard >>expected_filenames.txt &&
ls trace_target_dir >ls_output.txt &&
test_cmp expected_filenames.txt ls_output.txt &&
head -n1 trace_target_dir/git-trace2-discard | grep \"event\":\"version\" &&
head -n2 trace_target_dir/git-trace2-discard | tail -n1 | grep \"event\":\"too_many_files\"
'
test_done

View file

@ -22,6 +22,11 @@ test_expect_success 'setup helper scripts' '
exit 0
EOF
write_script git-credential-quit <<-\EOF &&
. ./dump
echo quit=1
EOF
write_script git-credential-verbatim <<-\EOF &&
user=$1; shift
pass=$1; shift
@ -35,43 +40,71 @@ test_expect_success 'setup helper scripts' '
test_expect_success 'credential_fill invokes helper' '
check fill "verbatim foo bar" <<-\EOF
protocol=http
host=example.com
--
protocol=http
host=example.com
username=foo
password=bar
--
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
EOF
'
test_expect_success 'credential_fill invokes multiple helpers' '
check fill useless "verbatim foo bar" <<-\EOF
protocol=http
host=example.com
--
protocol=http
host=example.com
username=foo
password=bar
--
useless: get
useless: protocol=http
useless: host=example.com
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
EOF
'
test_expect_success 'credential_fill stops when we get a full response' '
check fill "verbatim one two" "verbatim three four" <<-\EOF
protocol=http
host=example.com
--
protocol=http
host=example.com
username=one
password=two
--
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
EOF
'
test_expect_success 'credential_fill continues through partial response' '
check fill "verbatim one \"\"" "verbatim two three" <<-\EOF
protocol=http
host=example.com
--
protocol=http
host=example.com
username=two
password=three
--
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
verbatim: username=one
EOF
'
@ -97,14 +130,20 @@ test_expect_success 'credential_fill passes along metadata' '
test_expect_success 'credential_approve calls all helpers' '
check approve useless "verbatim one two" <<-\EOF
protocol=http
host=example.com
username=foo
password=bar
--
--
useless: store
useless: protocol=http
useless: host=example.com
useless: username=foo
useless: password=bar
verbatim: store
verbatim: protocol=http
verbatim: host=example.com
verbatim: username=foo
verbatim: password=bar
EOF
@ -112,6 +151,8 @@ test_expect_success 'credential_approve calls all helpers' '
test_expect_success 'do not bother storing password-less credential' '
check approve useless <<-\EOF
protocol=http
host=example.com
username=foo
--
--
@ -121,14 +162,20 @@ test_expect_success 'do not bother storing password-less credential' '
test_expect_success 'credential_reject calls all helpers' '
check reject useless "verbatim one two" <<-\EOF
protocol=http
host=example.com
username=foo
password=bar
--
--
useless: erase
useless: protocol=http
useless: host=example.com
useless: username=foo
useless: password=bar
verbatim: erase
verbatim: protocol=http
verbatim: host=example.com
verbatim: username=foo
verbatim: password=bar
EOF
@ -136,33 +183,49 @@ test_expect_success 'credential_reject calls all helpers' '
test_expect_success 'usernames can be preserved' '
check fill "verbatim \"\" three" <<-\EOF
protocol=http
host=example.com
username=one
--
protocol=http
host=example.com
username=one
password=three
--
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
verbatim: username=one
EOF
'
test_expect_success 'usernames can be overridden' '
check fill "verbatim two three" <<-\EOF
protocol=http
host=example.com
username=one
--
protocol=http
host=example.com
username=two
password=three
--
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
verbatim: username=one
EOF
'
test_expect_success 'do not bother completing already-full credential' '
check fill "verbatim three four" <<-\EOF
protocol=http
host=example.com
username=one
password=two
--
protocol=http
host=example.com
username=one
password=two
--
@ -174,23 +237,31 @@ test_expect_success 'do not bother completing already-full credential' '
# askpass helper is run, we know the internal getpass is working.
test_expect_success 'empty helper list falls back to internal getpass' '
check fill <<-\EOF
protocol=http
host=example.com
--
protocol=http
host=example.com
username=askpass-username
password=askpass-password
--
askpass: Username:
askpass: Password:
askpass: Username for '\''http://example.com'\'':
askpass: Password for '\''http://askpass-username@example.com'\'':
EOF
'
test_expect_success 'internal getpass does not ask for known username' '
check fill <<-\EOF
protocol=http
host=example.com
username=foo
--
protocol=http
host=example.com
username=foo
password=askpass-password
--
askpass: Password:
askpass: Password for '\''http://foo@example.com'\'':
EOF
'
@ -202,7 +273,11 @@ HELPER="!f() {
test_expect_success 'respect configured credentials' '
test_config credential.helper "$HELPER" &&
check fill <<-\EOF
protocol=http
host=example.com
--
protocol=http
host=example.com
username=foo
password=bar
--
@ -240,6 +315,102 @@ test_expect_success 'do not match configured credential' '
EOF
'
test_expect_success 'match multiple configured helpers' '
test_config credential.helper "verbatim \"\" \"\"" &&
test_config credential.https://example.com.helper "$HELPER" &&
check fill <<-\EOF
protocol=https
host=example.com
path=repo.git
--
protocol=https
host=example.com
username=foo
password=bar
--
verbatim: get
verbatim: protocol=https
verbatim: host=example.com
EOF
'
test_expect_success 'match multiple configured helpers with URLs' '
test_config credential.https://example.com/repo.git.helper "verbatim \"\" \"\"" &&
test_config credential.https://example.com.helper "$HELPER" &&
check fill <<-\EOF
protocol=https
host=example.com
path=repo.git
--
protocol=https
host=example.com
username=foo
password=bar
--
verbatim: get
verbatim: protocol=https
verbatim: host=example.com
EOF
'
test_expect_success 'match percent-encoded values' '
test_config credential.https://example.com/%2566.git.helper "$HELPER" &&
check fill <<-\EOF
url=https://example.com/%2566.git
--
protocol=https
host=example.com
username=foo
password=bar
--
EOF
'
test_expect_success 'match percent-encoded UTF-8 values in path' '
test_config credential.https://example.com.useHttpPath true &&
test_config credential.https://example.com/perú.git.helper "$HELPER" &&
check fill <<-\EOF
url=https://example.com/per%C3%BA.git
--
protocol=https
host=example.com
path=perú.git
username=foo
password=bar
--
EOF
'
test_expect_success 'match percent-encoded values in username' '
test_config credential.https://user%2fname@example.com/foo/bar.git.helper "$HELPER" &&
check fill <<-\EOF
url=https://user%2fname@example.com/foo/bar.git
--
protocol=https
host=example.com
username=foo
password=bar
--
EOF
'
test_expect_success 'fetch with multiple path components' '
test_unconfig credential.helper &&
test_config credential.https://example.com/foo/repo.git.helper "verbatim foo bar" &&
check fill <<-\EOF
url=https://example.com/foo/repo.git
--
protocol=https
host=example.com
username=foo
password=bar
--
verbatim: get
verbatim: protocol=https
verbatim: host=example.com
EOF
'
test_expect_success 'pull username from config' '
test_config credential.https://example.com.username foo &&
check fill <<-\EOF
@ -255,6 +426,63 @@ test_expect_success 'pull username from config' '
EOF
'
test_expect_success 'honors username from URL over helper (URL)' '
test_config credential.https://example.com.username bob &&
test_config credential.https://example.com.helper "verbatim \"\" bar" &&
check fill <<-\EOF
url=https://alice@example.com
--
protocol=https
host=example.com
username=alice
password=bar
--
verbatim: get
verbatim: protocol=https
verbatim: host=example.com
verbatim: username=alice
EOF
'
test_expect_success 'honors username from URL over helper (components)' '
test_config credential.https://example.com.username bob &&
test_config credential.https://example.com.helper "verbatim \"\" bar" &&
check fill <<-\EOF
protocol=https
host=example.com
username=alice
--
protocol=https
host=example.com
username=alice
password=bar
--
verbatim: get
verbatim: protocol=https
verbatim: host=example.com
verbatim: username=alice
EOF
'
test_expect_success 'last matching username wins' '
test_config credential.https://example.com/path.git.username bob &&
test_config credential.https://example.com.username alice &&
test_config credential.https://example.com.helper "verbatim \"\" bar" &&
check fill <<-\EOF
url=https://example.com/path.git
--
protocol=https
host=example.com
username=alice
password=bar
--
verbatim: get
verbatim: protocol=https
verbatim: host=example.com
verbatim: username=alice
EOF
'
test_expect_success 'http paths can be part of context' '
check fill "verbatim foo bar" <<-\EOF &&
protocol=https
@ -289,23 +517,179 @@ test_expect_success 'http paths can be part of context' '
EOF
'
test_expect_success 'context uses urlmatch' '
test_config "credential.https://*.org.useHttpPath" true &&
check fill "verbatim foo bar" <<-\EOF
protocol=https
host=example.org
path=foo.git
--
protocol=https
host=example.org
path=foo.git
username=foo
password=bar
--
verbatim: get
verbatim: protocol=https
verbatim: host=example.org
verbatim: path=foo.git
EOF
'
test_expect_success 'helpers can abort the process' '
test_must_fail git \
-c credential.helper="!f() { echo quit=1; }; f" \
-c credential.helper=quit \
-c credential.helper="verbatim foo bar" \
credential fill >stdout &&
test_must_be_empty stdout
credential fill >stdout 2>stderr <<-\EOF &&
protocol=http
host=example.com
EOF
test_must_be_empty stdout &&
cat >expect <<-\EOF &&
quit: get
quit: protocol=http
quit: host=example.com
fatal: credential helper '\''quit'\'' told us to quit
EOF
test_i18ncmp expect stderr
'
test_expect_success 'empty helper spec resets helper list' '
test_config credential.helper "verbatim file file" &&
check fill "" "verbatim cmdline cmdline" <<-\EOF
protocol=http
host=example.com
--
protocol=http
host=example.com
username=cmdline
password=cmdline
--
verbatim: get
verbatim: protocol=http
verbatim: host=example.com
EOF
'
test_expect_success 'url parser rejects embedded newlines' '
test_must_fail git credential fill 2>stderr <<-\EOF &&
url=https://one.example.com?%0ahost=two.example.com/
EOF
cat >expect <<-\EOF &&
warning: url contains a newline in its path component: https://one.example.com?%0ahost=two.example.com/
fatal: credential url cannot be parsed: https://one.example.com?%0ahost=two.example.com/
EOF
test_i18ncmp expect stderr
'
test_expect_success 'host-less URLs are parsed as empty host' '
check fill "verbatim foo bar" <<-\EOF
url=cert:///path/to/cert.pem
--
protocol=cert
host=
path=path/to/cert.pem
username=foo
password=bar
--
verbatim: get
verbatim: protocol=cert
verbatim: host=
verbatim: path=path/to/cert.pem
EOF
'
test_expect_success 'credential system refuses to work with missing host' '
test_must_fail git credential fill 2>stderr <<-\EOF &&
protocol=http
EOF
cat >expect <<-\EOF &&
fatal: refusing to work with credential missing host field
EOF
test_i18ncmp expect stderr
'
test_expect_success 'credential system refuses to work with missing protocol' '
test_must_fail git credential fill 2>stderr <<-\EOF &&
host=example.com
EOF
cat >expect <<-\EOF &&
fatal: refusing to work with credential missing protocol field
EOF
test_i18ncmp expect stderr
'
# usage: check_host_and_path <url> <expected-host> <expected-path>
check_host_and_path () {
# we always parse the path component, but we need this to make sure it
# is passed to the helper
test_config credential.useHTTPPath true &&
check fill "verbatim user pass" <<-EOF
url=$1
--
protocol=https
host=$2
path=$3
username=user
password=pass
--
verbatim: get
verbatim: protocol=https
verbatim: host=$2
verbatim: path=$3
EOF
}
test_expect_success 'url parser handles bare query marker' '
check_host_and_path https://example.com?foo.git example.com ?foo.git
'
test_expect_success 'url parser handles bare fragment marker' '
check_host_and_path https://example.com#foo.git example.com "#foo.git"
'
test_expect_success 'url parser not confused by encoded markers' '
check_host_and_path https://example.com%23%3f%2f/foo.git \
"example.com#?/" foo.git
'
test_expect_success 'credential config with partial URLs' '
echo "echo password=yep" | write_script git-credential-yep &&
test_write_lines url=https://user@example.com/repo.git >stdin &&
for partial in \
example.com \
user@example.com \
https:// \
https://example.com \
https://example.com/ \
https://user@example.com \
https://user@example.com/ \
https://example.com/repo.git \
https://user@example.com/repo.git \
/repo.git
do
git -c credential.$partial.helper=yep \
credential fill <stdin >stdout &&
grep yep stdout ||
return 1
done &&
for partial in \
dont.use.this \
http:// \
/repo
do
git -c credential.$partial.helper=yep \
credential fill <stdin >stdout &&
! grep yep stdout ||
return 1
done &&
git -c credential.$partial.helper=yep \
-c credential.with%0anewline.username=uh-oh \
credential fill <stdin >stdout 2>stderr &&
test_i18ngrep "skipping credential lookup for key" stderr
'
test_done

View file

@ -107,7 +107,6 @@ test_expect_success 'store: if both xdg and home files exist, only store in home
test_must_be_empty "$HOME/.config/git/credentials"
'
test_expect_success 'erase: erase matching credentials from both xdg and home files' '
echo "https://home-user:home-pass@example.com" >"$HOME/.git-credentials" &&
mkdir -p "$HOME/.config/git" &&
@ -120,4 +119,94 @@ test_expect_success 'erase: erase matching credentials from both xdg and home fi
test_must_be_empty "$HOME/.config/git/credentials"
'
invalid_credential_test() {
test_expect_success "get: ignore credentials without $1 as invalid" '
echo "$2" >"$HOME/.git-credentials" &&
check fill store <<-\EOF
protocol=https
host=example.com
--
protocol=https
host=example.com
username=askpass-username
password=askpass-password
--
askpass: Username for '\''https://example.com'\'':
askpass: Password for '\''https://askpass-username@example.com'\'':
--
EOF
'
}
invalid_credential_test "scheme" ://user:pass@example.com
invalid_credential_test "valid host/path" https://user:pass@
invalid_credential_test "username/password" https://pass@example.com
test_expect_success 'get: credentials with DOS line endings are invalid' '
printf "https://user:pass@example.com\r\n" >"$HOME/.git-credentials" &&
check fill store <<-\EOF
protocol=https
host=example.com
--
protocol=https
host=example.com
username=askpass-username
password=askpass-password
--
askpass: Username for '\''https://example.com'\'':
askpass: Password for '\''https://askpass-username@example.com'\'':
--
EOF
'
test_expect_success 'get: credentials with path and DOS line endings are valid' '
printf "https://user:pass@example.com/repo.git\r\n" >"$HOME/.git-credentials" &&
check fill store <<-\EOF
url=https://example.com/repo.git
--
protocol=https
host=example.com
username=user
password=pass
--
EOF
'
test_expect_success 'get: credentials with DOS line endings are invalid if path is relevant' '
printf "https://user:pass@example.com/repo.git\r\n" >"$HOME/.git-credentials" &&
test_config credential.useHttpPath true &&
check fill store <<-\EOF
url=https://example.com/repo.git
--
protocol=https
host=example.com
path=repo.git
username=askpass-username
password=askpass-password
--
askpass: Username for '\''https://example.com/repo.git'\'':
askpass: Password for '\''https://askpass-username@example.com/repo.git'\'':
--
EOF
'
test_expect_success 'get: store file can contain empty/bogus lines' '
echo "" >"$HOME/.git-credentials" &&
q_to_tab <<-\CREDENTIAL >>"$HOME/.git-credentials" &&
#comment
Q
https://user:pass@example.com
CREDENTIAL
check fill store <<-\EOF
protocol=https
host=example.com
--
protocol=https
host=example.com
username=user
password=pass
--
EOF
'
test_done

View file

@ -26,10 +26,44 @@ promise_and_delete () {
test_expect_success 'extensions.partialclone without filter' '
test_create_repo server &&
git clone --filter="blob:none" "file://$(pwd)/server" client &&
git -C client config --unset core.partialclonefilter &&
git -C client config --unset remote.origin.partialclonefilter &&
git -C client fetch origin
'
test_expect_success 'convert shallow clone to partial clone' '
rm -fr server client &&
test_create_repo server &&
test_commit -C server my_commit 1 &&
test_commit -C server my_commit2 1 &&
git clone --depth=1 "file://$(pwd)/server" client &&
git -C client fetch --unshallow --filter="blob:none" &&
test_cmp_config -C client true remote.origin.promisor &&
test_cmp_config -C client blob:none remote.origin.partialclonefilter &&
test_cmp_config -C client 1 core.repositoryformatversion
'
test_expect_success SHA1 'convert to partial clone with noop extension' '
rm -fr server client &&
test_create_repo server &&
test_commit -C server my_commit 1 &&
test_commit -C server my_commit2 1 &&
git clone --depth=1 "file://$(pwd)/server" client &&
test_cmp_config -C client 0 core.repositoryformatversion &&
git -C client config extensions.noop true &&
git -C client fetch --unshallow --filter="blob:none"
'
test_expect_success SHA1 'converting to partial clone fails with unrecognized extension' '
rm -fr server client &&
test_create_repo server &&
test_commit -C server my_commit 1 &&
test_commit -C server my_commit2 1 &&
git clone --depth=1 "file://$(pwd)/server" client &&
test_cmp_config -C client 0 core.repositoryformatversion &&
git -C client config extensions.nonsense true &&
test_must_fail git -C client fetch --unshallow --filter="blob:none"
'
test_expect_success 'missing reflog object, but promised by a commit, passes fsck' '
rm -rf repo &&
test_create_repo repo &&
@ -149,7 +183,7 @@ test_expect_success 'missing CLI object, but promised, passes fsck' '
'
test_expect_success 'fetching of missing objects' '
rm -rf repo &&
rm -rf repo err &&
test_create_repo server &&
test_commit -C server foo &&
git -C server repack -a -d --write-bitmap-index &&
@ -160,14 +194,18 @@ test_expect_success 'fetching of missing objects' '
git -C repo config core.repositoryformatversion 1 &&
git -C repo config extensions.partialclone "origin" &&
git -C repo cat-file -p "$HASH" &&
git -C repo cat-file -p "$HASH" 2>err &&
# Ensure that no spurious FETCH_HEAD messages are written
! grep FETCH_HEAD err &&
# Ensure that the .promisor file is written, and check that its
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
IDX=$(cat promisorlist | sed "s/promisor$/idx/") &&
git verify-pack --verbose "$IDX" | grep "$HASH"
IDX=$(sed "s/promisor$/idx/" promisorlist) &&
git verify-pack --verbose "$IDX" >out &&
grep "$HASH" out
'
test_expect_success 'fetching of missing objects works with ref-in-want enabled' '
@ -179,11 +217,58 @@ test_expect_success 'fetching of missing objects works with ref-in-want enabled'
rm -rf repo/.git/objects/* &&
rm -f trace &&
GIT_TRACE_PACKET="$(pwd)/trace" git -C repo cat-file -p "$HASH" &&
grep "git< fetch=.*ref-in-want" trace
grep "fetch< fetch=.*ref-in-want" trace
'
test_expect_success 'fetching of missing objects from another promisor remote' '
git clone "file://$(pwd)/server" server2 &&
test_commit -C server2 bar &&
git -C server2 repack -a -d --write-bitmap-index &&
HASH2=$(git -C server2 rev-parse bar) &&
git -C repo remote add server2 "file://$(pwd)/server2" &&
git -C repo config remote.server2.promisor true &&
git -C repo cat-file -p "$HASH2" &&
git -C repo fetch server2 &&
rm -rf repo/.git/objects/* &&
git -C repo cat-file -p "$HASH2" &&
# Ensure that the .promisor file is written, and check that its
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
IDX=$(sed "s/promisor$/idx/" promisorlist) &&
git verify-pack --verbose "$IDX" >out &&
grep "$HASH2" out
'
test_expect_success 'fetching of missing objects configures a promisor remote' '
git clone "file://$(pwd)/server" server3 &&
test_commit -C server3 baz &&
git -C server3 repack -a -d --write-bitmap-index &&
HASH3=$(git -C server3 rev-parse baz) &&
git -C server3 config uploadpack.allowfilter 1 &&
rm repo/.git/objects/pack/pack-*.promisor &&
git -C repo remote add server3 "file://$(pwd)/server3" &&
git -C repo fetch --filter="blob:none" server3 $HASH3 &&
test_cmp_config -C repo true remote.server3.promisor &&
# Ensure that the .promisor file is written, and check that its
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
IDX=$(sed "s/promisor$/idx/" promisorlist) &&
git verify-pack --verbose "$IDX" >out &&
grep "$HASH3" out
'
test_expect_success 'fetching of missing blobs works' '
rm -rf server repo &&
rm -rf server server2 repo &&
rm -rf server server3 repo &&
test_create_repo server &&
test_commit -C server foo &&
git -C server repack -a -d --write-bitmap-index &&
@ -234,7 +319,7 @@ test_expect_success 'rev-list stops traversal at missing and promised commit' '
git -C repo config core.repositoryformatversion 1 &&
git -C repo config extensions.partialclone "arbitrary string" &&
GIT_TEST_COMMIT_GRAPH=0 git -C repo rev-list --exclude-promisor-objects --objects bar >out &&
GIT_TEST_COMMIT_GRAPH=0 git -C repo -c core.commitGraph=false rev-list --exclude-promisor-objects --objects bar >out &&
grep $(git -C repo rev-parse bar) out &&
! grep $FOO out
'
@ -381,6 +466,19 @@ test_expect_success 'rev-list dies for missing objects on cmd line' '
done
'
test_expect_success 'single promisor remote can be re-initialized gracefully' '
# ensure one promisor is in the promisors list
rm -rf repo &&
test_create_repo repo &&
test_create_repo other &&
git -C repo remote add foo "file://$(pwd)/other" &&
git -C repo config remote.foo.promisor true &&
git -C repo config extensions.partialclone foo &&
# reinitialize the promisors list
git -C repo fetch --filter=blob:none foo
'
test_expect_success 'gc repacks promisor objects separately from non-promisor objects' '
rm -rf repo &&
test_create_repo repo &&
@ -492,6 +590,20 @@ test_expect_success 'gc stops traversal when a missing but promised object is re
! grep "$TREE_HASH" out
'
test_expect_success 'do not fetch when checking existence of tree we construct ourselves' '
rm -rf repo &&
test_create_repo repo &&
test_commit -C repo base &&
test_commit -C repo side1 &&
git -C repo checkout base &&
test_commit -C repo side2 &&
git -C repo config core.repositoryformatversion 1 &&
git -C repo config extensions.partialclone "arbitrary string" &&
git -C repo cherry-pick side1
'
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
@ -514,8 +626,12 @@ test_expect_success 'fetching of missing objects from an HTTP server' '
# associated packfile contains the object
ls repo/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
IDX=$(cat promisorlist | sed "s/promisor$/idx/") &&
git verify-pack --verbose "$IDX" | grep "$HASH"
IDX=$(sed "s/promisor$/idx/" promisorlist) &&
git verify-pack --verbose "$IDX" >out &&
grep "$HASH" out
'
# DO NOT add non-httpd-specific tests here, because the last part of this
# test script is only executed when httpd is available and enabled.
test_done

312
third_party/git/t/t0500-progress-display.sh vendored Executable file
View file

@ -0,0 +1,312 @@
#!/bin/sh
test_description='progress display'
. ./test-lib.sh
show_cr () {
tr '\015' Q | sed -e "s/Q/<CR>\\$LF/g"
}
test_expect_success 'simple progress display' '
cat >expect <<-\EOF &&
Working hard: 1<CR>
Working hard: 2<CR>
Working hard: 5<CR>
Working hard: 5, done.
EOF
cat >in <<-\EOF &&
update
progress 1
update
progress 2
progress 3
progress 4
update
progress 5
EOF
test-tool progress "Working hard" <in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress display with total' '
cat >expect <<-\EOF &&
Working hard: 33% (1/3)<CR>
Working hard: 66% (2/3)<CR>
Working hard: 100% (3/3)<CR>
Working hard: 100% (3/3), done.
EOF
cat >in <<-\EOF &&
progress 1
progress 2
progress 3
EOF
test-tool progress --total=3 "Working hard" <in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress display breaks long lines #1' '
sed -e "s/Z$//" >expect <<\EOF &&
Working hard.......2.........3.........4.........5.........6: 0% (100/100000)<CR>
Working hard.......2.........3.........4.........5.........6: 1% (1000/100000)<CR>
Working hard.......2.........3.........4.........5.........6: Z
10% (10000/100000)<CR>
100% (100000/100000)<CR>
100% (100000/100000), done.
EOF
cat >in <<-\EOF &&
progress 100
progress 1000
progress 10000
progress 100000
EOF
test-tool progress --total=100000 \
"Working hard.......2.........3.........4.........5.........6" \
<in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress display breaks long lines #2' '
# Note: we do not need that many spaces after the title to cover up
# the last line before breaking the progress line.
sed -e "s/Z$//" >expect <<\EOF &&
Working hard.......2.........3.........4.........5.........6: 0% (1/100000)<CR>
Working hard.......2.........3.........4.........5.........6: 0% (2/100000)<CR>
Working hard.......2.........3.........4.........5.........6: Z
10% (10000/100000)<CR>
100% (100000/100000)<CR>
100% (100000/100000), done.
EOF
cat >in <<-\EOF &&
update
progress 1
update
progress 2
progress 10000
progress 100000
EOF
test-tool progress --total=100000 \
"Working hard.......2.........3.........4.........5.........6" \
<in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress display breaks long lines #3 - even the first is too long' '
# Note: we do not actually need any spaces at the end of the title
# line, because there is no previous progress line to cover up.
sed -e "s/Z$//" >expect <<\EOF &&
Working hard.......2.........3.........4.........5.........6: Z
25% (25000/100000)<CR>
50% (50000/100000)<CR>
75% (75000/100000)<CR>
100% (100000/100000)<CR>
100% (100000/100000), done.
EOF
cat >in <<-\EOF &&
progress 25000
progress 50000
progress 75000
progress 100000
EOF
test-tool progress --total=100000 \
"Working hard.......2.........3.........4.........5.........6" \
<in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress display breaks long lines #4 - title line matches terminal width' '
cat >expect <<\EOF &&
Working hard.......2.........3.........4.........5.........6.........7.........:
25% (25000/100000)<CR>
50% (50000/100000)<CR>
75% (75000/100000)<CR>
100% (100000/100000)<CR>
100% (100000/100000), done.
EOF
cat >in <<-\EOF &&
progress 25000
progress 50000
progress 75000
progress 100000
EOF
test-tool progress --total=100000 \
"Working hard.......2.........3.........4.........5.........6.........7........." \
<in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
# Progress counter goes backwards, this should not happen in practice.
test_expect_success 'progress shortens - crazy caller' '
cat >expect <<-\EOF &&
Working hard: 10% (100/1000)<CR>
Working hard: 20% (200/1000)<CR>
Working hard: 0% (1/1000) <CR>
Working hard: 100% (1000/1000)<CR>
Working hard: 100% (1000/1000), done.
EOF
cat >in <<-\EOF &&
progress 100
progress 200
progress 1
progress 1000
EOF
test-tool progress --total=1000 "Working hard" <in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress display with throughput' '
cat >expect <<-\EOF &&
Working hard: 10<CR>
Working hard: 20, 200.00 KiB | 100.00 KiB/s<CR>
Working hard: 30, 300.00 KiB | 100.00 KiB/s<CR>
Working hard: 40, 400.00 KiB | 100.00 KiB/s<CR>
Working hard: 40, 400.00 KiB | 100.00 KiB/s, done.
EOF
cat >in <<-\EOF &&
throughput 102400 1000
update
progress 10
throughput 204800 2000
update
progress 20
throughput 307200 3000
update
progress 30
throughput 409600 4000
update
progress 40
EOF
test-tool progress "Working hard" <in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress display with throughput and total' '
cat >expect <<-\EOF &&
Working hard: 25% (10/40)<CR>
Working hard: 50% (20/40), 200.00 KiB | 100.00 KiB/s<CR>
Working hard: 75% (30/40), 300.00 KiB | 100.00 KiB/s<CR>
Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s<CR>
Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s, done.
EOF
cat >in <<-\EOF &&
throughput 102400 1000
progress 10
throughput 204800 2000
progress 20
throughput 307200 3000
progress 30
throughput 409600 4000
progress 40
EOF
test-tool progress --total=40 "Working hard" <in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'cover up after throughput shortens' '
cat >expect <<-\EOF &&
Working hard: 1<CR>
Working hard: 2, 800.00 KiB | 400.00 KiB/s<CR>
Working hard: 3, 1.17 MiB | 400.00 KiB/s <CR>
Working hard: 4, 1.56 MiB | 400.00 KiB/s<CR>
Working hard: 4, 1.56 MiB | 400.00 KiB/s, done.
EOF
cat >in <<-\EOF &&
throughput 409600 1000
update
progress 1
throughput 819200 2000
update
progress 2
throughput 1228800 3000
update
progress 3
throughput 1638400 4000
update
progress 4
EOF
test-tool progress "Working hard" <in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'cover up after throughput shortens a lot' '
cat >expect <<-\EOF &&
Working hard: 1<CR>
Working hard: 2, 1000.00 KiB | 1000.00 KiB/s<CR>
Working hard: 3, 3.00 MiB | 1.50 MiB/s <CR>
Working hard: 3, 3.00 MiB | 1024.00 KiB/s, done.
EOF
cat >in <<-\EOF &&
throughput 1 1000
update
progress 1
throughput 1024000 2000
update
progress 2
throughput 3145728 3000
update
progress 3
EOF
test-tool progress "Working hard" <in 2>stderr &&
show_cr <stderr >out &&
test_i18ncmp expect out
'
test_expect_success 'progress generates traces' '
cat >in <<-\EOF &&
throughput 102400 1000
update
progress 10
throughput 204800 2000
update
progress 20
throughput 307200 3000
update
progress 30
throughput 409600 4000
update
progress 40
EOF
GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool progress --total=40 \
"Working hard" <in 2>stderr &&
# t0212/parse_events.perl intentionally omits regions and data.
grep -e "region_enter" -e "\"category\":\"progress\"" trace.event &&
grep -e "region_leave" -e "\"category\":\"progress\"" trace.event &&
grep "\"key\":\"total_objects\",\"value\":\"40\"" trace.event &&
grep "\"key\":\"total_bytes\",\"value\":\"409600\"" trace.event
'
test_done

View file

@ -140,8 +140,6 @@ test_expect_success '--batch-check without %(rest) considers whole line' '
test_cmp expect actual
'
test_oid_init
tree_sha1=$(git write-tree)
tree_size=$(($(test_oid rawsz) + 13))
tree_pretty_content="100644 blob $hello_sha1 hello"

View file

@ -74,13 +74,19 @@ test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-
test_expect_success 'read-tree with empty .git/info/sparse-checkout' '
git config core.sparsecheckout true &&
echo >.git/info/sparse-checkout &&
read_tree_u_must_fail -m -u HEAD &&
read_tree_u_must_succeed -m -u HEAD &&
git ls-files --stage >result &&
test_cmp expected result &&
git ls-files -t >result &&
cat >expected.swt <<-\EOF &&
S init.t
S sub/added
S sub/addedtoo
S subsub/added
EOF
test_cmp expected.swt result &&
test -f init.t &&
test -f sub/added
! test -f init.t &&
! test -f sub/added
'
test_expect_success 'match directories with trailing slash' '
@ -215,7 +221,6 @@ test_expect_success 'read-tree adds to worktree, dirty case' '
'
test_expect_success 'index removal and worktree narrowing at the same time' '
>empty &&
echo init.t >.git/info/sparse-checkout &&
echo sub/added >>.git/info/sparse-checkout &&
git checkout -f top &&
@ -223,7 +228,7 @@ test_expect_success 'index removal and worktree narrowing at the same time' '
git checkout removed &&
git ls-files sub/added >result &&
test ! -f sub/added &&
test_cmp empty result
test_must_be_empty result
'
test_expect_success 'read-tree --reset removes outside worktree' '
@ -234,18 +239,19 @@ test_expect_success 'read-tree --reset removes outside worktree' '
test_must_be_empty result
'
test_expect_success 'print errors when failed to update worktree' '
test_expect_success 'print warnings when some worktree updates disabled' '
echo sub >.git/info/sparse-checkout &&
git checkout -f init &&
mkdir sub &&
touch sub/added sub/addedtoo &&
test_must_fail git checkout top 2>actual &&
# Use -q to suppress "Previous HEAD position" and "Head is now at" msgs
git checkout -q top 2>actual &&
cat >expected <<\EOF &&
error: The following untracked working tree files would be overwritten by checkout:
warning: The following paths were already present and thus not updated despite sparse patterns:
sub/added
sub/addedtoo
Please move or remove them before you switch branches.
Aborting
After fixing the above paths, you may want to run `git sparse-checkout reapply`.
EOF
test_i18ncmp expected actual
'

View file

@ -12,8 +12,8 @@ test_submodule_switch_recursing_with_args "read-tree -u -m"
test_submodule_forced_switch_recursing_with_args "read-tree -u --reset"
test_submodule_switch "git read-tree -u -m"
test_submodule_switch "read-tree -u -m"
test_submodule_forced_switch "git read-tree -u --reset"
test_submodule_forced_switch "read-tree -u --reset"
test_done

View file

@ -49,6 +49,7 @@ git~1
.git.SPACE .git.{space}
.\\\\.GIT\\\\foobar backslashes
.git\\\\foobar backslashes2
.git...:alternate-stream
EOF
test_expect_success 'utf-8 paths allowed with core.protectHFS off' '

View file

@ -53,7 +53,8 @@ test_expect_success 'add a large file or two' '
for p in .git/objects/pack/pack-*.pack
do
count=$(( $count + 1 ))
if test -f "$p" && idx=${p%.pack}.idx && test -f "$idx"
if test_path_is_file "$p" &&
idx=${p%.pack}.idx && test_path_is_file "$idx"
then
continue
fi
@ -63,9 +64,9 @@ test_expect_success 'add a large file or two' '
test $count = 1 &&
cnt=$(git show-index <"$idx" | wc -l) &&
test $cnt = 2 &&
for l in .git/objects/??/??????????????????????????????????????
for l in .git/objects/$OIDPATH_REGEX
do
test -f "$l" || continue
test_path_is_file "$l" || continue
bad=t
done &&
test -z "$bad" &&
@ -76,7 +77,8 @@ test_expect_success 'add a large file or two' '
for p in .git/objects/pack/pack-*.pack
do
count=$(( $count + 1 ))
if test -f "$p" && idx=${p%.pack}.idx && test -f "$idx"
if test_path_is_file "$p" &&
idx=${p%.pack}.idx && test_path_is_file "$idx"
then
continue
fi
@ -111,7 +113,7 @@ test_expect_success 'packsize limit' '
count=0 &&
for pi in .git/objects/pack/pack-*.idx
do
test -f "$pi" && count=$(( $count + 1 ))
test_path_is_file "$pi" && count=$(( $count + 1 ))
done &&
test $count = 2 &&
@ -175,7 +177,8 @@ test_expect_success 'git-show a large file' '
test_expect_success 'index-pack' '
git clone file://"$(pwd)"/.git foo &&
GIT_DIR=non-existent git index-pack --strict --verify foo/.git/objects/pack/*.pack
GIT_DIR=non-existent git index-pack --object-format=$(test_oid algo) \
--strict --verify foo/.git/objects/pack/*.pack
'
test_expect_success 'repack' '
@ -194,15 +197,15 @@ test_expect_success 'pack-objects with large loose object' '
test_cmp huge actual
'
test_expect_success 'tar achiving' '
test_expect_success 'tar archiving' '
git archive --format=tar HEAD >/dev/null
'
test_expect_success 'zip achiving, store only' '
test_expect_success 'zip archiving, store only' '
git archive --format=zip -0 HEAD >/dev/null
'
test_expect_success 'zip achiving, deflate' '
test_expect_success 'zip archiving, deflate' '
git archive --format=zip HEAD >/dev/null
'

View file

@ -63,7 +63,6 @@ test_expect_success 'in partial clone, sparse checkout only fetches needed blobs
git -C server commit -m message &&
test_config -C client core.sparsecheckout 1 &&
test_config -C client extensions.partialclone origin &&
echo "!/*" >client/.git/info/sparse-checkout &&
echo "/a" >>client/.git/info/sparse-checkout &&
git -C client fetch --filter=blob:none origin &&

Some files were not shown because too many files have changed in this diff Show more