threads / patch / 600

patch, 4 partsPulling refs files

Subject: [PATCH 0/4] Pulling refs files

## tl;dr

23 messages between May 13, 2005 and May 19, 2005. Diffs are folded; open one to read it.

replies: 22people: 5as markdown or json

Daniel Barkalow· May 13, 2005, 06:49 UTC · lore
This series makes the following changes:
 1: Adds support for having the C code know about the general existance of
    .git/refs, and functions for writing these files.
 2: Adds support in the generic pull code for fetching refs (and dummy
    implementations).
 3: Adds support in the HTTP pull code for fetching refs
 4: Adds support in the rsh pull code for fetching refs; this requires
    changes to the protocol. These changes should be sufficient to support
    any future extension, however.
	-Daniel
*This .sig left intentionally blank*
Daniel Barkalow· May 13, 2005, 06:53 UTC · re: Daniel Barkalow · lore

[PATCH 1/4] Support for refs directory

Add support for reading and writing files in the refs directory.
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Show changes to diff +178 −3
Index: Makefile
===================================================================
--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/Makefile  (mode:100644 sha1:6afcb3e867a6857f9128dba877e433c12366c1f4)
+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/Makefile  (mode:100644 sha1:653912b7290d1a28860db41f602fbf15ca2d9aa5)
@@ -36,9 +36,10 @@
 	$(INSTALL) $(PROG) $(SCRIPTS) $(dest)$(bin)
 
 LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
-	 tag.o date.o
+	 tag.o date.o refs.o
+
 LIB_FILE=libgit.a
-LIB_H=cache.h object.h blob.h tree.h commit.h tag.h
+LIB_H=cache.h object.h blob.h tree.h commit.h tag.h refs.h
 
 LIB_H += strbuf.h
 LIB_OBJS += strbuf.o
Index: cache.h
===================================================================
--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/cache.h  (mode:100644 sha1:c06b94107e0e1149be0ad642812e8d4a42f2193c)
+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/cache.h  (mode:100644 sha1:ca9d13a972e05d8d0aa15babd5a963688fdd5968)
@@ -110,8 +110,10 @@
 #define GIT_DIR_ENVIRONMENT "GIT_DIR"
 #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
 #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
+#define REFS_ENVIRONMENT "GIT_REFS_DIRECTORY"
 #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
 
+extern char *get_refs_directory(void);
 extern char *get_object_directory(void);
 extern char *get_index_file(void);
 
Index: init-db.c
===================================================================
--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/init-db.c  (mode:100644 sha1:b6bb78356762bd28261949da54638f46776e6d4b)
+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/init-db.c  (mode:100644 sha1:3441a35d7c2eb88e76db4886e8c068ca898ea8fd)
@@ -40,6 +40,7 @@
 	memcpy(path, sha1_dir, len);
 
 	safe_create_dir(sha1_dir);
+	safe_create_dir(get_refs_directory());
 	for (i = 0; i < 256; i++) {
 		sprintf(path+len, "/%02x", i);
 		safe_create_dir(path);
Index: refs.c
===================================================================
--- /dev/null  (tree:2a5e43fa9318a648bfb4dbf64208f4c26905a5f8)
+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/refs.c  (mode:100644 sha1:9ba5696c15d8597236e1f5b7a4dbd609045efc81)
@@ -0,0 +1,139 @@
+#include "refs.h"
+#include "cache.h"
+
+#include <errno.h>
+
+static char *split_ref_file_name(const char *dir, const char *name)
+{
+	char *base = get_refs_directory();
+	int baselen = strlen(base);
+	int dirlen = strlen(dir);
+	int namelen = strlen(name);
+	char *ret;
+	if (dir[0] == '.')
+		return NULL;
+	if (strchr(dir, '/'))
+		return NULL;
+	if (strchr(name, '/'))
+		return NULL;
+	ret = xmalloc(baselen + 3 + dirlen + namelen);
+	strcpy(ret, base);
+	ret[baselen] = '/';
+	strcpy(ret + baselen + 1, dir);
+	ret[baselen + 1 + dirlen] = '/';
+	strcpy(ret + baselen + 2 + dirlen, name);
+	ret[baselen + 2 + dirlen + namelen] = '\0';
+	return ret;
+}
+
+static char *ref_file_name(const char *ref)
+{
+	char *base = get_refs_directory();
+	int baselen = strlen(base);
+	int reflen = strlen(ref);
+	char *ret;
+	char *check;
+	if (ref[0] == '.')
+		return NULL;
+	check = strchr(ref, '/');
+	if (!check)
+		return NULL;
+	if (strchr(check + 1, '/'))
+		return NULL;
+	ret = xmalloc(baselen + 2 + reflen);
+	strcpy(ret, base);
+	ret[baselen] = '/';
+	strcpy(ret + baselen + 1, ref);
+	ret[baselen + 1 + reflen] = '\0';
+	return ret;
+}
+
+static int read_ref_file(char *filename, unsigned char *sha1) {
+	int fd = open(filename, O_RDONLY);
+	char hex[41];
+	if (fd < 0) {
+		return error("Couldn't open %s\n", filename);
+	}
+	if ((read(fd, hex, 41) < 41) ||
+	    (hex[40] != '\n') ||
+	    get_sha1_hex(hex, sha1)) {
+		error("Couldn't read a hash from %s\n", filename);
+		close(fd);
+		return -1;
+	}
+	close(fd);
+	return 0;
+}
+
+int get_split_ref_sha1(const char *dir, const char *name, unsigned char *sha1)
+{
+	char *filename = split_ref_file_name(dir, name);
+	int retval;
+	if (!filename)
+		return -1;
+	retval = read_ref_file(filename, sha1);
+	free(filename);
+	return retval;
+}
+
+int get_ref_sha1(const char *ref, unsigned char *sha1)
+{
+	char *filename = ref_file_name(ref);
+	int retval;
+	if (!filename)
+		return -1;
+	retval = read_ref_file(filename, sha1);
+	free(filename);
+	return retval;
+}
+
+int write_split_ref_sha1(const char *dir, const char *name,
+			 unsigned char *sha1)
+{
+	char *filename = split_ref_file_name(dir, name);
+	char *hex = sha1_to_hex(sha1);
+	char term = '\n';
+	int fd;
+	if (!filename)
+		return -1;
+	unlink(filename);
+	fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+	if (fd < 0 && errno == ENOENT) {
+		char *dirname = split_ref_file_name(dir, "");
+		mkdir(dirname, 0755);
+		free(dirname);
+		fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+	}
+	if (fd < 0) {
+		error("Couldn't open for writing %s: %s\n", filename,
+		      strerror(errno));
+		free(filename);
+		return -1;
+	}
+	if (write(fd, hex, 40) < 40 ||
+	    write(fd, &term, 1) < 1) {
+		error("Couldn't write %s\n", filename);
+		free(filename);
+		close(fd);
+		return -1;
+	}
+	close(fd);
+	return 0;
+	
+}
+
+int split_ref(char **dir, char **name, const char *ref)
+{
+	char *middle = strchr(ref, '/');
+	if (ref[0] == '.')
+		return -1;
+	if (!middle)
+		return -1;
+	if (strchr(middle + 1, '/'))
+		return -1;
+	*dir = xmalloc(middle - ref + 1);
+	*name = strdup(middle + 1);
+	(*dir)[middle - ref] = '\0';
+	memcpy(*dir, ref, middle - ref);
+	return 0;
+}
Index: refs.h
===================================================================
--- /dev/null  (tree:2a5e43fa9318a648bfb4dbf64208f4c26905a5f8)
+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/refs.h  (mode:100644 sha1:9ef6ed7563f70273aef6574a01d5626fee28345a)
@@ -0,0 +1,20 @@
+#ifndef REFS_H
+#define REFS_H
+
+/** Reads the refs file specified into sha1 **/
+extern int get_split_ref_sha1(const char *dir, const char *name,
+			      unsigned char *sha1);
+
+/** Reads the refs file specified into sha1 **/
+extern int get_ref_sha1(const char *ref, unsigned char *sha1);
+
+/** Writes sha1 into the refs file specified **/
+extern int write_split_ref_sha1(const char *dir, const char *name, 
+				unsigned char *sha1);
+
+/** Sets dir and name to the directory and name parts of ref, in new
+ * storage. 
+ **/
+extern int split_ref(char **dir, char **name, const char *ref);
+
+#endif /* REFS_H */
Index: sha1_file.c
===================================================================
--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/sha1_file.c  (mode:100644 sha1:942b673dc3c7fa9f057c5c452e3a1b73eaeb8707)
+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/sha1_file.c  (mode:100644 sha1:a3ab45fbb39f37622ae191fe5c3cbaf30389ec74)
@@ -59,7 +59,7 @@
 	return get_sha1_hex(buffer, result);
 }
 
