Repository: ishepard/pydriller
Pull request #112 (2020-04-05 19:17:02)

Arguments that enable '--all' and '--remotes' for git rev-list
These changes allow a user of pydriller to pass the 'include_refs' and 'include_remotes' arguments to RepositoryMiner that enable '--all' and '--remotes' in rev-list, respectively.

I found that these tweaks helped me to be more flexible and performant while using this package and I wanted to contribute to help out.

Keep up the good work!


Patch:
diff --git a/pydriller/repository_mining.py b/pydriller/repository_mining.py
index 6556111..b68089a 100644
--- a/pydriller/repository_mining.py
+++ b/pydriller/repository_mining.py
@@ -43,6 +43,8 @@ class RepositoryMining:
                  since: datetime = None, to: datetime = None,
                  from_commit: str = None, to_commit: str = None,
                  from_tag: str = None, to_tag: str = None,
+                 include_refs: bool = False,
+                 include_remotes: bool = False,
                  reversed_order: bool = False,
                  only_in_branch: str = None,
                  only_modifications_with_file_types: List[str] = None,
@@ -77,6 +79,8 @@ class RepositoryMining:
             if `since` and `from_commit` are None)
         :param str to_tag: ending the analysis from specified tag (only if
             `to` and `to_commit` are None)
+        :param bool include_refs: whether to include refs and HEAD in commit analysis
+        :param bool include_remotes: whether to include remote commits in analysis
         :param bool reversed_order: whether the commits should be analyzed
             in reversed order (**DEPRECATED**)
         :param str only_in_branch: only commits in this branch will be analyzed
@@ -96,7 +100,7 @@ class RepositoryMining:
         if only_commits is not None:
             only_commits = set(only_commits)
         if reversed_order:
-            logger.info("'reversed_oder' is deprecated and will be removed in the next release. "
+            logger.info("'reversed_order' is deprecated and will be removed in the next release. "
                         "Use 'order=reverse' instead. ")
             order = 'reverse'
 
@@ -110,6 +114,8 @@ class RepositoryMining:
             "since": since,
             "to": to,
             "single": single,
+            "include_refs": include_refs,
+            "include_remotes": include_remotes,
             "only_in_branch": only_in_branch,
             "only_modifications_with_file_types": only_modifications_with_file_types,
             "only_no_merge": only_no_merge,
diff --git a/pydriller/utils/conf.py b/pydriller/utils/conf.py
index 9ff9441..740c1a5 100644
--- a/pydriller/utils/conf.py
+++ b/pydriller/utils/conf.py
@@ -195,6 +195,8 @@ class Conf:
         until = self.get('to')
         from_commit = self.get('from_commit')
         to_commit = self.get('to_commit')
+        include_refs = self.get('include_refs')
+        remotes = self.get('include_remotes')
         branch = self.get('only_in_branch')
         authors = self.get('only_authors')
         order = self.get('order')
@@ -231,6 +233,12 @@ class Conf:
         elif order == 'topo-order':
             kwargs['topo-order'] = True
 
+        if include_refs is not None:
+            kwargs['all'] = include_refs
+
+        if remotes is not None:
+            kwargs['remotes'] = remotes
+
         if authors is not None:
             kwargs['author'] = authors
 


Test patch:
diff --git a/tests/integration/test_commit_filters.py b/tests/integration/test_commit_filters.py
index be27439..d196c32 100644
--- a/tests/integration/test_commit_filters.py
+++ b/tests/integration/test_commit_filters.py
@@ -15,6 +15,7 @@
 import logging
 from datetime import datetime, timezone, timedelta
 from pydriller.repository_mining import RepositoryMining
+from git import Repo
 
 import pytest
 
@@ -346,4 +347,43 @@ def test_should_visit_descendent_order_with_filters_reversed():
     assert len(lc) == 3
     assert lc[0].hash == '1f99848edadfffa903b8ba1286a935f1b92b2845'
     assert lc[1].hash == '09f6182cef737db02a085e1d018963c7a29bde5a'
-    assert lc[2].hash == '6411e3096dd2070438a17b225f44475136e54e3a'
\ No newline at end of file
+    assert lc[2].hash == '6411e3096dd2070438a17b225f44475136e54e3a'
+
+
+def test_include_refs():
+    commits_no_refs = list(RepositoryMining('test-repos/branches_not_merged/',
+                                            include_refs=False).traverse_commits())
+    assert len(commits_no_refs) == 3
+    commit_no_refs_hashes = [commit.hash for commit in commits_no_refs]
+
+    commits_with_refs = list(RepositoryMining('test-repos/branches_not_merged/',
+                                              include_refs=True).traverse_commits())
+    assert len(commits_with_refs) == 6
+    commit_with_refs_hashes = [commit.hash for commit in commits_with_refs]
+
+    commits_not_in_commits_no_refs = list(set(commit_with_refs_hashes) - set(commit_no_refs_hashes))
+    assert len(commits_not_in_commits_no_refs) == 3
+
+    # First commit on branch b1
+    assert '87a31153090808f1e6f679a14ea28729a0b74f4d' in commits_not_in_commits_no_refs
+    # Commit that branch b1 points to
+    assert '702d469710d2087e662c210fd0e4f9418ec813fd' in commits_not_in_commits_no_refs
+    # Commit that branch b2 points to
+    assert '7203c0b8220dcc7a59614bc7549799cd203ac072' in commits_not_in_commits_no_refs
+
+
+def test_include_remotes():
+    repo = Repo('test-repos/pydriller/')
+
+    # Prove that a recent commit is not in 'test-repos/pydriller'
+    commits_before_fetch = [commit.hash for commit in RepositoryMining('test-repos/pydriller/').traverse_commits()]
+    assert '2fa0d8c57829b086c9372722115a89d11c9bdd35' not in commits_before_fetch
+
+    # Fetch and re-assert that the commit is still not in the repo
+    repo.git.fetch('--all')
+    commits_after_fetch = [commit.hash for commit in RepositoryMining('test-repos/pydriller/').traverse_commits()]
+    assert '2fa0d8c57829b086c9372722115a89d11c9bdd35' not in commits_after_fetch
+
+    # Set include_remotes=True and assert that the commit is now found
+    commits_with_remotes = [commit.hash for commit in RepositoryMining('test-repos/pydriller/', include_remotes=True).traverse_commits()]
+    assert '2fa0d8c57829b086c9372722115a89d11c9bdd35' in commits_with_remotes