blob: 238032b798008cd1f96d5083b63dc582f8191a1d [file] [log] [blame]
Junio C Hamano215a7ad2005-09-07 17:26:23 -07001#include "fetch.h"
Daniel Barkalow4250a5e2005-04-30 16:53:56 -07002
3#include "cache.h"
4#include "commit.h"
5#include "tree.h"
Linus Torvalds1bc995a2006-05-29 12:20:48 -07006#include "tree-walk.h"
Daniel Barkalow3173bd42005-06-21 20:35:53 -04007#include "tag.h"
8#include "blob.h"
Daniel Barkalowcd541a62005-06-06 16:38:26 -04009#include "refs.h"
10
11const char *write_ref = NULL;
Shawn Pearced0740d92006-05-19 03:29:26 -040012const char *write_ref_log_details = NULL;
Daniel Barkalowcd541a62005-06-06 16:38:26 -040013
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070014int get_tree = 0;
15int get_history = 0;
16int get_all = 0;
Junio C Hamanoe78d9772005-05-06 01:37:21 -070017int get_verbosely = 0;
Daniel Barkalow820eca62005-09-26 21:38:08 -040018int get_recover = 0;
Junio C Hamanob2d62f12005-05-04 01:26:24 -070019static unsigned char current_commit_sha1[20];
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070020
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -040021void pull_say(const char *fmt, const char *hex)
22{
Junio C Hamanoe78d9772005-05-06 01:37:21 -070023 if (get_verbosely)
24 fprintf(stderr, fmt, hex);
25}
26
Junio C Hamanob2d62f12005-05-04 01:26:24 -070027static void report_missing(const char *what, const unsigned char *missing)
Junio C Hamanoee4f4392005-05-01 21:07:40 -070028{
Junio C Hamanob2d62f12005-05-04 01:26:24 -070029 char missing_hex[41];
30
31 strcpy(missing_hex, sha1_to_hex(missing));;
32 fprintf(stderr,
33 "Cannot obtain needed %s %s\nwhile processing commit %s.\n",
34 what, missing_hex, sha1_to_hex(current_commit_sha1));
35}
36
Sergey Vlasov80077f02005-09-21 20:33:54 +040037static int process(struct object *obj);
Daniel Barkalow3173bd42005-06-21 20:35:53 -040038
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -040039static int process_tree(struct tree *tree)
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070040{
Linus Torvalds1bc995a2006-05-29 12:20:48 -070041 struct tree_desc desc;
Linus Torvalds4c068a92006-05-30 09:45:45 -070042 struct name_entry entry;
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070043
44 if (parse_tree(tree))
45 return -1;
46
Linus Torvalds1bc995a2006-05-29 12:20:48 -070047 desc.buf = tree->buffer;
48 desc.size = tree->size;
Linus Torvalds4c068a92006-05-30 09:45:45 -070049 while (tree_entry(&desc, &entry)) {
Junio C Hamano6f9012b2006-06-02 15:23:47 -070050 struct object *obj = NULL;
51
Linus Torvalds4c068a92006-05-30 09:45:45 -070052 if (S_ISDIR(entry.mode)) {
53 struct tree *tree = lookup_tree(entry.sha1);
Junio C Hamano6f9012b2006-06-02 15:23:47 -070054 if (tree)
55 obj = &tree->object;
Linus Torvalds2d9c58c2006-05-29 12:18:33 -070056 }
Junio C Hamano6f9012b2006-06-02 15:23:47 -070057 else {
58 struct blob *blob = lookup_blob(entry.sha1);
59 if (blob)
60 obj = &blob->object;
61 }
62 if (!obj || process(obj))
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070063 return -1;
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070064 }
Linus Torvalds2d9c58c2006-05-29 12:18:33 -070065 free(tree->buffer);
66 tree->buffer = NULL;
Linus Torvalds1bc995a2006-05-29 12:20:48 -070067 tree->size = 0;
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070068 return 0;
69}
70
Sergey Vlasov24451c32005-09-21 20:34:24 +040071#define COMPLETE (1U << 0)
72#define SEEN (1U << 1)
73#define TO_SCAN (1U << 2)
Junio C Hamano85d106c2005-09-18 01:01:07 -070074
Junio C Hamanod0ac30f2005-09-16 14:30:29 -070075static struct commit_list *complete = NULL;
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -040076
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -040077static int process_commit(struct commit *commit)
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070078{
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -040079 if (parse_commit(commit))
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070080 return -1;
81
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -040082 while (complete && complete->item->date >= commit->date) {
Junio C Hamanod0ac30f2005-09-16 14:30:29 -070083 pop_most_recent_commit(&complete, COMPLETE);
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -040084 }
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -040085
Junio C Hamanod0ac30f2005-09-16 14:30:29 -070086 if (commit->object.flags & COMPLETE)
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -040087 return 0;
88
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -040089 memcpy(current_commit_sha1, commit->object.sha1, 20);
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070090
Junio C Hamano85d106c2005-09-18 01:01:07 -070091 pull_say("walk %s\n", sha1_to_hex(commit->object.sha1));
92
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070093 if (get_tree) {
Sergey Vlasov80077f02005-09-21 20:33:54 +040094 if (process(&commit->tree->object))
Daniel Barkalow4250a5e2005-04-30 16:53:56 -070095 return -1;
96 if (!get_all)
97 get_tree = 0;
98 }
99 if (get_history) {
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400100 struct commit_list *parents = commit->parents;
Daniel Barkalow4250a5e2005-04-30 16:53:56 -0700101 for (; parents; parents = parents->next) {
Sergey Vlasov80077f02005-09-21 20:33:54 +0400102 if (process(&parents->item->object))
Daniel Barkalow4250a5e2005-04-30 16:53:56 -0700103 return -1;
104 }
105 }
106 return 0;
107}
108
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400109static int process_tag(struct tag *tag)
Daniel Barkalow3173bd42005-06-21 20:35:53 -0400110{
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400111 if (parse_tag(tag))
Daniel Barkalow3173bd42005-06-21 20:35:53 -0400112 return -1;
Sergey Vlasov80077f02005-09-21 20:33:54 +0400113 return process(tag->tagged);
Daniel Barkalow3173bd42005-06-21 20:35:53 -0400114}
115
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400116static struct object_list *process_queue = NULL;
117static struct object_list **process_queue_end = &process_queue;
118
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400119static int process_object(struct object *obj)
120{
Linus Torvalds885a86a2006-06-14 16:45:13 -0700121 if (obj->type == TYPE_COMMIT) {
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400122 if (process_commit((struct commit *)obj))
123 return -1;
124 return 0;
125 }
Linus Torvalds885a86a2006-06-14 16:45:13 -0700126 if (obj->type == TYPE_TREE) {
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400127 if (process_tree((struct tree *)obj))
128 return -1;
129 return 0;
130 }
Linus Torvalds885a86a2006-06-14 16:45:13 -0700131 if (obj->type == TYPE_BLOB) {
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400132 return 0;
133 }
Linus Torvalds885a86a2006-06-14 16:45:13 -0700134 if (obj->type == TYPE_TAG) {
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400135 if (process_tag((struct tag *)obj))
136 return -1;
137 return 0;
138 }
139 return error("Unable to determine requirements "
140 "of type %s for %s",
Linus Torvalds885a86a2006-06-14 16:45:13 -0700141 typename(obj->type), sha1_to_hex(obj->sha1));
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400142}
143
Sergey Vlasov80077f02005-09-21 20:33:54 +0400144static int process(struct object *obj)
Daniel Barkalow3173bd42005-06-21 20:35:53 -0400145{
Sergey Vlasova82d07e2005-09-21 20:33:59 +0400146 if (obj->flags & SEEN)
147 return 0;
148 obj->flags |= SEEN;
149
Sergey Vlasov80077f02005-09-21 20:33:54 +0400150 if (has_sha1_file(obj->sha1)) {
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400151 /* We already have it, so we should scan it now. */
Junio C Hamano85d106c2005-09-18 01:01:07 -0700152 obj->flags |= TO_SCAN;
Junio C Hamanoe5f38ec2006-06-06 14:04:17 -0700153 }
154 else {
Sergey Vlasov7b64d062005-09-21 20:34:14 +0400155 if (obj->flags & COMPLETE)
156 return 0;
157 prefetch(obj->sha1);
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400158 }
Sergey Vlasov7b64d062005-09-21 20:34:14 +0400159
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400160 object_list_insert(obj, process_queue_end);
161 process_queue_end = &(*process_queue_end)->next;
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400162 return 0;
163}
164
165static int loop(void)
166{
Junio C Hamano85d106c2005-09-18 01:01:07 -0700167 struct object_list *elem;
168
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400169 while (process_queue) {
170 struct object *obj = process_queue->item;
Junio C Hamano85d106c2005-09-18 01:01:07 -0700171 elem = process_queue;
172 process_queue = elem->next;
173 free(elem);
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400174 if (!process_queue)
175 process_queue_end = &process_queue;
176
Junio C Hamano85d106c2005-09-18 01:01:07 -0700177 /* If we are not scanning this object, we placed it in
178 * the queue because we needed to fetch it first.
179 */
180 if (! (obj->flags & TO_SCAN)) {
Nick Hengeveld11f0daf2005-10-10 23:22:01 -0700181 if (fetch(obj->sha1)) {
Linus Torvalds885a86a2006-06-14 16:45:13 -0700182 report_missing(typename(obj->type), obj->sha1);
Junio C Hamano85d106c2005-09-18 01:01:07 -0700183 return -1;
184 }
185 }
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400186 if (!obj->type)
187 parse_object(obj->sha1);
Daniel Barkalowf88fcf82005-08-11 19:38:09 -0400188 if (process_object(obj))
189 return -1;
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400190 }
191 return 0;
Daniel Barkalow3173bd42005-06-21 20:35:53 -0400192}
193
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400194static int interpret_target(char *target, unsigned char *sha1)
195{
196 if (!get_sha1_hex(target, sha1))
197 return 0;
198 if (!check_ref_format(target)) {
199 if (!fetch_ref(target, sha1)) {
200 return 0;
201 }
202 }
203 return -1;
204}
205
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -0400206static int mark_complete(const char *path, const unsigned char *sha1)
207{
Junio C Hamanod0ac30f2005-09-16 14:30:29 -0700208 struct commit *commit = lookup_commit_reference_gently(sha1, 1);
209 if (commit) {
210 commit->object.flags |= COMPLETE;
211 insert_by_date(commit, &complete);
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -0400212 }
213 return 0;
214}
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400215
Daniel Barkalow4250a5e2005-04-30 16:53:56 -0700216int pull(char *target)
217{
Junio C Hamano99bd0f52006-05-31 15:23:44 -0700218 struct ref_lock *lock = NULL;
Daniel Barkalow4250a5e2005-04-30 16:53:56 -0700219 unsigned char sha1[20];
Shawn Pearced0740d92006-05-19 03:29:26 -0400220 char *msg;
221 int ret;
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400222
Junio C Hamano98533b92005-09-15 15:06:39 -0700223 save_commit_buffer = 0;
Sergey Vlasova95cb6f2005-09-23 16:28:13 +0400224 track_object_refs = 0;
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400225 if (write_ref) {
Junio C Hamanoa5c8a982006-05-24 16:49:24 -0700226 lock = lock_ref_sha1(write_ref, NULL, 0);
Shawn Pearced0740d92006-05-19 03:29:26 -0400227 if (!lock) {
228 error("Can't lock ref %s", write_ref);
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400229 return -1;
Shawn Pearced0740d92006-05-19 03:29:26 -0400230 }
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400231 }
232
Junio C Hamano84c667f2006-05-24 16:42:38 -0700233 if (!get_recover)
Daniel Barkalow820eca62005-09-26 21:38:08 -0400234 for_each_ref(mark_complete);
Daniel Barkalow22c6e1d2005-09-14 21:31:42 -0400235
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400236 if (interpret_target(target, sha1)) {
237 error("Could not interpret %s as something to pull", target);
Junio C Hamano99bd0f52006-05-31 15:23:44 -0700238 if (lock)
239 unlock_ref(lock);
barkalow@iabervon.org1e8be592005-08-02 19:46:10 -0400240 return -1;
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400241 }
242 if (process(lookup_unknown_object(sha1))) {
Junio C Hamano99bd0f52006-05-31 15:23:44 -0700243 if (lock)
244 unlock_ref(lock);
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400245 return -1;
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400246 }
247 if (loop()) {
Junio C Hamano99bd0f52006-05-31 15:23:44 -0700248 if (lock)
249 unlock_ref(lock);
Shawn Pearce4bd18c42006-05-17 05:55:02 -0400250 return -1;
251 }
252
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400253 if (write_ref) {
Shawn Pearced0740d92006-05-19 03:29:26 -0400254 if (write_ref_log_details) {
255 msg = xmalloc(strlen(write_ref_log_details) + 12);
256 sprintf(msg, "fetch from %s", write_ref_log_details);
Junio C Hamanoe5f38ec2006-06-06 14:04:17 -0700257 }
258 else
Shawn Pearced0740d92006-05-19 03:29:26 -0400259 msg = NULL;
260 ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)");
261 if (msg)
262 free(msg);
263 return ret;
Daniel Barkalowcd541a62005-06-06 16:38:26 -0400264 }
265 return 0;
Daniel Barkalow4250a5e2005-04-30 16:53:56 -0700266}