10
10
#include "diff.h"
11
11
#include "revision.h"
12
12
#include "list-objects.h"
13
+ #include "list-objects-filter.h"
14
+ #include "list-objects-filter-options.h"
13
15
#include "run-command.h"
14
16
#include "connect.h"
15
17
#include "sigchain.h"
18
20
#include "parse-options.h"
19
21
#include "argv-array.h"
20
22
#include "prio-queue.h"
23
+ #include "quote.h"
21
24
22
25
static const char * const upload_pack_usage [] = {
23
26
N_ ("git upload-pack [<options>] <dir>" ),
@@ -64,6 +67,10 @@ static int advertise_refs;
64
67
static int stateless_rpc ;
65
68
static const char * pack_objects_hook ;
66
69
70
+ static int filter_capability_requested ;
71
+ static int filter_advertise ;
72
+ static struct list_objects_filter_options filter_options ;
73
+
67
74
static void reset_timeout (void )
68
75
{
69
76
alarm (timeout );
@@ -131,6 +138,12 @@ static void create_pack_file(void)
131
138
argv_array_push (& pack_objects .args , "--delta-base-offset" );
132
139
if (use_include_tag )
133
140
argv_array_push (& pack_objects .args , "--include-tag" );
141
+ if (filter_options .filter_spec ) {
142
+ struct strbuf buf = STRBUF_INIT ;
143
+ sq_quote_buf (& buf , filter_options .filter_spec );
144
+ argv_array_pushf (& pack_objects .args , "--filter=%s" , buf .buf );
145
+ strbuf_release (& buf );
146
+ }
134
147
135
148
pack_objects .in = -1 ;
136
149
pack_objects .out = -1 ;
@@ -794,6 +807,12 @@ static void receive_needs(void)
794
807
deepen_rev_list = 1 ;
795
808
continue ;
796
809
}
810
+ if (skip_prefix (line , "filter " , & arg )) {
811
+ if (!filter_capability_requested )
812
+ die ("git upload-pack: filtering capability not negotiated" );
813
+ parse_list_objects_filter (& filter_options , arg );
814
+ continue ;
815
+ }
797
816
if (!skip_prefix (line , "want " , & arg ) ||
798
817
get_oid_hex (arg , & oid_buf ))
799
818
die ("git upload-pack: protocol error, "
@@ -821,6 +840,8 @@ static void receive_needs(void)
821
840
no_progress = 1 ;
822
841
if (parse_feature_request (features , "include-tag" ))
823
842
use_include_tag = 1 ;
843
+ if (parse_feature_request (features , "filter" ))
844
+ filter_capability_requested = 1 ;
824
845
825
846
o = parse_object (& oid_buf );
826
847
if (!o ) {
@@ -940,7 +961,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
940
961
struct strbuf symref_info = STRBUF_INIT ;
941
962
942
963
format_symref_info (& symref_info , cb_data );
943
- packet_write_fmt (1 , "%s %s%c%s%s%s%s%s agent=%s\n" ,
964
+ packet_write_fmt (1 , "%s %s%c%s%s%s%s%s%s agent=%s\n" ,
944
965
oid_to_hex (oid ), refname_nons ,
945
966
0 , capabilities ,
946
967
(allow_unadvertised_object_request & ALLOW_TIP_SHA1 ) ?
@@ -949,6 +970,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
949
970
" allow-reachable-sha1-in-want" : "" ,
950
971
stateless_rpc ? " no-done" : "" ,
951
972
symref_info .buf ,
973
+ filter_advertise ? " filter" : "" ,
952
974
git_user_agent_sanitized ());
953
975
strbuf_release (& symref_info );
954
976
} else {
@@ -1027,6 +1049,8 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
1027
1049
} else if (current_config_scope () != CONFIG_SCOPE_REPO ) {
1028
1050
if (!strcmp ("uploadpack.packobjectshook" , var ))
1029
1051
return git_config_string (& pack_objects_hook , var , value );
1052
+ } else if (!strcmp ("uploadpack.allowfilter" , var )) {
1053
+ filter_advertise = git_config_bool (var , value );
1030
1054
}
1031
1055
return parse_hide_refs_config (var , value , "uploadpack" );
1032
1056
}
0 commit comments