-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Shallow Clone Support #6396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shallow Clone Support #6396
Changes from all commits
0668384
919501a
3c17f22
a8b1d51
a35cc40
d54c008
22f201b
14a309a
05e286f
a11026e
70867f7
fd2398b
a4803c3
79af067
e07aa9c
13bd14d
7a93625
89494f6
562246b
6bab22f
ad56355
c4cd9a5
5918975
397753f
9d1507d
06eacb9
70a332a
afa79ca
10e2573
3e64f15
c652f3d
f19ffc8
7f46bfa
52ba17f
83f71b1
cfc2ae6
c01b784
14d2a60
62cc77a
a544a91
3d7a609
09acf69
a491917
68bbcef
73d25f0
598ec30
179aac7
e7294e8
2d33fe7
4536477
e93d081
da04d3f
8ef492f
829555a
09b3d33
df5eb32
49e641b
8b521f0
7c2b1f4
a3bfd28
01cb90b
b20f013
f1f9b45
6c46b58
4cf19ad
d0eba8a
89c1b01
34de5c8
7122fcd
47f36a9
d23a790
4f2f91a
a9793ac
570ef74
1cc2979
2da3e8c
d935773
79ed94e
e3bf6db
5b71133
e288f87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -743,6 +743,20 @@ typedef struct { | |
*/ | ||
git_proxy_options proxy_opts; | ||
|
||
/** | ||
* Depth of the fetch to perform. Depth <= 0 fetches the full history. | ||
* | ||
* The default is -1. | ||
*/ | ||
int depth; | ||
|
||
/** | ||
* Convert a shallow repository to a full repository. | ||
* | ||
* The default is 0, which means the flag is off. | ||
*/ | ||
int unshallow; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need |
||
|
||
/** | ||
* Whether to allow off-site redirects. If this is not | ||
* specified, the `http.followRedirects` configuration setting | ||
|
@@ -758,7 +772,7 @@ typedef struct { | |
|
||
#define GIT_FETCH_OPTIONS_VERSION 1 | ||
#define GIT_FETCH_OPTIONS_INIT { GIT_FETCH_OPTIONS_VERSION, GIT_REMOTE_CALLBACKS_INIT, GIT_FETCH_PRUNE_UNSPECIFIED, 1, \ | ||
GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED, GIT_PROXY_OPTIONS_INIT } | ||
GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED, GIT_PROXY_OPTIONS_INIT, -1, 0 } | ||
|
||
/** | ||
* Initialize git_fetch_options structure | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,15 @@ | |
|
||
GIT_BEGIN_DECL | ||
|
||
typedef struct git_shallowarray git_shallowarray; | ||
|
||
typedef struct { | ||
const git_remote_head * const *refs; | ||
size_t count; | ||
git_shallowarray *shallow_roots; | ||
int depth; | ||
} git_fetch_negotiation; | ||
|
||
struct git_transport { | ||
unsigned int version; /**< The struct version */ | ||
|
||
|
@@ -96,8 +105,7 @@ struct git_transport { | |
int GIT_CALLBACK(negotiate_fetch)( | ||
git_transport *transport, | ||
git_repository *repo, | ||
const git_remote_head * const *refs, | ||
size_t count); | ||
const git_fetch_negotiation *fetch_data); | ||
|
||
/** | ||
* Start downloading the packfile from the remote repository. | ||
|
@@ -442,6 +450,11 @@ GIT_EXTERN(int) git_smart_subtransport_ssh( | |
git_transport *owner, | ||
void *param); | ||
|
||
GIT_EXTERN(size_t) git_shallowarray_count(git_shallowarray *array); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be in transport.h? Does this really need to be public at all? |
||
GIT_EXTERN(const git_oid *) git_shallowarray_get(git_shallowarray *array, size_t idx); | ||
GIT_EXTERN(int) git_shallowarray_add(git_shallowarray *array, git_oid *oid); | ||
GIT_EXTERN(int) git_shallowarray_remove(git_shallowarray *array, git_oid *oid); | ||
|
||
/** @} */ | ||
GIT_END_DECL | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -420,7 +420,9 @@ static int clone_into( | |
|
||
memcpy(&fetch_opts, opts, sizeof(git_fetch_options)); | ||
fetch_opts.update_fetchhead = 0; | ||
fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; | ||
|
||
if (opts->depth <= 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't allow negative values, we should error on them. |
||
fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; | ||
|
||
if ((error = git_remote_connect_options__from_fetch_opts(&connect_opts, remote, &fetch_opts)) < 0) | ||
goto cleanup; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
#include "netops.h" | ||
#include "repository.h" | ||
#include "refs.h" | ||
#include "transports/smart.h" | ||
|
||
static int maybe_want(git_remote *remote, git_remote_head *head, git_refspec *tagspec, git_remote_autotag_option_t tagopt) | ||
{ | ||
|
@@ -59,8 +60,10 @@ static int mark_local(git_remote *remote) | |
return -1; | ||
|
||
git_vector_foreach(&remote->refs, i, head) { | ||
/* If we have the object, mark it so we don't ask for it */ | ||
if (git_odb_exists(odb, &head->oid)) | ||
/* If we have the object, mark it so we don't ask for it. | ||
However if we are unshallowing, we need to ask for it | ||
even though the head exists locally. */ | ||
if (remote->nego.depth != INT_MAX && git_odb_exists(odb, &head->oid)) | ||
head->local = 1; | ||
else | ||
remote->need_pack = 1; | ||
|
@@ -169,31 +172,55 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) | |
|
||
remote->need_pack = 0; | ||
|
||
if (!opts) | ||
remote->nego.depth = -1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The default shouldn't be |
||
else | ||
remote->nego.depth = opts->unshallow ? INT_MAX : opts->depth; | ||
|
||
if (filter_wants(remote, opts) < 0) | ||
return -1; | ||
|
||
/* Don't try to negotiate when we don't want anything */ | ||
if (!remote->need_pack) | ||
return 0; | ||
|
||
if (opts && opts->unshallow && opts->depth > 0) { | ||
git_error_set(GIT_ERROR_INVALID, "options '--depth' and '--unshallow' cannot be used together"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return -1; | ||
} | ||
|
||
/* | ||
* Now we have everything set up so we can start tell the | ||
* server what we want and what we have. | ||
*/ | ||
remote->nego.refs = (const git_remote_head * const *)remote->refs.contents; | ||
remote->nego.count = remote->refs.length; | ||
remote->nego.shallow_roots = git__malloc(sizeof(*remote->nego.shallow_roots)); | ||
|
||
git_array_init(remote->nego.shallow_roots->array); | ||
|
||
git_repository__shallow_roots(&remote->nego.shallow_roots->array, remote->repo); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm |
||
|
||
return t->negotiate_fetch(t, | ||
remote->repo, | ||
(const git_remote_head * const *)remote->refs.contents, | ||
remote->refs.length); | ||
&remote->nego); | ||
} | ||
|
||
int git_fetch_download_pack(git_remote *remote) | ||
{ | ||
git_transport *t = remote->transport; | ||
int error; | ||
|
||
if (!remote->need_pack) | ||
return 0; | ||
|
||
return t->download_pack(t, remote->repo, &remote->stats); | ||
if ((error = t->download_pack(t, remote->repo, &remote->stats)) != 0) | ||
return error; | ||
|
||
if ((error = git_repository__shallow_roots_write(remote->repo, remote->nego.shallow_roots->array)) != 0) | ||
return error; | ||
|
||
return 0; | ||
} | ||
|
||
int git_fetch_options_init(git_fetch_options *opts, unsigned int version) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't default to
-1
, it should default to0
. We shouldn't have multiple values (0
and all negative values) that mean the same thing, let's just make0
mean complete history and disallow negative values. We may want to use them for something meaningful in the future.