Skip to content

Commit 0d5bfb5

Browse files
committed
index.reset: updated parameter docs, but most importantly, the method now has better testing for the use of paths during reset. The IndexFile now implements this on its own, which also allows for something equivalent to git-reset --hard -- <paths>, which is not possible in the git command for some probably very good reason
1 parent 1b6b951 commit 0d5bfb5

File tree

2 files changed

+72
-28
lines changed

2 files changed

+72
-28
lines changed

lib/git/index/base.py

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,41 +1061,45 @@ def reset(self, commit='HEAD', working_tree=False, paths=None, head=False, **kwa
10611061
but if True, this method behaves like HEAD.reset.
10621062
10631063
:param paths: if given as an iterable of absolute or repository-relative paths,
1064-
only these will be reset to their state at the given commit'ish
1064+
only these will be reset to their state at the given commit'ish.
1065+
The paths need to exist at the commit, otherwise an exception will be
1066+
raised.
10651067
10661068
:param kwargs:
10671069
Additional keyword arguments passed to git-reset
10681070
10691071
:return: self """
1070-
# currently we have to use the git command to set the working copy.
1071-
# Otherwise we can use our own one
1072-
if working_tree:
1073-
cur_head = self.repo.head
1074-
prev_commit = cur_head.commit
1075-
1076-
cur_head.reset(commit, index=True, working_tree=working_tree, paths=paths, **kwargs)
1077-
1078-
# put the head back, possibly
1079-
if not head:
1080-
self.repo.head.commit = prev_commit
1081-
1082-
self._delete_entries_cache()
1083-
else:
1084-
# what we actually want to do is to merge the tree into our existing
1085-
# index, which is what git-read-tree does
1086-
# TODO: incorporate the given paths !
1087-
new_inst = type(self).from_tree(self.repo, commit)
1072+
# what we actually want to do is to merge the tree into our existing
1073+
# index, which is what git-read-tree does
1074+
new_inst = type(self).from_tree(self.repo, commit)
1075+
if not paths:
10881076
self.entries = new_inst.entries
1089-
self.write()
1090-
1091-
#new_inst = type(self).new(self.repo, self.repo.commit(commit).tree)
1092-
#self.entries = new_inst.entries
1093-
#self.write()
1094-
# self.repo.git.update_index(ignore_missing=True, refresh=True, q=True)
1095-
1096-
if head:
1097-
self.repo.head.commit = self.repo.commit(commit)
1077+
else:
1078+
nie = new_inst.entries
1079+
for path in paths:
1080+
path = self._to_relative_path(path)
1081+
try:
1082+
key = entry_key(path, 0)
1083+
self.entries[key] = nie[key]
1084+
except KeyError:
1085+
# if key is not in theirs, it musn't be in ours
1086+
try:
1087+
del(self.entries[key])
1088+
except KeyError:
1089+
pass
1090+
# END handle deletion keyerror
1091+
# END handle keyerror
1092+
# END for each path
1093+
# END handle paths
1094+
self.write()
1095+
1096+
if working_tree:
1097+
self.checkout(paths=paths, force=True)
10981098
# END handle working tree
1099+
1100+
if head:
1101+
self.repo.head.commit = self.repo.commit(commit)
1102+
# END handle head change
10991103

11001104
return self
11011105

test/git/test_index.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,46 @@ def make_paths():
599599

600600
for filenum in range(len(paths)):
601601
assert index.entry_key(str(filenum), 0) in index.entries
602+
603+
604+
# TEST RESET ON PATHS
605+
######################
606+
arela = "aa"
607+
brela = "bb"
608+
afile = self._make_file(arela, "adata", rw_repo)
609+
bfile = self._make_file(brela, "bdata", rw_repo)
610+
akey = index.entry_key(arela, 0)
611+
bkey = index.entry_key(brela, 0)
612+
keys = (akey, bkey)
613+
absfiles = (afile, bfile)
614+
files = (arela, brela)
615+
616+
for fkey in keys:
617+
assert not fkey in index.entries
618+
619+
index.add(files, write=True)
620+
nc = index.commit("2 files committed", head=False)
621+
622+
for fkey in keys:
623+
assert fkey in index.entries
624+
625+
# just the index
626+
index.reset(paths=(arela, afile))
627+
assert not akey in index.entries
628+
assert bkey in index.entries
629+
630+
# now with working tree - files on disk as well as entries must be recreated
631+
rw_repo.head.commit = nc
632+
for absfile in absfiles:
633+
os.remove(absfile)
634+
635+
index.reset(working_tree=True, paths=files)
636+
637+
for fkey in keys:
638+
assert fkey in index.entries
639+
for absfile in absfiles:
640+
assert os.path.isfile(absfile)
641+
602642

603643
@with_rw_repo('HEAD')
604644
def test_compare_write_tree(self, rw_repo):

0 commit comments

Comments
 (0)