refs.con commit Correct compiler warnings in fast-import. (10e8d68)
   1#include "cache.h"
   2#include "refs.h"
   3#include "object.h"
   4#include "tag.h"
   5
   6/* ISSYMREF=01 and ISPACKED=02 are public interfaces */
   7#define REF_KNOWS_PEELED 04
   8
   9struct ref_list {
  10        struct ref_list *next;
  11        unsigned char flag; /* ISSYMREF? ISPACKED? */
  12        unsigned char sha1[20];
  13        unsigned char peeled[20];
  14        char name[FLEX_ARRAY];
  15};
  16
  17static const char *parse_ref_line(char *line, unsigned char *sha1)
  18{
  19        /*
  20         * 42: the answer to everything.
  21         *
  22         * In this case, it happens to be the answer to
  23         *  40 (length of sha1 hex representation)
  24         *  +1 (space in between hex and name)
  25         *  +1 (newline at the end of the line)
  26         */
  27        int len = strlen(line) - 42;
  28
  29        if (len <= 0)
  30                return NULL;
  31        if (get_sha1_hex(line, sha1) < 0)
  32                return NULL;
  33        if (!isspace(line[40]))
  34                return NULL;
  35        line += 41;
  36        if (isspace(*line))
  37                return NULL;
  38        if (line[len] != '\n')
  39                return NULL;
  40        line[len] = 0;
  41
  42        return line;
  43}
  44
  45static struct ref_list *add_ref(const char *name, const unsigned char *sha1,
  46                                int flag, struct ref_list *list,
  47                                struct ref_list **new_entry)
  48{
  49        int len;
  50        struct ref_list **p = &list, *entry;
  51
  52        /* Find the place to insert the ref into.. */
  53        while ((entry = *p) != NULL) {
  54                int cmp = strcmp(entry->name, name);
  55                if (cmp > 0)
  56                        break;
  57
  58                /* Same as existing entry? */
  59                if (!cmp) {
  60                        if (new_entry)
  61                                *new_entry = entry;
  62                        return list;
  63                }
  64                p = &entry->next;
  65        }
  66
  67        /* Allocate it and add it in.. */
  68        len = strlen(name) + 1;
  69        entry = xmalloc(sizeof(struct ref_list) + len);
  70        hashcpy(entry->sha1, sha1);
  71        hashclr(entry->peeled);
  72        memcpy(entry->name, name, len);
  73        entry->flag = flag;
  74        entry->next = *p;
  75        *p = entry;
  76        if (new_entry)
  77                *new_entry = entry;
  78        return list;
  79}
  80
  81/*
  82 * Future: need to be in "struct repository"
  83 * when doing a full libification.
  84 */
  85struct cached_refs {
  86        char did_loose;
  87        char did_packed;
  88        struct ref_list *loose;
  89        struct ref_list *packed;
  90} cached_refs;
  91
  92static void free_ref_list(struct ref_list *list)
  93{
  94        struct ref_list *next;
  95        for ( ; list; list = next) {
  96                next = list->next;
  97                free(list);
  98        }
  99}
 100
 101static void invalidate_cached_refs(void)
 102{
 103        struct cached_refs *ca = &cached_refs;
 104
 105        if (ca->did_loose && ca->loose)
 106                free_ref_list(ca->loose);
 107        if (ca->did_packed && ca->packed)
 108                free_ref_list(ca->packed);
 109        ca->loose = ca->packed = NULL;
 110        ca->did_loose = ca->did_packed = 0;
 111}
 112
 113static void read_packed_refs(FILE *f, struct cached_refs *cached_refs)
 114{
 115        struct ref_list *list = NULL;
 116        struct ref_list *last = NULL;
 117        char refline[PATH_MAX];
 118        int flag = REF_ISPACKED;
 119
 120        while (fgets(refline, sizeof(refline), f)) {
 121                unsigned char sha1[20];
 122                const char *name;
 123                static const char header[] = "# pack-refs with:";
 124
 125                if (!strncmp(refline, header, sizeof(header)-1)) {
 126                        const char *traits = refline + sizeof(header) - 1;
 127                        if (strstr(traits, " peeled "))
 128                                flag |= REF_KNOWS_PEELED;
 129                        /* perhaps other traits later as well */
 130                        continue;
 131                }
 132
 133                name = parse_ref_line(refline, sha1);
 134                if (name) {
 135                        list = add_ref(name, sha1, flag, list, &last);
 136                        continue;
 137                }
 138                if (last &&
 139                    refline[0] == '^' &&
 140                    strlen(refline) == 42 &&
 141                    refline[41] == '\n' &&
 142                    !get_sha1_hex(refline + 1, sha1))
 143                        hashcpy(last->peeled, sha1);
 144        }
 145        cached_refs->packed = list;
 146}
 147
 148static struct ref_list *get_packed_refs(void)
 149{
 150        if (!cached_refs.did_packed) {
 151                FILE *f = fopen(git_path("packed-refs"), "r");
 152                cached_refs.packed = NULL;
 153                if (f) {
 154                        read_packed_refs(f, &cached_refs);
 155                        fclose(f);
 156                }
 157                cached_refs.did_packed = 1;
 158        }
 159        return cached_refs.packed;
 160}
 161
 162static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
 163{
 164        DIR *dir = opendir(git_path("%s", base));
 165
 166        if (dir) {
 167                struct dirent *de;
 168                int baselen = strlen(base);
 169                char *ref = xmalloc(baselen + 257);
 170
 171                memcpy(ref, base, baselen);
 172                if (baselen && base[baselen-1] != '/')
 173                        ref[baselen++] = '/';
 174
 175                while ((de = readdir(dir)) != NULL) {
 176                        unsigned char sha1[20];
 177                        struct stat st;
 178                        int flag;
 179                        int namelen;
 180
 181                        if (de->d_name[0] == '.')
 182                                continue;
 183                        namelen = strlen(de->d_name);
 184                        if (namelen > 255)
 185                                continue;
 186                        if (has_extension(de->d_name, ".lock"))
 187                                continue;
 188                        memcpy(ref + baselen, de->d_name, namelen+1);
 189                        if (stat(git_path("%s", ref), &st) < 0)
 190                                continue;
 191                        if (S_ISDIR(st.st_mode)) {
 192                                list = get_ref_dir(ref, list);
 193                                continue;
 194                        }
 195                        if (!resolve_ref(ref, sha1, 1, &flag)) {
 196                                error("%s points nowhere!", ref);
 197                                continue;
 198                        }
 199                        list = add_ref(ref, sha1, flag, list, NULL);
 200                }
 201                free(ref);
 202                closedir(dir);
 203        }
 204        return list;
 205}
 206
 207static struct ref_list *get_loose_refs(void)
 208{
 209        if (!cached_refs.did_loose) {
 210                cached_refs.loose = get_ref_dir("refs", NULL);
 211                cached_refs.did_loose = 1;
 212        }
 213        return cached_refs.loose;
 214}
 215
 216/* We allow "recursive" symbolic refs. Only within reason, though */
 217#define MAXDEPTH 5
 218
 219const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag)
 220{
 221        int depth = MAXDEPTH, len;
 222        char buffer[256];
 223        static char ref_buffer[256];
 224
 225        if (flag)
 226                *flag = 0;
 227
 228        for (;;) {
 229                const char *path = git_path("%s", ref);
 230                struct stat st;
 231                char *buf;
 232                int fd;
 233
 234                if (--depth < 0)
 235                        return NULL;
 236
 237                /* Special case: non-existing file.
 238                 * Not having the refs/heads/new-branch is OK
 239                 * if we are writing into it, so is .git/HEAD
 240                 * that points at refs/heads/master still to be
 241                 * born.  It is NOT OK if we are resolving for
 242                 * reading.
 243                 */
 244                if (lstat(path, &st) < 0) {
 245                        struct ref_list *list = get_packed_refs();
 246                        while (list) {
 247                                if (!strcmp(ref, list->name)) {
 248                                        hashcpy(sha1, list->sha1);
 249                                        if (flag)
 250                                                *flag |= REF_ISPACKED;
 251                                        return ref;
 252                                }
 253                                list = list->next;
 254                        }
 255                        if (reading || errno != ENOENT)
 256                                return NULL;
 257                        hashclr(sha1);
 258                        return ref;
 259                }
 260
 261                /* Follow "normalized" - ie "refs/.." symlinks by hand */
 262                if (S_ISLNK(st.st_mode)) {
 263                        len = readlink(path, buffer, sizeof(buffer)-1);
 264                        if (len >= 5 && !memcmp("refs/", buffer, 5)) {
 265                                buffer[len] = 0;
 266                                strcpy(ref_buffer, buffer);
 267                                ref = ref_buffer;
 268                                if (flag)
 269                                        *flag |= REF_ISSYMREF;
 270                                continue;
 271                        }
 272                }
 273
 274                /* Is it a directory? */
 275                if (S_ISDIR(st.st_mode)) {
 276                        errno = EISDIR;
 277                        return NULL;
 278                }
 279
 280                /*
 281                 * Anything else, just open it and try to use it as
 282                 * a ref
 283                 */
 284                fd = open(path, O_RDONLY);
 285                if (fd < 0)
 286                        return NULL;
 287                len = read_in_full(fd, buffer, sizeof(buffer)-1);
 288                close(fd);
 289
 290                /*
 291                 * Is it a symbolic ref?
 292                 */
 293                if (len < 4 || memcmp("ref:", buffer, 4))
 294                        break;
 295                buf = buffer + 4;
 296                len -= 4;
 297                while (len && isspace(*buf))
 298                        buf++, len--;
 299                while (len && isspace(buf[len-1]))
 300                        len--;
 301                buf[len] = 0;
 302                memcpy(ref_buffer, buf, len + 1);
 303                ref = ref_buffer;
 304                if (flag)
 305                        *flag |= REF_ISSYMREF;
 306        }
 307        if (len < 40 || get_sha1_hex(buffer, sha1))
 308                return NULL;
 309        return ref;
 310}
 311
 312int create_symref(const char *ref_target, const char *refs_heads_master)
 313{
 314        const char *lockpath;
 315        char ref[1000];
 316        int fd, len, written;
 317        const char *git_HEAD = git_path("%s", ref_target);
 318
 319#ifndef NO_SYMLINK_HEAD
 320        if (prefer_symlink_refs) {
 321                unlink(git_HEAD);
 322                if (!symlink(refs_heads_master, git_HEAD))
 323                        return 0;
 324                fprintf(stderr, "no symlink - falling back to symbolic ref\n");
 325        }
 326#endif
 327
 328        len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master);
 329        if (sizeof(ref) <= len) {
 330                error("refname too long: %s", refs_heads_master);
 331                return -1;
 332        }
 333        lockpath = mkpath("%s.lock", git_HEAD);
 334        fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666);
 335        if (fd < 0) {
 336                error("Unable to open %s for writing", lockpath);
 337                return -5;
 338        }
 339        written = write_in_full(fd, ref, len);
 340        close(fd);
 341        if (written != len) {
 342                unlink(lockpath);
 343                error("Unable to write to %s", lockpath);
 344                return -2;
 345        }
 346        if (rename(lockpath, git_HEAD) < 0) {
 347                unlink(lockpath);
 348                error("Unable to create %s", git_HEAD);
 349                return -3;
 350        }
 351        if (adjust_shared_perm(git_HEAD)) {
 352                unlink(lockpath);
 353                error("Unable to fix permissions on %s", lockpath);
 354                return -4;
 355        }
 356        return 0;
 357}
 358
 359int read_ref(const char *ref, unsigned char *sha1)
 360{
 361        if (resolve_ref(ref, sha1, 1, NULL))
 362                return 0;
 363        return -1;
 364}
 365
 366static int do_one_ref(const char *base, each_ref_fn fn, int trim,
 367                      void *cb_data, struct ref_list *entry)
 368{
 369        if (strncmp(base, entry->name, trim))
 370                return 0;
 371        if (is_null_sha1(entry->sha1))
 372                return 0;
 373        if (!has_sha1_file(entry->sha1)) {
 374                error("%s does not point to a valid object!", entry->name);
 375                return 0;
 376        }
 377        return fn(entry->name + trim, entry->sha1, entry->flag, cb_data);
 378}
 379
 380int peel_ref(const char *ref, unsigned char *sha1)
 381{
 382        int flag;
 383        unsigned char base[20];
 384        struct object *o;
 385
 386        if (!resolve_ref(ref, base, 1, &flag))
 387                return -1;
 388
 389        if ((flag & REF_ISPACKED)) {
 390                struct ref_list *list = get_packed_refs();
 391
 392                while (list) {
 393                        if (!strcmp(list->name, ref)) {
 394                                if (list->flag & REF_KNOWS_PEELED) {
 395                                        hashcpy(sha1, list->peeled);
 396                                        return 0;
 397                                }
 398                                /* older pack-refs did not leave peeled ones */
 399                                break;
 400                        }
 401                        list = list->next;
 402                }
 403        }
 404
 405        /* fallback - callers should not call this for unpacked refs */
 406        o = parse_object(base);
 407        if (o->type == OBJ_TAG) {
 408                o = deref_tag(o, ref, 0);
 409                if (o) {
 410                        hashcpy(sha1, o->sha1);
 411                        return 0;
 412                }
 413        }
 414        return -1;
 415}
 416
 417static int do_for_each_ref(const char *base, each_ref_fn fn, int trim,
 418                           void *cb_data)
 419{
 420        int retval;
 421        struct ref_list *packed = get_packed_refs();
 422        struct ref_list *loose = get_loose_refs();
 423
 424        while (packed && loose) {
 425                struct ref_list *entry;
 426                int cmp = strcmp(packed->name, loose->name);
 427                if (!cmp) {
 428                        packed = packed->next;
 429                        continue;
 430                }
 431                if (cmp > 0) {
 432                        entry = loose;
 433                        loose = loose->next;
 434                } else {
 435                        entry = packed;
 436                        packed = packed->next;
 437                }
 438                retval = do_one_ref(base, fn, trim, cb_data, entry);
 439                if (retval)
 440                        return retval;
 441        }
 442
 443        for (packed = packed ? packed : loose; packed; packed = packed->next) {
 444                retval = do_one_ref(base, fn, trim, cb_data, packed);
 445                if (retval)
 446                        return retval;
 447        }
 448        return 0;
 449}
 450
 451int head_ref(each_ref_fn fn, void *cb_data)
 452{
 453        unsigned char sha1[20];
 454        int flag;
 455
 456        if (resolve_ref("HEAD", sha1, 1, &flag))
 457                return fn("HEAD", sha1, flag, cb_data);
 458        return 0;
 459}
 460
 461int for_each_ref(each_ref_fn fn, void *cb_data)
 462{
 463        return do_for_each_ref("refs/", fn, 0, cb_data);
 464}
 465
 466int for_each_tag_ref(each_ref_fn fn, void *cb_data)
 467{
 468        return do_for_each_ref("refs/tags/", fn, 10, cb_data);
 469}
 470
 471int for_each_branch_ref(each_ref_fn fn, void *cb_data)
 472{
 473        return do_for_each_ref("refs/heads/", fn, 11, cb_data);
 474}
 475
 476int for_each_remote_ref(each_ref_fn fn, void *cb_data)
 477{
 478        return do_for_each_ref("refs/remotes/", fn, 13, cb_data);
 479}
 480
 481/* NEEDSWORK: This is only used by ssh-upload and it should go; the
 482 * caller should do resolve_ref or read_ref like everybody else.  Or
 483 * maybe everybody else should use get_ref_sha1() instead of doing
 484 * read_ref().
 485 */
 486int get_ref_sha1(const char *ref, unsigned char *sha1)
 487{
 488        if (check_ref_format(ref))
 489                return -1;
 490        return read_ref(mkpath("refs/%s", ref), sha1);
 491}
 492
 493/*
 494 * Make sure "ref" is something reasonable to have under ".git/refs/";
 495 * We do not like it if:
 496 *
 497 * - any path component of it begins with ".", or
 498 * - it has double dots "..", or
 499 * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
 500 * - it ends with a "/".
 501 */
 502
 503static inline int bad_ref_char(int ch)
 504{
 505        return (((unsigned) ch) <= ' ' ||
 506                ch == '~' || ch == '^' || ch == ':' ||
 507                /* 2.13 Pattern Matching Notation */
 508                ch == '?' || ch == '*' || ch == '[');
 509}
 510
 511int check_ref_format(const char *ref)
 512{
 513        int ch, level;
 514        const char *cp = ref;
 515
 516        level = 0;
 517        while (1) {
 518                while ((ch = *cp++) == '/')
 519                        ; /* tolerate duplicated slashes */
 520                if (!ch)
 521                        return -1; /* should not end with slashes */
 522
 523                /* we are at the beginning of the path component */
 524                if (ch == '.' || bad_ref_char(ch))
 525                        return -1;
 526
 527                /* scan the rest of the path component */
 528                while ((ch = *cp++) != 0) {
 529                        if (bad_ref_char(ch))
 530                                return -1;
 531                        if (ch == '/')
 532                                break;
 533                        if (ch == '.' && *cp == '.')
 534                                return -1;
 535                }
 536                level++;
 537                if (!ch) {
 538                        if (level < 2)
 539                                return -2; /* at least of form "heads/blah" */
 540                        return 0;
 541                }
 542        }
 543}
 544
 545static struct ref_lock *verify_lock(struct ref_lock *lock,
 546        const unsigned char *old_sha1, int mustexist)
 547{
 548        if (!resolve_ref(lock->ref_name, lock->old_sha1, mustexist, NULL)) {
 549                error("Can't verify ref %s", lock->ref_name);
 550                unlock_ref(lock);
 551                return NULL;
 552        }
 553        if (hashcmp(lock->old_sha1, old_sha1)) {
 554                error("Ref %s is at %s but expected %s", lock->ref_name,
 555                        sha1_to_hex(lock->old_sha1), sha1_to_hex(old_sha1));
 556                unlock_ref(lock);
 557                return NULL;
 558        }
 559        return lock;
 560}
 561
 562static int remove_empty_dir_recursive(char *path, int len)
 563{
 564        DIR *dir = opendir(path);
 565        struct dirent *e;
 566        int ret = 0;
 567
 568        if (!dir)
 569                return -1;
 570        if (path[len-1] != '/')
 571                path[len++] = '/';
 572        while ((e = readdir(dir)) != NULL) {
 573                struct stat st;
 574                int namlen;
 575                if ((e->d_name[0] == '.') &&
 576                    ((e->d_name[1] == 0) ||
 577                     ((e->d_name[1] == '.') && e->d_name[2] == 0)))
 578                        continue; /* "." and ".." */
 579
 580                namlen = strlen(e->d_name);
 581                if ((len + namlen < PATH_MAX) &&
 582                    strcpy(path + len, e->d_name) &&
 583                    !lstat(path, &st) &&
 584                    S_ISDIR(st.st_mode) &&
 585                    !remove_empty_dir_recursive(path, len + namlen))
 586                        continue; /* happy */
 587
 588                /* path too long, stat fails, or non-directory still exists */
 589                ret = -1;
 590                break;
 591        }
 592        closedir(dir);
 593        if (!ret) {
 594                path[len] = 0;
 595                ret = rmdir(path);
 596        }
 597        return ret;
 598}
 599
 600static int remove_empty_directories(char *file)
 601{
 602        /* we want to create a file but there is a directory there;
 603         * if that is an empty directory (or a directory that contains
 604         * only empty directories), remove them.
 605         */
 606        char path[PATH_MAX];
 607        int len = strlen(file);
 608
 609        if (len >= PATH_MAX) /* path too long ;-) */
 610                return -1;
 611        strcpy(path, file);
 612        return remove_empty_dir_recursive(path, len);
 613}
 614
 615static int is_refname_available(const char *ref, const char *oldref,
 616                                struct ref_list *list, int quiet)
 617{
 618        int namlen = strlen(ref); /* e.g. 'foo/bar' */
 619        while (list) {
 620                /* list->name could be 'foo' or 'foo/bar/baz' */
 621                if (!oldref || strcmp(oldref, list->name)) {
 622                        int len = strlen(list->name);
 623                        int cmplen = (namlen < len) ? namlen : len;
 624                        const char *lead = (namlen < len) ? list->name : ref;
 625                        if (!strncmp(ref, list->name, cmplen) &&
 626                            lead[cmplen] == '/') {
 627                                if (!quiet)
 628                                        error("'%s' exists; cannot create '%s'",
 629                                              list->name, ref);
 630                                return 0;
 631                        }
 632                }
 633                list = list->next;
 634        }
 635        return 1;
 636}
 637
 638static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char *old_sha1, int *flag)
 639{
 640        char *ref_file;
 641        const char *orig_ref = ref;
 642        struct ref_lock *lock;
 643        struct stat st;
 644        int last_errno = 0;
 645        int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
 646
 647        lock = xcalloc(1, sizeof(struct ref_lock));
 648        lock->lock_fd = -1;
 649
 650        ref = resolve_ref(ref, lock->old_sha1, mustexist, flag);
 651        if (!ref && errno == EISDIR) {
 652                /* we are trying to lock foo but we used to
 653                 * have foo/bar which now does not exist;
 654                 * it is normal for the empty directory 'foo'
 655                 * to remain.
 656                 */
 657                ref_file = git_path("%s", orig_ref);
 658                if (remove_empty_directories(ref_file)) {
 659                        last_errno = errno;
 660                        error("there are still refs under '%s'", orig_ref);
 661                        goto error_return;
 662                }
 663                ref = resolve_ref(orig_ref, lock->old_sha1, mustexist, flag);
 664        }
 665        if (!ref) {
 666                last_errno = errno;
 667                error("unable to resolve reference %s: %s",
 668                        orig_ref, strerror(errno));
 669                goto error_return;
 670        }
 671        /* When the ref did not exist and we are creating it,
 672         * make sure there is no existing ref that is packed
 673         * whose name begins with our refname, nor a ref whose
 674         * name is a proper prefix of our refname.
 675         */
 676        if (is_null_sha1(lock->old_sha1) &&
 677            !is_refname_available(ref, NULL, get_packed_refs(), 0))
 678                goto error_return;
 679
 680        lock->lk = xcalloc(1, sizeof(struct lock_file));
 681
 682        lock->ref_name = xstrdup(ref);
 683        lock->log_file = xstrdup(git_path("logs/%s", ref));
 684        ref_file = git_path("%s", ref);
 685        lock->force_write = lstat(ref_file, &st) && errno == ENOENT;
 686
 687        if (safe_create_leading_directories(ref_file)) {
 688                last_errno = errno;
 689                error("unable to create directory for %s", ref_file);
 690                goto error_return;
 691        }
 692        lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, 1);
 693
 694        return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
 695
 696 error_return:
 697        unlock_ref(lock);
 698        errno = last_errno;
 699        return NULL;
 700}
 701
 702struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1)
 703{
 704        char refpath[PATH_MAX];
 705        if (check_ref_format(ref))
 706                return NULL;
 707        strcpy(refpath, mkpath("refs/%s", ref));
 708        return lock_ref_sha1_basic(refpath, old_sha1, NULL);
 709}
 710
 711struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1)
 712{
 713        if (check_ref_format(ref) == -1)
 714                return NULL;
 715        return lock_ref_sha1_basic(ref, old_sha1, NULL);
 716}
 717
 718static struct lock_file packlock;
 719
 720static int repack_without_ref(const char *refname)
 721{
 722        struct ref_list *list, *packed_ref_list;
 723        int fd;
 724        int found = 0;
 725
 726        packed_ref_list = get_packed_refs();
 727        for (list = packed_ref_list; list; list = list->next) {
 728                if (!strcmp(refname, list->name)) {
 729                        found = 1;
 730                        break;
 731                }
 732        }
 733        if (!found)
 734                return 0;
 735        fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0);
 736        if (fd < 0)
 737                return error("cannot delete '%s' from packed refs", refname);
 738
 739        for (list = packed_ref_list; list; list = list->next) {
 740                char line[PATH_MAX + 100];
 741                int len;
 742
 743                if (!strcmp(refname, list->name))
 744                        continue;
 745                len = snprintf(line, sizeof(line), "%s %s\n",
 746                               sha1_to_hex(list->sha1), list->name);
 747                /* this should not happen but just being defensive */
 748                if (len > sizeof(line))
 749                        die("too long a refname '%s'", list->name);
 750                write_or_die(fd, line, len);
 751        }
 752        return commit_lock_file(&packlock);
 753}
 754
 755int delete_ref(const char *refname, unsigned char *sha1)
 756{
 757        struct ref_lock *lock;
 758        int err, i, ret = 0, flag = 0;
 759
 760        lock = lock_ref_sha1_basic(refname, sha1, &flag);
 761        if (!lock)
 762                return 1;
 763        if (!(flag & REF_ISPACKED)) {
 764                /* loose */
 765                i = strlen(lock->lk->filename) - 5; /* .lock */
 766                lock->lk->filename[i] = 0;
 767                err = unlink(lock->lk->filename);
 768                if (err) {
 769                        ret = 1;
 770                        error("unlink(%s) failed: %s",
 771                              lock->lk->filename, strerror(errno));
 772                }
 773                lock->lk->filename[i] = '.';
 774        }
 775        /* removing the loose one could have resurrected an earlier
 776         * packed one.  Also, if it was not loose we need to repack
 777         * without it.
 778         */
 779        ret |= repack_without_ref(refname);
 780
 781        err = unlink(lock->log_file);
 782        if (err && errno != ENOENT)
 783                fprintf(stderr, "warning: unlink(%s) failed: %s",
 784                        lock->log_file, strerror(errno));
 785        invalidate_cached_refs();
 786        unlock_ref(lock);
 787        return ret;
 788}
 789
 790int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 791{
 792        static const char renamed_ref[] = "RENAMED-REF";
 793        unsigned char sha1[20], orig_sha1[20];
 794        int flag = 0, logmoved = 0;
 795        struct ref_lock *lock;
 796        struct stat loginfo;
 797        int log = !lstat(git_path("logs/%s", oldref), &loginfo);
 798
 799        if (S_ISLNK(loginfo.st_mode))
 800                return error("reflog for %s is a symlink", oldref);
 801
 802        if (!resolve_ref(oldref, orig_sha1, 1, &flag))
 803                return error("refname %s not found", oldref);
 804
 805        if (!is_refname_available(newref, oldref, get_packed_refs(), 0))
 806                return 1;
 807
 808        if (!is_refname_available(newref, oldref, get_loose_refs(), 0))
 809                return 1;
 810
 811        lock = lock_ref_sha1_basic(renamed_ref, NULL, NULL);
 812        if (!lock)
 813                return error("unable to lock %s", renamed_ref);
 814        lock->force_write = 1;
 815        if (write_ref_sha1(lock, orig_sha1, logmsg))
 816                return error("unable to save current sha1 in %s", renamed_ref);
 817
 818        if (log && rename(git_path("logs/%s", oldref), git_path("tmp-renamed-log")))
 819                return error("unable to move logfile logs/%s to tmp-renamed-log: %s",
 820                        oldref, strerror(errno));
 821
 822        if (delete_ref(oldref, orig_sha1)) {
 823                error("unable to delete old %s", oldref);
 824                goto rollback;
 825        }
 826
 827        if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1)) {
 828                if (errno==EISDIR) {
 829                        if (remove_empty_directories(git_path("%s", newref))) {
 830                                error("Directory not empty: %s", newref);
 831                                goto rollback;
 832                        }
 833                } else {
 834                        error("unable to delete existing %s", newref);
 835                        goto rollback;
 836                }
 837        }
 838
 839        if (log && safe_create_leading_directories(git_path("logs/%s", newref))) {
 840                error("unable to create directory for %s", newref);
 841                goto rollback;
 842        }
 843
 844 retry:
 845        if (log && rename(git_path("tmp-renamed-log"), git_path("logs/%s", newref))) {
 846                if (errno==EISDIR || errno==ENOTDIR) {
 847                        /*
 848                         * rename(a, b) when b is an existing
 849                         * directory ought to result in ISDIR, but
 850                         * Solaris 5.8 gives ENOTDIR.  Sheesh.
 851                         */
 852                        if (remove_empty_directories(git_path("logs/%s", newref))) {
 853                                error("Directory not empty: logs/%s", newref);
 854                                goto rollback;
 855                        }
 856                        goto retry;
 857                } else {
 858                        error("unable to move logfile tmp-renamed-log to logs/%s: %s",
 859                                newref, strerror(errno));
 860                        goto rollback;
 861                }
 862        }
 863        logmoved = log;
 864
 865        lock = lock_ref_sha1_basic(newref, NULL, NULL);
 866        if (!lock) {
 867                error("unable to lock %s for update", newref);
 868                goto rollback;
 869        }
 870
 871        lock->force_write = 1;
 872        hashcpy(lock->old_sha1, orig_sha1);
 873        if (write_ref_sha1(lock, orig_sha1, logmsg)) {
 874                error("unable to write current sha1 into %s", newref);
 875                goto rollback;
 876        }
 877
 878        if (!strncmp(oldref, "refs/heads/", 11) &&
 879                        !strncmp(newref, "refs/heads/", 11)) {
 880                char oldsection[1024], newsection[1024];
 881
 882                snprintf(oldsection, 1024, "branch.%s", oldref + 11);
 883                snprintf(newsection, 1024, "branch.%s", newref + 11);
 884                if (git_config_rename_section(oldsection, newsection) < 0)
 885                        return 1;
 886        }
 887
 888        return 0;
 889
 890 rollback:
 891        lock = lock_ref_sha1_basic(oldref, NULL, NULL);
 892        if (!lock) {
 893                error("unable to lock %s for rollback", oldref);
 894                goto rollbacklog;
 895        }
 896
 897        lock->force_write = 1;
 898        flag = log_all_ref_updates;
 899        log_all_ref_updates = 0;
 900        if (write_ref_sha1(lock, orig_sha1, NULL))
 901                error("unable to write current sha1 into %s", oldref);
 902        log_all_ref_updates = flag;
 903
 904 rollbacklog:
 905        if (logmoved && rename(git_path("logs/%s", newref), git_path("logs/%s", oldref)))
 906                error("unable to restore logfile %s from %s: %s",
 907                        oldref, newref, strerror(errno));
 908        if (!logmoved && log &&
 909            rename(git_path("tmp-renamed-log"), git_path("logs/%s", oldref)))
 910                error("unable to restore logfile %s from tmp-renamed-log: %s",
 911                        oldref, strerror(errno));
 912
 913        return 1;
 914}
 915
 916void unlock_ref(struct ref_lock *lock)
 917{
 918        if (lock->lock_fd >= 0) {
 919                close(lock->lock_fd);
 920                /* Do not free lock->lk -- atexit() still looks at them */
 921                if (lock->lk)
 922                        rollback_lock_file(lock->lk);
 923        }
 924        free(lock->ref_name);
 925        free(lock->log_file);
 926        free(lock);
 927}
 928
 929static int log_ref_write(struct ref_lock *lock,
 930        const unsigned char *sha1, const char *msg)
 931{
 932        int logfd, written, oflags = O_APPEND | O_WRONLY;
 933        unsigned maxlen, len;
 934        int msglen;
 935        char *logrec;
 936        const char *committer;
 937
 938        if (log_all_ref_updates < 0)
 939                log_all_ref_updates = !is_bare_repository();
 940
 941        if (log_all_ref_updates &&
 942            (!strncmp(lock->ref_name, "refs/heads/", 11) ||
 943             !strncmp(lock->ref_name, "refs/remotes/", 13))) {
 944                if (safe_create_leading_directories(lock->log_file) < 0)
 945                        return error("unable to create directory for %s",
 946                                lock->log_file);
 947                oflags |= O_CREAT;
 948        }
 949
 950        logfd = open(lock->log_file, oflags, 0666);
 951        if (logfd < 0) {
 952                if (!(oflags & O_CREAT) && errno == ENOENT)
 953                        return 0;
 954
 955                if ((oflags & O_CREAT) && errno == EISDIR) {
 956                        if (remove_empty_directories(lock->log_file)) {
 957                                return error("There are still logs under '%s'",
 958                                             lock->log_file);
 959                        }
 960                        logfd = open(lock->log_file, oflags, 0666);
 961                }
 962
 963                if (logfd < 0)
 964                        return error("Unable to append to %s: %s",
 965                                     lock->log_file, strerror(errno));
 966        }
 967
 968        msglen = 0;
 969        if (msg) {
 970                /* clean up the message and make sure it is a single line */
 971                for ( ; *msg; msg++)
 972                        if (!isspace(*msg))
 973                                break;
 974                if (*msg) {
 975                        const char *ep = strchr(msg, '\n');
 976                        if (ep)
 977                                msglen = ep - msg;
 978                        else
 979                                msglen = strlen(msg);
 980                }
 981        }
 982
 983        committer = git_committer_info(-1);
 984        maxlen = strlen(committer) + msglen + 100;
 985        logrec = xmalloc(maxlen);
 986        len = sprintf(logrec, "%s %s %s\n",
 987                      sha1_to_hex(lock->old_sha1),
 988                      sha1_to_hex(sha1),
 989                      committer);
 990        if (msglen)
 991                len += sprintf(logrec + len - 1, "\t%.*s\n", msglen, msg) - 1;
 992        written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
 993        free(logrec);
 994        close(logfd);
 995        if (written != len)
 996                return error("Unable to append to %s", lock->log_file);
 997        return 0;
 998}
 999
