From: Teng Long <hidden> Date: 2021-05-07 02:11:51
On the server, more sophisticated means of excluding objects should be
supported, such as commit object. This commit introduces a new
configuration `uploadpack.commitpackfileuri` for this.
This patch only pack the commit object, not including the that commit
and all objects that it references. This work will be done in a further
patch recently.
Similarly, there are related documents that will be included in
subsequent patches.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 8 ++---
fetch-pack.c | 8 +++++
t/t5702-protocol-v2.sh | 71 +++++++++++++++++++++++++++++++++---------
upload-pack.c | 7 +++--
4 files changed, 73 insertions(+), 21 deletions(-)
@@ -2998,11 +2998,11 @@ static int git_pack_config(const char *k, const char *v, void *cb)*oid_end!=' '||parse_oid_hex(oid_end+1,&pack_hash,&pack_end)||*pack_end!=' ')-die(_("value of uploadpack.blobpackfileuri must be "-"of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);+die(_("value of uploadpack.blobpackfileuri or upload.commitpackfileuri must be "+"of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);if(oidmap_get(&configured_exclusions,&ex->e.oid))die(_("object already configured in another "-"uploadpack.blobpackfileuri (got '%s')"),v);+"uploadpack.blobpackfileuri or uploadpack.commitpackfileuri (got '%s')"),v);ex->pack_hash_hex=xcalloc(1,pack_end-oid_end);memcpy(ex->pack_hash_hex,oid_end+1,pack_end-oid_end-1);ex->uri=xstrdup(pack_end+1);
@@ -824,12 +824,22 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '' configure_exclusion(){-git-C"$1"hash-object"$2">objh&&-git-C"$1"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&-git-C"$1"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-catobjh+iftest"$1"="blob"+then+git-C"$2"hash-object"$3">objh&&+git-C"$2"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&+git-C"$2"config--add\+"uploadpack.blobpackfileuri"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+else+echo"$3">objh&&+git-C"$2"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&+git-C"$2"config--add\+"uploadpack.commitpackfileuri"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+fi} test_expect_success'part of packfile response provided as URI''
@@ -845,8 +855,8 @@ test_expect_success 'part of packfile response provided as URI' 'git-C"$P"addother-blob&&git-C"$P"commit-mx&&-configure_exclusion"$P"my-blob>h&&-configure_exclusion"$P"other-blob>h2&&+configure_exclusionblob"$P"my-blob>h&&+configure_exclusionblob"$P"other-blob>h2&&GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\
@@ -881,7 +891,7 @@ test_expect_success 'part of packfile response provided as URI' 'test_line_count=6filelist'-test_expect_success'packfile URIs with fetch instead of clone''+test_expect_success'blobs packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&rm-rf"$P"http_childlog&&
@@ -892,7 +902,7 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'git-C"$P"addmy-blob&&git-C"$P"commit-mx&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&gitinithttp_child&&
@@ -902,6 +912,37 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'fetch"$HTTPD_URL/smart/http_parent"'+test_expect_success'commits packfile URIs with fetch instead of clone''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+rm-rf"$P"http_childlog&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+git-C"$P"commit-mx&&+++mycommit=$(git-C"$P"rev-parseHEAD)&&+echoother-blob>"$P/other-blob"&&+git-C"$P"addother-blob&&+git-C"$P"commit-mx&&+othercommit=$(git-C"$P"rev-parseHEAD)&&+configure_exclusioncommit"$P""$mycommit">h&&+configure_exclusioncommit"$P""$othercommit">h2&&++gitinithttp_child&&++GIT_TRACE=1GIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch"$HTTPD_URL/smart/http_parent"&&+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=6filelist+'+ test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&rm-rf"$P"http_childlog&&
@@ -915,7 +956,7 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"addother-blob&&git-C"$P"commit-mx&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&# Configure a URL for other-blob. Just reuse the hash of the object as# the hash of the packfile, since the hash does not matter for this# test as long as it is not the hash of the pack, and it is of the
@@ -944,7 +985,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' 'git-C"$P"addmy-blob&&git-C"$P"commit-mx&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -978,7 +1019,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object'git-C"$P"addmy-blob&&git-C"$P"commit-mx&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1000,7 +1041,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmogit-C"$P"add.gitmodules&&git-C"$P"commit-mx&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1026,7 +1067,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodulgit-C"$P"add.gitmodules&&git-C"$P"commit-mx&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
On the server, more sophisticated means of excluding objects should be
supported, such as commit object. This commit introduces a new
configuration `uploadpack.commitpackfileuri` for this.
Per my understanding in
https://lore.kernel.org/git/87o8hk820f.fsf@evledraar.gmail.com/ this +
Jonathan's earlier bfc2a36ff2a (Doc: clarify contents of packfile sent
as URI, 2021-01-20) still makes this whole thing more confusing that it
needs to be.
I think we should just have a new uploadpack.excludeObject, and document
that uploadpack.blobpackfileuri is an (unfortunately named) synonym for
it. I.e. the actual implementation doesn't care about the objec type it
just excludes any object listed via an oidmap. No?
As for some comments on the implementation:
This patch only pack the commit object, not including the that commit
and all objects that it references. This work will be done in a further
patch recently.
I realize you're probably not a native English speaker (neither am I),
but I honestly can't understand that "This work will be done in a
further patch recently.". Do you mean something like:
This change does not add support for recursively excluding things
referenced by container objects such as "commit", "tag", and
"tree". We'll still just dumbly exclude that specific object (this
was originally meant for specific "blobs"). Smartly excluding things
recursively might be implemented by a future change.
Similarly, there are related documents that will be included in
subsequent patches.
Please send the earlier doc cleanup + the spec change for this + any doc
updates as one series.
Narrow comments on the patch:
@@ -2998,11 +2998,11 @@ static int git_pack_config(const char *k, const char *v, void *cb) *oid_end != ' ' || parse_oid_hex(oid_end + 1, &pack_hash, &pack_end) || *pack_end != ' ')- die(_("value of uploadpack.blobpackfileuri must be "- "of the form '<object-hash> <pack-hash> <uri>' (got '%s')"), v);+ die(_("value of uploadpack.blobpackfileuri or upload.commitpackfileuri must be "+ "of the form '<object-hash> <pack-hash> <uri>' (got '%s')"), v);
Indending with spaces.
if (oidmap_get(&configured_exclusions, &ex->e.oid))
die(_("object already configured in another "
- "uploadpack.blobpackfileuri (got '%s')"), v);
+ "uploadpack.blobpackfileuri or uploadpack.commitpackfileuri (got '%s')"), v);
I think by having a uploadpack.excludeObject documented as the primary
interface to this we could just say "object already listed by an earlier
exclusion" or something like that.
@@ -824,12 +824,22 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '' configure_exclusion(){-git-C"$1"hash-object"$2">objh&&-git-C"$1"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&-git-C"$1"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-catobjh+iftest"$1"="blob"+then
This whole if/else seems like it could be better split up by discovering
the variable first, using that as a variable, and then avoiding the
duplication. But if we just used uploadpack.excludeObject...
quoted hunk
+ fi
}
test_expect_success 'part of packfile response provided as URI' '
Personally I'd just skip this whole "rev-parse HEAD" etc. and just pass
the tag name(s) created by earlier test_commit, then have
configure_exclusion ust always do a rev-parse...
@@ -915,7 +956,7 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' git -C "$P" add other-blob && git -C "$P" commit -m x &&- configure_exclusion "$P" my-blob >h &&+ configure_exclusion blob "$P" my-blob >h && # Configure a URL for other-blob. Just reuse the hash of the object as # the hash of the packfile, since the hash does not matter for this # test as long as it is not the hash of the pack, and it is of the
@@ -1744,9 +1744,12 @@ int upload_pack_advertise(struct repository *r,allow_sideband_all_value))strbuf_addstr(value," sideband-all");-if(!repo_config_get_string(the_repository,+if((!repo_config_get_string(the_repository,"uploadpack.blobpackfileuri",-&str)&&+&str)||+!repo_config_get_string(the_repository,+"uploadpack.commitpackfileuri",+&str))&&str){strbuf_addstr(value," packfile-uris");free(str);
Not a new issue, but I wonder if we shouldn't just export
configset_find_element(). This is at least 2 stackframes down the chain
of the "does this key exist?" we actually care about here.
From: Teng Long <hidden> Date: 2021-05-18 08:50:25
Changes since v2:
* Rename the "uploadpack.blobpackfileuri" configuration to
"uploadpack.excludeobject".
* In addition to blobs, packfile-uris now supports the exclusion of
commit objects (recursive and non-recursive).
* Added a patch to modify the packfile-uris.txt file.
* Added a patch for related tests in t5702.
About renaming, I do not know whether it will bring some compatibility
impact, packfile-uris now is an experimental feature, how to deal
with this situation, hoping to get some advice.
Also, I did not consider implementing packfile-uri support for tree
objects, because in the design scenario of packfile-uris, it seems to
be of little use.
Teng Long (3):
packfile-uris: support for excluding commit object
packfile-uris.txt: excluding commit object
t5702: excluding commits with packfile-uris
Documentation/technical/packfile-uri.txt | 20 ++--
builtin/pack-objects.c | 53 ++++++---
fetch-pack.c | 5 +
t/t5702-protocol-v2.sh | 145 +++++++++++++++++------
upload-pack.c | 5 +-
5 files changed, 166 insertions(+), 62 deletions(-)
Range-diff against v1:
1: 1f2fb5c85f < -: ---------- Packfile-uris support excluding commit objects
-: ---------- > 1: 73e64147b1 packfile-uris: support for excluding commit object
-: ---------- > 2: 4abab98a76 packfile-uris.txt: excluding commit object
-: ---------- > 3: e824cc26a7 t5702: excluding commits with packfile-uris
--
2.31.1.442.g7e39198978.dirty
From: Teng Long <hidden> Date: 2021-05-18 08:50:34
On the server, more sophisticated means of excluding objects should be
supported, such as commit object. This commit introduces a new
configuration `uploadpack.excludeobject` for this.
The old configuration `uploadpack.blobpackfileuri` is only support to
exclude blobs and the name has no abstract meaning, so the configruation
name changes, to support more object types. Compatibility issues will
not be considered because packfile-uris now is an experimental feature.
In addition to the configuration name, the format of the configuration
value has also been expanded. When excluding the commits (or trees in
the future) objects, the old format `<object-hash> <pack-hash> <uri>`
can not express the meaning of recursion. So, the format is expanded,
the new format `<object-hash> <recursively> <pack-hash> <uri>` should
deal with this scenario (When processing commit objects, whether they
are absolutely recursively excluded).
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 53 ++++++++++++++++++++++++++++++------------
fetch-pack.c | 5 ++++
upload-pack.c | 5 ++--
3 files changed, 45 insertions(+), 18 deletions(-)
@@ -1291,10 +1294,16 @@ static int want_object_in_pack_one(struct packed_git *p,*anditsoffsetinthesevariables.*/staticintwant_object_in_pack(conststructobject_id*oid,+enumobject_typetype,intexclude,structpacked_git**found_pack,off_t*found_offset){+if(exclude_until_next_commit&&type!=OBJ_COMMIT)+return0;+if(type==OBJ_COMMIT)+exclude_until_next_commit=0;+intwant;structlist_head*pos;structmulti_pack_index*m;
@@ -1345,6 +1354,8 @@ static int want_object_in_pack(const struct object_id *oid,&p)&&*p==':'){oidset_insert(&excluded_by_config,oid);+if(ex->recursively&&type==OBJ_COMMIT)+exclude_until_next_commit=1;return0;}}
@@ -1394,7 +1405,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset)){+if(!want_object_in_pack(oid,type,exclude,&found_pack,&found_offset)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -1420,7 +1431,7 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,if(have_duplicate_entry(oid,0))return0;-if(!want_object_in_pack(oid,0,&pack,&offset))+if(!want_object_in_pack(oid,type,0,&pack,&offset))return0;create_object_entry(oid,type,name_hash,0,0,pack,offset);
@@ -2985,27 +2996,33 @@ static int git_pack_config(const char *k, const char *v, void *cb)pack_idx_opts.flags&=~WRITE_REV;return0;}-if(!strcmp(k,"uploadpack.blobpackfileuri")){+if(!strcmp(k,"uploadpack.excludeobject")){structconfigured_exclusion*ex=xmalloc(sizeof(*ex));-constchar*oid_end,*pack_end;+constchar*oid_end,*pack_end,*recursively_end;/**Storesthepackhash.ThisisnotatrueobjectID,butis*ofthesameform.*/structobject_idpack_hash;-+charrecursively[2];if(parse_oid_hex(v,&ex->e.oid,&oid_end)||*oid_end!=' '||-parse_oid_hex(oid_end+1,&pack_hash,&pack_end)||+!strlcpy(recursively,oid_end+1,sizeof(recursively))||+parse_oid_hex(oid_end+3,&pack_hash,&pack_end)||*pack_end!=' ')-die(_("value of uploadpack.blobpackfileuri must be "-"of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);+die(_("value of uploadpack.excludeobject must be "+"of the form '<object-hash> <recursively> <pack-hash> <uri>' (got '%s')"),v);if(oidmap_get(&configured_exclusions,&ex->e.oid))-die(_("object already configured in another "-"uploadpack.blobpackfileuri (got '%s')"),v);-ex->pack_hash_hex=xcalloc(1,pack_end-oid_end);-memcpy(ex->pack_hash_hex,oid_end+1,pack_end-oid_end-1);+die(_("object already configured by an earlier "+"uploadpack.excludeobject (got '%s')"),v);+recursively_end=oid_end+2;+ex->pack_hash_hex=xcalloc(1,pack_end-recursively_end);+memcpy(ex->pack_hash_hex,recursively_end+1,pack_end-recursively_end-1);ex->uri=xstrdup(pack_end+1);+if(atoi(recursively)){+ex->recursively=1;+in_commit_order=1;+}oidmap_put(&configured_exclusions,ex);}returngit_default_config(k,v,cb);
@@ -3023,7 +3040,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,structrev_info*revs=_data;structobject_infooi=OBJECT_INFO_INIT;off_tofs;-enumobject_typetype;+staticenumobject_typetype;display_progress(progress_state,++nr_seen);
@@ -3031,7 +3048,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;ofs=nth_packed_object_offset(p,pos);-if(!want_object_in_pack(oid,0,&p,&ofs))+if(!want_object_in_pack(oid,type,0,&p,&ofs))return0;oi.typep=&type;
@@ -3831,7 +3848,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)N_("respect islands during delta compression")),OPT_STRING_LIST(0,"uri-protocol",&uri_protocols,N_("protocol"),-N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),+N_("exclude any configured uploadpack.excludeobject with this protocol")),OPT_END(),};
From: Teng Long <hidden> Date: 2021-05-18 08:50:38
Modified the content related to the configuration of packfile-uris, that
is, the modification of the configuration format and the support for
excluding commit objects, and cut some descriptions about future work.
Signed-off-by: Teng Long <redacted>
---
Documentation/technical/packfile-uri.txt | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
@@ -35,13 +35,16 @@ include some sort of non-trivial implementation in the Minimum Viable Product, at least so that we can test the client. This is the implementation: a feature, marked experimental, that allows the-server to be configured by one or more `uploadpack.blobPackfileUri=<sha1>-<uri>` entries. Whenever the list of objects to be sent is assembled, all such-blobs are excluded, replaced with URIs. As noted in "Future work" below, the-server can evolve in the future to support excluding other objects (or other-implementations of servers could be made that support excluding other objects)-without needing a protocol change, so clients should not expect that packfiles-downloaded in this way only contain single blobs.+server to be configured by one or more entries with the format:++ uploadpack.excludeobject=<object-hash> <recursively> <pack-hash> <uri>++Value <object-hash> is the key of entry, and the object type can be a blob+or commit. Value <recursively> works for commit object, if <recursively>+is configured as '1', then the commit and all the referenced objects by+the commit will be recursively excluded. Otherwise, only the commit itself+will be excluded. Whenever the list of objects to be sent is assembled, all+such objects are excluded, replaced with URIs. Client design -------------
@@ -65,9 +68,6 @@ The protocol design allows some evolution of the server and client without any need for protocol changes, so only a small-scoped design is included here to form the MVP. For example, the following can be done:- * On the server, more sophisticated means of excluding objects (e.g. by- specifying a commit to represent that commit and all objects that it- references). * On the client, resumption of clone. If a clone is interrupted, information could be recorded in the repository's config and a "clone-resume" command can resume the clone in progress. (Resumption of subsequent fetches is more
From: Teng Long <hidden> Date: 2021-05-18 08:50:41
Modify the logic of configure_exclusion to support the processing of
commits objects and add test cases for excluding commit objects
(recursive and non-recursive).
Replace "rm..." in the original test with "test_when_finished...".
Replace "git commit..." in the original test with "test_commit...".
Signed-off-by: Teng Long <redacted>
---
t/t5702-protocol-v2.sh | 145 +++++++++++++++++++++++++++++++----------
1 file changed, 111 insertions(+), 34 deletions(-)
@@ -753,7 +753,7 @@ test_expect_success 'ls-remote with v2 http sends only one POST' '' test_expect_success'push with http:// and a config of v2 does not request v2''-test_when_finished"rm -f log"&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&# Till v2 for push is designed, make sure that if a client has# protocol.version configured to use v2, that the client instead falls# back and uses v0.
@@ -776,7 +776,7 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '' test_expect_success'when server sends "ready", expect DELIM''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_child&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -796,7 +796,7 @@ test_expect_success 'when server sends "ready", expect DELIM' '' test_expect_success'when server does not send "ready", expect FLUSH''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_childlog&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -824,17 +824,39 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '' configure_exclusion(){-git-C"$1"hash-object"$2">objh&&-git-C"$1"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&-git-C"$1"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-catobjh+objt="$1"+P="$2"+recursive="$4"++iftest"$objt"="blob"+then+git-C"$P"hash-object"$3">objh&&+git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&+git-C"$P"config--add\+"uploadpack.excludeobject"\+"$(catobjh)$recursive$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+eliftest"$objt"="commit"+then+echo"$3">objh+iftest"$recursive"=0+then+git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh+else+git-C"$2"pack-objects--revs"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh+fi+git-C"$P"config--add\+"uploadpack.excludeobject"\+"$(catobjh)$recursive$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+else+echo"unsupported object type in configure_exclusion (got $objt)"+fi} test_expect_success'part of packfile response provided as URI''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -843,10 +865,10 @@ test_expect_success 'part of packfile response provided as URI' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&-configure_exclusion"$P"other-blob>h2&&+configure_exclusionblob"$P"my-blob0>h&&+configure_exclusionblob"$P"other-blob0>h2&&GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\
@@ -881,18 +903,18 @@ test_expect_success 'part of packfile response provided as URI' 'test_line_count=6filelist'-test_expect_success'packfile URIs with fetch instead of clone''+test_expect_success'blobs packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob0>h&&gitinithttp_child&&
@@ -902,9 +924,65 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'fetch"$HTTPD_URL/smart/http_parent"'+test_expect_success'commits(not recursively) packfile URIs with fetch instead of clone''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&++mycommit=$(git-C"$P"rev-parseA)&&+echoother-blob>"$P/other-blob"&&+git-C"$P"addother-blob&&+test_commit-C"$P"B&&+othercommit=$(git-C"$P"rev-parseB)&&++configure_exclusioncommit"$P""$mycommit"0>h&&+configure_exclusioncommit"$P""$othercommit"0>h2&&++gitinithttp_child&&++GIT_TRACE=1GIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch"$HTTPD_URL/smart/http_parent"+'++test_expect_success'commits(recursively) packfile URIs with fetch instead of clone''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&++mycommit=$(git-C"$P"rev-parseA)&&+echoother-blob>"$P/other-blob"&&+git-C"$P"addother-blob&&+test_commit-C"$P"B&&+othercommit=$(git-C"$P"rev-parseB)&&++configure_exclusioncommit"$P""$mycommit"1>h2&&+configure_exclusioncommit"$P""$othercommit"1>h2&&++gitinithttp_child&&++GIT_TRACE=1GIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch"$HTTPD_URL/smart/http_parent"+'+ test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -913,9 +991,9 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob0>h&&# Configure a URL for other-blob. Just reuse the hash of the object as# the hash of the packfile, since the hash does not matter for this# test as long as it is not the hash of the pack, and it is of the
@@ -923,8 +1001,8 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"hash-objectother-blob>objh&&git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&git-C"$P"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catobjh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+"uploadpack.excludeobject"\+"$(catobjh) 0 $(catobjh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&test_must_failenvGIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\
@@ -935,16 +1013,15 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' test_expect_success'packfile-uri with transfer.fsckobjects''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&--configure_exclusion"$P"my-blob>h&&+test_commit-C"$P"A&&+configure_exclusionblob"$P"my-blob0>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -959,7 +1036,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' ' test_expect_success'packfile-uri with transfer.fsckobjects fails on bad object''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -976,9 +1053,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob0>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -989,7 +1066,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object' test_expect_success'packfile-uri with transfer.fsckobjects succeeds when .gitmodules is separate from tree''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_child&&+test_when_finished"rm -rf \"$P\" http_child"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1000,7 +1077,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmogit-C"$P"add.gitmodules&&git-C"$P"commit-mx&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules0>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1015,7 +1092,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmo test_expect_success'packfile-uri with transfer.fsckobjects fails when .gitmodules separate from tree is invalid''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childerr&&+test_when_finished"rm -rf \"$P\" http_child err"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1024,9 +1101,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodulecho"path = include/foo">>"$P/.gitmodules"&&echo"url = git://example.com/git/lib.git">>"$P/.gitmodules"&&git-C"$P"add.gitmodules&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules0>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
From: Teng Long <hidden> Date: 2021-07-26 09:47:02
On the server, more sophisticated means of excluding objects should be
supported, such as commit object. This commit introduces a new
configuration `uploadpack.excludeobject` for this.
The reason for bringing a new configuration is for two considerations.
First, the old configuration supports a single object type (blob), which
limits the use of this feature. Secondly, the name of the old
configuration is not abstract enough, this make extension difficult. If
different object types use different configuration names, the
configuration items will be bloated and difficult to maintain, so the
new configuration is more abstract in name and easy to extend.
Although a new configuration has been introduced, the old one is
still available and compatible with the new configuration. The old
configuration `uploadpack.blobpackfileuri` only supports excluding
blobs. The new configuration `uploadpack.excludeobject` not only
supports excluding blob objects, but also supports excluding commit
objects, as well as recursively excluding tree objects and blob objects
they contain.
Signed-off-by: Teng Long <redacted>
---
builtin/describe.c | 4 +-
builtin/pack-objects.c | 97 ++++++++++++++++++++++++------------------
builtin/rev-list.c | 2 +-
fetch-pack.c | 6 +++
list-objects.c | 37 +++++++++-------
list-objects.h | 2 +-
object.c | 15 +++++--
object.h | 4 ++
pack-bitmap.c | 8 ++--
reachable.c | 8 ++--
revision.c | 36 +++++++++++-----
revision.h | 4 ++
upload-pack.c | 7 +++
13 files changed, 148 insertions(+), 82 deletions(-)
@@ -1394,7 +1406,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset)){+if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_commit)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -1420,7 +1432,7 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,if(have_duplicate_entry(oid,0))return0;-if(!want_object_in_pack(oid,0,&pack,&offset))+if(!want_object_in_pack(oid,0,&pack,&offset,NULL))return0;create_object_entry(oid,type,name_hash,0,0,pack,offset);
@@ -2998,11 +3010,11 @@ static int git_pack_config(const char *k, const char *v, void *cb)*oid_end!=' '||parse_oid_hex(oid_end+1,&pack_hash,&pack_end)||*pack_end!=' ')-die(_("value of uploadpack.blobpackfileuri must be "-"of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);+die(_("value of uploadpack.excludeobject or uploadpack.blobpackfileuri must be "+"of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);if(oidmap_get(&configured_exclusions,&ex->e.oid))-die(_("object already configured in another "-"uploadpack.blobpackfileuri (got '%s')"),v);+die(_("object already configured by an earlier "+"uploadpack.excludeobject or uploadpack.blobpackfileuri (got '%s')"),v);ex->pack_hash_hex=xcalloc(1,pack_end-oid_end);memcpy(ex->pack_hash_hex,oid_end+1,pack_end-oid_end-1);ex->uri=xstrdup(pack_end+1);
@@ -3031,7 +3043,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;ofs=nth_packed_object_offset(p,pos);-if(!want_object_in_pack(oid,0,&p,&ofs))+if(!want_object_in_pack(oid,0,&p,&ofs,NULL))return0;oi.typep=&type;
@@ -3538,7 +3551,8 @@ static int get_object_list_from_bitmap(struct rev_info *revs)staticvoidrecord_recent_object(structobject*obj,constchar*name,-void*data)+void*show_data,+void*carry_data){oid_array_append(&recent_objects,&obj->oid);}
@@ -3831,7 +3845,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)N_("respect islands during delta compression")),OPT_STRING_LIST(0,"uri-protocol",&uri_protocols,N_("protocol"),-N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),+N_("exclude any configured uploadpack.excludeobject or "+"uploadpack.blobpackfileuri with this protocol")),OPT_END(),};
@@ -2817,7 +2833,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct sif(get_oid_with_context(revs->repo,revs->def,0,&oid,&oc))diagnose_missing_default(revs->def);object=get_reference(revs,revs->def,&oid,0);-add_pending_object_with_mode(revs,object,revs->def,oc.mode);+add_pending_object_with_mode(revs,object,revs->def,oc.mode,NULL);}/* Did the user ask for any diff output? Run the diff! */
@@ -753,7 +753,7 @@ test_expect_success 'ls-remote with v2 http sends only one POST' '' test_expect_success'push with http:// and a config of v2 does not request v2''-test_when_finished"rm -f log"&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&# Till v2 for push is designed, make sure that if a client has# protocol.version configured to use v2, that the client instead falls# back and uses v0.
@@ -776,7 +776,7 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '' test_expect_success'when server sends "ready", expect DELIM''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_child&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -796,7 +796,7 @@ test_expect_success 'when server sends "ready", expect DELIM' '' test_expect_success'when server does not send "ready", expect FLUSH''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_childlog&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -824,17 +824,44 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '' configure_exclusion(){-git-C"$1"hash-object"$2">objh&&-git-C"$1"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&-git-C"$1"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-catobjh+objt="$1"+P="$2"+version="$3"++oldc="uploadpack.blobpackfileuri"+newc="uploadpack.excludeobject"+configkey=""+iftest"$version"="0"+then+configkey="$oldc"+else+configkey="$newc"+fi++iftest"$objt"="blob"+then+git-C"$P"hash-object"$3">objh&&+git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+eliftest"$objt"="commit"||test"$objt"="tag"+then+echo"$3">objh+git-C"$2"pack-objects--revs"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+else+echo"unsupported object type in configure_exclusion (got $objt)"+fi} test_expect_success'part of packfile response provided as URI''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -843,10 +870,10 @@ test_expect_success 'part of packfile response provided as URI' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&-configure_exclusion"$P"other-blob>h2&&+configure_exclusionblob"$P"my-blob0>h&&+configure_exclusionblob"$P"other-blob0>h2&&GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\
@@ -881,18 +908,40 @@ test_expect_success 'part of packfile response provided as URI' 'test_line_count=6filelist'-test_expect_success'packfile URIs with fetch instead of clone''+test_expect_success'blobs packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&++configure_exclusionblob"$P"my-blob>h&&++gitinithttp_child&&++GIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch"$HTTPD_URL/smart/http_parent"+'++test_expect_success'blobs packfile URIs(Compatible with the old) with fetch instead of clone''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+# with the old "uploadpack.blobpackfileuri" configure+configure_exclusionblob"$P"my-blob0>h&&gitinithttp_child&&
@@ -902,9 +951,60 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'fetch"$HTTPD_URL/smart/http_parent"'+test_expect_success'commits packfile URIs with fetch instead of clone''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&++mycommit=$(git-C"$P"rev-parseA)&&+echoother-blob>"$P/other-blob"&&+git-C"$P"addother-blob&&+test_commit-C"$P"B&&+othercommit=$(git-C"$P"rev-parseB)&&++configure_exclusioncommit"$P""$mycommit">h2&&+configure_exclusioncommit"$P""$othercommit">h2&&++gitinithttp_child&&++GIT_TRACE=1GIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch"$HTTPD_URL/smart/http_parent"+'++test_expect_success'tags packfile URIs with fetch instead of clone''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&+git-C"$P"tag-a-m"annotated_tag"tagA&&+tagObj=$(git-C"$P"rev-parsetagA)&&++configure_exclusiontag"$P""$tagObj">h2&&++gitinithttp_child&&++GIT_TRACE=1GIT_TRACE_PACKET=1GIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch--tags"$HTTPD_URL/smart/http_parent"+'+ test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -913,9 +1013,9 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&# Configure a URL for other-blob. Just reuse the hash of the object as# the hash of the packfile, since the hash does not matter for this# test as long as it is not the hash of the pack, and it is of the
@@ -923,7 +1023,7 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"hash-objectother-blob>objh&&git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&git-C"$P"config--add\-"uploadpack.blobpackfileuri"\+"uploadpack.excludeobject"\"$(catobjh)$(catobjh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&test_must_failenvGIT_TEST_SIDEBAND_ALL=1\
@@ -933,18 +1033,18 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'test_i18ngrep"pack downloaded from.*does not match expected hash"err'+ test_expect_success'packfile-uri with transfer.fsckobjects''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&--configure_exclusion"$P"my-blob>h&&+test_commit-C"$P"A&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -959,7 +1059,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' ' test_expect_success'packfile-uri with transfer.fsckobjects fails on bad object''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -976,9 +1076,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -989,7 +1089,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object' test_expect_success'packfile-uri with transfer.fsckobjects succeeds when .gitmodules is separate from tree''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_child&&+test_when_finished"rm -rf \"$P\" http_child"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1000,7 +1100,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmogit-C"$P"add.gitmodules&&git-C"$P"commit-mx&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1015,7 +1115,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmo test_expect_success'packfile-uri with transfer.fsckobjects fails when .gitmodules separate from tree is invalid''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childerr&&+test_when_finished"rm -rf \"$P\" http_child err"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1024,9 +1124,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodulecho"path = include/foo">>"$P/.gitmodules"&&echo"url = git://example.com/git/lib.git">>"$P/.gitmodules"&&git-C"$P"add.gitmodules&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -35,13 +35,16 @@ include some sort of non-trivial implementation in the Minimum Viable Product, at least so that we can test the client. This is the implementation: a feature, marked experimental, that allows the-server to be configured by one or more `uploadpack.blobPackfileUri=<sha1>-<uri>` entries. Whenever the list of objects to be sent is assembled, all such-blobs are excluded, replaced with URIs. As noted in "Future work" below, the-server can evolve in the future to support excluding other objects (or other-implementations of servers could be made that support excluding other objects)-without needing a protocol change, so clients should not expect that packfiles-downloaded in this way only contain single blobs.+server to be configured by one or more entries with the format:++ uploadpack.excludeobject=<object-hash> <recursively> <pack-hash> <uri>++Value <object-hash> is the key of entry, and the object type can be a blob+or commit. Whenever the list of objects to be sent is assembled, all such+objects are excluded, replaced with URIs. At the same time, for the old+configuration `uploadpack.blobPackfileUri=<sha1> <pack-hash> <uri>` is+still compatible for now, but this configuration only supports the+exclusion of blob objects. Client design -------------
@@ -65,9 +68,6 @@ The protocol design allows some evolution of the server and client without any need for protocol changes, so only a small-scoped design is included here to form the MVP. For example, the following can be done:- * On the server, more sophisticated means of excluding objects (e.g. by- specifying a commit to represent that commit and all objects that it- references). * On the client, resumption of clone. If a clone is interrupted, information could be recorded in the repository's config and a "clone-resume" command can resume the clone in progress. (Resumption of subsequent fetches is more
@@ -753,7 +753,7 @@ test_expect_success 'ls-remote with v2 http sends only one POST' '' test_expect_success'push with http:// and a config of v2 does not request v2''-test_when_finished"rm -f log"&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&# Till v2 for push is designed, make sure that if a client has# protocol.version configured to use v2, that the client instead falls# back and uses v0.
@@ -776,7 +776,7 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '' test_expect_success'when server sends "ready", expect DELIM''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_child&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -796,7 +796,7 @@ test_expect_success 'when server sends "ready", expect DELIM' '' test_expect_success'when server does not send "ready", expect FLUSH''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_childlog&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -824,17 +824,44 @@ test_expect_success 'when server does not send "ready", expect FLUSH' ''
This looks like a good cleanup, but should be split into another cleanup
commit. It looks unrelated.
From: Teng Long <hidden> Date: 2021-08-11 01:46:17
quoted
This looks like a good cleanup, but should be split into another cleanup
commit. It looks unrelated.
Agree.
Will split up in next patchset.
quoted
You've got all sorts of mixed space/tab indent here.
Yes.
Will fix wrong indents in next patchset.
quoted
Isn't accepting http and https the default?
I think it's NOT after I took a view at function `fetch_pack_config`.
This may be optimized in another patch I think and also will listen
to some other suggestions.
Thank you.
From: Teng Long <hidden> Date: 2021-08-11 07:46:26
During the pack-objects process, "show_object" function will be called
to find the object and show the process("show_object_fn" in
"list-object.h"), the function definition contains three parameters:
1. struct object *obj(contains object type, flags, and oid).
2. const char *name(the object name).
3. void *show_data(function to show progress info).
This commit adds a new parameter: "void *carry_data", the reason is
mainly based on scalability and performance considerations when showing
an object, space for time, avoid costly temporary calculations in the
"show" phase. For example, carry the ownership relationship between
blob or tree object and the referred commit to avoid redundant and
expensive calculations.
Signed-off-by: Teng Long <redacted>
---
builtin/describe.c | 4 ++--
builtin/pack-objects.c | 15 ++++++++-------
builtin/rev-list.c | 2 +-
list-objects.c | 8 ++++----
list-objects.h | 2 +-
pack-bitmap.c | 8 ++++----
reachable.c | 8 ++++----
7 files changed, 24 insertions(+), 23 deletions(-)
From: Teng Long <hidden> Date: 2021-08-11 07:46:28
Currently packfile-uri supports the exclusion of blob objects, but in
some scenarios, users may wish to exclude more types of objects, such as
commit and tree objects, not only because packfile itself supports
storing these object types, but also on the other hand, to make
configuration items maintainable and simpler.
This commit is used to support the recursive exclusion of a commit
object, which means that if the exclusion of a commit is configured as
packfile-uri, the commit itself and all the objects it contains will
also be recursively excluded. In addition, to support this feature, a
new configuration `uploadpack.excludeobject` is introduced.
The reason for bringing a new configuration is for two considerations.
First, the old configuration supports a single object type (blob), which
limits the use of this feature. Secondly, the name of the old
configuration is not abstract enough, this make extension difficult. If
different object types use different configuration names, the
configuration items will be bloated and difficult to maintain, so the
new configuration is more abstract in name and easy to extend.
Although a new configuration has been introduced, the old one is
still available and compatible with the new configuration. The old
configuration `uploadpack.blobpackfileuri` only supports excluding
blobs. The new configuration `uploadpack.excludeobject` not only
supports excluding blob objects, but also supports excluding commit
objects, as well as recursively excluding tree objects and blob objects
they contain.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 50 +++++++++++++++++++++++++-----------------
list-objects.c | 37 +++++++++++++++++--------------
object.c | 15 ++++++++++---
object.h | 4 +++-
revision.c | 34 ++++++++++++++++++++--------
revision.h | 3 +++
upload-pack.c | 7 ++++++
7 files changed, 101 insertions(+), 49 deletions(-)
@@ -1403,7 +1411,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset)){+if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_commit)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -1429,7 +1437,7 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,if(have_duplicate_entry(oid,0))return0;-if(!want_object_in_pack(oid,0,&pack,&offset))+if(!want_object_in_pack(oid,0,&pack,&offset,NULL))return0;create_object_entry(oid,type,name_hash,0,0,pack,offset);
@@ -3007,11 +3015,11 @@ static int git_pack_config(const char *k, const char *v, void *cb)*oid_end!=' '||parse_oid_hex(oid_end+1,&pack_hash,&pack_end)||*pack_end!=' ')-die(_("value of uploadpack.blobpackfileuri must be "+die(_("value of uploadpack.excludeobject or uploadpack.blobpackfileuri must be ""of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);if(oidmap_get(&configured_exclusions,&ex->e.oid))-die(_("object already configured in another "-"uploadpack.blobpackfileuri (got '%s')"),v);+die(_("object already configured by an earlier "+"uploadpack.excludeobject or uploadpack.blobpackfileuri (got '%s')"),v);ex->pack_hash_hex=xcalloc(1,pack_end-oid_end);memcpy(ex->pack_hash_hex,oid_end+1,pack_end-oid_end-1);ex->uri=xstrdup(pack_end+1);
@@ -3040,7 +3048,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;ofs=nth_packed_object_offset(p,pos);-if(!want_object_in_pack(oid,0,&p,&ofs))+if(!want_object_in_pack(oid,0,&p,&ofs,NULL))return0;oi.typep=&type;
@@ -3841,7 +3850,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)N_("respect islands during delta compression")),OPT_STRING_LIST(0,"uri-protocol",&uri_protocols,N_("protocol"),-N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),+N_("exclude any configured uploadpack.excludeobject or "+"uploadpack.blobpackfileuri with this protocol")),OPT_END(),};
@@ -326,20 +327,35 @@ static void add_pending_object_with_path(struct rev_info *revs,strbuf_release(&buf);return;/* do not add the commit itself */}-add_object_array_with_path(obj,name,&revs->pending,mode,path);+add_object_array_with_path_and_referred_commit(obj,name,&revs->pending,mode,path,referred_commit);}+staticvoidadd_pending_object_with_path(structrev_info*revs,+structobject*obj,+constchar*name,unsignedmode,+constchar*path)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,path,NULL);+}staticvoidadd_pending_object_with_mode(structrev_info*revs,structobject*obj,-constchar*name,unsignedmode)+constchar*name,unsignedmode,+structobject*referred_commit)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,NULL,referred_commit);+}++voidadd_pending_object_with_referred_commit(structrev_info*revs,+structobject*obj,constchar*name,+structobject*referred_commit){-add_pending_object_with_path(revs,obj,name,mode,NULL);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,referred_commit);}voidadd_pending_object(structrev_info*revs,structobject*obj,constchar*name){-add_pending_object_with_mode(revs,obj,name,S_IFINVALID);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,NULL);}voidadd_head_to_pending(structrev_info*revs)
@@ -2817,7 +2833,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct sif(get_oid_with_context(revs->repo,revs->def,0,&oid,&oc))diagnose_missing_default(revs->def);object=get_reference(revs,revs->def,&oid,0);-add_pending_object_with_mode(revs,object,revs->def,oc.mode);+add_pending_object_with_mode(revs,object,revs->def,oc.mode,NULL);}/* Did the user ask for any diff output? Run the diff! */
From: Teng Long <hidden> Date: 2021-08-11 07:46:35
This commit supports the use of `uploadpack.excludeobject` to exclude
tree objects, which means that when a type object is configured as
packfile-uri, the tree object itself and all objects contains will be
recursively excluded.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 30 ++++++++++++++++++++----------
list-objects.c | 32 ++++++++++++++++++--------------
object.c | 6 +++++-
object.h | 13 ++++++++++++-
4 files changed, 55 insertions(+), 26 deletions(-)
@@ -1411,7 +1421,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_commit)){+if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_objs)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -35,13 +35,26 @@ include some sort of non-trivial implementation in the Minimum Viable Product, at least so that we can test the client. This is the implementation: a feature, marked experimental, that allows the-server to be configured by one or more `uploadpack.blobPackfileUri=<sha1>-<uri>` entries. Whenever the list of objects to be sent is assembled, all such-blobs are excluded, replaced with URIs. As noted in "Future work" below, the-server can evolve in the future to support excluding other objects (or other-implementations of servers could be made that support excluding other objects)-without needing a protocol change, so clients should not expect that packfiles-downloaded in this way only contain single blobs.+server to be configured by one or more entries with the format:++ uploadpack.excludeobject=<object-hash> <pack-hash> <uri>++Value <object-hash> is the key of entry, and the object type can be a blob,+tree, or commit. The exclusion of tree and commit is recursive by default,+which means that when a tree or commit object is excluded, the object itself+and all reachable objects of the object will be excluded recursively. Whenever+the list of objects to be sent is assembled, all such objects are excluded,+replaced with URIs.++Configuration compatibility+-------------++The old configuration of packfile-uri:++ `uploadpack.blobPackfileUri=<object-hash> <pack-hash> <uri>`++For the old configuration is compatible with the new one, but it only+supports the exclusion of blob objects. Client design -------------
@@ -65,9 +78,6 @@ The protocol design allows some evolution of the server and client without any need for protocol changes, so only a small-scoped design is included here to form the MVP. For example, the following can be done:- * On the server, more sophisticated means of excluding objects (e.g. by- specifying a commit to represent that commit and all objects that it- references). * On the client, resumption of clone. If a clone is interrupted, information could be recorded in the repository's config and a "clone-resume" command can resume the clone in progress. (Resumption of subsequent fetches is more
@@ -78,4 +88,4 @@ There are some possible features that will require a change in protocol: * Additional HTTP headers (e.g. authentication) * Byte range support- * Different file formats referenced by URIs (e.g. raw object)+ * Different file formats referenced by URIs (e.g. raw object)
\ No newline at end of file
--
2.31.1.449.gb2aa5456a8.dirty
@@ -753,7 +753,7 @@ test_expect_success 'ls-remote with v2 http sends only one POST' '' test_expect_success'push with http:// and a config of v2 does not request v2''-test_when_finished"rm -f log"&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&# Till v2 for push is designed, make sure that if a client has# protocol.version configured to use v2, that the client instead falls# back and uses v0.
@@ -776,7 +776,7 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '' test_expect_success'when server sends "ready", expect DELIM''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_child&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -796,7 +796,7 @@ test_expect_success 'when server sends "ready", expect DELIM' '' test_expect_success'when server does not send "ready", expect FLUSH''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_childlog&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -834,7 +834,7 @@ configure_exclusion () { test_expect_success'part of packfile response provided as URI''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -883,7 +883,7 @@ test_expect_success 'part of packfile response provided as URI' ' test_expect_success'packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -904,7 +904,7 @@ test_expect_success 'packfile URIs with fetch instead of clone' ' test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -935,7 +935,7 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' test_expect_success'packfile-uri with transfer.fsckobjects''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -959,7 +959,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' ' test_expect_success'packfile-uri with transfer.fsckobjects fails on bad object''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -989,7 +989,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object' test_expect_success'packfile-uri with transfer.fsckobjects succeeds when .gitmodules is separate from tree''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_child&&+test_when_finished"rm -rf \"$P\" http_child"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1015,7 +1015,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmo test_expect_success'packfile-uri with transfer.fsckobjects fails when .gitmodules separate from tree is invalid''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childerr&&+test_when_finished"rm -rf \"$P\" http_child err"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1038,4 +1038,4 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodul# DO NOT add non-httpd-specific tests here, because the last part of this# test script is only executed when httpd is available and enabled.-test_done+test_done
\ No newline at end of file
--
2.31.1.449.gb2aa5456a8.dirty
@@ -824,17 +824,47 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '' configure_exclusion(){-git-C"$1"hash-object"$2">objh&&-git-C"$1"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&-git-C"$1"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-catobjh+objt="$1"+P="$2"+oid="$3"+version="$4"++oldc="uploadpack.blobpackfileuri"+newc="uploadpack.excludeobject"+configkey=""++iftest"$version"="old"+then+configkey="$oldc"+else+configkey="$newc"+fi++iftest"$objt"="blob"+then+git-C"$P"hash-object"$oid">objh&&+git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+eliftest"$objt"="commit"||test"$objt"="tree"||test"$objt"="tag"+then+echo"$oid">objh+git-C"$P"pack-objects--revs"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+else+echo"unsupported object type in configure_exclusion (got $objt)"+fi}-test_expect_success'part of packfile response provided as URI''+part_of_packfile_response_verify(){+config="$1"P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-test_when_finished"rm -rf \"$P\" http_child log"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -843,10 +873,10 @@ test_expect_success 'part of packfile response provided as URI' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&-configure_exclusion"$P"other-blob>h2&&+configure_exclusionblob"$P"my-blobconfig>h&&+configure_exclusionblob"$P"other-blobconfig>h2&&GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\
@@ -879,9 +909,11 @@ test_expect_success 'part of packfile response provided as URI' 'lshttp_child/.git/objects/pack/*.pack\http_child/.git/objects/pack/*.idx>filelist&&test_line_count=6filelist-'+}++blobpackfileuri_fetch(){+config="$1"-test_expect_success'packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_when_finished"rm -rf \"$P\" http_child log"&&
@@ -890,9 +922,9 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob$config>h&&gitinithttp_child&&
@@ -900,6 +932,215 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'git-Chttp_child-cprotocol.version=2\-cfetch.uriprotocols=http,https\fetch"$HTTPD_URL/smart/http_parent"+}++test_expect_success'blob-exclusion (using uploadpack.blobpackfileuri): part of packfile response provided as URI''+part_of_packfile_response_verifyold+'++test_expect_success'blob-exclusion (using uploadpack.excludeobject): part of packfile response provided as URI''+part_of_packfile_response_verifynew+'++test_expect_success'blob-exclusion (using uploadpack.blobpackfileuri): packfile URIs with fetch instead of clone''+blobpackfileuri_fetchold+'++test_expect_success'blob-exclusion (using uploadpack.excludeobject): packfile URIs with fetch instead of clone''+blobpackfileuri_fetchnew+'++test_expect_success'tree-exclusion: part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++# Dir struct+# .+# |-- A.t+# |-- my-tree+# | `-- my-blob+# `-- other-tree+# |-- other-blob+# `-- sub-tree+# `-- sub-blob+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/other-tree&&+echoother-blob>"$P"/other-tree/other-blob&&+mkdir"$P"/other-tree/sub-tree&&+echosub-blob>"$P"/other-tree/sub-tree/sub-blob&&+git-C"$P"addother-tree&&+test_commit-C"$P"A&&++commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+ah=$(git-C"$P"hash-objectA.t)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+othertreeh=$(git-C"$P"ls-treeHEADother-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADother-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+otherblobh=$(git-C"$P"hash-objectother-tree/other-blob)&&+subblobh=$(git-C"$P"hash-objectother-tree/sub-tree/sub-blob)&&++configure_exclusiontree"$P""$mytreeh"config>h&&+configure_exclusiontree"$P""$othertreeh"config>h2&&++GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&++# Ensure that my-tree and other-tree and theirs complementary set are in separate packfiles.+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=3out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi+eliftest_line_count=2out.objectlist+then+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi+eliftest_line_count=4out.objectlist+then+ifgrep$othertreehout+then+>othertreehfound+fi&&+ifgrep$otherblobhout+then+>otherblobhfound+fi+ifgrep$subtreehout+then+>subtreehfound+fi&&+ifgrep$subblobhout+then+>subblobhfound+fi+fi+done&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fothertreehfound&&+test-fotherblobhfound&&+test-fsubtreehfound&&+test-fsubblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&++# Ensure that there are exactly 3 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=6filelist+'++test_expect_success'commit-exclusion: part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/my-tree/sub-tree&&+echosub-blob>"$P"/my-tree/sub-tree/sub-blob&&+git-C"$P"addmy-tree&&+test_commit-C"$P"A&&++commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADmy-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+ah=$(git-C"$P"hash-objectA.t)&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+subblobh=$(git-C"$P"hash-objectmy-tree/sub-tree/sub-blob)&&++configure_exclusioncommit"$P""$commith">h&&++GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&++foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=7out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi&&+ifgrep$subtreehout+then+>subtreehfound+fi&&+ifgrep$subblobhout+then+>subblobhfound+fi+fi+done&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fsubtreehfound&&+test-fsubblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&++# Ensure that there are exactly 2 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist' test_expect_success'fetching with valid packfile URI but invalid hash fails''
@@ -913,9 +1154,9 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&# Configure a URL for other-blob. Just reuse the hash of the object as# the hash of the packfile, since the hash does not matter for this# test as long as it is not the hash of the pack, and it is of the
@@ -923,7 +1164,7 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"hash-objectother-blob>objh&&git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&git-C"$P"config--add\-"uploadpack.blobpackfileuri"\+"uploadpack.excludeobject"\"$(catobjh)$(catobjh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&test_must_failenvGIT_TEST_SIDEBAND_ALL=1\
@@ -942,9 +1183,8 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' 'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&--configure_exclusion"$P"my-blob>h&&+test_commit-C"$P"A&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -976,9 +1216,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1000,7 +1240,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmogit-C"$P"add.gitmodules&&git-C"$P"commit-mx&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1024,9 +1264,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodulecho"path = include/foo">>"$P/.gitmodules"&&echo"url = git://example.com/git/lib.git">>"$P/.gitmodules"&&git-C"$P"add.gitmodules&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
+The old configuration of packfile-uri:
+
+ `uploadpack.blobPackfileUri=<object-hash> <pack-hash> <uri>`
+
+For the old configuration is compatible with the new one, but it only
+supports the exclusion of blob objects.
I think better say "The old configuration of packfile-uri ... is
compatible with the new one, but it only supports exclusion of blobs".
--
An old man doll... just what I always wanted! - Clara
From: Teng Long <hidden> Date: 2021-08-25 02:22:10
Changes since v5:
* Support tag objects exclusion (configurable but will repeat download object
data in previous patch)
* Tests and docs modification for tag exclusion feature
* Abstraction of some reusable methods
Teng Long (14):
pack-objects.c: introduce new method `match_packfile_uri_exclusions`
Add new parameter "carry_data" for "show_object" function
packfile-uri: support for excluding commit objects
packfile-uri: support for excluding tree objects
packfile-uri.txt: support for excluding commits and trees
t5702: replace with "test_when_finished" for cleanup
t5702: support for excluding commit objects
Add new parameter "carry_data" for "show_commit function
commit.h: add wrapped tags in commit struct
object.h: add referred tags in `referred_objects` struct
packfile-uri: support for excluding tag objects
packfile-uri.txt: support for excluding tag objects
t5702: add tag exclusion test case
pack-objects.c: introduce `want_exclude_object` function
Documentation/technical/packfile-uri.txt | 38 ++-
builtin/describe.c | 8 +-
builtin/pack-objects.c | 128 ++++++---
builtin/rev-list.c | 6 +-
bundle.c | 4 +-
commit.h | 5 +
list-objects.c | 50 ++--
list-objects.h | 4 +-
object.c | 20 +-
object.h | 16 +-
pack-bitmap.c | 14 +-
reachable.c | 8 +-
revision.c | 42 ++-
revision.h | 3 +
shallow.c | 4 +-
t/t5702-protocol-v2.sh | 330 ++++++++++++++++++++---
upload-pack.c | 7 +
17 files changed, 542 insertions(+), 145 deletions(-)
Range-diff against v4:
-: ---------- > 1: 73a5b4ccc1 pack-objects.c: introduce new method `match_packfile_uri_exclusions`
-: ---------- > 2: bc8fea97e3 Add new parameter "carry_data" for "show_object" function
-: ---------- > 3: f71b310842 packfile-uri: support for excluding commit objects
-: ---------- > 4: bbb0413cc4 packfile-uri: support for excluding tree objects
-: ---------- > 5: 8e5bf4010c packfile-uri.txt: support for excluding commits and trees
-: ---------- > 6: f3b1cba7e1 t5702: replace with "test_when_finished" for cleanup
-: ---------- > 7: 3b5f9732b8 t5702: support for excluding commit objects
1: 19f7670384 = 8: 19f7670384 Add new parameter "carry_data" for "show_commit function
2: 011e5eaea3 = 9: 011e5eaea3 commit.h: add wrapped tags in commit struct
3: 824844499f = 10: 824844499f object.h: add referred tags in `referred_objects` struct
4: 43aa811b65 = 11: 43aa811b65 packfile-uri: support for excluding tag objects
5: c83db0055c = 12: c83db0055c packfile-uri.txt: support for excluding tag objects
6: 29a52b7a0d = 13: 29a52b7a0d t5702: add tag exclusion test case
7: 1a7c4c5894 = 14: 1a7c4c5894 pack-objects.c: introduce `want_exclude_object` function
--
2.31.1.456.gec51e24953
From: Teng Long <hidden> Date: 2021-08-25 02:22:14
During the pack-objects process, "show_object" function will be called
to find the object and show the process("show_object_fn" in
"list-object.h"), the function definition contains three parameters:
1. struct object *obj(contains object type, flags, and oid).
2. const char *name(the object name).
3. void *show_data(function to show progress info).
This commit adds a new parameter: "void *carry_data", the reason is
mainly based on scalability and performance considerations when showing
an object, space for time, avoid costly temporary calculations in the
"show" phase. For example, carry the ownership relationship between
blob or tree object and the referred commit to avoid redundant and
expensive calculations.
Signed-off-by: Teng Long <redacted>
---
builtin/describe.c | 4 ++--
builtin/pack-objects.c | 15 ++++++++-------
builtin/rev-list.c | 2 +-
list-objects.c | 8 ++++----
list-objects.h | 2 +-
pack-bitmap.c | 8 ++++----
reachable.c | 8 ++++----
7 files changed, 24 insertions(+), 23 deletions(-)
From: Teng Long <hidden> Date: 2021-08-25 02:22:16
Currently packfile-uri supports the exclusion of blob objects, but in
some scenarios, users may wish to exclude more types of objects, such as
commit and tree objects, not only because packfile itself supports
storing these object types, but also on the other hand, to make
configuration items maintainable and simpler.
This commit is used to support the recursive exclusion of a commit
object, which means that if the exclusion of a commit is configured as
packfile-uri, the commit itself and all the objects it contains will
also be recursively excluded. In addition, to support this feature, a
new configuration `uploadpack.excludeobject` is introduced.
The reason for bringing a new configuration is for two considerations.
First, the old configuration supports a single object type (blob), which
limits the use of this feature. Secondly, the name of the old
configuration is not abstract enough, this make extension difficult. If
different object types use different configuration names, the
configuration items will be bloated and difficult to maintain, so the
new configuration is more abstract in name and easy to extend.
Although a new configuration has been introduced, the old one is
still available and compatible with the new configuration. The old
configuration `uploadpack.blobpackfileuri` only supports excluding
blobs. The new configuration `uploadpack.excludeobject` not only
supports excluding blob objects, but also supports excluding commit
objects, as well as recursively excluding tree objects and blob objects
they contain.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 50 +++++++++++++++++++++++++-----------------
list-objects.c | 37 +++++++++++++++++--------------
object.c | 15 ++++++++++---
object.h | 4 +++-
revision.c | 34 ++++++++++++++++++++--------
revision.h | 3 +++
upload-pack.c | 7 ++++++
7 files changed, 101 insertions(+), 49 deletions(-)
@@ -1403,7 +1411,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset)){+if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_commit)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -1429,7 +1437,7 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,if(have_duplicate_entry(oid,0))return0;-if(!want_object_in_pack(oid,0,&pack,&offset))+if(!want_object_in_pack(oid,0,&pack,&offset,NULL))return0;create_object_entry(oid,type,name_hash,0,0,pack,offset);
@@ -3007,11 +3015,11 @@ static int git_pack_config(const char *k, const char *v, void *cb)*oid_end!=' '||parse_oid_hex(oid_end+1,&pack_hash,&pack_end)||*pack_end!=' ')-die(_("value of uploadpack.blobpackfileuri must be "+die(_("value of uploadpack.excludeobject or uploadpack.blobpackfileuri must be ""of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);if(oidmap_get(&configured_exclusions,&ex->e.oid))-die(_("object already configured in another "-"uploadpack.blobpackfileuri (got '%s')"),v);+die(_("object already configured by an earlier "+"uploadpack.excludeobject or uploadpack.blobpackfileuri (got '%s')"),v);ex->pack_hash_hex=xcalloc(1,pack_end-oid_end);memcpy(ex->pack_hash_hex,oid_end+1,pack_end-oid_end-1);ex->uri=xstrdup(pack_end+1);
@@ -3040,7 +3048,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;ofs=nth_packed_object_offset(p,pos);-if(!want_object_in_pack(oid,0,&p,&ofs))+if(!want_object_in_pack(oid,0,&p,&ofs,NULL))return0;oi.typep=&type;
@@ -3841,7 +3850,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)N_("respect islands during delta compression")),OPT_STRING_LIST(0,"uri-protocol",&uri_protocols,N_("protocol"),-N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),+N_("exclude any configured uploadpack.excludeobject or "+"uploadpack.blobpackfileuri with this protocol")),OPT_END(),};
@@ -326,20 +327,35 @@ static void add_pending_object_with_path(struct rev_info *revs,strbuf_release(&buf);return;/* do not add the commit itself */}-add_object_array_with_path(obj,name,&revs->pending,mode,path);+add_object_array_with_path_and_referred_commit(obj,name,&revs->pending,mode,path,referred_commit);}+staticvoidadd_pending_object_with_path(structrev_info*revs,+structobject*obj,+constchar*name,unsignedmode,+constchar*path)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,path,NULL);+}staticvoidadd_pending_object_with_mode(structrev_info*revs,structobject*obj,-constchar*name,unsignedmode)+constchar*name,unsignedmode,+structobject*referred_commit)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,NULL,referred_commit);+}++voidadd_pending_object_with_referred_commit(structrev_info*revs,+structobject*obj,constchar*name,+structobject*referred_commit){-add_pending_object_with_path(revs,obj,name,mode,NULL);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,referred_commit);}voidadd_pending_object(structrev_info*revs,structobject*obj,constchar*name){-add_pending_object_with_mode(revs,obj,name,S_IFINVALID);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,NULL);}voidadd_head_to_pending(structrev_info*revs)
@@ -2817,7 +2833,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct sif(get_oid_with_context(revs->repo,revs->def,0,&oid,&oc))diagnose_missing_default(revs->def);object=get_reference(revs,revs->def,&oid,0);-add_pending_object_with_mode(revs,object,revs->def,oc.mode);+add_pending_object_with_mode(revs,object,revs->def,oc.mode,NULL);}/* Did the user ask for any diff output? Run the diff! */
From: Teng Long <hidden> Date: 2021-08-25 02:22:18
This commit supports the use of `uploadpack.excludeobject` to exclude
tree objects, which means that when a type object is configured as
packfile-uri, the tree object itself and all objects contains will be
recursively excluded.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 30 ++++++++++++++++++++----------
list-objects.c | 32 ++++++++++++++++++--------------
object.c | 6 +++++-
object.h | 13 ++++++++++++-
4 files changed, 55 insertions(+), 26 deletions(-)
@@ -1411,7 +1421,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_commit)){+if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_objs)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -35,13 +35,26 @@ include some sort of non-trivial implementation in the Minimum Viable Product, at least so that we can test the client. This is the implementation: a feature, marked experimental, that allows the-server to be configured by one or more `uploadpack.blobPackfileUri=<sha1>-<uri>` entries. Whenever the list of objects to be sent is assembled, all such-blobs are excluded, replaced with URIs. As noted in "Future work" below, the-server can evolve in the future to support excluding other objects (or other-implementations of servers could be made that support excluding other objects)-without needing a protocol change, so clients should not expect that packfiles-downloaded in this way only contain single blobs.+server to be configured by one or more entries with the format:++ uploadpack.excludeobject=<object-hash> <pack-hash> <uri>++Value <object-hash> is the key of entry, and the object type can be a blob,+tree, or commit. The exclusion of tree and commit is recursive by default,+which means that when a tree or commit object is excluded, the object itself+and all reachable objects of the object will be excluded recursively. Whenever+the list of objects to be sent is assembled, all such objects are excluded,+replaced with URIs.++Configuration compatibility+-------------++The old configuration of packfile-uri:++ `uploadpack.blobPackfileUri=<object-hash> <pack-hash> <uri>`++For the old configuration is compatible with the new one, but it only+supports the exclusion of blob objects. Client design -------------
@@ -65,9 +78,6 @@ The protocol design allows some evolution of the server and client without any need for protocol changes, so only a small-scoped design is included here to form the MVP. For example, the following can be done:- * On the server, more sophisticated means of excluding objects (e.g. by- specifying a commit to represent that commit and all objects that it- references). * On the client, resumption of clone. If a clone is interrupted, information could be recorded in the repository's config and a "clone-resume" command can resume the clone in progress. (Resumption of subsequent fetches is more
@@ -78,4 +88,4 @@ There are some possible features that will require a change in protocol: * Additional HTTP headers (e.g. authentication) * Byte range support- * Different file formats referenced by URIs (e.g. raw object)+ * Different file formats referenced by URIs (e.g. raw object)
\ No newline at end of file
--
2.31.1.456.gec51e24953
@@ -753,7 +753,7 @@ test_expect_success 'ls-remote with v2 http sends only one POST' '' test_expect_success'push with http:// and a config of v2 does not request v2''-test_when_finished"rm -f log"&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&# Till v2 for push is designed, make sure that if a client has# protocol.version configured to use v2, that the client instead falls# back and uses v0.
@@ -776,7 +776,7 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '' test_expect_success'when server sends "ready", expect DELIM''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_child&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -796,7 +796,7 @@ test_expect_success 'when server sends "ready", expect DELIM' '' test_expect_success'when server does not send "ready", expect FLUSH''-rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_childlog&&+test_when_finished"rm -rf \"$HTTPD_DOCUMENT_ROOT_PATH/http_parent\" http_child log"&&gitinit"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_commit-C"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"one&&
@@ -834,7 +834,7 @@ configure_exclusion () { test_expect_success'part of packfile response provided as URI''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -883,7 +883,7 @@ test_expect_success 'part of packfile response provided as URI' ' test_expect_success'packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -904,7 +904,7 @@ test_expect_success 'packfile URIs with fetch instead of clone' ' test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -935,7 +935,7 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' test_expect_success'packfile-uri with transfer.fsckobjects''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -959,7 +959,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' ' test_expect_success'packfile-uri with transfer.fsckobjects fails on bad object''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -989,7 +989,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object' test_expect_success'packfile-uri with transfer.fsckobjects succeeds when .gitmodules is separate from tree''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_child&&+test_when_finished"rm -rf \"$P\" http_child"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1015,7 +1015,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmo test_expect_success'packfile-uri with transfer.fsckobjects fails when .gitmodules separate from tree is invalid''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childerr&&+test_when_finished"rm -rf \"$P\" http_child err"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1038,4 +1038,4 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodul# DO NOT add non-httpd-specific tests here, because the last part of this# test script is only executed when httpd is available and enabled.-test_done+test_done
\ No newline at end of file
--
2.31.1.456.gec51e24953
@@ -824,17 +824,47 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '' configure_exclusion(){-git-C"$1"hash-object"$2">objh&&-git-C"$1"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&-git-C"$1"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-catobjh+objt="$1"+P="$2"+oid="$3"+version="$4"++oldc="uploadpack.blobpackfileuri"+newc="uploadpack.excludeobject"+configkey=""++iftest"$version"="old"+then+configkey="$oldc"+else+configkey="$newc"+fi++iftest"$objt"="blob"+then+git-C"$P"hash-object"$oid">objh&&+git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+eliftest"$objt"="commit"||test"$objt"="tree"||test"$objt"="tag"+then+echo"$oid">objh+git-C"$P"pack-objects--revs"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+else+echo"unsupported object type in configure_exclusion (got $objt)"+fi}-test_expect_success'part of packfile response provided as URI''+part_of_packfile_response_verify(){+config="$1"P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-test_when_finished"rm -rf \"$P\" http_child log"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -843,10 +873,10 @@ test_expect_success 'part of packfile response provided as URI' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&-configure_exclusion"$P"other-blob>h2&&+configure_exclusionblob"$P"my-blobconfig>h&&+configure_exclusionblob"$P"other-blobconfig>h2&&GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\
@@ -879,9 +909,11 @@ test_expect_success 'part of packfile response provided as URI' 'lshttp_child/.git/objects/pack/*.pack\http_child/.git/objects/pack/*.idx>filelist&&test_line_count=6filelist-'+}++blobpackfileuri_fetch(){+config="$1"-test_expect_success'packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_when_finished"rm -rf \"$P\" http_child log"&&
@@ -890,9 +922,9 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob$config>h&&gitinithttp_child&&
@@ -900,6 +932,215 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'git-Chttp_child-cprotocol.version=2\-cfetch.uriprotocols=http,https\fetch"$HTTPD_URL/smart/http_parent"+}++test_expect_success'blob-exclusion (using uploadpack.blobpackfileuri): part of packfile response provided as URI''+part_of_packfile_response_verifyold+'++test_expect_success'blob-exclusion (using uploadpack.excludeobject): part of packfile response provided as URI''+part_of_packfile_response_verifynew+'++test_expect_success'blob-exclusion (using uploadpack.blobpackfileuri): packfile URIs with fetch instead of clone''+blobpackfileuri_fetchold+'++test_expect_success'blob-exclusion (using uploadpack.excludeobject): packfile URIs with fetch instead of clone''+blobpackfileuri_fetchnew+'++test_expect_success'tree-exclusion: part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++# Dir struct+# .+# |-- A.t+# |-- my-tree+# | `-- my-blob+# `-- other-tree+# |-- other-blob+# `-- sub-tree+# `-- sub-blob+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/other-tree&&+echoother-blob>"$P"/other-tree/other-blob&&+mkdir"$P"/other-tree/sub-tree&&+echosub-blob>"$P"/other-tree/sub-tree/sub-blob&&+git-C"$P"addother-tree&&+test_commit-C"$P"A&&++commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+ah=$(git-C"$P"hash-objectA.t)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+othertreeh=$(git-C"$P"ls-treeHEADother-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADother-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+otherblobh=$(git-C"$P"hash-objectother-tree/other-blob)&&+subblobh=$(git-C"$P"hash-objectother-tree/sub-tree/sub-blob)&&++configure_exclusiontree"$P""$mytreeh"config>h&&+configure_exclusiontree"$P""$othertreeh"config>h2&&++GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&++# Ensure that my-tree and other-tree and theirs complementary set are in separate packfiles.+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=3out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi+eliftest_line_count=2out.objectlist+then+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi+eliftest_line_count=4out.objectlist+then+ifgrep$othertreehout+then+>othertreehfound+fi&&+ifgrep$otherblobhout+then+>otherblobhfound+fi+ifgrep$subtreehout+then+>subtreehfound+fi&&+ifgrep$subblobhout+then+>subblobhfound+fi+fi+done&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fothertreehfound&&+test-fotherblobhfound&&+test-fsubtreehfound&&+test-fsubblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&++# Ensure that there are exactly 3 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=6filelist+'++test_expect_success'commit-exclusion: part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&++gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&++mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/my-tree/sub-tree&&+echosub-blob>"$P"/my-tree/sub-tree/sub-blob&&+git-C"$P"addmy-tree&&+test_commit-C"$P"A&&++commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADmy-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+ah=$(git-C"$P"hash-objectA.t)&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+subblobh=$(git-C"$P"hash-objectmy-tree/sub-tree/sub-blob)&&++configure_exclusioncommit"$P""$commith">h&&++GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&++foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=7out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi&&+ifgrep$subtreehout+then+>subtreehfound+fi&&+ifgrep$subblobhout+then+>subblobhfound+fi+fi+done&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fsubtreehfound&&+test-fsubblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&++# Ensure that there are exactly 2 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist' test_expect_success'fetching with valid packfile URI but invalid hash fails''
@@ -913,9 +1154,9 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&# Configure a URL for other-blob. Just reuse the hash of the object as# the hash of the packfile, since the hash does not matter for this# test as long as it is not the hash of the pack, and it is of the
@@ -923,7 +1164,7 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"hash-objectother-blob>objh&&git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&git-C"$P"config--add\-"uploadpack.blobpackfileuri"\+"uploadpack.excludeobject"\"$(catobjh)$(catobjh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&test_must_failenvGIT_TEST_SIDEBAND_ALL=1\
@@ -942,9 +1183,8 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' 'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&--configure_exclusion"$P"my-blob>h&&+test_commit-C"$P"A&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -976,9 +1216,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1000,7 +1240,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmogit-C"$P"add.gitmodules&&git-C"$P"commit-mx&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -1024,9 +1264,9 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodulecho"path = include/foo">>"$P/.gitmodules"&&echo"url = git://example.com/git/lib.git">>"$P/.gitmodules"&&git-C"$P"add.gitmodules&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P".gitmodules>h&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\
@@ -3080,7 +3080,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;}-staticvoidshow_commit_pack_hint(structcommit*commit,void*_data)+staticvoidshow_commit_pack_hint(structcommit*commit,void*show_data,void*carry_data){/* nothing to do; commits don't have a namehash */}
@@ -3258,7 +3258,7 @@ static void read_object_list_from_stdin(void)/* Remember to update object flag allocation in object.h */#define OBJECT_ADDED (1u<<20)-staticvoidshow_commit(structcommit*commit,void*data)+staticvoidshow_commit(structcommit*commit,void*show_data,void*carry_data){add_object_entry(&commit->object.oid,OBJ_COMMIT,NULL,0,NULL);commit->object.flags|=OBJECT_ADDED;
From: Teng Long <hidden> Date: 2021-08-25 02:22:45
This commit supports the use of `uploadpack.excludeobject` to exclude
tag objects, both lightweight tag and annotated tag are supported:
-If a lightweight tag (such as a commit object) have been configured,
the mechanism of exclusion is the same as the commit object (the commit
object and all objects it contains will be recusively excluded).
-If an annotated tag (created with -a, -s, or -u) have been configured,
the annotated tag and all the objects that it contains will be excluded,
For an example of the annotated tag:
Create an annotated tag from HEAD:
git tag -a A -m "tag A description"
Output the SHA (<tag_oid>) of tag "A" :
git rev-parse A^{object}
Dereference <tag_oid>, output the SHA <commit_oid> of commit:
git rev-parse A^{}
In the above case, when the tag object (<tag_oid>) is configured with
`uploadpack.excludeobject` which means <tag_oid>, the dereference
commit object (<commit_oid>), and all the objects that <commit_oid>
recursively contains (trees, blobs), will be excluded (using a packfile
URI instead).
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 20 ++++++++++++++++++--
list-objects.c | 9 ++++++++-
2 files changed, 26 insertions(+), 3 deletions(-)
@@ -39,12 +39,18 @@ server to be configured by one or more entries with the format: uploadpack.excludeobject=<object-hash> <pack-hash> <uri>-Value <object-hash> is the key of entry, and the object type can be a blob,-tree, or commit. The exclusion of tree and commit is recursive by default,-which means that when a tree or commit object is excluded, the object itself-and all reachable objects of the object will be excluded recursively. Whenever-the list of objects to be sent is assembled, all such objects are excluded,-replaced with URIs.+Value <object-hash> is the key of entry, and the object type can be blob, tree,+commit, or tag. When an object is configured with `uploadpack.excludeobject` which+means that whenever the list of objects to be sent is assembled, the object (also+include the related objects in some cases, the following will introduce) will be+excluded, replaced with URIS. The mechanism for exclusion is as follows:++ * blob: exclude blob object.+ * tree: exclude tree object, blobs that the tree list, and recursive into sub-trees.+ * commit: exclude commit object, and recursively exclude all the reachable trees+ (ditto tree exclusion) and blobs it contains.+ * tag: exclude tag object itself, and the dereference commit (ditto commit exclusion)+ if the tag is annotated. Configuration compatibility -------------
@@ -1142,6 +1142,24 @@ test_expect_success 'commit-exclusion: part of packfile response provided as URIhttp_child/.git/objects/pack/*.idx>filelist&&test_line_count=4filelist'+test_expect_success'tag-exclusion: part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&+git-C"$P"tag-a-m"annotated_tag"tagA&&+tagObj=$(git-C"$P"rev-parsetagA)&&+configure_exclusiontag"$P""$tagObj">h2&&+gitinithttp_child&&+GIT_TRACE=1GIT_TRACE_PACKET=`pwd`/logGIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child\+-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch--tags"$HTTPD_URL/smart/http_parent"+' test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&
Currently packfile-uri supports the exclusion of blob objects, but in
some scenarios, users may wish to exclude more types of objects, such as
commit and tree objects, not only because packfile itself supports
storing these object types, but also on the other hand, to make
configuration items maintainable and simpler.
This commit is used to support the recursive exclusion of a commit
object, which means that if the exclusion of a commit is configured as
packfile-uri, the commit itself and all the objects it contains will
also be recursively excluded. In addition, to support this feature, a
new configuration `uploadpack.excludeobject` is introduced.
The reason for bringing a new configuration is for two considerations.
First, the old configuration supports a single object type (blob), which
limits the use of this feature. Secondly, the name of the old
configuration is not abstract enough, this make extension difficult. If
different object types use different configuration names, the
configuration items will be bloated and difficult to maintain, so the
new configuration is more abstract in name and easy to extend.
Although a new configuration has been introduced, the old one is
still available and compatible with the new configuration. The old
configuration `uploadpack.blobpackfileuri` only supports excluding
blobs. The new configuration `uploadpack.excludeobject` not only
supports excluding blob objects, but also supports excluding commit
objects, as well as recursively excluding tree objects and blob objects
they contain.
I was under the impression that with uploadpack.blobpackfileuri we
already supported excluding non-blobs, it was just unfortunately
named. Perhaps I'm conflating that with the protocol payload for
packfile-uri, which I know doesn't only support excluding blobs.
What we didn't support at all was a way to have the server-side
mechanism in git.git recursively exclude anything, which I think is what
you're adding here...
@@ -1403,7 +1411,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset)){+if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_commit)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -1429,7 +1437,7 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,if(have_duplicate_entry(oid,0))return0;-if(!want_object_in_pack(oid,0,&pack,&offset))+if(!want_object_in_pack(oid,0,&pack,&offset,NULL))return0;create_object_entry(oid,type,name_hash,0,0,pack,offset);
@@ -3007,11 +3015,11 @@ static int git_pack_config(const char *k, const char *v, void *cb)*oid_end!=' '||parse_oid_hex(oid_end+1,&pack_hash,&pack_end)||*pack_end!=' ')-die(_("value of uploadpack.blobpackfileuri must be "+die(_("value of uploadpack.excludeobject or uploadpack.blobpackfileuri must be ""of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);if(oidmap_get(&configured_exclusions,&ex->e.oid))-die(_("object already configured in another "-"uploadpack.blobpackfileuri (got '%s')"),v);+die(_("object already configured by an earlier "+"uploadpack.excludeobject or uploadpack.blobpackfileuri (got '%s')"),v);ex->pack_hash_hex=xcalloc(1,pack_end-oid_end);memcpy(ex->pack_hash_hex,oid_end+1,pack_end-oid_end-1);ex->uri=xstrdup(pack_end+1);
@@ -3040,7 +3048,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;ofs=nth_packed_object_offset(p,pos);-if(!want_object_in_pack(oid,0,&p,&ofs))+if(!want_object_in_pack(oid,0,&p,&ofs,NULL))return0;oi.typep=&type;
@@ -3841,7 +3850,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)N_("respect islands during delta compression")),OPT_STRING_LIST(0,"uri-protocol",&uri_protocols,N_("protocol"),-N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),+N_("exclude any configured uploadpack.excludeobject or "+"uploadpack.blobpackfileuri with this protocol")),OPT_END(),};
@@ -326,20 +327,35 @@ static void add_pending_object_with_path(struct rev_info *revs,strbuf_release(&buf);return;/* do not add the commit itself */}-add_object_array_with_path(obj,name,&revs->pending,mode,path);+add_object_array_with_path_and_referred_commit(obj,name,&revs->pending,mode,path,referred_commit);}+staticvoidadd_pending_object_with_path(structrev_info*revs,+structobject*obj,+constchar*name,unsignedmode,+constchar*path)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,path,NULL);+}staticvoidadd_pending_object_with_mode(structrev_info*revs,structobject*obj,-constchar*name,unsignedmode)+constchar*name,unsignedmode,+structobject*referred_commit)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,NULL,referred_commit);+}++voidadd_pending_object_with_referred_commit(structrev_info*revs,+structobject*obj,constchar*name,+structobject*referred_commit){-add_pending_object_with_path(revs,obj,name,mode,NULL);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,referred_commit);}voidadd_pending_object(structrev_info*revs,structobject*obj,constchar*name){-add_pending_object_with_mode(revs,obj,name,S_IFINVALID);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,NULL);}voidadd_head_to_pending(structrev_info*revs)
@@ -2817,7 +2833,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct sif(get_oid_with_context(revs->repo,revs->def,0,&oid,&oc))diagnose_missing_default(revs->def);object=get_reference(revs,revs->def,&oid,0);-add_pending_object_with_mode(revs,object,revs->def,oc.mode);+add_pending_object_with_mode(revs,object,revs->def,oc.mode,NULL);}/* Did the user ask for any diff output? Run the diff! */
@@ -65,9 +78,6 @@ The protocol design allows some evolution of the server and client without any need for protocol changes, so only a small-scoped design is included here to form the MVP. For example, the following can be done:- * On the server, more sophisticated means of excluding objects (e.g. by- specifying a commit to represent that commit and all objects that it- references). * On the client, resumption of clone. If a clone is interrupted, information could be recorded in the repository's config and a "clone-resume" command can resume the clone in progress. (Resumption of subsequent fetches is more
@@ -78,4 +88,4 @@ There are some possible features that will require a change in protocol: * Additional HTTP headers (e.g. authentication) * Byte range support- * Different file formats referenced by URIs (e.g. raw object)+ * Different file formats referenced by URIs (e.g. raw object)
On Wed, Aug 25 2021, Teng Long wrote:
Thanks, much needed cleanup. I have an unsubmitted patch to do pretty
much this, plus some: https://github.com/avar/git/commit/27b3543c6ed
You might find the difference between the two interesting..
From: Teng Long <hidden> Date: 2021-09-02 11:37:52
Thanks, much needed cleanup. I have an unsubmitted patch to do pretty
much this, plus some: https://github.com/avar/git/commit/27b3543c6ed
You might find the difference between the two interesting..
Cool.
I had took a look at the commit. In comparision, I ignored some places that need
to cleanup, I don't know if I got your meaning?
If so, how to deal with this situation better, continue my work or rebase your commit
to the current patchset?
From: Teng Long <hidden> Date: 2021-09-02 12:17:23
Ævar Arnfjörð Bjarmason wrote:
Can't we store this info on the side between these two static functions
somehow, instead of adding this "wraps" to all commit structs?
Thanks very much and I have some doubts.
... instead of adding this "wraps" to all commit structs?
I think "adding this "wraps" to all commit struct" is an easy but a little
rough indeed. I didn't know if this is okay at the time. So I pushed the patch,
hoping to ask some different opinions.
Can't we store this info on the side between these two static functions...
Do you mean to use static storage to share the "wraps", or other way? I want to make
sure that I understand your opinion accurately.
Thank you.
From: Teng Long <hidden> Date: 2021-09-02 12:26:52
Ævar Arnfjörð Bjarmason wrote:
I was under the impression that with uploadpack.blobpackfileuri we
already supported excluding non-blobs, it was just unfortunately
named. Perhaps I'm conflating that with the protocol payload for
packfile-uri, which I know doesn't only support excluding blobs.
What we didn't support at all was a way to have the server-side
mechanism in git.git recursively exclude anything, which I think is what
you're adding here...
Agree.
You are absolutely right(ಥ_ಥ ). The description of the commit is inaccurate, I will
fix this problem in the next patch.
Thank you.
From: Teng Long <hidden> Date: 2021-10-19 11:39:03
About This Patch:
-----------------
This patch has almost no reuse of previous patch's commits, because this
one redesigned the exclusion for various object types and reoganized the
commits.
Commit (1): objects.c: introduce `exclude_level` enum
This commit introduce a new enum named `exclude_level` in object.c, it
contains three enumerated values: "ET_SELF", "ET_INCLUDE" and
"ET_REACHABLE". The commit only makes the definitions, without any
implementations.
Commit (2): Introduce function `match_packfile_uri_exclusions`
This one move the codes used for matching the URI protocols from
`want_found_object` to new function `match_packfile_uri_exclusions`. The
purpose is to improve code readability related to the feature and make
preparation for further extension about the matching and exclusion for
multiple object types.
Commit (3): Replace `show_data` with structure `show_info`
There is no feature related codes in this commit. This commit modified
the parameters in function `show_object` by replacing `show_data` with a
new structure `show_info`, this is another way of implementation about
the previous commit[1] in patch v5.
Commit (4): Introduce `uploadpack.excludeobject` configuration
This commit introduce a new and backward-compatible configuration named
`uploadpack.excludeobject`, the diff between old and new:
uploadpack.blobPackfileUri=<object-hash> <pack-hash> <uri>
uploadpack.excludeobject=<object-hash> <level> <pack-hash> <uri>
The <level> is correspond to the exclusion scope of the given object,
and it's mentioned as `exclude_value` in object.c by "Commit (1)".
Commit (6,8,10): Implementations for excluding commits, trees and tags
Commit (7,9,11): Tests for excluding excluding commits, trees and tags
Commit (12): Corresponding documentation modifications
bundle-uri And packfile-uri
----------------------------
Ævar Arnfjörð Bjarmason post a new feature patchset[2] named "bundle-uri",
it supports to let client download the full or incremental bundles
directly without any negotiations with the server (full clone first and
in a MVP progress now). I'm sorry if I misleading the meanings and
please point it out.
In "packfile-uri", different with "bundle-uri", happens in the span of
packing objects during git-upload-pack on the server. This is an
experimental feature, originally designed as a CDN for large BLOB
objects, but it's not yet fully functional. I'm currently working on it
for making it support other types of objects.
I also noticed that some opinions about the two features are mentioned
in the patch[2], so I cc to Stolee in this patch, I hope I did not
disturb you.
[1] https://public-inbox.org/git/xmqqlf4oc4u1.fsf@gitster.g/
[2] https://lore.kernel.org/git/RFC-cover-00.13-0000000000-20210805T150534Z-avarab@gmail.com/
Teng Long (12):
objects.c: introduce `exclude_level` enum
Introduce function `match_packfile_uri_exclusions`
Replace `show_data` with structure `show_info`
Introduce `uploadpack.excludeobject` configuration
t5702: test cases for `uploadpack.excludeobject`
packfile-uri: support for excluding commits
t5702: test cases for excluding commits
packfile-uri: support for excluding trees
t5702: test cases for excluding trees
packfile-uri: support for excluding tags
t5702: test cases for excluding tags
packfile-uri.txt: support multiple object types
Documentation/technical/packfile-uri.txt | 74 +-
builtin/describe.c | 9 +-
builtin/pack-objects.c | 236 +++++--
builtin/rev-list.c | 11 +-
bundle.c | 5 +-
list-objects.c | 74 +-
list-objects.h | 11 +-
object.c | 21 +-
object.h | 16 +-
pack-bitmap.c | 16 +-
reachable.c | 11 +-
revision.c | 47 +-
revision.h | 12 +
shallow.c | 4 +-
t/t5702-protocol-v2.sh | 856 +++++++++++++++++++++--
upload-pack.c | 7 +
16 files changed, 1253 insertions(+), 157 deletions(-)
Range-diff against v5:
1: 3a885678c9 = 1: 3a885678c9 objects.c: introduce `exclude_level` enum
2: 36426b4d9f = 2: 36426b4d9f Introduce function `match_packfile_uri_exclusions`
3: dced036f89 = 3: dced036f89 Replace `show_data` with structure `show_info`
4: b1d779b26a = 4: b1d779b26a Introduce `uploadpack.excludeobject` configuration
5: f643db3c71 = 5: f643db3c71 t5702: test cases for `uploadpack.excludeobject`
6: c29efeac21 = 6: c29efeac21 packfile-uri: support for excluding commits
7: ca72efd22e = 7: ca72efd22e t5702: test cases for excluding commits
8: c7a885ebec = 8: c7a885ebec packfile-uri: support for excluding trees
9: 5fc79a9a32 = 9: 5fc79a9a32 t5702: test cases for excluding trees
10: 16c41c40a2 = 10: 16c41c40a2 packfile-uri: support for excluding tags
11: 171ece533b = 11: 171ece533b t5702: test cases for excluding tags
12: 79fc2c23cf = 12: 79fc2c23cf packfile-uri.txt: support multiple object types
--
2.31.1.453.g945ddc3a74.dirty
From: Teng Long <hidden> Date: 2021-10-19 11:39:12
From: Teng Long <redacted>
Currently packfile-uri supports the exclusion of blob objects, but
in some scenarios, users may wish to exclude more types of objects,
such as commits, trees and tags, the difference with blob is they are
more complicated. In addition to the meaning of a single object itself,
it may also represent a collection of the objects that it includes
(trees and blob in a root-tree) or reaches (ancestors of a commit).
The exclusion range is designed by an enum named `exclude_level` in
"pack-objects.c" that enumerate three values, "ET_SELF", "ET_INCLUDE"
and "ET_REACHABLE".
Here are some explanations for their differences:
- Scene 1: "ET_SELF" for excluding object itself.
Reason to support the "ET_SELF" is because the definition of
exclusion-level should be better to be consistent, no matter what
the object type is. Excluding a single object itself has meaning for
blobs, because blob is the smallest granularity among object types, and
indeed, sometimes there are some frequently used big-size blobs in
repository.
If you want to exclude more ownership or reachable objects, it can be
considered to use "ET_INCLUDE" or "ET_REACHABLE".
- Scene 2: "ET_INCLUDE" for excluding object itself and objects it
contains.
When a commit is specified to be excluded as packfile-uri,
more offen, it's hoped to exclude the trees and blobs contained in
its top-level tree, as well as the commit itself, but not the
ancestors of the commit. This applies to scenarios where we want to
exclude a specified non-blob object that includes some big-size
objects.
Commit, tag and tree are suitable for this scenario. When a tag
is specified, it will exclude the dereference commit, and all trees and
blobs contained in its top-tree, as well as the tag itself if it's not a
lightweight one.
- Scene 3: "ET_REACHABLE" for excluding object itself, all the objects
it contains, and its ancestors.
For further exclusion range, the ancestors are needed to excluded
together, for example, the clone scenes.
This commit only defines the `exclude_level` enum type. The implementations
of non-blob object types will be added in subsequent commits.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 44 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
From: Teng Long <hidden> Date: 2021-10-19 11:39:15
From: Teng Long <redacted>
The matching codes now placed in function `want_object_in_pack`, move it
to a new function `match_packfile_uri_exclusions` to prevent subsequent
modifications caused by its continuing expansion.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)
From: Teng Long <hidden> Date: 2021-10-19 11:39:21
From: Teng Long <redacted>
During the pack-objects process, "show_object" function will be called
to find and show the object the function contains three parameters:
1. struct object *obj
2. const char *name
3. void *show_data
This commit replace "show_data" with with a new structure `show_info`,
it has two members:
1. void *show_data
2. void *show_cache
The `show_data` in `show_info `is the same purpose with the original
one, is the callback when showing the objects.
The `show_cache` is the cache that ownership the relationship data.
It stores around the extra data for showing the objects, for example,
carry the ownership relationship between blob or tree objects and the
referred commit to avoid redundant and expensive calculations.
Signed-off-by: Teng Long <redacted>
---
builtin/describe.c | 9 +++++----
builtin/pack-objects.c | 23 +++++++++++++----------
builtin/rev-list.c | 11 ++++++-----
bundle.c | 5 +++--
list-objects.c | 29 +++++++++++++++++++++++------
list-objects.h | 11 ++++++++---
pack-bitmap.c | 16 +++++++++-------
reachable.c | 11 +++++++----
shallow.c | 4 ++--
9 files changed, 76 insertions(+), 43 deletions(-)
@@ -3106,13 +3106,13 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;}-staticvoidshow_commit_pack_hint(structcommit*commit,void*_data)+staticvoidshow_commit_pack_hint(structcommit*commit,structshow_info*info){/* nothing to do; commits don't have a namehash */}staticvoidshow_object_pack_hint(structobject*object,constchar*name,-void*_data)+structshow_info*info){structobject_entry*oe=packlist_find(&to_pack,&object->oid);if(!oe)
@@ -3284,7 +3284,7 @@ static void read_object_list_from_stdin(void)/* Remember to update object flag allocation in object.h */#define OBJECT_ADDED (1u<<20)-staticvoidshow_commit(structcommit*commit,void*data)+staticvoidshow_commit(structcommit*commit,structshow_info*info){add_object_entry(&commit->object.oid,OBJ_COMMIT,NULL,0);commit->object.flags|=OBJECT_ADDED;
@@ -5,9 +5,14 @@ struct commit;structobject;structrev_info;-typedefvoid(*show_commit_fn)(structcommit*,void*);-typedefvoid(*show_object_fn)(structobject*,constchar*,void*);-voidtraverse_commit_list(structrev_info*,show_commit_fn,show_object_fn,void*);+structshow_info{+void*show_data;/* the data necessary for showing the object */+void*show_cache;/* the cache ownership relationship data for showing the object */+};++typedefvoid(*show_commit_fn)(structcommit*,structshow_info*);+typedefvoid(*show_object_fn)(structobject*,constchar*,structshow_info*);+voidtraverse_commit_list(structrev_info*,show_commit_fn,show_object_fn,void*show_data);typedefvoid(*show_edge_fn)(structcommit*);voidmark_edges_uninteresting(structrev_info*revs,
@@ -230,6 +231,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,return;}+/**Setuptherevisionwalk-thiswillmoveallcommits*fromthependinglisttothecommitwalkinglist.
@@ -244,6 +246,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,die("unable to mark recent objects");if(prepare_revision_walk(revs))die("revision walk setup failed");+traverse_commit_list(revs,mark_commit,mark_object,&cp);}
From: Teng Long <hidden> Date: 2021-10-19 11:39:24
From: Teng Long <redacted>
Background:
The `uploadpack.blobpackfileuri` is made for the "packfile-uri" feature,
the feature is similar to a CDN cache, it supports the client to download
pack file by a URI directly, without or reducing the server load when make
packing and transporting.
Reasons:
First reason, `uploadpack.blobpackfileuri` supports to exclude a single
object, but actually the object type can be not only a blob, so the name
is inaccurate currently.
Secondly, the name of the old configuration is not abstract enough, this
make the furthur extension difficult. If do not change its name, to let
different object types use different configuration names, the
configuration items will be bloated and difficult to maintain, so the
new configuration is more abstract in name.
Configuation format diff:
old: uploadpack.blobPackfileUri=<object-hash> <pack-hash> <uri>
new: uploadpack.excludeobject=<object-hash> <level> <pack-hash> <uri>
The new configuration `uploadpack.excludeobject` not only supports to
exclude a single object itself, but also to exclude related objects with
it at once, the scope of exclusion is determined by the object type and
the specified `<level>` value in the entry.
-Compatibility:
Although a new configuration has been introduced, the old one is
available to use and compatible with the new configuration.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 33 ++++++++++++++++++++++++++++++++-
upload-pack.c | 7 +++++++
2 files changed, 39 insertions(+), 1 deletion(-)
@@ -3061,6 +3061,36 @@ static int git_pack_config(const char *k, const char *v, void *cb)ex->uri=xstrdup(pack_end+1);oidmap_put(&configured_exclusions,ex);}+if(!strcmp(k,"uploadpack.excludeobject")){+structconfigured_exclusion*ex=xmalloc(sizeof(*ex));+constchar*oid_end,*pack_end,*type_end;+structobject_idpack_hash;+chartype[2];+intlevel;++if(parse_oid_hex(v,&ex->e.oid,&oid_end)||+*oid_end!=' '||+!strlcpy(type,oid_end+1,sizeof(type))||+parse_oid_hex(oid_end+3,&pack_hash,&pack_end)||+*pack_end!=' ')+die(_("value of uploadpack.excludeobject must be "+"of the form '<object-hash> <level> <pack-hash> <uri>' (got '%s')"),v);+if(oidmap_get(&configured_exclusions,&ex->e.oid))+die(_("object already configured by an earlier "+"uploadpack.excludeobject (got '%s')"),v);++level=atoi(type);+if(level<ET_SELF||level>ET_REACHABLE){+die(_("value of <level> must be 0 or 1 or 2 (got '%s')"),v);+}+ex->level=level;+type_end=oid_end+2;+ex->pack_hash_hex=xcalloc(1,pack_end-type_end);+memcpy(ex->pack_hash_hex,type_end+1,pack_end-type_end-1);+ex->uri=xstrdup(pack_end+1);+oidmap_put(&configured_exclusions,ex);+}+returngit_default_config(k,v,cb);}
@@ -3887,7 +3917,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)N_("respect islands during delta compression")),OPT_STRING_LIST(0,"uri-protocol",&uri_protocols,N_("protocol"),-N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),+N_("exclude any configured uploadpack.excludeobject or "+"uploadpack.blobpackfileuri with this protocol")),OPT_END(),};
From: Teng Long <hidden> Date: 2021-10-19 11:39:27
This commit expends the function `configure_exclusion` to support new
excluding type: commit, tree and tag.
Signed-off-by: Teng Long <redacted>
---
t/t5702-protocol-v2.sh | 146 +++++++++++++++++++++++++++--------------
1 file changed, 98 insertions(+), 48 deletions(-)
@@ -824,17 +824,63 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '' configure_exclusion(){-git-C"$1"hash-object"$2">objh&&-git-C"$1"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&-git-C"$1"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-catobjh+objt="$1"+P="$2"+oid="$3"+version="$4"+excluding_type="$5"++oldc="uploadpack.blobpackfileuri"+newc="uploadpack.excludeobject"+configkey=""++iftest"$version"="old"+then+configkey="$oldc"+else+configkey="$newc"+fi++iftest"$objt"="blob"+then+excluding_type="0"+git-C"$P"hash-object"$oid">objh&&+git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&+iftest"$version"="old"+then+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"+else+git-C"$P"config--add\+"$configkey"\+"$(catobjh)$excluding_type$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"+fi&&+catobjh+eliftest"$objt"="commit"||test"$objt"="tree"||test"$objt"="tag"+then+echo"$oid">objh&&+iftest"$excluding_type"="0"+then+git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh+else+git-C"$P"pack-objects--revs"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh+fi&&++git-C"$P"config--add\+"$configkey"\+"$(catobjh)$excluding_type$(catpackh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&+catobjh+else+echo"unsupported object type in configure_exclusion (got $objt)"+fi}-test_expect_success'part of packfile response provided as URI''+part_of_packfile_response_verify(){++config="$1"&&P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -843,10 +889,10 @@ test_expect_success 'part of packfile response provided as URI' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&-configure_exclusion"$P"other-blob>h2&&+configure_exclusionblob"$P"my-blob"$config">h&&+configure_exclusionblob"$P"other-blob"$config">h2&&GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\
@@ -879,20 +925,22 @@ test_expect_success 'part of packfile response provided as URI' 'lshttp_child/.git/objects/pack/*.pack\http_child/.git/objects/pack/*.idx>filelist&&test_line_count=6filelist-'+}++blobpackfileuri_fetch(){+config="$1"-test_expect_success'packfile URIs with fetch instead of clone''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&+test_commit-C"$P"A&&-configure_exclusion"$P"my-blob>h&&+configure_exclusionblob"$P"my-blob$config>h&&gitinithttp_child&&
@@ -900,12 +948,28 @@ test_expect_success 'packfile URIs with fetch instead of clone' 'git-Chttp_child-cprotocol.version=2\-cfetch.uriprotocols=http,https\fetch"$HTTPD_URL/smart/http_parent"+}++test_expect_success'blob-exclusion (using uploadpack.blobpackfileuri): part of packfile response provided as URI''+rm-rf"$HTTPD_DOCUMENT_ROOT_PATH/http_parent"http_childlog&&+part_of_packfile_response_verifyold+'++test_expect_success'blob-exclusion (using uploadpack.excludeobject): part of packfile response provided as URI''+part_of_packfile_response_verifynew+'++test_expect_success'blob-exclusion (using uploadpack.blobpackfileuri): packfile URIs with fetch instead of clone''+blobpackfileuri_fetchold+'++test_expect_success'blob-exclusion (using uploadpack.excludeobject): packfile URIs with fetch instead of clone''+blobpackfileuri_fetchnew' test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&-+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -913,9 +977,8 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"addmy-blob&&echoother-blob>"$P/other-blob"&&git-C"$P"addother-blob&&-git-C"$P"commit-mx&&--configure_exclusion"$P"my-blob>h&&+test_commit-C"$P"A&&+configure_exclusionblob"$P"my-blob>h&&# Configure a URL for other-blob. Just reuse the hash of the object as# the hash of the packfile, since the hash does not matter for this# test as long as it is not the hash of the pack, and it is of the
@@ -923,9 +986,8 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' 'git-C"$P"hash-objectother-blob>objh&&git-C"$P"pack-objects"$HTTPD_DOCUMENT_ROOT_PATH/mypack"<objh>packh&&git-C"$P"config--add\-"uploadpack.blobpackfileuri"\-"$(catobjh)$(catobjh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&-+"uploadpack.excludeobject"\+"$(catobjh) 0 $(catobjh)$HTTPD_URL/dumb/mypack-$(catpackh).pack"&&test_must_failenvGIT_TEST_SIDEBAND_ALL=1\git-cprotocol.version=2\-cfetch.uriprotocols=http,https\
@@ -935,17 +997,14 @@ test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' test_expect_success'packfile-uri with transfer.fsckobjects''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&-+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&--configure_exclusion"$P"my-blob>h&&-+test_commit-C"$P"A&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\-cfetch.uriprotocols=http,https\
@@ -959,8 +1018,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects' ' test_expect_success'packfile-uri with transfer.fsckobjects fails on bad object''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childlog&&-+test_when_finished"rm -rf \"$P\" http_child log"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -976,10 +1034,8 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object'echomy-blob>"$P/my-blob"&&git-C"$P"addmy-blob&&-git-C"$P"commit-mx&&--configure_exclusion"$P"my-blob>h&&-+test_commit-C"$P"A&&+configure_exclusionblob"$P"my-blob>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\-cfetch.uriprotocols=http,https\
@@ -989,8 +1045,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object' test_expect_success'packfile-uri with transfer.fsckobjects succeeds when .gitmodules is separate from tree''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_child&&-+test_when_finished"rm -rf \"$P\" http_child"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -999,9 +1054,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmoecho"url = git://example.com/git/lib.git">>"$P/.gitmodules"&&git-C"$P"add.gitmodules&&git-C"$P"commit-mx&&--configure_exclusion"$P".gitmodules>h&&-+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&git-cprotocol.version=2-ctransfer.fsckobjects=1\-cfetch.uriprotocols=http,https\
@@ -1015,8 +1068,7 @@ test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmo test_expect_success'packfile-uri with transfer.fsckobjects fails when .gitmodules separate from tree is invalid''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&-rm-rf"$P"http_childerr&&-+test_when_finished"rm -rf \"$P\" http_child err"&&gitinit"$P"&&git-C"$P"config"uploadpack.allowsidebandall""true"&&
@@ -1024,10 +1076,8 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodulecho"path = include/foo">>"$P/.gitmodules"&&echo"url = git://example.com/git/lib.git">>"$P/.gitmodules"&&git-C"$P"add.gitmodules&&-git-C"$P"commit-mx&&--configure_exclusion"$P".gitmodules>h&&-+test_commit-C"$P"A&&+configure_exclusionblob"$P".gitmodules>h&&sane_unsetGIT_TEST_SIDEBAND_ALL&&test_must_failgit-cprotocol.version=2-ctransfer.fsckobjects=1\-cfetch.uriprotocols=http,https\
@@ -1038,4 +1088,4 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodul# DO NOT add non-httpd-specific tests here, because the last part of this# test script is only executed when httpd is available and enabled.-test_done+test_done
\ No newline at end of file
--
2.31.1.453.g945ddc3a74.dirty
From: Teng Long <hidden> Date: 2021-10-19 11:40:00
From: Teng Long <redacted>
This commit work on the exlusion of commit objects, and the
Its excluding `level` can be configured as "ET_SELF", "ET_INCLUDE"
or "ET_REACHABLE".
Exclusion scope on different level:
1. When a commit is specified to be excluded with level "ET_SELF", only the
commit object itself will be excluded.
2. When it's specified to be excluded with level "ET_INCLUDE", exclude
all trees and blobs contained in its top-level tree, as well as the
commit itself.
3. When it is specified with level "ET_REACHABLE", exclude its
ancestors, as well as the objects need to be excluded under the level
"ET_INCLUDED".
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 83 +++++++++++++++++++++++++++++++++---------
list-objects.c | 37 +++++++++++--------
object.c | 19 ++++++++--
object.h | 14 ++++++-
revision.c | 34 ++++++++++++-----
revision.h | 3 ++
6 files changed, 144 insertions(+), 46 deletions(-)
@@ -1446,7 +1458,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,if(have_duplicate_entry(oid,exclude))return0;-if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset)){+if(!want_object_in_pack(oid,exclude,&found_pack,&found_offset,referred_objs)){/* The pack is missing an object, so it will not have closure */if(write_bitmap_index){if(write_bitmap_index!=WRITE_BITMAP_QUIET)
@@ -1472,7 +1484,7 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,if(have_duplicate_entry(oid,0))return0;-if(!want_object_in_pack(oid,0,&pack,&offset))+if(!want_object_in_pack(oid,0,&pack,&offset,NULL))return0;create_object_entry(oid,type,name_hash,0,0,pack,offset);
@@ -2882,7 +2894,7 @@ static void add_tag_chain(const struct object_id *oid)die(_("unable to pack objects reachable from tag %s"),oid_to_hex(oid));-add_object_entry(&tag->object.oid,OBJ_TAG,NULL,0);+add_object_entry(&tag->object.oid,OBJ_TAG,NULL,0,NULL);if(tag->tagged->type!=OBJ_TAG)return;
@@ -3050,8 +3062,6 @@ static int git_pack_config(const char *k, const char *v, void *cb)*oid_end!=' '||parse_oid_hex(oid_end+1,&pack_hash,&pack_end)||*pack_end!=' ')-die(_("value of uploadpack.blobpackfileuri must be "-"of the form '<object-hash> <pack-hash> <uri>' (got '%s')"),v);if(oidmap_get(&configured_exclusions,&ex->e.oid))die(_("object already configured in another ""uploadpack.blobpackfileuri (got '%s')"),v);
@@ -3114,7 +3124,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,return0;ofs=nth_packed_object_offset(p,pos);-if(!want_object_in_pack(oid,0,&p,&ofs))+if(!want_object_in_pack(oid,0,&p,&ofs,NULL))return0;oi.typep=&type;
@@ -326,20 +327,35 @@ static void add_pending_object_with_path(struct rev_info *revs,strbuf_release(&buf);return;/* do not add the commit itself */}-add_object_array_with_path(obj,name,&revs->pending,mode,path);+add_object_array_with_path_and_referred_commit(obj,name,&revs->pending,mode,path,referred_commit);}+staticvoidadd_pending_object_with_path(structrev_info*revs,+structobject*obj,+constchar*name,unsignedmode,+constchar*path)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,path,NULL);+}staticvoidadd_pending_object_with_mode(structrev_info*revs,structobject*obj,-constchar*name,unsignedmode)+constchar*name,unsignedmode,+structcommit*referred_commit)+{+add_pending_object_with_path_and_referred_commit(revs,obj,name,mode,NULL,referred_commit);+}++voidadd_pending_object_with_referred_commit(structrev_info*revs,+structobject*obj,constchar*name,+structcommit*referred_commit){-add_pending_object_with_path(revs,obj,name,mode,NULL);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,referred_commit);}voidadd_pending_object(structrev_info*revs,structobject*obj,constchar*name){-add_pending_object_with_mode(revs,obj,name,S_IFINVALID);+add_pending_object_with_mode(revs,obj,name,S_IFINVALID,NULL);}voidadd_head_to_pending(structrev_info*revs)
@@ -2817,7 +2833,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct sif(get_oid_with_context(revs->repo,revs->def,0,&oid,&oc))diagnose_missing_default(revs->def);object=get_reference(revs,revs->def,&oid,0);-add_pending_object_with_mode(revs,object,revs->def,oc.mode);+add_pending_object_with_mode(revs,object,revs->def,oc.mode,NULL);}/* Did the user ask for any diff output? Run the diff! */
@@ -967,6 +967,306 @@ test_expect_success 'blob-exclusion (using uploadpack.excludeobject): packfile Ublobpackfileuri_fetchnew'+test_expect_success'commit-exclusion(excluding_type=ET_SELF): part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&+excluding_type="0"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/my-tree/sub-tree&&+echosub-blob>"$P"/my-tree/sub-tree/sub-blob&&+git-C"$P"addmy-tree&&+test_commit-C"$P"A&&+commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADmy-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+ah=$(git-C"$P"hash-objectA.t)&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+subblobh=$(git-C"$P"hash-objectmy-tree/sub-tree/sub-blob)&&+configure_exclusioncommit"$P""$commith"new"$excluding_type">h&&+GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child+'++test_expect_success'commit-exclusion(excluding_type=ET_INCLUDE): part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&+excluding_type="1"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/my-tree/sub-tree&&+echosub-blob>"$P"/my-tree/sub-tree/sub-blob&&+git-C"$P"addmy-tree&&+test_commit-C"$P"A&&+commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADmy-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+ah=$(git-C"$P"hash-objectA.t)&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+subblobh=$(git-C"$P"hash-objectmy-tree/sub-tree/sub-blob)&&+configure_exclusioncommit"$P""$commith"new"$excluding_type">h&&+GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=7out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi&&+ifgrep$subtreehout+then+>subtreehfound+fi&&+ifgrep$subblobhout+then+>subblobhfound+fi+fi+done&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fsubtreehfound&&+test-fsubblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&+# Ensure that there are exactly 2 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist+'++test_expect_success'commit-exclusion(excluding_type=ET_REACHABLE): hitten a full packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&+excluding_type="2"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+test_commit-C"$P"A&&+commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+ah=$(git-C"$P"hash-objectA.t)&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+configure_exclusioncommit"$P""$commith"new"$excluding_type">h&&+GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=5out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi+eliftest_line_count=0out.objectlist+then+>emptypackfound+fi+done&&+test-femptypackfound&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&+# Ensure that there are exactly 2 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist+'++test_expect_success'commit-exclusion(excluding_type=ET_REACHABLE): part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&+excluding_type="2"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+test_commit-C"$P"A&&+mkdir"$P"/other-tree&&+echoother-blob>"$P"/other-tree/other-blob&&+git-C"$P"addother-tree&&+test_commit-C"$P"B&&+ah=$(git-C"$P"hash-objectA.t)&&+bh=$(git-C"$P"hash-objectB.t)&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+otherblobh=$(git-C"$P"hash-objectother-tree/other-blob)&&+rm-rf"$P"/my-tree"$P"/other-tree"$P"/A.t"$P"/B.t&&+mkdir"$P"/another-tree&&+echoanother-blob>"$P"/another-tree/another-blob&&+git-C"$P"add.&&+test_commit-C"$P"C&&+commitAh=$(git-C"$P"rev-parseA)&&+commitBh=$(git-C"$P"rev-parseB)&&+commitCh=$(git-C"$P"rev-parseC)&&+roottreeAh=$(git-C"$P"rev-parseA:)&&+roottreeBh=$(git-C"$P"rev-parseB:)&&+roottreeCh=$(git-C"$P"rev-parseC:)&&+mytreeh=$(git-C"$P"ls-treeAmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+othertreeh=$(git-C"$P"ls-treeBother-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+anothertreeh=$(git-C"$P"ls-treeCanother-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+ch=$(git-C"$P"hash-objectC.t)&&+anotherblobh=$(git-C"$P"hash-objectanother-tree/another-blob)&&+configure_exclusioncommit"$P""$commitBh"new"$excluding_type">h&&+GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=5out.objectlist+then+ifgrep$commitChout+then+>commitChfound+fi&&+ifgrep$roottreeChout+then+>roottreeChfound+fi&&+ifgrep$anothertreehout+then+>anothertreehfound+fi&&+ifgrep$anotherblobhout+then+>anotherblobhfound+fi&&+ifgrep$chout+then+>chfound+fi+eliftest_line_count=10out.objectlist+then+ifgrep$commitAhout+then+>commitAhfound+fi&&+ifgrep$commitBhout+then+>commitBhfound+fi&&+ifgrep$roottreeAhout+then+>roottreeAhfound+fi&&+ifgrep$roottreeBhout+then+>roottreeBhfound+fi&&+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$othertreehout+then+>othertreehfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi&&+ifgrep$otherblobhout+then+>otherblobhfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$bhout+then+>bhfound+fi+fi+done&&+test-fcommitChfound&&+test-froottreeChfound&&+test-fanothertreehfound&&+test-fanotherblobhfound&&+test-fchfound&&+test-fcommitAhfound&&+test-fcommitBhfound&&+test-froottreeAhfound&&+test-froottreeBhfound&&+test-fmytreehfound&&+test-fothertreehfound&&+test-fmyblobhfound&&+test-fotherblobhfound&&+test-fahfound&&+test-fbhfound&&+# Ensure that there are exactly 2 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist+'+ test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_when_finished"rm -rf \"$P\" http_child log"&&
From: Teng Long <hidden> Date: 2021-10-19 11:40:06
From: Teng Long <redacted>
This commit introduce the exclusion of tree objects. The exclusion range
is designed by an enum named `exclude_level` in "pack-objects.c" that
enumerate three values, "ET_SELF", "ET_INCLUDE" and "ET_REACHABLE".
Exclusion scope on different level:
1. When a tree is specified to be excluded with level "ET_SELF",
only the tree object itself will be excluded.
2. When a tree specified to be excluded with level "ET_INCLUDE",
exclude the tree itself, as well as all the trees and blobs it contains.
3. When it is specified with level "ET_REACHABLE", the excluding scope
is as same as level "ET_INCLUDE", because tree do not have any
ancestors.
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 18 ++++++++++++++++++
list-objects.c | 8 ++++++--
object.c | 1 +
object.h | 1 +
4 files changed, 26 insertions(+), 2 deletions(-)
@@ -1267,6 +1267,219 @@ test_expect_success 'commit-exclusion(excluding_type=ET_REACHABLE): part of packtest_line_count=4filelist'+test_expect_success'tree-exclusion(excluding_type=ET_SELF): part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&+excluding_type="0"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+# Dir struct+# .+# |-- A.t+# |-- my-tree+# | `-- my-blob+# `-- other-tree+# |-- other-blob+# `-- sub-tree+# `-- sub-blob+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/other-tree&&+echoother-blob>"$P"/other-tree/other-blob&&+mkdir"$P"/other-tree/sub-tree&&+echosub-blob>"$P"/other-tree/sub-tree/sub-blob&&+git-C"$P"addother-tree&&+test_commit-C"$P"A&&+commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+ah=$(git-C"$P"hash-objectA.t)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+othertreeh=$(git-C"$P"ls-treeHEADother-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADother-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+otherblobh=$(git-C"$P"hash-objectother-tree/other-blob)&&+subblobh=$(git-C"$P"hash-objectother-tree/sub-tree/sub-blob)&&++configure_exclusiontree"$P""$mytreeh"new0>h&&+configure_exclusiontree"$P""$othertreeh"new0>h2&&++GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&+# Ensure that my-tree and other-tree and theirs complementary set are in separate packfiles.+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=1out.objectlist+then+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$othertreehout+then+>othertreehfound+fi+eliftest_line_count=7out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$subtreehout+then+>subtreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi&&+ifgrep$otherblobhout+then+>otherblobhfound+fi&&+ifgrep$subblobhout+then+>subblobhfound+fi+fi+done&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fothertreehfound&&+test-fotherblobhfound&&+test-fsubtreehfound&&+test-fsubblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&+# Ensure that there are exactly 3 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=6filelist+'++test_expect_success'tree-exclusion(excluding_type=ET_INCLUDE), part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log *found"&&+excluding_type="1"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+# Dir struct+# .+# |-- A.t+# |-- my-tree+# | `-- my-blob+# `-- other-tree+# |-- other-blob+# `-- sub-tree+# `-- sub-blob+mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+mkdir"$P"/other-tree&&+echoother-blob>"$P"/other-tree/other-blob&&+mkdir"$P"/other-tree/sub-tree&&+echosub-blob>"$P"/other-tree/sub-tree/sub-blob&&+git-C"$P"addother-tree&&+test_commit-C"$P"A&&++commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+ah=$(git-C"$P"hash-objectA.t)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+othertreeh=$(git-C"$P"ls-treeHEADother-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+subtreeh=$(git-C"$P"ls-treeHEADother-tree/sub-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+otherblobh=$(git-C"$P"hash-objectother-tree/other-blob)&&+subblobh=$(git-C"$P"hash-objectother-tree/sub-tree/sub-blob)&&++configure_exclusiontree"$P""$mytreeh"new$excluding_type>h&&+configure_exclusiontree"$P""$othertreeh"new$excluding_type>h2&&++GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&+# Ensure that my-tree and other-tree and theirs complementary set are in separate packfiles.+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=3out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi+eliftest_line_count=2out.objectlist+then+ifgrep$mytreehout+then+>mytreehfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi+eliftest_line_count=4out.objectlist+then+ifgrep$othertreehout+then+>othertreehfound+fi&&+ifgrep$otherblobhout+then+>otherblobhfound+fi&&+ifgrep$subtreehout+then+>subtreehfound+fi&&+ifgrep$subblobhout+then+>subblobhfound+fi+fi+done&&+test-fmytreehfound&&+test-fmyblobhfound&&+test-fothertreehfound&&+test-fotherblobhfound&&+test-fsubtreehfound&&+test-fsubblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&+# Ensure that there are exactly 3 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=6filelist+'+ test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_when_finished"rm -rf \"$P\" http_child log"&&
From: Teng Long <hidden> Date: 2021-10-19 11:40:11
From: Teng Long <redacted>
This commit brings the tags exclusion feature of packfile-uri. The
excluding level of tag is supported with "ET_SELF", "ET_INCLUDE"
and "ET_REACHABLE".
Exclusion scope on different level:
1. When a tag is specified to be excluded with level "ET_SELF",
only the tag object itself will be excluded.
2. When it's specified to be excluded with level "ET_INCLUDE",
exclude the referenced commit, and all trees and blobs contained in its
top-level. If it's a annotated tag, the tag object will be excluded
too.
3. When it is specified with level "ET_REACHABLE", exclude the ancestors
of the referenced commit, as well as the objects need to be excluded
under the level "ET_INCLUDED".
Signed-off-by: Teng Long <redacted>
---
builtin/pack-objects.c | 6 +++++-
list-objects.c | 20 ++++++++++++++++----
object.c | 1 +
object.h | 1 +
revision.c | 13 ++++++++++++-
revision.h | 9 +++++++++
6 files changed, 44 insertions(+), 6 deletions(-)
@@ -321,6 +327,9 @@ struct rev_info {/* misc. flags related to '--no-kept-objects' */unsignedkeep_pack_cache_flags;++/* The commit_wraps caches the referred wrapped objects(such as tags) of a commit */+structoidmap*commit_wraps;};intref_excluded(structstring_list*,constchar*path);
@@ -1480,6 +1480,203 @@ test_expect_success 'tree-exclusion(excluding_type=ET_INCLUDE), part of packfiletest_line_count=6filelist'+test_expect_success'tag-exclusion(excluding_type=ET_SELF): part of packfile response provided as URI''+test_when_finished"rm -rf \"$P\" http_child log"&&+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&+git-C"$P"tag-a-m"annotated_tag"tagA&&++tagh=$(git-C"$P"rev-parsetagA)&&+commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+ah=$(git-C"$P"hash-objectA.t)&&+myblobh=$(git-C"$P"hash-objectmy-blob)&&++configure_exclusiontag"$P""$tagh"new0>h2&&+gitinithttp_child&&+GIT_TRACE=1GIT_TRACE_PACKET=`pwd`/logGIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child\+-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch--tags"$HTTPD_URL/smart/http_parent"&&++# Ensure that my-tree and other-tree and theirs complementary set are in separate packfiles.+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=1out.objectlist+then+ifgrep$taghout+then+>taghfound+fi++eliftest_line_count=4out.objectlist+then+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi+fi+done&&+test-fmyblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&+test-ftaghfound&&+# Ensure that there are exactly 3 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist+'++test_expect_success'tag-exclusion(excluding_type=ET_INCLUDE): part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+echomy-blob>"$P/my-blob"&&+git-C"$P"addmy-blob&&+test_commit-C"$P"A&&+git-C"$P"tag-a-m"annotated_tag"tagA&&++tagh=$(git-C"$P"rev-parsetagA)&&+commith=$(git-C"$P"rev-parseA)&&+roottreeh=$(git-C"$P"rev-parseA:)&&+ah=$(git-C"$P"hash-objectA.t)&&+myblobh=$(git-C"$P"hash-objectmy-blob)&&++configure_exclusiontag"$P""$tagh"new1>h2&&++gitinithttp_child&&+GIT_TRACE=1GIT_TRACE_PACKET=`pwd`/logGIT_TEST_SIDEBAND_ALL=1\+git-Chttp_child\+-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+fetch--tags"$HTTPD_URL/smart/http_parent"&&++# Ensure that my-tree and other-tree and theirs complementary set are in separate packfiles.+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=5out.objectlist+then+ifgrep$taghout+then+>taghfound+fi&&+ifgrep$commithout+then+>commithfound+fi&&+ifgrep$roottreehout+then+>roottreehfound+fi&&+ifgrep$ahout+then+>ahfound+fi&&+ifgrep$myblobhout+then+>myblobhfound+fi+fi+done&&+test-fmyblobhfound&&+test-fcommithfound&&+test-froottreehfound&&+test-fahfound&&+test-ftaghfound&&+# Ensure that there are exactly 3 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist+'++test_expect_success'tag-exclusion(excluding_type=ET_REACHABLE): part of packfile response provided as URI''+P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&+test_when_finished"rm -rf \"$P\" http_child log"&&+gitinit"$P"&&+git-C"$P"config"uploadpack.allowsidebandall""true"&&+++mkdir"$P"/my-tree&&+echomy-blob>"$P"/my-tree/my-blob&&+git-C"$P"addmy-tree&&+test_commit-C"$P"A&&++mkdir"$P"/other-tree&&+echoother-blob>"$P"/other-tree/other-blob&&+git-C"$P"addother-tree&&+test_commit-C"$P"B&&++git-C"$P"tag-a-m"tag X"tagX&&++tagh=$(git-C"$P"rev-parsetagX)&&+commitAh=$(git-C"$P"rev-parseA)&&+commitBh=$(git-C"$P"rev-parseB)&&+roottreeAh=$(git-C"$P"rev-parseA:)&&+roottreeBh=$(git-C"$P"rev-parseB:)&&+mytreeh=$(git-C"$P"ls-treeHEADmy-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+othertreeh=$(git-C"$P"ls-treeHEADother-tree|sed-ne"s/.*\($OID_REGEX\).*/\1/p")&&+ah=$(git-C"$P"hash-objectA.t)&&+bh=$(git-C"$P"hash-objectB.t)&&+myblobh=$(git-C"$P"hash-objectmy-tree/my-blob)&&+otherblobh=$(git-C"$P"hash-objectother-tree/other-blob)&&++configure_exclusiontag"$P""$tagh"new2>h&&++GIT_TRACE=1GIT_TRACE_PACKET="$(pwd)/log"GIT_TEST_SIDEBAND_ALL=1\+git-cprotocol.version=2\+-cfetch.uriprotocols=http,https\+clone"$HTTPD_URL/smart/http_parent"http_child&&++# Ensure that my-tree and other-tree and theirs complementary set are in separate packfiles.+foridxinhttp_child/.git/objects/pack/*.idx+do+gitverify-pack--object-format=$(test_oidalgo)--verbose$idx>out&&+{+grep"^[0-9a-f]\{16,\} "out||:+}>out.objectlist&&+iftest_line_count=11out.objectlist+then+>fullpackfound+eliftest_line_count=0out.objectlist+then+>emptypackfound+fi+done&&+test-ffullpackfound&&+test-femptypackfound&&+# Ensure that there are exactly 3 packfiles with associated .idx+lshttp_child/.git/objects/pack/*.pack\+http_child/.git/objects/pack/*.idx>filelist&&+test_line_count=4filelist+'+ test_expect_success'fetching with valid packfile URI but invalid hash fails''P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent"&&test_when_finished"rm -rf \"$P\" http_child log"&&
@@ -34,14 +34,69 @@ having it advertise `packfile-uris`, tolerating the client sending include some sort of non-trivial implementation in the Minimum Viable Product, at least so that we can test the client.-This is the implementation: a feature, marked experimental, that allows the-server to be configured by one or more `uploadpack.blobPackfileUri=<sha1>-<uri>` entries. Whenever the list of objects to be sent is assembled, all such-blobs are excluded, replaced with URIs. As noted in "Future work" below, the-server can evolve in the future to support excluding other objects (or other-implementations of servers could be made that support excluding other objects)-without needing a protocol change, so clients should not expect that packfiles-downloaded in this way only contain single blobs.+This is the implementation: a feature, marked experimental, that allows+the server to be configured by one or more entries with the format:++ uploadpack.excludeobject=<object-hash> <level> <pack-hash> <uri>++Value `<object-hash>` is the key of entry, and the object type can be+blob, tree, commit, or tag. Value of entry has three parts,+`<pack-hash>` is used to identify the packfile which contains the given+`<object-hash>` object, and `<uri>` is the URI to download the packfile by+client. For example, When a blob is configured with `uploadpack.excludeobject`+that means whenever the blob to be send is assembled, the object will+be excluded.++In addition to excluding a single object like blob, sometimes it's+hoped to exclude not only the object itself, but also all the related+objects with it, like all the objects a tree contains or the ancestors+that a commit can reach. In these cases, the `<level>` is designed to+distinguish the scope of exclusion, it supports three levels:++- Level 0: Excluding a single object itself, without any objects that+ have a relationship with it. ++- Level 1: Excluding object itself, and objects it contains.++- Level 2: Excluding object itself, the objects it contains, and the+ ancestors it can reach.++If `<level>` is configured as 0, only the object itself will be+excluded, no matter what the object type is. It is a common scenario+for large size blobs, but it does much not sense for other object types+(e.g. download a singe commit without downloading the blobs and tree+in it).++If `<level>` is configured as 1, not only the single object but also all+the objects in it will be excluded. This applies to scenarios where+it's wanted to exclude a specified non-blob object that includes some+lage size objects.++- If <object-hash> is a blob, the result is the same as level 0, because blob+contains nothing just itself.++- If <object-hash> is a tree, the tree itself, and all blobs and trees+ in it will be excluded.++- If <object-hash> is a commit, the commit itself, the referenced+ root-tree, and all blobs and trees in the root-tree will be excluded.++- If <object-hash> is a tag, the tag itself, the dereferenced commit+ and all trees and blobs contained in its root-tree will be excluded.++If `<level>` is configured as 2, not only the objects in the scope of+level 1 , but also the reachable ancestors will be excluded if+`<object-hash>` is commit or tag.++Configuration compatibility+---------------------------++The old configuration of packfile-uri:++ uploadpack.blobPackfileUri=<object-hash> <pack-hash> <uri>++For the old configuration is compatible with the new one, but it only+supports the exclusion of blob objects. Client design -------------
@@ -65,9 +120,6 @@ The protocol design allows some evolution of the server and client without any need for protocol changes, so only a small-scoped design is included here to form the MVP. For example, the following can be done:- * On the server, more sophisticated means of excluding objects (e.g. by- specifying a commit to represent that commit and all objects that it- references). * On the client, resumption of clone. If a clone is interrupted, information could be recorded in the repository's config and a "clone-resume" command can resume the clone in progress. (Resumption of subsequent fetches is more