From 1b5bf479ffa0679bbecab70f840a6453fb541100 Mon Sep 17 00:00:00 2001
From: Nico von Geyso <Nico.Geyso@FU-Berlin.de>
Date: Sun, 17 Feb 2013 14:59:54 +0100
Subject: [PATCH] added functionality to checkout from index

---
 src/repository.c        | 13 +++++++------
 test/test_repository.py | 22 +++++++++++++++++++---
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/src/repository.c b/src/repository.c
index cf816d9..b187ab6 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1082,12 +1082,12 @@ Repository_checkout(Repository *self, PyObject *args, PyObject *kw)
     Reference* ref = NULL;
     git_object* object;
     const git_oid* id;
-    int err;
+    int err, head = 0;
 
-    static char *kwlist[] = {"strategy", "reference", NULL};
+    static char *kwlist[] = {"strategy", "reference", "head", NULL};
 
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "|IO!", kwlist,
-                                     &strategy, &ReferenceType, &ref))
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|IO!i", kwlist,
+                                     &strategy, &ReferenceType, &ref, &head))
         return NULL;
 
     if (ref != NULL) { // checkout from treeish
@@ -1101,9 +1101,10 @@ Repository_checkout(Repository *self, PyObject *args, PyObject *kw)
                           git_reference_name(ref->reference));
             }
         }
-    } else { // checkout from head
+    } else { // checkout from head / index
         opts.checkout_strategy = strategy;
-        err = git_checkout_head(self->repo, &opts);
+        err = (!head) ? git_checkout_index(self->repo, NULL, &opts) :
+                        git_checkout_head(self->repo, &opts);
     }
 
     if(err < 0)
diff --git a/test/test_repository.py b/test/test_repository.py
index e85e6a5..10c9885 100644
--- a/test/test_repository.py
+++ b/test/test_repository.py
@@ -184,7 +184,7 @@ class RepositoryTest_II(utils.RepoTestCase):
         expected = realpath(join(self._temp_dir, 'testrepo'))
         self.assertEqual(directory, expected)
 
-    def test_checkout(self):
+    def test_checkout_ref(self):
         ref_i18n = self.repo.lookup_reference('refs/heads/i18n')
 
         # checkout i18n with conflicts and default strategy should
@@ -199,13 +199,29 @@ class RepositoryTest_II(utils.RepoTestCase):
         self.assertTrue('new' in self.repo.head.tree)
         self.assertTrue('bye.txt' not in self.repo.status())
 
+    def test_checkout_index(self):
         # some changes to working dir
-        with open(os.path.join(self.repo.workdir, 'bye.txt'), 'w') as f:
+        with open(os.path.join(self.repo.workdir, 'hello.txt'), 'w') as f:
           f.write('new content')
 
-        # checkout head
+        # checkout index
+        self.assertTrue('hello.txt' in self.repo.status())
+        self.repo.checkout(pygit2.GIT_CHECKOUT_FORCE)
+        self.assertTrue('hello.txt' not in self.repo.status())
+
+    def test_checkout_head(self):
+        # some changes to the index
+        with open(os.path.join(self.repo.workdir, 'bye.txt'), 'w') as f:
+          f.write('new content')
+        self.repo.index.add('bye.txt')
+
+        # checkout from index should not change anything
         self.assertTrue('bye.txt' in self.repo.status())
         self.repo.checkout(pygit2.GIT_CHECKOUT_FORCE)
+        self.assertTrue('bye.txt' in self.repo.status())
+
+        # checkout from head will reset index as well
+        self.repo.checkout(pygit2.GIT_CHECKOUT_FORCE, head=True)
         self.assertTrue('bye.txt' not in self.repo.status())
 
 class NewRepositoryTest(utils.NoRepoTestCase):