diff options
-rw-r--r-- | lib/git/index.py | 39 | ||||
-rw-r--r-- | test/git/test_index.py | 39 |
2 files changed, 60 insertions, 18 deletions
diff --git a/lib/git/index.py b/lib/git/index.py index 86bdfd39..89e716d4 100644 --- a/lib/git/index.py +++ b/lib/git/index.py @@ -711,7 +711,7 @@ class IndexFile(LazyMixin, diff.Diffable): return [ p[4:-1] for p in removed_paths ] @default_index - def commit(self, message, parent_commits=None): + def commit(self, message, parent_commits=None, head=True): """ Commit the current index, creating a commit object. @@ -726,6 +726,11 @@ class IndexFile(LazyMixin, diff.Diffable): If None , the current head commit will be the parent of the new commit object + ``head`` + If True, the HEAD will be advanced to the new commit automatically. + Else the HEAD will remain pointing on the previous commit. This could + lead to undesired results when diffing files. + Returns Commit object representing the new commit @@ -752,17 +757,23 @@ class IndexFile(LazyMixin, diff.Diffable): # write the current index as tree tree_sha = self.repo.git.write_tree() commit_sha = self.repo.git.commit_tree(tree_sha, parent_args, istream=fp) - return Commit(self.repo, commit_sha) + new_commit = Commit(self.repo, commit_sha) + + if head: + self.repo.head.commit = new_commit + # END advance head handling + + return new_commit finally: fp.close() os.remove(tmp_file_path) - + @clear_cache @default_index - def reset(self, commit='HEAD', working_tree=False, paths=None, **kwargs): + def reset(self, commit='HEAD', working_tree=False, paths=None, head=False, **kwargs): """ Reset the index to reflect the tree at the given commit. This will not - adjust our HEAD reference as opposed to HEAD.reset. + adjust our HEAD reference as opposed to HEAD.reset by default. ``commit`` Revision, Reference or Commit specifying the commit we should represent. @@ -775,19 +786,27 @@ class IndexFile(LazyMixin, diff.Diffable): Please note that changes to the working copy will be discarded without warning ! + ``head`` + If True, the head will be set to the given commit. This is False by default, + but if True, this method behaves like HEAD.reset. + ``**kwargs`` Additional keyword arguments passed to git-reset Returns self """ - head = self.repo.head - prev_commit = head.commit + cur_head = self.repo.head + prev_commit = cur_head.commit # reset to get the tree/working copy - head.reset(commit, index=True, working_tree=working_tree, paths=paths, **kwargs) - # put the head back - head.reset(prev_commit, index=False, working_tree=False) + cur_head.reset(commit, index=True, working_tree=working_tree, paths=paths, **kwargs) + + # put the head back, possibly + if not head: + cur_head.reset(prev_commit, index=False, working_tree=False) + # END reset head + return self @default_index diff --git a/test/git/test_index.py b/test/git/test_index.py index 0a5f4c35..e25f3d2e 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -191,6 +191,8 @@ class TestTree(TestBase): def test_index_mutation(self, rw_repo): index = rw_repo.index num_entries = len(index.entries) + cur_head = rw_repo.head + # remove all of the files, provide a wild mix of paths, BaseIndexEntries, # IndexEntries def mixed_iterator(): @@ -236,18 +238,39 @@ class TestTree(TestBase): assert len(deleted_files) > 1 self.failUnlessRaises(ValueError, index.remove, ["/doesnt/exists"]) - # test committing + # TEST COMMITTING # commit changed index - cur_commit = rw_repo.head.commit + cur_commit = cur_head.commit commit_message = "commit default head" - new_commit = index.commit(commit_message) + + new_commit = index.commit(commit_message, head=False) assert new_commit.message == commit_message assert new_commit.parents[0] == cur_commit - - self.fail("commit with no parents") - self.fail("commit multiple parents") - + assert len(new_commit.parents) == 1 + assert cur_head.commit == cur_commit + + # same index, no parents + commit_message = "index without parents" + commit_no_parents = index.commit(commit_message, parent_commits=list(), head=True) + assert commit_no_parents.message == commit_message + assert len(commit_no_parents.parents) == 0 + assert cur_head.commit == commit_no_parents + + # same index, multiple parents + commit_message = "Index with multiple parents\n commit with another line" + commit_multi_parent = index.commit(commit_message,parent_commits=(commit_no_parents, new_commit)) + assert commit_multi_parent.message == commit_message + assert len(commit_multi_parent.parents) == 2 + assert commit_multi_parent.parents[0] == commit_no_parents + assert commit_multi_parent.parents[1] == new_commit + assert cur_head.commit == commit_multi_parent # re-add all files in lib - self.fail( "add, commit, working tree handling" ) + # get the lib folder back on disk, but get an index without it + index.reset(new_commit.parents[0], working_tree=True).reset(new_commit, working_tree=False) + lib_file_path = "lib/git/__init__.py" + assert (lib_file_path, 0) not in index.entries + assert os.path.isfile(os.path.join(rw_repo.git.git_dir, lib_file_path)) + + self.fail( "add file using simple path, blob, blob as symlink, entries with stages" ) |