]> asedeno.scripts.mit.edu Git - git.git/blob - builtin-pack-refs.c
Tell between packed, unpacked and symbolic refs.
[git.git] / builtin-pack-refs.c
1 #include "cache.h"
2 #include "refs.h"
3
4 static const char *result_path, *lock_path;
5
6 static void remove_lock_file(void)
7 {
8         if (lock_path)
9                 unlink(lock_path);
10 }
11
12 static int handle_one_ref(const char *path, const unsigned char *sha1,
13                           int flags, void *cb_data)
14 {
15         FILE *refs_file = cb_data;
16
17         fprintf(refs_file, "%s %s\n", sha1_to_hex(sha1), path);
18         return 0;
19 }
20
21 int cmd_pack_refs(int argc, const char **argv, const char *prefix)
22 {
23         int fd;
24         FILE *refs_file;
25
26         result_path = xstrdup(git_path("packed-refs"));
27         lock_path = xstrdup(mkpath("%s.lock", result_path));
28
29         fd = open(lock_path, O_CREAT | O_EXCL | O_WRONLY, 0666);
30         if (fd < 0)
31                 die("unable to create new ref-pack file (%s)", strerror(errno));
32         atexit(remove_lock_file);
33
34         refs_file = fdopen(fd, "w");
35         if (!refs_file)
36                 die("unable to create ref-pack file structure (%s)", strerror(errno));
37         for_each_ref(handle_one_ref, refs_file);
38         fsync(fd);
39         fclose(refs_file);
40         if (rename(lock_path, result_path) < 0)
41                 die("unable to overwrite old ref-pack file (%s)", strerror(errno));
42         lock_path = NULL;
43         return 0;
44 }