Commit 14741d62d9a8ae79774cf891a7ed665d8d650188

Ben Straub 2012-06-21T11:13:19

Clone: new home for git_checkout_force.

diff --git a/include/git2/checkout.h b/include/git2/checkout.h
new file mode 100644
index 0000000..9dec5b9
--- /dev/null
+++ b/include/git2/checkout.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 the libgit2 contributors
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_checkout_h__
+#define INCLUDE_git_checkout_h__
+
+#include "common.h"
+#include "types.h"
+#include "indexer.h"
+
+
+/**
+ * @file git2/checkout.h
+ * @brief Git checkout routines
+ * @defgroup git_checkout Git checkout routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Updates files in the working tree to match the version in the index
+ * or HEAD.
+ *
+ * @param repo repository to check out (must be non-bare)
+ * @param origin_url repository to clone from
+ * @param workdir_path local directory to clone to
+ * @param stats pointer to structure that receives progress information (may be NULL)
+ * @return 0 on success, GIT_ERROR otherwise (use git_error_last for information about the error)
+ */
+GIT_EXTERN(int) git_checkout_force(git_repository *repo, git_indexer_stats *stats);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/src/checkout.c b/src/checkout.c
new file mode 100644
index 0000000..f3bee6b
--- /dev/null
+++ b/src/checkout.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009-2012 the libgit2 contributors
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+
+#include <assert.h>
+
+#include "git2/checkout.h"
+#include "git2/repository.h"
+#include "git2/refs.h"
+#include "git2/tree.h"
+#include "git2/commit.h"
+
+#include "common.h"
+#include "refs.h"
+
+GIT_BEGIN_DECL
+
+
+static int get_head_tree(git_tree **out, git_repository *repo)
+{
+   int retcode = GIT_ERROR;
+   git_reference *head = NULL;
+
+   /* Dereference HEAD all the way to an OID ref */
+   if (!git_reference_lookup_resolved(&head, repo, GIT_HEAD_FILE, -1)) {
+      /* The OID should be a commit */
+      git_object *commit;
+      if (!git_object_lookup(&commit, repo,
+                             git_reference_oid(head), GIT_OBJ_COMMIT)) {
+         /* Get the tree */
+         if (!git_commit_tree(out, (git_commit*)commit)) {
+            retcode = 0;
+         }
+         git_object_free(commit);
+      }
+      git_reference_free(head);
+   }
+
+   return retcode;
+}
+
+/* TODO
+ * -> Line endings
+ */
+int git_checkout_force(git_repository *repo, git_indexer_stats *stats)
+{
+   int retcode = GIT_ERROR;
+   git_indexer_stats dummy_stats;
+   git_tree *tree;
+
+   assert(repo);
+   if (!stats) stats = &dummy_stats;
+
+   if (!get_head_tree(&tree, repo)) {
+      /* TODO */
+      retcode = 0;
+   }
+
+   return retcode;
+}
+
+
+GIT_END_DECL
diff --git a/src/clone.c b/src/clone.c
index 7ae3c14..cc20b97 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -12,12 +12,12 @@
 #include "git2/revparse.h"
 #include "git2/branch.h"
 #include "git2/config.h"
+#include "git2/checkout.h"
 
 #include "common.h"
 #include "remote.h"
 #include "fileops.h"
 #include "refs.h"
-// TODO #include "checkout.h"
 
 GIT_BEGIN_DECL
 
@@ -27,14 +27,6 @@ struct HeadInfo {
    git_buf branchname;
 };
 
-static int git_checkout_force(git_repository *repo)
-{
-   /* TODO
-    * -> Line endings
-    */
-   return 0;
-}
-
 static int create_tracking_branch(git_repository *repo, git_oid *target, const char *name)
 {
    git_object *head_obj = NULL;
@@ -214,6 +206,7 @@ int git_clone_bare(git_repository **out,
                    const char *dest_path,
                    git_indexer_stats *stats)
 {
+   assert(out && origin_url && dest_path);
    return clone_internal(out, origin_url, dest_path, stats, 1);
 }
 
@@ -225,8 +218,11 @@ int git_clone(git_repository **out,
 {
    int retcode = GIT_ERROR;
 
+   assert(out && origin_url && workdir_path);
+
    if (!(retcode = clone_internal(out, origin_url, workdir_path, stats, 0))) {
-      retcode = git_checkout_force(*out);
+      git_indexer_stats checkout_stats;
+      retcode = git_checkout_force(*out, &checkout_stats);
    }
 
    return retcode;