-static char *git_dir, *git_object_dir, *git_index_file;
+static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir;
 static void setup_git_env(void)
 {
 	git_dir = gitenv(GIT_DIR_ENVIRONMENT);
@@ -70,6 +70,11 @@
 		git_object_dir = xmalloc(strlen(git_dir) + 9);
 		sprintf(git_object_dir, "%s/objects", git_dir);
 	}
+	git_refs_dir = gitenv(REFS_ENVIRONMENT);
+	if (!git_refs_dir) {
+		git_refs_dir = xmalloc(strlen(git_dir) + 6);
+		sprintf(git_refs_dir, "%s/refs", git_dir);
+	}
 	git_index_file = gitenv(INDEX_ENVIRONMENT);
 	if (!git_index_file) {
 		git_index_file = xmalloc(strlen(git_dir) + 7);
@@ -91,6 +96,13 @@
 	return git_index_file;
 }
 
+char *get_refs_directory(void)
+{
+	if (!git_refs_dir)
+		setup_git_env();
+	return git_refs_dir;
+}
+
 int get_sha1(const char *str, unsigned char *sha1)
 {
 	static char pathname[PATH_MAX];
Daniel Barkalow· May 13, 2005, 06:56 UTC · re: Daniel Barkalow · lore

[PATCH 2/4] Generic support for pulling refs

This adds a pull method to pull refs, provides dummy implementations for the existing programs, and uses that method to try to get refs if requested. It also adds generic support for writing the target to a refs file.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Show changes to diff +69 −6
Index: http-pull.c
===================================================================
--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/http-pull.c  (mode:100644 sha1:024457a9895ab10c4ef18aa6e232d12fdaab4da9)
+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/http-pull.c  (mode:100644 sha1:af4e82fdf9c58a15564d40bef85d57e9f6626727)
@@ -98,6 +98,11 @@
 	return 0;
 }
 
