Re: [PATCH 00/10] pack v4 UI support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 26 Sep 2013, Duy Nguyen wrote:

> On Thu, Sep 26, 2013 at 11:51 AM, Nicolas Pitre <nico@xxxxxxxxxxx> wrote:
> >> Multi-base tree support is not part of "packv4" capability. Let's see
> >> if such support comes before the series is merged to master. If so we
> >> can drop that line from protocol-capabilities.txt. Otherwise a new
> >> capability can be added for multi-base trees.
> >
> > What is that for?  Multi-base trees are not created yet, but the code to
> > parse them is already there.  So I don't see the point of having a
> > capability in the protocol for this.
> 
> pv4_get_tree() can. index-pack cannot.

Hmmm... right.

I think this ought to be part of the "packv4" capability nevertheless. 
This is not going into the official git branch right away so there is 
still time to implement it.

> >> Another capability could be added for sending the actual number of
> >> objects in a thin pack for more accurate display in index-pack. Low
> >> priority in my opinion.
> >
> > That just cannot be communicated during capability exchange.  This
> > number is known only after object enumeration.  Hence my suggestion of a
> > ['T', 'H', 'I', 'N', htonl(<number_of_sent_objects>)] special header
> > prepended to the actual pack on the wire.  And that has to be decided
> > before formalizing the pack v4 capability.  That makes it a somewhat
> > higher priority.
> 
> The capability is to let the server know the client understands ['T',
> 'H', 'I', 'N' ..]. The server can choose not to send it later, but
> that's ok. Hence the new capability. I'm somewhat reluctant to do it
> because of peeking code in fetch-pack and receive-pack and some
> refactoring may be needed first. But I could certainly put it on
> higher priority.

Here's what I'm suggesting as a start (untested):

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index e3eb5fc..04e5ae1 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -792,9 +792,10 @@ static struct command *read_head_info(void)
 	return commands;
 }
 
-static const char *parse_pack_header(struct pack_header *hdr)
+static const char *parse_pack_header(struct pack_header *hdr,
+				     struct thin_header *thin_hdr)
 {
-	switch (read_pack_header(0, hdr)) {
+	switch (read_pack_header(0, hdr, thin_hdr)) {
 	case PH_ERROR_EOF:
 		return "eof before pack header was fully read";
 
@@ -817,23 +818,25 @@ static const char *pack_lockfile;
 static const char *unpack(int err_fd)
 {
 	struct pack_header hdr;
+	struct thin_header thin_hdr;
 	const char *hdr_err;
-	char hdr_arg[38];
+	char hdr_arg[50];
 	int fsck_objects = (receive_fsck_objects >= 0
 			    ? receive_fsck_objects
 			    : transfer_fsck_objects >= 0
 			    ? transfer_fsck_objects
 			    : 0);
 
-	hdr_err = parse_pack_header(&hdr);
+	hdr_err = parse_pack_header(&hdr, &thin_hdr);
 	if (hdr_err) {
 		if (err_fd > 0)
 			close(err_fd);
 		return hdr_err;
 	}
 	snprintf(hdr_arg, sizeof(hdr_arg),
-			"--pack_header=%"PRIu32",%"PRIu32,
-			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
+			"--pack_header=%"PRIu32",%"PRIu32",%"PRIu32,
+			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries),
+			ntohl(thin_hdr.hdr_entries));
 
 	if (ntohl(hdr.hdr_entries) < unpack_limit) {
 		int code, i = 0;
diff --git a/fetch-pack.c b/fetch-pack.c
index 6684348..d86e5d1 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -715,12 +715,14 @@ static int get_pack(struct fetch_pack_args *args,
 	*hdr_arg = 0;
 	if (!args->keep_pack && unpack_limit) {
 		struct pack_header header;
+		struct thin_header thin_hdr;
 
-		if (read_pack_header(demux.out, &header))
+		if (read_pack_header(demux.out, &header, &thin_hdr))
 			die("protocol error: bad pack header");
 		snprintf(hdr_arg, sizeof(hdr_arg),
-			 "--pack_header=%"PRIu32",%"PRIu32,
-			 ntohl(header.hdr_version), ntohl(header.hdr_entries));
+			 "--pack_header=%"PRIu32",%"PRIu32",%"PRIu32,
+			 ntohl(header.hdr_version), ntohl(header.hdr_entries),
+			 ntohl(thin_hdr.hdr_entries));
 		if (ntohl(header.hdr_entries) < unpack_limit)
 			do_keep = 0;
 		else
diff --git a/pack.h b/pack.h
index ccefdbe..974b860 100644
--- a/pack.h
+++ b/pack.h
@@ -16,6 +16,18 @@ struct pack_header {
 };
 
 /*
+ * Pack v4 header prefix for thin packs, indicating the actual number
+ * of objects being transmitted.  Expected before the actual pack header
+ * on the wire and not stored on disk upon reception.  This is not
+ * included in the computation of the pack trailing SHA1.
+ */
+#define THIN_SIGNATURE 0x5448494e	/* "THIN" */
+struct thin_header {
+	uint32_t hdr_signature;
+	uint32_t hdr_entries;
+};
+
+/*
  * The first four bytes of index formats later than version 1 should
  * start with this signature, as all older git binaries would find this
  * value illegal and abort reading the file.
@@ -88,7 +100,7 @@ extern int pv4_encode_object_header(enum object_type, uintmax_t, unsigned char *
 #define PH_ERROR_EOF		(-1)
 #define PH_ERROR_PACK_SIGNATURE	(-2)
 #define PH_ERROR_PROTOCOL	(-3)
-extern int read_pack_header(int fd, struct pack_header *);
+extern int read_pack_header(int fd, struct pack_header *, struct thin_header *);
 
 extern struct sha1file *create_tmp_packfile(char **pack_tmp_name);
 extern void finish_tmp_packfile(char *name_buffer, const char *pack_tmp_name, struct pack_idx_entry **written_list, uint32_t nr_written, struct pack_idx_option *pack_idx_opts, unsigned char sha1[]);
diff --git a/sha1_file.c b/sha1_file.c
index ef6ecc8..5f00c15 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3180,12 +3180,26 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned
 	return 0;
 }
 
-int read_pack_header(int fd, struct pack_header *header)
+int read_pack_header(int fd, struct pack_header *header,
+		     struct thin_header *thin_hdr)
 {
 	if (read_in_full(fd, header, sizeof(*header)) < sizeof(*header))
 		/* "eof before pack header was fully read" */
 		return PH_ERROR_EOF;
 
+	if (header->hdr_signature == htonl(THIN_SIGNATURE)) {
+		char *thin_hdr_end = (char *)header + sizeof(*thin_hdr);
+		int leftover = sizeof(*header) - sizeof(*thin_hdr);
+		if (!thin_hdr)
+			return PH_ERROR_PROTOCOL;
+		memcpy(thin_hdr, header, sizeof(*thin_hdr));
+		memcpy(header, thin_hdr_end, leftover);
+		if (read_in_full(fd, thin_hdr_end, sizeof(*header) - leftover)
+				< sizeof(*header) - leftover)
+			return PH_ERROR_EOF;
+	} else if (thin_hdr)
+		memset(thin_hdr, 0, sizeof(*thin_hdr));
+
 	if (header->hdr_signature != htonl(PACK_SIGNATURE))
 		/* "protocol error (pack signature mismatch detected)" */
 		return PH_ERROR_PACK_SIGNATURE;


Nicolas
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]