/* Allow request of any sha1. Implies ALLOW_TIP_SHA1 and ALLOW_REACHABLE_SHA1. */
#define ALLOW_ANY_SHA1 07
static unsigned int allow_unadvertised_object_request;
-static int shallow_nr;
static struct object_array extra_edge_obj;
-static int keepalive = 5;
-static const char *pack_objects_hook;
-
-static int allow_filter;
-static int allow_ref_in_want;
-
-static int allow_sideband_all;
/*
* Please annotate, and if possible group together, fields used only
timestamp_t deepen_since;
int deepen_rev_list;
int deepen_relative;
+ int keepalive;
+ int shallow_nr;
unsigned int timeout; /* v0 only */
enum {
struct packet_writer writer;
+ const char *pack_objects_hook;
+
unsigned stateless_rpc : 1; /* v0 only */
unsigned no_done : 1; /* v0 only */
unsigned daemon_mode : 1; /* v0 only */
unsigned use_ofs_delta : 1;
unsigned no_progress : 1;
unsigned use_include_tag : 1;
+ unsigned allow_filter : 1;
unsigned done : 1; /* v2 only */
+ unsigned allow_ref_in_want : 1; /* v2 only */
+ unsigned allow_sideband_all : 1; /* v2 only */
};
static void upload_pack_data_init(struct upload_pack_data *data)
data->shallows = shallows;
data->deepen_not = deepen_not;
packet_writer_init(&data->writer, 1);
+
+ data->keepalive = 5;
}
static void upload_pack_data_clear(struct upload_pack_data *data)
object_array_clear(&data->shallows);
string_list_clear(&data->deepen_not, 0);
list_objects_filter_release(&data->filter_options);
+
+ free((char *)data->pack_objects_hook);
}
static void reset_timeout(unsigned int timeout)
int i;
FILE *pipe_fd;
- if (!pack_objects_hook)
+ if (!pack_data->pack_objects_hook)
pack_objects.git_cmd = 1;
else {
- argv_array_push(&pack_objects.args, pack_objects_hook);
+ argv_array_push(&pack_objects.args, pack_data->pack_objects_hook);
argv_array_push(&pack_objects.args, "git");
pack_objects.use_shell = 1;
}
- if (shallow_nr) {
+ if (pack_data->shallow_nr) {
argv_array_push(&pack_objects.args, "--shallow-file");
argv_array_push(&pack_objects.args, "");
}
argv_array_push(&pack_objects.args, "--thin");
argv_array_push(&pack_objects.args, "--stdout");
- if (shallow_nr)
+ if (pack_data->shallow_nr)
argv_array_push(&pack_objects.args, "--shallow");
if (!pack_data->no_progress)
argv_array_push(&pack_objects.args, "--progress");
pipe_fd = xfdopen(pack_objects.in, "w");
- if (shallow_nr)
+ if (pack_data->shallow_nr)
for_each_commit_graft(write_one_shallow, pipe_fd);
for (i = 0; i < pack_data->want_obj.nr; i++)
while (1) {
struct pollfd pfd[2];
- int pe, pu, pollsize;
+ int pe, pu, pollsize, polltimeout;
int ret;
reset_timeout(pack_data->timeout);
if (!pollsize)
break;
- ret = poll(pfd, pollsize,
- keepalive < 0 ? -1 : 1000 * keepalive);
+ polltimeout = pack_data->keepalive < 0
+ ? -1
+ : 1000 * pack_data->keepalive;
+
+ ret = poll(pfd, pollsize, polltimeout);
if (ret < 0) {
if (errno != EINTR) {
}
}
-static void send_shallow(struct packet_writer *writer,
+static void send_shallow(struct upload_pack_data *data,
struct commit_list *result)
{
while (result) {
struct object *object = &result->item->object;
if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
- packet_writer_write(writer, "shallow %s",
+ packet_writer_write(&data->writer, "shallow %s",
oid_to_hex(&object->oid));
register_shallow(the_repository, &object->oid);
- shallow_nr++;
+ data->shallow_nr++;
}
result = result->next;
}
}
-static void send_unshallow(struct packet_writer *writer,
- const struct object_array *shallows,
- struct object_array *want_obj)
+static void send_unshallow(struct upload_pack_data *data)
{
int i;
- for (i = 0; i < shallows->nr; i++) {
- struct object *object = shallows->objects[i].item;
+ for (i = 0; i < data->shallows.nr; i++) {
+ struct object *object = data->shallows.objects[i].item;
if (object->flags & NOT_SHALLOW) {
struct commit_list *parents;
- packet_writer_write(writer, "unshallow %s",
+ packet_writer_write(&data->writer, "unshallow %s",
oid_to_hex(&object->oid));
object->flags &= ~CLIENT_SHALLOW;
/*
parents = ((struct commit *)object)->parents;
while (parents) {
add_object_array(&parents->item->object,
- NULL, want_obj);
+ NULL, &data->want_obj);
parents = parents->next;
}
add_object_array(object, NULL, &extra_edge_obj);
static int check_ref(const char *refname_full, const struct object_id *oid,
int flag, void *cb_data);
-static void deepen(struct packet_writer *writer, int depth, int deepen_relative,
- struct object_array *shallows, struct object_array *want_obj)
+static void deepen(struct upload_pack_data *data, int depth)
{
if (depth == INFINITE_DEPTH && !is_repository_shallow(the_repository)) {
int i;
- for (i = 0; i < shallows->nr; i++) {
- struct object *object = shallows->objects[i].item;
+ for (i = 0; i < data->shallows.nr; i++) {
+ struct object *object = data->shallows.objects[i].item;
object->flags |= NOT_SHALLOW;
}
- } else if (deepen_relative) {
+ } else if (data->deepen_relative) {
struct object_array reachable_shallows = OBJECT_ARRAY_INIT;
struct commit_list *result;
head_ref_namespaced(check_ref, NULL);
for_each_namespaced_ref(check_ref, NULL);
- get_reachable_list(shallows, &reachable_shallows);
+ get_reachable_list(&data->shallows, &reachable_shallows);
result = get_shallow_commits(&reachable_shallows,
depth + 1,
SHALLOW, NOT_SHALLOW);
- send_shallow(writer, result);
+ send_shallow(data, result);
free_commit_list(result);
object_array_clear(&reachable_shallows);
} else {
struct commit_list *result;
- result = get_shallow_commits(want_obj, depth,
+ result = get_shallow_commits(&data->want_obj, depth,
SHALLOW, NOT_SHALLOW);
- send_shallow(writer, result);
+ send_shallow(data, result);
free_commit_list(result);
}
- send_unshallow(writer, shallows, want_obj);
+ send_unshallow(data);
}
-static void deepen_by_rev_list(struct packet_writer *writer, int ac,
- const char **av,
- struct object_array *shallows,
- struct object_array *want_obj)
+static void deepen_by_rev_list(struct upload_pack_data *data,
+ int ac,
+ const char **av)
{
struct commit_list *result;
disable_commit_graph(the_repository);
result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
- send_shallow(writer, result);
+ send_shallow(data, result);
free_commit_list(result);
- send_unshallow(writer, shallows, want_obj);
+ send_unshallow(data);
}
/* Returns 1 if a shallow list is sent or 0 otherwise */
-static int send_shallow_list(struct packet_writer *writer,
- int depth, int deepen_rev_list,
- timestamp_t deepen_since,
- struct string_list *deepen_not,
- int deepen_relative,
- struct object_array *shallows,
- struct object_array *want_obj)
+static int send_shallow_list(struct upload_pack_data *data)
{
int ret = 0;
- if (depth > 0 && deepen_rev_list)
+ if (data->depth > 0 && data->deepen_rev_list)
die("git upload-pack: deepen and deepen-since (or deepen-not) cannot be used together");
- if (depth > 0) {
- deepen(writer, depth, deepen_relative, shallows, want_obj);
+ if (data->depth > 0) {
+ deepen(data, data->depth);
ret = 1;
- } else if (deepen_rev_list) {
+ } else if (data->deepen_rev_list) {
struct argv_array av = ARGV_ARRAY_INIT;
int i;
argv_array_push(&av, "rev-list");
- if (deepen_since)
- argv_array_pushf(&av, "--max-age=%"PRItime, deepen_since);
- if (deepen_not->nr) {
+ if (data->deepen_since)
+ argv_array_pushf(&av, "--max-age=%"PRItime, data->deepen_since);
+ if (data->deepen_not.nr) {
argv_array_push(&av, "--not");
- for (i = 0; i < deepen_not->nr; i++) {
- struct string_list_item *s = deepen_not->items + i;
+ for (i = 0; i < data->deepen_not.nr; i++) {
+ struct string_list_item *s = data->deepen_not.items + i;
argv_array_push(&av, s->string);
}
argv_array_push(&av, "--not");
}
- for (i = 0; i < want_obj->nr; i++) {
- struct object *o = want_obj->objects[i].item;
+ for (i = 0; i < data->want_obj.nr; i++) {
+ struct object *o = data->want_obj.objects[i].item;
argv_array_push(&av, oid_to_hex(&o->oid));
}
- deepen_by_rev_list(writer, av.argc, av.argv, shallows, want_obj);
+ deepen_by_rev_list(data, av.argc, av.argv);
argv_array_clear(&av);
ret = 1;
} else {
- if (shallows->nr > 0) {
+ if (data->shallows.nr > 0) {
int i;
- for (i = 0; i < shallows->nr; i++)
+ for (i = 0; i < data->shallows.nr; i++)
register_shallow(the_repository,
- &shallows->objects[i].item->oid);
+ &data->shallows.objects[i].item->oid);
}
}
- shallow_nr += shallows->nr;
+ data->shallow_nr += data->shallows.nr;
return ret;
}
{
int has_non_tip = 0;
- shallow_nr = 0;
+ data->shallow_nr = 0;
for (;;) {
struct object *o;
const char *features;
data->no_progress = 1;
if (parse_feature_request(features, "include-tag"))
data->use_include_tag = 1;
- if (allow_filter && parse_feature_request(features, "filter"))
+ if (data->allow_filter &&
+ parse_feature_request(features, "filter"))
data->filter_capability_requested = 1;
o = parse_object(the_repository, &oid_buf);
if (data->depth == 0 && !data->deepen_rev_list && data->shallows.nr == 0)
return;
- if (send_shallow_list(&data->writer,
- data->depth,
- data->deepen_rev_list,
- data->deepen_since,
- &data->deepen_not,
- data->deepen_relative,
- &data->shallows,
- &data->want_obj))
+ if (send_shallow_list(data))
packet_flush(1);
}
" allow-reachable-sha1-in-want" : "",
data->stateless_rpc ? " no-done" : "",
symref_info.buf,
- allow_filter ? " filter" : "",
+ data->allow_filter ? " filter" : "",
git_user_agent_sanitized());
strbuf_release(&symref_info);
} else {
static int upload_pack_config(const char *var, const char *value, void *cb_data)
{
+ struct upload_pack_data *data = cb_data;
+
if (!strcmp("uploadpack.allowtipsha1inwant", var)) {
if (git_config_bool(var, value))
allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
else
allow_unadvertised_object_request &= ~ALLOW_ANY_SHA1;
} else if (!strcmp("uploadpack.keepalive", var)) {
- keepalive = git_config_int(var, value);
- if (!keepalive)
- keepalive = -1;
+ data->keepalive = git_config_int(var, value);
+ if (!data->keepalive)
+ data->keepalive = -1;
} else if (!strcmp("uploadpack.allowfilter", var)) {
- allow_filter = git_config_bool(var, value);
+ data->allow_filter = git_config_bool(var, value);
} else if (!strcmp("uploadpack.allowrefinwant", var)) {
- allow_ref_in_want = git_config_bool(var, value);
+ data->allow_ref_in_want = git_config_bool(var, value);
} else if (!strcmp("uploadpack.allowsidebandall", var)) {
- allow_sideband_all = git_config_bool(var, value);
+ data->allow_sideband_all = git_config_bool(var, value);
} else if (!strcmp("core.precomposeunicode", var)) {
precomposed_unicode = git_config_bool(var, value);
}
if (current_config_scope() != CONFIG_SCOPE_LOCAL &&
current_config_scope() != CONFIG_SCOPE_WORKTREE) {
if (!strcmp("uploadpack.packobjectshook", var))
- return git_config_string(&pack_objects_hook, var, value);
+ return git_config_string(&data->pack_objects_hook, var, value);
}
return parse_hide_refs_config(var, value, "uploadpack");
/* process want */
if (parse_want(&data->writer, arg, &data->want_obj))
continue;
- if (allow_ref_in_want &&
+ if (data->allow_ref_in_want &&
parse_want_ref(&data->writer, arg, &data->wanted_refs,
&data->want_obj))
continue;
continue;
}
- if (allow_filter && skip_prefix(arg, "filter ", &p)) {
+ if (data->allow_filter && skip_prefix(arg, "filter ", &p)) {
list_objects_filter_die_if_populated(&data->filter_options);
parse_list_objects_filter(&data->filter_options, p);
continue;
}
if ((git_env_bool("GIT_TEST_SIDEBAND_ALL", 0) ||
- allow_sideband_all) &&
+ data->allow_sideband_all) &&
!strcmp(arg, "sideband-all")) {
data->writer.use_sideband = 1;
continue;
packet_writer_write(&data->writer, "shallow-info\n");
- if (!send_shallow_list(&data->writer, data->depth,
- data->deepen_rev_list,
- data->deepen_since, &data->deepen_not,
- data->deepen_relative,
- &data->shallows, &data->want_obj) &&
+ if (!send_shallow_list(data) &&
is_repository_shallow(the_repository))
- deepen(&data->writer, INFINITE_DEPTH, data->deepen_relative,
- &data->shallows, &data->want_obj);
+ deepen(data, INFINITE_DEPTH);
packet_delim(1);
}