+int fetch_ref(char *dir, char *name, unsigned char *sha1)
+{
+	return -1;
+}
+
 int main(int argc, char **argv)
 {
 	char *commit_id;
Index: local-pull.c
===================================================================
--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/local-pull.c  (mode:100644 sha1:3a342ab18390d7ce0df1f970a4961b31548a9417)
+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/local-pull.c  (mode:100644 sha1:73aad965d0b190627aa95726e4feaa2623d31d26)
@@ -18,6 +18,11 @@
 
 static char *path;
 
+int fetch_ref(char *dir, char *name, unsigned char *sha1)
+{
+	return -1;
+}
+
 int fetch(unsigned char *sha1)
 {
 	static int object_name_start = -1;
Index: pull.c
===================================================================
--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/pull.c  (mode:100644 sha1:0bed44f4cbf6716cfc3152f35626123992766408)
+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/pull.c  (mode:100644 sha1:d4d858cd638e915096a408ba3c37090a1b460c21)
@@ -3,6 +3,12 @@
 #include "cache.h"
 #include "commit.h"
 #include "tree.h"
+#include "tag.h"
+
+#include "refs.h"
+
+char *write_ref_dir = NULL;
+char *write_ref_name = NULL;
 
 int get_tree = 0;
 int get_history = 0;
@@ -98,16 +104,52 @@
 	return 0;
 }
 
+static int process_tag(unsigned char *sha1)
+{
+	return 0;
+}
+
+static int process_unknown(unsigned char *sha1)
+{
+	struct object *obj;
+	if (make_sure_we_have_it(NULL, sha1))
+		return -1;
+	obj = parse_object(sha1);
+	if (obj->type == commit_type) {
+		memcpy(current_commit_sha1, sha1, 20);
+		return process_commit(sha1);
+	} else if (obj->type == tag_type)
+		return process_tag(sha1);
+	return error("Cannot pull a %s object", obj->type);
+}
+
+static int interpret_target(char *target, unsigned char *sha1)
+{
+	char *dir, *name;
+	if (!get_sha1_hex(target, sha1))
+		return 0;
+	if (!split_ref(&dir, &name, target)) {
+		if (!fetch_ref(dir, name, sha1)) {
+			return 0;
+		}
+	}
+	return -1;
+}
+
 int pull(char *target)
 {
 	int retval;
 	unsigned char sha1[20];
-	retval = get_sha1_hex(target, sha1);
-	if (retval)
-		return retval;
-	retval = make_sure_we_have_it(commitS, sha1);
+	retval = interpret_target(target, sha1);
+	if (retval) {
+		return error("Could not interpret %s as something to pull",
+			     target);
+	}
+	retval = process_unknown(sha1);
 	if (retval)
 		return retval;
-	memcpy(current_commit_sha1, sha1, 20);
-	return process_commit(sha1);
+
+	if (write_ref_dir && write_ref_name)
+		write_split_ref_sha1(write_ref_dir, write_ref_name, sha1);
+	return 0;
 }
Index: pull.h
===================================================================
--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/pull.h  (mode:100644 sha1:d2dca02de7c23426e84e9f63762df9428933e8d8)
+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/pull.h  (mode:100644 sha1:de0e9245b68856bcf84c033650b6b3eb151641e2)
@@ -4,6 +4,12 @@
 /** To be provided by the particular implementation. **/
 extern int fetch(unsigned char *sha1);
 
+extern int fetch_ref(char *dir, char *name, unsigned char *sha1);
+
+/** Ref filename to write target to. **/
+extern char *write_ref_dir;
+extern char *write_ref_name;
+
 /** Set to fetch the target tree. */
 extern int get_tree;
 
Index: rpull.c
===================================================================
--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/rpull.c  (mode:100644 sha1:b48e63157c66c160b9751603a92831f77106044c)
+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/rpull.c  (mode:100644 sha1:493fcdae670ebb1d93b8c75d3e28798e060d7537)
@@ -22,6 +22,11 @@
 	return ret;
 }
 
+int fetch_ref(char *dir, char *name, unsigned char *sha1)
+{
+	return -1;
+}
+
 int main(int argc, char **argv)
 {
 	char *commit_id;
Daniel Barkalow· May 13, 2005, 06:57 UTC · re: Daniel Barkalow · lore

[PATCH 3/4] Pull refs by HTTP

Adds support for pulling refs by HTTP, and an option for writing the pulled ref to a file.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Show changes to diff +53 −2
Index: http-pull.c
===================================================================
--- 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/http-pull.c  (mode:100644 sha1:af4e82fdf9c58a15564d40bef85d57e9f6626727)
+++ 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/http-pull.c  (mode:100644 sha1:6e8dc48ddd0ea1ae89074f6ae0d89c54303895b7)
@@ -7,6 +7,8 @@
 #include <errno.h>
 #include <stdio.h>
 
+#include "refs.h"
+
 #include "pull.h"
 
 #include <curl/curl.h>
@@ -45,6 +47,23 @@
 	return size;
 }
 
+struct buffer
+{
+	size_t posn;
+	size_t size;
+	void *buffer;
+};
+
+static size_t fwrite_buffer(void *ptr, size_t eltsize, size_t nmemb,
+			    struct buffer *buffer) {
+	size_t size = eltsize * nmemb;
+	if (size > buffer->size - buffer->posn)
+		size = buffer->size - buffer->posn;
+	memcpy(buffer->buffer + buffer->posn, ptr, size);
+	buffer->posn += size;
+	return size;
+}
+
 int fetch(unsigned char *sha1)
 {
 	char *hex = sha1_to_hex(sha1);
@@ -93,14 +112,42 @@
 		unlink(filename);
 		return error("File %s has bad hash\n", hex);
 	}
-	
 	pull_say("got %s\n", hex);
 	return 0;
 }
 
 int fetch_ref(char *dir, char *name, unsigned char *sha1)
 {
-	return -1;
+	char *url, *posn;
+	char hex[42];
+	struct buffer buffer;
+	buffer.size = 41;
+	buffer.posn = 0;
+	buffer.buffer = hex;
+	hex[41] = '\0';
+	
+	curl_easy_setopt(curl, CURLOPT_FILE, &buffer);
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
+
+	url = xmalloc(strlen(base) + 7 + strlen(dir) + strlen(name));
+	strcpy(url, base);
+	posn = url + strlen(base);
+	strcpy(posn, "refs/");
+	posn += 5;
+	strcpy(posn, dir);
+	posn += strlen(dir);
+	*(posn++) = '/';
+	strcpy(posn, name);
+
+	curl_easy_setopt(curl, CURLOPT_URL, url);
+
+	if (curl_easy_perform(curl))
+		return error("Couldn't get %s for %s/%s\n", url,
+			     dir, name);
+
+	hex[40] = '\0';
+	get_sha1_hex(hex, sha1);
+	return 0;
 }
 
 int main(int argc, char **argv)
@@ -120,6 +167,10 @@
 			get_history = 1;
 		} else if (argv[arg][1] == 'v') {
 			get_verbosely = 1;
+		} else if (argv[arg][1] == 'w') {
+			char *write_ref = argv[arg + 1];
+			split_ref(&write_ref_dir, &write_ref_name, write_ref);
+			arg++;
 		}
 		arg++;
 	}
Edgar Toernig· May 13, 2005, 11:15 UTC · re: Daniel Barkalow · lore

Re: [PATCH 3/4] Pull refs by HTTP

