+ if (len < 40 || get_sha1_hex(buffer, sha1))
+ return NULL;
+ return path;
+}
+
+int create_symref(const char *git_HEAD, const char *refs_heads_master)
+{
+ const char *lockpath;
+ char ref[1000];
+ int fd, len, written;
+
+#if USE_SYMLINK_HEAD
+ if (!only_use_symrefs) {
+ unlink(git_HEAD);
+ if (!symlink(refs_heads_master, git_HEAD))
+ return 0;
+ fprintf(stderr, "no symlink - falling back to symbolic ref\n");
+ }
+#endif
+
+ len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master);
+ if (sizeof(ref) <= len) {
+ error("refname too long: %s", refs_heads_master);
+ return -1;
+ }
+ lockpath = mkpath("%s.lock", git_HEAD);
+ fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666);
+ written = write(fd, ref, len);
+ close(fd);
+ if (written != len) {
+ unlink(lockpath);
+ error("Unable to write to %s", lockpath);
+ return -2;
+ }
+ if (rename(lockpath, git_HEAD) < 0) {
+ unlink(lockpath);
+ error("Unable to create %s", git_HEAD);
+ return -3;
+ }
+ return 0;
+}
+
+int read_ref(const char *filename, unsigned char *sha1)
+{
+ if (resolve_ref(filename, sha1, 1))
+ return 0;
+ return -1;