negotiator/noop: add noop fetch negotiator
Add a noop fetch negotiator. This is introduced to allow partial clones to skip the unneeded negotiation step when fetching missing objects using a "git fetch" subprocess. (The implementation of spawning a "git fetch" subprocess will be done in a subsequent patch.) But this can also be useful for end users, e.g. as a blunt fix for object corruption. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jonathan Tan committed
Aug 17, 2020 at 21:01 UTC
cbe566a0710b39691ca8f6cb6a764f6c553cd97b
8 files changed
+87
-1
Documentation/config/fetch.txt
+4
-1
@@ -60,7 +60,10 @@ fetch.negotiationAlgorithm::
60
sent when negotiating the contents of the packfile to be sent by the
61
server. Set to "skipping" to use an algorithm that skips commits in an
62
effort to converge faster, but may result in a larger-than-necessary
63
- packfile; The default is "default" which instructs Git to use the default algorithm
63
+ packfile; or set to "noop" to not send any information at all, which
64
+ will almost certainly result in a larger-than-necessary packfile, but
65
+ will skip the negotiation step.
66
+ The default is "default" which instructs Git to use the default algorithm
67
that never skips commits (unless the server has acknowledged it or one
68
of its descendants). If `feature.experimental` is enabled, then this
69
setting defaults to "skipping".
Makefile
+1
@@ -916,6 +916,7 @@ LIB_OBJS += mergesort.o
916
LIB_OBJS += midx.o
917
LIB_OBJS += name-hash.o
918
LIB_OBJS += negotiator/default.o
919
+LIB_OBJS += negotiator/noop.o
920
LIB_OBJS += negotiator/skipping.o
921
LIB_OBJS += notes-cache.o
922
LIB_OBJS += notes-merge.o
fetch-negotiator.c
+5
@@ -2,6 +2,7 @@
2
#include "fetch-negotiator.h"
3
#include "negotiator/default.h"
4
#include "negotiator/skipping.h"
5
+#include "negotiator/noop.h"
6
#include "repository.h"
7
8
void fetch_negotiator_init(struct repository *r,
@@ -13,6 +14,10 @@ void fetch_negotiator_init(struct repository *r,
14
skipping_negotiator_init(negotiator);
15
return;
16
17
+ case FETCH_NEGOTIATION_NOOP:
18
+ noop_negotiator_init(negotiator);
19
+ return;
20
+
21
case FETCH_NEGOTIATION_DEFAULT:
22
default:
23
default_negotiator_init(negotiator);
negotiator/noop.c
new
+44
@@ -0,0 +1,44 @@
1
+#include "cache.h"
2
+#include "noop.h"
3
+#include "../commit.h"
4
+#include "../fetch-negotiator.h"
5
+
6
+static void known_common(struct fetch_negotiator *n, struct commit *c)
7
+{
8
+ /* do nothing */
9
+}
10
+
11
+static void add_tip(struct fetch_negotiator *n, struct commit *c)
12
+{
13
+ /* do nothing */
14
+}
15
+
16
+static const struct object_id *next(struct fetch_negotiator *n)
17
+{
18
+ return NULL;
19
+}
20
+
21
+static int ack(struct fetch_negotiator *n, struct commit *c)
22
+{
23
+ /*
24
+ * This negotiator does not emit any commits, so there is no commit to
25
+ * be acknowledged. If there is any ack, there is a bug.
26
+ */
27
+ BUG("ack with noop negotiator, which does not emit any commits");
28
+ return 0;
29
+}
30
+
31
+static void release(struct fetch_negotiator *n)
32
+{
33
+ /* nothing to release */
34
+}
35
+
36
+void noop_negotiator_init(struct fetch_negotiator *negotiator)
37
+{
38
+ negotiator->known_common = known_common;
39
+ negotiator->add_tip = add_tip;
40
+ negotiator->next = next;
41
+ negotiator->ack = ack;
42
+ negotiator->release = release;
43
+ negotiator->data = NULL;
44
+}
negotiator/noop.h
new
+8
@@ -0,0 +1,8 @@
1
+#ifndef NEGOTIATOR_NOOP_H
2
+#define NEGOTIATOR_NOOP_H
3
+
4
+struct fetch_negotiator;
5
+
6
+void noop_negotiator_init(struct fetch_negotiator *negotiator);
7
+
8
+#endif
repo-settings.c
+2
@@ -39,6 +39,8 @@ void prepare_repo_settings(struct repository *r)
39
if (!repo_config_get_string(r, "fetch.negotiationalgorithm", &strval)) {
40
if (!strcasecmp(strval, "skipping"))
41
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;
42
+ else if (!strcasecmp(strval, "noop"))
43
+ r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_NOOP;
44
else
45
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_DEFAULT;
46
}
repository.h
+1
@@ -23,6 +23,7 @@ enum fetch_negotiation_setting {
23
FETCH_NEGOTIATION_NONE = 0,
24
FETCH_NEGOTIATION_DEFAULT = 1,
25
FETCH_NEGOTIATION_SKIPPING = 2,
26
+ FETCH_NEGOTIATION_NOOP = 3,
27
};
28
29
struct repo_settings {
t/t5554-noop-fetch-negotiator.sh
new
+22
@@ -0,0 +1,22 @@
1
+#!/bin/sh
2
+
3
+test_description='test noop fetch negotiator'
4
+. ./test-lib.sh
5
+
6
+test_expect_success 'noop negotiator does not emit any "have"' '
7
+ rm -f trace &&
8
+
9
+ test_create_repo server &&
10
+ test_commit -C server to_fetch &&
11
+
12
+ test_create_repo client &&
13
+ test_commit -C client we_have &&
14
+
15
+ test_config -C client fetch.negotiationalgorithm noop &&
16
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "$(pwd)/server" &&
17
+
18
+ ! grep "fetch> have" trace &&
19
+ grep "fetch> done" trace
20
+'
21
+
22
+test_done