Daniel Barkalow wrote:
Show 10 quoted lines
>
> +	url = xmalloc(strlen(base) + 7 + strlen(dir) + strlen(name));
> +	strcpy(url, base);
> +	posn = url + strlen(base);
> +	strcpy(posn, "refs/");
> +	posn += 5;
> +	strcpy(posn, dir);
> +	posn += strlen(dir);
> +	*(posn++) = '/';
> +	strcpy(posn, name);
Have you ever heard of sprintf & co?
	sprintf(url, "%srefs/%s/%s", base, dir, name);
Ciao, ET.
Daniel Barkalow· May 13, 2005, 07:01 UTC · re: Daniel Barkalow · lore

[PATCH 4/4] Pulling refs by ssh

Adds support for pulling refs by rsh.

This changes the rsh protocol to allow requests for different things, and to allow the server to report that it doesn't have something without breaking the connection.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Show changes to diff +110 −34
Index: rpull.c
===================================================================
--- 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/rpull.c  (mode:100644 sha1:493fcdae670ebb1d93b8c75d3e28798e060d7537)
+++ a219d8e31f3882aaa32e7dbac7a1f92b35a9dbff/rpull.c  (mode:100644 sha1:cce9e71becc95f728d320ef49e11a647a420b75d)
@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include "rsh.h"
 #include "pull.h"
+#include "refs.h"
 
 static int fd_in;
 static int fd_out;
@@ -15,16 +16,34 @@
 int fetch(unsigned char *sha1)
 {
 	int ret;
+	signed char remote;
+	char type = 'o';
+	if (has_sha1_file(sha1))
+		return 0;
+	write(fd_out, &type, 1);
 	write(fd_out, sha1, 20);
+	if (read(fd_in, &remote, 1) < 1)
+		return -1;
+	if (remote < 0)
+		return remote;
 	ret = write_sha1_from_fd(sha1, fd_in);
 	if (!ret)
 		pull_say("got %s\n", sha1_to_hex(sha1));
 	return ret;
 }
 
-int fetch_ref(char *dir, char *name, unsigned char *sha1)
+int fetch_ref(char *name, char *dir, unsigned char *sha1)
 {
-	return -1;
+	signed char remote;
+	char type = 'r';
+	write(fd_out, &type, 1);
+	write(fd_out, name, strlen(name) + 1);
+	write(fd_out, dir, strlen(dir) + 1);
+	read(fd_in, &remote, 1);
+	if (remote < 0)
+		return remote;
+	read(fd_in, sha1, 20);
+	return 0;
 }
 
 int main(int argc, char **argv)
@@ -44,6 +63,10 @@
 			get_history = 1;
 		} else if (argv[arg][1] == 'v') {
 			get_verbosely = 1;
+		} else if (argv[arg][1] == 'w') {
+			char *write_ref = argv[arg + 1];
+			split_ref(&write_ref_dir, &write_ref_name, write_ref);
+			arg++;
 		}
 		arg++;
 	}
Index: rpush.c
===================================================================
--- 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/rpush.c  (mode:100644 sha1:26518846704ecf63ad00390599b251aa1b32713e)
+++ a219d8e31f3882aaa32e7dbac7a1f92b35a9dbff/rpush.c  (mode:100644 sha1:c3cad4eac186307e743eacb913a0b382a455d1f4)
@@ -2,47 +2,98 @@
 #include "rsh.h"
 #include <sys/socket.h>
 #include <errno.h>
+#include "refs.h"
 
