* [PATCH 01/20] upload-pack: move shallow deepen code out of receive_needs()
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 02/20] upload-pack: move "shallow" sending code out of deepen() Nguyễn Thái Ngọc Duy
` (19 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This is a prep step for further refactoring. Besides reindentation and
s/shallows\./shallows->/g, no other changes are expected.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
upload-pack.c | 99 +++++++++++++++++++++++++++++++----------------------------
1 file changed, 52 insertions(+), 47 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index b3f6653..97ed620 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -538,6 +538,55 @@ error:
}
}
+static void deepen(int depth, const struct object_array *shallows)
+{
+ struct commit_list *result = NULL, *backup = NULL;
+ int i;
+ if (depth == INFINITE_DEPTH && !is_repository_shallow())
+ for (i = 0; i < shallows->nr; i++) {
+ struct object *object = shallows->objects[i].item;
+ object->flags |= NOT_SHALLOW;
+ }
+ else
+ backup = result =
+ get_shallow_commits(&want_obj, depth,
+ SHALLOW, NOT_SHALLOW);
+ while (result) {
+ struct object *object = &result->item->object;
+ if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
+ packet_write(1, "shallow %s",
+ oid_to_hex(&object->oid));
+ register_shallow(object->oid.hash);
+ shallow_nr++;
+ }
+ result = result->next;
+ }
+ free_commit_list(backup);
+ for (i = 0; i < shallows->nr; i++) {
+ struct object *object = shallows->objects[i].item;
+ if (object->flags & NOT_SHALLOW) {
+ struct commit_list *parents;
+ packet_write(1, "unshallow %s",
+ oid_to_hex(&object->oid));
+ object->flags &= ~CLIENT_SHALLOW;
+ /* make sure the real parents are parsed */
+ unregister_shallow(object->oid.hash);
+ object->parsed = 0;
+ parse_commit_or_die((struct commit *)object);
+ parents = ((struct commit *)object)->parents;
+ while (parents) {
+ add_object_array(&parents->item->object,
+ NULL, &want_obj);
+ parents = parents->next;
+ }
+ add_object_array(object, NULL, &extra_edge_obj);
+ }
+ /* make sure commit traversal conforms to client */
+ register_shallow(object->oid.hash);
+ }
+ packet_flush(1);
+}
+
static void receive_needs(void)
{
struct object_array shallows = OBJECT_ARRAY_INIT;
@@ -630,53 +679,9 @@ static void receive_needs(void)
if (depth == 0 && shallows.nr == 0)
return;
- if (depth > 0) {
- struct commit_list *result = NULL, *backup = NULL;
- int i;
- if (depth == INFINITE_DEPTH && !is_repository_shallow())
- for (i = 0; i < shallows.nr; i++) {
- struct object *object = shallows.objects[i].item;
- object->flags |= NOT_SHALLOW;
- }
- else
- backup = result =
- get_shallow_commits(&want_obj, depth,
- SHALLOW, NOT_SHALLOW);
- while (result) {
- struct object *object = &result->item->object;
- if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
- packet_write(1, "shallow %s",
- oid_to_hex(&object->oid));
- register_shallow(object->oid.hash);
- shallow_nr++;
- }
- result = result->next;
- }
- free_commit_list(backup);
- for (i = 0; i < shallows.nr; i++) {
- struct object *object = shallows.objects[i].item;
- if (object->flags & NOT_SHALLOW) {
- struct commit_list *parents;
- packet_write(1, "unshallow %s",
- oid_to_hex(&object->oid));
- object->flags &= ~CLIENT_SHALLOW;
- /* make sure the real parents are parsed */
- unregister_shallow(object->oid.hash);
- object->parsed = 0;
- parse_commit_or_die((struct commit *)object);
- parents = ((struct commit *)object)->parents;
- while (parents) {
- add_object_array(&parents->item->object,
- NULL, &want_obj);
- parents = parents->next;
- }
- add_object_array(object, NULL, &extra_edge_obj);
- }
- /* make sure commit traversal conforms to client */
- register_shallow(object->oid.hash);
- }
- packet_flush(1);
- } else
+ if (depth > 0)
+ deepen(depth, &shallows);
+ else
if (shallows.nr > 0) {
int i;
for (i = 0; i < shallows.nr; i++)
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 02/20] upload-pack: move "shallow" sending code out of deepen()
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 01/20] upload-pack: move shallow deepen code out of receive_needs() Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 03/20] upload-pack: remove unused variable "backup" Nguyễn Thái Ngọc Duy
` (18 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
upload-pack.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index 97ed620..0eb9a0b 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -538,6 +538,20 @@ error:
}
}
+static void send_shallow(struct commit_list *result)
+{
+ while (result) {
+ struct object *object = &result->item->object;
+ if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
+ packet_write(1, "shallow %s",
+ oid_to_hex(&object->oid));
+ register_shallow(object->oid.hash);
+ shallow_nr++;
+ }
+ result = result->next;
+ }
+}
+
static void deepen(int depth, const struct object_array *shallows)
{
struct commit_list *result = NULL, *backup = NULL;
@@ -551,16 +565,7 @@ static void deepen(int depth, const struct object_array *shallows)
backup = result =
get_shallow_commits(&want_obj, depth,
SHALLOW, NOT_SHALLOW);
- while (result) {
- struct object *object = &result->item->object;
- if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
- packet_write(1, "shallow %s",
- oid_to_hex(&object->oid));
- register_shallow(object->oid.hash);
- shallow_nr++;
- }
- result = result->next;
- }
+ send_shallow(result);
free_commit_list(backup);
for (i = 0; i < shallows->nr; i++) {
struct object *object = shallows->objects[i].item;
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 03/20] upload-pack: remove unused variable "backup"
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 01/20] upload-pack: move shallow deepen code out of receive_needs() Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 02/20] upload-pack: move "shallow" sending code out of deepen() Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 04/20] upload-pack: move "unshallow" sending code out of deepen() Nguyễn Thái Ngọc Duy
` (17 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
After the last patch, "result" and "backup" are the same. "result" used
to move, but the movement is now contained in send_shallow(). Delete
this redundant variable.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
upload-pack.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index 0eb9a0b..4774f78 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -554,7 +554,7 @@ static void send_shallow(struct commit_list *result)
static void deepen(int depth, const struct object_array *shallows)
{
- struct commit_list *result = NULL, *backup = NULL;
+ struct commit_list *result = NULL;
int i;
if (depth == INFINITE_DEPTH && !is_repository_shallow())
for (i = 0; i < shallows->nr; i++) {
@@ -562,11 +562,11 @@ static void deepen(int depth, const struct object_array *shallows)
object->flags |= NOT_SHALLOW;
}
else
- backup = result =
+ result =
get_shallow_commits(&want_obj, depth,
SHALLOW, NOT_SHALLOW);
send_shallow(result);
- free_commit_list(backup);
+ free_commit_list(result);
for (i = 0; i < shallows->nr; i++) {
struct object *object = shallows->objects[i].item;
if (object->flags & NOT_SHALLOW) {
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 04/20] upload-pack: move "unshallow" sending code out of deepen()
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (2 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 03/20] upload-pack: remove unused variable "backup" Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 05/20] shallow.c: implement a generic shallow boundary finder based on rev-list Nguyễn Thái Ngọc Duy
` (16 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
upload-pack.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index 4774f78..4bb104c 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -552,21 +552,10 @@ static void send_shallow(struct commit_list *result)
}
}
-static void deepen(int depth, const struct object_array *shallows)
+static void send_unshallow(const struct object_array *shallows)
{
- struct commit_list *result = NULL;
int i;
- if (depth == INFINITE_DEPTH && !is_repository_shallow())
- for (i = 0; i < shallows->nr; i++) {
- struct object *object = shallows->objects[i].item;
- object->flags |= NOT_SHALLOW;
- }
- else
- result =
- get_shallow_commits(&want_obj, depth,
- SHALLOW, NOT_SHALLOW);
- send_shallow(result);
- free_commit_list(result);
+
for (i = 0; i < shallows->nr; i++) {
struct object *object = shallows->objects[i].item;
if (object->flags & NOT_SHALLOW) {
@@ -589,6 +578,24 @@ static void deepen(int depth, const struct object_array *shallows)
/* make sure commit traversal conforms to client */
register_shallow(object->oid.hash);
}
+}
+
+static void deepen(int depth, const struct object_array *shallows)
+{
+ struct commit_list *result = NULL;
+ int i;
+ if (depth == INFINITE_DEPTH && !is_repository_shallow())
+ for (i = 0; i < shallows->nr; i++) {
+ struct object *object = shallows->objects[i].item;
+ object->flags |= NOT_SHALLOW;
+ }
+ else
+ result =
+ get_shallow_commits(&want_obj, depth,
+ SHALLOW, NOT_SHALLOW);
+ send_shallow(result);
+ free_commit_list(result);
+ send_unshallow(shallows);
packet_flush(1);
}
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 05/20] shallow.c: implement a generic shallow boundary finder based on rev-list
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (3 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 04/20] upload-pack: move "unshallow" sending code out of deepen() Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 06/20] upload-pack: glue code to use get_shallow_commits_by_rev_list Nguyễn Thái Ngọc Duy
` (15 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Instead of a custom commit walker like get_shallow_commits(), this new
function uses rev-list to mark NOT_SHALLOW to all reachable commits,
except borders. The definition of reachable is to be defined by the
protocol later. This makes it more flexible to define shallow boundary.
Note: if a commit has one NOT_SHALLOW parent and one SHALLOW parent,
then it's considered the boundary. Which means in the client side, this
commit has _no_ parents. This could lead to surprising cuts if we're not
careful.
Another option is to include more commits and only mark commits whose
all parents are SHALLOW as boundary.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
commit.h | 2 ++
shallow.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+)
diff --git a/commit.h b/commit.h
index 5d58be0..b717be1 100644
--- a/commit.h
+++ b/commit.h
@@ -258,6 +258,8 @@ extern int for_each_commit_graft(each_commit_graft_fn, void *);
extern int is_repository_shallow(void);
extern struct commit_list *get_shallow_commits(struct object_array *heads,
int depth, int shallow_flag, int not_shallow_flag);
+extern struct commit_list *get_shallow_commits_by_rev_list(
+ int ac, const char **av, int shallow_flag, int not_shallow_flag);
extern void set_alternate_shallow_file(const char *path, int override);
extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
const struct sha1_array *extra);
diff --git a/shallow.c b/shallow.c
index 60f1505..45dffaa 100644
--- a/shallow.c
+++ b/shallow.c
@@ -10,6 +10,8 @@
#include "diff.h"
#include "revision.h"
#include "commit-slab.h"
+#include "revision.h"
+#include "list-objects.h"
static int is_shallow = -1;
static struct stat_validity shallow_stat;
@@ -137,6 +139,96 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
return result;
}
+static void show_commit(struct commit *commit, void *data)
+{
+ commit->object.flags |= *(int *)data;
+}
+
+/*
+ * Given rev-list arguments, run rev-list. All reachable commits
+ * except border ones are marked with not_shallow_flag. Border commits
+ * are marked with shallow_flag. The list of border/shallow commits
+ * are also returned.
+ */
+struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
+ int shallow_flag,
+ int not_shallow_flag)
+{
+ struct commit_list *result = NULL, *cl;
+ struct rev_info revs;
+ unsigned int i, nr;
+
+ /*
+ * SHALLOW and NOT_SHALLOW should not be set at this
+ * point. But better be safe than sorry.
+ */
+ nr = get_max_object_index();
+ for (i = 0; i < nr; i++) {
+ struct object *o = get_indexed_object(i);
+ if (!o)
+ continue;
+ o->flags &= ~(shallow_flag | not_shallow_flag);
+ }
+
+ is_repository_shallow(); /* make sure shallows are read */
+
+ init_revisions(&revs, NULL);
+ save_commit_buffer = 0;
+ setup_revisions(ac, av, &revs, NULL);
+
+ /* Mark all reachable commits as NOT_SHALLOW */
+ if (prepare_revision_walk(&revs))
+ die("revision walk setup failed");
+ traverse_commit_list(&revs, show_commit, NULL, ¬_shallow_flag);
+
+ /*
+ * mark border commits SHALLOW + NOT_SHALLOW.
+ * We cannot clear NOT_SHALLOW right now. Imagine border
+ * commit A is processed first, then commit B, whose parent is
+ * A, later. If NOT_SHALLOW on A is cleared at step 1, B
+ * itself is considered border at step 2, which is incorrect.
+ */
+ nr = get_max_object_index();
+ for (i = 0; i < nr; i++) {
+ struct object *o = get_indexed_object(i);
+ struct commit *c = (struct commit *)o;
+ struct commit_list *p;
+ int parent_is_shallow = 0;
+
+ if (!o || o->type != OBJ_COMMIT || !(o->flags & not_shallow_flag))
+ continue;
+
+ if (parse_commit(c))
+ die("unable to parse commit %s",
+ oid_to_hex(&c->object.oid));
+
+ for (p = c->parents; p; p = p->next) {
+ if (p->item->object.flags & not_shallow_flag)
+ continue;
+ parent_is_shallow = 1;
+ if (p->item->object.flags & shallow_flag)
+ continue;
+ p->item->object.flags |= shallow_flag;
+ commit_list_insert(p->item, &result);
+ }
+
+ if (parent_is_shallow) {
+ o->flags |= shallow_flag;
+ commit_list_insert(c, &result);
+ }
+ }
+ /* clean up NOT_SHALLOW on border commits */
+ cl = result;
+ while (cl) {
+ struct object *object = &result->item->object;
+ if ((object->flags & not_shallow_flag) &&
+ (object->flags & shallow_flag))
+ object->flags &= ~not_shallow_flag;
+ cl = cl->next;
+ }
+ return result;
+}
+
static void check_shallow_file_for_update(void)
{
if (is_shallow == -1)
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 06/20] upload-pack: glue code to use get_shallow_commits_by_rev_list
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (4 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 05/20] shallow.c: implement a generic shallow boundary finder based on rev-list Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 07/20] upload-pack: use skip_prefix() instead of starts_with() when possible Nguyễn Thái Ngọc Duy
` (14 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
The remaining thing to do is protocol extensions and translate the
requests to rev-list options.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
upload-pack.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/upload-pack.c b/upload-pack.c
index 4bb104c..9ae09a0 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -599,6 +599,18 @@ static void deepen(int depth, const struct object_array *shallows)
packet_flush(1);
}
+static void deepen_by_rev_list(int ac, const char **av,
+ struct object_array *shallows)
+{
+ struct commit_list *result;
+
+ result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
+ send_shallow(result);
+ free_commit_list(result);
+ send_unshallow(shallows);
+ packet_flush(1);
+}
+
static void receive_needs(void)
{
struct object_array shallows = OBJECT_ARRAY_INIT;
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 07/20] upload-pack: use skip_prefix() instead of starts_with() when possible
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (5 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 06/20] upload-pack: glue code to use get_shallow_commits_by_rev_list Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 08/20] upload-pack: tighten number parsing at "deepen" lines Nguyễn Thái Ngọc Duy
` (13 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
upload-pack.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index 9ae09a0..e9594d1 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -276,7 +276,7 @@ static void create_pack_file(void)
die("git upload-pack: %s", abort_msg);
}
-static int got_sha1(char *hex, unsigned char *sha1)
+static int got_sha1(const char *hex, unsigned char *sha1)
{
struct object *o;
int we_knew_they_have = 0;
@@ -382,6 +382,8 @@ static int get_common_commits(void)
for (;;) {
char *line = packet_read_line(0, NULL);
+ const char *arg;
+
reset_timeout();
if (!line) {
@@ -403,8 +405,8 @@ static int get_common_commits(void)
got_other = 0;
continue;
}
- if (starts_with(line, "have ")) {
- switch (got_sha1(line+5, sha1)) {
+ if (skip_prefix(line, "have ", &arg)) {
+ switch (got_sha1(arg, sha1)) {
case -1: /* they have what we do not */
got_other = 1;
if (multi_ack && ok_to_give_up()) {
@@ -623,14 +625,16 @@ static void receive_needs(void)
const char *features;
unsigned char sha1_buf[20];
char *line = packet_read_line(0, NULL);
+ const char *arg;
+
reset_timeout();
if (!line)
break;
- if (starts_with(line, "shallow ")) {
+ if (skip_prefix(line, "shallow ", &arg)) {
unsigned char sha1[20];
struct object *object;
- if (get_sha1_hex(line + 8, sha1))
+ if (get_sha1_hex(arg, sha1))
die("invalid shallow line: %s", line);
object = parse_object(sha1);
if (!object)
@@ -643,19 +647,19 @@ static void receive_needs(void)
}
continue;
}
- if (starts_with(line, "deepen ")) {
+ if (skip_prefix(line, "deepen ", &arg)) {
char *end;
- depth = strtol(line + 7, &end, 0);
- if (end == line + 7 || depth <= 0)
+ depth = strtol(arg, &end, 0);
+ if (end == arg || depth <= 0)
die("Invalid deepen: %s", line);
continue;
}
- if (!starts_with(line, "want ") ||
- get_sha1_hex(line+5, sha1_buf))
+ if (!skip_prefix(line, "want ", &arg) ||
+ get_sha1_hex(arg, sha1_buf))
die("git upload-pack: protocol error, "
"expected to get sha, not '%s'", line);
- features = line + 45;
+ features = arg + 40;
if (parse_feature_request(features, "multi_ack_detailed"))
multi_ack = 2;
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 08/20] upload-pack: tighten number parsing at "deepen" lines
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (6 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 07/20] upload-pack: use skip_prefix() instead of starts_with() when possible Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 09/20] upload-pack: add deepen-since to cut shallow repos based on time Nguyễn Thái Ngọc Duy
` (12 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
upload-pack.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index e9594d1..573ffa2 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -648,9 +648,9 @@ static void receive_needs(void)
continue;
}
if (skip_prefix(line, "deepen ", &arg)) {
- char *end;
+ char *end = NULL;
depth = strtol(arg, &end, 0);
- if (end == arg || depth <= 0)
+ if (!end || *end || depth <= 0)
die("Invalid deepen: %s", line);
continue;
}
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 09/20] upload-pack: add deepen-since to cut shallow repos based on time
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (7 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 08/20] upload-pack: tighten number parsing at "deepen" lines Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 10/20] fetch-pack: use a common function for verbose printing Nguyễn Thái Ngọc Duy
` (11 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This should allow the user to say "create a shallow clone containing the
work from last year" (once the client side is fixed up, of course).
In theory deepen-since and deepen (aka --depth) can be used together to
draw the shallow boundary (whether it's intersection or union is up to
discussion, but if rev-list is used, it's likely intersection). However,
because deepen goes with a custom commit walker, we can't mix the two
yet.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/technical/pack-protocol.txt | 3 ++-
Documentation/technical/protocol-capabilities.txt | 9 +++++++
upload-pack.c | 33 +++++++++++++++++++++--
3 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index c6977bb..9251df1 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -219,7 +219,8 @@ out of what the server said it could do with the first 'want' line.
shallow-line = PKT-LINE("shallow" SP obj-id)
- depth-request = PKT-LINE("deepen" SP depth)
+ depth-request = PKT-LINE("deepen" SP depth) /
+ PKT-LINE("deepen-since" SP timestamp)
first-want = PKT-LINE("want" SP obj-id SP capability-list)
additional-want = PKT-LINE("want" SP obj-id)
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index eaab6b4..f08cc4e 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -179,6 +179,15 @@ This capability adds "deepen", "shallow" and "unshallow" commands to
the fetch-pack/upload-pack protocol so clients can request shallow
clones.
+deepen-since
+------------
+
+This capability adds "deepen-since" command to fetch-pack/upload-pack
+protocol so the client can request shallow clones that are cut at a
+specific time, instead of depth. Internally it's equivalent of doing
+"rev-list --max-age=<timestamp>" on the server side. "deepen-since"
+cannot be used with "deepen".
+
no-progress
-----------
diff --git a/upload-pack.c b/upload-pack.c
index 573ffa2..100b604 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -14,6 +14,7 @@
#include "sigchain.h"
#include "version.h"
#include "string-list.h"
+#include "argv-array.h"
static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
@@ -618,6 +619,8 @@ static void receive_needs(void)
struct object_array shallows = OBJECT_ARRAY_INIT;
int depth = 0;
int has_non_tip = 0;
+ unsigned long deepen_since = 0;
+ int deepen_rev_list = 0;
shallow_nr = 0;
for (;;) {
@@ -654,6 +657,16 @@ static void receive_needs(void)
die("Invalid deepen: %s", line);
continue;
}
+ if (skip_prefix(line, "deepen-since ", &arg)) {
+ char *end = NULL;
+ deepen_since = strtoul(arg, &end, 0);
+ if (!end || *end || !deepen_since ||
+ /* revisions.c's max_age -1 is special */
+ deepen_since == -1)
+ die("Invalid deepen-since: %s", line);
+ deepen_rev_list = 1;
+ continue;
+ }
if (!skip_prefix(line, "want ", &arg) ||
get_sha1_hex(arg, sha1_buf))
die("git upload-pack: protocol error, "
@@ -705,10 +718,26 @@ static void receive_needs(void)
if (!use_sideband && daemon_mode)
no_progress = 1;
- if (depth == 0 && shallows.nr == 0)
+ if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
return;
+ if (depth > 0 && deepen_rev_list)
+ die("--depth and --since cannot be used together");
if (depth > 0)
deepen(depth, &shallows);
+ else if (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=%lu", deepen_since);
+ for (i = 0; i < want_obj.nr; i++) {
+ struct object *o = want_obj.objects[i].item;
+ argv_array_push(&av, oid_to_hex(&o->oid));
+ }
+ deepen_by_rev_list(av.argc, av.argv, &shallows);
+ argv_array_clear(&av);
+ }
else
if (shallows.nr > 0) {
int i;
@@ -757,7 +786,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
int flag, void *cb_data)
{
static const char *capabilities = "multi_ack thin-pack side-band"
- " side-band-64k ofs-delta shallow no-progress"
+ " side-band-64k ofs-delta shallow deepen-since no-progress"
" include-tag multi_ack_detailed";
const char *refname_nons = strip_namespace(refname);
struct object_id peeled;
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 10/20] fetch-pack: use a common function for verbose printing
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (8 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 09/20] upload-pack: add deepen-since to cut shallow repos based on time Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 11/20] fetch-pack: use a separate flag for fetch in deepening mode Nguyễn Thái Ngọc Duy
` (10 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This reduces the number of "if (verbose)" which makes it a bit easier
to read imo. It also makes it easier to redirect all these printouts,
to a file for example.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
fetch-pack.c | 88 +++++++++++++++++++++++++++++-------------------------------
1 file changed, 42 insertions(+), 46 deletions(-)
diff --git a/fetch-pack.c b/fetch-pack.c
index 01e34b6..16917f9 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -50,6 +50,21 @@ static int non_common_revs, multi_ack, use_sideband;
#define ALLOW_REACHABLE_SHA1 02
static unsigned int allow_unadvertised_object_request;
+__attribute__((format (printf, 2, 3)))
+static inline void print_verbose(const struct fetch_pack_args *args,
+ const char *fmt, ...)
+{
+ va_list params;
+
+ if (!args->verbose)
+ return;
+
+ va_start(params, fmt);
+ vfprintf(stderr, fmt, params);
+ va_end(params);
+ fputc('\n', stderr);
+}
+
static void rev_list_push(struct commit *commit, int mark)
{
if (!(commit->object.flags & mark)) {
@@ -375,8 +390,7 @@ static int find_common(struct fetch_pack_args *args,
retval = -1;
while ((sha1 = get_rev())) {
packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1));
- if (args->verbose)
- fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
+ print_verbose(args, "have %s", sha1_to_hex(sha1));
in_vain++;
if (flush_at <= ++count) {
int ack;
@@ -397,9 +411,9 @@ static int find_common(struct fetch_pack_args *args,
consume_shallow_list(args, fd[0]);
do {
ack = get_ack(fd[0], result_sha1);
- if (args->verbose && ack)
- fprintf(stderr, "got ack %d %s\n", ack,
- sha1_to_hex(result_sha1));
+ if (ack)
+ print_verbose(args, "got ack %d %s", ack,
+ sha1_to_hex(result_sha1));
switch (ack) {
case ACK:
flushes = 0;
@@ -438,8 +452,7 @@ static int find_common(struct fetch_pack_args *args,
} while (ack);
flushes--;
if (got_continue && MAX_IN_VAIN < in_vain) {
- if (args->verbose)
- fprintf(stderr, "giving up\n");
+ print_verbose(args, "giving up");
break; /* give up */
}
}
@@ -449,8 +462,7 @@ done:
packet_buf_write(&req_buf, "done\n");
send_request(args, fd[1], &req_buf);
}
- if (args->verbose)
- fprintf(stderr, "done\n");
+ print_verbose(args, "done");
if (retval != 0) {
multi_ack = 0;
flushes++;
@@ -462,9 +474,8 @@ done:
while (flushes || multi_ack) {
int ack = get_ack(fd[0], result_sha1);
if (ack) {
- if (args->verbose)
- fprintf(stderr, "got ack (%d) %s\n", ack,
- sha1_to_hex(result_sha1));
+ print_verbose(args, "got ack (%d) %s", ack,
+ sha1_to_hex(result_sha1));
if (ack == ACK)
return 0;
multi_ack = 1;
@@ -509,9 +520,8 @@ static void mark_recent_complete_commits(struct fetch_pack_args *args,
unsigned long cutoff)
{
while (complete && cutoff <= complete->item->date) {
- if (args->verbose)
- fprintf(stderr, "Marking %s as complete\n",
- oid_to_hex(&complete->item->object.oid));
+ print_verbose(args, "Marking %s as complete",
+ oid_to_hex(&complete->item->object.oid));
pop_most_recent_commit(&complete, COMPLETE);
}
}
@@ -652,18 +662,12 @@ static int everything_local(struct fetch_pack_args *args,
o = lookup_object(remote);
if (!o || !(o->flags & COMPLETE)) {
retval = 0;
- if (!args->verbose)
- continue;
- fprintf(stderr,
- "want %s (%s)\n", sha1_to_hex(remote),
- ref->name);
+ print_verbose(args, "want %s (%s)", sha1_to_hex(remote),
+ ref->name);
continue;
}
- if (!args->verbose)
- continue;
- fprintf(stderr,
- "already have %s (%s)\n", sha1_to_hex(remote),
- ref->name);
+ print_verbose(args, "already have %s (%s)", sha1_to_hex(remote),
+ ref->name);
}
return retval;
}
@@ -810,39 +814,32 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
die("Server does not support shallow clients");
if (server_supports("multi_ack_detailed")) {
- if (args->verbose)
- fprintf(stderr, "Server supports multi_ack_detailed\n");
+ print_verbose(args, "Server supports multi_ack_detailed");
multi_ack = 2;
if (server_supports("no-done")) {
- if (args->verbose)
- fprintf(stderr, "Server supports no-done\n");
+ print_verbose(args, "Server supports no-done");
if (args->stateless_rpc)
no_done = 1;
}
}
else if (server_supports("multi_ack")) {
- if (args->verbose)
- fprintf(stderr, "Server supports multi_ack\n");
+ print_verbose(args, "Server supports multi_ack");
multi_ack = 1;
}
if (server_supports("side-band-64k")) {
- if (args->verbose)
- fprintf(stderr, "Server supports side-band-64k\n");
+ print_verbose(args, "Server supports side-band-64k");
use_sideband = 2;
}
else if (server_supports("side-band")) {
- if (args->verbose)
- fprintf(stderr, "Server supports side-band\n");
+ print_verbose(args, "Server supports side-band");
use_sideband = 1;
}
if (server_supports("allow-tip-sha1-in-want")) {
- if (args->verbose)
- fprintf(stderr, "Server supports allow-tip-sha1-in-want\n");
+ print_verbose(args, "Server supports allow-tip-sha1-in-want");
allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
}
if (server_supports("allow-reachable-sha1-in-want")) {
- if (args->verbose)
- fprintf(stderr, "Server supports allow-reachable-sha1-in-want\n");
+ print_verbose(args, "Server supports allow-reachable-sha1-in-want\n");
allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
}
if (!server_supports("thin-pack"))
@@ -851,17 +848,16 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
args->no_progress = 0;
if (!server_supports("include-tag"))
args->include_tag = 0;
- if (server_supports("ofs-delta")) {
- if (args->verbose)
- fprintf(stderr, "Server supports ofs-delta\n");
- } else
+ if (server_supports("ofs-delta"))
+ print_verbose(args, "Server supports ofs-delta");
+ else
prefer_ofs_delta = 0;
if ((agent_feature = server_feature_value("agent", &agent_len))) {
agent_supported = 1;
- if (args->verbose && agent_len)
- fprintf(stderr, "Server version is %.*s\n",
- agent_len, agent_feature);
+ if (agent_len)
+ print_verbose(args, "Server version is %.*s",
+ agent_len, agent_feature);
}
if (everything_local(args, &ref, sought, nr_sought)) {
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 11/20] fetch-pack: use a separate flag for fetch in deepening mode
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (9 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 10/20] fetch-pack: use a common function for verbose printing Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 12/20] fetch: define shallow boundary with --since Nguyễn Thái Ngọc Duy
` (9 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
The shallow repo could be deepened or shortened when then user gives
--depth. But in future that won't be the only way to deepen/shorten a
repo. Stop relying on args->depth in this mode. Future deepening
methods can simply set this flag on instead of updating all these if
expressions.
The new name "deepen" was chosen after the command to define shallow
boundary in pack protocol. New commands also follow this tradition.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
fetch-pack.c | 14 ++++++++------
fetch-pack.h | 1 +
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/fetch-pack.c b/fetch-pack.c
index 16917f9..e947514 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -197,7 +197,7 @@ enum ack_type {
static void consume_shallow_list(struct fetch_pack_args *args, int fd)
{
- if (args->stateless_rpc && args->depth > 0) {
+ if (args->stateless_rpc && args->deepen) {
/* If we sent a depth we will get back "duplicate"
* shallow and unshallow commands every time there
* is a block of have lines exchanged.
@@ -348,7 +348,7 @@ static int find_common(struct fetch_pack_args *args,
packet_buf_flush(&req_buf);
state_len = req_buf.len;
- if (args->depth > 0) {
+ if (args->deepen) {
char *line;
const char *arg;
unsigned char sha1[20];
@@ -557,7 +557,7 @@ static void filter_refs(struct fetch_pack_args *args,
}
if (!keep && args->fetch_all &&
- (!args->depth || !starts_with(ref->name, "refs/tags/")))
+ (!args->deepen || !starts_with(ref->name, "refs/tags/")))
keep = 1;
if (keep) {
@@ -627,7 +627,7 @@ static int everything_local(struct fetch_pack_args *args,
}
}
- if (!args->depth) {
+ if (!args->deepen) {
for_each_ref(mark_complete_oid, NULL);
for_each_alternate_ref(mark_alternate_complete, NULL);
commit_list_sort_by_date(&complete);
@@ -813,6 +813,8 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
die("Server does not support shallow clients");
+ if (args->depth > 0)
+ args->deepen = 1;
if (server_supports("multi_ack_detailed")) {
print_verbose(args, "Server supports multi_ack_detailed");
multi_ack = 2;
@@ -873,7 +875,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
if (args->stateless_rpc)
packet_flush(fd[1]);
- if (args->depth > 0)
+ if (args->deepen)
setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
NULL);
else if (si->nr_ours || si->nr_theirs)
@@ -940,7 +942,7 @@ static void update_shallow(struct fetch_pack_args *args,
int *status;
int i;
- if (args->depth > 0 && alternate_shallow_file) {
+ if (args->deepen && alternate_shallow_file) {
if (*alternate_shallow_file == '\0') { /* --unshallow */
unlink_or_warn(git_path_shallow());
rollback_lock_file(&shallow_lock);
diff --git a/fetch-pack.h b/fetch-pack.h
index bb7fd76..4d0adb0 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -25,6 +25,7 @@ struct fetch_pack_args {
unsigned self_contained_and_connected:1;
unsigned cloning:1;
unsigned update_shallow:1;
+ unsigned deepen:1;
};
/*
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 12/20] fetch: define shallow boundary with --since
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (10 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 11/20] fetch-pack: use a separate flag for fetch in deepening mode Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 13/20] clone: define shallow clone boundary based on time " Nguyễn Thái Ngọc Duy
` (8 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/fetch-options.txt | 4 ++++
builtin/fetch.c | 12 ++++++++++--
fetch-pack.c | 12 +++++++++++-
fetch-pack.h | 1 +
transport.c | 4 ++++
transport.h | 4 ++++
6 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 45583d8..ff6e6ad 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -13,6 +13,10 @@
to the specified number of commits from the tip of each remote
branch history. Tags for the deepened commits are not fetched.
+--since=<date>::
+ Deepen or shorten the history of a 'shallow' repository to
+ include all reachable commits after <date>.
+
--unshallow::
If the source repository is complete, convert a shallow
repository to a complete one, removing all the limitations
diff --git a/builtin/fetch.c b/builtin/fetch.c
index c85f347..3317152 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -36,8 +36,9 @@ static int prune = -1; /* unspecified */
static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;
static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-static int tags = TAGS_DEFAULT, unshallow, update_shallow;
+static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
static const char *depth;
+static const char *deepen_since;
static const char *upload_pack;
static struct strbuf default_rla = STRBUF_INIT;
static struct transport *gtransport;
@@ -112,6 +113,8 @@ static struct option builtin_fetch_options[] = {
OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
OPT_STRING(0, "depth", &depth, N_("depth"),
N_("deepen history of shallow clone")),
+ OPT_STRING(0, "since", &deepen_since, N_("time"),
+ N_("deepen history of shallow clone based on time")),
{ OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
N_("convert to a complete repository"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
@@ -751,7 +754,7 @@ static int quickfetch(struct ref *ref_map)
* really need to perform. Claiming failure now will ensure
* we perform the network exchange to deepen our history.
*/
- if (depth)
+ if (deepen)
return -1;
return check_everything_connected(iterate_ref_map, 1, &rm);
}
@@ -867,6 +870,8 @@ static struct transport *prepare_transport(struct remote *remote)
set_option(transport, TRANS_OPT_KEEP, "yes");
if (depth)
set_option(transport, TRANS_OPT_DEPTH, depth);
+ if (deepen_since)
+ set_option(transport, TRANS_OPT_DEEPEN_SINCE, deepen_since);
if (update_shallow)
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
return transport;
@@ -881,6 +886,7 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, NULL);
transport_set_option(transport, TRANS_OPT_DEPTH, "0");
+ transport_set_option(transport, TRANS_OPT_DEEPEN_SINCE, NULL);
fetch_refs(transport, ref_map);
if (gsecondary) {
@@ -1164,6 +1170,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
/* no need to be strict, transport_set_option() will validate it again */
if (depth && atoi(depth) < 1)
die(_("depth %s is not a positive number"), depth);
+ if (depth || deepen_since)
+ deepen = 1;
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
if (recurse_submodules_default) {
diff --git a/fetch-pack.c b/fetch-pack.c
index e947514..f26cef4 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -21,6 +21,7 @@ static int fetch_unpack_limit = -1;
static int unpack_limit = 100;
static int prefer_ofs_delta = 1;
static int no_done;
+static int deepen_since_ok;
static int fetch_fsck_objects = -1;
static int transfer_fsck_objects = -1;
static int agent_supported;
@@ -326,6 +327,7 @@ static int find_common(struct fetch_pack_args *args,
if (args->no_progress) strbuf_addstr(&c, " no-progress");
if (args->include_tag) strbuf_addstr(&c, " include-tag");
if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
+ if (deepen_since_ok) strbuf_addstr(&c, " deepen-since");
if (agent_supported) strbuf_addf(&c, " agent=%s",
git_user_agent_sanitized());
packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
@@ -345,6 +347,10 @@ static int find_common(struct fetch_pack_args *args,
write_shallow_commits(&req_buf, 1, NULL);
if (args->depth > 0)
packet_buf_write(&req_buf, "deepen %d", args->depth);
+ if (args->deepen_since) {
+ unsigned long max_age = approxidate(args->deepen_since);
+ packet_buf_write(&req_buf, "deepen-since %lu", max_age);
+ }
packet_buf_flush(&req_buf);
state_len = req_buf.len;
@@ -813,7 +819,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
die("Server does not support shallow clients");
- if (args->depth > 0)
+ if (args->depth > 0 || args->deepen_since)
args->deepen = 1;
if (server_supports("multi_ack_detailed")) {
print_verbose(args, "Server supports multi_ack_detailed");
@@ -861,6 +867,10 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
print_verbose(args, "Server version is %.*s",
agent_len, agent_feature);
}
+ if (server_supports("deepen-since"))
+ deepen_since_ok = 1;
+ else if (args->deepen_since)
+ die("Server does not support --since");
if (everything_local(args, &ref, sought, nr_sought)) {
packet_flush(fd[1]);
diff --git a/fetch-pack.h b/fetch-pack.h
index 4d0adb0..f7eadb2 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -10,6 +10,7 @@ struct fetch_pack_args {
const char *uploadpack;
int unpacklimit;
int depth;
+ const char *deepen_since;
unsigned quiet:1;
unsigned keep_pack:1;
unsigned lock_pack:1;
diff --git a/transport.c b/transport.c
index 67f3666..4902036 100644
--- a/transport.c
+++ b/transport.c
@@ -477,6 +477,9 @@ static int set_git_option(struct git_transport_options *opts,
die("transport: invalid depth option '%s'", value);
}
return 0;
+ } else if (!strcmp(name, TRANS_OPT_DEEPEN_SINCE)) {
+ opts->deepen_since = value;
+ return 0;
}
return 1;
}
@@ -530,6 +533,7 @@ static int fetch_refs_via_pack(struct transport *transport,
args.quiet = (transport->verbose < 0);
args.no_progress = !transport->progress;
args.depth = data->options.depth;
+ args.deepen_since = data->options.deepen_since;
args.check_self_contained_and_connected =
data->options.check_self_contained_and_connected;
args.cloning = transport->cloning;
diff --git a/transport.h b/transport.h
index 8ebaaf2..9c10a44 100644
--- a/transport.h
+++ b/transport.h
@@ -13,6 +13,7 @@ struct git_transport_options {
unsigned self_contained_and_connected : 1;
unsigned update_shallow : 1;
int depth;
+ const char *deepen_since;
const char *uploadpack;
const char *receivepack;
struct push_cas_option *cas;
@@ -171,6 +172,9 @@ int transport_restrict_protocols(void);
/* Limit the depth of the fetch if not null */
#define TRANS_OPT_DEPTH "depth"
+/* Limit the depth of the fetch based on time if not null */
+#define TRANS_OPT_DEEPEN_SINCE "deepen-since"
+
/* Aggressively fetch annotated tags if possible */
#define TRANS_OPT_FOLLOWTAGS "followtags"
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 13/20] clone: define shallow clone boundary based on time with --since
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (11 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 12/20] fetch: define shallow boundary with --since Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 14/20] Add test_repo_expect_success for running tests in a new repository Nguyễn Thái Ngọc Duy
` (7 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-clone.txt | 3 +++
builtin/clone.c | 16 +++++++++++++---
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 6bf000d..28993c6 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -192,6 +192,9 @@ objects from the source repository into a pack in the cloned repository.
Create a 'shallow' clone with a history truncated to the
specified number of revisions.
+--since=<date>::
+ Create a 'shallow' clone with a history after the specified time.
+
--[no-]single-branch::
Clone only the history leading to the tip of a single branch,
either specified by the `--branch` option or the primary
diff --git a/builtin/clone.c b/builtin/clone.c
index a0b3cd9..94bbfef 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -40,7 +40,8 @@ static const char * const builtin_clone_usage[] = {
static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
-static char *option_template, *option_depth;
+static int deepen;
+static char *option_template, *option_depth, *option_since;
static char *option_origin = NULL;
static char *option_branch = NULL;
static const char *real_git_dir;
@@ -86,6 +87,8 @@ static struct option builtin_clone_options[] = {
N_("path to git-upload-pack on the remote")),
OPT_STRING(0, "depth", &option_depth, N_("depth"),
N_("create a shallow clone of that depth")),
+ OPT_STRING(0, "since", &option_since, N_("time"),
+ N_("create a shallow clone since a specific time")),
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
@@ -846,8 +849,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
usage_msg_opt(_("You must specify a repository to clone."),
builtin_clone_usage, builtin_clone_options);
+ if (option_depth || option_since)
+ deepen = 1;
if (option_single_branch == -1)
- option_single_branch = option_depth ? 1 : 0;
+ option_single_branch = deepen ? 1 : 0;
if (option_mirror)
option_bare = 1;
@@ -973,6 +978,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (is_local) {
if (option_depth)
warning(_("--depth is ignored in local clones; use file:// instead."));
+ if (option_since)
+ warning(_("--since is ignored in local clones; use file:// instead."));
if (!access(mkpath("%s/shallow", path), F_OK)) {
if (option_local > 0)
warning(_("source repository is shallow, ignoring --local"));
@@ -991,6 +998,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_depth)
transport_set_option(transport, TRANS_OPT_DEPTH,
option_depth);
+ if (option_since)
+ transport_set_option(transport, TRANS_OPT_DEEPEN_SINCE,
+ option_since);
if (option_single_branch)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
@@ -998,7 +1008,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
transport_set_option(transport, TRANS_OPT_UPLOADPACK,
option_upload_pack);
- if (transport->smart_options && !option_depth)
+ if (transport->smart_options && !deepen)
transport->smart_options->check_self_contained_and_connected = 1;
refs = transport_get_remote_refs(transport);
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 14/20] Add test_repo_expect_success for running tests in a new repository
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (12 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 13/20] clone: define shallow clone boundary based on time " Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 14:12 ` Duy Nguyen
2015-12-29 12:10 ` [PATCH 15/20] t5500: test for shallow depth since a specific date Nguyễn Thái Ngọc Duy
` (6 subsequent siblings)
20 siblings, 1 reply; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This could be convenient when tests are independent from the rest in the
same file. Normally we would do this
test_expect_success '...' '
git init foo &&
(
cd foo &&
<script>
)
'
Now we can write a shorter version
test_repo_expect_success '...' '
<script>
'
The other function, test_subdir_expect_success, expands the script to
"( cd <repo> && <script> )", which can be useful for grouping a series of
tests that operate on the same repository in a subdir, e.g.
test_expect_success 'create repo abc' 'test_create_repo abc'
test_subdir_expect_success abc '...' <script>
test_subdir_expect_success abc '...' <another-script>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
t/README | 15 +++++++++++++++
t/test-lib-functions.sh | 20 ++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/t/README b/t/README
index 1dc908e..6fc0d92 100644
--- a/t/README
+++ b/t/README
@@ -743,6 +743,21 @@ library for your script to use.
the symbolic link in the file system and a part that does; then only
the latter part need be protected by a SYMLINKS prerequisite (see below).
+ - test_subdir_expect_success <subdir> [<prereq>] <message> <script>
+ test_subdir_expect_success <subdir> <prereq> <message> <script> <prologue>
+
+ Expands to
+
+ test_expect_success [<prereq>] <message> "( cd <subdir> && <script> )"
+ or
+
+ test_expect_success <prereq> <message> "<prologue> && ( cd <subdir> && <script> )"
+
+ - test_repo_expect_success [<prereq>] <message> <script>
+
+ Create a new repository and perform <script> inside this repository
+ in a subshell.
+
Prerequisites
-------------
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index c64e5a5..3182b9a 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -416,6 +416,26 @@ test_expect_success () {
test_finish_
}
+test_subdir_expect_success () {
+ local subdir="$1"
+ shift
+ case "$#" in
+ 2) test_expect_success "$1" "( cd $subdir && $2 )";;
+ 3) test_expect_success "$1" "$2" "( cd $subdir && $3 )";;
+ 4) test_expect_success "$1" "$2" "$4 && ( cd $subdir && $3 )";;
+ *) error "bug in the test script: not 3-5 parameters to test-subdir-expect-success";;
+ esac
+}
+
+test_repo_expect_success () {
+ local repo=repo-$(($test_count+1))
+ case "$#" in
+ 2) test_subdir_expect_success "$repo" '' "$1" "$2" "test_create_repo $repo";;
+ 3) test_subdir_expect_success "$repo" "$1" "$2" "$3" "test_create_repo $repo";;
+ *) error "bug in the test script: not 2 or 3 parameters to test-repo-expect-success";;
+ esac
+}
+
# test_external runs external test scripts that provide continuous
# test output about their progress, and succeeds/fails on
# zero/non-zero exit code. It outputs the test output on stdout even
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 15/20] t5500: test for shallow depth since a specific date
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (13 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 14/20] Add test_repo_expect_success for running tests in a new repository Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 16/20] upload-pack: support define shallow boundary by excluding revisions Nguyễn Thái Ngọc Duy
` (5 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
t/t5500-fetch-pack.sh | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 3a9b775..338b46e 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -637,4 +637,22 @@ test_expect_success MINGW 'fetch-pack --diag-url c:repo' '
check_prot_path c:repo file c:repo
'
+test_repo_expect_success 'clone shallow since ...' '
+ GIT_COMMITTER_DATE="100000000 +0700" git commit --allow-empty -m one &&
+ GIT_COMMITTER_DATE="200000000 +0700" git commit --allow-empty -m two &&
+ GIT_COMMITTER_DATE="300000000 +0700" git commit --allow-empty -m three &&
+ git clone --since "300000000 +0700" "file://$(pwd)/." ../shallow11 &&
+ git -C ../shallow11 log --pretty=tformat:%s HEAD >actual &&
+ echo three >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'fetch shallow since ...' '
+ git -C shallow11 fetch --since "200000000 +0700" origin &&
+ git -C shallow11 log --pretty=tformat:%s origin/master >actual &&
+ echo three >expected &&
+ echo two >>expected &&
+ test_cmp expected actual
+'
+
test_done
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 16/20] upload-pack: support define shallow boundary by excluding revisions
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (14 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 15/20] t5500: test for shallow depth since a specific date Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 17/20] fetch: define shallow boundary with --not Nguyễn Thái Ngọc Duy
` (4 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This should allow the user to say "create a shallow clone of this branch
after version <some-tag>".
deepen-not cannot be used with deepen the same way deepen-since cannot
be used with deepen. But deepen-not can be mixed with deepen-since. The
result is exactly how you do the command "git rev-list --since=... --not
ref".
FIXME: restrict dwim_ref. Access to reflog at server side may not be a
good idea. Either that or force the user to specify full ref names at
client side (a bit annoying).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/technical/pack-protocol.txt | 3 ++-
Documentation/technical/protocol-capabilities.txt | 9 +++++++++
upload-pack.c | 24 +++++++++++++++++++++--
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 9251df1..dee33a6 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -220,7 +220,8 @@ out of what the server said it could do with the first 'want' line.
shallow-line = PKT-LINE("shallow" SP obj-id)
depth-request = PKT-LINE("deepen" SP depth) /
- PKT-LINE("deepen-since" SP timestamp)
+ PKT-LINE("deepen-since" SP timestamp) /
+ PKT-LINE("deepen-not" SP ref)
first-want = PKT-LINE("want" SP obj-id SP capability-list)
additional-want = PKT-LINE("want" SP obj-id)
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index f08cc4e..0e6b57d 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -188,6 +188,15 @@ specific time, instead of depth. Internally it's equivalent of doing
"rev-list --max-age=<timestamp>" on the server side. "deepen-since"
cannot be used with "deepen".
+deepen-not
+----------
+
+This capability adds "deepen-not" command to fetch-pack/upload-pack
+protocol so the client can request shallow clones that are cut at a
+specific revision, instead of depth. Internally it's equivalent of
+doing "rev-list --not <rev>" on the server side. "deepen-not"
+cannot be used with "deepen", but can be used with "deepen-since".
+
no-progress
-----------
diff --git a/upload-pack.c b/upload-pack.c
index 100b604..90ecb5b 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -617,6 +617,7 @@ static void deepen_by_rev_list(int ac, const char **av,
static void receive_needs(void)
{
struct object_array shallows = OBJECT_ARRAY_INIT;
+ struct string_list deepen_not = STRING_LIST_INIT_DUP;
int depth = 0;
int has_non_tip = 0;
unsigned long deepen_since = 0;
@@ -667,6 +668,18 @@ static void receive_needs(void)
deepen_rev_list = 1;
continue;
}
+ if (skip_prefix(line, "deepen-not ", &arg)) {
+ char *ref = NULL;
+ unsigned char sha1[20];
+ if (dwim_ref(arg, strlen(arg), sha1, &ref) != 1)
+ die("Ambiguous deepen-not: %s", line);
+ if (!ref || check_refname_format(ref, 0))
+ die("Invalid deepen-not: %s", line);
+ string_list_append(&deepen_not, ref);
+ free(ref);
+ deepen_rev_list = 1;
+ continue;
+ }
if (!skip_prefix(line, "want ", &arg) ||
get_sha1_hex(arg, sha1_buf))
die("git upload-pack: protocol error, "
@@ -721,7 +734,7 @@ static void receive_needs(void)
if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
return;
if (depth > 0 && deepen_rev_list)
- die("--depth and --since cannot be used together");
+ die("--depth and --since (or --not) cannot be used together");
if (depth > 0)
deepen(depth, &shallows);
else if (deepen_rev_list) {
@@ -735,6 +748,13 @@ static void receive_needs(void)
struct object *o = want_obj.objects[i].item;
argv_array_push(&av, oid_to_hex(&o->oid));
}
+ if (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;
+ argv_array_push(&av, s->string);
+ }
+ }
deepen_by_rev_list(av.argc, av.argv, &shallows);
argv_array_clear(&av);
}
@@ -786,7 +806,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
int flag, void *cb_data)
{
static const char *capabilities = "multi_ack thin-pack side-band"
- " side-band-64k ofs-delta shallow deepen-since no-progress"
+ " side-band-64k ofs-delta shallow deepen-since deepen-not no-progress"
" include-tag multi_ack_detailed";
const char *refname_nons = strip_namespace(refname);
struct object_id peeled;
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 17/20] fetch: define shallow boundary with --not
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (15 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 16/20] upload-pack: support define shallow boundary by excluding revisions Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 18/20] clone: define shallow clone " Nguyễn Thái Ngọc Duy
` (3 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/fetch-options.txt | 5 +++++
builtin/fetch.c | 17 ++++++++++++++++-
fetch-pack.c | 15 ++++++++++++++-
fetch-pack.h | 1 +
transport.c | 4 ++++
transport.h | 6 ++++++
6 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index ff6e6ad..39fbcc3 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -17,6 +17,11 @@
Deepen or shorten the history of a 'shallow' repository to
include all reachable commits after <date>.
+--not=<revision>::
+ Deepen or shorten the history of a 'shallow' repository to
+ exclude commits reachable from a specified remote branch or tag.
+ This option can be specified multiple times.
+
--unshallow::
If the source repository is complete, convert a shallow
repository to a complete one, removing all the limitations
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 3317152..02a50e4 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -40,6 +40,7 @@ static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
static const char *depth;
static const char *deepen_since;
static const char *upload_pack;
+struct string_list deepen_not = STRING_LIST_INIT_NODUP;
static struct strbuf default_rla = STRBUF_INIT;
static struct transport *gtransport;
static struct transport *gsecondary;
@@ -49,6 +50,13 @@ static int shown_url = 0;
static int refmap_alloc, refmap_nr;
static const char **refmap_array;
+static int option_parse_deepen_not(const struct option *opt,
+ const char *arg, int unset)
+{
+ string_list_append(&deepen_not, arg);
+ return 0;
+}
+
static int option_parse_recurse_submodules(const struct option *opt,
const char *arg, int unset)
{
@@ -115,6 +123,9 @@ static struct option builtin_fetch_options[] = {
N_("deepen history of shallow clone")),
OPT_STRING(0, "since", &deepen_since, N_("time"),
N_("deepen history of shallow clone based on time")),
+ { OPTION_CALLBACK, 0, "not", NULL, N_("revision"),
+ N_("deepen history of shallow clone by excluding rev"),
+ PARSE_OPT_NONEG, option_parse_deepen_not },
{ OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
N_("convert to a complete repository"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
@@ -872,6 +883,9 @@ static struct transport *prepare_transport(struct remote *remote)
set_option(transport, TRANS_OPT_DEPTH, depth);
if (deepen_since)
set_option(transport, TRANS_OPT_DEEPEN_SINCE, deepen_since);
+ if (deepen_not.nr)
+ set_option(transport, TRANS_OPT_DEEPEN_NOT,
+ (const char *)&deepen_not);
if (update_shallow)
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
return transport;
@@ -887,6 +901,7 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, NULL);
transport_set_option(transport, TRANS_OPT_DEPTH, "0");
transport_set_option(transport, TRANS_OPT_DEEPEN_SINCE, NULL);
+ transport_set_option(transport, TRANS_OPT_DEEPEN_NOT, NULL);
fetch_refs(transport, ref_map);
if (gsecondary) {
@@ -1170,7 +1185,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
/* no need to be strict, transport_set_option() will validate it again */
if (depth && atoi(depth) < 1)
die(_("depth %s is not a positive number"), depth);
- if (depth || deepen_since)
+ if (depth || deepen_since || deepen_not.nr)
deepen = 1;
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
diff --git a/fetch-pack.c b/fetch-pack.c
index f26cef4..45f69de 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -22,6 +22,7 @@ static int unpack_limit = 100;
static int prefer_ofs_delta = 1;
static int no_done;
static int deepen_since_ok;
+static int deepen_not_ok;
static int fetch_fsck_objects = -1;
static int transfer_fsck_objects = -1;
static int agent_supported;
@@ -328,6 +329,7 @@ static int find_common(struct fetch_pack_args *args,
if (args->include_tag) strbuf_addstr(&c, " include-tag");
if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
if (deepen_since_ok) strbuf_addstr(&c, " deepen-since");
+ if (deepen_not_ok) strbuf_addstr(&c, " deepen-not");
if (agent_supported) strbuf_addf(&c, " agent=%s",
git_user_agent_sanitized());
packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
@@ -351,6 +353,13 @@ static int find_common(struct fetch_pack_args *args,
unsigned long max_age = approxidate(args->deepen_since);
packet_buf_write(&req_buf, "deepen-since %lu", max_age);
}
+ if (args->deepen_not) {
+ int i;
+ for (i = 0; i < args->deepen_not->nr; i++) {
+ struct string_list_item *s = args->deepen_not->items + i;
+ packet_buf_write(&req_buf, "deepen-not %s", s->string);
+ }
+ }
packet_buf_flush(&req_buf);
state_len = req_buf.len;
@@ -819,7 +828,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
die("Server does not support shallow clients");
- if (args->depth > 0 || args->deepen_since)
+ if (args->depth > 0 || args->deepen_since || args->deepen_not)
args->deepen = 1;
if (server_supports("multi_ack_detailed")) {
print_verbose(args, "Server supports multi_ack_detailed");
@@ -871,6 +880,10 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
deepen_since_ok = 1;
else if (args->deepen_since)
die("Server does not support --since");
+ if (server_supports("deepen-not"))
+ deepen_not_ok = 1;
+ else if (args->deepen_not)
+ die("Server does not support --not");
if (everything_local(args, &ref, sought, nr_sought)) {
packet_flush(fd[1]);
diff --git a/fetch-pack.h b/fetch-pack.h
index f7eadb2..144301f 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -11,6 +11,7 @@ struct fetch_pack_args {
int unpacklimit;
int depth;
const char *deepen_since;
+ const struct string_list *deepen_not;
unsigned quiet:1;
unsigned keep_pack:1;
unsigned lock_pack:1;
diff --git a/transport.c b/transport.c
index 4902036..3094c6b 100644
--- a/transport.c
+++ b/transport.c
@@ -480,6 +480,9 @@ static int set_git_option(struct git_transport_options *opts,
} else if (!strcmp(name, TRANS_OPT_DEEPEN_SINCE)) {
opts->deepen_since = value;
return 0;
+ } else if (!strcmp(name, TRANS_OPT_DEEPEN_NOT)) {
+ opts->deepen_not = (const struct string_list *)value;
+ return 0;
}
return 1;
}
@@ -534,6 +537,7 @@ static int fetch_refs_via_pack(struct transport *transport,
args.no_progress = !transport->progress;
args.depth = data->options.depth;
args.deepen_since = data->options.deepen_since;
+ args.deepen_not = data->options.deepen_not;
args.check_self_contained_and_connected =
data->options.check_self_contained_and_connected;
args.cloning = transport->cloning;
diff --git a/transport.h b/transport.h
index 9c10a44..ab61932 100644
--- a/transport.h
+++ b/transport.h
@@ -5,6 +5,8 @@
#include "run-command.h"
#include "remote.h"
+struct string_list;
+
struct git_transport_options {
unsigned thin : 1;
unsigned keep : 1;
@@ -14,6 +16,7 @@ struct git_transport_options {
unsigned update_shallow : 1;
int depth;
const char *deepen_since;
+ const struct string_list *deepen_not;
const char *uploadpack;
const char *receivepack;
struct push_cas_option *cas;
@@ -175,6 +178,9 @@ int transport_restrict_protocols(void);
/* Limit the depth of the fetch based on time if not null */
#define TRANS_OPT_DEEPEN_SINCE "deepen-since"
+/* Limit the depth of the fetch based on revs if not null */
+#define TRANS_OPT_DEEPEN_NOT "deepen-not"
+
/* Aggressively fetch annotated tags if possible */
#define TRANS_OPT_FOLLOWTAGS "followtags"
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 18/20] clone: define shallow clone boundary with --not
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (16 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 17/20] fetch: define shallow boundary with --not Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 19/20] t5500: test for shallow depth excluding a ref Nguyễn Thái Ngọc Duy
` (2 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-clone.txt | 5 +++++
builtin/clone.c | 18 +++++++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 28993c6..3589e57 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -195,6 +195,11 @@ objects from the source repository into a pack in the cloned repository.
--since=<date>::
Create a 'shallow' clone with a history after the specified time.
+--not=<revision>::
+ Create a 'shallow' clone with a history, excluding commits
+ reachable from a specified remote branch or tag. This option
+ can be specified multiple times.
+
--[no-]single-branch::
Clone only the history leading to the tip of a single branch,
either specified by the `--branch` option or the primary
diff --git a/builtin/clone.c b/builtin/clone.c
index 94bbfef..0e99354 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -44,6 +44,7 @@ static int deepen;
static char *option_template, *option_depth, *option_since;
static char *option_origin = NULL;
static char *option_branch = NULL;
+static struct string_list option_not = STRING_LIST_INIT_NODUP;
static const char *real_git_dir;
static char *option_upload_pack = "git-upload-pack";
static int option_verbosity;
@@ -52,6 +53,13 @@ static struct string_list option_config;
static struct string_list option_reference;
static int option_dissociate;
+static int option_parse_deepen_not(const struct option *opt,
+ const char *arg, int unset)
+{
+ string_list_append(&option_not, arg);
+ return 0;
+}
+
static struct option builtin_clone_options[] = {
OPT__VERBOSITY(&option_verbosity),
OPT_BOOL(0, "progress", &option_progress,
@@ -89,6 +97,9 @@ static struct option builtin_clone_options[] = {
N_("create a shallow clone of that depth")),
OPT_STRING(0, "since", &option_since, N_("time"),
N_("create a shallow clone since a specific time")),
+ { OPTION_CALLBACK, 0, "not", NULL, N_("revision"),
+ N_("deepen history of shallow clone by excluding rev"),
+ PARSE_OPT_NONEG, option_parse_deepen_not },
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
@@ -849,7 +860,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
usage_msg_opt(_("You must specify a repository to clone."),
builtin_clone_usage, builtin_clone_options);
- if (option_depth || option_since)
+ if (option_depth || option_since || option_not.nr)
deepen = 1;
if (option_single_branch == -1)
option_single_branch = deepen ? 1 : 0;
@@ -980,6 +991,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
warning(_("--depth is ignored in local clones; use file:// instead."));
if (option_since)
warning(_("--since is ignored in local clones; use file:// instead."));
+ if (option_not.nr)
+ warning(_("--not is ignored in local clones; use file:// instead."));
if (!access(mkpath("%s/shallow", path), F_OK)) {
if (option_local > 0)
warning(_("source repository is shallow, ignoring --local"));
@@ -1001,6 +1014,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_since)
transport_set_option(transport, TRANS_OPT_DEEPEN_SINCE,
option_since);
+ if (option_not.nr)
+ transport_set_option(transport, TRANS_OPT_DEEPEN_NOT,
+ (const char *)&option_not);
if (option_single_branch)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 19/20] t5500: test for shallow depth excluding a ref
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (17 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 18/20] clone: define shallow clone " Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2015-12-29 12:10 ` [PATCH 20/20] fetch: add --deepen=<N> to extend shallow boundary by <N> commits Nguyễn Thái Ngọc Duy
2015-12-29 19:09 ` [PATCH 00/20] More flexibility in making shallow clones Junio C Hamano
20 siblings, 0 replies; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
t/t5500-fetch-pack.sh | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 338b46e..2259631 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -655,4 +655,22 @@ test_expect_success 'fetch shallow since ...' '
test_cmp expected actual
'
+test_repo_expect_success 'shallow clone exclude tag two' '
+ test_commit one &&
+ test_commit two &&
+ test_commit three &&
+ git clone --not two "file://$(pwd)/." ../shallow12 &&
+ git -C ../shallow12 log --pretty=tformat:%s HEAD >actual &&
+ echo three >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'fetch exclude tag one' '
+ git -C shallow12 fetch --not one origin &&
+ git -C shallow12 log --pretty=tformat:%s origin/master >actual &&
+ echo three >expected &&
+ echo two >>expected &&
+ test_cmp expected actual
+'
+
test_done
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 20/20] fetch: add --deepen=<N> to extend shallow boundary by <N> commits
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (18 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 19/20] t5500: test for shallow depth excluding a ref Nguyễn Thái Ngọc Duy
@ 2015-12-29 12:10 ` Nguyễn Thái Ngọc Duy
2016-01-04 9:45 ` Eric Sunshine
2015-12-29 19:09 ` [PATCH 00/20] More flexibility in making shallow clones Junio C Hamano
20 siblings, 1 reply; 24+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2015-12-29 12:10 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy, Dongcan Jiang
In git-fetch, --depth argument is always relative with the latest
remote refs. This makes it a bit difficult to cover this use case,
where the user wants to make the shallow history, say 3 levels
deeper. It would work if remote refs have not moved yet, but nobody
can guarantee that, especially when that use case is performed a
couple months after the last clone or "git fetch --depth". Also,
modifying shallow boundary using --depth does not work well with
clones created by --since or --not.
This patch fixes that. A new argument --deepen=<N> will add <N> more (*)
parent commits to the current history regardless of where remote refs
are. Note that "git fetch --deepen" also fetches latest changes (so
updates happen on both shallow and ref ends). This is mostly to ease
the verification task at server side.
The main work was done by Dongcan Jiang. I fixed it up here and there.
And of course all the bugs belong to me.
(*) We could even support --deepen=<N> where <N> is negative. In that
case we can cut some history from the shallow clone. This operation
(and --depth=<shorter depth>) does not require interaction with remote
side (and more complicated to implement as a result).
Helped-by: Duy Nguyen <pclouds@gmail.com>
Helped-By: Eric Sunshine <sunshine@sunshineco.com>
Helped-By: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Dongcan Jiang <dongcan.jiang@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/fetch-options.txt | 5 +++++
Documentation/technical/protocol-capabilities.txt | 7 +++++++
builtin/fetch.c | 17 +++++++++++++++--
fetch-pack.c | 3 +++
fetch-pack.h | 1 +
t/t5510-fetch.sh | 12 ++++++++++++
transport.c | 3 +++
transport.h | 4 ++++
upload-pack.c | 14 ++++++++++++--
9 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 39fbcc3..c12f1c5 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -13,6 +13,11 @@
to the specified number of commits from the tip of each remote
branch history. Tags for the deepened commits are not fetched.
+--deepen=<depth>::
+ Similar to --depth, except it specifies the number of commits
+ from the current shallow boundary instead of from the tip of
+ reach remote branch history.
+
--since=<date>::
Deepen or shorten the history of a 'shallow' repository to
include all reachable commits after <date>.
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index 0e6b57d..f732a41 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -197,6 +197,13 @@ specific revision, instead of depth. Internally it's equivalent of
doing "rev-list --not <rev>" on the server side. "deepen-not"
cannot be used with "deepen", but can be used with "deepen-since".
+deepen-relative
+---------------
+
+If this capacity is requested by the client, the semantics of "deepen"
+command is changed. The "depth" argument is the depth from the current
+shallow boundary, instead of the depth from remote refs.
+
no-progress
-----------
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 02a50e4..0aff238 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -34,7 +34,7 @@ static int fetch_prune_config = -1; /* unspecified */
static int prune = -1; /* unspecified */
#define PRUNE_BY_DEFAULT 0 /* do we prune by default? */
-static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;
+static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity, deepen_relative;
static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
static const char *depth;
@@ -126,6 +126,8 @@ static struct option builtin_fetch_options[] = {
{ OPTION_CALLBACK, 0, "not", NULL, N_("revision"),
N_("deepen history of shallow clone by excluding rev"),
PARSE_OPT_NONEG, option_parse_deepen_not },
+ OPT_INTEGER(0, "deepen", &deepen_relative,
+ N_("deepen history of shallow clone")),
{ OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
N_("convert to a complete repository"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
@@ -775,7 +777,7 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
int ret = quickfetch(ref_map);
if (ret)
ret = transport_fetch_refs(transport, ref_map);
- if (!ret)
+ if (!ret && !deepen_relative)
ret |= store_updated_refs(transport->url,
transport->remote->name,
ref_map);
@@ -886,6 +888,8 @@ static struct transport *prepare_transport(struct remote *remote)
if (deepen_not.nr)
set_option(transport, TRANS_OPT_DEEPEN_NOT,
(const char *)&deepen_not);
+ if (deepen_relative)
+ set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, "yes");
if (update_shallow)
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
return transport;
@@ -1185,6 +1189,15 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
/* no need to be strict, transport_set_option() will validate it again */
if (depth && atoi(depth) < 1)
die(_("depth %s is not a positive number"), depth);
+ if (deepen_relative) {
+ struct strbuf sb = STRBUF_INIT;
+ if (deepen_relative < 0)
+ die(_("Negative depth in --deepen is not supported"));
+ if (depth)
+ die(_("--deepen and --depth are mutually exclusive"));
+ strbuf_addf(&sb, "%d", deepen_relative);
+ depth = strbuf_detach(&sb, NULL);
+ }
if (depth || deepen_since || deepen_not.nr)
deepen = 1;
diff --git a/fetch-pack.c b/fetch-pack.c
index 45f69de..67cbb7a 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -324,6 +324,7 @@ static int find_common(struct fetch_pack_args *args,
if (no_done) strbuf_addstr(&c, " no-done");
if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k");
if (use_sideband == 1) strbuf_addstr(&c, " side-band");
+ if (args->deepen_relative) strbuf_addstr(&c, " deepen-relative");
if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack");
if (args->no_progress) strbuf_addstr(&c, " no-progress");
if (args->include_tag) strbuf_addstr(&c, " include-tag");
@@ -884,6 +885,8 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
deepen_not_ok = 1;
else if (args->deepen_not)
die("Server does not support --not");
+ if (!server_supports("deepen-relative") && args->deepen_relative)
+ die("Server does not support --deepen");
if (everything_local(args, &ref, sought, nr_sought)) {
packet_flush(fd[1]);
diff --git a/fetch-pack.h b/fetch-pack.h
index 144301f..c912e3d 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -12,6 +12,7 @@ struct fetch_pack_args {
int depth;
const char *deepen_since;
const struct string_list *deepen_not;
+ unsigned deepen_relative:1;
unsigned quiet:1;
unsigned keep_pack:1;
unsigned lock_pack:1;
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 0ba9db0..760cd23 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -708,4 +708,16 @@ test_expect_success 'fetching a one-level ref works' '
)
'
+test_expect_success 'fetching deepen' '
+ git clone . deepen --depth=1 && (
+ cd deepen &&
+ git fetch .. foo --depth=1
+ git show foo
+ test_must_fail git show foo~
+ git fetch .. foo --deepen=1
+ git show foo~
+ test_must_fail git show foo~2
+ )
+'
+
test_done
diff --git a/transport.c b/transport.c
index 3094c6b..2f3823a 100644
--- a/transport.c
+++ b/transport.c
@@ -482,6 +482,8 @@ static int set_git_option(struct git_transport_options *opts,
return 0;
} else if (!strcmp(name, TRANS_OPT_DEEPEN_NOT)) {
opts->deepen_not = (const struct string_list *)value;
+ } else if (!strcmp(name, TRANS_OPT_DEEPEN_RELATIVE)) {
+ opts->deepen_relative = !!value;
return 0;
}
return 1;
@@ -538,6 +540,7 @@ static int fetch_refs_via_pack(struct transport *transport,
args.depth = data->options.depth;
args.deepen_since = data->options.deepen_since;
args.deepen_not = data->options.deepen_not;
+ args.deepen_relative = data->options.deepen_relative;
args.check_self_contained_and_connected =
data->options.check_self_contained_and_connected;
args.cloning = transport->cloning;
diff --git a/transport.h b/transport.h
index ab61932..bdc3518 100644
--- a/transport.h
+++ b/transport.h
@@ -14,6 +14,7 @@ struct git_transport_options {
unsigned check_self_contained_and_connected : 1;
unsigned self_contained_and_connected : 1;
unsigned update_shallow : 1;
+ unsigned deepen_relative : 1;
int depth;
const char *deepen_since;
const struct string_list *deepen_not;
@@ -181,6 +182,9 @@ int transport_restrict_protocols(void);
/* Limit the depth of the fetch based on revs if not null */
#define TRANS_OPT_DEEPEN_NOT "deepen-not"
+/* Limit the deepen of the fetch if not null */
+#define TRANS_OPT_DEEPEN_RELATIVE "deepen-relative"
+
/* Aggressively fetch annotated tags if possible */
#define TRANS_OPT_FOLLOWTAGS "followtags"
diff --git a/upload-pack.c b/upload-pack.c
index 90ecb5b..5384411 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -32,6 +32,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<
static unsigned long oldest_have;
+static int deepen_relative;
static int multi_ack;
static int no_done;
static int use_thin_pack, use_ofs_delta, use_include_tag;
@@ -583,7 +584,8 @@ static void send_unshallow(const struct object_array *shallows)
}
}
-static void deepen(int depth, const struct object_array *shallows)
+static void deepen(int depth, int deepen_relative,
+ struct object_array *shallows)
{
struct commit_list *result = NULL;
int i;
@@ -592,6 +594,9 @@ static void deepen(int depth, const struct object_array *shallows)
struct object *object = shallows->objects[i].item;
object->flags |= NOT_SHALLOW;
}
+ else if (deepen_relative)
+ result = get_shallow_commits(shallows, depth + 1,
+ SHALLOW, NOT_SHALLOW);
else
result =
get_shallow_commits(&want_obj, depth,
@@ -687,6 +692,8 @@ static void receive_needs(void)
features = arg + 40;
+ if (parse_feature_request(features, "deepen-relative"))
+ deepen_relative = 1;
if (parse_feature_request(features, "multi_ack_detailed"))
multi_ack = 2;
else if (parse_feature_request(features, "multi_ack"))
@@ -706,6 +713,9 @@ static void receive_needs(void)
if (parse_feature_request(features, "include-tag"))
use_include_tag = 1;
+ if (deepen_relative)
+ continue;
+
o = parse_object(sha1_buf);
if (!o)
die("git upload-pack: not our ref %s",
@@ -736,7 +746,7 @@ static void receive_needs(void)
if (depth > 0 && deepen_rev_list)
die("--depth and --since (or --not) cannot be used together");
if (depth > 0)
- deepen(depth, &shallows);
+ deepen(depth, deepen_relative, &shallows);
else if (deepen_rev_list) {
struct argv_array av = ARGV_ARRAY_INIT;
int i;
--
2.3.0.rc1.137.g477eb31
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 20/20] fetch: add --deepen=<N> to extend shallow boundary by <N> commits
2015-12-29 12:10 ` [PATCH 20/20] fetch: add --deepen=<N> to extend shallow boundary by <N> commits Nguyễn Thái Ngọc Duy
@ 2016-01-04 9:45 ` Eric Sunshine
0 siblings, 0 replies; 24+ messages in thread
From: Eric Sunshine @ 2016-01-04 9:45 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: Git List, Dongcan Jiang
On Tue, Dec 29, 2015 at 7:10 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> In git-fetch, --depth argument is always relative with the latest
> remote refs. This makes it a bit difficult to cover this use case,
> where the user wants to make the shallow history, say 3 levels
> deeper. It would work if remote refs have not moved yet, but nobody
> can guarantee that, especially when that use case is performed a
> couple months after the last clone or "git fetch --depth". Also,
> modifying shallow boundary using --depth does not work well with
> clones created by --since or --not.
> [...]
>
> Helped-by: Duy Nguyen <pclouds@gmail.com>
> Helped-By: Eric Sunshine <sunshine@sunshineco.com>
s/By/by/
> Helped-By: Junio C Hamano <gitster@pobox.com>
Ditto.
> Signed-off-by: Dongcan Jiang <dongcan.jiang@gmail.com>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
> diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
> @@ -13,6 +13,11 @@
> +--deepen=<depth>::
> + Similar to --depth, except it specifies the number of commits
> + from the current shallow boundary instead of from the tip of
> + reach remote branch history.
Did you mean s/reach/each/ ?
> diff --git a/builtin/fetch.c b/builtin/fetch.c
> @@ -1185,6 +1189,15 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
> /* no need to be strict, transport_set_option() will validate it again */
> if (depth && atoi(depth) < 1)
> die(_("depth %s is not a positive number"), depth);
> + if (deepen_relative) {
> + struct strbuf sb = STRBUF_INIT;
> + if (deepen_relative < 0)
> + die(_("Negative depth in --deepen is not supported"));
> + if (depth)
> + die(_("--deepen and --depth are mutually exclusive"));
> + strbuf_addf(&sb, "%d", deepen_relative);
> + depth = strbuf_detach(&sb, NULL);
Maybe replace:
struct strbuf sb = STRBUF_INIT;
...
strbuf_addf(&sb, "%d", deepen_relative);
depth = strbuf_detach(&sb, NULL);
with:
depth = xstrfmt("%d", deepen_relative);
?
> + }
> if (depth || deepen_since || deepen_not.nr)
> deepen = 1;
> diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
> @@ -708,4 +708,16 @@ test_expect_success 'fetching a one-level ref works' '
> +test_expect_success 'fetching deepen' '
> + git clone . deepen --depth=1 && (
Style: ( on its own line.
> + cd deepen &&
> + git fetch .. foo --depth=1
> + git show foo
Are these git-show instances merely for checking if a ref is valid? If
so, perhaps git-rev-parse would be clearer?
> + test_must_fail git show foo~
> + git fetch .. foo --deepen=1
> + git show foo~
> + test_must_fail git show foo~2
&&-chain heavily broken in subshell.
> + )
> +'
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 00/20] More flexibility in making shallow clones
2015-12-29 12:10 [PATCH 00/20] More flexibility in making shallow clones Nguyễn Thái Ngọc Duy
` (19 preceding siblings ...)
2015-12-29 12:10 ` [PATCH 20/20] fetch: add --deepen=<N> to extend shallow boundary by <N> commits Nguyễn Thái Ngọc Duy
@ 2015-12-29 19:09 ` Junio C Hamano
20 siblings, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2015-12-29 19:09 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> This series brings three new options to shallow clone/fetch. --since
> lets you specify cut point by time. --not cuts by excluding specified
> refs. And --deepen=<N> extends shallow boundary in a more predictable
> way. Some of these were requested in the past.
Hmm, is this --deepen=<N> a response to the "--depth=<N> after too
long a time since the clone may even lose the originally acquired
history because the tip has advanced more than <N>"? If that is so,
I guess it is a welcome change ;-)
> An important point of this series is it starts to use rev-list behind
> the scene to define shallow boundary, which opens doors to even more
> ways of cutting a repository.
>
> The series is good enough to look at but I don't think I have stared
> long enough to spot all the bugs. This mail is mostly about checking
> if the design (at both code and protocol levels) and the UI make
> sense. I'm thinking --since and --not may be too generic, but I don't
> see any better names, for example.
>
> Refactor/cleanup patches are sprinkled throughout (bad?). The meat is
> in 05, 09, 12, 13, 16, 17, 18 and 20.
Thanks. As an initial "how about going in this direction?"
weatherbaloon, the order of changes are less important, but as the
topic gets closer to the final, it would be nicer to see preparatory
things done as, eh, preparatory steps ;-)
> HTTP support is not in this series (and I don't intend to do soon).
> The amount of filler code just to pass some info from UI down to the
> protocol seems too much, and it's even more so when HTTP support is
> added. But I don't see anyway around it. Maybe we can share some code
> between git-clone, git-fetch and git-fetch-pack, at least the argument
> parsing..
>
> Nguyễn Thái Ngọc Duy (20):
> upload-pack: move shallow deepen code out of receive_needs()
> upload-pack: move "shallow" sending code out of deepen()
> upload-pack: remove unused variable "backup"
> upload-pack: move "unshallow" sending code out of deepen()
> shallow.c: implement a generic shallow boundary finder based on rev-list
> upload-pack: glue code to use get_shallow_commits_by_rev_list
> upload-pack: use skip_prefix() instead of starts_with() when possible
> upload-pack: tighten number parsing at "deepen" lines
> upload-pack: add deepen-since to cut shallow repos based on time
> fetch-pack: use a common function for verbose printing
> fetch-pack: use a separate flag for fetch in deepening mode
> fetch: define shallow boundary with --since
> clone: define shallow clone boundary based on time with --since
> Add test_repo_expect_success for running tests in a new repository
> t5500: test for shallow depth since a specific date
> upload-pack: support define shallow boundary by excluding revisions
> fetch: define shallow boundary with --not
> clone: define shallow clone boundary with --not
> t5500: test for shallow depth excluding a ref
> fetch: add --deepen=<N> to extend shallow boundary by <N> commits
>
> Documentation/fetch-options.txt | 14 ++
> Documentation/git-clone.txt | 8 +
> Documentation/technical/pack-protocol.txt | 4 +-
> Documentation/technical/protocol-capabilities.txt | 25 +++
> builtin/clone.c | 32 +++-
> builtin/fetch.c | 44 ++++-
> commit.h | 2 +
> fetch-pack.c | 128 ++++++++------
> fetch-pack.h | 4 +
> shallow.c | 92 ++++++++++
> t/README | 15 ++
> t/t5500-fetch-pack.sh | 36 ++++
> t/t5510-fetch.sh | 12 ++
> t/test-lib-functions.sh | 20 +++
> transport.c | 11 ++
> transport.h | 14 ++
> upload-pack.c | 206 ++++++++++++++++------
> 17 files changed, 550 insertions(+), 117 deletions(-)
^ permalink raw reply [flat|nested] 24+ messages in thread