1000int write_ref_sha1(struct ref_lock *lock,
1001        const unsigned char *sha1, const char *logmsg)
1002{
1003        static char term = '\n';
1004
1005        if (!lock)
1006                return -1;
1007        if (!lock->force_write && !hashcmp(lock->old_sha1, sha1)) {
1008                unlock_ref(lock);
1009                return 0;
1010        }
1011        if (write_in_full(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 ||
1012            write_in_full(lock->lock_fd, &term, 1) != 1
1013                || close(lock->lock_fd) < 0) {
1014                error("Couldn't write %s", lock->lk->filename);
1015                unlock_ref(lock);
1016                return -1;
1017        }
1018        invalidate_cached_refs();
1019        if (log_ref_write(lock, sha1, logmsg) < 0) {
1020                unlock_ref(lock);
1021                return -1;
1022        }
1023        if (commit_lock_file(lock->lk)) {
1024                error("Couldn't set %s", lock->ref_name);
1025                unlock_ref(lock);
1026                return -1;
1027        }
1028        lock->lock_fd = -1;
1029        unlock_ref(lock);
1030        return 0;
1031}
1032
1033static char *ref_msg(const char *line, const char *endp)
1034{
1035        const char *ep;
1036        char *msg;
1037
1038        line += 82;
1039        for (ep = line; ep < endp && *ep != '\n'; ep++)
1040                ;
1041        msg = xmalloc(ep - line + 1);
1042        memcpy(msg, line, ep - line);
1043        msg[ep - line] = 0;
1044        return msg;
1045}
1046
1047int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
1048{
1049        const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
1050        char *tz_c;
1051        int logfd, tz, reccnt = 0;
1052        struct stat st;
1053        unsigned long date;
1054        unsigned char logged_sha1[20];
1055        void *log_mapped;
1056
1057        logfile = git_path("logs/%s", ref);
1058        logfd = open(logfile, O_RDONLY, 0);
1059        if (logfd < 0)
1060                die("Unable to read log %s: %s", logfile, strerror(errno));
1061        fstat(logfd, &st);
1062        if (!st.st_size)
1063                die("Log %s is empty.", logfile);
1064        log_mapped = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0);
1065        logdata = log_mapped;
1066        close(logfd);
1067
1068        lastrec = NULL;
1069        rec = logend = logdata + st.st_size;
1070        while (logdata < rec) {
1071                reccnt++;
1072                if (logdata < rec && *(rec-1) == '\n')
1073                        rec--;
1074                lastgt = NULL;
1075                while (logdata < rec && *(rec-1) != '\n') {
1076                        rec--;
1077                        if (*rec == '>')
1078                                lastgt = rec;
1079                }
1080                if (!lastgt)
1081                        die("Log %s is corrupt.", logfile);
1082                date = strtoul(lastgt + 1, &tz_c, 10);
1083                if (date <= at_time || cnt == 0) {
1084                        tz = strtoul(tz_c, NULL, 10);
1085                        if (msg)
1086                                *msg = ref_msg(rec, logend);
1087                        if (cutoff_time)
1088                                *cutoff_time = date;
1089                        if (cutoff_tz)
1090                                *cutoff_tz = tz;
1091                        if (cutoff_cnt)
1092                                *cutoff_cnt = reccnt - 1;
1093                        if (lastrec) {
1094                                if (get_sha1_hex(lastrec, logged_sha1))
1095                                        die("Log %s is corrupt.", logfile);
1096                                if (get_sha1_hex(rec + 41, sha1))
1097                                        die("Log %s is corrupt.", logfile);
1098                                if (hashcmp(logged_sha1, sha1)) {
1099                                        fprintf(stderr,
1100                                                "warning: Log %s has gap after %s.\n",
1101                                                logfile, show_rfc2822_date(date, tz));
1102                                }
1103                        }
1104                        else if (date == at_time) {
1105                                if (get_sha1_hex(rec + 41, sha1))
1106                                        die("Log %s is corrupt.", logfile);
1107                        }
1108                        else {
1109                                if (get_sha1_hex(rec + 41, logged_sha1))
1110                                        die("Log %s is corrupt.", logfile);
1111                                if (hashcmp(logged_sha1, sha1)) {
1112                                        fprintf(stderr,
1113                                                "warning: Log %s unexpectedly ended on %s.\n",
1114                                                logfile, show_rfc2822_date(date, tz));
1115                                }
1116                        }
1117                        munmap(log_mapped, st.st_size);
1118                        return 0;
1119                }
1120                lastrec = rec;
1121                if (cnt > 0)
1122                        cnt--;
1123        }
1124
1125        rec = logdata;
1126        while (rec < logend && *rec != '>' && *rec != '\n')
1127                rec++;
1128        if (rec == logend || *rec == '\n')
1129                die("Log %s is corrupt.", logfile);
1130        date = strtoul(rec + 1, &tz_c, 10);
1131        tz = strtoul(tz_c, NULL, 10);
1132        if (get_sha1_hex(logdata, sha1))
1133                die("Log %s is corrupt.", logfile);
1134        if (msg)
1135                *msg = ref_msg(logdata, logend);
1136        munmap(log_mapped, st.st_size);
1137
1138        if (cutoff_time)
1139                *cutoff_time = date;
1140        if (cutoff_tz)
1141                *cutoff_tz = tz;
1142        if (cutoff_cnt)
1143                *cutoff_cnt = reccnt;
1144        return 1;
1145}
1146
1147int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
1148{
1149        const char *logfile;
1150        FILE *logfp;
1151        char buf[1024];
1152        int ret = 0;
1153
1154        logfile = git_path("logs/%s", ref);
1155        logfp = fopen(logfile, "r");
1156        if (!logfp)
1157                return -1;
1158        while (fgets(buf, sizeof(buf), logfp)) {
1159                unsigned char osha1[20], nsha1[20];
1160                char *email_end, *message;
1161                unsigned long timestamp;
1162                int len, tz;
1163
1164                /* old SP new SP name <email> SP time TAB msg LF */
1165                len = strlen(buf);
1166                if (len < 83 || buf[len-1] != '\n' ||
1167                    get_sha1_hex(buf, osha1) || buf[40] != ' ' ||
1168                    get_sha1_hex(buf + 41, nsha1) || buf[81] != ' ' ||
1169                    !(email_end = strchr(buf + 82, '>')) ||
1170                    email_end[1] != ' ' ||
1171                    !(timestamp = strtoul(email_end + 2, &message, 10)) ||
1172                    !message || message[0] != ' ' ||
1173                    (message[1] != '+' && message[1] != '-') ||
1174                    !isdigit(message[2]) || !isdigit(message[3]) ||
1175                    !isdigit(message[4]) || !isdigit(message[5]) ||
1176                    message[6] != '\t')
1177                        continue; /* corrupt? */
1178                email_end[1] = '\0';
1179                tz = strtol(message + 1, NULL, 10);
1180                message += 7;
1181                ret = fn(osha1, nsha1, buf+82, timestamp, tz, message, cb_data);
1182                if (ret)
1183                        break;
1184        }
1185        fclose(logfp);
1186        return ret;
1187}
1188