-void service(int fd_in, int fd_out) {
+int serve_object(int fd_in, int fd_out) {
 	ssize_t size;
-	int posn;
+	int posn = 0;
 	char sha1[20];
 	unsigned long objsize;
 	void *buf;
+	signed char remote;
 	do {
-		posn = 0;
-		do {
-			size = read(fd_in, sha1 + posn, 20 - posn);
-			if (size < 0) {
-				perror("rpush: read ");
-				return;
+		size = read(fd_in, sha1 + posn, 20 - posn);
+		if (size < 0) {
+			perror("rpush: read ");
+			return -1;
+		}
+		if (!size)
+			return -1;
+		posn += size;
+	} while (posn < 20);
+	
+	/* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */
+	remote = 0;
+	
+	buf = map_sha1_file(sha1, &objsize);
+	
+	if (!buf) {
+		fprintf(stderr, "rpush: could not find %s\n", 
+			sha1_to_hex(sha1));
+		remote = -1;
+	}
+	
+	write(fd_out, &remote, 1);
+	
+	if (remote < 0)
+		return 0;
+	
+	posn = 0;
+	do {
+		size = write(fd_out, buf + posn, objsize - posn);
+		if (size <= 0) {
+			if (!size) {
+				fprintf(stderr, "rpush: write closed");
+			} else {
+				perror("rpush: write ");
 			}
-			if (!size)
-				return;
-			posn += size;
-		} while (posn < 20);
+			return -1;
+		}
+		posn += size;
+	} while (posn < objsize);
+	return 0;
+}
 
-		/* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */
+int serve_ref(int fd_in, int fd_out)
+{
+	char dir[PATH_MAX], name[PATH_MAX];
+	unsigned char sha1[20];
+	int posn = 0;
+	signed char remote = 0;
+	do {
+		if (read(fd_in, dir + posn, 1) < 1)
+			return -1;
+		posn++;
+	} while (dir[posn - 1]);
+	posn = 0;
+	do {
+		if (read(fd_in, name + posn, 1) < 1)
+			return -1;
+		posn++;
+	} while (name[posn - 1]);
+	if (get_split_ref_sha1(dir, name, sha1))
+		remote = -1;
+	write(fd_out, &remote, 1);
+	if (remote)
+		return 0;
+	write(fd_out, sha1, 20);
+	return 0;
+}
 
-		buf = map_sha1_file(sha1, &objsize);
-		if (!buf) {
-			fprintf(stderr, "rpush: could not find %s\n", 
-				sha1_to_hex(sha1));
+void service(int fd_in, int fd_out) {
+	char type;
+	int retval;
+	do {
+		retval = read(fd_in, &type, 1);
+		if (retval < 1) {
+			if (retval < 0)
+				perror("rpush: read ");
 			return;
 		}
-		posn = 0;
-		do {
-			size = write(fd_out, buf + posn, objsize - posn);
-			if (size <= 0) {
-				if (!size) {
-					fprintf(stderr, "rpush: write closed");
-				} else {
-					perror("rpush: write ");
-				}
-				return;
-			}
-			posn += size;
-		} while (posn < objsize);
+		if (type == 'o' && serve_object(fd_in, fd_out))
+			return;
+		if (type == 'r' && serve_ref(fd_in, fd_out))
+			return;
 	} while (1);
 }
 
@@ -53,6 +104,8 @@
         char *url;
 	int fd_in, fd_out;
 	while (arg < argc && argv[arg][0] == '-') {
+		if (argv[arg][1] == 'w')
+			arg++;
                 arg++;
         }
         if (argc < arg + 2) {
Index: rsh.c
===================================================================
--- 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/rsh.c  (mode:100644 sha1:5d1cb9d578a8e679fc190a9d7d2c842ad811223f)
+++ a219d8e31f3882aaa32e7dbac7a1f92b35a9dbff/rsh.c  (mode:100644 sha1:192d8f67e9a5e2bf7bb9e14c8c037dff49e74d57)
@@ -36,8 +36,8 @@
 	*(path++) = '\0';
 	/* ssh <host> 'cd /<path>; stdio-pull <arg...> <commit-id>' */
 	snprintf(command, COMMAND_SIZE, 
-		 "cd /%s; %s=objects %s",
-		 path, DB_ENVIRONMENT, remote_prog);
+		 "cd /%s; GIT_DIR=. %s",
+		 path, remote_prog);
 	posn = command + strlen(command);
 	for (i = 0; i < rmt_argc; i++) {
 		*(posn++) = ' ';
H. Peter Anvin· May 13, 2005, 18:59 UTC · re: Daniel Barkalow · lore

Re: [PATCH 4/4] Pulling refs by ssh

Daniel Barkalow wrote:
Show 6 quoted lines
> Adds support for pulling refs by rsh.
> 
> This changes the rsh protocol to allow requests for different things, and
> to allow the server to report that it doesn't have something without
> breaking the connection.
> 

Use && rather than semicolon, and make sure you quote things that need to be quoted.

	-hpa
Daniel Barkalow· May 15, 2005, 15:48 UTC · re: H. Peter Anvin · lore

Re: [PATCH 4/4] Pulling refs by ssh

On Fri, 13 May 2005, H. Peter Anvin wrote:
> Use && rather than semicolon, and make sure you quote things that need 
> to be quoted.

This is a separate issue from the change for refs; could you send a patch that quotes things properly? The "cd" should be unnecessary now that we have the GIT_DIR environment variable.

	-Daniel
*This .sig left intentionally blank*
Petr Baudis· May 13, 2005, 22:19 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

Dear diary, on Fri, May 13, 2005 at 08:49:25AM CEST, I got a letter where Daniel Barkalow <barkalow@iabervon.org> told me that...

Show 10 quoted lines
> This series makes the following changes:
> 
>  1: Adds support for having the C code know about the general existance of
>     .git/refs, and functions for writing these files.
>  2: Adds support in the generic pull code for fetching refs (and dummy
>     implementations).
>  3: Adds support in the HTTP pull code for fetching refs
>  4: Adds support in the rsh pull code for fetching refs; this requires
>     changes to the protocol. These changes should be sufficient to support
>     any future extension, however.

Hmm, I've honestly expected something different - a generic way to specify any file in the repository to be pulled along, instead of a introducing refs awareness at this level of git. What would be the advantages of that approach against just specifying list of other files to pull along?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
Daniel Barkalow· May 13, 2005, 23:14 UTC · re: Petr Baudis · lore

Re: [PATCH 0/4] Pulling refs files

On Sat, 14 May 2005, Petr Baudis wrote:
Show 5 quoted lines
> Hmm, I've honestly expected something different - a generic way to
> specify any file in the repository to be pulled along, instead of a
> introducing refs awareness at this level of git. What would be the
> advantages of that approach against just specifying list of other files
> to pull along?

The point is to specify the commit to pull by fetching a file from the other side, not just to move a file. So you need to be specifying that the file is a hex encoding of the sha1 hash of the starting point of the pull, and the refs/ area is where these are expected to be. (Note that it still doesn't have any knowledge about the meanings of files in refs/; you tell it which one you want to use, and optionally which one you want to write to, and it will use the names you provide).

It wouldn't help much to download the head file if you had to know the contents of that file already in order to do everything as a single transfer.

	-Daniel
*This .sig left intentionally blank*
Petr Baudis· May 13, 2005, 23:37 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

Dear diary, on Sat, May 14, 2005 at 01:14:22AM CEST, I got a letter where Daniel Barkalow <barkalow@iabervon.org> told me that...

Show 19 quoted lines
> On Sat, 14 May 2005, Petr Baudis wrote:
> 
> > Hmm, I've honestly expected something different - a generic way to
> > specify any file in the repository to be pulled along, instead of a
> > introducing refs awareness at this level of git. What would be the
> > advantages of that approach against just specifying list of other files
> > to pull along?
> 
> The point is to specify the commit to pull by fetching a file from the
> other side, not just to move a file. So you need to be specifying that the
> file is a hex encoding of the sha1 hash of the starting point of the pull,
> and the refs/ area is where these are expected to be. (Note that it still
> doesn't have any knowledge about the meanings of files in refs/; you tell
> it which one you want to use, and optionally which one you want to write
> to, and it will use the names you provide).
> 
> It wouldn't help much to download the head file if you had to know the
> contents of that file already in order to do everything as a single
> transfer.
So what about just something like
	git-wormhole-pull remote:refs/head/master wormhole://localhost/

That is, you could just specify remote:path_relative_to_url instead of SHA1 id as the commit.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
Daniel Barkalow· May 15, 2005, 03:23 UTC · re: Petr Baudis · lore

Re: [PATCH 0/4] Pulling refs files

On Sat, 14 May 2005, Petr Baudis wrote:
Show 6 quoted lines
> So what about just something like
> 
> 	git-wormhole-pull remote:refs/head/master wormhole://localhost/
> 
> That is, you could just specify remote:path_relative_to_url instead of
> SHA1 id as the commit.

Do you have any sensible alternatives to "remote:refs/<something>" in mind? I suppose that "remote:HEAD" would also work. How are you thinking of having the value get written locally?

Do you also have some idea for user-invoked rpush? It has to call something that writes the value on the other side (and I'd ideally like it to do the update atomically and locked against other clients). This series uses the same mechanism to write it that it uses to write hashes fetched from remote machines.

	-Daniel
*This .sig left intentionally blank*
Petr Baudis· May 17, 2005, 20:14 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

Dear diary, on Sun, May 15, 2005 at 05:23:18AM CEST, I got a letter where Daniel Barkalow <barkalow@iabervon.org> told me that...

Show 12 quoted lines
> On Sat, 14 May 2005, Petr Baudis wrote:
> 
> > So what about just something like
> > 
> > 	git-wormhole-pull remote:refs/head/master wormhole://localhost/
> > 
> > That is, you could just specify remote:path_relative_to_url instead of
> > SHA1 id as the commit.
> 
> Do you have any sensible alternatives to "remote:refs/<something>" in
> mind? I suppose that "remote:HEAD" would also work. How are you thinking
> of having the value get written locally?

Anything that gets eventually wound up in the info/ directory. (The name of the ignore file saved in info/ignore is the current hit.)

Show 5 quoted lines
> Do you also have some idea for user-invoked rpush? It has to call
> something that writes the value on the other side (and I'd ideally like it
> to do the update atomically and locked against other clients). This series
> uses the same mechanism to write it that it uses to write hashes fetched
> from remote machines.

Well, it'd be again nice to have some generic mechanism for this so that the user could theoretically push over rsync too or something (although that'll be even more racy, it is fine for single-user repository).

I think the remote file to write the value inside should be porcelain business. What you should always check though is that before the pull (and after the locking) the value in that file is the same as the "push base". This way you make sure that you are still following a single branch and in case of multiuser repositories that you were fully merged before pushing.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
Daniel Barkalow· May 17, 2005, 21:20 UTC · re: Petr Baudis · lore

Re: [PATCH 0/4] Pulling refs files

On Tue, 17 May 2005, Petr Baudis wrote:
Show 17 quoted lines
> Dear diary, on Sun, May 15, 2005 at 05:23:18AM CEST, I got a letter
> where Daniel Barkalow <barkalow@iabervon.org> told me that...
> > On Sat, 14 May 2005, Petr Baudis wrote:
> > 
> > > So what about just something like
> > > 
> > > 	git-wormhole-pull remote:refs/head/master wormhole://localhost/
> > > 
> > > That is, you could just specify remote:path_relative_to_url instead of
> > > SHA1 id as the commit.
> > 
> > Do you have any sensible alternatives to "remote:refs/<something>" in
> > mind? I suppose that "remote:HEAD" would also work. How are you thinking
> > of having the value get written locally?
> 
> Anything that gets eventually wound up in the info/ directory. (The name
> of the ignore file saved in info/ignore is the current hit.)

Hmm... maybe the right thing is to make the implementation-provided transfer code handle arbitrary things in GIT_DIR, but have code for updating reference files atomically and using a reference file to start from use "refs/"? Certainly, there's nothing special about reference files in transit.

Certainly the things in the info/ directory shouldn't be treated a head that you're going to pull, so that has to be different above the protocol level anyway.

> Well, it'd be again nice to have some generic mechanism for this so that
> the user could theoretically push over rsync too or something (although
> that'll be even more racy, it is fine for single-user repository).
Hmm; I'm not sure what would be good for interfacing with rsync.
> I think the remote file to write the value inside should be porcelain
> business.

Certainly it's porcelain business what remote file to write; but I think it has to be core business doing the lock, test, and update. I think it would be inconvenient to go back to the porcelain layer in the middle of the operation, particularly since it would have to go back to the core, which is what has the connection to the remote host.

Show 5 quoted lines
> What you should always check though is that before the pull
> (and after the locking) the value in that file is the same as the "push
> base". This way you make sure that you are still following a single
> branch and in case of multiuser repositories that you were fully merged
> before pushing.

So the remote receiver should get an instruction: change X from OLD to NEW and pull NEW. It should:

 - lock the file against further updates
 - check that the current value is the provided OLD
 - pull the necessary objects
 - write NEW to the file
 - report success
On failure of any step, it should unlock the file without changing it.
	-Daniel
*This .sig left intentionally blank*
Petr Baudis· May 17, 2005, 21:45 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

Dear diary, on Tue, May 17, 2005 at 11:20:54PM CEST, I got a letter where Daniel Barkalow <barkalow@iabervon.org> told me that...

Show 13 quoted lines
> On Tue, 17 May 2005, Petr Baudis wrote:
> > Anything that gets eventually wound up in the info/ directory. (The name
> > of the ignore file saved in info/ignore is the current hit.)
> 
> Hmm... maybe the right thing is to make the implementation-provided
> transfer code handle arbitrary things in GIT_DIR, but have code for
> updating reference files atomically and using a reference file to start
> from use "refs/"? Certainly, there's nothing special about reference files
> in transit.
> 
> Certainly the things in the info/ directory shouldn't be treated a head
> that you're going to pull, so that has to be different above the protocol
> level anyway.

*confused* :) I'm sorry, I have trouble understanding this. Could you rephrase, please?

Show 5 quoted lines
> > Well, it'd be again nice to have some generic mechanism for this so that
> > the user could theoretically push over rsync too or something (although
> > that'll be even more racy, it is fine for single-user repository).
> 
> Hmm; I'm not sure what would be good for interfacing with rsync.

I've been thinking about writing some FTP-like client for rsync, where you could "interactively" tell it what files to download etc.

Show 8 quoted lines
> > I think the remote file to write the value inside should be porcelain
> > business.
> 
> Certainly it's porcelain business what remote file to write; but I think
> it has to be core business doing the lock, test, and update. I think it
> would be inconvenient to go back to the porcelain layer in the middle of
> the operation, particularly since it would have to go back to the core,
> which is what has the connection to the remote host.
Of course. The porcelain file would just provide the filename.
Show 13 quoted lines
> > What you should always check though is that before the pull
> > (and after the locking) the value in that file is the same as the "push
> > base". This way you make sure that you are still following a single
> > branch and in case of multiuser repositories that you were fully merged
> > before pushing.
> 
> So the remote receiver should get an instruction: change X from OLD to NEW
> and pull NEW. It should:
> 
>  - lock the file against further updates
>  - check that the current value is the provided OLD
>  - pull the necessary objects
>  - write NEW to the file
- unlock the file ;-))
>  - report success
> 
> On failure of any step, it should unlock the file without changing it.
Sounds right.
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
Daniel Barkalow· May 17, 2005, 22:20 UTC · re: Petr Baudis · lore

Re: [PATCH 0/4] Pulling refs files

On Tue, 17 May 2005, Petr Baudis wrote:
Show 14 quoted lines
> Dear diary, on Tue, May 17, 2005 at 11:20:54PM CEST, I got a letter
> where Daniel Barkalow <barkalow@iabervon.org> told me that...
> > Hmm... maybe the right thing is to make the implementation-provided
> > transfer code handle arbitrary things in GIT_DIR, but have code for
> > updating reference files atomically and using a reference file to start
> > from use "refs/"? Certainly, there's nothing special about reference files
> > in transit.
> > 
> > Certainly the things in the info/ directory shouldn't be treated a head
> > that you're going to pull, so that has to be different above the protocol
> > level anyway.
> 
> *confused* :) I'm sorry, I have trouble understanding this. Could you
> rephrase, please?

If you want to get info/ignore, you want to get it and save it, not download a set of objects it refers to. So it's different from specifying that you want to use refs/heads/master as the starting point for a pull.

There would be a separation between transfering whatever file you specify and treating the specified (remote) file from refs/ as the starting point for pulling objects.

Also, you don't need to do the same kind of careful update, since the desired value of info/ignore isn't going to depend on the previous value.

Show 8 quoted lines
> > So the remote receiver should get an instruction: change X from OLD to NEW
> > and pull NEW. It should:
> > 
> >  - lock the file against further updates
> >  - check that the current value is the provided OLD
> >  - pull the necessary objects
> >  - write NEW to the file
> - unlock the file ;-))

The way I'm actually doing things is to write NEW into the lock file at some arbitrary point, and "writing to the file" is actually renaming the lock file to the normal filename. So writing unlocks the file automatically.

Show 5 quoted lines
> >  - report success
> > 
> > On failure of any step, it should unlock the file without changing it.
> 
> Sounds right.

I think I'll get to implementing it Wednesday night. I might be able to get the first step done tonight (my previous patch, except with the transfer applying to arbitrary files).

	-Daniel
*This .sig left intentionally blank*
Petr Baudis· May 18, 2005, 21:35 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

Dear diary, on Wed, May 18, 2005 at 12:20:40AM CEST, I got a letter where Daniel Barkalow <barkalow@iabervon.org> told me that...

Show 20 quoted lines
> On Tue, 17 May 2005, Petr Baudis wrote:
> 
> > Dear diary, on Tue, May 17, 2005 at 11:20:54PM CEST, I got a letter
> > where Daniel Barkalow <barkalow@iabervon.org> told me that...
> > > Hmm... maybe the right thing is to make the implementation-provided
> > > transfer code handle arbitrary things in GIT_DIR, but have code for
> > > updating reference files atomically and using a reference file to start
> > > from use "refs/"? Certainly, there's nothing special about reference files
> > > in transit.
> > > 
> > > Certainly the things in the info/ directory shouldn't be treated a head
> > > that you're going to pull, so that has to be different above the protocol
> > > level anyway.
> > 
> > *confused* :) I'm sorry, I have trouble understanding this. Could you
> > rephrase, please?
> 
> If you want to get info/ignore, you want to get it and save it, not
> download a set of objects it refers to. So it's different from specifying
> that you want to use refs/heads/master as the starting point for a pull.

