summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/git/index/base.py21
-rw-r--r--lib/git/index/fun.py4
-rw-r--r--test/git/test_index.py31
-rw-r--r--test/testlib/helper.py6
4 files changed, 42 insertions, 20 deletions
diff --git a/lib/git/index/base.py b/lib/git/index/base.py
index 96a9430c..48b2d766 100644
--- a/lib/git/index/base.py
+++ b/lib/git/index/base.py
@@ -889,40 +889,41 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
@default_index
def checkout(self, paths=None, force=False, fprogress=lambda *args: None, **kwargs):
- """
- Checkout the given paths or all files from the version known to the index into
+ """Checkout the given paths or all files from the version known to the index into
the working tree.
+
+ :note: Be sure you have written pending changes using the ``write`` method
+ in case you have altered the enties dictionary directly
- ``paths``
+ :param paths:
If None, all paths in the index will be checked out. Otherwise an iterable
of relative or absolute paths or a single path pointing to files or directories
in the index is expected.
- ``force``
+ :param force:
If True, existing files will be overwritten even if they contain local modifications.
If False, these will trigger a CheckoutError.
- ``fprogress``
+ :param fprogress:
see Index.add_ for signature and explanation.
The provided progress information will contain None as path and item if no
explicit paths are given. Otherwise progress information will be send
prior and after a file has been checked out
- ``**kwargs``
+ :param **kwargs:
Additional arguments to be pasesd to git-checkout-index
- Returns
+ :return:
iterable yielding paths to files which have been checked out and are
guaranteed to match the version stored in the index
- Raise CheckoutError
+ :raise CheckoutError:
If at least one file failed to be checked out. This is a summary,
hence it will checkout as many files as it can anyway.
If one of files or directories do not exist in the index
( as opposed to the original git command who ignores them ).
Raise GitCommandError if error lines could not be parsed - this truly is
- an exceptional state
- """
+ an exceptional state"""
args = ["--index"]
if force:
args.append("--force")
diff --git a/lib/git/index/fun.py b/lib/git/index/fun.py
index 557941d5..9f877a66 100644
--- a/lib/git/index/fun.py
+++ b/lib/git/index/fun.py
@@ -168,11 +168,11 @@ def write_tree_from_cache(entries, odb, sl, si=0):
xi = ci
while xi < end:
oentry = entries[xi]
- xi += 1
- orbound = oentry.path.find('/')
+ orbound = oentry.path.find('/', si)
if orbound == -1 or oentry.path[si:orbound] != base:
break
# END abort on base mismatch
+ xi += 1
# END find common base
# enter recursion
diff --git a/test/git/test_index.py b/test/git/test_index.py
index efb1b477..cd005c1d 100644
--- a/test/git/test_index.py
+++ b/test/git/test_index.py
@@ -6,6 +6,7 @@
from test.testlib import *
from git import *
+from git.index.util import TemporaryFileSwap
import inspect
import os
import sys
@@ -94,23 +95,24 @@ class TestIndex(TestBase):
raise AssertionError( "CMP Failed: Missing entries in index: %s, missing in tree: %s" % (bset-iset, iset-bset) )
# END assertion message
- def test_index_file_from_tree(self):
+ @with_rw_repo('0.1.6')
+ def test_index_file_from_tree(self, rw_repo):
common_ancestor_sha = "5117c9c8a4d3af19a9958677e45cda9269de1541"
cur_sha = "4b43ca7ff72d5f535134241e7c797ddc9c7a3573"
other_sha = "39f85c4358b7346fee22169da9cad93901ea9eb9"
# simple index from tree
- base_index = IndexFile.from_tree(self.rorepo, common_ancestor_sha)
+ base_index = IndexFile.from_tree(rw_repo, common_ancestor_sha)
assert base_index.entries
self._cmp_tree_index(common_ancestor_sha, base_index)
# merge two trees - its like a fast-forward
- two_way_index = IndexFile.from_tree(self.rorepo, common_ancestor_sha, cur_sha)
+ two_way_index = IndexFile.from_tree(rw_repo, common_ancestor_sha, cur_sha)
assert two_way_index.entries
self._cmp_tree_index(cur_sha, two_way_index)
# merge three trees - here we have a merge conflict
- three_way_index = IndexFile.from_tree(self.rorepo, common_ancestor_sha, cur_sha, other_sha)
+ three_way_index = IndexFile.from_tree(rw_repo, common_ancestor_sha, cur_sha, other_sha)
assert len(list(e for e in three_way_index.entries.values() if e.stage != 0))
@@ -476,7 +478,7 @@ class TestIndex(TestBase):
fake_symlink_relapath = "my_fake_symlink"
link_target = "/etc/that"
fake_symlink_path = self._make_file(fake_symlink_relapath, link_target, rw_repo)
- fake_entry = BaseIndexEntry((0120000, null_hex_sha, 0, fake_symlink_relapath))
+ fake_entry = BaseIndexEntry((0120000, null_bin_sha, 0, fake_symlink_relapath))
entries = index.reset(new_commit).add([fake_entry], fprogress=self._fprogress_add)
self._assert_fprogress(entries)
assert entries[0].hexsha != null_hex_sha
@@ -497,6 +499,7 @@ class TestIndex(TestBase):
# a tree created from this should contain the symlink
tree = index.write_tree()
assert fake_symlink_relapath in tree
+ index.write() # flush our changes for the checkout
# checkout the fakelink, should be a link then
assert not S_ISLNK(os.stat(fake_symlink_path)[ST_MODE])
@@ -569,5 +572,19 @@ class TestIndex(TestBase):
for filenum in range(len(paths)):
assert index.entry_key(str(filenum), 0) in index.entries
- def test_compare_write_tree(self):
- self.fail("compare git-write-tree with python implementation, must have same output")
+ @with_rw_repo('HEAD')
+ def test_compare_write_tree(self, rw_repo):
+ def write_tree(index):
+ tree_sha = index.repo.git.write_tree(missing_ok=True)
+ return Tree(index.repo, tree_sha, 0, '')
+ # END git cmd write tree
+
+ # write all trees and compare them
+ for commit in rw_repo.head.commit.traverse():
+ index = rw_repo.index.reset(commit)
+ orig_tree = commit.tree
+ new_git_tree = write_tree(index)
+ assert new_git_tree == orig_tree
+ assert index.write_tree() == orig_tree
+ # END for each commit
+
diff --git a/test/testlib/helper.py b/test/testlib/helper.py
index 715427c2..ebff57f6 100644
--- a/test/testlib/helper.py
+++ b/test/testlib/helper.py
@@ -5,6 +5,7 @@
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
import os
+import sys
from git import Repo, Remote, GitCommandError
from unittest import TestCase
import tempfile
@@ -105,7 +106,10 @@ def with_rw_repo(working_tree_ref):
os.chdir(rw_repo.working_dir)
try:
return func(self, rw_repo)
- finally:
+ except:
+ print >> sys.stderr, "Keeping repo after failure: %s" % repo_dir
+ raise
+ else:
os.chdir(prev_cwd)
rw_repo.git.clear_cache()
shutil.rmtree(repo_dir, onerror=_rmtree_onerror)