Merge branch 'jc/clone-borrow'

Allow "git clone --reference" to be used more safely.

* jc/clone-borrow:
  clone: --dissociate option to mark that reference is only temporary
This commit is contained in:
Junio C Hamano 2015-01-07 12:42:13 -08:00
Родитель da178ac793 fb1d6dabce
Коммит d35c802793
3 изменённых файлов: 46 добавлений и 2 удалений

Просмотреть файл

@ -12,7 +12,7 @@ SYNOPSIS
'git clone' [--template=<template_directory>]
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
[-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
[--separate-git-dir <git dir>]
[--dissociate] [--separate-git-dir <git dir>]
[--depth <depth>] [--[no-]single-branch]
[--recursive | --recurse-submodules] [--] <repository>
[<directory>]
@ -98,7 +98,14 @@ objects from the source repository into a pack in the cloned repository.
require fewer objects to be copied from the repository
being cloned, reducing network and local storage costs.
+
*NOTE*: see the NOTE for the `--shared` option.
*NOTE*: see the NOTE for the `--shared` option, and also the
`--dissociate` option.
--dissociate::
Borrow the objects from reference repositories specified
with the `--reference` options only to reduce network
transfer and stop borrowing from them after a clone is made
by making necessary local copies of borrowed objects.
--quiet::
-q::

Просмотреть файл

@ -49,6 +49,7 @@ static int option_verbosity;
static int option_progress = -1;
static struct string_list option_config;
static struct string_list option_reference;
static int option_dissociate;
static int opt_parse_reference(const struct option *opt, const char *arg, int unset)
{
@ -94,6 +95,8 @@ static struct option builtin_clone_options[] = {
N_("create a shallow clone of that depth")),
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
OPT_BOOL(0, "dissociate", &option_dissociate,
N_("use --reference only while cloning")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
N_("separate git dir from working tree")),
OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
@ -735,6 +738,16 @@ static void write_refspec_config(const char *src_ref_prefix,
strbuf_release(&value);
}
static void dissociate_from_references(void)
{
static const char* argv[] = { "repack", "-a", "-d", NULL };
if (run_command_v_opt(argv, RUN_GIT_CMD|RUN_COMMAND_NO_STDIN))
die(_("cannot repack to clean up"));
if (unlink(git_path("objects/info/alternates")) && errno != ENOENT)
die_errno(_("cannot unlink temporary alternates file"));
}
int cmd_clone(int argc, const char **argv, const char *prefix)
{
int is_bundle = 0, is_local;
@ -880,6 +893,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_reference.nr)
setup_reference();
else if (option_dissociate) {
warning(_("--dissociate given, but there is no --reference"));
option_dissociate = 0;
}
fetch_pattern = value.buf;
refspec = parse_fetch_refspec(1, &fetch_pattern);
@ -993,6 +1010,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
transport_unlock_pack(transport);
transport_disconnect(transport);
if (option_dissociate)
dissociate_from_references();
junk_mode = JUNK_LEAVE_REPO;
err = checkout();

Просмотреть файл

@ -198,4 +198,21 @@ test_expect_success 'clone using repo pointed at by gitfile as reference' '
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_done