aboutsummaryrefslogtreecommitdiff
path: root/rpull.c
diff options
context:
space:
mode:
authorDaniel Barkalow <barkalow@iabervon.org>2005-04-23 18:47:23 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-23 18:47:23 -0700
commit6eb7ed5403b7d57d5ed7e30d0cd0b312888ee95c (patch)
tree3b4a5bb703599458ce8fe504f37f8e28b77bd6ca /rpull.c
parentb6b15db3f464b18180eee79927cb324fd63e15ff (diff)
downloadgit-6eb7ed5403b7d57d5ed7e30d0cd0b312888ee95c.tar.gz
git-6eb7ed5403b7d57d5ed7e30d0cd0b312888ee95c.tar.xz
[PATCH] Various transport programs
This patch adds three similar and related programs. http-pull downloads objects from an HTTP server; rpull downloads objects by using ssh and rpush on the other side; and rpush uploads objects by using ssh and rpull on the other side. The algorithm should be sufficient to make the network throughput required depend only on how much content is new, not at all on how much content the repository contains. The combination should enable people to have remote repositories by way of ssh login for authenticated users and HTTP for anonymous access. Signed-Off-By: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'rpull.c')
-rw-r--r--rpull.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/rpull.c b/rpull.c
new file mode 100644
index 000000000..c27af2c24
--- /dev/null
+++ b/rpull.c
@@ -0,0 +1,128 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include "cache.h"
+#include "commit.h"
+#include <errno.h>
+#include <stdio.h>
+#include "rsh.h"
+
+static int tree = 0;
+static int commits = 0;
+static int all = 0;
+
+static int fd_in;
+static int fd_out;
+
+static int fetch(unsigned char *sha1)
+{
+ if (has_sha1_file(sha1))
+ return 0;
+ write(fd_out, sha1, 20);
+ return write_sha1_from_fd(sha1, fd_in);
+}
+
+static int process_tree(unsigned char *sha1)
+{
+ struct tree *tree = lookup_tree(sha1);
+ struct tree_entry_list *entries;
+
+ if (parse_tree(tree))
+ return -1;
+
+ for (entries = tree->entries; entries; entries = entries->next) {
+ /*
+ fprintf(stderr, "Tree %s ", sha1_to_hex(sha1));
+ fprintf(stderr, "needs %s\n",
+ sha1_to_hex(entries->item.tree->object.sha1));
+ */
+ if (fetch(entries->item.tree->object.sha1)) {
+ return error("Missing item %s",
+ sha1_to_hex(entries->item.tree->object.sha1));
+ }
+ if (entries->directory) {
+ if (process_tree(entries->item.tree->object.sha1))
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int process_commit(unsigned char *sha1)
+{
+ struct commit *obj = lookup_commit(sha1);
+
+ if (fetch(sha1)) {
+ return error("Fetching %s", sha1_to_hex(sha1));
+ }
+
+ if (parse_commit(obj))
+ return -1;
+
+ if (tree) {
+ if (fetch(obj->tree->object.sha1))
+ return -1;
+ if (process_tree(obj->tree->object.sha1))
+ return -1;
+ if (!all)
+ tree = 0;
+ }
+ if (commits) {
+ struct commit_list *parents = obj->parents;
+ for (; parents; parents = parents->next) {
+ if (has_sha1_file(parents->item->object.sha1))
+ continue;
+ if (fetch(parents->item->object.sha1)) {
+ /* The server might not have it, and
+ * we don't mind.
+ */
+ error("Missing tree %s; continuing",
+ sha1_to_hex(parents->item->object.sha1));
+ continue;
+ }
+ if (process_commit(parents->item->object.sha1))
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ char *commit_id;
+ char *url;
+ int arg = 1;
+ unsigned char sha1[20];
+
+ while (arg < argc && argv[arg][0] == '-') {
+ if (argv[arg][1] == 't') {
+ tree = 1;
+ } else if (argv[arg][1] == 'c') {
+ commits = 1;
+ } else if (argv[arg][1] == 'a') {
+ all = 1;
+ tree = 1;
+ commits = 1;
+ }
+ arg++;
+ }
+ if (argc < arg + 2) {
+ usage("rpull [-c] [-t] [-a] commit-id url");
+ return 1;
+ }
+ commit_id = argv[arg];
+ url = argv[arg + 1];
+
+ if (setup_connection(&fd_in, &fd_out, "rpush", url, arg, argv + 1))
+ return 1;
+
+ get_sha1_hex(commit_id, sha1);
+
+ if (fetch(sha1))
+ return 1;
+ if (process_commit(sha1))
+ return 1;
+
+ return 0;
+}