summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/git/index/base.py60
-rw-r--r--test/git/test_index.py40
2 files changed, 72 insertions, 28 deletions
diff --git a/lib/git/index/base.py b/lib/git/index/base.py
index a28374b0..05501ba1 100644
--- a/lib/git/index/base.py
+++ b/lib/git/index/base.py
@@ -1061,41 +1061,45 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
but if True, this method behaves like HEAD.reset.
:param paths: if given as an iterable of absolute or repository-relative paths,
- only these will be reset to their state at the given commit'ish
+ only these will be reset to their state at the given commit'ish.
+ The paths need to exist at the commit, otherwise an exception will be
+ raised.
:param kwargs:
Additional keyword arguments passed to git-reset
:return: self """
- # currently we have to use the git command to set the working copy.
- # Otherwise we can use our own one
- if working_tree:
- cur_head = self.repo.head
- prev_commit = cur_head.commit
-
- cur_head.reset(commit, index=True, working_tree=working_tree, paths=paths, **kwargs)
-
- # put the head back, possibly
- if not head:
- self.repo.head.commit = prev_commit
-
- self._delete_entries_cache()
- else:
- # what we actually want to do is to merge the tree into our existing
- # index, which is what git-read-tree does
- # TODO: incorporate the given paths !
- new_inst = type(self).from_tree(self.repo, commit)
+ # what we actually want to do is to merge the tree into our existing
+ # index, which is what git-read-tree does
+ new_inst = type(self).from_tree(self.repo, commit)
+ if not paths:
self.entries = new_inst.entries
- self.write()
-
- #new_inst = type(self).new(self.repo, self.repo.commit(commit).tree)
- #self.entries = new_inst.entries
- #self.write()
- # self.repo.git.update_index(ignore_missing=True, refresh=True, q=True)
-
- if head:
- self.repo.head.commit = self.repo.commit(commit)
+ else:
+ nie = new_inst.entries
+ for path in paths:
+ path = self._to_relative_path(path)
+ try:
+ key = entry_key(path, 0)
+ self.entries[key] = nie[key]
+ except KeyError:
+ # if key is not in theirs, it musn't be in ours
+ try:
+ del(self.entries[key])
+ except KeyError:
+ pass
+ # END handle deletion keyerror
+ # END handle keyerror
+ # END for each path
+ # END handle paths
+ self.write()
+
+ if working_tree:
+ self.checkout(paths=paths, force=True)
# END handle working tree
+
+ if head:
+ self.repo.head.commit = self.repo.commit(commit)
+ # END handle head change
return self
diff --git a/test/git/test_index.py b/test/git/test_index.py
index 29ad2b5c..b5600eeb 100644
--- a/test/git/test_index.py
+++ b/test/git/test_index.py
@@ -599,6 +599,46 @@ class TestIndex(TestBase):
for filenum in range(len(paths)):
assert index.entry_key(str(filenum), 0) in index.entries
+
+
+ # TEST RESET ON PATHS
+ ######################
+ arela = "aa"
+ brela = "bb"
+ afile = self._make_file(arela, "adata", rw_repo)
+ bfile = self._make_file(brela, "bdata", rw_repo)
+ akey = index.entry_key(arela, 0)
+ bkey = index.entry_key(brela, 0)
+ keys = (akey, bkey)
+ absfiles = (afile, bfile)
+ files = (arela, brela)
+
+ for fkey in keys:
+ assert not fkey in index.entries
+
+ index.add(files, write=True)
+ nc = index.commit("2 files committed", head=False)
+
+ for fkey in keys:
+ assert fkey in index.entries
+
+ # just the index
+ index.reset(paths=(arela, afile))
+ assert not akey in index.entries
+ assert bkey in index.entries
+
+ # now with working tree - files on disk as well as entries must be recreated
+ rw_repo.head.commit = nc
+ for absfile in absfiles:
+ os.remove(absfile)
+
+ index.reset(working_tree=True, paths=files)
+
+ for fkey in keys:
+ assert fkey in index.entries
+ for absfile in absfiles:
+ assert os.path.isfile(absfile)
+
@with_rw_repo('HEAD')
def test_compare_write_tree(self, rw_repo):