Obviously. I think you should need to "explicitly" tell pull to actually save any files locally, since you (I mean Cogito) certainly does not want the pull stuff to touch the local refs/heads/master - it wants it in some other file.

Show 13 quoted lines
> > > So the remote receiver should get an instruction: change X from OLD to NEW
> > > and pull NEW. It should:
> > > 
> > >  - lock the file against further updates
> > >  - check that the current value is the provided OLD
> > >  - pull the necessary objects
> > >  - write NEW to the file
> > - unlock the file ;-))
> 
> The way I'm actually doing things is to write NEW into the lock file at
> some arbitrary point, and "writing to the file" is actually renaming the
> lock file to the normal filename. So writing unlocks the file
> automatically.
Ah. Obviously. That makes sense. :-)
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
Daniel Barkalow· May 19, 2005, 03:19 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

On Tue, 17 May 2005, Daniel Barkalow wrote:
> I think I'll get to implementing it Wednesday night. I might be able to
> get the first step done tonight (my previous patch, except with the
> transfer applying to arbitrary files).

Upon further consideration, I think there are three things that pull implementation needs to handle:

 1) fetching object files by hash, validating them, and writing them to
    the local objects directory
 2) fetching reference files by name, and making them available to the
    local program without writing them to disk at all.
 3) fetching other files by name and writing them to either the
    corresponding filename or a provided replacement.

