Start handling references internally as a sorted in-memory list
[git] / refs.c
1 #include "refs.h"
2 #include "cache.h"
3
4 #include <errno.h>
5
6 struct ref_list {
7         struct ref_list *next;
8         unsigned char sha1[20];
9         char name[FLEX_ARRAY];
10 };
11
12 static const char *parse_ref_line(char *line, unsigned char *sha1)
13 {
14         /*
15          * 42: the answer to everything.
16          *
17          * In this case, it happens to be the answer to
18          *  40 (length of sha1 hex representation)
19          *  +1 (space in between hex and name)
20          *  +1 (newline at the end of the line)
21          */
22         int len = strlen(line) - 42;
23
24         if (len <= 0)
25                 return NULL;
26         if (get_sha1_hex(line, sha1) < 0)
27                 return NULL;
28         if (!isspace(line[40]))
29                 return NULL;
30         line += 41;
31         if (line[len] != '\n')
32                 return NULL;
33         line[len] = 0;
34         return line;
35 }
36
37 static struct ref_list *add_ref(const char *name, const unsigned char *sha1, struct ref_list *list)
38 {
39         int len;
40         struct ref_list **p = &list, *entry;
41
42         /* Find the place to insert the ref into.. */
43         while ((entry = *p) != NULL) {
44                 int cmp = strcmp(entry->name, name);
45                 if (cmp > 0)
46                         break;
47
48                 /* Same as existing entry? */
49                 if (!cmp)
50                         return list;
51                 p = &entry->next;
52         }
53
54         /* Allocate it and add it in.. */
55         len = strlen(name) + 1;
56         entry = xmalloc(sizeof(struct ref_list) + len);
57         hashcpy(entry->sha1, sha1);
58         memcpy(entry->name, name, len);
59         entry->next = *p;
60         *p = entry;
61         return list;
62 }
63
64 static struct ref_list *get_packed_refs(void)
65 {
66         static int did_refs = 0;
67         static struct ref_list *refs = NULL;
68
69         if (!did_refs) {
70                 FILE *f = fopen(git_path("packed-refs"), "r");
71                 if (f) {
72                         struct ref_list *list = NULL;
73                         char refline[PATH_MAX];
74                         while (fgets(refline, sizeof(refline), f)) {
75                                 unsigned char sha1[20];
76                                 const char *name = parse_ref_line(refline, sha1);
77                                 if (!name)
78                                         continue;
79                                 list = add_ref(name, sha1, list);
80                         }
81                         fclose(f);
82                         refs = list;
83                 }
84                 did_refs = 1;
85         }
86         return refs;
87 }
88
89 static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
90 {
91         DIR *dir = opendir(git_path("%s", base));
92
93         if (dir) {
94                 struct dirent *de;
95                 int baselen = strlen(base);
96                 char *path = xmalloc(baselen + 257);
97
98                 memcpy(path, base, baselen);
99                 if (baselen && base[baselen-1] != '/')
100                         path[baselen++] = '/';
101
102                 while ((de = readdir(dir)) != NULL) {
103                         unsigned char sha1[20];
104                         struct stat st;
105                         int namelen;
106
107                         if (de->d_name[0] == '.')
108                                 continue;
109                         namelen = strlen(de->d_name);
110                         if (namelen > 255)
111                                 continue;
112                         if (has_extension(de->d_name, ".lock"))
113                                 continue;
114                         memcpy(path + baselen, de->d_name, namelen+1);
115                         if (stat(git_path("%s", path), &st) < 0)
116                                 continue;
117                         if (S_ISDIR(st.st_mode)) {
118                                 list = get_ref_dir(path, list);
119                                 continue;
120                         }
121                         if (read_ref(git_path("%s", path), sha1) < 0) {
122                                 error("%s points nowhere!", path);
123                                 continue;
124                         }
125                         list = add_ref(path, sha1, list);
126                 }
127                 free(path);
128                 closedir(dir);
129         }
130         return list;
131 }
132
133 static struct ref_list *get_loose_refs(void)
134 {
135         static int did_refs = 0;
136         static struct ref_list *refs = NULL;
137
138         if (!did_refs) {
139                 refs = get_ref_dir("refs", NULL);
140                 did_refs = 1;
141         }
142         return refs;
143 }
144
145 /* We allow "recursive" symbolic refs. Only within reason, though */
146 #define MAXDEPTH 5
147
148 const char *resolve_ref(const char *path, unsigned char *sha1, int reading)
149 {
150         int depth = MAXDEPTH, len;
151         char buffer[256];
152
153         for (;;) {
154                 struct stat st;
155                 char *buf;
156                 int fd;
157
158                 if (--depth < 0)
159                         return NULL;
160
161                 /* Special case: non-existing file.
162                  * Not having the refs/heads/new-branch is OK
163                  * if we are writing into it, so is .git/HEAD
164                  * that points at refs/heads/master still to be
165                  * born.  It is NOT OK if we are resolving for
166                  * reading.
167                  */
168                 if (lstat(path, &st) < 0) {
169                         if (reading || errno != ENOENT)
170                                 return NULL;
171                         hashclr(sha1);
172                         return path;
173                 }
174
175                 /* Follow "normalized" - ie "refs/.." symlinks by hand */
176                 if (S_ISLNK(st.st_mode)) {
177                         len = readlink(path, buffer, sizeof(buffer)-1);
178                         if (len >= 5 && !memcmp("refs/", buffer, 5)) {
179                                 path = git_path("%.*s", len, buffer);
180                                 continue;
181                         }
182                 }
183
184                 /*
185                  * Anything else, just open it and try to use it as
186                  * a ref
187                  */
188                 fd = open(path, O_RDONLY);
189                 if (fd < 0)
190                         return NULL;
191                 len = read(fd, buffer, sizeof(buffer)-1);
192                 close(fd);
193
194                 /*
195                  * Is it a symbolic ref?
196                  */
197                 if (len < 4 || memcmp("ref:", buffer, 4))
198                         break;
199                 buf = buffer + 4;
200                 len -= 4;
201                 while (len && isspace(*buf))
202                         buf++, len--;
203                 while (len && isspace(buf[len-1]))
204                         buf[--len] = 0;
205                 path = git_path("%.*s", len, buf);
206         }
207         if (len < 40 || get_sha1_hex(buffer, sha1))
208                 return NULL;
209         return path;
210 }
211
212 int create_symref(const char *git_HEAD, const char *refs_heads_master)
213 {
214         const char *lockpath;
215         char ref[1000];
216         int fd, len, written;
217
218 #ifndef NO_SYMLINK_HEAD
219         if (prefer_symlink_refs) {
220                 unlink(git_HEAD);
221                 if (!symlink(refs_heads_master, git_HEAD))
222                         return 0;
223                 fprintf(stderr, "no symlink - falling back to symbolic ref\n");
224         }
225 #endif
226
227         len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master);
228         if (sizeof(ref) <= len) {
229                 error("refname too long: %s", refs_heads_master);
230                 return -1;
231         }
232         lockpath = mkpath("%s.lock", git_HEAD);
233         fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); 
234         written = write(fd, ref, len);
235         close(fd);
236         if (written != len) {
237                 unlink(lockpath);
238                 error("Unable to write to %s", lockpath);
239                 return -2;
240         }
241         if (rename(lockpath, git_HEAD) < 0) {
242                 unlink(lockpath);
243                 error("Unable to create %s", git_HEAD);
244                 return -3;
245         }
246         if (adjust_shared_perm(git_HEAD)) {
247                 unlink(lockpath);
248                 error("Unable to fix permissions on %s", lockpath);
249                 return -4;
250         }
251         return 0;
252 }
253
254 int read_ref(const char *filename, unsigned char *sha1)
255 {
256         if (resolve_ref(filename, sha1, 1))
257                 return 0;
258         return -1;
259 }
260
261 static int do_for_each_ref(const char *base, int (*fn)(const char *path, const unsigned char *sha1), int trim)
262 {
263         int retval;
264         struct ref_list *packed = get_packed_refs();
265         struct ref_list *loose = get_loose_refs();
266
267         while (packed && loose) {
268                 struct ref_list *entry;
269                 int cmp = strcmp(packed->name, loose->name);
270                 if (!cmp) {
271                         packed = packed->next;
272                         continue;
273                 }
274                 if (cmp > 0) {
275                         entry = loose;
276                         loose = loose->next;
277                 } else {
278                         entry = packed;
279                         packed = packed->next;
280                 }
281                 if (strncmp(base, entry->name, trim))
282                         continue;
283                 retval = fn(entry->name + trim, entry->sha1);
284                 if (retval)
285                         return retval;
286         }
287
288         packed = packed ? packed : loose;
289         while (packed) {
290                 if (!strncmp(base, packed->name, trim)) {
291                         retval = fn(packed->name + trim, packed->sha1);
292                         if (retval)
293                                 return retval;
294                 }
295                 packed = packed->next;
296         }
297         return 0;
298 }
299
300 int head_ref(int (*fn)(const char *path, const unsigned char *sha1))
301 {
302         unsigned char sha1[20];
303         if (!read_ref(git_path("HEAD"), sha1))
304                 return fn("HEAD", sha1);
305         return 0;
306 }
307
308 int for_each_ref(int (*fn)(const char *path, const unsigned char *sha1))
309 {
310         return do_for_each_ref("refs/", fn, 0);
311 }
312
313 int for_each_tag_ref(int (*fn)(const char *path, const unsigned char *sha1))
314 {
315         return do_for_each_ref("refs/tags/", fn, 10);
316 }
317
318 int for_each_branch_ref(int (*fn)(const char *path, const unsigned char *sha1))
319 {
320         return do_for_each_ref("refs/heads/", fn, 11);
321 }
322
323 int for_each_remote_ref(int (*fn)(const char *path, const unsigned char *sha1))
324 {
325         return do_for_each_ref("refs/remotes/", fn, 13);
326 }
327
328 int get_ref_sha1(const char *ref, unsigned char *sha1)
329 {
330         if (check_ref_format(ref))
331                 return -1;
332         return read_ref(git_path("refs/%s", ref), sha1);
333 }
334
335 /*
336  * Make sure "ref" is something reasonable to have under ".git/refs/";
337  * We do not like it if:
338  *
339  * - any path component of it begins with ".", or
340  * - it has double dots "..", or
341  * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
342  * - it ends with a "/".
343  */
344
345 static inline int bad_ref_char(int ch)
346 {
347         return (((unsigned) ch) <= ' ' ||
348                 ch == '~' || ch == '^' || ch == ':' ||
349                 /* 2.13 Pattern Matching Notation */
350                 ch == '?' || ch == '*' || ch == '[');
351 }
352
353 int check_ref_format(const char *ref)
354 {
355         int ch, level;
356         const char *cp = ref;
357
358         level = 0;
359         while (1) {
360                 while ((ch = *cp++) == '/')
361                         ; /* tolerate duplicated slashes */
362                 if (!ch)
363                         return -1; /* should not end with slashes */
364
365                 /* we are at the beginning of the path component */
366                 if (ch == '.' || bad_ref_char(ch))
367                         return -1;
368
369                 /* scan the rest of the path component */
370                 while ((ch = *cp++) != 0) {
371                         if (bad_ref_char(ch))
372                                 return -1;
373                         if (ch == '/')
374                                 break;
375                         if (ch == '.' && *cp == '.')
376                                 return -1;
377                 }
378                 level++;
379                 if (!ch) {
380                         if (level < 2)
381                                 return -1; /* at least of form "heads/blah" */
382                         return 0;
383                 }
384         }
385 }
386
387 static struct ref_lock *verify_lock(struct ref_lock *lock,
388         const unsigned char *old_sha1, int mustexist)
389 {
390         char buf[40];
391         int nr, fd = open(lock->ref_file, O_RDONLY);
392         if (fd < 0 && (mustexist || errno != ENOENT)) {
393                 error("Can't verify ref %s", lock->ref_file);
394                 unlock_ref(lock);
395                 return NULL;
396         }
397         nr = read(fd, buf, 40);
398         close(fd);
399         if (nr != 40 || get_sha1_hex(buf, lock->old_sha1) < 0) {
400                 error("Can't verify ref %s", lock->ref_file);
401                 unlock_ref(lock);
402                 return NULL;
403         }
404         if (hashcmp(lock->old_sha1, old_sha1)) {
405                 error("Ref %s is at %s but expected %s", lock->ref_file,
406                         sha1_to_hex(lock->old_sha1), sha1_to_hex(old_sha1));
407                 unlock_ref(lock);
408                 return NULL;
409         }
410         return lock;
411 }
412
413 static struct ref_lock *lock_ref_sha1_basic(const char *path,
414         int plen,
415         const unsigned char *old_sha1, int mustexist)
416 {
417         const char *orig_path = path;
418         struct ref_lock *lock;
419         struct stat st;
420
421         lock = xcalloc(1, sizeof(struct ref_lock));
422         lock->lock_fd = -1;
423
424         plen = strlen(path) - plen;
425         path = resolve_ref(path, lock->old_sha1, mustexist);
426         if (!path) {
427                 int last_errno = errno;
428                 error("unable to resolve reference %s: %s",
429                         orig_path, strerror(errno));
430                 unlock_ref(lock);
431                 errno = last_errno;
432                 return NULL;
433         }
434         lock->lk = xcalloc(1, sizeof(struct lock_file));
435
436         lock->ref_file = xstrdup(path);
437         lock->log_file = xstrdup(git_path("logs/%s", lock->ref_file + plen));
438         lock->force_write = lstat(lock->ref_file, &st) && errno == ENOENT;
439
440         if (safe_create_leading_directories(lock->ref_file))
441                 die("unable to create directory for %s", lock->ref_file);
442         lock->lock_fd = hold_lock_file_for_update(lock->lk, lock->ref_file, 1);
443
444         return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
445 }
446
447 struct ref_lock *lock_ref_sha1(const char *ref,
448         const unsigned char *old_sha1, int mustexist)
449 {
450         if (check_ref_format(ref))
451                 return NULL;
452         return lock_ref_sha1_basic(git_path("refs/%s", ref),
453                 5 + strlen(ref), old_sha1, mustexist);
454 }
455
456 struct ref_lock *lock_any_ref_for_update(const char *ref,
457         const unsigned char *old_sha1, int mustexist)
458 {
459         return lock_ref_sha1_basic(git_path("%s", ref),
460                 strlen(ref), old_sha1, mustexist);
461 }
462
463 void unlock_ref(struct ref_lock *lock)
464 {
465         if (lock->lock_fd >= 0) {
466                 close(lock->lock_fd);
467                 /* Do not free lock->lk -- atexit() still looks at them */
468                 if (lock->lk)
469                         rollback_lock_file(lock->lk);
470         }
471         free(lock->ref_file);
472         free(lock->log_file);
473         free(lock);
474 }
475
476 static int log_ref_write(struct ref_lock *lock,
477         const unsigned char *sha1, const char *msg)
478 {
479         int logfd, written, oflags = O_APPEND | O_WRONLY;
480         unsigned maxlen, len;
481         char *logrec;
482         const char *committer;
483
484         if (log_all_ref_updates) {
485                 if (safe_create_leading_directories(lock->log_file) < 0)
486                         return error("unable to create directory for %s",
487                                 lock->log_file);
488                 oflags |= O_CREAT;
489         }
490
491         logfd = open(lock->log_file, oflags, 0666);
492         if (logfd < 0) {
493                 if (!log_all_ref_updates && errno == ENOENT)
494                         return 0;
495                 return error("Unable to append to %s: %s",
496                         lock->log_file, strerror(errno));
497         }
498
499         committer = git_committer_info(1);
500         if (msg) {
501                 maxlen = strlen(committer) + strlen(msg) + 2*40 + 5;
502                 logrec = xmalloc(maxlen);
503                 len = snprintf(logrec, maxlen, "%s %s %s\t%s\n",
504                         sha1_to_hex(lock->old_sha1),
505                         sha1_to_hex(sha1),
506                         committer,
507                         msg);
508         }
509         else {
510                 maxlen = strlen(committer) + 2*40 + 4;
511                 logrec = xmalloc(maxlen);
512                 len = snprintf(logrec, maxlen, "%s %s %s\n",
513                         sha1_to_hex(lock->old_sha1),
514                         sha1_to_hex(sha1),
515                         committer);
516         }
517         written = len <= maxlen ? write(logfd, logrec, len) : -1;
518         free(logrec);
519         close(logfd);
520         if (written != len)
521                 return error("Unable to append to %s", lock->log_file);
522         return 0;
523 }
524
525 int write_ref_sha1(struct ref_lock *lock,
526         const unsigned char *sha1, const char *logmsg)
527 {
528         static char term = '\n';
529
530         if (!lock)
531                 return -1;
532         if (!lock->force_write && !hashcmp(lock->old_sha1, sha1)) {
533                 unlock_ref(lock);
534                 return 0;
535         }
536         if (write(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 ||
537             write(lock->lock_fd, &term, 1) != 1
538                 || close(lock->lock_fd) < 0) {
539                 error("Couldn't write %s", lock->lk->filename);
540                 unlock_ref(lock);
541                 return -1;
542         }
543         if (log_ref_write(lock, sha1, logmsg) < 0) {
544                 unlock_ref(lock);
545                 return -1;
546         }
547         if (commit_lock_file(lock->lk)) {
548                 error("Couldn't set %s", lock->ref_file);
549                 unlock_ref(lock);
550                 return -1;
551         }
552         lock->lock_fd = -1;
553         unlock_ref(lock);
554         return 0;
555 }
556
557 int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
558 {
559         const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
560         char *tz_c;
561         int logfd, tz;
562         struct stat st;
563         unsigned long date;
564         unsigned char logged_sha1[20];
565
566         logfile = git_path("logs/%s", ref);
567         logfd = open(logfile, O_RDONLY, 0);
568         if (logfd < 0)
569                 die("Unable to read log %s: %s", logfile, strerror(errno));
570         fstat(logfd, &st);
571         if (!st.st_size)
572                 die("Log %s is empty.", logfile);
573         logdata = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0);
574         close(logfd);
575
576         lastrec = NULL;
577         rec = logend = logdata + st.st_size;
578         while (logdata < rec) {
579                 if (logdata < rec && *(rec-1) == '\n')
580                         rec--;
581                 lastgt = NULL;
582                 while (logdata < rec && *(rec-1) != '\n') {
583                         rec--;
584                         if (*rec == '>')
585                                 lastgt = rec;
586                 }
587                 if (!lastgt)
588                         die("Log %s is corrupt.", logfile);
589                 date = strtoul(lastgt + 1, &tz_c, 10);
590                 if (date <= at_time) {
591                         if (lastrec) {
592                                 if (get_sha1_hex(lastrec, logged_sha1))
593                                         die("Log %s is corrupt.", logfile);
594                                 if (get_sha1_hex(rec + 41, sha1))
595                                         die("Log %s is corrupt.", logfile);
596                                 if (hashcmp(logged_sha1, sha1)) {
597                                         tz = strtoul(tz_c, NULL, 10);
598                                         fprintf(stderr,
599                                                 "warning: Log %s has gap after %s.\n",
600                                                 logfile, show_rfc2822_date(date, tz));
601                                 }
602                         }
603                         else if (date == at_time) {
604                                 if (get_sha1_hex(rec + 41, sha1))
605                                         die("Log %s is corrupt.", logfile);
606                         }
607                         else {
608                                 if (get_sha1_hex(rec + 41, logged_sha1))
609                                         die("Log %s is corrupt.", logfile);
610                                 if (hashcmp(logged_sha1, sha1)) {
611                                         tz = strtoul(tz_c, NULL, 10);
612                                         fprintf(stderr,
613                                                 "warning: Log %s unexpectedly ended on %s.\n",
614                                                 logfile, show_rfc2822_date(date, tz));
615                                 }
616                         }
617                         munmap((void*)logdata, st.st_size);
618                         return 0;
619                 }
620                 lastrec = rec;
621         }
622
623         rec = logdata;
624         while (rec < logend && *rec != '>' && *rec != '\n')
625                 rec++;
626         if (rec == logend || *rec == '\n')
627                 die("Log %s is corrupt.", logfile);
628         date = strtoul(rec + 1, &tz_c, 10);
629         tz = strtoul(tz_c, NULL, 10);
630         if (get_sha1_hex(logdata, sha1))
631                 die("Log %s is corrupt.", logfile);
632         munmap((void*)logdata, st.st_size);
633         fprintf(stderr, "warning: Log %s only goes back to %s.\n",
634                 logfile, show_rfc2822_date(date, tz));
635         return 0;
636 }