]>
Commit | Line | Data |
---|---|---|
6eb7ed54 DB |
1 | #include <fcntl.h> |
2 | #include <unistd.h> | |
3 | #include <string.h> | |
4 | #include <stdlib.h> | |
5 | #include "cache.h" | |
6 | #include "commit.h" | |
7 | #include <errno.h> | |
8 | #include <stdio.h> | |
9 | #include "rsh.h" | |
10 | ||
11 | static int tree = 0; | |
12 | static int commits = 0; | |
13 | static int all = 0; | |
14 | ||
15 | static int fd_in; | |
16 | static int fd_out; | |
17 | ||
18 | static int fetch(unsigned char *sha1) | |
19 | { | |
20 | if (has_sha1_file(sha1)) | |
21 | return 0; | |
22 | write(fd_out, sha1, 20); | |
23 | return write_sha1_from_fd(sha1, fd_in); | |
24 | } | |
25 | ||
26 | static int process_tree(unsigned char *sha1) | |
27 | { | |
28 | struct tree *tree = lookup_tree(sha1); | |
29 | struct tree_entry_list *entries; | |
30 | ||
31 | if (parse_tree(tree)) | |
32 | return -1; | |
33 | ||
34 | for (entries = tree->entries; entries; entries = entries->next) { | |
35 | /* | |
36 | fprintf(stderr, "Tree %s ", sha1_to_hex(sha1)); | |
37 | fprintf(stderr, "needs %s\n", | |
38 | sha1_to_hex(entries->item.tree->object.sha1)); | |
39 | */ | |
40 | if (fetch(entries->item.tree->object.sha1)) { | |
41 | return error("Missing item %s", | |
42 | sha1_to_hex(entries->item.tree->object.sha1)); | |
43 | } | |
44 | if (entries->directory) { | |
45 | if (process_tree(entries->item.tree->object.sha1)) | |
46 | return -1; | |
47 | } | |
48 | } | |
49 | return 0; | |
50 | } | |
51 | ||
52 | static int process_commit(unsigned char *sha1) | |
53 | { | |
54 | struct commit *obj = lookup_commit(sha1); | |
55 | ||
56 | if (fetch(sha1)) { | |
57 | return error("Fetching %s", sha1_to_hex(sha1)); | |
58 | } | |
59 | ||
60 | if (parse_commit(obj)) | |
61 | return -1; | |
62 | ||
63 | if (tree) { | |
64 | if (fetch(obj->tree->object.sha1)) | |
65 | return -1; | |
66 | if (process_tree(obj->tree->object.sha1)) | |
67 | return -1; | |
68 | if (!all) | |
69 | tree = 0; | |
70 | } | |
71 | if (commits) { | |
72 | struct commit_list *parents = obj->parents; | |
73 | for (; parents; parents = parents->next) { | |
74 | if (has_sha1_file(parents->item->object.sha1)) | |
75 | continue; | |
76 | if (fetch(parents->item->object.sha1)) { | |
77 | /* The server might not have it, and | |
78 | * we don't mind. | |
79 | */ | |
80 | error("Missing tree %s; continuing", | |
81 | sha1_to_hex(parents->item->object.sha1)); | |
82 | continue; | |
83 | } | |
84 | if (process_commit(parents->item->object.sha1)) | |
85 | return -1; | |
86 | } | |
87 | } | |
88 | return 0; | |
89 | } | |
90 | ||
91 | int main(int argc, char **argv) | |
92 | { | |
93 | char *commit_id; | |
94 | char *url; | |
95 | int arg = 1; | |
96 | unsigned char sha1[20]; | |
97 | ||
98 | while (arg < argc && argv[arg][0] == '-') { | |
99 | if (argv[arg][1] == 't') { | |
100 | tree = 1; | |
101 | } else if (argv[arg][1] == 'c') { | |
102 | commits = 1; | |
103 | } else if (argv[arg][1] == 'a') { | |
104 | all = 1; | |
105 | tree = 1; | |
106 | commits = 1; | |
107 | } | |
108 | arg++; | |
109 | } | |
110 | if (argc < arg + 2) { | |
111 | usage("rpull [-c] [-t] [-a] commit-id url"); | |
112 | return 1; | |
113 | } | |
114 | commit_id = argv[arg]; | |
115 | url = argv[arg + 1]; | |
116 | ||
117 | if (setup_connection(&fd_in, &fd_out, "rpush", url, arg, argv + 1)) | |
118 | return 1; | |
119 | ||
120 | get_sha1_hex(commit_id, sha1); | |
121 | ||
122 | if (fetch(sha1)) | |
123 | return 1; | |
124 | if (process_commit(sha1)) | |
125 | return 1; | |
126 | ||
127 | return 0; | |
128 | } |