} cached_refs;
static struct ref_list *current_ref;
+static struct ref_list *extra_refs;
+
static void free_ref_list(struct ref_list *list)
{
struct ref_list *next;
cached_refs->packed = sort_ref_list(list);
}
+void add_extra_ref(const char *name, const unsigned char *sha1, int flag)
+{
+ extra_refs = add_ref(name, sha1, flag, extra_refs, NULL);
+}
+
+void clear_extra_refs(void)
+{
+ free_ref_list(extra_refs);
+ extra_refs = NULL;
+}
+
static struct ref_list *get_packed_refs(void)
{
if (!cached_refs.did_packed) {
{
int len = strlen(path), retval;
char *gitdir;
+ const char *tmp;
while (len && path[len-1] == '/')
len--;
return -1;
gitdir = xmalloc(len + MAXREFLEN + 8);
memcpy(gitdir, path, len);
- memcpy(gitdir + len, "/.git/", 7);
-
- retval = resolve_gitlink_ref_recursive(gitdir, len+6, refname, result, 0);
+ memcpy(gitdir + len, "/.git", 6);
+ len += 5;
+
+ tmp = read_gitfile_gently(gitdir);
+ if (tmp) {
+ free(gitdir);
+ len = strlen(tmp);
+ gitdir = xmalloc(len + MAXREFLEN + 3);
+ memcpy(gitdir, tmp, len);
+ }
+ gitdir[len] = '/';
+ gitdir[++len] = '\0';
+ retval = resolve_gitlink_ref_recursive(gitdir, len, refname, result, 0);
free(gitdir);
return retval;
}
const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag)
{
- int depth = MAXDEPTH, len;
+ int depth = MAXDEPTH;
+ ssize_t len;
char buffer[256];
static char ref_buffer[256];
struct ref_list *packed = get_packed_refs();
struct ref_list *loose = get_loose_refs();
+ struct ref_list *extra;
+
+ for (extra = extra_refs; extra; extra = extra->next)
+ retval = do_one_ref(base, fn, trim, cb_data, extra);
+
while (packed && loose) {
struct ref_list *entry;
int cmp = strcmp(packed->name, loose->name);
i = strlen(lock->lk->filename) - 5; /* .lock */
lock->lk->filename[i] = 0;
err = unlink(lock->lk->filename);
- if (err) {
+ if (err && errno != ENOENT) {
ret = 1;
error("unlink(%s) failed: %s",
lock->lk->filename, strerror(errno));