builtin-blame: Reencode commit messages according to git-log rules.
[gitweb.git] / builtin-clone.c
index c0e3086437ced05d1b81d4098e3a4c7c3031b0ee..8e1a1d399580af3faa39c3c50350b3ca19df0634 100644 (file)
@@ -38,9 +38,11 @@ static int option_local, option_no_hardlinks, option_shared;
 static char *option_template, *option_reference, *option_depth;
 static char *option_origin = NULL;
 static char *option_upload_pack = "git-upload-pack";
+static int option_verbose;
 
 static struct option builtin_clone_options[] = {
        OPT__QUIET(&option_quiet),
+       OPT__VERBOSE(&option_verbose),
        OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
                    "don't create a checkout"),
        OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
@@ -58,7 +60,7 @@ static struct option builtin_clone_options[] = {
        OPT_STRING(0, "reference", &option_reference, "repo",
                   "reference repository"),
        OPT_STRING('o', "origin", &option_origin, "branch",
-                  "use <branch> instead or 'origin' to track upstream"),
+                  "use <branch> instead of 'origin' to track upstream"),
        OPT_STRING('u', "upload-pack", &option_upload_pack, "path",
                   "path to git-upload-pack on the remote"),
        OPT_STRING(0, "depth", &option_depth, "depth",
@@ -77,7 +79,7 @@ static char *get_repo_path(const char *repo, int *is_bundle)
        for (i = 0; i < ARRAY_SIZE(suffix); i++) {
                const char *path;
                path = mkpath("%s%s", repo, suffix[i]);
-               if (!stat(path, &st) && S_ISDIR(st.st_mode)) {
+               if (is_directory(path)) {
                        *is_bundle = 0;
                        return xstrdup(make_nonrelative_path(path));
                }
@@ -140,11 +142,13 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
        return xstrndup(start, end - start);
 }
 
-static int is_directory(const char *path)
+static void strip_trailing_slashes(char *dir)
 {
-       struct stat buf;
+       char *end = dir + strlen(dir);
 
-       return !stat(path, &buf) && S_ISDIR(buf.st_mode);
+       while (dir < end - 1 && is_dir_sep(end[-1]))
+               end--;
+       *end = '\0';
 }
 
 static void setup_reference(const char *repo)
@@ -262,10 +266,9 @@ pid_t junk_pid;
 
 static void remove_junk(void)
 {
-       struct strbuf sb;
+       struct strbuf sb = STRBUF_INIT;
        if (getpid() != junk_pid)
                return;
-       strbuf_init(&sb, 0);
        if (junk_git_dir) {
                strbuf_addstr(&sb, junk_git_dir);
                remove_dir_recursively(&sb, 0);
@@ -352,7 +355,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        char *path, *dir;
        const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
        char branch_top[256], key[256], value[256];
-       struct strbuf reflog_msg;
+       struct strbuf reflog_msg = STRBUF_INIT;
        struct transport *transport = NULL;
        char *src_ref_prefix = "refs/heads/";
 
@@ -387,7 +390,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
        path = get_repo_path(repo_name, &is_bundle);
        if (path)
-               repo = path;
+               repo = xstrdup(make_nonrelative_path(repo_name));
        else if (!strchr(repo_name, ':'))
                repo = xstrdup(make_absolute_path(repo_name));
        else
@@ -397,11 +400,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                dir = xstrdup(argv[1]);
        else
                dir = guess_dir_name(repo_name, is_bundle, option_bare);
+       strip_trailing_slashes(dir);
 
        if (!stat(dir, &buf))
                die("destination directory '%s' already exists.", dir);
 
-       strbuf_init(&reflog_msg, 0);
        strbuf_addf(&reflog_msg, "clone: from %s", repo);
 
        if (option_bare)
@@ -422,10 +425,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        if (!option_bare) {
                junk_work_tree = work_tree;
                if (safe_create_leading_directories_const(work_tree) < 0)
-                       die("could not create leading directories of '%s'",
-                                       work_tree);
+                       die("could not create leading directories of '%s': %s",
+                                       work_tree, strerror(errno));
                if (mkdir(work_tree, 0755))
-                       die("could not create work tree dir '%s'.", work_tree);
+                       die("could not create work tree dir '%s': %s.",
+                                       work_tree, strerror(errno));
                set_git_work_tree(work_tree);
        }
        junk_git_dir = git_dir;
@@ -502,6 +506,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
                if (option_quiet)
                        transport->verbose = -1;
+               else if (option_verbose)
+                       transport->progress = 1;
 
                if (option_upload_pack)
                        transport_set_option(transport, TRANS_OPT_UPLOADPACK,
@@ -522,7 +528,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                create_symref("HEAD", head_points_at->name, NULL);
 
                if (!option_bare) {
-                       struct strbuf head_ref;
+                       struct strbuf head_ref = STRBUF_INIT;
                        const char *head = head_points_at->name;
 
                        if (!prefixcmp(head, "refs/heads/"))
@@ -535,7 +541,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                                   head_points_at->old_sha1,
                                   NULL, 0, DIE_ON_ERR);
 
-                       strbuf_init(&head_ref, 0);
                        strbuf_addstr(&head_ref, branch_top);
                        strbuf_addstr(&head_ref, "HEAD");