summaryrefslogtreecommitdiff
path: root/upload-pack.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-07-04 20:26:53 (GMT)
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-04 20:26:53 (GMT)
commitdef88e9afbf915ad76781aba7274398963b5e1a7 (patch)
treef522cf646eafdefe3f916ff58ecfc779dde69ada /upload-pack.c
parent013e7c7ff498aae82d799f80da37fbd395545456 (diff)
downloadgit-def88e9afbf915ad76781aba7274398963b5e1a7.zip
git-def88e9afbf915ad76781aba7274398963b5e1a7.tar.gz
git-def88e9afbf915ad76781aba7274398963b5e1a7.tar.bz2
Commit first cut at "git-fetch-pack"
It's meant to be used by "git fetch" for the local and ssh case. It doesn't actually do the fetching now, but it does discover the common commit point.
Diffstat (limited to 'upload-pack.c')
-rw-r--r--upload-pack.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/upload-pack.c b/upload-pack.c
new file mode 100644
index 0000000..18b8e1a
--- /dev/null
+++ b/upload-pack.c
@@ -0,0 +1,86 @@
+#include "cache.h"
+#include "refs.h"
+#include "pkt-line.h"
+
+static const char upload_pack_usage[] = "git-upload-pack <dir>";
+
+static int got_sha1(char *hex, unsigned char *sha1)
+{
+ if (get_sha1_hex(hex, sha1))
+ die("git-upload-pack: expected SHA1 object, got '%s'", hex);
+ return has_sha1_file(sha1);
+}
+
+static int get_common_commits(void)
+{
+ static char line[1000];
+ unsigned char sha1[20];
+ int len;
+
+ for(;;) {
+ len = packet_read_line(0, line, sizeof(line));
+
+ if (!len) {
+ packet_write(1, "NAK\n");
+ continue;
+ }
+ if (line[len-1] == '\n')
+ line[--len] = 0;
+ if (!strncmp(line, "have ", 5)) {
+ if (got_sha1(line+5, sha1)) {
+ packet_write(1, "ACK %s\n", sha1_to_hex(sha1));
+ break;
+ }
+ continue;
+ }
+ if (!strcmp(line, "done")) {
+ packet_write(1, "NAK\n");
+ return -1;
+ }
+ die("git-upload-pack: expected SHA1 list, got '%s'", line);
+ }
+
+ for (;;) {
+ len = packet_read_line(0, line, sizeof(line));
+ if (!len)
+ break;
+ if (!strncmp(line, "have ", 5)) {
+ got_sha1(line+5, sha1);
+ continue;
+ }
+ if (!strcmp(line, "done"))
+ break;
+ die("git-upload-pack: expected SHA1 list, got '%s'", line);
+ }
+ return 0;
+}
+
+static int send_ref(const char *refname, const unsigned char *sha1)
+{
+ packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
+ return 0;
+}
+
+static int upload_pack(void)
+{
+ for_each_ref(send_ref);
+ packet_flush(1);
+ get_common_commits();
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ const char *dir;
+ if (argc != 2)
+ usage(upload_pack_usage);
+ dir = argv[1];
+ if (chdir(dir))
+ die("git-upload-pack unable to chdir to %s", dir);
+ chdir(".git");
+ if (access("objects", X_OK) || access("refs", X_OK))
+ die("git-upload-pack: %s doesn't seem to be a git archive", dir);
+ setenv("GIT_DIR", ".", 1);
+ upload_pack();
+ return 0;
+}