smart-http: support shallow fetch/clone
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
58f2ed051f
commit
16094885ca
@ -437,6 +437,13 @@ set by Git if the remote helper has the 'option' capability.
|
|||||||
'option check-connectivity' \{'true'|'false'\}::
|
'option check-connectivity' \{'true'|'false'\}::
|
||||||
Request the helper to check connectivity of a clone.
|
Request the helper to check connectivity of a clone.
|
||||||
|
|
||||||
|
'option cloning \{'true'|'false'\}::
|
||||||
|
Notify the helper this is a clone request (i.e. the current
|
||||||
|
repository is guaranteed empty).
|
||||||
|
|
||||||
|
'option update-shallow \{'true'|'false'\}::
|
||||||
|
Allow to extend .git/shallow if the new refs require it.
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkgit:git-remote[1]
|
linkgit:git-remote[1]
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "fetch-pack.h"
|
#include "fetch-pack.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
|
#include "sha1-array.h"
|
||||||
|
|
||||||
static const char fetch_pack_usage[] =
|
static const char fetch_pack_usage[] =
|
||||||
"git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] "
|
"git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] "
|
||||||
@ -46,6 +47,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
|
|||||||
char **pack_lockfile_ptr = NULL;
|
char **pack_lockfile_ptr = NULL;
|
||||||
struct child_process *conn;
|
struct child_process *conn;
|
||||||
struct fetch_pack_args args;
|
struct fetch_pack_args args;
|
||||||
|
struct sha1_array shallow = SHA1_ARRAY_INIT;
|
||||||
|
|
||||||
packet_trace_identity("fetch-pack");
|
packet_trace_identity("fetch-pack");
|
||||||
|
|
||||||
@ -113,6 +115,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
|
|||||||
args.check_self_contained_and_connected = 1;
|
args.check_self_contained_and_connected = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("--cloning", arg)) {
|
||||||
|
args.cloning = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp("--update-shallow", arg)) {
|
||||||
|
args.update_shallow = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
usage(fetch_pack_usage);
|
usage(fetch_pack_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,10 +167,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
|
|||||||
args.verbose ? CONNECT_VERBOSE : 0);
|
args.verbose ? CONNECT_VERBOSE : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, NULL);
|
get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow);
|
||||||
|
|
||||||
ref = fetch_pack(&args, fd, conn, ref, dest,
|
ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
|
||||||
sought, nr_sought, NULL, pack_lockfile_ptr);
|
&shallow, pack_lockfile_ptr);
|
||||||
if (pack_lockfile) {
|
if (pack_lockfile) {
|
||||||
printf("lock %s\n", pack_lockfile);
|
printf("lock %s\n", pack_lockfile);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "sideband.h"
|
#include "sideband.h"
|
||||||
#include "argv-array.h"
|
#include "argv-array.h"
|
||||||
#include "credential.h"
|
#include "credential.h"
|
||||||
|
#include "sha1-array.h"
|
||||||
|
|
||||||
static struct remote *remote;
|
static struct remote *remote;
|
||||||
/* always ends with a trailing slash */
|
/* always ends with a trailing slash */
|
||||||
@ -20,6 +21,8 @@ struct options {
|
|||||||
unsigned long depth;
|
unsigned long depth;
|
||||||
unsigned progress : 1,
|
unsigned progress : 1,
|
||||||
check_self_contained_and_connected : 1,
|
check_self_contained_and_connected : 1,
|
||||||
|
cloning : 1,
|
||||||
|
update_shallow : 1,
|
||||||
followtags : 1,
|
followtags : 1,
|
||||||
dry_run : 1,
|
dry_run : 1,
|
||||||
thin : 1;
|
thin : 1;
|
||||||
@ -87,8 +90,23 @@ static int set_option(const char *name, const char *value)
|
|||||||
string_list_append(&cas_options, val.buf);
|
string_list_append(&cas_options, val.buf);
|
||||||
strbuf_release(&val);
|
strbuf_release(&val);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (!strcmp(name, "cloning")) {
|
||||||
else {
|
if (!strcmp(value, "true"))
|
||||||
|
options.cloning = 1;
|
||||||
|
else if (!strcmp(value, "false"))
|
||||||
|
options.cloning = 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
} else if (!strcmp(name, "update-shallow")) {
|
||||||
|
if (!strcmp(value, "true"))
|
||||||
|
options.update_shallow = 1;
|
||||||
|
else if (!strcmp(value, "false"))
|
||||||
|
options.update_shallow = 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
return 1 /* unsupported */;
|
return 1 /* unsupported */;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,6 +117,7 @@ struct discovery {
|
|||||||
char *buf;
|
char *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
struct ref *refs;
|
struct ref *refs;
|
||||||
|
struct sha1_array shallow;
|
||||||
unsigned proto_git : 1;
|
unsigned proto_git : 1;
|
||||||
};
|
};
|
||||||
static struct discovery *last_discovery;
|
static struct discovery *last_discovery;
|
||||||
@ -107,7 +126,7 @@ static struct ref *parse_git_refs(struct discovery *heads, int for_push)
|
|||||||
{
|
{
|
||||||
struct ref *list = NULL;
|
struct ref *list = NULL;
|
||||||
get_remote_heads(-1, heads->buf, heads->len, &list,
|
get_remote_heads(-1, heads->buf, heads->len, &list,
|
||||||
for_push ? REF_NORMAL : 0, NULL, NULL);
|
for_push ? REF_NORMAL : 0, NULL, &heads->shallow);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +187,7 @@ static void free_discovery(struct discovery *d)
|
|||||||
if (d) {
|
if (d) {
|
||||||
if (d == last_discovery)
|
if (d == last_discovery)
|
||||||
last_discovery = NULL;
|
last_discovery = NULL;
|
||||||
|
free(d->shallow.sha1);
|
||||||
free(d->buf_alloc);
|
free(d->buf_alloc);
|
||||||
free_refs(d->refs);
|
free_refs(d->refs);
|
||||||
free(d);
|
free(d);
|
||||||
@ -688,7 +708,7 @@ static int fetch_git(struct discovery *heads,
|
|||||||
struct strbuf preamble = STRBUF_INIT;
|
struct strbuf preamble = STRBUF_INIT;
|
||||||
char *depth_arg = NULL;
|
char *depth_arg = NULL;
|
||||||
int argc = 0, i, err;
|
int argc = 0, i, err;
|
||||||
const char *argv[16];
|
const char *argv[17];
|
||||||
|
|
||||||
argv[argc++] = "fetch-pack";
|
argv[argc++] = "fetch-pack";
|
||||||
argv[argc++] = "--stateless-rpc";
|
argv[argc++] = "--stateless-rpc";
|
||||||
@ -704,6 +724,10 @@ static int fetch_git(struct discovery *heads,
|
|||||||
}
|
}
|
||||||
if (options.check_self_contained_and_connected)
|
if (options.check_self_contained_and_connected)
|
||||||
argv[argc++] = "--check-self-contained-and-connected";
|
argv[argc++] = "--check-self-contained-and-connected";
|
||||||
|
if (options.cloning)
|
||||||
|
argv[argc++] = "--cloning";
|
||||||
|
if (options.update_shallow)
|
||||||
|
argv[argc++] = "--update-shallow";
|
||||||
if (!options.progress)
|
if (!options.progress)
|
||||||
argv[argc++] = "--no-progress";
|
argv[argc++] = "--no-progress";
|
||||||
if (options.depth) {
|
if (options.depth) {
|
||||||
|
@ -173,4 +173,31 @@ EOF
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
|
||||||
|
say 'skipping remaining tests, git built without http support'
|
||||||
|
test_done
|
||||||
|
fi
|
||||||
|
|
||||||
|
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5536'}
|
||||||
|
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||||
|
start_httpd
|
||||||
|
|
||||||
|
test_expect_success 'clone http repository' '
|
||||||
|
git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||||
|
git clone $HTTPD_URL/smart/repo.git clone &&
|
||||||
|
(
|
||||||
|
cd clone &&
|
||||||
|
git fsck &&
|
||||||
|
git log --format=%s origin/master >actual &&
|
||||||
|
cat <<EOF >expect &&
|
||||||
|
6
|
||||||
|
5
|
||||||
|
4
|
||||||
|
3
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
stop_httpd
|
||||||
test_done
|
test_done
|
||||||
|
@ -360,6 +360,12 @@ static int fetch_with_fetch(struct transport *transport,
|
|||||||
data->transport_options.check_self_contained_and_connected)
|
data->transport_options.check_self_contained_and_connected)
|
||||||
set_helper_option(transport, "check-connectivity", "true");
|
set_helper_option(transport, "check-connectivity", "true");
|
||||||
|
|
||||||
|
if (transport->cloning)
|
||||||
|
set_helper_option(transport, "cloning", "true");
|
||||||
|
|
||||||
|
if (data->transport_options.update_shallow)
|
||||||
|
set_helper_option(transport, "update-shallow", "true");
|
||||||
|
|
||||||
for (i = 0; i < nr_heads; i++) {
|
for (i = 0; i < nr_heads; i++) {
|
||||||
const struct ref *posn = to_fetch[i];
|
const struct ref *posn = to_fetch[i];
|
||||||
if (posn->status & REF_STATUS_UPTODATE)
|
if (posn->status & REF_STATUS_UPTODATE)
|
||||||
|
@ -836,8 +836,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (!enter_repo(dir, strict))
|
if (!enter_repo(dir, strict))
|
||||||
die("'%s' does not appear to be a git repository", dir);
|
die("'%s' does not appear to be a git repository", dir);
|
||||||
if (is_repository_shallow() && stateless_rpc)
|
|
||||||
die("attempt to push into a shallow repository");
|
|
||||||
|
|
||||||
git_config(upload_pack_config, NULL);
|
git_config(upload_pack_config, NULL);
|
||||||
upload_pack();
|
upload_pack();
|
||||||
|
Loading…
Reference in New Issue
Block a user