return get_ref_dir(refs->loose);
}
-/* We allow "recursive" symbolic refs. Only within reason, though */
-#define MAXDEPTH 5
#define MAXREFLEN (1024)
/*
char buffer[128], *p;
char *path;
- if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN)
+ if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN)
return -1;
path = *refs->name
? git_pathdup_submodule(refs->name, "%s", refname)
* - in all other cases, symref will be untouched, and therefore
* refname will still be valid and unchanged.
*/
-static int read_raw_ref(const char *refname, unsigned char *sha1,
- struct strbuf *symref, unsigned int *flags)
+int read_raw_ref(const char *refname, unsigned char *sha1,
+ struct strbuf *symref, unsigned int *flags)
{
struct strbuf sb_contents = STRBUF_INIT;
struct strbuf sb_path = STRBUF_INIT;
return ret;
}
-/* This function needs to return a meaningful errno on failure */
-const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
- unsigned char *sha1, int *flags)
-{
- static struct strbuf sb_refname = STRBUF_INIT;
- int unused_flags;
- int symref_count;
-
- if (!flags)
- flags = &unused_flags;
-
- *flags = 0;
-
- if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
- if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
- !refname_is_safe(refname)) {
- errno = EINVAL;
- return NULL;
- }
-
- /*
- * dwim_ref() uses REF_ISBROKEN to distinguish between
- * missing refs and refs that were present but invalid,
- * to complain about the latter to stderr.
- *
- * We don't know whether the ref exists, so don't set
- * REF_ISBROKEN yet.
- */
- *flags |= REF_BAD_NAME;
- }
-
- for (symref_count = 0; symref_count < MAXDEPTH; symref_count++) {
- unsigned int read_flags = 0;
-
- if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) {
- *flags |= read_flags;
- if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING))
- return NULL;
- hashclr(sha1);
- if (*flags & REF_BAD_NAME)
- *flags |= REF_ISBROKEN;
- return refname;
- }
-
- *flags |= read_flags;
-
- if (!(read_flags & REF_ISSYMREF)) {
- if (*flags & REF_BAD_NAME) {
- hashclr(sha1);
- *flags |= REF_ISBROKEN;
- }
- return refname;
- }
-
- refname = sb_refname.buf;
- if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
- hashclr(sha1);
- return refname;
- }
- if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
- if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
- !refname_is_safe(refname)) {
- errno = EINVAL;
- return NULL;
- }
-
- *flags |= REF_ISBROKEN | REF_BAD_NAME;
- }
- }
-
- errno = ELOOP;
- return NULL;
-}
-
/*
* Peel the entry (if possible) and return its new peel_status. If
* repeel is true, re-peel the entry even if there is an old peeled
return ret;
}
+int set_worktree_head_symref(const char *gitdir, const char *target)
+{
+ static struct lock_file head_lock;
+ struct ref_lock *lock;
+ struct strbuf head_path = STRBUF_INIT;
+ const char *head_rel;
+ int ret;
+
+ strbuf_addf(&head_path, "%s/HEAD", absolute_path(gitdir));
+ if (hold_lock_file_for_update(&head_lock, head_path.buf,
+ LOCK_NO_DEREF) < 0) {
+ struct strbuf err = STRBUF_INIT;
+ unable_to_lock_message(head_path.buf, errno, &err);
+ error("%s", err.buf);
+ strbuf_release(&err);
+ strbuf_release(&head_path);
+ return -1;
+ }
+
+ /* head_rel will be "HEAD" for the main tree, "worktrees/wt/HEAD" for
+ linked trees */
+ head_rel = remove_leading_path(head_path.buf,
+ absolute_path(get_git_common_dir()));
+ /* to make use of create_symref_locked(), initialize ref_lock */
+ lock = xcalloc(1, sizeof(struct ref_lock));
+ lock->lk = &head_lock;
+ lock->ref_name = xstrdup(head_rel);
+ lock->orig_ref_name = xstrdup(head_rel);
+
+ ret = create_symref_locked(lock, head_rel, target, NULL);
+
+ unlock_ref(lock); /* will free lock */
+ strbuf_release(&head_path);
+ return ret;
+}
+
int reflog_exists(const char *refname)
{
struct stat st;
* reference itself, plus we might need to update the
* reference if --updateref was specified:
*/
- lock = lock_ref_sha1_basic(refname, sha1, NULL, NULL, 0, &type, &err);
+ lock = lock_ref_sha1_basic(refname, sha1, NULL, NULL, REF_NODEREF,
+ &type, &err);
if (!lock) {
error("cannot lock ref '%s': %s", refname, err.buf);
strbuf_release(&err);