I had thought that (2) could be done as a special case of (3), but I think that it has to be separate, because (2) just returns the value, while (3) can't just return the contents, but has to write it somewhere, since it isn't constrained to be exactly 20 bytes.

So I think I'd like to do essentially the original series, slightly rearranged and with a few edits, and then add (3) afterwards; this should be easy once the rpush/rpull changes to make the protocol extensible are in place.

I'll also do additional (independant) patches to provide an expected starting point and lock things appropriately.

	-Daniel
*This .sig left intentionally blank*
Petr Baudis· May 19, 2005, 06:52 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

Dear diary, on Thu, May 19, 2005 at 05:19:01AM CEST, I got a letter where Daniel Barkalow <barkalow@iabervon.org> told me that...

Show 9 quoted lines
>  2) fetching reference files by name, and making them available to the
>     local program without writing them to disk at all.
>  3) fetching other files by name and writing them to either the
>     corresponding filename or a provided replacement.
> 
> I had thought that (2) could be done as a special case of (3), but I think
> that it has to be separate, because (2) just returns the value, while
> (3) can't just return the contents, but has to write it somewhere, since
> it isn't constrained to be exactly 20 bytes.

Huh. How would (2) be useful and why can't you just still write it e.g. to some user-supplied temporary file? I think that'd be still actually much less trouble for the scripts to handle.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
Daniel Barkalow· May 19, 2005, 16:00 UTC · re: Petr Baudis · lore

