6 static char *ref_file_name(const char *ref
)
8 char *base
= get_refs_directory();
9 int baselen
= strlen(base
);
10 int reflen
= strlen(ref
);
11 char *ret
= xmalloc(baselen
+ 2 + reflen
);
12 sprintf(ret
, "%s/%s", base
, ref
);
16 static char *ref_lock_file_name(const char *ref
)
18 char *base
= get_refs_directory();
19 int baselen
= strlen(base
);
20 int reflen
= strlen(ref
);
21 char *ret
= xmalloc(baselen
+ 7 + reflen
);
22 sprintf(ret
, "%s/%s.lock", base
, ref
);
26 static int read_ref_file(const char *filename
, unsigned char *sha1
) {
27 int fd
= open(filename
, O_RDONLY
);
30 return error("Couldn't open %s\n", filename
);
32 if ((read(fd
, hex
, 41) < 41) ||
34 get_sha1_hex(hex
, sha1
)) {
35 error("Couldn't read a hash from %s\n", filename
);
43 int get_ref_sha1(const char *ref
, unsigned char *sha1
)
47 if (check_ref_format(ref
))
49 filename
= ref_file_name(ref
);
50 retval
= read_ref_file(filename
, sha1
);
55 static int lock_ref_file(const char *filename
, const char *lock_filename
,
56 const unsigned char *old_sha1
)
58 int fd
= open(lock_filename
, O_WRONLY
| O_CREAT
| O_EXCL
, 0666);
59 unsigned char current_sha1
[20];
62 return error("Couldn't open lock file for %s: %s",
63 filename
, strerror(errno
));
65 retval
= read_ref_file(filename
, current_sha1
);
69 unlink(lock_filename
);
70 return error("Could not read the current value of %s",
73 if (memcmp(current_sha1
, old_sha1
, 20)) {
75 unlink(lock_filename
);
76 error("The current value of %s is %s",
77 filename
, sha1_to_hex(current_sha1
));
78 return error("Expected %s",
79 sha1_to_hex(old_sha1
));
84 unlink(lock_filename
);
85 return error("Unexpectedly found a value of %s for %s",
86 sha1_to_hex(current_sha1
), filename
);
92 int lock_ref_sha1(const char *ref
, const unsigned char *old_sha1
)
97 if (check_ref_format(ref
))
99 filename
= ref_file_name(ref
);
100 lock_filename
= ref_lock_file_name(ref
);
101 retval
= lock_ref_file(filename
, lock_filename
, old_sha1
);
107 static int write_ref_file(const char *filename
,
108 const char *lock_filename
, int fd
,
109 const unsigned char *sha1
)
111 char *hex
= sha1_to_hex(sha1
);
113 if (write(fd
, hex
, 40) < 40 ||
114 write(fd
, &term
, 1) < 1) {
115 error("Couldn't write %s\n", filename
);
120 rename(lock_filename
, filename
);
124 int write_ref_sha1(const char *ref
, int fd
, const unsigned char *sha1
)
131 if (check_ref_format(ref
))
133 filename
= ref_file_name(ref
);
134 lock_filename
= ref_lock_file_name(ref
);
135 retval
= write_ref_file(filename
, lock_filename
, fd
, sha1
);
141 int check_ref_format(const char *ref
)
144 if (ref
[0] == '.' || ref
[0] == '/')
146 middle
= strchr(ref
, '/');
147 if (!middle
|| !middle
[1])
149 if (strchr(middle
+ 1, '/'))
154 int write_ref_sha1_unlocked(const char *ref
, const unsigned char *sha1
)
160 if (check_ref_format(ref
))
162 filename
= ref_file_name(ref
);
163 lock_filename
= ref_lock_file_name(ref
);
164 fd
= open(lock_filename
, O_WRONLY
| O_CREAT
| O_EXCL
, 0666);
166 error("Writing %s", lock_filename
);
169 retval
= write_ref_file(filename
, lock_filename
, fd
, sha1
);