Commit 8340dd5d5f0daf3ffda0c7ecb1791b21a152ecd2

Ben Straub 2012-06-20T14:17:54

Clone: remove fragile path-handling code. Also standardized on 3-space indentation. Sorry about that.

diff --git a/src/clone.c b/src/clone.c
index def1c0f..a737d97 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -19,10 +19,23 @@
 GIT_BEGIN_DECL
 
 
-static int git_checkout_branch(git_repository *repo, const char *branchname)
+static int git_checkout_force(git_repository *repo)
 {
-  /* TODO */
-  return 0;
+   /* TODO */
+   return 0;
+}
+
+static int update_head_to_remote(git_repository *repo, git_remote *remote)
+{
+   int retcode = 0;
+
+   /* Get the remote's HEAD. This is always the first ref in remote->refs. */
+   git_buf remote_default_branch = GIT_BUF_INIT;
+   /* TODO */
+
+   git_buf_free(&remote_default_branch);
+
+   return retcode;
 }
 
 /*
@@ -36,49 +49,60 @@ static int setup_remotes_and_fetch(git_repository *repo,
                                    const char *origin_url,
                                    git_indexer_stats *stats)
 {
-  int retcode = GIT_ERROR;
-  git_remote *origin = NULL;
-  git_off_t bytes = 0;
-  git_indexer_stats dummy_stats;
-
-  if (!stats) stats = &dummy_stats;
-
-  if (!git_remote_add(&origin, repo, "origin", origin_url)) {
-    if (!git_remote_connect(origin, GIT_DIR_FETCH)) {
-      if (!git_remote_download(origin, &bytes, stats)) {
-        if (!git_remote_update_tips(origin, NULL)) {
-          retcode = 0;
-        }
+   int retcode = GIT_ERROR;
+   git_remote *origin = NULL;
+   git_off_t bytes = 0;
+   git_indexer_stats dummy_stats;
+
+   if (!stats) stats = &dummy_stats;
+
+   /* Create the "origin" remote */
+   if (!git_remote_add(&origin, repo, "origin", origin_url)) {
+      /* Connect and download everything */
+      if (!git_remote_connect(origin, GIT_DIR_FETCH)) {
+         if (!git_remote_download(origin, &bytes, stats)) {
+            /* Create "origin/foo" branches for all remote branches */
+            if (!git_remote_update_tips(origin, NULL)) {
+               /* Point HEAD to the same ref as the remote's head */
+               if (!update_head_to_remote(repo, origin)) {
+                  retcode = 0;
+               }
+            }
+         }
+         git_remote_disconnect(origin);
       }
-      git_remote_disconnect(origin);
-    }
-    git_remote_free(origin);
-  }
+      git_remote_free(origin);
+   }
 
-  return retcode;
+   return retcode;
 }
 
 static int clone_internal(git_repository **out,
                           const char *origin_url,
-                          const char *fullpath,
+                          const char *path,
                           git_indexer_stats *stats,
                           int is_bare)
 {
-  int retcode = GIT_ERROR;
-  git_repository *repo = NULL;
-
-  if (!(retcode = git_repository_init(&repo, fullpath, is_bare))) {
-    if ((retcode = setup_remotes_and_fetch(repo, origin_url, stats)) < 0) {
-      /* Failed to fetch; clean up */
-      git_repository_free(repo);
-      git_futils_rmdir_r(fullpath, GIT_DIRREMOVAL_FILES_AND_DIRS);
-    } else {
-      *out = repo;
-      retcode = 0;
-    }
-  }
-
-  return retcode;
+   int retcode = GIT_ERROR;
+   git_repository *repo = NULL;
+
+   if (git_path_exists(path)) {
+      giterr_set(GITERR_INVALID, "Path '%s' already exists.", path);
+      return GIT_ERROR;
+   }
+
+   if (!(retcode = git_repository_init(&repo, path, is_bare))) {
+      if ((retcode = setup_remotes_and_fetch(repo, origin_url, stats)) < 0) {
+         /* Failed to fetch; clean up */
+         git_repository_free(repo);
+         git_futils_rmdir_r(path, GIT_DIRREMOVAL_FILES_AND_DIRS);
+      } else {
+         *out = repo;
+         retcode = 0;
+      }
+   }
+
+   return retcode;
 }
 
 int git_clone_bare(git_repository **out,
@@ -86,15 +110,7 @@ int git_clone_bare(git_repository **out,
                    const char *dest_path,
                    git_indexer_stats *stats)
 {
-  char fullpath[512] = {0};
-
-  p_realpath(dest_path, fullpath);
-  if (git_path_exists(fullpath)) {
-    giterr_set(GITERR_INVALID, "Destination already exists: %s", fullpath);
-    return GIT_ERROR;
-  }
-
-  return clone_internal(out, origin_url, fullpath, stats, 1);
+   return clone_internal(out, origin_url, dest_path, stats, 1);
 }
 
 
@@ -103,22 +119,13 @@ int git_clone(git_repository **out,
               const char *workdir_path,
               git_indexer_stats *stats)
 {
-  int retcode = GIT_ERROR;
-  char fullpath[512] = {0};
-
-  p_realpath(workdir_path, fullpath);
-  if (git_path_exists(fullpath)) {
-    giterr_set(GITERR_INVALID, "Destination already exists: %s", fullpath);
-    return GIT_ERROR;
-  }
-
-  if (!clone_internal(out, origin_url, workdir_path, stats, 0)) {
-    char default_branch_name[256] = "master";
-    /* TODO */
-    retcode = git_checkout_branch(*out, default_branch_name);
-  }
-
-  return retcode;
+   int retcode = GIT_ERROR;
+
+   if (!(retcode = clone_internal(out, origin_url, workdir_path, stats, 0))) {
+      retcode = git_checkout_force(*out);
+   }
+
+   return retcode;
 }
 
 
diff --git a/tests-clar/clone/clone.c b/tests-clar/clone/clone.c
index 6fb6a79..b4e9c30 100644
--- a/tests-clar/clone/clone.c
+++ b/tests-clar/clone/clone.c
@@ -86,16 +86,22 @@ void test_clone_clone__local(void)
 }
 
 
-void test_clone_clone__network(void)
+void test_clone_clone__network_full(void)
 {
 #if 0
   cl_git_pass(git_clone(&g_repo,
                         "https://github.com/libgit2/libgit2.git",
                         "./libgit2", NULL));
+  git_futils_rmdir_r("./libgit2", GIT_DIRREMOVAL_FILES_AND_DIRS);
+#endif
+}
+
+void test_clone_clone__network_bare(void)
+{
+#if 0
   cl_git_pass(git_clone_bare(&g_repo,
                              "https://github.com/libgit2/libgit2.git",
                              "./libgit2.git", NULL));
-  git_futils_rmdir_r("./libgit2", GIT_DIRREMOVAL_FILES_AND_DIRS);
   git_futils_rmdir_r("./libgit2.git", GIT_DIRREMOVAL_FILES_AND_DIRS);
 #endif
 }