Build updates for MSVC.
* ss/msvc:
MSVC: use shipped headers instead of fallback definitions
MSVC: vsnprintf in Visual Studio 2015 doesn't need SNPRINTF_SIZE_CORR any more
--- /dev/null
+Git v2.8.1 Release Notes
+========================
+
+Fixes since v2.8
+----------------
+
+ * "make rpmbuild" target was broken as its input, git.spec.in, was
+ not updated to match a file it describes that has been renamed
+ recently. This has been fixed.
--- /dev/null
+Git v2.8.2 Release Notes
+========================
+
+Fixes since v2.8.1
+------------------
+
+ * The embedded args argv-array in the child process is used to build
+ the command line to run pack-objects instead of using a separate
+ array of strings.
+
+ * Bunch of tests on "git clone" has been renumbered for better
+ organization.
+
+ * The tests that involve running httpd leaked the system-wide
+ configuration in /etc/gitconfig to the tested environment.
+
+ * "index-pack --keep=<msg>" was broken since v2.1.0 timeframe.
+
+ * "git config --get-urlmatch", unlike other variants of the "git
+ config --get" family, did not signal error with its exit status
+ when there was no matching configuration.
+
+ * The "--local-env-vars" and "--resolve-git-dir" options of "git
+ rev-parse" failed to work outside a repository when the command's
+ option parsing was rewritten in 1.8.5 era.
+
+ * Fetching of history by naming a commit object name directly didn't
+ work across remote-curl transport.
+
+ * A small memory leak in an error codepath has been plugged in xdiff
+ code.
+
+ * strbuf_getwholeline() did not NUL-terminate the buffer on certain
+ corner cases in its error codepath.
+
+ * The startup_info data, which records if we are working inside a
+ repository (among other things), are now uniformly available to Git
+ subcommand implementations, and Git avoids attempting to touch
+ references when we are not in a repository.
+
+ * "git mergetool" did not work well with conflicts that both sides
+ deleted.
+
+ * "git send-email" had trouble parsing alias file in mailrc format
+ when lines in it had trailing whitespaces on them.
+
+ * When "git merge --squash" stopped due to conflict, the concluding
+ "git commit" failed to read in the SQUASH_MSG that shows the log
+ messages from all the squashed commits.
+
+ * "git merge FETCH_HEAD" dereferenced NULL pointer when merging
+ nothing into an unborn history (which is arguably unusual usage,
+ which perhaps was the reason why nobody noticed it).
+
+Also contains minor documentation updates and code clean-ups.
ifndef::git-format-patch[]
--check::
- Warn if changes introduce whitespace errors. What are
- considered whitespace errors is controlled by `core.whitespace`
+ Warn if changes introduce conflict markers or whitespace errors.
+ What are considered whitespace errors is controlled by `core.whitespace`
configuration. By default, trailing whitespaces (including
lines that solely consist of whitespaces) and a space character
that is immediately followed by a tab character inside the
[--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
[-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached]
- [--ignore-space-change | --ignore-whitespace ]
+ [--ignore-space-change | --ignore-whitespace]
[--whitespace=(nowarn|warn|fix|error|error-all)]
[--exclude=<path>] [--include=<path>] [--directory=<root>]
[--verbose] [--unsafe-paths] [<patch>...]
DESCRIPTION
-----------
Reads the supplied diff output (i.e. "a patch") and applies it to files.
+When running from a subdirectory in a repository, patched paths
+outside the directory are ignored.
With the `--index` option the patch is also applied to the index, and
with the `--cached` option the patch is only applied to the index.
Without these options, the command applies the patch only to files,
This command will fail with non-zero status upon error. Some exit
codes are:
-. The config file is invalid (ret=3),
-. can not write to the config file (ret=4),
-. no section or name was provided (ret=2),
-. the section or key is invalid (ret=1),
-. you try to unset an option which does not exist (ret=5),
-. you try to unset/set an option for which multiple lines match (ret=5), or
-. you try to use an invalid regexp (ret=6).
+- The config file is invalid (ret=3),
+- can not write to the config file (ret=4),
+- no section or name was provided (ret=2),
+- the section or key is invalid (ret=1),
+- you try to unset an option which does not exist (ret=5),
+- you try to unset/set an option for which multiple lines match (ret=5), or
+- you try to use an invalid regexp (ret=6).
On success, the command returns the exit code 0.
found and the last value if multiple key values were found.
--get-all::
- Like get, but does not fail if the number of values for the key
- is not exactly one.
+ Like get, but returns all values for a multi-valued key.
--get-regexp::
Like --get-all, but interprets the name as a regular expression and
given URL is returned (if no such key exists, the value for
section.key is used as a fallback). When given just the
section as name, do so for all the keys in the section and
- list them.
+ list them. Returns error code 1 if no value is found.
--global::
For writing options: write to global `~/.gitconfig` file
The remote heads to update from. This is relative to
$GIT_DIR (e.g. "HEAD", "refs/heads/master"). When
unspecified, update from all heads the remote side has.
++
+If the remote has enabled the options `uploadpack.allowTipSHA1InWant` or
+`uploadpack.allowReachableSHA1InWant`, they may alternatively be 40-hex
+sha1s present on the remote.
SEE ALSO
--------
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v2.8.0/git.html[documentation for release 2.8]
+* link:v2.8.1/git.html[documentation for release 2.8.1]
* release notes for
+ link:RelNotes/2.8.1.txt[2.8.1].
link:RelNotes/2.8.0.txt[2.8].
* link:v2.7.3/git.html[documentation for release 2.7.3]
pass the command-line option, which can be specified multiple times,
to another command.
+`OPT_CMDMODE(short, long, &int_var, description, enum_val)`::
+ Define an "operation mode" option, only one of which in the same
+ group of "operating mode" options that share the same `int_var`
+ can be given by the user. `enum_val` is set to `int_var` when the
+ option is used, but an error is reported if other "operating mode"
+ option has already set its value to the same `int_var`.
+
The last element of the array must be `OPT_END()`.
}
trace_performance(t, "frotz");
------------
+
+Bugs & Caveats
+--------------
+
+GIT_TRACE_* environment variables can be used to tell Git to show
+trace output to its standard error stream. Git can often spawn a pager
+internally to run its subcommand and send its standard output and
+standard error to it.
+
+Because GIT_TRACE_PERFORMANCE trace is generated only at the very end
+of the program with atexit(), which happens after the pager exits, it
+would not work well if you send its log to the standard error output
+and let Git spawn the pager at the same time.
+
+As a work around, you can for example use '--no-pager', or set
+GIT_TRACE_PERFORMANCE to another file descriptor which is redirected
+to stderr, or set GIT_TRACE_PERFORMANCE to a file specified by its
+absolute path.
+
+For example instead of the following command which by default may not
+print any performance information:
+
+------------
+GIT_TRACE_PERFORMANCE=2 git log -1
+------------
+
+you may want to use:
+
+------------
+GIT_TRACE_PERFORMANCE=2 git --no-pager log -1
+------------
+
+or:
+
+------------
+GIT_TRACE_PERFORMANCE=3 3>&2 git log -1
+------------
+
+or:
+
+------------
+GIT_TRACE_PERFORMANCE=/path/to/log/file git log -1
+------------
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.8.0
+DEF_VER=v2.8.1
LF='
'
-Documentation/RelNotes/2.8.0.txt
\ No newline at end of file
+Documentation/RelNotes/2.8.1.txt
\ No newline at end of file
const char *pattern;
int patternlen;
int nowildcardlen;
- int flags; /* EXC_FLAG_* */
+ unsigned flags; /* EXC_FLAG_* */
};
/*
&sb, &ctx);
hook_arg1 = "message";
} else if (!stat(git_path_merge_msg(), &statbuf)) {
+ /*
+ * prepend SQUASH_MSG here if it exists and a
+ * "merge --squash" was originally performed
+ */
+ if (!stat(git_path_squash_msg(), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0)
+ die_errno(_("could not read SQUASH_MSG"));
+ hook_arg1 = "squash";
+ } else
+ hook_arg1 = "merge";
if (strbuf_read_file(&sb, git_path_merge_msg(), 0) < 0)
die_errno(_("could not read MERGE_MSG"));
- hook_arg1 = "merge";
} else if (!stat(git_path_squash_msg(), &statbuf)) {
if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0)
die_errno(_("could not read SQUASH_MSG"));
static int get_urlmatch(const char *var, const char *url)
{
+ int ret;
char *section_tail;
struct string_list_item *item;
struct urlmatch_config config = { STRING_LIST_INIT_DUP };
git_config_with_options(urlmatch_config_entry, &config,
&given_config_source, respect_includes);
+ ret = !values.nr;
+
for_each_string_list_item(item, &values) {
struct urlmatch_current_candidate_value *matched = item->util;
struct strbuf buf = STRBUF_INIT;
free(config.url.url);
free((void *)config.section);
- return 0;
+ return ret;
}
static char *default_user_config(void)
struct ref *ref;
struct object_id oid;
- if (!get_oid_hex(name, &oid) && name[GIT_SHA1_HEXSZ] == ' ')
- name += GIT_SHA1_HEXSZ + 1;
- else
+ if (!get_oid_hex(name, &oid)) {
+ if (name[GIT_SHA1_HEXSZ] == ' ') {
+ /* <sha1> <ref>, find refname */
+ name += GIT_SHA1_HEXSZ + 1;
+ } else if (name[GIT_SHA1_HEXSZ] == '\0') {
+ ; /* <sha1>, leave sha1 as name */
+ } else {
+ /* <ref>, clear cruft from oid */
+ oidclr(&oid);
+ }
+ } else {
+ /* <ref>, clear cruft from get_oid_hex */
oidclr(&oid);
+ }
ref = alloc_ref(name);
oidcpy(&ref->old_oid, &oid);
}
static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
- int exc_std)
+ int exc_std, int use_index)
{
struct dir_struct dir;
int i, hit = 0;
memset(&dir, 0, sizeof(dir));
+ if (!use_index)
+ dir.flags |= DIR_NO_GITLINKS;
if (exc_std)
setup_standard_excludes(&dir);
int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude;
if (list.nr)
die(_("--no-index or --untracked cannot be used with revs."));
- hit = grep_directory(&opt, &pathspec, use_exclude);
+ hit = grep_directory(&opt, &pathspec, use_exclude, use_index);
} else if (0 <= opt_exclude) {
die(_("--[no-]exclude-standard cannot be used for tracked contents."));
} else if (!list.nr) {
}
}
+static const char *derive_filename(const char *pack_name, const char *suffix,
+ struct strbuf *buf)
+{
+ size_t len;
+ if (!strip_suffix(pack_name, ".pack", &len))
+ die(_("packfile name '%s' does not end with '.pack'"),
+ pack_name);
+ strbuf_add(buf, pack_name, len);
+ strbuf_addstr(buf, suffix);
+ return buf->buf;
+}
+
int cmd_index_pack(int argc, const char **argv, const char *prefix)
{
int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
usage(index_pack_usage);
if (fix_thin_pack && !from_stdin)
die(_("--fix-thin cannot be used without --stdin"));
- if (!index_name && pack_name) {
- size_t len;
- if (!strip_suffix(pack_name, ".pack", &len))
- die(_("packfile name '%s' does not end with '.pack'"),
- pack_name);
- strbuf_add(&index_name_buf, pack_name, len);
- strbuf_addstr(&index_name_buf, ".idx");
- index_name = index_name_buf.buf;
- }
- if (keep_msg && !keep_name && pack_name) {
- size_t len;
- if (!strip_suffix(pack_name, ".pack", &len))
- die(_("packfile name '%s' does not end with '.pack'"),
- pack_name);
- strbuf_add(&keep_name_buf, pack_name, len);
- strbuf_addstr(&keep_name_buf, ".idx");
- keep_name = keep_name_buf.buf;
- }
+ if (!index_name && pack_name)
+ index_name = derive_filename(pack_name, ".idx", &index_name_buf);
+ if (keep_msg && !keep_name && pack_name)
+ keep_name = derive_filename(pack_name, ".keep", &keep_name_buf);
+
if (verify) {
if (!index_name)
die(_("--verify with no packfile name given"));
set_git_dir(real_path(git_dir));
git_link = NULL;
}
+ startup_info->have_repository = 1;
return 0;
}
builtin_merge_options);
if (!head_commit) {
- struct commit *remote_head;
/*
* If the merged head is a valid one there is no reason
* to forbid "git merge" into a branch yet to be born.
* We do the same for "git pull".
*/
+ unsigned char *remote_head_sha1;
if (squash)
die(_("Squash commit into empty head not supported yet"));
if (fast_forward == FF_NO)
"an empty head"));
remoteheads = collect_parents(head_commit, &head_subsumed,
argc, argv, NULL);
- remote_head = remoteheads->item;
- if (!remote_head)
+ if (!remoteheads)
die(_("%s - not something we can merge"), argv[0]);
if (remoteheads->next)
die(_("Can merge only exactly one commit into empty head"));
- read_empty(remote_head->object.oid.hash, 0);
- update_ref("initial pull", "HEAD", remote_head->object.oid.hash,
+ remote_head_sha1 = remoteheads->item->object.oid.hash;
+ read_empty(remote_head_sha1, 0);
+ update_ref("initial pull", "HEAD", remote_head_sha1,
NULL, 0, UPDATE_REFS_DIE_ON_ERR);
goto done;
}
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+ int did_repo_setup = 0;
int has_dashdash = 0;
int output_prefix = 0;
unsigned char sha1[20];
}
}
- prefix = setup_git_directory();
- git_config(git_default_config, NULL);
+ /* No options; just report on whether we're in a git repo or not. */
+ if (argc == 1) {
+ setup_git_directory();
+ git_config(git_default_config, NULL);
+ return 0;
+ }
+
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
+ if (!strcmp(arg, "--local-env-vars")) {
+ int i;
+ for (i = 0; local_repo_env[i]; i++)
+ printf("%s\n", local_repo_env[i]);
+ continue;
+ }
+ if (!strcmp(arg, "--resolve-git-dir")) {
+ const char *gitdir = argv[++i];
+ if (!gitdir)
+ die("--resolve-git-dir requires an argument");
+ gitdir = resolve_gitdir(gitdir);
+ if (!gitdir)
+ die("not a gitdir '%s'", argv[i]);
+ puts(gitdir);
+ continue;
+ }
+
+ /* The rest of the options require a git repository. */
+ if (!did_repo_setup) {
+ prefix = setup_git_directory();
+ git_config(git_default_config, NULL);
+ did_repo_setup = 1;
+ }
+
if (!strcmp(arg, "--git-path")) {
if (!argv[i + 1])
die("--git-path requires an argument");
add_ref_exclusion(&ref_excludes, arg + 10);
continue;
}
- if (!strcmp(arg, "--local-env-vars")) {
- int i;
- for (i = 0; local_repo_env[i]; i++)
- printf("%s\n", local_repo_env[i]);
- continue;
- }
if (!strcmp(arg, "--show-toplevel")) {
const char *work_tree = get_git_work_tree();
if (work_tree)
puts(prefix_filename(pfx, strlen(pfx), get_git_common_dir()));
continue;
}
- if (!strcmp(arg, "--resolve-git-dir")) {
- const char *gitdir = argv[++i];
- if (!gitdir)
- die("--resolve-git-dir requires an argument");
- gitdir = resolve_gitdir(gitdir);
- if (!gitdir)
- die("not a gitdir '%s'", argv[i]);
- puts(gitdir);
- continue;
- }
if (!strcmp(arg, "--is-inside-git-dir")) {
printf("%s\n", is_inside_git_dir() ? "true"
: "false");
/* Takes a negative value returned by split_cmdline */
const char *split_cmdline_strerror(int cmdline_errno);
-/* git.c */
+/* setup.c */
struct startup_info {
int have_repository;
const char *prefix;
fprintf(out, "password=%s\n", e->item.password);
}
}
- else if (!strcmp(action.buf, "exit"))
+ else if (!strcmp(action.buf, "exit")) {
+ /*
+ * It's important that we clean up our socket first, and then
+ * signal the client only once we have finished the cleanup.
+ * Calling exit() directly does this, because we clean up in
+ * our atexit() handler, and then signal the client when our
+ * process actually ends, which closes the socket and gives
+ * them EOF.
+ */
exit(0);
+ }
else if (!strcmp(action.buf, "erase"))
remove_credential(&c);
else if (!strcmp(action.buf, "store")) {
void parse_exclude_pattern(const char **pattern,
int *patternlen,
- int *flags,
+ unsigned *flags,
int *nowildcardlen)
{
const char *p = *pattern;
{
struct exclude *x;
int patternlen;
- int flags;
+ unsigned flags;
int nowildcardlen;
parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen);
int match_basename(const char *basename, int basenamelen,
const char *pattern, int prefix, int patternlen,
- int flags)
+ unsigned flags)
{
if (prefix == patternlen) {
if (patternlen == basenamelen &&
int match_pathname(const char *pathname, int pathlen,
const char *base, int baselen,
const char *pattern, int prefix, int patternlen,
- int flags)
+ unsigned flags)
{
const char *name;
int namelen;
int nowildcardlen;
const char *base;
int baselen;
- int flags;
+ unsigned flags; /* EXC_FLAG_* */
/*
* Counting starts from 1 for line numbers in ignore files,
* attr.c:path_matches()
*/
extern int match_basename(const char *, int,
- const char *, int, int, int);
+ const char *, int, int, unsigned);
extern int match_pathname(const char *, int,
const char *, int,
- const char *, int, int, int);
+ const char *, int, int, unsigned);
extern struct exclude *last_exclude_matching(struct dir_struct *dir,
const char *name, int *dtype);
extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
struct exclude_list *el, int check_index);
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
-extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen);
+extern void parse_exclude_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen);
extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *el, int srcpos);
extern void clear_exclude_list(struct exclude_list *el);
int core_apply_sparse_checkout;
int merge_log_config = -1;
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
-struct startup_info *startup_info;
unsigned long pack_size_limit_cfg;
#ifndef PROTECT_HFS_DEFAULT
case "$ans" in
[mMcC]*)
git add -- "$MERGED"
- cleanup_temp_files --save-backup
+ if test "$merge_keep_backup" = "true"
+ then
+ cleanup_temp_files --save-backup
+ else
+ cleanup_temp_files
+ fi
return 0
;;
[dD]*)
return 0
;;
[aA]*)
+ if test "$merge_keep_temporaries" = "false"
+ then
+ cleanup_temp_files
+ fi
return 1
;;
esac
return
fi
- mv -- "$MERGED" "$BACKUP"
- cp -- "$BACKUP" "$MERGED"
+ if test -f "$MERGED"
+ then
+ mv -- "$MERGED" "$BACKUP"
+ cp -- "$BACKUP" "$MERGED"
+ fi
+ # Create a parent directory to handle delete/delete conflicts
+ # where the base's directory no longer exists.
+ mkdir -p "$(dirname "$MERGED")"
checkout_staged_file 1 "$MERGED" "$BASE"
checkout_staged_file 2 "$MERGED" "$LOCAL"
describe_file "$local_mode" "local" "$LOCAL"
describe_file "$remote_mode" "remote" "$REMOTE"
resolve_deleted_merge
- return
+ status=$?
+ rmdir -p "$(dirname "$MERGED")" 2>/dev/null
+ return $status
fi
if is_symlink "$local_mode" || is_symlink "$remote_mode"
$aliases{$alias} = \@addr
}}},
mailrc => sub { my $fh = shift; while (<$fh>) {
- if (/^alias\s+(\S+)\s+(.*)$/) {
+ if (/^alias\s+(\S+)\s+(.*?)\s*$/) {
# spaces delimit multiple addresses
$aliases{$1} = [ quotewords('\s+', 0, $2) ];
}}},
"concept guides. See 'git help <command>' or 'git help <concept>'\n"
"to read about a specific subcommand or concept.");
-static struct startup_info git_startup_info;
static int use_pager = -1;
static char *orig_cwd;
static const char *env_names[] = {
const char *cmd;
int done_help = 0;
- startup_info = &git_startup_info;
-
cmd = git_extract_argv0_path(argv[0]);
if (!cmd)
cmd = "git-help";
%files -f bin-man-doc-files
%defattr(-,root,root)
%{_datadir}/git-core/
-%doc README COPYING Documentation/*.txt
+%doc README.md COPYING Documentation/*.txt
%{!?_without_docs: %doc Documentation/*.html Documentation/howto}
%{!?_without_docs: %doc Documentation/technical}
%{_sysconfdir}/bash_completion.d
void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
{
if (err == EEXIST) {
- strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
- "If no other git process is currently running, this probably means a\n"
- "git process crashed in this repository earlier. Make sure no other git\n"
- "process is running and remove the file manually to continue.",
+ strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n"
+ "Another git process seems to be running in this repository, e.g.\n"
+ "an editor opened by 'git commit'. Please make sure all processes\n"
+ "are terminated then try again. If it still fails, a git process\n"
+ "may have crashed in this repository earlier:\n"
+ "remove the file manually to continue."),
absolute_path(path), strerror(err));
} else
- strbuf_addf(buf, "Unable to create '%s.lock': %s",
+ strbuf_addf(buf, _("Unable to create '%s.lock': %s"),
absolute_path(path), strerror(err));
}
git_mailmap_blob = "HEAD:.mailmap";
err |= read_mailmap_file(map, ".mailmap", repo_abbrev);
- err |= read_mailmap_blob(map, git_mailmap_blob, repo_abbrev);
+ if (startup_info->have_repository)
+ err |= read_mailmap_blob(map, git_mailmap_blob, repo_abbrev);
err |= read_mailmap_file(map, git_mailmap_file, repo_abbrev);
return err;
}
#: builtin/am.c:2321 builtin/commit.c:1593 builtin/merge.c:225
#: builtin/pull.c:159 builtin/revert.c:92 builtin/tag.c:355
msgid "key-id"
-msgstr "id de clé"
+msgstr "id-clé"
#: builtin/am.c:2322
msgid "GPG-sign commits"
#: builtin/checkout.c:1154
msgid "conflict style (merge or diff3)"
-msgstr "style de conflit (fusion ou diff3)"
+msgstr "style de conflit (merge (fusion) ou diff3)"
#: builtin/checkout.c:1157
msgid "do not limit pathspecs to sparse entries only"
#: builtin/fetch.c:122 builtin/log.c:1236
msgid "dir"
-msgstr "dir"
+msgstr "répertoire"
#: builtin/fetch.c:123
msgid "prepend this to submodule path output"
#: builtin/show-ref.c:165
msgid "only show tags (can be combined with heads)"
-msgstr "afficher seulement les étiquettes (peut être combiné avec des têtes)"
+msgstr "afficher seulement les étiquettes (peut être combiné avec heads)"
#: builtin/show-ref.c:166
msgid "only show heads (can be combined with tags)"
-msgstr "afficher seulement les têtes (peut être combiné avec des étiquettes)"
+msgstr "afficher seulement les têtes (peut être combiné avec tags)"
#: builtin/show-ref.c:167
msgid "stricter reference checking, requires exact ref path"
{
static int loaded;
struct object_id oid;
- const char *head_ref;
int flag;
if (loaded)
loaded = 1;
current_branch = NULL;
- head_ref = resolve_ref_unsafe("HEAD", 0, oid.hash, &flag);
- if (head_ref && (flag & REF_ISSYMREF) &&
- skip_prefix(head_ref, "refs/heads/", &head_ref)) {
- current_branch = make_branch(head_ref, 0);
+ if (startup_info->have_repository) {
+ const char *head_ref = resolve_ref_unsafe("HEAD", 0, oid.hash, &flag);
+ if (head_ref && (flag & REF_ISSYMREF) &&
+ skip_prefix(head_ref, "refs/heads/", &head_ref)) {
+ current_branch = make_branch(head_ref, 0);
+ }
}
git_config(handle_config, NULL);
alias_all_urls();
static int work_tree_config_is_bogus;
static struct string_list unknown_extensions = STRING_LIST_INIT_DUP;
+static struct startup_info the_startup_info;
+struct startup_info *startup_info = &the_startup_info;
+
/*
* The input parameter must contain an absolute path, and it must already be
* normalized.
else
setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
- if (startup_info) {
- startup_info->have_repository = !nongit_ok || !*nongit_ok;
- startup_info->prefix = prefix;
- }
+ startup_info->have_repository = !nongit_ok || !*nongit_ok;
+ startup_info->prefix = prefix;
+
return prefix;
}
int check_repository_format(void)
{
- return check_repository_format_gently(get_git_dir(), NULL);
+ check_repository_format_gently(get_git_dir(), NULL);
+ startup_info->have_repository = 1;
+ return 0;
}
/*
if (!starts_with(rel, "./") && !starts_with(rel, "../"))
return NULL;
- if (!startup_info)
- die("BUG: startup_info struct is not initialized.");
-
if (!is_inside_work_tree())
die("relative path syntax can't be used outside working tree.");
if (errno == ENOMEM)
die("Out of memory, getdelim failed");
- /* Restore slopbuf that we moved out of the way before */
+ /*
+ * Restore strbuf invariants; if getdelim left us with a NULL pointer,
+ * we can just re-init, but otherwise we should make sure that our
+ * length is empty, and that the result is NUL-terminated.
+ */
if (!sb->buf)
strbuf_init(sb, 0);
+ else
+ strbuf_reset(sb);
return EOF;
}
#else
PassEnv GNUPGHOME
PassEnv ASAN_OPTIONS
PassEnv GIT_TRACE
+PassEnv GIT_CONFIG_NOSYSTEM
Alias /dumb/ www/
Alias /auth/dumb/ www/auth/dumb/
cookieFile = /tmp/cookie.txt
EOF
+ test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
+ test_must_be_empty actual &&
+
echo true >expect &&
git config --bool --get-urlmatch http.SSLverify https://good.example.com >actual &&
test_cmp expect actual &&
grep "relative path syntax can.t be used outside working tree." error
'
-test_expect_success 'relative path when startup_info is NULL' '
- test_must_fail test-match-trees HEAD:./file.txt HEAD:./file.txt 2>error &&
- grep "BUG: startup_info struct is not initialized." error
-'
-
test_expect_success '<commit>:file correctly diagnosed after a pathname' '
test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&
test_i18ngrep ! "exists on disk" error &&
--- /dev/null
+#!/bin/sh
+
+test_description='check that certain rev-parse options work outside repo'
+. ./test-lib.sh
+
+test_expect_success 'set up non-repo directory' '
+ GIT_CEILING_DIRECTORIES=$(pwd) &&
+ export GIT_CEILING_DIRECTORIES &&
+ mkdir non-repo &&
+ cd non-repo &&
+ # confirm that git does not find a repo
+ test_must_fail git rev-parse --git-dir
+'
+
+# Rather than directly test the output of sq-quote directly,
+# make sure the shell can read back a tricky case, since
+# that's what we really care about anyway.
+tricky="really tricky with \\ and \" and '"
+dump_args () {
+ for i in "$@"; do
+ echo "arg: $i"
+ done
+}
+test_expect_success 'rev-parse --sq-quote' '
+ dump_args "$tricky" easy >expect &&
+ eval "dump_args $(git rev-parse --sq-quote "$tricky" easy)" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rev-parse --local-env-vars' '
+ git rev-parse --local-env-vars >actual &&
+ # we do not want to depend on the complete list here,
+ # so just look for something plausible
+ grep ^GIT_DIR actual
+'
+
+test_expect_success 'rev-parse --resolve-git-dir' '
+ git init --separate-git-dir repo dir &&
+ test_must_fail git rev-parse --resolve-git-dir . &&
+ echo "$(pwd)/repo" >expect &&
+ git rev-parse --resolve-git-dir dir/.git >actual &&
+ test_cmp expect actual
+'
+
+test_done
git index-pack test-3.pack &&
cmp test-3.idx test-3-${packname_3}.idx &&
+ cat test-1-${packname_1}.pack >test-4.pack &&
+ rm -f test-4.keep &&
+ git index-pack --keep=why test-4.pack &&
+ cmp test-1-${packname_1}.idx test-4.idx &&
+ test -f test-4.keep &&
+
:'
test_expect_success 'unpacking with --strict' '
git fsck
)
'
+
+test_expect_success 'fetch-pack can fetch a raw sha1' '
+ git init hidden &&
+ (
+ cd hidden &&
+ test_commit 1 &&
+ test_commit 2 &&
+ git update-ref refs/hidden/one HEAD^ &&
+ git config transfer.hiderefs refs/hidden &&
+ git config uploadpack.allowtipsha1inwant true
+ ) &&
+ git fetch-pack hidden $(git -C hidden rev-parse refs/hidden/one)
+'
+
check_prot_path () {
cat >expected <<-EOF &&
Diag: url=$1
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
+#
+
+test_description='test clone --reference'
+. ./test-lib.sh
+
+base_dir=$(pwd)
+
+U=$base_dir/UPLOAD_LOG
+
+# create a commit in repo $1 with name $2
+commit_in () {
+ (
+ cd "$1" &&
+ echo "$2" >"$2" &&
+ git add "$2" &&
+ git commit -m "$2"
+ )
+}
+
+# check that there are $2 loose objects in repo $1
+test_objcount () {
+ echo "$2" >expect &&
+ git -C "$1" count-objects >actual.raw &&
+ cut -d' ' -f1 <actual.raw >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'preparing first repository' '
+ test_create_repo A &&
+ commit_in A file1
+'
+
+test_expect_success 'preparing second repository' '
+ git clone A B &&
+ commit_in B file2 &&
+ git -C B repack -ad &&
+ git -C B prune
+'
+
+test_expect_success 'cloning with reference (-l -s)' '
+ git clone -l -s --reference B A C
+'
+
+test_expect_success 'existence of info/alternates' '
+ test_line_count = 2 C/.git/objects/info/alternates
+'
+
+test_expect_success 'pulling from reference' '
+ git -C C pull ../B master
+'
+
+test_expect_success 'that reference gets used' '
+ test_objcount C 0
+'
+
+test_expect_success 'cloning with reference (no -l -s)' '
+ GIT_TRACE_PACKET=$U.D git clone --reference B "file://$(pwd)/A" D
+'
+
+test_expect_success 'fetched no objects' '
+ test -s "$U.D" &&
+ ! grep " want" "$U.D"
+'
+
+test_expect_success 'existence of info/alternates' '
+ test_line_count = 1 D/.git/objects/info/alternates
+'
+
+test_expect_success 'pulling from reference' '
+ git -C D pull ../B master
+'
+
+test_expect_success 'that reference gets used' '
+ test_objcount D 0
+'
+
+test_expect_success 'updating origin' '
+ commit_in A file3 &&
+ git -C A repack -ad &&
+ git -C A prune
+'
+
+test_expect_success 'pulling changes from origin' '
+ git -C C pull origin
+'
+
+# the 2 local objects are commit and tree from the merge
+test_expect_success 'that alternate to origin gets used' '
+ test_objcount C 2
+'
+
+test_expect_success 'pulling changes from origin' '
+ git -C D pull origin
+'
+
+# the 5 local objects are expected; file3 blob, commit in A to add it
+# and its tree, and 2 are our tree and the merge commit.
+test_expect_success 'check objects expected to exist locally' '
+ test_objcount D 5
+'
+
+test_expect_success 'preparing alternate repository #1' '
+ test_create_repo F &&
+ commit_in F file1
+'
+
+test_expect_success 'cloning alternate repo #2 and adding changes to repo #1' '
+ git clone F G &&
+ commit_in F file2
+'
+
+test_expect_success 'cloning alternate repo #1, using #2 as reference' '
+ git clone --reference G F H
+'
+
+test_expect_success 'cloning with reference being subset of source (-l -s)' '
+ git clone -l -s --reference A B E
+'
+
+test_expect_success 'cloning with multiple references drops duplicates' '
+ git clone -s --reference B --reference A --reference B A dups &&
+ test_line_count = 2 dups/.git/objects/info/alternates
+'
+
+test_expect_success 'clone with reference from a tagged repository' '
+ (
+ cd A && git tag -a -m tagged HEAD
+ ) &&
+ git clone --reference=A A I
+'
+
+test_expect_success 'prepare branched repository' '
+ git clone A J &&
+ (
+ cd J &&
+ git checkout -b other master^ &&
+ echo other >otherfile &&
+ git add otherfile &&
+ git commit -m other &&
+ git checkout master
+ )
+'
+
+test_expect_success 'fetch with incomplete alternates' '
+ git init K &&
+ echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates &&
+ (
+ cd K &&
+ git remote add J "file://$base_dir/J" &&
+ GIT_TRACE_PACKET=$U.K git fetch J
+ ) &&
+ master_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/master) &&
+ test -s "$U.K" &&
+ ! grep " want $master_object" "$U.K" &&
+ tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) &&
+ ! grep " want $tag_object" "$U.K"
+'
+
+test_expect_success 'clone using repo with gitfile as a reference' '
+ git clone --separate-git-dir=L A M &&
+ git clone --reference=M A N &&
+ echo "$base_dir/L/objects" >expected &&
+ test_cmp expected "$base_dir/N/.git/objects/info/alternates"
+'
+
+test_expect_success 'clone using repo pointed at by gitfile as reference' '
+ git clone --reference=M/.git A O &&
+ echo "$base_dir/L/objects" >expected &&
+ test_cmp expected "$base_dir/O/.git/objects/info/alternates"
+'
+
+test_expect_success 'clone and dissociate from reference' '
+ git init P &&
+ (
+ cd P && test_commit one
+ ) &&
+ git clone P Q &&
+ (
+ cd Q && test_commit two
+ ) &&
+ git clone --no-local --reference=P Q R &&
+ git clone --no-local --reference=P --dissociate Q S &&
+ # removing the reference P would corrupt R but not S
+ rm -fr P &&
+ test_must_fail git -C R fsck &&
+ git -C S fsck
+'
+test_expect_success 'clone, dissociate from partial reference and repack' '
+ rm -fr P Q R &&
+ git init P &&
+ (
+ cd P &&
+ test_commit one &&
+ git repack &&
+ test_commit two &&
+ git repack
+ ) &&
+ git clone --bare P Q &&
+ (
+ cd P &&
+ git checkout -b second &&
+ test_commit three &&
+ git repack
+ ) &&
+ git clone --bare --dissociate --reference=P Q R &&
+ ls R/objects/pack/*.pack >packs.txt &&
+ test_line_count = 1 packs.txt
+'
+
+test_expect_success 'clone, dissociate from alternates' '
+ rm -fr A B C &&
+ test_create_repo A &&
+ commit_in A file1 &&
+ git clone --reference=A A B &&
+ test_line_count = 1 B/.git/objects/info/alternates &&
+ git clone --local --dissociate B C &&
+ ! test -f C/.git/objects/info/alternates &&
+ ( cd C && git fsck )
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='test local clone'
+. ./test-lib.sh
+
+repo_is_hardlinked() {
+ find "$1/objects" -type f -links 1 >output &&
+ test_line_count = 0 output
+}
+
+test_expect_success 'preparing origin repository' '
+ : >file && git add . && git commit -m1 &&
+ git clone --bare . a.git &&
+ git clone --bare . x &&
+ test "$(cd a.git && git config --bool core.bare)" = true &&
+ test "$(cd x && git config --bool core.bare)" = true &&
+ git bundle create b1.bundle --all &&
+ git bundle create b2.bundle master &&
+ mkdir dir &&
+ cp b1.bundle dir/b3 &&
+ cp b1.bundle b4
+'
+
+test_expect_success 'local clone without .git suffix' '
+ git clone -l -s a b &&
+ (cd b &&
+ test "$(git config --bool core.bare)" = false &&
+ git fetch)
+'
+
+test_expect_success 'local clone with .git suffix' '
+ git clone -l -s a.git c &&
+ (cd c && git fetch)
+'
+
+test_expect_success 'local clone from x' '
+ git clone -l -s x y &&
+ (cd y && git fetch)
+'
+
+test_expect_success 'local clone from x.git that does not exist' '
+ test_must_fail git clone -l -s x.git z
+'
+
+test_expect_success 'With -no-hardlinks, local will make a copy' '
+ git clone --bare --no-hardlinks x w &&
+ ! repo_is_hardlinked w
+'
+
+test_expect_success 'Even without -l, local will make a hardlink' '
+ rm -fr w &&
+ git clone -l --bare x w &&
+ repo_is_hardlinked w
+'
+
+test_expect_success 'local clone of repo with nonexistent ref in HEAD' '
+ echo "ref: refs/heads/nonexistent" > a.git/HEAD &&
+ git clone a d &&
+ (cd d &&
+ git fetch &&
+ test ! -e .git/refs/remotes/origin/HEAD)
+'
+
+test_expect_success 'bundle clone without .bundle suffix' '
+ git clone dir/b3 &&
+ (cd b3 && git fetch)
+'
+
+test_expect_success 'bundle clone with .bundle suffix' '
+ git clone b1.bundle &&
+ (cd b1 && git fetch)
+'
+
+test_expect_success 'bundle clone from b4' '
+ git clone b4 bdl &&
+ (cd bdl && git fetch)
+'
+
+test_expect_success 'bundle clone from b4.bundle that does not exist' '
+ test_must_fail git clone b4.bundle bb
+'
+
+test_expect_success 'bundle clone with nonexistent HEAD' '
+ git clone b2.bundle b2 &&
+ (cd b2 &&
+ git fetch &&
+ test_must_fail git rev-parse --verify refs/heads/master)
+'
+
+test_expect_success 'clone empty repository' '
+ mkdir empty &&
+ (cd empty &&
+ git init &&
+ git config receive.denyCurrentBranch warn) &&
+ git clone empty empty-clone &&
+ test_tick &&
+ (cd empty-clone
+ echo "content" >> foo &&
+ git add foo &&
+ git commit -m "Initial commit" &&
+ git push origin master &&
+ expected=$(git rev-parse master) &&
+ actual=$(git --git-dir=../empty/.git rev-parse master) &&
+ test $actual = $expected)
+'
+
+test_expect_success 'clone empty repository, and then push should not segfault.' '
+ rm -fr empty/ empty-clone/ &&
+ mkdir empty &&
+ (cd empty && git init) &&
+ git clone empty empty-clone &&
+ (cd empty-clone &&
+ test_must_fail git push)
+'
+
+test_expect_success 'cloning non-existent directory fails' '
+ rm -rf does-not-exist &&
+ test_must_fail git clone does-not-exist
+'
+
+test_expect_success 'cloning non-git directory fails' '
+ rm -rf not-a-git-repo not-a-git-repo-clone &&
+ mkdir not-a-git-repo &&
+ test_must_fail git clone not-a-git-repo not-a-git-repo-clone
+'
+
+test_expect_success 'cloning file:// does not hardlink' '
+ git clone --bare file://"$(pwd)"/a non-local &&
+ ! repo_is_hardlinked non-local
+'
+
+test_expect_success 'cloning a local path with --no-local does not hardlink' '
+ git clone --bare --no-local a force-nonlocal &&
+ ! repo_is_hardlinked force-nonlocal
+'
+
+test_expect_success 'cloning locally respects "-u" for fetching refs' '
+ test_must_fail git clone --bare -u false a should_not_work.git
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='basic clone options'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+
+ mkdir parent &&
+ (cd parent && git init &&
+ echo one >file && git add file &&
+ git commit -m one)
+
+'
+
+test_expect_success 'clone -o' '
+
+ git clone -o foo parent clone-o &&
+ (cd clone-o && git rev-parse --verify refs/remotes/foo/master)
+
+'
+
+test_expect_success 'redirected clone does not show progress' '
+
+ git clone "file://$(pwd)/parent" clone-redirected >out 2>err &&
+ ! grep % err &&
+ test_i18ngrep ! "Checking connectivity" err
+
+'
+
+test_expect_success 'redirected clone -v does show progress' '
+
+ git clone --progress "file://$(pwd)/parent" clone-redirected-progress \
+ >out 2>err &&
+ grep % err
+
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='some bundle related tests'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit initial &&
+ test_tick &&
+ git tag -m tag tag &&
+ test_commit second &&
+ test_commit third &&
+ git tag -d initial &&
+ git tag -d second &&
+ git tag -d third
+'
+
+test_expect_success 'annotated tags can be excluded by rev-list options' '
+ git bundle create bundle --all --since=7.Apr.2005.15:14:00.-0700 &&
+ git ls-remote bundle > output &&
+ grep tag output &&
+ git bundle create bundle --all --since=7.Apr.2005.15:16:00.-0700 &&
+ git ls-remote bundle > output &&
+ ! grep tag output
+'
+
+test_expect_success 'die if bundle file cannot be created' '
+ mkdir adir &&
+ test_must_fail git bundle create adir --all
+'
+
+test_expect_failure 'bundle --stdin' '
+ echo master | git bundle create stdin-bundle.bdl --stdin &&
+ git ls-remote stdin-bundle.bdl >output &&
+ grep master output
+'
+
+test_expect_failure 'bundle --stdin <rev-list options>' '
+ echo master | git bundle create hybrid-bundle.bdl --stdin tag &&
+ git ls-remote hybrid-bundle.bdl >output &&
+ grep master output
+'
+
+test_expect_success 'empty bundle file is rejected' '
+ : >empty-bundle &&
+ test_must_fail git fetch empty-bundle
+'
+
+# This triggers a bug in older versions where the resulting line (with
+# --pretty=oneline) was longer than a 1024-char buffer.
+test_expect_success 'ridiculously long subject in boundary' '
+ : >file4 &&
+ test_tick &&
+ git add file4 &&
+ printf "%01200d\n" 0 | git commit -F - &&
+ test_commit fifth &&
+ git bundle create long-subject-bundle.bdl HEAD^..HEAD &&
+ git bundle list-heads long-subject-bundle.bdl >heads &&
+ test -s heads &&
+ git fetch long-subject-bundle.bdl &&
+ sed -n "/^-/{p;q;}" long-subject-bundle.bdl >boundary &&
+ grep "^-[0-9a-f]\\{40\\} " boundary
+'
+
+test_expect_success 'prerequisites with an empty commit message' '
+ : >file1 &&
+ git add file1 &&
+ test_tick &&
+ git commit --allow-empty-message -m "" &&
+ test_commit file2 &&
+ git bundle create bundle HEAD^.. &&
+ git bundle verify bundle
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='Test cloning a repository larger than 2 gigabyte'
+. ./test-lib.sh
+
+if test -z "$GIT_TEST_CLONE_2GB"
+then
+ say 'Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t'
+else
+ test_set_prereq CLONE_2GB
+fi
+
+test_expect_success CLONE_2GB 'setup' '
+
+ git config pack.compression 0 &&
+ git config pack.depth 0 &&
+ blobsize=$((100*1024*1024)) &&
+ blobcount=$((2*1024*1024*1024/$blobsize+1)) &&
+ i=1 &&
+ (while test $i -le $blobcount
+ do
+ printf "Generating blob $i/$blobcount\r" >&2 &&
+ printf "blob\nmark :$i\ndata $blobsize\n" &&
+ #test-genrandom $i $blobsize &&
+ printf "%-${blobsize}s" $i &&
+ echo "M 100644 :$i $i" >> commit
+ i=$(($i+1)) ||
+ echo $? > exit-status
+ done &&
+ echo "commit refs/heads/master" &&
+ echo "author A U Thor <author@email.com> 123456789 +0000" &&
+ echo "committer C O Mitter <committer@email.com> 123456789 +0000" &&
+ echo "data 5" &&
+ echo ">2gb" &&
+ cat commit) |
+ git fast-import --big-file-threshold=2 &&
+ test ! -f exit-status
+
+'
+
+test_expect_success CLONE_2GB 'clone - bare' '
+
+ git clone --bare --no-hardlinks . clone-bare
+
+'
+
+test_expect_success CLONE_2GB 'clone - with worktree, file:// protocol' '
+
+ git clone "file://$(pwd)" clone-wt
+
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='clone --branch option'
+. ./test-lib.sh
+
+check_HEAD() {
+ echo refs/heads/"$1" >expect &&
+ git symbolic-ref HEAD >actual &&
+ test_cmp expect actual
+}
+
+check_file() {
+ echo "$1" >expect &&
+ test_cmp expect file
+}
+
+test_expect_success 'setup' '
+ mkdir parent &&
+ (cd parent && git init &&
+ echo one >file && git add file && git commit -m one &&
+ git checkout -b two &&
+ echo two >file && git add file && git commit -m two &&
+ git checkout master) &&
+ mkdir empty &&
+ (cd empty && git init)
+'
+
+test_expect_success 'vanilla clone chooses HEAD' '
+ git clone parent clone &&
+ (cd clone &&
+ check_HEAD master &&
+ check_file one
+ )
+'
+
+test_expect_success 'clone -b chooses specified branch' '
+ git clone -b two parent clone-two &&
+ (cd clone-two &&
+ check_HEAD two &&
+ check_file two
+ )
+'
+
+test_expect_success 'clone -b sets up tracking' '
+ (cd clone-two &&
+ echo origin >expect &&
+ git config branch.two.remote >actual &&
+ echo refs/heads/two >>expect &&
+ git config branch.two.merge >>actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'clone -b does not munge remotes/origin/HEAD' '
+ (cd clone-two &&
+ echo refs/remotes/origin/master >expect &&
+ git symbolic-ref refs/remotes/origin/HEAD >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'clone -b with bogus branch' '
+ test_must_fail git clone -b bogus parent clone-bogus
+'
+
+test_expect_success 'clone -b not allowed with empty repos' '
+ test_must_fail git clone -b branch empty clone-branch-empty
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='test cloning a repository with detached HEAD'
+. ./test-lib.sh
+
+head_is_detached() {
+ git --git-dir=$1/.git rev-parse --verify HEAD &&
+ test_must_fail git --git-dir=$1/.git symbolic-ref HEAD
+}
+
+test_expect_success 'setup' '
+ echo one >file &&
+ git add file &&
+ git commit -m one &&
+ echo two >file &&
+ git commit -a -m two &&
+ git tag two &&
+ echo three >file &&
+ git commit -a -m three
+'
+
+test_expect_success 'clone repo (detached HEAD points to branch)' '
+ git checkout master^0 &&
+ git clone "file://$PWD" detached-branch
+'
+test_expect_success 'cloned HEAD matches' '
+ echo three >expect &&
+ git --git-dir=detached-branch/.git log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+test_expect_failure 'cloned HEAD is detached' '
+ head_is_detached detached-branch
+'
+
+test_expect_success 'clone repo (detached HEAD points to tag)' '
+ git checkout two^0 &&
+ git clone "file://$PWD" detached-tag
+'
+test_expect_success 'cloned HEAD matches' '
+ echo two >expect &&
+ git --git-dir=detached-tag/.git log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+test_expect_success 'cloned HEAD is detached' '
+ head_is_detached detached-tag
+'
+
+test_expect_success 'clone repo (detached HEAD points to history)' '
+ git checkout two^ &&
+ git clone "file://$PWD" detached-history
+'
+test_expect_success 'cloned HEAD matches' '
+ echo one >expect &&
+ git --git-dir=detached-history/.git log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+test_expect_success 'cloned HEAD is detached' '
+ head_is_detached detached-history
+'
+
+test_expect_success 'clone repo (orphan detached HEAD)' '
+ git checkout master^0 &&
+ echo four >file &&
+ git commit -a -m four &&
+ git clone "file://$PWD" detached-orphan
+'
+test_expect_success 'cloned HEAD matches' '
+ echo four >expect &&
+ git --git-dir=detached-orphan/.git log -1 --format=%s >actual &&
+ test_cmp expect actual
+'
+test_expect_success 'cloned HEAD is detached' '
+ head_is_detached detached-orphan
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='tests for git clone -c key=value'
+. ./test-lib.sh
+
+test_expect_success 'clone -c sets config in cloned repo' '
+ rm -rf child &&
+ git clone -c core.foo=bar . child &&
+ echo bar >expect &&
+ git --git-dir=child/.git config core.foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'clone -c can set multi-keys' '
+ rm -rf child &&
+ git clone -c core.foo=bar -c core.foo=baz . child &&
+ { echo bar; echo baz; } >expect &&
+ git --git-dir=child/.git config --get-all core.foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'clone -c without a value is boolean true' '
+ rm -rf child &&
+ git clone -c core.foo . child &&
+ echo true >expect &&
+ git --git-dir=child/.git config --bool core.foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'clone -c config is available during clone' '
+ echo content >file &&
+ git add file &&
+ git commit -m one &&
+ rm -rf child &&
+ git clone -c core.autocrlf . child &&
+ printf "content\\r\\n" >expect &&
+ test_cmp expect child/file
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='test refspec written by clone-command'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ # Make two branches, "master" and "side"
+ echo one >file &&
+ git add file &&
+ git commit -m one &&
+ echo two >file &&
+ git commit -a -m two &&
+ git tag two &&
+ echo three >file &&
+ git commit -a -m three &&
+ git checkout -b side &&
+ echo four >file &&
+ git commit -a -m four &&
+ git checkout master &&
+
+ # default clone
+ git clone . dir_all &&
+
+ # default --single that follows HEAD=master
+ git clone --single-branch . dir_master &&
+
+ # default --single that follows HEAD=side
+ git checkout side &&
+ git clone --single-branch . dir_side &&
+
+ # explicit --single that follows side
+ git checkout master &&
+ git clone --single-branch --branch side . dir_side2 &&
+
+ # default --single with --mirror
+ git clone --single-branch --mirror . dir_mirror &&
+
+ # default --single with --branch and --mirror
+ git clone --single-branch --mirror --branch side . dir_mirror_side &&
+
+ # --single that does not know what branch to follow
+ git checkout two^ &&
+ git clone --single-branch . dir_detached &&
+
+ # explicit --single with tag
+ git clone --single-branch --branch two . dir_tag &&
+
+ # advance both "master" and "side" branches
+ git checkout side &&
+ echo five >file &&
+ git commit -a -m five &&
+ git checkout master &&
+ echo six >file &&
+ git commit -a -m six &&
+
+ # update tag
+ git tag -d two && git tag two
+'
+
+test_expect_success 'by default all branches will be kept updated' '
+ (
+ cd dir_all && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # follow both master and side
+ git for-each-ref refs/heads >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'by default no tags will be kept updated' '
+ (
+ cd dir_all && git fetch &&
+ git for-each-ref refs/tags >../actual
+ ) &&
+ git for-each-ref refs/tags >expect &&
+ test_must_fail test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at master' '
+ (
+ cd dir_master && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow master
+ git for-each-ref refs/heads/master >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at side' '
+ (
+ cd dir_side && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow side
+ git for-each-ref refs/heads/side >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch side' '
+ (
+ cd dir_side2 && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow side
+ git for-each-ref refs/heads/side >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch with tag fetches updated tag' '
+ (
+ cd dir_tag && git fetch &&
+ git for-each-ref refs/tags >../actual
+ ) &&
+ git for-each-ref refs/tags >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with --mirror' '
+ (
+ cd dir_mirror && git fetch &&
+ git for-each-ref refs > ../actual
+ ) &&
+ git for-each-ref refs >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch and --mirror' '
+ (
+ cd dir_mirror_side && git fetch &&
+ git for-each-ref refs > ../actual
+ ) &&
+ git for-each-ref refs >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with detached' '
+ (
+ cd dir_detached && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+ -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # nothing
+ >expect &&
+ test_cmp expect actual
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
+#
+
+test_description='test transitive info/alternate entries'
+. ./test-lib.sh
+
+# test that a file is not reachable in the current repository
+# but that it is after creating a info/alternate entry
+reachable_via() {
+ alternate="$1"
+ file="$2"
+ if git cat-file -e "HEAD:$file"; then return 1; fi
+ echo "$alternate" >> .git/objects/info/alternate
+ git cat-file -e "HEAD:$file"
+}
+
+test_valid_repo() {
+ git fsck --full > fsck.log &&
+ test_line_count = 0 fsck.log
+}
+
+base_dir=$(pwd)
+
+test_expect_success 'preparing first repository' \
+'test_create_repo A && cd A &&
+echo "Hello World" > file1 &&
+git add file1 &&
+git commit -m "Initial commit" file1 &&
+git repack -a -d &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'preparing second repository' \
+'git clone -l -s A B && cd B &&
+echo "foo bar" > file2 &&
+git add file2 &&
+git commit -m "next commit" file2 &&
+git repack -a -d -l &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'preparing third repository' \
+'git clone -l -s B C && cd C &&
+echo "Goodbye, cruel world" > file3 &&
+git add file3 &&
+git commit -m "one more" file3 &&
+git repack -a -d -l &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'creating too deep nesting' \
+'git clone -l -s C D &&
+git clone -l -s D E &&
+git clone -l -s E F &&
+git clone -l -s F G &&
+git clone --bare -l -s G H'
+
+test_expect_success 'invalidity of deepest repository' \
+'cd H && {
+ test_valid_repo
+ test $? -ne 0
+}'
+
+cd "$base_dir"
+
+test_expect_success 'validity of third repository' \
+'cd C &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success 'validity of fourth repository' \
+'cd D &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success 'breaking of loops' \
+'echo "$base_dir"/B/.git/objects >> "$base_dir"/A/.git/objects/info/alternates&&
+cd C &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success 'that info/alternates is necessary' \
+'cd C &&
+rm -f .git/objects/info/alternates &&
+! (test_valid_repo)'
+
+cd "$base_dir"
+
+test_expect_success 'that relative alternate is possible for current dir' \
+'cd C &&
+echo "../../../B/.git/objects" > .git/objects/info/alternates &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success \
+ 'that relative alternate is only possible for current dir' '
+ cd D &&
+ ! (test_valid_repo)
+'
+
+cd "$base_dir"
+
+test_done
+++ /dev/null
-#!/bin/sh
-#
-# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
-#
-
-test_description='test clone --reference'
-. ./test-lib.sh
-
-base_dir=$(pwd)
-
-U=$base_dir/UPLOAD_LOG
-
-# create a commit in repo $1 with name $2
-commit_in () {
- (
- cd "$1" &&
- echo "$2" >"$2" &&
- git add "$2" &&
- git commit -m "$2"
- )
-}
-
-# check that there are $2 loose objects in repo $1
-test_objcount () {
- echo "$2" >expect &&
- git -C "$1" count-objects >actual.raw &&
- cut -d' ' -f1 <actual.raw >actual &&
- test_cmp expect actual
-}
-
-test_expect_success 'preparing first repository' '
- test_create_repo A &&
- commit_in A file1
-'
-
-test_expect_success 'preparing second repository' '
- git clone A B &&
- commit_in B file2 &&
- git -C B repack -ad &&
- git -C B prune
-'
-
-test_expect_success 'cloning with reference (-l -s)' '
- git clone -l -s --reference B A C
-'
-
-test_expect_success 'existence of info/alternates' '
- test_line_count = 2 C/.git/objects/info/alternates
-'
-
-test_expect_success 'pulling from reference' '
- git -C C pull ../B master
-'
-
-test_expect_success 'that reference gets used' '
- test_objcount C 0
-'
-
-test_expect_success 'cloning with reference (no -l -s)' '
- GIT_TRACE_PACKET=$U.D git clone --reference B "file://$(pwd)/A" D
-'
-
-test_expect_success 'fetched no objects' '
- test -s "$U.D" &&
- ! grep " want" "$U.D"
-'
-
-test_expect_success 'existence of info/alternates' '
- test_line_count = 1 D/.git/objects/info/alternates
-'
-
-test_expect_success 'pulling from reference' '
- git -C D pull ../B master
-'
-
-test_expect_success 'that reference gets used' '
- test_objcount D 0
-'
-
-test_expect_success 'updating origin' '
- commit_in A file3 &&
- git -C A repack -ad &&
- git -C A prune
-'
-
-test_expect_success 'pulling changes from origin' '
- git -C C pull origin
-'
-
-# the 2 local objects are commit and tree from the merge
-test_expect_success 'that alternate to origin gets used' '
- test_objcount C 2
-'
-
-test_expect_success 'pulling changes from origin' '
- git -C D pull origin
-'
-
-# the 5 local objects are expected; file3 blob, commit in A to add it
-# and its tree, and 2 are our tree and the merge commit.
-test_expect_success 'check objects expected to exist locally' '
- test_objcount D 5
-'
-
-test_expect_success 'preparing alternate repository #1' '
- test_create_repo F &&
- commit_in F file1
-'
-
-test_expect_success 'cloning alternate repo #2 and adding changes to repo #1' '
- git clone F G &&
- commit_in F file2
-'
-
-test_expect_success 'cloning alternate repo #1, using #2 as reference' '
- git clone --reference G F H
-'
-
-test_expect_success 'cloning with reference being subset of source (-l -s)' '
- git clone -l -s --reference A B E
-'
-
-test_expect_success 'cloning with multiple references drops duplicates' '
- git clone -s --reference B --reference A --reference B A dups &&
- test_line_count = 2 dups/.git/objects/info/alternates
-'
-
-test_expect_success 'clone with reference from a tagged repository' '
- (
- cd A && git tag -a -m tagged HEAD
- ) &&
- git clone --reference=A A I
-'
-
-test_expect_success 'prepare branched repository' '
- git clone A J &&
- (
- cd J &&
- git checkout -b other master^ &&
- echo other >otherfile &&
- git add otherfile &&
- git commit -m other &&
- git checkout master
- )
-'
-
-test_expect_success 'fetch with incomplete alternates' '
- git init K &&
- echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates &&
- (
- cd K &&
- git remote add J "file://$base_dir/J" &&
- GIT_TRACE_PACKET=$U.K git fetch J
- ) &&
- master_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/master) &&
- test -s "$U.K" &&
- ! grep " want $master_object" "$U.K" &&
- tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) &&
- ! grep " want $tag_object" "$U.K"
-'
-
-test_expect_success 'clone using repo with gitfile as a reference' '
- git clone --separate-git-dir=L A M &&
- git clone --reference=M A N &&
- echo "$base_dir/L/objects" >expected &&
- test_cmp expected "$base_dir/N/.git/objects/info/alternates"
-'
-
-test_expect_success 'clone using repo pointed at by gitfile as reference' '
- git clone --reference=M/.git A O &&
- echo "$base_dir/L/objects" >expected &&
- test_cmp expected "$base_dir/O/.git/objects/info/alternates"
-'
-
-test_expect_success 'clone and dissociate from reference' '
- git init P &&
- (
- cd P && test_commit one
- ) &&
- git clone P Q &&
- (
- cd Q && test_commit two
- ) &&
- git clone --no-local --reference=P Q R &&
- git clone --no-local --reference=P --dissociate Q S &&
- # removing the reference P would corrupt R but not S
- rm -fr P &&
- test_must_fail git -C R fsck &&
- git -C S fsck
-'
-test_expect_success 'clone, dissociate from partial reference and repack' '
- rm -fr P Q R &&
- git init P &&
- (
- cd P &&
- test_commit one &&
- git repack &&
- test_commit two &&
- git repack
- ) &&
- git clone --bare P Q &&
- (
- cd P &&
- git checkout -b second &&
- test_commit three &&
- git repack
- ) &&
- git clone --bare --dissociate --reference=P Q R &&
- ls R/objects/pack/*.pack >packs.txt &&
- test_line_count = 1 packs.txt
-'
-
-test_expect_success 'clone, dissociate from alternates' '
- rm -fr A B C &&
- test_create_repo A &&
- commit_in A file1 &&
- git clone --reference=A A B &&
- test_line_count = 1 B/.git/objects/info/alternates &&
- git clone --local --dissociate B C &&
- ! test -f C/.git/objects/info/alternates &&
- ( cd C && git fsck )
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='test local clone'
-. ./test-lib.sh
-
-repo_is_hardlinked() {
- find "$1/objects" -type f -links 1 >output &&
- test_line_count = 0 output
-}
-
-test_expect_success 'preparing origin repository' '
- : >file && git add . && git commit -m1 &&
- git clone --bare . a.git &&
- git clone --bare . x &&
- test "$(cd a.git && git config --bool core.bare)" = true &&
- test "$(cd x && git config --bool core.bare)" = true &&
- git bundle create b1.bundle --all &&
- git bundle create b2.bundle master &&
- mkdir dir &&
- cp b1.bundle dir/b3 &&
- cp b1.bundle b4
-'
-
-test_expect_success 'local clone without .git suffix' '
- git clone -l -s a b &&
- (cd b &&
- test "$(git config --bool core.bare)" = false &&
- git fetch)
-'
-
-test_expect_success 'local clone with .git suffix' '
- git clone -l -s a.git c &&
- (cd c && git fetch)
-'
-
-test_expect_success 'local clone from x' '
- git clone -l -s x y &&
- (cd y && git fetch)
-'
-
-test_expect_success 'local clone from x.git that does not exist' '
- test_must_fail git clone -l -s x.git z
-'
-
-test_expect_success 'With -no-hardlinks, local will make a copy' '
- git clone --bare --no-hardlinks x w &&
- ! repo_is_hardlinked w
-'
-
-test_expect_success 'Even without -l, local will make a hardlink' '
- rm -fr w &&
- git clone -l --bare x w &&
- repo_is_hardlinked w
-'
-
-test_expect_success 'local clone of repo with nonexistent ref in HEAD' '
- echo "ref: refs/heads/nonexistent" > a.git/HEAD &&
- git clone a d &&
- (cd d &&
- git fetch &&
- test ! -e .git/refs/remotes/origin/HEAD)
-'
-
-test_expect_success 'bundle clone without .bundle suffix' '
- git clone dir/b3 &&
- (cd b3 && git fetch)
-'
-
-test_expect_success 'bundle clone with .bundle suffix' '
- git clone b1.bundle &&
- (cd b1 && git fetch)
-'
-
-test_expect_success 'bundle clone from b4' '
- git clone b4 bdl &&
- (cd bdl && git fetch)
-'
-
-test_expect_success 'bundle clone from b4.bundle that does not exist' '
- test_must_fail git clone b4.bundle bb
-'
-
-test_expect_success 'bundle clone with nonexistent HEAD' '
- git clone b2.bundle b2 &&
- (cd b2 &&
- git fetch &&
- test_must_fail git rev-parse --verify refs/heads/master)
-'
-
-test_expect_success 'clone empty repository' '
- mkdir empty &&
- (cd empty &&
- git init &&
- git config receive.denyCurrentBranch warn) &&
- git clone empty empty-clone &&
- test_tick &&
- (cd empty-clone
- echo "content" >> foo &&
- git add foo &&
- git commit -m "Initial commit" &&
- git push origin master &&
- expected=$(git rev-parse master) &&
- actual=$(git --git-dir=../empty/.git rev-parse master) &&
- test $actual = $expected)
-'
-
-test_expect_success 'clone empty repository, and then push should not segfault.' '
- rm -fr empty/ empty-clone/ &&
- mkdir empty &&
- (cd empty && git init) &&
- git clone empty empty-clone &&
- (cd empty-clone &&
- test_must_fail git push)
-'
-
-test_expect_success 'cloning non-existent directory fails' '
- rm -rf does-not-exist &&
- test_must_fail git clone does-not-exist
-'
-
-test_expect_success 'cloning non-git directory fails' '
- rm -rf not-a-git-repo not-a-git-repo-clone &&
- mkdir not-a-git-repo &&
- test_must_fail git clone not-a-git-repo not-a-git-repo-clone
-'
-
-test_expect_success 'cloning file:// does not hardlink' '
- git clone --bare file://"$(pwd)"/a non-local &&
- ! repo_is_hardlinked non-local
-'
-
-test_expect_success 'cloning a local path with --no-local does not hardlink' '
- git clone --bare --no-local a force-nonlocal &&
- ! repo_is_hardlinked force-nonlocal
-'
-
-test_expect_success 'cloning locally respects "-u" for fetching refs' '
- test_must_fail git clone --bare -u false a should_not_work.git
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='basic clone options'
-. ./test-lib.sh
-
-test_expect_success 'setup' '
-
- mkdir parent &&
- (cd parent && git init &&
- echo one >file && git add file &&
- git commit -m one)
-
-'
-
-test_expect_success 'clone -o' '
-
- git clone -o foo parent clone-o &&
- (cd clone-o && git rev-parse --verify refs/remotes/foo/master)
-
-'
-
-test_expect_success 'redirected clone does not show progress' '
-
- git clone "file://$(pwd)/parent" clone-redirected >out 2>err &&
- ! grep % err &&
- test_i18ngrep ! "Checking connectivity" err
-
-'
-
-test_expect_success 'redirected clone -v does show progress' '
-
- git clone --progress "file://$(pwd)/parent" clone-redirected-progress \
- >out 2>err &&
- grep % err
-
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='some bundle related tests'
-. ./test-lib.sh
-
-test_expect_success 'setup' '
- test_commit initial &&
- test_tick &&
- git tag -m tag tag &&
- test_commit second &&
- test_commit third &&
- git tag -d initial &&
- git tag -d second &&
- git tag -d third
-'
-
-test_expect_success 'annotated tags can be excluded by rev-list options' '
- git bundle create bundle --all --since=7.Apr.2005.15:14:00.-0700 &&
- git ls-remote bundle > output &&
- grep tag output &&
- git bundle create bundle --all --since=7.Apr.2005.15:16:00.-0700 &&
- git ls-remote bundle > output &&
- ! grep tag output
-'
-
-test_expect_success 'die if bundle file cannot be created' '
- mkdir adir &&
- test_must_fail git bundle create adir --all
-'
-
-test_expect_failure 'bundle --stdin' '
- echo master | git bundle create stdin-bundle.bdl --stdin &&
- git ls-remote stdin-bundle.bdl >output &&
- grep master output
-'
-
-test_expect_failure 'bundle --stdin <rev-list options>' '
- echo master | git bundle create hybrid-bundle.bdl --stdin tag &&
- git ls-remote hybrid-bundle.bdl >output &&
- grep master output
-'
-
-test_expect_success 'empty bundle file is rejected' '
- : >empty-bundle &&
- test_must_fail git fetch empty-bundle
-'
-
-# This triggers a bug in older versions where the resulting line (with
-# --pretty=oneline) was longer than a 1024-char buffer.
-test_expect_success 'ridiculously long subject in boundary' '
- : >file4 &&
- test_tick &&
- git add file4 &&
- printf "%01200d\n" 0 | git commit -F - &&
- test_commit fifth &&
- git bundle create long-subject-bundle.bdl HEAD^..HEAD &&
- git bundle list-heads long-subject-bundle.bdl >heads &&
- test -s heads &&
- git fetch long-subject-bundle.bdl &&
- sed -n "/^-/{p;q;}" long-subject-bundle.bdl >boundary &&
- grep "^-[0-9a-f]\\{40\\} " boundary
-'
-
-test_expect_success 'prerequisites with an empty commit message' '
- : >file1 &&
- git add file1 &&
- test_tick &&
- git commit --allow-empty-message -m "" &&
- test_commit file2 &&
- git bundle create bundle HEAD^.. &&
- git bundle verify bundle
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='Test cloning a repository larger than 2 gigabyte'
-. ./test-lib.sh
-
-if test -z "$GIT_TEST_CLONE_2GB"
-then
- say 'Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t'
-else
- test_set_prereq CLONE_2GB
-fi
-
-test_expect_success CLONE_2GB 'setup' '
-
- git config pack.compression 0 &&
- git config pack.depth 0 &&
- blobsize=$((100*1024*1024)) &&
- blobcount=$((2*1024*1024*1024/$blobsize+1)) &&
- i=1 &&
- (while test $i -le $blobcount
- do
- printf "Generating blob $i/$blobcount\r" >&2 &&
- printf "blob\nmark :$i\ndata $blobsize\n" &&
- #test-genrandom $i $blobsize &&
- printf "%-${blobsize}s" $i &&
- echo "M 100644 :$i $i" >> commit
- i=$(($i+1)) ||
- echo $? > exit-status
- done &&
- echo "commit refs/heads/master" &&
- echo "author A U Thor <author@email.com> 123456789 +0000" &&
- echo "committer C O Mitter <committer@email.com> 123456789 +0000" &&
- echo "data 5" &&
- echo ">2gb" &&
- cat commit) |
- git fast-import --big-file-threshold=2 &&
- test ! -f exit-status
-
-'
-
-test_expect_success CLONE_2GB 'clone - bare' '
-
- git clone --bare --no-hardlinks . clone-bare
-
-'
-
-test_expect_success CLONE_2GB 'clone - with worktree, file:// protocol' '
-
- git clone "file://$(pwd)" clone-wt
-
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='clone --branch option'
-. ./test-lib.sh
-
-check_HEAD() {
- echo refs/heads/"$1" >expect &&
- git symbolic-ref HEAD >actual &&
- test_cmp expect actual
-}
-
-check_file() {
- echo "$1" >expect &&
- test_cmp expect file
-}
-
-test_expect_success 'setup' '
- mkdir parent &&
- (cd parent && git init &&
- echo one >file && git add file && git commit -m one &&
- git checkout -b two &&
- echo two >file && git add file && git commit -m two &&
- git checkout master) &&
- mkdir empty &&
- (cd empty && git init)
-'
-
-test_expect_success 'vanilla clone chooses HEAD' '
- git clone parent clone &&
- (cd clone &&
- check_HEAD master &&
- check_file one
- )
-'
-
-test_expect_success 'clone -b chooses specified branch' '
- git clone -b two parent clone-two &&
- (cd clone-two &&
- check_HEAD two &&
- check_file two
- )
-'
-
-test_expect_success 'clone -b sets up tracking' '
- (cd clone-two &&
- echo origin >expect &&
- git config branch.two.remote >actual &&
- echo refs/heads/two >>expect &&
- git config branch.two.merge >>actual &&
- test_cmp expect actual
- )
-'
-
-test_expect_success 'clone -b does not munge remotes/origin/HEAD' '
- (cd clone-two &&
- echo refs/remotes/origin/master >expect &&
- git symbolic-ref refs/remotes/origin/HEAD >actual &&
- test_cmp expect actual
- )
-'
-
-test_expect_success 'clone -b with bogus branch' '
- test_must_fail git clone -b bogus parent clone-bogus
-'
-
-test_expect_success 'clone -b not allowed with empty repos' '
- test_must_fail git clone -b branch empty clone-branch-empty
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='test cloning a repository with detached HEAD'
-. ./test-lib.sh
-
-head_is_detached() {
- git --git-dir=$1/.git rev-parse --verify HEAD &&
- test_must_fail git --git-dir=$1/.git symbolic-ref HEAD
-}
-
-test_expect_success 'setup' '
- echo one >file &&
- git add file &&
- git commit -m one &&
- echo two >file &&
- git commit -a -m two &&
- git tag two &&
- echo three >file &&
- git commit -a -m three
-'
-
-test_expect_success 'clone repo (detached HEAD points to branch)' '
- git checkout master^0 &&
- git clone "file://$PWD" detached-branch
-'
-test_expect_success 'cloned HEAD matches' '
- echo three >expect &&
- git --git-dir=detached-branch/.git log -1 --format=%s >actual &&
- test_cmp expect actual
-'
-test_expect_failure 'cloned HEAD is detached' '
- head_is_detached detached-branch
-'
-
-test_expect_success 'clone repo (detached HEAD points to tag)' '
- git checkout two^0 &&
- git clone "file://$PWD" detached-tag
-'
-test_expect_success 'cloned HEAD matches' '
- echo two >expect &&
- git --git-dir=detached-tag/.git log -1 --format=%s >actual &&
- test_cmp expect actual
-'
-test_expect_success 'cloned HEAD is detached' '
- head_is_detached detached-tag
-'
-
-test_expect_success 'clone repo (detached HEAD points to history)' '
- git checkout two^ &&
- git clone "file://$PWD" detached-history
-'
-test_expect_success 'cloned HEAD matches' '
- echo one >expect &&
- git --git-dir=detached-history/.git log -1 --format=%s >actual &&
- test_cmp expect actual
-'
-test_expect_success 'cloned HEAD is detached' '
- head_is_detached detached-history
-'
-
-test_expect_success 'clone repo (orphan detached HEAD)' '
- git checkout master^0 &&
- echo four >file &&
- git commit -a -m four &&
- git clone "file://$PWD" detached-orphan
-'
-test_expect_success 'cloned HEAD matches' '
- echo four >expect &&
- git --git-dir=detached-orphan/.git log -1 --format=%s >actual &&
- test_cmp expect actual
-'
-test_expect_success 'cloned HEAD is detached' '
- head_is_detached detached-orphan
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='tests for git clone -c key=value'
-. ./test-lib.sh
-
-test_expect_success 'clone -c sets config in cloned repo' '
- rm -rf child &&
- git clone -c core.foo=bar . child &&
- echo bar >expect &&
- git --git-dir=child/.git config core.foo >actual &&
- test_cmp expect actual
-'
-
-test_expect_success 'clone -c can set multi-keys' '
- rm -rf child &&
- git clone -c core.foo=bar -c core.foo=baz . child &&
- { echo bar; echo baz; } >expect &&
- git --git-dir=child/.git config --get-all core.foo >actual &&
- test_cmp expect actual
-'
-
-test_expect_success 'clone -c without a value is boolean true' '
- rm -rf child &&
- git clone -c core.foo . child &&
- echo true >expect &&
- git --git-dir=child/.git config --bool core.foo >actual &&
- test_cmp expect actual
-'
-
-test_expect_success 'clone -c config is available during clone' '
- echo content >file &&
- git add file &&
- git commit -m one &&
- rm -rf child &&
- git clone -c core.autocrlf . child &&
- printf "content\\r\\n" >expect &&
- test_cmp expect child/file
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-
-test_description='test refspec written by clone-command'
-. ./test-lib.sh
-
-test_expect_success 'setup' '
- # Make two branches, "master" and "side"
- echo one >file &&
- git add file &&
- git commit -m one &&
- echo two >file &&
- git commit -a -m two &&
- git tag two &&
- echo three >file &&
- git commit -a -m three &&
- git checkout -b side &&
- echo four >file &&
- git commit -a -m four &&
- git checkout master &&
-
- # default clone
- git clone . dir_all &&
-
- # default --single that follows HEAD=master
- git clone --single-branch . dir_master &&
-
- # default --single that follows HEAD=side
- git checkout side &&
- git clone --single-branch . dir_side &&
-
- # explicit --single that follows side
- git checkout master &&
- git clone --single-branch --branch side . dir_side2 &&
-
- # default --single with --mirror
- git clone --single-branch --mirror . dir_mirror &&
-
- # default --single with --branch and --mirror
- git clone --single-branch --mirror --branch side . dir_mirror_side &&
-
- # --single that does not know what branch to follow
- git checkout two^ &&
- git clone --single-branch . dir_detached &&
-
- # explicit --single with tag
- git clone --single-branch --branch two . dir_tag &&
-
- # advance both "master" and "side" branches
- git checkout side &&
- echo five >file &&
- git commit -a -m five &&
- git checkout master &&
- echo six >file &&
- git commit -a -m six &&
-
- # update tag
- git tag -d two && git tag two
-'
-
-test_expect_success 'by default all branches will be kept updated' '
- (
- cd dir_all && git fetch &&
- git for-each-ref refs/remotes/origin |
- sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
- ) &&
- # follow both master and side
- git for-each-ref refs/heads >expect &&
- test_cmp expect actual
-'
-
-test_expect_success 'by default no tags will be kept updated' '
- (
- cd dir_all && git fetch &&
- git for-each-ref refs/tags >../actual
- ) &&
- git for-each-ref refs/tags >expect &&
- test_must_fail test_cmp expect actual
-'
-
-test_expect_success '--single-branch while HEAD pointing at master' '
- (
- cd dir_master && git fetch &&
- git for-each-ref refs/remotes/origin |
- sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
- ) &&
- # only follow master
- git for-each-ref refs/heads/master >expect &&
- test_cmp expect actual
-'
-
-test_expect_success '--single-branch while HEAD pointing at side' '
- (
- cd dir_side && git fetch &&
- git for-each-ref refs/remotes/origin |
- sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
- ) &&
- # only follow side
- git for-each-ref refs/heads/side >expect &&
- test_cmp expect actual
-'
-
-test_expect_success '--single-branch with explicit --branch side' '
- (
- cd dir_side2 && git fetch &&
- git for-each-ref refs/remotes/origin |
- sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
- ) &&
- # only follow side
- git for-each-ref refs/heads/side >expect &&
- test_cmp expect actual
-'
-
-test_expect_success '--single-branch with explicit --branch with tag fetches updated tag' '
- (
- cd dir_tag && git fetch &&
- git for-each-ref refs/tags >../actual
- ) &&
- git for-each-ref refs/tags >expect &&
- test_cmp expect actual
-'
-
-test_expect_success '--single-branch with --mirror' '
- (
- cd dir_mirror && git fetch &&
- git for-each-ref refs > ../actual
- ) &&
- git for-each-ref refs >expect &&
- test_cmp expect actual
-'
-
-test_expect_success '--single-branch with explicit --branch and --mirror' '
- (
- cd dir_mirror_side && git fetch &&
- git for-each-ref refs > ../actual
- ) &&
- git for-each-ref refs >expect &&
- test_cmp expect actual
-'
-
-test_expect_success '--single-branch with detached' '
- (
- cd dir_detached && git fetch &&
- git for-each-ref refs/remotes/origin |
- sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
- ) &&
- # nothing
- >expect &&
- test_cmp expect actual
-'
-
-test_done
+++ /dev/null
-#!/bin/sh
-#
-# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
-#
-
-test_description='test transitive info/alternate entries'
-. ./test-lib.sh
-
-# test that a file is not reachable in the current repository
-# but that it is after creating a info/alternate entry
-reachable_via() {
- alternate="$1"
- file="$2"
- if git cat-file -e "HEAD:$file"; then return 1; fi
- echo "$alternate" >> .git/objects/info/alternate
- git cat-file -e "HEAD:$file"
-}
-
-test_valid_repo() {
- git fsck --full > fsck.log &&
- test_line_count = 0 fsck.log
-}
-
-base_dir=$(pwd)
-
-test_expect_success 'preparing first repository' \
-'test_create_repo A && cd A &&
-echo "Hello World" > file1 &&
-git add file1 &&
-git commit -m "Initial commit" file1 &&
-git repack -a -d &&
-git prune'
-
-cd "$base_dir"
-
-test_expect_success 'preparing second repository' \
-'git clone -l -s A B && cd B &&
-echo "foo bar" > file2 &&
-git add file2 &&
-git commit -m "next commit" file2 &&
-git repack -a -d -l &&
-git prune'
-
-cd "$base_dir"
-
-test_expect_success 'preparing third repository' \
-'git clone -l -s B C && cd C &&
-echo "Goodbye, cruel world" > file3 &&
-git add file3 &&
-git commit -m "one more" file3 &&
-git repack -a -d -l &&
-git prune'
-
-cd "$base_dir"
-
-test_expect_success 'creating too deep nesting' \
-'git clone -l -s C D &&
-git clone -l -s D E &&
-git clone -l -s E F &&
-git clone -l -s F G &&
-git clone --bare -l -s G H'
-
-test_expect_success 'invalidity of deepest repository' \
-'cd H && {
- test_valid_repo
- test $? -ne 0
-}'
-
-cd "$base_dir"
-
-test_expect_success 'validity of third repository' \
-'cd C &&
-test_valid_repo'
-
-cd "$base_dir"
-
-test_expect_success 'validity of fourth repository' \
-'cd D &&
-test_valid_repo'
-
-cd "$base_dir"
-
-test_expect_success 'breaking of loops' \
-'echo "$base_dir"/B/.git/objects >> "$base_dir"/A/.git/objects/info/alternates&&
-cd C &&
-test_valid_repo'
-
-cd "$base_dir"
-
-test_expect_success 'that info/alternates is necessary' \
-'cd C &&
-rm -f .git/objects/info/alternates &&
-! (test_valid_repo)'
-
-cd "$base_dir"
-
-test_expect_success 'that relative alternate is possible for current dir' \
-'cd C &&
-echo "../../../B/.git/objects" > .git/objects/info/alternates &&
-test_valid_repo'
-
-cd "$base_dir"
-
-test_expect_success \
- 'that relative alternate is only possible for current dir' '
- cd D &&
- ! (test_valid_repo)
-'
-
-cd "$base_dir"
-
-test_done
test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG
'
- test_expect_success 'commit' '
- try_commit "" &&
- test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG
- '
-
test_expect_success 'commit --status' '
try_commit --status &&
test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG
printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >file.1
printf '%s\n' 1 2 3 4 '5 X' 6 7 8 9 >file.5
printf '%s\n' 1 2 3 4 5 6 7 8 '9 X' >file.9
+printf '%s\n' 1 2 3 4 5 6 7 8 '9 Y' >file.9y
printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >result.1
printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 9 >result.1-5
printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 '9 X' >result.1-5-9
+printf '%s\n' 1 2 3 4 5 6 7 8 '9 Z' >result.9z
>empty
create_merge_msgs () {
git tag c2 &&
c2=$(git rev-parse HEAD) &&
git reset --hard "$c0" &&
+ cp file.9y file &&
+ git add file &&
+ test_tick &&
+ git commit -m "commit 7" &&
+ git tag c7 &&
+ git reset --hard "$c0" &&
cp file.9 file &&
git add file &&
test_tick &&
verify_parents $c1 $c2
'
+test_expect_success 'merge --squash c3 with c7' '
+ git reset --hard c3 &&
+ test_must_fail git merge --squash c7 &&
+ cat result.9z >file &&
+ git commit --no-edit -a &&
+
+ {
+ cat <<-EOF
+ Squashed commit of the following:
+
+ $(git show -s c7)
+
+ # Conflicts:
+ # file
+ EOF
+ } >expect &&
+ git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
+ test_cmp expect actual
+'
+
test_debug 'git log --graph --decorate --oneline --all'
test_expect_success 'merge c1 with c2 and c3' '
test_must_fail git merge -s resolve master
'
+test_expect_success 'merge nothing into void' '
+ git init void &&
+ (
+ cd void &&
+ git remote add up .. &&
+ git fetch up &&
+ test_must_fail git merge FETCH_HEAD
+ )
+'
+
test_done
git reset --hard
'
+test_expect_success 'mergetool delete/delete conflict' '
+ git checkout -b delete-base branch1 &&
+ mkdir -p a/a &&
+ (echo one; echo two; echo 3; echo 4) >a/a/file.txt &&
+ git add a/a/file.txt &&
+ git commit -m"base file" &&
+ git checkout -b move-to-b delete-base &&
+ mkdir -p b/b &&
+ git mv a/a/file.txt b/b/file.txt &&
+ (echo one; echo two; echo 4) >b/b/file.txt &&
+ git commit -a -m"move to b" &&
+ git checkout -b move-to-c delete-base &&
+ mkdir -p c/c &&
+ git mv a/a/file.txt c/c/file.txt &&
+ (echo one; echo two; echo 3) >c/c/file.txt &&
+ git commit -a -m"move to c" &&
+ test_must_fail git merge move-to-b &&
+ echo d | git mergetool a/a/file.txt &&
+ ! test -f a/a/file.txt &&
+ git reset --hard HEAD &&
+ test_must_fail git merge move-to-b &&
+ echo m | git mergetool a/a/file.txt &&
+ test -f b/b/file.txt &&
+ git reset --hard HEAD &&
+ test_must_fail git merge move-to-b &&
+ ! echo a | git mergetool a/a/file.txt &&
+ ! test -f a/a/file.txt &&
+ git reset --hard HEAD
+'
+
+test_expect_success 'mergetool produces no errors when keepBackup is used' '
+ test_config mergetool.keepBackup true &&
+ test_must_fail git merge move-to-b &&
+ : >expect &&
+ echo d | git mergetool a/a/file.txt 2>actual &&
+ test_cmp expect actual &&
+ ! test -d a &&
+ git reset --hard HEAD
+'
+
+test_expect_success 'mergetool honors tempfile config for deleted files' '
+ test_config mergetool.keepTemporaries false &&
+ test_must_fail git merge move-to-b &&
+ echo d | git mergetool a/a/file.txt &&
+ ! test -d a &&
+ git reset --hard HEAD
+'
+
+test_expect_success 'mergetool keeps tempfiles when aborting delete/delete' '
+ test_config mergetool.keepTemporaries true &&
+ test_must_fail git merge move-to-b &&
+ ! (echo a; echo n) | git mergetool a/a/file.txt &&
+ test -d a/a &&
+ cat >expect <<-\EOF &&
+ file_BASE_.txt
+ file_LOCAL_.txt
+ file_REMOTE_.txt
+ EOF
+ ls -1 a/a | sed -e "s/[0-9]*//g" >actual &&
+ test_cmp expect actual &&
+ git clean -fdx &&
+ git reset --hard HEAD
+'
+
test_expect_success 'deleted vs modified submodule' '
git checkout -b test6 branch1 &&
git submodule update -N &&
)
'
+test_expect_success 'grep --no-index descends into repos, but not .git' '
+ rm -fr non &&
+ mkdir -p non/git &&
+ (
+ GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd non/git &&
+
+ echo magic >file &&
+ git init repo &&
+ (
+ cd repo &&
+ echo magic >file &&
+ git add file &&
+ git commit -m foo &&
+ echo magic >.git/file
+ ) &&
+
+ cat >expect <<-\EOF &&
+ file
+ repo/file
+ EOF
+ git grep -l --no-index magic >actual &&
+ test_cmp expect actual
+ )
+'
+
test_expect_success 'setup double-dash tests' '
cat >double-dash <<EOF &&
--
git fast-import </dev/null
'
+test_expect_success 'truncated stream complains' '
+ echo "tag foo" | test_must_fail git fast-import
+'
+
test_expect_success 'A: create pack from stdin' '
test_tick &&
cat >input <<-INPUT_END &&
unsigned char hash1[20], hash2[20], shifted[20];
struct tree *one, *two;
+ setup_git_directory();
+
if (get_sha1(av[1], hash1))
die("cannot parse %s as an object name", av[1]);
if (get_sha1(av[2], hash2))
if (argc < 2)
return 1;
+ setup_git_directory();
+
if (!strcmp(argv[1], "run-twice")) {
printf("1st\n");
if (!run_revision_walk())
"corruption on the remote side.";
int buffered = -1;
ssize_t sz;
- const char *argv[13];
- int i, arg = 0;
+ int i;
FILE *pipe_fd;
if (shallow_nr) {
- argv[arg++] = "--shallow-file";
- argv[arg++] = "";
+ argv_array_push(&pack_objects.args, "--shallow-file");
+ argv_array_push(&pack_objects.args, "");
}
- argv[arg++] = "pack-objects";
- argv[arg++] = "--revs";
+ argv_array_push(&pack_objects.args, "pack-objects");
+ argv_array_push(&pack_objects.args, "--revs");
if (use_thin_pack)
- argv[arg++] = "--thin";
+ argv_array_push(&pack_objects.args, "--thin");
- argv[arg++] = "--stdout";
+ argv_array_push(&pack_objects.args, "--stdout");
if (shallow_nr)
- argv[arg++] = "--shallow";
+ argv_array_push(&pack_objects.args, "--shallow");
if (!no_progress)
- argv[arg++] = "--progress";
+ argv_array_push(&pack_objects.args, "--progress");
if (use_ofs_delta)
- argv[arg++] = "--delta-base-offset";
+ argv_array_push(&pack_objects.args, "--delta-base-offset");
if (use_include_tag)
- argv[arg++] = "--include-tag";
- argv[arg++] = NULL;
+ argv_array_push(&pack_objects.args, "--include-tag");
pack_objects.in = -1;
pack_objects.out = -1;
pack_objects.err = -1;
pack_objects.git_cmd = 1;
- pack_objects.argv = argv;
if (start_command(&pack_objects))
die("git upload-pack: unable to fork git-pack-objects");
xdl_free_ctx(&xe->xdf2);
xdl_free_ctx(&xe->xdf1);
+ xdl_free_classifier(&cf);
return -1;
}
- if (!(xpp->flags & XDF_HISTOGRAM_DIFF))
+ if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)
xdl_free_classifier(&cf);
return 0;