transport: transports can indicate support for fetch by oid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
diff --git a/include/git2/sys/remote.h b/include/git2/sys/remote.h
new file mode 100644
index 0000000..dd243ca
--- /dev/null
+++ b/include/git2/sys/remote.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#ifndef INCLUDE_sys_git_remote_h
+#define INCLUDE_sys_git_remote_h
+
+/**
+ * @file git2/sys/remote.h
+ * @brief Low-level remote functionality for custom transports
+ * @defgroup git_remote Low-level remote functionality
+ * @ingroup Git
+ * @{
+*/
+
+GIT_BEGIN_DECL
+
+typedef enum {
+ /** Remote supports fetching an advertised object by ID. */
+ GIT_REMOTE_CAPABILITY_TIP_OID = (1 << 0),
+
+ /** Remote supports fetching an individual reachable object. */
+ GIT_REMOTE_CAPABILITY_REACHABLE_OID = (1 << 1),
+} git_remote_capability_t;
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/src/transports/local.c b/src/transports/local.c
index 0c768fa..6c754a0 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -28,6 +28,7 @@
#include "git2/pack.h"
#include "git2/commit.h"
#include "git2/revparse.h"
+#include "git2/sys/remote.h"
typedef struct {
git_transport parent;
@@ -260,7 +261,8 @@ static int local_capabilities(unsigned int *capabilities, git_transport *transpo
{
GIT_UNUSED(transport);
- *capabilities = 0;
+ *capabilities = GIT_REMOTE_CAPABILITY_TIP_OID |
+ GIT_REMOTE_CAPABILITY_REACHABLE_OID;
return 0;
}
diff --git a/src/transports/smart.c b/src/transports/smart.c
index 3b58b84..801fcbe 100644
--- a/src/transports/smart.c
+++ b/src/transports/smart.c
@@ -8,6 +8,7 @@
#include "smart.h"
#include "git2.h"
+#include "git2/sys/remote.h"
#include "refs.h"
#include "refspec.h"
#include "proxy.h"
@@ -228,9 +229,16 @@ static int git_smart__set_connect_opts(
static int git_smart__capabilities(unsigned int *capabilities, git_transport *transport)
{
- GIT_UNUSED(transport);
+ transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent);
*capabilities = 0;
+
+ if (t->caps.want_tip_sha1)
+ *capabilities |= GIT_REMOTE_CAPABILITY_TIP_OID;
+
+ if (t->caps.want_reachable_sha1)
+ *capabilities |= GIT_REMOTE_CAPABILITY_REACHABLE_OID;
+
return 0;
}
diff --git a/src/transports/smart.h b/src/transports/smart.h
index 8860a1e..9323d6c 100644
--- a/src/transports/smart.h
+++ b/src/transports/smart.h
@@ -30,6 +30,8 @@
#define GIT_CAP_REPORT_STATUS "report-status"
#define GIT_CAP_THIN_PACK "thin-pack"
#define GIT_CAP_SYMREF "symref"
+#define GIT_CAP_WANT_TIP_SHA1 "allow-tip-sha1-in-want"
+#define GIT_CAP_WANT_REACHABLE_SHA1 "allow-reachable-sha1-in-want"
extern bool git_smart__ofs_delta_enabled;
@@ -128,7 +130,9 @@ typedef struct transport_smart_caps {
include_tag:1,
delete_refs:1,
report_status:1,
- thin_pack:1;
+ thin_pack:1,
+ want_tip_sha1:1,
+ want_reachable_sha1:1;
} transport_smart_caps;
typedef int (*packetsize_cb)(size_t received, void *payload);
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index 0610281..e61c5f4 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -205,6 +205,18 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec
continue;
}
+ if (!git__prefixcmp(ptr, GIT_CAP_WANT_TIP_SHA1)) {
+ caps->common = caps->want_tip_sha1 = 1;
+ ptr += strlen(GIT_CAP_DELETE_REFS);
+ continue;
+ }
+
+ if (!git__prefixcmp(ptr, GIT_CAP_WANT_REACHABLE_SHA1)) {
+ caps->common = caps->want_reachable_sha1 = 1;
+ ptr += strlen(GIT_CAP_DELETE_REFS);
+ continue;
+ }
+
/* We don't know this capability, so skip it */
ptr = strchr(ptr, ' ');
}