From: Mark Thomas <markbt@efaref.net>
To: git@vger.kernel.org
Cc: Mark Thomas <markbt@efaref.net>
Subject: [RFC 3/4] upload-pack: Send all commits if client requests on-demand
Date: Sat, 4 Mar 2017 19:19:00 +0000 [thread overview]
Message-ID: <20170304191901.9622-4-markbt@efaref.net> (raw)
In-Reply-To: <20170304191901.9622-1-markbt@efaref.net>
Signed-off-by: Mark Thomas <markbt@efaref.net>
---
builtin/pack-objects.c | 26 ++++++++++++++++++++++++--
list-objects.c | 12 +++++++-----
list-objects.h | 13 ++++++++++++-
object.h | 1 +
on_demand.c | 26 ++++++++++++++++++++++++++
on_demand.h | 4 ++++
upload-pack.c | 8 +++++++-
7 files changed, 81 insertions(+), 9 deletions(-)
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index f294dcf..c8b2503 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -24,6 +24,7 @@
#include "sha1-array.h"
#include "argv-array.h"
#include "mru.h"
+#include "on_demand.h"
static const char *pack_usage[] = {
N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
@@ -77,6 +78,8 @@ static unsigned long cache_max_small_delta_size = 1000;
static unsigned long window_memory_limit = 0;
+static int send_all_commits;
+
/*
* stats
*/
@@ -2750,12 +2753,15 @@ static void record_recent_commit(struct commit *commit, void *data)
static void get_object_list(int ac, const char **av)
{
struct rev_info revs;
+ struct rev_info revs2;
char line[1000];
int flags = 0;
init_revisions(&revs, NULL);
+ init_revisions(&revs2, NULL);
save_commit_buffer = 0;
setup_revisions(ac, av, &revs, NULL);
+ setup_revisions(ac, av, &revs2, NULL);
/* make sure shallows are read */
is_repository_shallow();
@@ -2776,7 +2782,10 @@ static void get_object_list(int ac, const char **av)
unsigned char sha1[20];
if (get_sha1_hex(line + 10, sha1))
die("not an SHA-1 '%s'", line + 10);
- register_shallow(sha1);
+ if (send_all_commits)
+ register_on_demand_cutoff(sha1);
+ else
+ register_shallow(sha1);
use_bitmap_index = 0;
continue;
}
@@ -2784,6 +2793,8 @@ static void get_object_list(int ac, const char **av)
}
if (handle_revision_arg(line, &revs, flags, REVARG_CANNOT_BE_FILENAME))
die("bad revision '%s'", line);
+ if (handle_revision_arg(line, &revs2, flags, REVARG_CANNOT_BE_FILENAME))
+ die("bad revision '%s'", line);
}
if (use_bitmap_index && !get_object_list_from_bitmap(&revs))
@@ -2792,7 +2803,16 @@ static void get_object_list(int ac, const char **av)
if (prepare_revision_walk(&revs))
die("revision walk setup failed");
mark_edges_uninteresting(&revs, show_edge);
- traverse_commit_list(&revs, show_commit, show_object, NULL);
+
+ if (send_all_commits) {
+ revs2.include_check = on_demand_include_check;
+ traverse_commit_list(&revs2, on_demand_show_commit_tree, NULL,
+ NULL);
+ reset_revision_walk();
+ }
+
+ traverse_commit_list_extended(&revs, show_commit, show_object,
+ on_demand_show_tree_check, NULL);
if (unpack_unreachable_expiration) {
revs.ignore_missing_links = 1;
@@ -2928,6 +2948,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
N_("use a bitmap index if available to speed up counting objects")),
OPT_BOOL(0, "write-bitmap-index", &write_bitmap_index,
N_("write a bitmap index together with the pack index")),
+ OPT_BOOL(0, "send-all-commits", &send_all_commits,
+ N_("send all commits for on-demand shallow fetches")),
OPT_END(),
};
diff --git a/list-objects.c b/list-objects.c
index f3ca6aa..2607549 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -183,10 +183,11 @@ static void add_pending_tree(struct rev_info *revs, struct tree *tree)
add_pending_object(revs, &tree->object, "");
}
-void traverse_commit_list(struct rev_info *revs,
- show_commit_fn show_commit,
- show_object_fn show_object,
- void *data)
+void traverse_commit_list_extended(struct rev_info *revs,
+ show_commit_fn show_commit,
+ show_object_fn show_object,
+ show_tree_check_fn show_tree_check,
+ void *data)
{
int i;
struct commit *commit;
@@ -198,7 +199,8 @@ void traverse_commit_list(struct rev_info *revs,
* an uninteresting boundary commit may not have its tree
* parsed yet, but we are not going to show them anyway
*/
- if (commit->tree)
+ if (show_object && commit->tree &&
+ (!show_tree_check || show_tree_check(commit, data)))
add_pending_tree(revs, commit->tree);
show_commit(commit, data);
}
diff --git a/list-objects.h b/list-objects.h
index 0cebf85..e80dc8c 100644
--- a/list-objects.h
+++ b/list-objects.h
@@ -3,7 +3,18 @@
typedef void (*show_commit_fn)(struct commit *, void *);
typedef void (*show_object_fn)(struct object *, const char *, void *);
-void traverse_commit_list(struct rev_info *, show_commit_fn, show_object_fn, void *);
+typedef int (*show_tree_check_fn)(struct commit *, void *);
+void traverse_commit_list_extended(struct rev_info *, show_commit_fn,
+ show_object_fn, show_tree_check_fn, void *);
+
+inline void traverse_commit_list(struct rev_info *revs,
+ show_commit_fn show_commit,
+ show_object_fn show_object,
+ void *data)
+{
+ traverse_commit_list_extended(revs, show_commit, show_object, NULL,
+ data);
+}
typedef void (*show_edge_fn)(struct commit *);
void mark_edges_uninteresting(struct rev_info *, show_edge_fn);
diff --git a/object.h b/object.h
index f52957d..25177fd 100644
--- a/object.h
+++ b/object.h
@@ -38,6 +38,7 @@ struct object_array {
* http-push.c: 16-----19
* commit.c: 16-----19
* sha1_name.c: 20
+ * on_demand.c: 21-22
*/
#define FLAG_BITS 27
diff --git a/on_demand.c b/on_demand.c
index a0aaf18..c72d7a5 100644
--- a/on_demand.c
+++ b/on_demand.c
@@ -155,3 +155,29 @@ int object_info_on_demand(const unsigned char *sha1, struct object_info *oi)
die("git on-demand: protocol error, "
"unexpected response: '%s'", line);
}
+
+#define ON_DEMAND_CUTOFF (1u << 21)
+#define ON_DEMAND_SHOW_TREE (1u << 22)
+
+void register_on_demand_cutoff(const unsigned char *sha1)
+{
+ struct commit *commit = lookup_commit(sha1);
+ if (commit)
+ commit->object.flags |= ON_DEMAND_CUTOFF;
+}
+
+int on_demand_include_check(struct commit *commit, void *data)
+{
+ return !(commit->object.flags & ON_DEMAND_CUTOFF);
+}
+
+void on_demand_show_commit_tree(struct commit *commit, void *data)
+{
+ commit->object.flags |= ON_DEMAND_SHOW_TREE;
+}
+
+int on_demand_show_tree_check(struct commit *commit, void *data)
+{
+ return !!(commit->object.flags &
+ (ON_DEMAND_SHOW_TREE|ON_DEMAND_CUTOFF));
+}
diff --git a/on_demand.h b/on_demand.h
index 09a8072..7bbb523 100644
--- a/on_demand.h
+++ b/on_demand.h
@@ -4,5 +4,9 @@
void *read_remote_on_demand(const unsigned char *sha1, enum object_type *type,
unsigned long *size);
int object_info_on_demand(const unsigned char *sha1, struct object_info *oi);
+void register_on_demand_cutoff(const unsigned char *sha1);
+int on_demand_include_check(struct commit *commit, void *data);
+void on_demand_show_commit_tree(struct commit *commit, void *data);
+int on_demand_show_tree_check(struct commit *commit, void *data);
#endif
diff --git a/upload-pack.c b/upload-pack.c
index 7597ba3..1b552b4 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -42,6 +42,7 @@ static int multi_ack;
static int no_done;
static int use_thin_pack, use_ofs_delta, use_include_tag;
static int no_progress, daemon_mode;
+static int send_all_commits;
/* Allow specifying sha1 if it is a ref tip. */
#define ALLOW_TIP_SHA1 01
/* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
@@ -130,6 +131,8 @@ static void create_pack_file(void)
argv_array_push(&pack_objects.args, "--delta-base-offset");
if (use_include_tag)
argv_array_push(&pack_objects.args, "--include-tag");
+ if (send_all_commits)
+ argv_array_push(&pack_objects.args, "--send-all-commits");
pack_objects.in = -1;
pack_objects.out = -1;
@@ -820,6 +823,8 @@ static void receive_needs(void)
no_progress = 1;
if (parse_feature_request(features, "include-tag"))
use_include_tag = 1;
+ if (parse_feature_request(features, "on-demand"))
+ send_all_commits = 1;
o = parse_object(sha1_buf);
if (!o)
@@ -924,7 +929,8 @@ static int send_ref(const char *refname, const struct object_id *oid,
{
static const char *capabilities = "multi_ack thin-pack side-band"
" side-band-64k ofs-delta shallow deepen-since deepen-not"
- " deepen-relative no-progress include-tag multi_ack_detailed";
+ " deepen-relative no-progress include-tag multi_ack_detailed"
+ " on-demand";
const char *refname_nons = strip_namespace(refname);
struct object_id peeled;
--
2.7.4
next prev parent reply other threads:[~2017-03-04 19:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-04 19:18 [RFC 0/4] Shallow clones with on-demand fetch Mark Thomas
2017-03-04 19:18 ` [RFC 1/4] upload-file: Add upload-file command Mark Thomas
2017-03-04 19:18 ` [RFC 2/4] on-demand: Fetch missing files from remote Mark Thomas
2017-03-04 19:19 ` Mark Thomas [this message]
2017-03-04 19:19 ` [RFC 4/4] clone: Request on-demand shallow clones Mark Thomas
2017-03-06 19:16 ` [RFC 0/4] Shallow clones with on-demand fetch Jonathan Tan
2017-03-06 20:01 ` Stefan Beller
2017-03-06 19:18 ` Junio C Hamano
2017-03-07 9:42 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170304191901.9622-4-markbt@efaref.net \
--to=markbt@efaref.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).