#include "exec_cmd.h"
#include "commit.h"
#include "object.h"
+#include "remote.h"
+#include "transport.h"
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
+static int deny_deletes = 0;
static int deny_non_fast_forwards = 0;
static int receive_fsck_objects;
static int receive_unpack_limit = -1;
static int receive_pack_config(const char *var, const char *value, void *cb)
{
+ if (strcmp(var, "receive.denydeletes") == 0) {
+ deny_deletes = git_config_bool(var, value);
+ return 0;
+ }
+
if (strcmp(var, "receive.denynonfastforwards") == 0) {
deny_non_fast_forwards = git_config_bool(var, value);
return 0;
"but I can't find it!", sha1_to_hex(new_sha1));
return "bad pack";
}
+ if (deny_deletes && is_null_sha1(new_sha1) &&
+ !is_null_sha1(old_sha1) &&
+ !prefixcmp(name, "refs/heads/")) {
+ error("denying ref deletion for %s", name);
+ return "deletion prohibited";
+ }
if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
!is_null_sha1(old_sha1) &&
!prefixcmp(name, "refs/heads/")) {
return 1;
}
+static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
+{
+ char *other;
+ size_t len;
+ struct remote *remote;
+ struct transport *transport;
+ const struct ref *extra;
+
+ e->name[-1] = '\0';
+ other = xstrdup(make_absolute_path(e->base));
+ e->name[-1] = '/';
+ len = strlen(other);
+
+ while (other[len-1] == '/')
+ other[--len] = '\0';
+ if (len < 8 || memcmp(other + len - 8, "/objects", 8))
+ return 0;
+ /* Is this a git repository with refs? */
+ memcpy(other + len - 8, "/refs", 6);
+ if (!is_directory(other))
+ return 0;
+ other[len - 8] = '\0';
+ remote = remote_get(other);
+ transport = transport_get(remote, other);
+ for (extra = transport_get_remote_refs(transport);
+ extra;
+ extra = extra->next) {
+ add_extra_ref(".have", extra->old_sha1, 0);
+ }
+ transport_disconnect(transport);
+ free(other);
+ return 0;
+}
+
+static void add_alternate_refs(void)
+{
+ foreach_alt_odb(add_refs_from_alternate, NULL);
+}
+
int cmd_receive_pack(int argc, const char **argv, const char *prefix)
{
int i;
else if (0 <= receive_unpack_limit)
unpack_limit = receive_unpack_limit;
+ add_alternate_refs();
write_head_info();
+ clear_extra_refs();
/* EOF */
packet_flush(1);