Skip to content

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

Merged
merged 81 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
0668384
repo: basic graft API
tiennou Aug 2, 2018
919501a
repo: load grafts on open
tiennou Aug 2, 2018
3c17f22
repo: load shallow roots
tiennou Oct 10, 2019
a8b1d51
repo: graft shallow roots on open
tiennou Aug 2, 2018
a35cc40
commit: apply grafts when parsing
tiennou Aug 2, 2018
d54c008
tests: graft commits
tiennou Aug 2, 2018
22f201b
grafts: make the structure self-contained and opaque
pks-t Oct 3, 2019
14a309a
repository: convert grafts parsing to use parse context
pks-t Oct 3, 2019
05e286f
grafts: move parsing into grafts module
pks-t May 12, 2020
a11026e
repository: reuse grafts for shallow roots
pks-t Oct 24, 2019
70867f7
repository: disentangle shallow and normal grafts
pks-t Oct 3, 2019
fd2398b
grafts: move refresh logic into grafts code
pks-t Oct 3, 2019
a4803c3
grafts: fix memory leak if replacing pre-existing graft
pks-t Oct 10, 2019
79af067
repository: do not expose grafting mechanism
pks-t Oct 24, 2019
e07aa9c
Merge branch 'main' into pr/pks-t/5254
lya001 Jun 24, 2022
13bd14d
add feature flag for shallow clone support
Jun 27, 2022
7a93625
add test for shallow feature flag
Jun 27, 2022
89494f6
add shallow.h
Jun 27, 2022
562246b
move declaration of feature flag to graft.h/graft.c
Jun 27, 2022
6bab22f
move feature flag tests to tests/grafts/shallow.c
Jun 27, 2022
ad56355
use shallow feature flag in shallow clone support source code
Jun 27, 2022
c4cd9a5
correct naming of feature flag
Jun 27, 2022
5918975
disable shallow clone support by default
Jun 28, 2022
397753f
enable shallow clone support in tests when necessary
Jun 28, 2022
9d1507d
correct use of feature flag
Jun 28, 2022
06eacb9
fix graft assertion
Jun 28, 2022
70a332a
disable shallow clone feature flag in test cleanup
Jun 28, 2022
afa79ca
Merge branch 'pr/tiennou/4747' into transportPR
Jul 4, 2022
10e2573
attempt to build
Jul 5, 2022
3e64f15
rewrite shallow_root
Jul 7, 2022
c652f3d
enable cloning of shallow repo
Jul 19, 2022
f19ffc8
add test for shallow repo depth 1
Jul 19, 2022
7f46bfa
unset GIT_RAND_GETENTROPY to avoid linux GLIBC issues (#3)
lya001 Jul 26, 2022
52ba17f
Merge branch 'pr/pks-t/5254' into shallow-clone-local
Jul 26, 2022
83f71b1
fix build errors
Jul 26, 2022
cfc2ae6
eliminate build warnings
Jul 27, 2022
c01b784
improve error handling
Jul 28, 2022
14d2a60
fix load_grafts
Jul 28, 2022
62cc77a
refactor commit parent assignment with graft
Jul 28, 2022
a544a91
rename function assign_parents_from_graft
Jul 28, 2022
3d7a609
Merge pull request #4 from lya001/shallow-clone-local
lya001 Jul 29, 2022
09acf69
Merge branch 'mw_dev' into shallow-clone-local
lya001 Jul 29, 2022
a491917
Merge pull request #5 from mathworks/shallow-clone-local
lya001 Jul 29, 2022
68bbcef
Merge branch 'transportPR' into shallow-clone-network
Jul 29, 2022
73d25f0
remove build errors
Jul 29, 2022
598ec30
eliminate build warnings
Jul 29, 2022
179aac7
fix clone::shallow test behaviour
Jul 29, 2022
e7294e8
fix memory leaks about packets
Aug 1, 2022
2d33fe7
refactor git_fetch_option.depth and usage
Aug 2, 2022
4536477
fix memory leak
Aug 2, 2022
e93d081
attempt to fix nego.shallowarray memory leak
Aug 2, 2022
da04d3f
fix grafts and shallowarray memory leaks
Aug 2, 2022
8ef492f
fix build warning
Aug 2, 2022
829555a
edit tests for shallow clones
Aug 2, 2022
09b3d33
fix memory leak
Aug 9, 2022
df5eb32
support fetch unshallow option on shallow repos
Aug 9, 2022
49e641b
remove unused api
Aug 11, 2022
8b521f0
document unshallow behaviour in fetch.c
Aug 11, 2022
7c2b1f4
Merge pull request #6 from lya001/shallow-clone-network
lya001 Aug 11, 2022
a3bfd28
Use GIT_OID_SHA1_HEXSIZE
lya001 Aug 31, 2022
01cb90b
restore GIT_RAND_GETENTROPY
lya001 Aug 31, 2022
b20f013
restore getentropy
lya001 Aug 31, 2022
f1f9b45
fix test failures
lya001 Aug 31, 2022
6c46b58
include oid.h in grafts.c
lya001 Aug 31, 2022
4cf19ad
refactor smart_pkt
lya001 Aug 31, 2022
d0eba8a
fix shallowarray test
lya001 Aug 31, 2022
89c1b01
fix free error
lya001 Aug 31, 2022
34de5c8
fix seg faults
lya001 Sep 5, 2022
7122fcd
fix depth initialisation
lya001 Sep 5, 2022
47f36a9
fix error handling
lya001 Sep 5, 2022
d23a790
remove unused statements
lya001 Sep 5, 2022
4f2f91a
fix shallow array search
lya001 Sep 6, 2022
a9793ac
refactor grafts tests
lya001 Sep 6, 2022
570ef74
Merge commit 'd066d0d95c43e97df6624292f3f527f9372ca8fe'
lrm29 Mar 10, 2023
1cc2979
Fix merge error
lrm29 Mar 10, 2023
2da3e8c
Remove stray comma
lrm29 Mar 10, 2023
d935773
Remove unused git_transport_flags_t
lrm29 Mar 10, 2023
79ed94e
Apply suggestions from code review
lrm29 Mar 10, 2023
e3bf6db
Merge branch 'shallow-clone-network' of https://github.com/mathworks/…
lrm29 Mar 10, 2023
5b71133
Update src/libgit2/fetch.c
lrm29 Mar 10, 2023
e288f87
Remove unnecessary include.
lrm29 Mar 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/git2/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ typedef enum {
GIT_OPT_GET_OWNER_VALIDATION,
GIT_OPT_SET_OWNER_VALIDATION,
GIT_OPT_GET_HOMEDIR,
GIT_OPT_SET_HOMEDIR
GIT_OPT_SET_HOMEDIR,
GIT_OPT_ENABLE_SHALLOW
} git_libgit2_opt_t;

/**
Expand Down Expand Up @@ -461,6 +462,9 @@ typedef enum {
* > { "!noop", "newext" } indicates that the caller does not want
* > to support repositories with the `noop` extension but does want
* > to support repositories with the `newext` extension.
*
* opts(GIT_OPT_ENABLE_SHALLOW, int enabled)
* > Enable or disable shallow clone support completely.
*
* opts(GIT_OPT_GET_OWNER_VALIDATION, int *enabled)
* > Gets the owner validation setting for repository
Expand Down
3 changes: 2 additions & 1 deletion include/git2/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ typedef enum {
GIT_ERROR_WORKTREE,
GIT_ERROR_SHA,
GIT_ERROR_HTTP,
GIT_ERROR_INTERNAL
GIT_ERROR_INTERNAL,
GIT_ERROR_GRAFTS
} git_error_t;

/**
Expand Down
16 changes: 15 additions & 1 deletion include/git2/remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Member

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 to 0. We shouldn't have multiple values (0 and all negative values) that mean the same thing, let's just make 0 mean complete history and disallow negative values. We may want to use them for something meaningful in the future.


/**
* Convert a shallow repository to a full repository.
*
* The default is 0, which means the flag is off.
*/
int unshallow;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need depth and unshallow? It looks like unshallow just implies a large depth. 🙁


/**
* Whether to allow off-site redirects. If this is not
* specified, the `http.followRedirects` configuration setting
Expand All @@ -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
Expand Down
17 changes: 15 additions & 2 deletions include/git2/sys/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The 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
4 changes: 3 additions & 1 deletion src/libgit2/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The 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;
Expand Down
43 changes: 34 additions & 9 deletions src/libgit2/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "object.h"
#include "array.h"
#include "oidarray.h"
#include "grafts.h"

void git_commit__free(void *_commit)
{
Expand Down Expand Up @@ -427,10 +428,6 @@ static int commit_parse(
buffer += tree_len;
}

/*
* TODO: commit grafts!
*/

while (git_object__parse_oid_header(&parent_id,
&buffer, buffer_end, "parent ",
opts->oid_type) == 0) {
Expand Down Expand Up @@ -532,16 +529,44 @@ int git_commit__parse_raw(
return commit_parse(commit, data, size, &parse_options);
}

static int assign_commit_parents_from_graft(git_commit *commit, git_commit_graft *graft) {
size_t idx;
git_oid *oid;

git_array_clear(commit->parent_ids);
git_array_init_to_size(commit->parent_ids, git_array_size(graft->parents));
git_array_foreach(graft->parents, idx, oid) {
git_oid *id = git_array_alloc(commit->parent_ids);
GIT_ERROR_CHECK_ALLOC(id);

git_oid_cpy(id, oid);
}

return 0;
}

int git_commit__parse_ext(
git_commit *commit,
git_odb_object *odb_obj,
git_commit__parse_options *parse_opts)
{
return commit_parse(
commit,
git_odb_object_data(odb_obj),
git_odb_object_size(odb_obj),
parse_opts);
git_repository *repo = git_object_owner((git_object *)commit);
git_commit_graft *graft;
int error;

if ((error = commit_parse(commit, git_odb_object_data(odb_obj),
git_odb_object_size(odb_obj), parse_opts)) < 0)
return error;

if (!git_shallow__enabled)
return 0;

/* Perform necessary grafts */
if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) != 0 &&
git_grafts_get(&graft, repo->shallow_grafts, git_odb_object_id(odb_obj)) != 0)
return 0;

return assign_commit_parents_from_graft(commit, graft);
}

#define GIT_COMMIT_GETTER(_rvalue, _name, _return, _invalid) \
Expand Down
37 changes: 32 additions & 5 deletions src/libgit2/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default shouldn't be -1, it should be 0.

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");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--depth and --unshallow are command line options for git. libgit2 users should not be given error messages as if they were using git. They're not.

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);
Copy link
Member

Choose a reason for hiding this comment

The 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)
Expand Down
Loading