Re: [PATCH 0/4] Pulling refs files

On Thu, 19 May 2005, Petr Baudis wrote:
Show 15 quoted lines
> Dear diary, on Thu, May 19, 2005 at 05:19:01AM CEST, I got a letter
> where Daniel Barkalow <barkalow@iabervon.org> told me that...
> >  2) fetching reference files by name, and making them available to the
> >     local program without writing them to disk at all.
> >  3) fetching other files by name and writing them to either the
> >     corresponding filename or a provided replacement.
> > 
> > I had thought that (2) could be done as a special case of (3), but I think
> > that it has to be separate, because (2) just returns the value, while
> > (3) can't just return the contents, but has to write it somewhere, since
> > it isn't constrained to be exactly 20 bytes.
> 
> Huh. How would (2) be useful and why can't you just still write it e.g.
> to some user-supplied temporary file? I think that'd be still actually
> much less trouble for the scripts to handle.

(2) is what is needed if the user just requests downloading objects starting with a reference stored remotely, and doesn't request that the reference be written anywhere. It is also useful because the system wants to verify that it has actually downloaded the objects successfully before writing the reference.

Note that the scripts see a higher-level interface; these are the operations that (e.g.) http-pull.c has to provide for pull.c, which builds a larger operation (determine the target hash, download the objects, write the specified ref file) out of them. It would be inconvenient for pull.c to download to a temporary file and then read the temporary file, which shouldn't normally be visible yet, to figure out what it's doing. It wants to have a function that takes a string and returns a hash, getting the value from the remote host, and it's inconvenient to deal with the disk in the middle.

	-Daniel
*This .sig left intentionally blank*
Junio C Hamano· May 15, 2005, 05:33 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

I am having a bit hard time understanding how the end user uses what you are trying to give them. Is the basic idea to let them say "I want to get Pasky's $GIT_DIR/refs/heads/master and store it in my $GIT_DIR/refs/heads/git-pb, and then I want to start the pull starting from the commit recorded in that ref"?

Assuming that is what you are doing, I do not have much objection to it. I however think introducing REFS_ENVIRONMENT is going overboard.

My understanding of the definition of GIT_DIR is "the directory traditionally known as $(pwd)/.git/ where various things hang underneath". We have GIT_OBJECT_DIRECTORY configurable to be set to something other than $GIT_DIR/objects because people may want to use shared object pools. We have GIT_INDEX_FILE configurable to be set to something other than $GIT_DIR/index because being able to have it on tmp filesystem for some application (like "merge my head and his head without using what I have in my work dir which is a bit ahead of my head already") helps performance; also some Porcelain operations benefit from being able to switch between multiple cache files. I cannot think of a similar argument with an example use pattern that justifies REFS_ENVIRONMENT being set to anything other than $GIT_DIR/refs/.

Daniel Barkalow· May 15, 2005, 15:40 UTC · re: Junio C Hamano · lore

Re: [PATCH 0/4] Pulling refs files

On Sat, 14 May 2005, Junio C Hamano wrote:
Show 5 quoted lines
> I am having a bit hard time understanding how the end user uses
> what you are trying to give them.  Is the basic idea to let them
> say "I want to get Pasky's $GIT_DIR/refs/heads/master and store
> it in my $GIT_DIR/refs/heads/git-pb, and then I want to start
> the pull starting from the commit recorded in that ref"?

Yes. This would be: git-http-pull -w heads/git-pb heads/master http://www.kernel.org/pub/scm/cogito/git-pb.git/

> Assuming that is what you are doing, I do not have much
> objection to it.  I however think introducing REFS_ENVIRONMENT
> is going overboard.

Now that we have GIT_DIR, you're probably right. I mainly kept it there for symmetry. On the other hand, I think that, if you're using a shared objects directory, you want to also use a shared refs directory, or you'll never be able to identify unreachable objects accurately.

	-Daniel
*This .sig left intentionally blank*
Junio C Hamano· May 16, 2005, 07:55 UTC · re: Daniel Barkalow · lore

Re: [PATCH 0/4] Pulling refs files

>>>>> "DB" == Daniel Barkalow <barkalow@iabervon.org> writes:
DB> On Sat, 14 May 2005, Junio C Hamano wrote:
Show 5 quoted lines
>> I am having a bit hard time understanding how the end user uses
>> what you are trying to give them.  Is the basic idea to let them
>> say "I want to get Pasky's $GIT_DIR/refs/heads/master and store
>> it in my $GIT_DIR/refs/heads/git-pb, and then I want to start
>> the pull starting from the commit recorded in that ref"?

DB> Yes. This would be: git-http-pull -w heads/git-pb heads/master DB> http://www.kernel.org/pub/scm/cogito/git-pb.git/

That would be quite handy. IIRC, Pasky had a gripe about limiting this under refs hierarchy (that's why you can write "heads/master" in your example not "refs/heads/master", though), and I am sympathetic to it. Giving unlimited download access anywhere under foobar.git/ would be fine. About the receiving side, letting things to be written anywhere the user wants would also be fine.

Since this will all be scripted anyway, I do not mind if the above example needs to be spelled as:

 $ git-http-pull -w ${GIT_DIR-.git}/refs/heads/git-pb refs/heads/master \
   http://www.kernel.org/pub/scm/cogito/git-pb.git/

← back to recent threads