summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES2
-rw-r--r--TODO2
-rw-r--r--lib/git/repo.py30
-rw-r--r--test/git/test_repo.py22
4 files changed, 32 insertions, 24 deletions
diff --git a/CHANGES b/CHANGES
index 96f476b3..c66930d6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -87,6 +87,8 @@ Repo
of the active branch.
* tree method now requires a Ref instance as input and defaults to the active_branche
instead of master
+* is_dirty now takes additional arguments allowing fine-grained control about what is
+ considered dirty
* Removed the following methods:
- 'log' method as it as effectively the same as the 'commits' method
- 'commits_since' as it is just a flag given to rev-list in Commit.iter_items
diff --git a/TODO b/TODO
index 55c30fb1..685c8646 100644
--- a/TODO
+++ b/TODO
@@ -32,8 +32,6 @@ Index
Repo
----
* Nice fetch/pull handling, at least supported/wired throuhg to the git command
-* is_dirty should be improved to allow options what to diff with:
- working tree|index|head - also it should use raw mode to prevent patch generation
* repo.bare is set according to the path it is initialized with, although it
should be read from the configuration in fact. Check uses of repo.bare.
* Blame: Read the blame format making assumptions about its structure,
diff --git a/lib/git/repo.py b/lib/git/repo.py
index 0f4be1b1..8126bff4 100644
--- a/lib/git/repo.py
+++ b/lib/git/repo.py
@@ -370,23 +370,33 @@ class Repo(object):
alternates = property(_get_alternates, _set_alternates, doc="Retrieve a list of alternates paths or set a list paths to be used as alternates")
@property
- def is_dirty(self):
+ def is_dirty(self, index=True, working_tree=True, untracked_files=False):
"""
- Return the status of the index.
-
Returns
- ``True``, if the index has any uncommitted changes,
- otherwise ``False``
-
- NOTE
- Working tree changes that have not been staged will not be detected !
+ ``True``, the repository is considered dirty. By default it will react
+ like a git-status without untracked files, hence it is dirty if the
+ index or the working copy have changes.
"""
if self.bare:
# Bare repositories with no associated working directory are
# always consired to be clean.
return False
-
- return len(self.git.diff('HEAD', '--').strip()) > 0
+
+ # start from the one which is fastest to evaluate
+ default_args = ('--abbrev=40', '--full-index', '--raw')
+ if index:
+ if len(self.git.diff('HEAD', '--cached', *default_args)):
+ return True
+ # END index handling
+ if working_tree:
+ if len(self.git.diff('HEAD', *default_args)):
+ return True
+ # END working tree handling
+ if untracked_files:
+ if len(self.untracked_files):
+ return True
+ # END untracked files
+ return False
@property
def untracked_files(self):
diff --git a/test/git/test_repo.py b/test/git/test_repo.py
index f9d81c69..7ad68414 100644
--- a/test/git/test_repo.py
+++ b/test/git/test_repo.py
@@ -160,19 +160,17 @@ class TestRepo(TestCase):
self.repo.bare = True
assert_false(self.repo.is_dirty)
- @patch_object(Git, '_call_process')
- def test_is_dirty_with_clean_working_dir(self, git):
- self.repo.bare = False
- git.return_value = ''
- assert_false(self.repo.is_dirty)
- assert_equal(git.call_args, (('diff', 'HEAD', '--'), {}))
-
- @patch_object(Git, '_call_process')
- def test_is_dirty_with_dirty_working_dir(self, git):
+ def test_is_dirty(self):
self.repo.bare = False
- git.return_value = '''-aaa\n+bbb'''
- assert_true(self.repo.is_dirty)
- assert_equal(git.call_args, (('diff', 'HEAD', '--'), {}))
+ for index in (0,1):
+ for working_tree in (0,1):
+ for untracked_files in (0,1):
+ assert self.repo.is_dirty in (True, False)
+ # END untracked files
+ # END working tree
+ # END index
+ self.repo.bare = True
+ assert self.repo.is_dirty == False
@patch_object(Git, '_call_process')
def test_active_branch(self, git):