Add support for negative refs
[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                 if (is_null_sha1(entry->sha1))
284                         continue;
285                 if (!has_sha1_file(entry->sha1)) {
286                         error("%s does not point to a valid object!", entry->name);
287                         continue;
288                 }
289                 retval = fn(entry->name + trim, entry->sha1);
290                 if (retval)
291                         return retval;
292         }
293
294         packed = packed ? packed : loose;
295         while (packed) {
296                 if (!strncmp(base, packed->name, trim)) {
297                         retval = fn(packed->name + trim, packed->sha1);
298                         if (retval)
299                                 return retval;
300                 }
301                 packed = packed->next;
302         }
303         return 0;
304 }
305
306 int head_ref(int (*fn)(const char *path, const unsigned char *sha1))
307 {
308         unsigned char sha1[20];
309         if (!read_ref(git_path("HEAD"), sha1))
310                 return fn("HEAD", sha1);
311         return 0;
312 }
313
314 int for_each_ref(int (*fn)(const char *path, const unsigned char *sha1))
315 {
316         return do_for_each_ref("refs/", fn, 0);
317 }
318
319 int for_each_tag_ref(int (*fn)(const char *path, const unsigned char *sha1))
320 {
321         return do_for_each_ref("refs/tags/", fn, 10);
322 }
323
324 int for_each_branch_ref(int (*fn)(const char *path, const unsigned char *sha1))
325 {
326         return do_for_each_ref("refs/heads/", fn, 11);
327 }
328
329 int for_each_remote_ref(int (*fn)(const char *path, const unsigned char *sha1))
330 {
331         return do_for_each_ref("refs/remotes/", fn, 13);
332 }
333
334 int get_ref_sha1(const char *ref, unsigned char *sha1)
335 {
336         if (check_ref_format(ref))
337                 return -1;
338         return read_ref(git_path("refs/%s", ref), sha1);
339 }
340
341 /*
342  * Make sure "ref" is something reasonable to have under ".git/refs/";
343  * We do not like it if:
344  *
345  * - any path component of it begins with ".", or
346  * - it has double dots "..", or
347  * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
348  * - it ends with a "/".
349  */
350
351 static inline int bad_ref_char(int ch)
352 {
353         return (((unsigned) ch) <= ' ' ||
354                 ch == '~' || ch == '^' || ch == ':' ||
355                 /* 2.13 Pattern Matching Notation */
356                 ch == '?' || ch == '*' || ch == '[');
357 }
358
359 int check_ref_format(const char *ref)
360 {
361         int ch, level;
362         const char *cp = ref;
363
364         level = 0;
365         while (1) {
366                 while ((ch = *cp++) == '/')
367                         ; /* tolerate duplicated slashes */
368                 if (!ch)
369                         return -1; /* should not end with slashes */
370
371                 /* we are at the beginning of the path component */
372                 if (ch == '.' || bad_ref_char(ch))
373                         return -1;
374
375                 /* scan the rest of the path component */
376                 while ((ch = *cp++) != 0) {
377                         if (bad_ref_char(ch))
378                                 return -1;
379                         if (ch == '/')
380                                 break;
381                         if (ch == '.' && *cp == '.')
382                                 return -1;
383                 }
384                 level++;
385                 if (!ch) {
386                         if (level < 2)
387                                 return -1; /* at least of form "heads/blah" */
388                         return 0;
389                 }
390         }
391 }
392
393 static struct ref_lock *verify_lock(struct ref_lock *lock,
394         const unsigned char *old_sha1, int mustexist)
395 {
396         char buf[40];
397         int nr, fd = open(lock->ref_file, O_RDONLY);
398         if (fd < 0 && (mustexist || errno != ENOENT)) {
399                 error("Can't verify ref %s", lock->ref_file);
400                 unlock_ref(lock);
401                 return NULL;
402         }
403         nr = read(fd, buf, 40);
404         close(fd);
405         if (nr != 40 || get_sha1_hex(buf, lock->old_sha1) < 0) {
406                 error("Can't verify ref %s", lock->ref_file);
407                 unlock_ref(lock);
408                 return NULL;
409         }
410         if (hashcmp(lock->old_sha1, old_sha1)) {
411                 error("Ref %s is at %s but expected %s", lock->ref_file,
412                         sha1_to_hex(lock->old_sha1), sha1_to_hex(old_sha1));
413                 unlock_ref(lock);
414                 return NULL;
415         }
416         return lock;
417 }
418
419 static struct ref_lock *lock_ref_sha1_basic(const char *path,
420         int plen,
421         const unsigned char *old_sha1, int mustexist)
422 {
423         const char *orig_path = path;
424         struct ref_lock *lock;
425         struct stat st;
426
427         lock = xcalloc(1, sizeof(struct ref_lock));
428         lock->lock_fd = -1;
429
430         plen = strlen(path) - plen;
431         path = resolve_ref(path, lock->old_sha1, mustexist);
432         if (!path) {
433                 int last_errno = errno;
434                 error("unable to resolve reference %s: %s",
435                         orig_path, strerror(errno));
436                 unlock_ref(lock);
437                 errno = last_errno;
438                 return NULL;
439         }
440         lock->lk = xcalloc(1, sizeof(struct lock_file));
441
442         lock->ref_file = xstrdup(path);
443         lock->log_file = xstrdup(git_path("logs/%s", lock->ref_file + plen));
444         lock->force_write = lstat(lock->ref_file, &st) && errno == ENOENT;
445
446         if (safe_create_leading_directories(lock->ref_file))
447                 die("unable to create directory for %s", lock->ref_file);
448         lock->lock_fd = hold_lock_file_for_update(lock->lk, lock->ref_file, 1);
449
450         return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
451 }
452
453 struct ref_lock *lock_ref_sha1(const char *ref,
454         const unsigned char *old_sha1, int mustexist)
455 {
456         if (check_ref_format(ref))
457                 return NULL;
458         return lock_ref_sha1_basic(git_path("refs/%s", ref),
459                 5 + strlen(ref), old_sha1, mustexist);
460 }
461
462 struct ref_lock *lock_any_ref_for_update(const char *ref,
463         const unsigned char *old_sha1, int mustexist)
464 {
465         return lock_ref_sha1_basic(git_path("%s", ref),
466                 strlen(ref), old_sha1, mustexist);
467 }
468
469 void unlock_ref(struct ref_lock *lock)
470 {
471         if (lock->lock_fd >= 0) {
472                 close(lock->lock_fd);
473                 /* Do not free lock->lk -- atexit() still looks at them */
474                 if (lock->lk)
475                         rollback_lock_file(lock->lk);
476         }
477         free(lock->ref_file);
478         free(lock->log_file);
479         free(lock);
480 }
481
482 static int log_ref_write(struct ref_lock *lock,
483         const unsigned char *sha1, const char *msg)
484 {
485         int logfd, written, oflags = O_APPEND | O_WRONLY;
486         unsigned maxlen, len;
487         char *logrec;
488         const char *committer;
489
490         if (log_all_ref_updates) {
491                 if (safe_create_leading_directories(lock->log_file) < 0)
492                         return error("unable to create directory for %s",
493                                 lock->log_file);
494                 oflags |= O_CREAT;
495         }
496
497         logfd = open(lock->log_file, oflags, 0666);
498         if (logfd < 0) {
499                 if (!log_all_ref_updates && errno == ENOENT)
500                         return 0;
501                 return error("Unable to append to %s: %s",
502                         lock->log_file, strerror(errno));
503         }
504
505         committer = git_committer_info(1);
506         if (msg) {
507                 maxlen = strlen(committer) + strlen(msg) + 2*40 + 5;
508                 logrec = xmalloc(maxlen);
509                 len = snprintf(logrec, maxlen, "%s %s %s\t%s\n",
510                         sha1_to_hex(lock->old_sha1),
511                         sha1_to_hex(sha1),
512                         committer,
513                         msg);
514         }
515         else {
516                 maxlen = strlen(committer) + 2*40 + 4;
517                 logrec = xmalloc(maxlen);
518                 len = snprintf(logrec, maxlen, "%s %s %s\n",
519                         sha1_to_hex(lock->old_sha1),
520                         sha1_to_hex(sha1),
521                         committer);
522         }
523         written = len <= maxlen ? write(logfd, logrec, len) : -1;
524         free(logrec);
525         close(logfd);
526         if (written != len)
527                 return error("Unable to append to %s", lock->log_file);
528         return 0;
529 }
530
531 int write_ref_sha1(struct ref_lock *lock,
532         const unsigned char *sha1, const char *logmsg)
533 {
534         static char term = '\n';
535
536         if (!lock)
537                 return -1;
538         if (!lock->force_write && !hashcmp(lock->old_sha1, sha1)) {
539                 unlock_ref(lock);
540                 return 0;
541         }
542         if (write(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 ||
543             write(lock->lock_fd, &term, 1) != 1
544                 || close(lock->lock_fd) < 0) {
545                 error("Couldn't write %s", lock->lk->filename);
546                 unlock_ref(lock);
547                 return -1;
548         }
549         if (log_ref_write(lock, sha1, logmsg) < 0) {
550                 unlock_ref(lock);
551                 return -1;
552         }
553         if (commit_lock_file(lock->lk)) {
554                 error("Couldn't set %s", lock->ref_file);
555                 unlock_ref(lock);
556                 return -1;
557         }
558         lock->lock_fd = -1;
559         unlock_ref(lock);
560         return 0;
561 }
562
563 int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
564 {
565         const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
566         char *tz_c;
567         int logfd, tz;
568         struct stat st;
569         unsigned long date;
570         unsigned char logged_sha1[20];
571
572         logfile = git_path("logs/%s", ref);
573         logfd = open(logfile, O_RDONLY, 0);
574         if (logfd < 0)
575                 die("Unable to read log %s: %s", logfile, strerror(errno));
576         fstat(logfd, &st);
577         if (!st.st_size)
578                 die("Log %s is empty.", logfile);
579         logdata = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0);
580         close(logfd);
581
582         lastrec = NULL;
583         rec = logend = logdata + st.st_size;
584         while (logdata < rec) {
585                 if (logdata < rec && *(rec-1) == '\n')
586                         rec--;
587                 lastgt = NULL;
588                 while (logdata < rec && *(rec-1) != '\n') {
589                         rec--;
590                         if (*rec == '>')
591                                 lastgt = rec;
592                 }
593                 if (!lastgt)
594                         die("Log %s is corrupt.", logfile);
595                 date = strtoul(lastgt + 1, &tz_c, 10);
596                 if (date <= at_time) {
597                         if (lastrec) {
598                                 if (get_sha1_hex(lastrec, logged_sha1))
599                                         die("Log %s is corrupt.", logfile);
600                                 if (get_sha1_hex(rec + 41, sha1))
601                                         die("Log %s is corrupt.", logfile);
602                                 if (hashcmp(logged_sha1, sha1)) {
603                                         tz = strtoul(tz_c, NULL, 10);
604                                         fprintf(stderr,
605                                                 "warning: Log %s has gap after %s.\n",
606                                                 logfile, show_rfc2822_date(date, tz));
607                                 }
608                         }
609                         else if (date == at_time) {
610                                 if (get_sha1_hex(rec + 41, sha1))
611                                         die("Log %s is corrupt.", logfile);
612                         }
613                         else {
614                                 if (get_sha1_hex(rec + 41, logged_sha1))
615                                         die("Log %s is corrupt.", logfile);
616                                 if (hashcmp(logged_sha1, sha1)) {
617                                         tz = strtoul(tz_c, NULL, 10);
618                                         fprintf(stderr,
619                                                 "warning: Log %s unexpectedly ended on %s.\n",
620                                                 logfile, show_rfc2822_date(date, tz));
621                                 }
622                         }
623                         munmap((void*)logdata, st.st_size);
624                         return 0;
625                 }
626                 lastrec = rec;
627         }
628
629         rec = logdata;
630         while (rec < logend && *rec != '>' && *rec != '\n')
631                 rec++;
632         if (rec == logend || *rec == '\n')
633                 die("Log %s is corrupt.", logfile);
634         date = strtoul(rec + 1, &tz_c, 10);
635         tz = strtoul(tz_c, NULL, 10);
636         if (get_sha1_hex(logdata, sha1))
637                 die("Log %s is corrupt.", logfile);
638         munmap((void*)logdata, st.st_size);
639         fprintf(stderr, "warning: Log %s only goes back to %s.\n",
640                 logfile, show_rfc2822_date(date, tz));
641         return 0;
642 }