Merge branch 'dt/untracked-subdir'
[gitweb.git] / builtin / clone.c
index f60d3271ed32638ca8d1306d236c650b995471a4..578da85254418a620d3c7c847af8eed6a3a29d58 100644 (file)
@@ -99,51 +99,66 @@ static const char *argv_submodule[] = {
        "submodule", "update", "--init", "--recursive", NULL
 };
 
-static char *get_repo_path(const char *repo, int *is_bundle)
+static const char *get_repo_path_1(struct strbuf *path, int *is_bundle)
 {
        static char *suffix[] = { "/.git", "", ".git/.git", ".git" };
        static char *bundle_suffix[] = { ".bundle", "" };
+       size_t baselen = path->len;
        struct stat st;
        int i;
 
        for (i = 0; i < ARRAY_SIZE(suffix); i++) {
-               const char *path;
-               path = mkpath("%s%s", repo, suffix[i]);
-               if (stat(path, &st))
+               strbuf_setlen(path, baselen);
+               strbuf_addstr(path, suffix[i]);
+               if (stat(path->buf, &st))
                        continue;
-               if (S_ISDIR(st.st_mode) && is_git_directory(path)) {
+               if (S_ISDIR(st.st_mode) && is_git_directory(path->buf)) {
                        *is_bundle = 0;
-                       return xstrdup(absolute_path(path));
+                       return path->buf;
                } else if (S_ISREG(st.st_mode) && st.st_size > 8) {
                        /* Is it a "gitfile"? */
                        char signature[8];
-                       int len, fd = open(path, O_RDONLY);
+                       const char *dst;
+                       int len, fd = open(path->buf, O_RDONLY);
                        if (fd < 0)
                                continue;
                        len = read_in_full(fd, signature, 8);
                        close(fd);
                        if (len != 8 || strncmp(signature, "gitdir: ", 8))
                                continue;
-                       path = read_gitfile(path);
-                       if (path) {
+                       dst = read_gitfile(path->buf);
+                       if (dst) {
                                *is_bundle = 0;
-                               return xstrdup(absolute_path(path));
+                               return dst;
                        }
                }
        }
 
        for (i = 0; i < ARRAY_SIZE(bundle_suffix); i++) {
-               const char *path;
-               path = mkpath("%s%s", repo, bundle_suffix[i]);
-               if (!stat(path, &st) && S_ISREG(st.st_mode)) {
+               strbuf_setlen(path, baselen);
+               strbuf_addstr(path, bundle_suffix[i]);
+               if (!stat(path->buf, &st) && S_ISREG(st.st_mode)) {
                        *is_bundle = 1;
-                       return xstrdup(absolute_path(path));
+                       return path->buf;
                }
        }
 
        return NULL;
 }
 
+static char *get_repo_path(const char *repo, int *is_bundle)
+{
+       struct strbuf path = STRBUF_INIT;
+       const char *raw;
+       char *canon;
+
+       strbuf_addstr(&path, repo);
+       raw = get_repo_path_1(&path, is_bundle);
+       canon = raw ? xstrdup(absolute_path(raw)) : NULL;
+       strbuf_release(&path);
+       return canon;
+}
+
 static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
 {
        const char *end = repo + strlen(repo), *start, *ptr;
@@ -320,16 +335,17 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst,
        struct strbuf line = STRBUF_INIT;
 
        while (strbuf_getline(&line, in, '\n') != EOF) {
-               char *abs_path, abs_buf[PATH_MAX];
+               char *abs_path;
                if (!line.len || line.buf[0] == '#')
                        continue;
                if (is_absolute_path(line.buf)) {
                        add_to_alternates_file(line.buf);
                        continue;
                }
-               abs_path = mkpath("%s/objects/%s", src_repo, line.buf);
-               normalize_path_copy(abs_buf, abs_path);
-               add_to_alternates_file(abs_buf);
+               abs_path = mkpathdup("%s/objects/%s", src_repo, line.buf);
+               normalize_path_copy(abs_path, abs_path);
+               add_to_alternates_file(abs_path);
+               free(abs_path);
        }
        strbuf_release(&line);
        fclose(in);
@@ -526,16 +542,26 @@ static void write_remote_refs(const struct ref *local_refs)
 {
        const struct ref *r;
 
-       lock_packed_refs(LOCK_DIE_ON_ERROR);
+       struct ref_transaction *t;
+       struct strbuf err = STRBUF_INIT;
+
+       t = ref_transaction_begin(&err);
+       if (!t)
+               die("%s", err.buf);
 
        for (r = local_refs; r; r = r->next) {
                if (!r->peer_ref)
                        continue;
-               add_packed_ref(r->peer_ref->name, r->old_sha1);
+               if (ref_transaction_create(t, r->peer_ref->name, r->old_sha1,
+                                          0, NULL, &err))
+                       die("%s", err.buf);
        }
 
-       if (commit_packed_refs())
-               die_errno("unable to overwrite old ref-pack file");
+       if (initial_ref_transaction_commit(t, &err))
+               die("%s", err.buf);
+
+       strbuf_release(&err);
+       ref_transaction_free(t);
 }
 
 static void write_followtags(const struct ref *refs, const char *msg)