Skip to content

Commit 1609488

Browse files
pcloudsgitster
authored andcommitted
smart-http: support shallow fetch/clone
Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 58f2ed0 commit 1609488

File tree

6 files changed

+81
-9
lines changed

6 files changed

+81
-9
lines changed

Documentation/gitremote-helpers.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,13 @@ set by Git if the remote helper has the 'option' capability.
437437
'option check-connectivity' \{'true'|'false'\}::
438438
Request the helper to check connectivity of a clone.
439439

440+
'option cloning \{'true'|'false'\}::
441+
Notify the helper this is a clone request (i.e. the current
442+
repository is guaranteed empty).
443+
444+
'option update-shallow \{'true'|'false'\}::
445+
Allow to extend .git/shallow if the new refs require it.
446+
440447
SEE ALSO
441448
--------
442449
linkgit:git-remote[1]

builtin/fetch-pack.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "fetch-pack.h"
44
#include "remote.h"
55
#include "connect.h"
6+
#include "sha1-array.h"
67

78
static const char fetch_pack_usage[] =
89
"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)
4647
char **pack_lockfile_ptr = NULL;
4748
struct child_process *conn;
4849
struct fetch_pack_args args;
50+
struct sha1_array shallow = SHA1_ARRAY_INIT;
4951

5052
packet_trace_identity("fetch-pack");
5153

@@ -113,6 +115,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
113115
args.check_self_contained_and_connected = 1;
114116
continue;
115117
}
118+
if (!strcmp("--cloning", arg)) {
119+
args.cloning = 1;
120+
continue;
121+
}
122+
if (!strcmp("--update-shallow", arg)) {
123+
args.update_shallow = 1;
124+
continue;
125+
}
116126
usage(fetch_pack_usage);
117127
}
118128

@@ -157,10 +167,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
157167
args.verbose ? CONNECT_VERBOSE : 0);
158168
}
159169

160-
get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, NULL);
170+
get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow);
161171

162-
ref = fetch_pack(&args, fd, conn, ref, dest,
163-
sought, nr_sought, NULL, pack_lockfile_ptr);
172+
ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
173+
&shallow, pack_lockfile_ptr);
164174
if (pack_lockfile) {
165175
printf("lock %s\n", pack_lockfile);
166176
fflush(stdout);

remote-curl.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "sideband.h"
1111
#include "argv-array.h"
1212
#include "credential.h"
13+
#include "sha1-array.h"
1314

1415
static struct remote *remote;
1516
/* always ends with a trailing slash */
@@ -20,6 +21,8 @@ struct options {
2021
unsigned long depth;
2122
unsigned progress : 1,
2223
check_self_contained_and_connected : 1,
24+
cloning : 1,
25+
update_shallow : 1,
2326
followtags : 1,
2427
dry_run : 1,
2528
thin : 1;
@@ -87,8 +90,23 @@ static int set_option(const char *name, const char *value)
8790
string_list_append(&cas_options, val.buf);
8891
strbuf_release(&val);
8992
return 0;
90-
}
91-
else {
93+
} else if (!strcmp(name, "cloning")) {
94+
if (!strcmp(value, "true"))
95+
options.cloning = 1;
96+
else if (!strcmp(value, "false"))
97+
options.cloning = 0;
98+
else
99+
return -1;
100+
return 0;
101+
} else if (!strcmp(name, "update-shallow")) {
102+
if (!strcmp(value, "true"))
103+
options.update_shallow = 1;
104+
else if (!strcmp(value, "false"))
105+
options.update_shallow = 0;
106+
else
107+
return -1;
108+
return 0;
109+
} else {
92110
return 1 /* unsupported */;
93111
}
94112
}
@@ -99,6 +117,7 @@ struct discovery {
99117
char *buf;
100118
size_t len;
101119
struct ref *refs;
120+
struct sha1_array shallow;
102121
unsigned proto_git : 1;
103122
};
104123
static struct discovery *last_discovery;
@@ -107,7 +126,7 @@ static struct ref *parse_git_refs(struct discovery *heads, int for_push)
107126
{
108127
struct ref *list = NULL;
109128
get_remote_heads(-1, heads->buf, heads->len, &list,
110-
for_push ? REF_NORMAL : 0, NULL, NULL);
129+
for_push ? REF_NORMAL : 0, NULL, &heads->shallow);
111130
return list;
112131
}
113132

@@ -168,6 +187,7 @@ static void free_discovery(struct discovery *d)
168187
if (d) {
169188
if (d == last_discovery)
170189
last_discovery = NULL;
190+
free(d->shallow.sha1);
171191
free(d->buf_alloc);
172192
free_refs(d->refs);
173193
free(d);
@@ -688,7 +708,7 @@ static int fetch_git(struct discovery *heads,
688708
struct strbuf preamble = STRBUF_INIT;
689709
char *depth_arg = NULL;
690710
int argc = 0, i, err;
691-
const char *argv[16];
711+
const char *argv[17];
692712

693713
argv[argc++] = "fetch-pack";
694714
argv[argc++] = "--stateless-rpc";
@@ -704,6 +724,10 @@ static int fetch_git(struct discovery *heads,
704724
}
705725
if (options.check_self_contained_and_connected)
706726
argv[argc++] = "--check-self-contained-and-connected";
727+
if (options.cloning)
728+
argv[argc++] = "--cloning";
729+
if (options.update_shallow)
730+
argv[argc++] = "--update-shallow";
707731
if (!options.progress)
708732
argv[argc++] = "--no-progress";
709733
if (options.depth) {

t/t5537-fetch-shallow.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,31 @@ EOF
173173
)
174174
'
175175

176+
if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
177+
say 'skipping remaining tests, git built without http support'
178+
test_done
179+
fi
180+
181+
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5536'}
182+
. "$TEST_DIRECTORY"/lib-httpd.sh
183+
start_httpd
184+
185+
test_expect_success 'clone http repository' '
186+
git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
187+
git clone $HTTPD_URL/smart/repo.git clone &&
188+
(
189+
cd clone &&
190+
git fsck &&
191+
git log --format=%s origin/master >actual &&
192+
cat <<EOF >expect &&
193+
6
194+
5
195+
4
196+
3
197+
EOF
198+
test_cmp expect actual
199+
)
200+
'
201+
202+
stop_httpd
176203
test_done

transport-helper.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,12 @@ static int fetch_with_fetch(struct transport *transport,
360360
data->transport_options.check_self_contained_and_connected)
361361
set_helper_option(transport, "check-connectivity", "true");
362362

363+
if (transport->cloning)
364+
set_helper_option(transport, "cloning", "true");
365+
366+
if (data->transport_options.update_shallow)
367+
set_helper_option(transport, "update-shallow", "true");
368+
363369
for (i = 0; i < nr_heads; i++) {
364370
const struct ref *posn = to_fetch[i];
365371
if (posn->status & REF_STATUS_UPTODATE)

upload-pack.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,8 +836,6 @@ int main(int argc, char **argv)
836836

837837
if (!enter_repo(dir, strict))
838838
die("'%s' does not appear to be a git repository", dir);
839-
if (is_repository_shallow() && stateless_rpc)
840-
die("attempt to push into a shallow repository");
841839

842840
git_config(upload_pack_config, NULL);
843841
upload_pack();

0 commit comments

Comments
 (0)