From 45eb6bd22554e5dad2417d185d39fe665b7a7419 Mon Sep 17 00:00:00 2001 From: Thomas Rehn Date: Fri, 2 Jan 2015 15:12:37 +0100 Subject: [PATCH 0001/2790] [IMP] branch names may contain '#' characters --- git/remote.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/remote.py b/git/remote.py index bce11f7d6..a9a74ab69 100644 --- a/git/remote.py +++ b/git/remote.py @@ -202,7 +202,7 @@ class FetchInfo(object): FAST_FORWARD, ERROR = [1 << x for x in range(8)] # %c %-*s %-*s -> %s (%s) - re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.]+\]?)\s+(.+) -> ([/\w_\+\.-]+)( \(.*\)?$)?") + re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.]+\]?)\s+(.+) -> ([/\w_\+\.\-#]+)( \(.*\)?$)?") _flag_map = {'!': ERROR, '+': FORCED_UPDATE, '-': TAG_UPDATE, '*': 0, '=': HEAD_UPTODATE, ' ': FAST_FORWARD} From c9d884511ed2c8e9ca96de04df835aaa6eb973eb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 2 Jan 2015 16:30:48 +0100 Subject: [PATCH 0002/2790] Auto-launching git daemon to make tests more independent Fixes #217 --- git/test/lib/helper.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 55e7ba658..40e34fe05 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -6,7 +6,7 @@ import os import sys -from git import Repo, Remote, GitCommandError +from git import Repo, Remote, GitCommandError, Git from unittest import TestCase import tempfile import shutil @@ -149,6 +149,7 @@ def case(self, rw_repo, rw_remote_repo) This setup allows you to test push and pull scenarios and hooks nicely. See working dir info in with_rw_repo + :note: We attempt to launch our own invocation of git-daemon, which will be shutdown at the end of the test. """ assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout" @@ -186,17 +187,30 @@ def remote_repo_creator(self): d_remote.config_writer.set('url', remote_repo_url) + temp_dir = os.path.dirname(_mktemp()) + # On windows, this will fail ... we deal with failures anyway and default to telling the user to do it + try: + gd = Git().daemon(temp_dir, as_process=True) + except Exception as err: + gd = None + # end + # try to list remotes to diagnoes whether the server is up try: rw_repo.git.ls_remote(d_remote) except GitCommandError, e: + # We assume in good faith that we didn't start the daemon - but make sure we kill it anyway + # Of course we expect it to work here already, but maybe there are timing constraints + # on some platforms ? + if gd is not None: + os.kill(gd.proc.pid, 15) print str(e) if os.name == 'nt': raise AssertionError( - 'git-daemon needs to run this test, but windows does not have one. Otherwise, run: git-daemon "%s"' % os.path.dirname(_mktemp())) + 'git-daemon needs to run this test, but windows does not have one. Otherwise, run: git-daemon "%s"' % temp_dir) else: raise AssertionError( - 'Please start a git-daemon to run this test, execute: git-daemon "%s"' % os.path.dirname(_mktemp())) + 'Please start a git-daemon to run this test, execute: git-daemon "%s"' % temp_dir) # END make assertion # END catch ls remote error @@ -206,11 +220,16 @@ def remote_repo_creator(self): try: return func(self, rw_repo, rw_remote_repo) finally: + # gd.proc.kill() ... no idea why that doesn't work + os.kill(gd.proc.pid, 15) + os.chdir(prev_cwd) rw_repo.git.clear_cache() rw_remote_repo.git.clear_cache() shutil.rmtree(repo_dir, onerror=_rmtree_onerror) shutil.rmtree(remote_repo_dir, onerror=_rmtree_onerror) + + gd.proc.wait() # END cleanup # END bare repo creator remote_repo_creator.__name__ = func.__name__ From de9a6bb0c8931e7f74ea35edb372e5ca7d0a5047 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 3 Jan 2015 14:34:39 +0100 Subject: [PATCH 0003/2790] Various fixes and improvements * GIT_PYTHON_TRACE now behaves correctly for fetch, and pull (i.e. if as_process is used) * Improved parsing of fetch head information However, there is still a messy bit that tries to bring together fetch progress information with fetch head information. Even though it works now, an alternative implementation should be attempted. --- .travis.yml | 9 +++-- git/cmd.py | 2 +- git/remote.py | 82 ++++++++++++++++++++++++++--------------- git/test/test_remote.py | 13 ++++--- 4 files changed, 66 insertions(+), 40 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0a2906dc2..dfeaad545 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,15 @@ python: - "2.6" - "2.7" # - "pypy" - won't work as smmap doesn't work (see gitdb/.travis.yml for details) - +git: + # a higher depth is needed for most of the tests - must be high enough to not actually be shallow + # as we clone our own repository in the process + depth: 99999 install: - git submodule update --init --recursive - git fetch --tags - pip install coveralls script: - - nosetests --with-coverage -# after_success: as long as we are not running smoothly ... give it the cover treatment every time + - nosetests -v --with-coverage +after_success: - coveralls diff --git a/git/cmd.py b/git/cmd.py index f4d23002d..bfdefb17f 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -333,7 +333,7 @@ def execute(self, command, :note: If you add additional keyword arguments to the signature of this method, you must update the execute_kwargs tuple housed in this module.""" - if self.GIT_PYTHON_TRACE and not self.GIT_PYTHON_TRACE == 'full': + if self.GIT_PYTHON_TRACE and (self.GIT_PYTHON_TRACE != 'full' or as_process): print ' '.join(command) # Allow the user to have the command executed in their working dir. diff --git a/git/remote.py b/git/remote.py index a9a74ab69..0cd1e2af5 100644 --- a/git/remote.py +++ b/git/remote.py @@ -204,8 +204,12 @@ class FetchInfo(object): # %c %-*s %-*s -> %s (%s) re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.]+\]?)\s+(.+) -> ([/\w_\+\.\-#]+)( \(.*\)?$)?") - _flag_map = {'!': ERROR, '+': FORCED_UPDATE, '-': TAG_UPDATE, '*': 0, - '=': HEAD_UPTODATE, ' ': FAST_FORWARD} + _flag_map = {'!': ERROR, + '+': FORCED_UPDATE, + '-': TAG_UPDATE, + '*': 0, + '=': HEAD_UPTODATE, + ' ': FAST_FORWARD} def __init__(self, ref, flags, note='', old_commit=None): """ @@ -259,6 +263,34 @@ def _from_line(cls, repo, line, fetch_line): except ValueError: # unpack error raise ValueError("Failed to parse FETCH__HEAD line: %r" % fetch_line) + # parse flags from control_character + flags = 0 + try: + flags |= cls._flag_map[control_character] + except KeyError: + raise ValueError("Control character %r unknown as parsed from line %r" % (control_character, line)) + # END control char exception hanlding + + # parse operation string for more info - makes no sense for symbolic refs, but we parse it anyway + old_commit = None + is_tag_operation = False + if 'rejected' in operation: + flags |= cls.REJECTED + if 'new tag' in operation: + flags |= cls.NEW_TAG + is_tag_operation = True + if 'tag update' in operation: + flags |= cls.TAG_UPDATE + is_tag_operation = True + if 'new branch' in operation: + flags |= cls.NEW_HEAD + if '...' in operation or '..' in operation: + split_token = '...' + if control_character == ' ': + split_token = split_token[:-1] + old_commit = repo.rev_parse(operation.split(split_token)[0]) + # END handle refspec + # handle FETCH_HEAD and figure out ref type # If we do not specify a target branch like master:refs/remotes/origin/master, # the fetch result is stored in FETCH_HEAD which destroys the rule we usually @@ -266,12 +298,12 @@ def _from_line(cls, repo, line, fetch_line): ref_type = None if remote_local_ref == "FETCH_HEAD": ref_type = SymbolicReference + elif ref_type_name == "tag" or is_tag_operation: + ref_type = TagReference elif ref_type_name in ("remote-tracking", "branch"): # note: remote-tracking is just the first part of the 'remote-tracking branch' token. # We don't parse it correctly, but its enough to know what to do, and its new in git 1.7something ref_type = RemoteReference - elif ref_type_name == "tag": - ref_type = TagReference else: raise TypeError("Cannot handle reference type: %r" % ref_type_name) # END handle ref type @@ -308,31 +340,6 @@ def _from_line(cls, repo, line, fetch_line): note = (note and note.strip()) or '' - # parse flags from control_character - flags = 0 - try: - flags |= cls._flag_map[control_character] - except KeyError: - raise ValueError("Control character %r unknown as parsed from line %r" % (control_character, line)) - # END control char exception hanlding - - # parse operation string for more info - makes no sense for symbolic refs - old_commit = None - if isinstance(remote_local_ref, Reference): - if 'rejected' in operation: - flags |= cls.REJECTED - if 'new tag' in operation: - flags |= cls.NEW_TAG - if 'new branch' in operation: - flags |= cls.NEW_HEAD - if '...' in operation or '..' in operation: - split_token = '...' - if control_character == ' ': - split_token = split_token[:-1] - old_commit = repo.rev_parse(operation.split(split_token)[0]) - # END handle refspec - # END reference flag handling - return cls(remote_local_ref, flags, note, old_commit) @@ -513,9 +520,17 @@ def _get_fetch_info_from_stderr(self, proc, progress): # this also waits for the command to finish # Skip some progress lines that don't provide relevant information fetch_info_lines = list() + # fetches all for later in case we don't get any ... this handling is a bit fishy as + # the underlying logic of git is not properly understood. This fix merely helps a test-case, and probably + # won't be too wrong otherwise. + fetch_info_lines_reserve = list() for line in digest_process_messages(proc.stderr, progress): + # cc, _, _ = line.split('\t', 3) if line.startswith('From') or line.startswith('remote: Total') or line.startswith('POST') \ or line.startswith(' ='): + # Why do we even skip lines that begin with a = ? + if line.startswith(' ='): + fetch_info_lines_reserve.append(line) continue elif line.startswith('warning:'): print >> sys.stderr, line @@ -536,9 +551,15 @@ def _get_fetch_info_from_stderr(self, proc, progress): # This project needs a lot of work ! # assert len(fetch_info_lines) == len(fetch_head_info), "len(%s) != len(%s)" % (fetch_head_info, fetch_info_lines) + # EVIL HACK: This basically fixes our test-case, and possibly helps better results to be returned in future + # The actual question is why we are unable to properly parse progress messages and sync them to the + # respective fetch-head information ... . + if len(fetch_info_lines) != len(fetch_head_info) and len(fetch_info_lines_reserve) == len(fetch_head_info): + fetch_info_lines = fetch_info_lines_reserve + # end + output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info)) - finalize_process(proc) return output @@ -594,6 +615,7 @@ def fetch(self, refspec=None, progress=None, **kwargs): args = refspec else: args = [refspec] + proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, v=True, **kwargs) return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 254ad9234..c9329f257 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -200,9 +200,10 @@ def get_info(res, remote, name): res = fetch_and_test(remote, refspec='master') assert len(res) == 1 - # ... multiple refspecs - res = fetch_and_test(remote, refspec=['master', 'fred']) - assert len(res) == 1 + # ... multiple refspecs ... works, but git command returns with error if one ref is wrong without + # doing anything. This is new in later binaries + # res = fetch_and_test(remote, refspec=['master', 'fred']) + # assert len(res) == 1 # add new tag reference rtag = TagReference.create(remote_repo, "1.0-RV_hello.there") @@ -447,13 +448,13 @@ def test_creation_and_removal(self, bare_rw_repo): def test_fetch_info(self): # assure we can handle remote-tracking branches - fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of git://github.com/gitpython-developers/GitPython" + fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of git://github.com/gitpython-developers/GitPython" remote_info_line_fmt = "* [new branch] nomatter -> %s" fi = FetchInfo._from_line(self.rorepo, remote_info_line_fmt % "local/master", fetch_info_line_fmt % 'remote-tracking branch') - assert fi.ref.is_valid() - assert fi.ref.commit + assert not fi.ref.is_valid() + assert fi.ref.name == "local/master" # handles non-default refspecs: One can specify a different path in refs/remotes # or a special path just in refs/something for instance From 863a40e0d35f3ff3c3e4b5dc9ff1272e1b1783b1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 3 Jan 2015 15:12:03 +0100 Subject: [PATCH 0004/2790] Reduced hackyness of remote reference parsing. This could however, introduce a chance of an assertion hitting once again as it has been commented out for quite a long time. Now it's back in a changed form though, and once again tries to make sure we get proper results --- doc/source/changes.rst | 4 ++++ git/remote.py | 52 ++++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 4238e5f5a..1c34e6293 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,10 @@ Changelog ========= +0.3.3 +===== +* When fetching, pulling or pushing, and an error occours, it will not be reported on stdout anymore. However, if there is a fatal error, it will still result in a GitCommandError to be thrown. This goes hand in hand with improved fetch result parsing. + 0.3.2.1 ======= * `Fix for #207 `_ diff --git a/git/remote.py b/git/remote.py index 0cd1e2af5..bf0a0021f 100644 --- a/git/remote.py +++ b/git/remote.py @@ -100,9 +100,13 @@ class PushInfo(object): NEW_TAG, NEW_HEAD, NO_MATCH, REJECTED, REMOTE_REJECTED, REMOTE_FAILURE, DELETED, \ FORCED_UPDATE, FAST_FORWARD, UP_TO_DATE, ERROR = [1 << x for x in range(11)] - _flag_map = {'X': NO_MATCH, '-': DELETED, '*': 0, - '+': FORCED_UPDATE, ' ': FAST_FORWARD, - '=': UP_TO_DATE, '!': ERROR} + _flag_map = {'X': NO_MATCH, + '-': DELETED, + '*': 0, + '+': FORCED_UPDATE, + ' ': FAST_FORWARD, + '=': UP_TO_DATE, + '!': ERROR} def __init__(self, flags, local_ref, remote_ref_string, remote, old_commit=None, summary=''): @@ -299,6 +303,8 @@ def _from_line(cls, repo, line, fetch_line): if remote_local_ref == "FETCH_HEAD": ref_type = SymbolicReference elif ref_type_name == "tag" or is_tag_operation: + # the ref_type_name can be branch, whereas we are still seeing a tag operation. It happens during + # testing, which is based on actual git operations ref_type = TagReference elif ref_type_name in ("remote-tracking", "branch"): # note: remote-tracking is just the first part of the 'remote-tracking branch' token. @@ -520,25 +526,19 @@ def _get_fetch_info_from_stderr(self, proc, progress): # this also waits for the command to finish # Skip some progress lines that don't provide relevant information fetch_info_lines = list() - # fetches all for later in case we don't get any ... this handling is a bit fishy as - # the underlying logic of git is not properly understood. This fix merely helps a test-case, and probably - # won't be too wrong otherwise. - fetch_info_lines_reserve = list() + # Basically we want all fetch info lines which appear to be in regular form, and thus have a + # command character. Everything else we ignore, + cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys()) for line in digest_process_messages(proc.stderr, progress): - # cc, _, _ = line.split('\t', 3) - if line.startswith('From') or line.startswith('remote: Total') or line.startswith('POST') \ - or line.startswith(' ='): - # Why do we even skip lines that begin with a = ? - if line.startswith(' ='): - fetch_info_lines_reserve.append(line) - continue - elif line.startswith('warning:'): - print >> sys.stderr, line - continue - elif line.startswith('fatal:'): + if line.startswith('fatal:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) # END handle special messages - fetch_info_lines.append(line) + for cmd in cmds: + if line[1] == cmd: + fetch_info_lines.append(line) + continue + # end find command code + # end for each comand code we know # END for each line # read head information @@ -546,17 +546,9 @@ def _get_fetch_info_from_stderr(self, proc, progress): fetch_head_info = fp.readlines() fp.close() - # NOTE: HACK Just disabling this line will make github repositories work much better. - # I simply couldn't stand it anymore, so here is the quick and dirty fix ... . - # This project needs a lot of work ! - # assert len(fetch_info_lines) == len(fetch_head_info), "len(%s) != len(%s)" % (fetch_head_info, fetch_info_lines) - - # EVIL HACK: This basically fixes our test-case, and possibly helps better results to be returned in future - # The actual question is why we are unable to properly parse progress messages and sync them to the - # respective fetch-head information ... . - if len(fetch_info_lines) != len(fetch_head_info) and len(fetch_info_lines_reserve) == len(fetch_head_info): - fetch_info_lines = fetch_info_lines_reserve - # end + # NOTE: We assume to fetch at least enough progress lines to allow matching each fetch head line with it. + assert len(fetch_info_lines) >= len(fetch_head_info), "len(%s) <= len(%s)" % (fetch_head_info, + fetch_info_lines) output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info)) From 342a0276dbf11366ae91ce28dcceddc332c97eaf Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 3 Jan 2015 19:48:05 +0100 Subject: [PATCH 0005/2790] Fixed all remaining non-performance tests * travis configuration adjusted to hopefully work better than before Performance traversal still fails when using git-python as standard repository. It naturally wants a larger one. On travis these tests are skipped though. --- .travis.yml | 12 +++++++ git/test/performance/__init__.py | 1 + git/test/performance/lib.py | 49 +++++++++++++--------------- git/test/performance/test_commit.py | 6 +++- git/test/performance/test_odb.py | 3 +- git/test/performance/test_streams.py | 3 +- git/test/performance/test_utils.py | 8 ++++- git/test/test_index.py | 10 ++++-- git/test/test_repo.py | 14 ++++---- git/test/test_submodule.py | 3 ++ 10 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 git/test/performance/__init__.py diff --git a/.travis.yml b/.travis.yml index dfeaad545..928429416 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,18 @@ install: - git submodule update --init --recursive - git fetch --tags - pip install coveralls + # for now we have to make sure there is a master branch - at some point we should just have it by default + - git branch master 0.3 + # generate some reflog as git-python tests need it + - git reset --hard HEAD~1 + - git reset --hard HEAD~1 + - git reset --hard HEAD~1 + - git reset --hard origin/0.3 + - git checkout master + - git reset --hard HEAD~1 + - git reset --hard HEAD~1 + - git reset --hard origin/0.3 + - git checkout 0.3 script: - nosetests -v --with-coverage after_success: diff --git a/git/test/performance/__init__.py b/git/test/performance/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/git/test/performance/__init__.py @@ -0,0 +1 @@ + diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index 6beff6171..985e36379 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -3,6 +3,7 @@ from git.test.lib import * import shutil import tempfile +import logging from git.db import ( GitCmdObjectDB, @@ -18,18 +19,6 @@ #} END invariants -#{ Utilities -def resolve_or_fail(env_var): - """:return: resolved environment variable or raise EnvironmentError""" - try: - return os.environ[env_var] - except KeyError: - raise EnvironmentError("Please set the %r envrionment variable and retry" % env_var) - # END exception handling - -#} END utilities - - #{ Base Classes class TestBigRepoR(TestBase): @@ -51,12 +40,19 @@ class TestBigRepoR(TestBase): head_sha_50 = '32347c375250fd470973a5d76185cac718955fd5' #} END invariants - @classmethod - def setUp(cls): - super(TestBigRepoR, cls).setUp() - repo_path = resolve_or_fail(k_env_git_repo) - cls.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB) - cls.puregitrorepo = Repo(repo_path, odbt=GitDB) + def setUp(self): + try: + super(TestBigRepoR, self).setUp() + except AttributeError: + pass + + repo_path = os.environ.get(k_env_git_repo) + if repo_path is None: + logging.info("You can set the %s environment variable to a .git repository of your choice - defaulting to the gitpython repository", k_env_git_repo) + repo_path = os.path.dirname(__file__) + # end set some repo path + self.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB) + self.puregitrorepo = Repo(repo_path, odbt=GitDB) class TestBigRepoRW(TestBigRepoR): @@ -65,16 +61,17 @@ class TestBigRepoRW(TestBigRepoR): Provides ``self.gitrwrepo`` and ``self.puregitrwrepo``""" - @classmethod - def setUp(cls): - super(TestBigRepoRW, cls).setUp() + def setUp(self): + try: + super(TestBigRepoRW, self).setUp() + except AttributeError: + pass dirname = tempfile.mktemp() os.mkdir(dirname) - cls.gitrwrepo = cls.gitrorepo.clone(dirname, shared=True, bare=True, odbt=GitCmdObjectDB) - cls.puregitrwrepo = Repo(dirname, odbt=GitDB) + self.gitrwrepo = self.gitrorepo.clone(dirname, shared=True, bare=True, odbt=GitCmdObjectDB) + self.puregitrwrepo = Repo(dirname, odbt=GitDB) - @classmethod - def tearDownAll(cls): - shutil.rmtree(cls.gitrwrepo.working_dir) + def tearDown(self): + shutil.rmtree(self.gitrwrepo.working_dir) #} END base classes diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index c988d1605..a8f63f954 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -8,6 +8,7 @@ from git import * from gitdb import IStream from git.test.test_commit import assert_commit_serialization +from gitdb.test.lib import skip_on_travis_ci from cStringIO import StringIO from time import time import sys @@ -28,6 +29,7 @@ def _query_commit_info(self, c): c.message c.parents + @skip_on_travis_ci def test_iteration(self): no = 0 nc = 0 @@ -49,6 +51,7 @@ def test_iteration(self): print >> sys.stderr, "Traversed %i Trees and a total of %i unchached objects in %s [s] ( %f objs/s )" % ( nc, no, elapsed_time, no / elapsed_time) + @skip_on_travis_ci def test_commit_traversal(self): # bound to cat-file parsing performance nc = 0 @@ -60,6 +63,7 @@ def test_commit_traversal(self): elapsed_time = time() - st print >> sys.stderr, "Traversed %i Commits in %s [s] ( %f commits/s )" % (nc, elapsed_time, nc / elapsed_time) + @skip_on_travis_ci def test_commit_iteration(self): # bound to stream parsing performance nc = 0 @@ -71,6 +75,7 @@ def test_commit_iteration(self): elapsed_time = time() - st print >> sys.stderr, "Iterated %i Commits in %s [s] ( %f commits/s )" % (nc, elapsed_time, nc / elapsed_time) + @skip_on_travis_ci def test_commit_serialization(self): assert_commit_serialization(self.gitrwrepo, self.head_sha_2k, True) @@ -80,7 +85,6 @@ def test_commit_serialization(self): # serialization is probably limited on IO hc = rwrepo.commit(self.head_sha_2k) - commits = list() nc = 5000 st = time() for i in xrange(nc): diff --git a/git/test/performance/test_odb.py b/git/test/performance/test_odb.py index 6696e4595..1c4bd9ed4 100644 --- a/git/test/performance/test_odb.py +++ b/git/test/performance/test_odb.py @@ -2,7 +2,7 @@ from time import time import sys -import stat +from gitdb.test.lib import skip_on_travis_ci from lib import ( TestBigRepoR @@ -11,6 +11,7 @@ class TestObjDBPerformance(TestBigRepoR): + @skip_on_travis_ci def test_random_access(self): results = [["Iterate Commits"], ["Iterate Blobs"], ["Retrieve Blob Data"]] for repo in (self.gitrorepo, self.puregitrorepo): diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index 7800144d9..a2bca94c7 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -3,11 +3,11 @@ from git.test.lib import * from gitdb import * from gitdb.util import bin_to_hex +from gitdb.test.lib import skip_on_travis_ci from time import time import os import sys -import stat import subprocess from gitdb.test.lib import make_memory_file @@ -22,6 +22,7 @@ class TestObjDBPerformance(TestBigRepoR): large_data_size_bytes = 1000 * 1000 * 10 # some MiB should do it moderate_data_size_bytes = 1000 * 1000 * 1 # just 1 MiB + @skip_on_travis_ci @with_rw_repo('HEAD', bare=True) def test_large_data_streaming(self, rwrepo): # TODO: This part overlaps with the same file in gitdb.test.performance.test_stream diff --git a/git/test/performance/test_utils.py b/git/test/performance/test_utils.py index 7db972f79..b0d6fa48e 100644 --- a/git/test/performance/test_utils.py +++ b/git/test/performance/test_utils.py @@ -1,7 +1,8 @@ """Performance of utilities""" from time import time import sys -import stat + +from gitdb.test.lib import skip_on_travis_ci from lib import ( TestBigRepoR @@ -10,6 +11,7 @@ class TestUtilPerformance(TestBigRepoR): + @skip_on_travis_ci def test_access(self): # compare dict vs. slot access class Slotty(object): @@ -64,6 +66,7 @@ def __init__(self): cls.__name__, na, elapsed, na / elapsed) # END for each sequence + @skip_on_travis_ci def test_instantiation(self): ni = 100000 max_num_items = 4 @@ -106,6 +109,7 @@ def test_instantiation(self): elapsed = time() - st print >> sys.stderr, "Created %i tuples tuple((1,2,3,4)) in %f s ( %f tuples / s)" % (ni, elapsed, ni / elapsed) + @skip_on_travis_ci def test_unpacking_vs_indexing(self): ni = 1000000 list_items = [1, 2, 3, 4] @@ -137,6 +141,7 @@ def test_unpacking_vs_indexing(self): ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed) # END for each sequence + @skip_on_travis_ci def test_large_list_vs_iteration(self): # what costs more: alloc/realloc of lists, or the cpu strain of iterators ? def slow_iter(ni): @@ -161,6 +166,7 @@ def slow_iter(ni): print >> sys.stderr, "Iterated %i items from iterator in %f s ( %f acc / s)" % (ni, elapsed, ni / elapsed) # END for each number of iterations + @skip_on_travis_ci def test_type_vs_inst_class(self): class NewType(object): pass diff --git a/git/test/test_index.py b/git/test/test_index.py index c1153e5e2..5431df44e 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -6,6 +6,7 @@ from git.test.lib import * from git import * +from gitdb.util import hex_to_bin import inspect import os import sys @@ -17,7 +18,10 @@ from StringIO import StringIO from gitdb.base import IStream from git.objects import Blob -from git.index.typ import BaseIndexEntry +from git.index.typ import ( + BaseIndexEntry, + IndexEntry +) class TestIndex(TestBase): @@ -211,6 +215,8 @@ def test_index_merge_tree(self, rw_repo): # self.failUnlessRaises(GitCommandError, index.write_tree) # if missing objects are okay, this would work though ( they are always okay now ) + # As we can't read back the tree with NULL_SHA, we rather set it to something else + index.entries[manifest_key] = IndexEntry(manifest_entry[:1] + (hex_to_bin('f'*40),) + manifest_entry[2:]) tree = index.write_tree() # now make a proper three way merge with unmerged entries @@ -322,7 +328,7 @@ def test_index_file_diffing(self, rw_repo): fp.close() try: index.checkout(test_file) - except CheckoutError, e: + except CheckoutError as e: assert len(e.failed_files) == 1 and e.failed_files[0] == os.path.basename(test_file) assert (len(e.failed_files) == len(e.failed_reasons)) and isinstance(e.failed_reasons[0], basestring) assert len(e.valid_files) == 0 diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 2cef40819..328995a2c 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -34,12 +34,13 @@ def test_new_should_raise_on_invalid_repo_location(self): def test_new_should_raise_on_non_existant_path(self): Repo("repos/foobar") - def test_repo_creation_from_different_paths(self): - r_from_gitdir = Repo(self.rorepo.git_dir) - assert r_from_gitdir.git_dir == self.rorepo.git_dir + @with_rw_repo('0.3.2.1') + def test_repo_creation_from_different_paths(self, rw_repo): + r_from_gitdir = Repo(rw_repo.git_dir) + assert r_from_gitdir.git_dir == rw_repo.git_dir assert r_from_gitdir.git_dir.endswith('.git') - assert not self.rorepo.git.working_dir.endswith('.git') - assert r_from_gitdir.git.working_dir == self.rorepo.git.working_dir + assert not rw_repo.git.working_dir.endswith('.git') + assert r_from_gitdir.git.working_dir == rw_repo.git.working_dir def test_description(self): txt = "Test repository" @@ -210,8 +211,7 @@ def test_alternates(self): self.rorepo.alternates = cur_alternates def test_repr(self): - path = os.path.join(os.path.abspath(GIT_REPO), '.git') - assert_equal('' % path, repr(self.rorepo)) + assert repr(self.rorepo).startswith(' Date: Sat, 3 Jan 2015 20:25:01 +0100 Subject: [PATCH 0006/2790] Auto-skip performance tests more quietly on travis ... and be able to run performance tests independently of the chosen performance test repo Now all tests run fine locally --- .travis.yml | 7 +++++++ git/test/lib/helper.py | 3 +++ git/test/performance/lib.py | 10 ++++++---- git/test/performance/test_commit.py | 13 ++++--------- git/test/performance/test_odb.py | 4 +--- git/test/performance/test_streams.py | 2 -- git/test/performance/test_utils.py | 7 ------- 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index 928429416..7a21ad945 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,10 @@ install: - git submodule update --init --recursive - git fetch --tags - pip install coveralls + # for now we have to make sure there is a master branch - at some point we should just have it by default - git branch master 0.3 + # generate some reflog as git-python tests need it - git reset --hard HEAD~1 - git reset --hard HEAD~1 @@ -21,8 +23,13 @@ install: - git checkout master - git reset --hard HEAD~1 - git reset --hard HEAD~1 + - git reset --hard HEAD~1 - git reset --hard origin/0.3 - git checkout 0.3 + + # as commits are performed with the default user, it needs to be set for travis too + - git config --global user.email "travis@ci.com" + - git config --global user.name "Travis Runner" script: - nosetests -v --with-coverage after_success: diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 40e34fe05..df94abde6 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -8,6 +8,7 @@ import sys from git import Repo, Remote, GitCommandError, Git from unittest import TestCase +import time import tempfile import shutil import cStringIO @@ -191,6 +192,8 @@ def remote_repo_creator(self): # On windows, this will fail ... we deal with failures anyway and default to telling the user to do it try: gd = Git().daemon(temp_dir, as_process=True) + # yes, I know ... fortunately, this is always going to work if sleep time is just large enough + time.sleep(0.5) except Exception as err: gd = None # end diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index 985e36379..9b6f45bfb 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -1,6 +1,7 @@ """Contains library functions""" import os from git.test.lib import * +from gitdb.test.lib import skip_on_travis_ci import shutil import tempfile import logging @@ -36,11 +37,11 @@ class TestBigRepoR(TestBase): """ #{ Invariants - head_sha_2k = '235d521da60e4699e5bd59ac658b5b48bd76ddca' - head_sha_50 = '32347c375250fd470973a5d76185cac718955fd5' #} END invariants def setUp(self): + # This will raise on travis, which is what we want to happen early as to prevent us to do any work + skip_on_travis_ci(lambda *args: None)(self) try: super(TestBigRepoR, self).setUp() except AttributeError: @@ -54,7 +55,6 @@ def setUp(self): self.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB) self.puregitrorepo = Repo(repo_path, odbt=GitDB) - class TestBigRepoRW(TestBigRepoR): """As above, but provides a big repository that we can write to. @@ -62,6 +62,7 @@ class TestBigRepoRW(TestBigRepoR): Provides ``self.gitrwrepo`` and ``self.puregitrwrepo``""" def setUp(self): + self.gitrwrepo = None try: super(TestBigRepoRW, self).setUp() except AttributeError: @@ -72,6 +73,7 @@ def setUp(self): self.puregitrwrepo = Repo(dirname, odbt=GitDB) def tearDown(self): - shutil.rmtree(self.gitrwrepo.working_dir) + if self.gitrwrepo is not None: + shutil.rmtree(self.gitrwrepo.working_dir) #} END base classes diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index a8f63f954..c256a75c2 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -8,7 +8,6 @@ from git import * from gitdb import IStream from git.test.test_commit import assert_commit_serialization -from gitdb.test.lib import skip_on_travis_ci from cStringIO import StringIO from time import time import sys @@ -29,7 +28,6 @@ def _query_commit_info(self, c): c.message c.parents - @skip_on_travis_ci def test_iteration(self): no = 0 nc = 0 @@ -51,39 +49,36 @@ def test_iteration(self): print >> sys.stderr, "Traversed %i Trees and a total of %i unchached objects in %s [s] ( %f objs/s )" % ( nc, no, elapsed_time, no / elapsed_time) - @skip_on_travis_ci def test_commit_traversal(self): # bound to cat-file parsing performance nc = 0 st = time() - for c in self.gitrorepo.commit(self.head_sha_2k).traverse(branch_first=False): + for c in self.gitrorepo.commit().traverse(branch_first=False): nc += 1 self._query_commit_info(c) # END for each traversed commit elapsed_time = time() - st print >> sys.stderr, "Traversed %i Commits in %s [s] ( %f commits/s )" % (nc, elapsed_time, nc / elapsed_time) - @skip_on_travis_ci def test_commit_iteration(self): # bound to stream parsing performance nc = 0 st = time() - for c in Commit.iter_items(self.gitrorepo, self.head_sha_2k): + for c in Commit.iter_items(self.gitrorepo, self.gitrorepo.head): nc += 1 self._query_commit_info(c) # END for each traversed commit elapsed_time = time() - st print >> sys.stderr, "Iterated %i Commits in %s [s] ( %f commits/s )" % (nc, elapsed_time, nc / elapsed_time) - @skip_on_travis_ci def test_commit_serialization(self): - assert_commit_serialization(self.gitrwrepo, self.head_sha_2k, True) + assert_commit_serialization(self.gitrwrepo, self.gitrwrepo.head, True) rwrepo = self.gitrwrepo make_object = rwrepo.odb.store # direct serialization - deserialization can be tested afterwards # serialization is probably limited on IO - hc = rwrepo.commit(self.head_sha_2k) + hc = rwrepo.commit(rwrepo.head) nc = 5000 st = time() diff --git a/git/test/performance/test_odb.py b/git/test/performance/test_odb.py index 1c4bd9ed4..9d8572605 100644 --- a/git/test/performance/test_odb.py +++ b/git/test/performance/test_odb.py @@ -2,7 +2,6 @@ from time import time import sys -from gitdb.test.lib import skip_on_travis_ci from lib import ( TestBigRepoR @@ -11,13 +10,12 @@ class TestObjDBPerformance(TestBigRepoR): - @skip_on_travis_ci def test_random_access(self): results = [["Iterate Commits"], ["Iterate Blobs"], ["Retrieve Blob Data"]] for repo in (self.gitrorepo, self.puregitrorepo): # GET COMMITS st = time() - root_commit = repo.commit(self.head_sha_2k) + root_commit = repo.commit(repo.head) commits = list(root_commit.traverse()) nc = len(commits) elapsed = time() - st diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index a2bca94c7..facf9eed5 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -3,7 +3,6 @@ from git.test.lib import * from gitdb import * from gitdb.util import bin_to_hex -from gitdb.test.lib import skip_on_travis_ci from time import time import os @@ -22,7 +21,6 @@ class TestObjDBPerformance(TestBigRepoR): large_data_size_bytes = 1000 * 1000 * 10 # some MiB should do it moderate_data_size_bytes = 1000 * 1000 * 1 # just 1 MiB - @skip_on_travis_ci @with_rw_repo('HEAD', bare=True) def test_large_data_streaming(self, rwrepo): # TODO: This part overlaps with the same file in gitdb.test.performance.test_stream diff --git a/git/test/performance/test_utils.py b/git/test/performance/test_utils.py index b0d6fa48e..e7c33aa22 100644 --- a/git/test/performance/test_utils.py +++ b/git/test/performance/test_utils.py @@ -2,8 +2,6 @@ from time import time import sys -from gitdb.test.lib import skip_on_travis_ci - from lib import ( TestBigRepoR ) @@ -11,7 +9,6 @@ class TestUtilPerformance(TestBigRepoR): - @skip_on_travis_ci def test_access(self): # compare dict vs. slot access class Slotty(object): @@ -66,7 +63,6 @@ def __init__(self): cls.__name__, na, elapsed, na / elapsed) # END for each sequence - @skip_on_travis_ci def test_instantiation(self): ni = 100000 max_num_items = 4 @@ -109,7 +105,6 @@ def test_instantiation(self): elapsed = time() - st print >> sys.stderr, "Created %i tuples tuple((1,2,3,4)) in %f s ( %f tuples / s)" % (ni, elapsed, ni / elapsed) - @skip_on_travis_ci def test_unpacking_vs_indexing(self): ni = 1000000 list_items = [1, 2, 3, 4] @@ -141,7 +136,6 @@ def test_unpacking_vs_indexing(self): ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed) # END for each sequence - @skip_on_travis_ci def test_large_list_vs_iteration(self): # what costs more: alloc/realloc of lists, or the cpu strain of iterators ? def slow_iter(ni): @@ -166,7 +160,6 @@ def slow_iter(ni): print >> sys.stderr, "Iterated %i items from iterator in %f s ( %f acc / s)" % (ni, elapsed, ni / elapsed) # END for each number of iterations - @skip_on_travis_ci def test_type_vs_inst_class(self): class NewType(object): pass From db828cdfef651dd25867382d9dc5ac4c4f7f1de3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 3 Jan 2015 20:58:46 +0100 Subject: [PATCH 0007/2790] This should help getting travis to work, finally --- .travis.yml | 4 ++++ git/test/test_git.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7a21ad945..3b0f12e7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,10 @@ install: # as commits are performed with the default user, it needs to be set for travis too - git config --global user.email "travis@ci.com" - git config --global user.name "Travis Runner" + + # debugging + - tree .git/logs + - cat .git/logs/HEAD script: - nosetests -v --with-coverage after_success: diff --git a/git/test/test_git.py b/git/test/test_git.py index 759d4d443..9c8bb490d 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -125,7 +125,7 @@ def test_options_are_passed_to_git(self): def test_single_char_git_options_are_passed_to_git(self): input_value = 'TestValue' - output_value = self.git(c='user.name={}'.format(input_value)).config('--get', 'user.name') + output_value = self.git(c='user.name=%s' % input_value).config('--get', 'user.name') self.assertEquals(input_value, output_value) def test_change_to_transform_kwargs_does_not_break_command_options(self): From 17f245cad19bf77a5a5fecdee6a41217cc128a73 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 3 Jan 2015 21:01:38 +0100 Subject: [PATCH 0008/2790] 'tree' program doesn't exist on travis install, fine --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3b0f12e7e..cd3cf1cd5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ install: - git config --global user.name "Travis Runner" # debugging - - tree .git/logs + - find .git/logs - cat .git/logs/HEAD script: - nosetests -v --with-coverage From e3e8ce69bec72277354eff252064a59f515d718a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 10:24:10 +0100 Subject: [PATCH 0009/2790] Somemore debugging for rev-parse issue --- .travis.yml | 8 ++------ git/test/test_repo.py | 8 +++++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index cd3cf1cd5..3d560bb6f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,9 @@ install: - pip install coveralls # for now we have to make sure there is a master branch - at some point we should just have it by default - - git branch master 0.3 + - git branch master - # generate some reflog as git-python tests need it + # generate some reflog as git-python tests need it (in 0.3) - git reset --hard HEAD~1 - git reset --hard HEAD~1 - git reset --hard HEAD~1 @@ -30,10 +30,6 @@ install: # as commits are performed with the default user, it needs to be set for travis too - git config --global user.email "travis@ci.com" - git config --global user.name "Travis Runner" - - # debugging - - find .git/logs - - cat .git/logs/HEAD script: - nosetests -v --with-coverage after_success: diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 328995a2c..64525ed1b 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -581,15 +581,17 @@ def test_rev_parse(self): assert rev_parse(refspec + ":CHANGES").type == 'blob' # END operate on non-detached head - # the last position - assert rev_parse('@{1}') != head.commit - # position doesn't exist self.failUnlessRaises(IndexError, rev_parse, '@{10000}') # currently, nothing more is supported self.failUnlessRaises(NotImplementedError, rev_parse, "@{1 week ago}") + # the last position + # For some reason, this test fails on travis - lets gather more information + print self.rorepo + assert rev_parse('@{1}') != head.commit + def test_repo_odbtype(self): target_type = GitDB if sys.version_info[1] < 5: From a8535d1a2485b4e063ab9ef0a2719a1aab8187d3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 10:36:43 +0100 Subject: [PATCH 0010/2790] Intermediate debug commit for travis ... do not use --- git/refs/log.py | 2 ++ git/test/test_repo.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/git/refs/log.py b/git/refs/log.py index 742c9ccd7..e0f92fbe8 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -197,6 +197,8 @@ def entry_at(cls, filepath, index): the index is negative """ fp = open(filepath, 'rb') + # DEBUG + print filepath if index < 0: return RefLogEntry.from_line(fp.readlines()[index].strip()) else: diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 64525ed1b..1079cd045 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -588,8 +588,8 @@ def test_rev_parse(self): self.failUnlessRaises(NotImplementedError, rev_parse, "@{1 week ago}") # the last position - # For some reason, this test fails on travis - lets gather more information - print self.rorepo + # For some reason, this test fails on travis - even though there is a rev log + # from all I see there. assert rev_parse('@{1}') != head.commit def test_repo_odbtype(self): From 4228b2cc8e1c9bd080fe48db98a46c21305e1464 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 10:39:12 +0100 Subject: [PATCH 0011/2790] Another travis debugging commit --- .travis.yml | 3 +++ git/refs/log.py | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d560bb6f..b40e0dfc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,9 @@ install: # as commits are performed with the default user, it needs to be set for travis too - git config --global user.email "travis@ci.com" - git config --global user.name "Travis Runner" + + # DEBUG + cat /home/travis/build/gitpython-developers/GitPython/.git/logs/refs/heads/0.3 script: - nosetests -v --with-coverage after_success: diff --git a/git/refs/log.py b/git/refs/log.py index e0f92fbe8..742c9ccd7 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -197,8 +197,6 @@ def entry_at(cls, filepath, index): the index is negative """ fp = open(filepath, 'rb') - # DEBUG - print filepath if index < 0: return RefLogEntry.from_line(fp.readlines()[index].strip()) else: From 79d9c4cb175792e80950fdd363a43944fb16a441 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 10:42:28 +0100 Subject: [PATCH 0012/2790] Fixed travis debugging yaml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b40e0dfc7..0c6a248dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ install: - git config --global user.name "Travis Runner" # DEBUG - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/refs/heads/0.3 + - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/refs/heads/0.3 script: - nosetests -v --with-coverage after_success: From c255c14e9eb15f4ff29a4baead3ed31a9943e04e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 10:49:19 +0100 Subject: [PATCH 0013/2790] Another, last and final travis debugging commit --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0c6a248dd..2acd16bee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,8 @@ install: # DEBUG - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/refs/heads/0.3 + - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/refs/heads/master + - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/HEAD script: - nosetests -v --with-coverage after_success: From acac4bb07af3f168e10eee392a74a06e124d1cdd Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 10:54:57 +0100 Subject: [PATCH 0014/2790] Let's hope travis works now --- .travis.yml | 8 ++------ git/test/test_repo.py | 2 -- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2acd16bee..c56b9d43f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,10 @@ install: - pip install coveralls # for now we have to make sure there is a master branch - at some point we should just have it by default - - git branch master + - git branch master 0.3 # generate some reflog as git-python tests need it (in 0.3) + - git checkout 0.3 - git reset --hard HEAD~1 - git reset --hard HEAD~1 - git reset --hard HEAD~1 @@ -30,11 +31,6 @@ install: # as commits are performed with the default user, it needs to be set for travis too - git config --global user.email "travis@ci.com" - git config --global user.name "Travis Runner" - - # DEBUG - - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/refs/heads/0.3 - - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/refs/heads/master - - cat /home/travis/build/gitpython-developers/GitPython/.git/logs/HEAD script: - nosetests -v --with-coverage after_success: diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 1079cd045..d40696700 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -588,8 +588,6 @@ def test_rev_parse(self): self.failUnlessRaises(NotImplementedError, rev_parse, "@{1 week ago}") # the last position - # For some reason, this test fails on travis - even though there is a rev log - # from all I see there. assert rev_parse('@{1}') != head.commit def test_repo_odbtype(self): From 965a08c3f9f2fbd62691d533425c699c943cb865 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 11:22:20 +0100 Subject: [PATCH 0015/2790] Applied autopep8 autopep8 -v -j 8 --max-line-length 120 --in-place --recursive --- git/objects/util.py | 4 ++-- git/remote.py | 24 ++++++++++++------------ git/test/lib/helper.py | 2 +- git/test/performance/__init__.py | 1 - git/test/performance/lib.py | 4 +++- git/test/test_index.py | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/git/objects/util.py b/git/objects/util.py index 350739713..76a24a6fb 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -157,8 +157,8 @@ def parse_date(string_date): try: dtstruct = time.strptime(date_part, fmt) utctime = calendar.timegm((dtstruct.tm_year, dtstruct.tm_mon, dtstruct.tm_mday, - tstruct.tm_hour, tstruct.tm_min, tstruct.tm_sec, - dtstruct.tm_wday, dtstruct.tm_yday, tstruct.tm_isdst)) + tstruct.tm_hour, tstruct.tm_min, tstruct.tm_sec, + dtstruct.tm_wday, dtstruct.tm_yday, tstruct.tm_isdst)) return int(utctime), offset except ValueError: continue diff --git a/git/remote.py b/git/remote.py index bf0a0021f..4742111a2 100644 --- a/git/remote.py +++ b/git/remote.py @@ -100,12 +100,12 @@ class PushInfo(object): NEW_TAG, NEW_HEAD, NO_MATCH, REJECTED, REMOTE_REJECTED, REMOTE_FAILURE, DELETED, \ FORCED_UPDATE, FAST_FORWARD, UP_TO_DATE, ERROR = [1 << x for x in range(11)] - _flag_map = {'X': NO_MATCH, - '-': DELETED, + _flag_map = {'X': NO_MATCH, + '-': DELETED, '*': 0, - '+': FORCED_UPDATE, + '+': FORCED_UPDATE, ' ': FAST_FORWARD, - '=': UP_TO_DATE, + '=': UP_TO_DATE, '!': ERROR} def __init__(self, flags, local_ref, remote_ref_string, remote, old_commit=None, @@ -208,11 +208,11 @@ class FetchInfo(object): # %c %-*s %-*s -> %s (%s) re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.]+\]?)\s+(.+) -> ([/\w_\+\.\-#]+)( \(.*\)?$)?") - _flag_map = {'!': ERROR, - '+': FORCED_UPDATE, - '-': TAG_UPDATE, + _flag_map = {'!': ERROR, + '+': FORCED_UPDATE, + '-': TAG_UPDATE, '*': 0, - '=': HEAD_UPTODATE, + '=': HEAD_UPTODATE, ' ': FAST_FORWARD} def __init__(self, ref, flags, note='', old_commit=None): @@ -526,8 +526,8 @@ def _get_fetch_info_from_stderr(self, proc, progress): # this also waits for the command to finish # Skip some progress lines that don't provide relevant information fetch_info_lines = list() - # Basically we want all fetch info lines which appear to be in regular form, and thus have a - # command character. Everything else we ignore, + # Basically we want all fetch info lines which appear to be in regular form, and thus have a + # command character. Everything else we ignore, cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys()) for line in digest_process_messages(proc.stderr, progress): if line.startswith('fatal:'): @@ -547,8 +547,8 @@ def _get_fetch_info_from_stderr(self, proc, progress): fp.close() # NOTE: We assume to fetch at least enough progress lines to allow matching each fetch head line with it. - assert len(fetch_info_lines) >= len(fetch_head_info), "len(%s) <= len(%s)" % (fetch_head_info, - fetch_info_lines) + assert len(fetch_info_lines) >= len(fetch_head_info), "len(%s) <= len(%s)" % (fetch_head_info, + fetch_info_lines) output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info)) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index df94abde6..341f57890 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -196,7 +196,7 @@ def remote_repo_creator(self): time.sleep(0.5) except Exception as err: gd = None - # end + # end # try to list remotes to diagnoes whether the server is up try: diff --git a/git/test/performance/__init__.py b/git/test/performance/__init__.py index 8b1378917..e69de29bb 100644 --- a/git/test/performance/__init__.py +++ b/git/test/performance/__init__.py @@ -1 +0,0 @@ - diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index 9b6f45bfb..e92e2b2df 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -49,12 +49,14 @@ def setUp(self): repo_path = os.environ.get(k_env_git_repo) if repo_path is None: - logging.info("You can set the %s environment variable to a .git repository of your choice - defaulting to the gitpython repository", k_env_git_repo) + logging.info( + "You can set the %s environment variable to a .git repository of your choice - defaulting to the gitpython repository", k_env_git_repo) repo_path = os.path.dirname(__file__) # end set some repo path self.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB) self.puregitrorepo = Repo(repo_path, odbt=GitDB) + class TestBigRepoRW(TestBigRepoR): """As above, but provides a big repository that we can write to. diff --git a/git/test/test_index.py b/git/test/test_index.py index 5431df44e..3f85ea902 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -216,7 +216,7 @@ def test_index_merge_tree(self, rw_repo): # if missing objects are okay, this would work though ( they are always okay now ) # As we can't read back the tree with NULL_SHA, we rather set it to something else - index.entries[manifest_key] = IndexEntry(manifest_entry[:1] + (hex_to_bin('f'*40),) + manifest_entry[2:]) + index.entries[manifest_key] = IndexEntry(manifest_entry[:1] + (hex_to_bin('f' * 40),) + manifest_entry[2:]) tree = index.write_tree() # now make a proper three way merge with unmerged entries From c80d727e374321573bb00e23876a67c77ff466e3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 13:48:29 +0100 Subject: [PATCH 0016/2790] Bumped version, updated changelog, reduced code smell There is more work to do though, as many imports are still incorrect. Also, there are still print statements --- README.md | 2 +- VERSION | 2 +- doc/source/changes.rst | 3 +++ git/cmd.py | 16 ++++++------ git/config.py | 8 +++--- git/diff.py | 5 ++-- git/ext/gitdb | 2 +- git/index/__init__.py | 6 +++-- git/index/base.py | 16 +++++------- git/index/fun.py | 9 +++---- git/index/typ.py | 3 ++- git/objects/__init__.py | 21 ++++++++-------- git/objects/base.py | 1 - git/objects/commit.py | 4 +-- git/objects/submodule/base.py | 12 +++++---- git/objects/submodule/root.py | 10 +++++--- git/objects/tree.py | 3 ++- git/objects/util.py | 9 +++---- git/odict.py | 7 +++--- git/refs/__init__.py | 17 +++++++------ git/refs/head.py | 3 +-- git/refs/log.py | 4 --- git/refs/reference.py | 5 ---- git/refs/symbolic.py | 4 ++- git/remote.py | 4 +-- git/repo/__init__.py | 4 +-- git/repo/base.py | 5 +--- git/test/lib/asserts.py | 1 - git/test/lib/helper.py | 17 +++++++------ git/test/performance/lib.py | 3 ++- git/test/performance/test_odb.py | 5 ++-- git/test/performance/test_streams.py | 20 +++++++++------ git/test/test_actor.py | 1 - git/test/test_base.py | 3 --- git/test/test_blob.py | 1 - git/test/test_config.py | 4 +-- git/test/test_diff.py | 2 +- git/test/test_index.py | 37 ++++++++++++++-------------- git/test/test_refs.py | 4 +-- git/test/test_remote.py | 4 +-- git/test/test_repo.py | 13 +++++----- git/test/test_submodule.py | 4 +-- git/test/test_tree.py | 5 +--- git/test/test_util.py | 1 - git/util.py | 4 ++- requirements.txt | 2 +- setup.py | 4 +-- tox.ini | 2 ++ 48 files changed, 157 insertions(+), 165 deletions(-) diff --git a/README.md b/README.md index b99c4c2f5..4b6781849 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ New BSD License. See the LICENSE file. ### DEVELOPMENT STATUS [![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg?branch=0.3)](https://travis-ci.org/gitpython-developers/GitPython) -[![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png)](https://coveralls.io/r/gitpython-developers/GitPython) +[![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=0.3)](https://coveralls.io/r/gitpython-developers/GitPython?branch=0.3) [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) diff --git a/VERSION b/VERSION index e8a6b9305..1c09c74e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.2.1 +0.3.3 diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 1c34e6293..924743bd1 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -5,6 +5,9 @@ Changelog 0.3.3 ===== * When fetching, pulling or pushing, and an error occours, it will not be reported on stdout anymore. However, if there is a fatal error, it will still result in a GitCommandError to be thrown. This goes hand in hand with improved fetch result parsing. +* Code Cleanup (in preparation for python 3 support) + * Applied autopep8 and cleaned up code + * Using python logging module instead of print statments to signal certain kinds of errors 0.3.2.1 ======= diff --git a/git/cmd.py b/git/cmd.py index bfdefb17f..d024b4097 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -334,7 +334,7 @@ def execute(self, command, If you add additional keyword arguments to the signature of this method, you must update the execute_kwargs tuple housed in this module.""" if self.GIT_PYTHON_TRACE and (self.GIT_PYTHON_TRACE != 'full' or as_process): - print ' '.join(command) + print(' '.join(command)) # Allow the user to have the command executed in their working dir. if with_keep_cwd or self._working_dir is None: @@ -389,11 +389,11 @@ def execute(self, command, if self.GIT_PYTHON_TRACE == 'full': cmdstr = " ".join(command) if stderr_value: - print "%s -> %d; stdout: '%s'; stderr: '%s'" % (cmdstr, status, stdout_value, stderr_value) + print("%s -> %d; stdout: '%s'; stderr: '%s'" % (cmdstr, status, stdout_value, stderr_value)) elif stdout_value: - print "%s -> %d; stdout: '%s'" % (cmdstr, status, stdout_value) + print("%s -> %d; stdout: '%s'" % (cmdstr, status, stdout_value)) else: - print "%s -> %d" % (cmdstr, status) + print("%s -> %d" % (cmdstr, status)) # END handle debug printing if with_exceptions and status != 0: @@ -522,14 +522,16 @@ def make_call(): raise # END handle overridden variable type(self).GIT_PYTHON_GIT_EXECUTABLE = self.git_exec_name_win - call = [self.GIT_PYTHON_GIT_EXECUTABLE] + list(args) try: return self.execute(make_call(), **_kwargs) finally: import warnings - msg = "WARNING: Automatically switched to use git.cmd as git executable, which reduces performance by ~70%." - msg += "Its recommended to put git.exe into the PATH or to set the %s environment variable to the executable's location" % self._git_exec_env_var + msg = "WARNING: Automatically switched to use git.cmd as git executable" + msg += ", which reduces performance by ~70%." + msg += "Its recommended to put git.exe into the PATH or to " + msg += "set the %s " % self._git_exec_env_var + msg += "environment variable to the executable's location" warnings.warn(msg) # END print of warning # END catch first failure diff --git a/git/config.py b/git/config.py index 8a15466f4..51337db4c 100644 --- a/git/config.py +++ b/git/config.py @@ -7,10 +7,8 @@ configuration files""" import re -import os import ConfigParser as cp import inspect -import cStringIO from git.odict import OrderedDict from git.util import LockFile @@ -188,8 +186,8 @@ def __del__(self): try: try: self.write() - except IOError, e: - print "Exception during destruction of GitConfigParser: %s" % str(e) + except IOError as e: + print("Exception during destruction of GitConfigParser: %s" % str(e)) finally: self._lock._release_lock() @@ -287,7 +285,7 @@ def read(self): try: fp = open(file_object) close_fp = True - except IOError, e: + except IOError: continue # END fp handling diff --git a/git/diff.py b/git/diff.py index 456974afd..5325ad6ba 100644 --- a/git/diff.py +++ b/git/diff.py @@ -7,7 +7,6 @@ import re from objects.blob import Blob from objects.util import mode_str_to_int -from exc import GitCommandError from gitdb.util import hex_to_bin @@ -106,7 +105,7 @@ def diff(self, other=Index, paths=None, create_patch=False, **kwargs): diff_method = Diff._index_from_patch_format index = diff_method(self.repo, proc.stdout) - status = proc.wait() + proc.wait() return index @@ -321,7 +320,7 @@ def _index_from_raw_format(cls, repo, stream): modify, delete and add files :return: git.DiffIndex""" # handles - # :100644 100644 6870991011cc8d9853a7a8a6f02061512c6a8190 37c5e30c879213e9ae83b21e9d11e55fc20c54b7 M .gitignore + # :100644 100644 687099101... 37c5e30c8... M .gitignore index = DiffIndex() for line in stream: if not line.startswith(":"): diff --git a/git/ext/gitdb b/git/ext/gitdb index ab4520683..ff7615321 160000 --- a/git/ext/gitdb +++ b/git/ext/gitdb @@ -1 +1 @@ -Subproject commit ab4520683ab325046f2a9fe6ebf127dbbab60dfe +Subproject commit ff7615321ee31d981a171f7677a56a971c554059 diff --git a/git/index/__init__.py b/git/index/__init__.py index 4a495c33f..c5080d2e7 100644 --- a/git/index/__init__.py +++ b/git/index/__init__.py @@ -1,4 +1,6 @@ """Initialize the index package""" -from base import * -from typ import * +from __future__ import absolute_import + +from .base import * +from .typ import * diff --git a/git/index/base.py b/git/index/base.py index 051423bfd..fdcfcd12f 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -24,7 +24,6 @@ git_working_dir ) -import git.objects import git.diff as diff from git.exc import ( @@ -43,13 +42,11 @@ from git.objects.util import Serializable from git.util import ( - IndexFileSHA1Writer, LazyMixin, LockedFD, join_path_native, file_contents_ro, to_native_path_linux, - to_native_path ) from fun import ( @@ -418,9 +415,6 @@ def iter_blobs(self, predicate=lambda t: True): iterator. A default filter, the BlobFilter, allows you to yield blobs only if they match a given list of paths. """ for entry in self.entries.itervalues(): - # TODO: is it necessary to convert the mode ? We did that when adding - # it to the index, right ? - mode = stat_mode_to_index_mode(entry.mode) blob = entry.to_blob(self.repo) blob.size = entry.size output = (entry.stage, blob) @@ -602,7 +596,7 @@ def _entries_for_paths(self, paths, path_rewriter, fprogress, entries): def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=None, write=True): """Add files from the working tree, specific blobs or BaseIndexEntries - to the index. + to the index. :param items: Multiple types of items are supported, types can be mixed within one call. @@ -630,7 +624,7 @@ def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=Non must be a path relative to our repository. If their sha is null ( 40*0 ), their path must exist in the file system - relative to the git repository as an object will be created from + relative to the git repository as an object will be created from the data at the path. The handling now very much equals the way string paths are processed, except that the mode you have set will be kept. This allows you to create symlinks @@ -892,7 +886,8 @@ def commit(self, message, parent_commits=None, head=True, author=None, committer :return: Commit object representing the new commit""" tree = self.write_tree() - return Commit.create_from_tree(self.repo, tree, message, parent_commits, head, author=author, committer=committer) + return Commit.create_from_tree(self.repo, tree, message, parent_commits, + head, author=author, committer=committer) @classmethod def _flush_stdin_and_wait(cls, proc, ignore_stdout=False): @@ -995,7 +990,8 @@ def handle_stderr(proc, iter_checked_out_files): if failed_files: valid_files = list(set(iter_checked_out_files) - set(failed_files)) raise CheckoutError( - "Some files could not be checked out from the index due to local modifications", failed_files, valid_files, failed_reasons) + "Some files could not be checked out from the index due to local modifications", + failed_files, valid_files, failed_reasons) # END stderr handler if paths is None: diff --git a/git/index/fun.py b/git/index/fun.py index 4750463cc..eec90519c 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -5,7 +5,6 @@ S_IFDIR, S_IFLNK, S_ISLNK, - S_IFDIR, S_ISDIR, S_IFMT, S_IFREG, @@ -146,7 +145,7 @@ def read_cache(stream): path = read(path_size) real_size = ((tell() - beginoffset + 8) & ~7) - data = read((beginoffset + real_size) - tell()) + read((beginoffset + real_size) - tell()) entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size)) # entry_key would be the method to use, but we safe the effort entries[(path, entry.stage)] = entry @@ -160,8 +159,8 @@ def read_cache(stream): # 4 bytes length of chunk # repeated 0 - N times extension_data = stream.read(~0) - assert len(extension_data) > 19, "Index Footer was not at least a sha on content as it was only %i bytes in size" % len( - extension_data) + assert len(extension_data) > 19, "Index Footer was not at least a sha on content as it was only %i bytes in size"\ + % len(extension_data) content_sha = extension_data[-20:] @@ -265,7 +264,7 @@ def aggressive_tree_merge(odb, tree_shas): # it exists in all branches, if it was changed in both # its a conflict, otherwise we take the changed version # This should be the most common branch, so it comes first - if( base[0] != ours[0] and base[0] != theirs[0] and ours[0] != theirs[0] ) or \ + if(base[0] != ours[0] and base[0] != theirs[0] and ours[0] != theirs[0]) or \ (base[1] != ours[1] and base[1] != theirs[1] and ours[1] != theirs[1]): # changed by both out_append(_tree_entry_to_baseindexentry(base, 1)) diff --git a/git/index/typ.py b/git/index/typ.py index a71fc2c6b..222252c55 100644 --- a/git/index/typ.py +++ b/git/index/typ.py @@ -172,4 +172,5 @@ def from_base(cls, base): def from_blob(cls, blob, stage=0): """:return: Minimal entry resembling the given blob object""" time = pack(">LL", 0, 0) - return IndexEntry((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path, time, time, 0, 0, 0, 0, blob.size)) + return IndexEntry((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path, + time, time, 0, 0, 0, 0, blob.size)) diff --git a/git/objects/__init__.py b/git/objects/__init__.py index 0b40934c0..1fe881f3b 100644 --- a/git/objects/__init__.py +++ b/git/objects/__init__.py @@ -1,21 +1,22 @@ """ Import all submodules main classes into the package space """ +from __future__ import absolute_import import inspect -from base import * +from .base import * # Fix import dependency - add IndexObject to the util module, so that it can be # imported by the submodule.base -import submodule.util -submodule.util.IndexObject = IndexObject -submodule.util.Object = Object -from submodule.base import * -from submodule.root import * +from .submodule import util +util.IndexObject = IndexObject +util.Object = Object +from .submodule.base import * +from .submodule.root import * # must come after submodule was made available -from tag import * -from blob import * -from commit import * -from tree import * +from .tag import * +from .blob import * +from .commit import * +from .tree import * __all__ = [name for name, obj in locals().items() if not (name.startswith('_') or inspect.ismodule(obj))] diff --git a/git/objects/base.py b/git/objects/base.py index 50647a3a7..20147e578 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -6,7 +6,6 @@ from git.util import LazyMixin, join_path_native, stream_copy from util import get_object_type_by_name from gitdb.util import ( - hex_to_bin, bin_to_hex, basename ) diff --git a/git/objects/commit.py b/git/objects/commit.py index c6adcc94b..4a4a314c7 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -276,9 +276,9 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, 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. - :param author: The name of the author, optional. If unset, the repository + :param author: The name of the author, optional. If unset, the repository configuration is used to obtain this value. - :param committer: The name of the committer, optional. If unset, the + :param committer: The name of the committer, optional. If unset, the repository configuration is used to obtain this value. :return: Commit object representing the new commit diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index e3d580773..6951fd63f 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -28,7 +28,6 @@ import os import sys -import time __all__ = ["Submodule", "UpdateProgress"] @@ -140,7 +139,8 @@ def __str__(self): return self._name def __repr__(self): - return "git.%s(name=%s, path=%s, url=%s, branch_path=%s)" % (type(self).__name__, self._name, self.path, self.url, self.branch_path) + return "git.%s(name=%s, path=%s, url=%s, branch_path=%s)"\ + % (type(self).__name__, self._name, self.path, self.url, self.branch_path) @classmethod def _config_parser(cls, repo, parent_commit, read_only): @@ -236,7 +236,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): # assure we never put backslashes into the url, as some operating systems # like it ... - if url != None: + if url is not None: url = to_native_path_linux(url) # END assure url correctness @@ -449,7 +449,8 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= # handles dry_run if mrepo is not None and mrepo.head.commit.binsha != binsha: progress.update(BEGIN | UPDWKTREE, 0, 1, prefix + - "Updating working tree at %s for submodule %r to revision %s" % (self.path, self.name, hexsha)) + "Updating working tree at %s for submodule %r to revision %s" + % (self.path, self.name, hexsha)) if not dry_run: if is_detached: # NOTE: for now we force, the user is no supposed to change detached @@ -638,7 +639,8 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): mod = self.module() if mod.is_dirty(untracked_files=True): raise InvalidGitRepositoryError( - "Cannot delete module at %s with any modifications, unless force is specified" % mod.working_tree_dir) + "Cannot delete module at %s with any modifications, unless force is specified" + % mod.working_tree_dir) # END check for dirt # figure out whether we have new commits compared to the remotes diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index f68f75674..871cc21c4 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -186,7 +186,9 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= # in the new remote as well. if len([r for r in smr.refs if r.remote_head == sm.branch_name]) == 0: raise ValueError( - "Submodule branch named %r was not available in new submodule remote at %r" % (sm.branch_name, sm.url)) + "Submodule branch named %r was not available in new submodule remote at %r" + % (sm.branch_name, sm.url) + ) # END head is not detached # now delete the changed one @@ -245,7 +247,8 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= # this way, it will be checked out in the next step # This will change the submodule relative to us, so # the user will be able to commit the change easily - print >> sys.stderr, "WARNING: Current sha %s was not contained in the tracking branch at the new remote, setting it the the remote's tracking branch" % sm.hexsha + print >> sys.stderr, "WARNING: Current sha %s was not contained in the tracking\ + branch at the new remote, setting it the the remote's tracking branch" % sm.hexsha sm.binsha = rref.commit.binsha # END reset binsha @@ -262,7 +265,8 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= # finally, create a new tracking branch which tracks the # new remote branch progress.update(BEGIN | BRANCHCHANGE, i, len_csms, prefix + - "Changing branch of submodule %r from %s to %s" % (sm.name, psm.branch_path, sm.branch_path)) + "Changing branch of submodule %r from %s to %s" + % (sm.name, psm.branch_path, sm.branch_path)) if not dry_run: smm = sm.module() smmr = smm.remotes diff --git a/git/objects/tree.py b/git/objects/tree.py index 9f63e4e3f..beb5f1fdd 100644 --- a/git/objects/tree.py +++ b/git/objects/tree.py @@ -187,7 +187,8 @@ def __div__(self, file): else: for info in self._cache: if info[2] == file: # [2] == name - return self._map_id_to_type[info[1] >> 12](self.repo, info[0], info[1], join_path(self.path, info[2])) + return self._map_id_to_type[info[1] >> 12](self.repo, info[0], info[1], + join_path(self.path, info[2])) # END for each obj raise KeyError(msg % file) # END handle long paths diff --git a/git/objects/util.py b/git/objects/util.py index 76a24a6fb..fdf9622be 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -15,7 +15,6 @@ from string import digits import time import calendar -import os __all__ = ('get_object_type_by_name', 'parse_date', 'parse_actor_and_date', 'ProcessStreamAdapter', 'Traversable', 'altz_to_utctz_str', 'utctz_to_altz', @@ -89,10 +88,10 @@ def verify_utctz(offset): raise fmt_exc if offset[0] not in "+-": raise fmt_exc - if offset[1] not in digits or \ - offset[2] not in digits or \ - offset[3] not in digits or \ - offset[4] not in digits: + if offset[1] not in digits or\ + offset[2] not in digits or\ + offset[3] not in digits or\ + offset[4] not in digits: raise fmt_exc # END for each char return offset diff --git a/git/odict.py b/git/odict.py index c4c80499f..c505b7fd2 100644 --- a/git/odict.py +++ b/git/odict.py @@ -616,8 +616,7 @@ def pop(self, key, *args): TypeError: pop expected at most 2 arguments, got 3 """ if len(args) > 1: - raise TypeError, ('pop expected at most 2 arguments, got %s' % - (len(args) + 1)) + raise TypeError('pop expected at most 2 arguments, got %s' % (len(args) + 1)) if key in self: val = self[key] del self[key] @@ -1199,7 +1198,7 @@ def __setitem__(self, index, value): keys = self._main._sequence[index] if len(keys) != len(value): raise ValueError('attempt to assign sequence of size %s ' - 'to slice of size %s' % (len(name), len(keys))) + 'to slice of size %s' % (len(value), len(keys))) # FIXME: efficiency? Would be better to calculate the indexes # directly from the slice object # NOTE: the new keys can collide with existing keys (or even @@ -1511,7 +1510,7 @@ def __init__(self, init_val=(), strict=True): def __setattr__(self, name, value): """Protect keys, items, and values.""" - if not '_att_dict' in self.__dict__: + if '_att_dict' not in self.__dict__: object.__setattr__(self, name, value) else: try: diff --git a/git/refs/__init__.py b/git/refs/__init__.py index 3123b9914..0281121ae 100644 --- a/git/refs/__init__.py +++ b/git/refs/__init__.py @@ -1,21 +1,22 @@ +from __future__ import absolute_import # import all modules in order, fix the names they require -from symbolic import * -from reference import * -from head import * -from tag import * -from remote import * +from .symbolic import * +from .reference import * +from .head import * +from .tag import * +from .remote import * # name fixes -import head +from . import head head.RemoteReference = RemoteReference del(head) -import symbolic +from . import symbolic for item in (HEAD, Head, RemoteReference, TagReference, Reference, SymbolicReference): setattr(symbolic, item.__name__, item) del(symbolic) -from log import * +from .log import * diff --git a/git/refs/head.py b/git/refs/head.py index 6f36a9560..acdd37d6b 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -210,9 +210,8 @@ def checkout(self, force=False, **kwargs): By default it is only allowed to checkout heads - everything else will leave the HEAD detached which is allowed and possible, but remains a special state that some tools might not be able to handle.""" - args = list() kwargs['f'] = force - if kwargs['f'] == False: + if kwargs['f'] is False: kwargs.pop('f') self.repo.git.checkout(self, **kwargs) diff --git a/git/refs/log.py b/git/refs/log.py index 742c9ccd7..e3f3363c3 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -1,5 +1,4 @@ from git.util import ( - join_path, Actor, LockedFD, LockFile, @@ -16,12 +15,10 @@ from git.objects.util import ( parse_date, Serializable, - utctz_to_altz, altz_to_utctz_str, ) import time -import os import re __all__ = ["RefLog", "RefLogEntry"] @@ -281,7 +278,6 @@ def write(self): #{ Serializable Interface def _serialize(self, stream): - lm1 = len(self) - 1 write = stream.write # write all entries diff --git a/git/refs/reference.py b/git/refs/reference.py index f71ded720..b07ac0cd7 100644 --- a/git/refs/reference.py +++ b/git/refs/reference.py @@ -4,11 +4,6 @@ Iterable, ) -from gitdb.util import ( - isfile, - hex_to_bin -) - __all__ = ["Reference"] #{ Utilities diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 1e361244d..2fa58d123 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -424,7 +424,7 @@ def delete(cls, repo, path): # in the line # If we deleted the last line and this one is a tag-reference object, # we drop it as well - if ( line.startswith('#') or full_ref_path not in line ) and \ + if (line.startswith('#') or full_ref_path not in line) and \ (not dropped_last_line or dropped_last_line and not line.startswith('^')): new_lines.append(line) dropped_last_line = False @@ -623,6 +623,8 @@ def from_path(cls, repo, path): if not path: raise ValueError("Cannot create Reference from %r" % path) + # Names like HEAD are inserted after the refs module is imported - we have an import dependency + # cycle and don't want to import these names in-function for ref_type in (HEAD, Head, RemoteReference, TagReference, Reference, SymbolicReference): try: instance = ref_type(repo, path) diff --git a/git/remote.py b/git/remote.py index 4742111a2..44b7ffaa7 100644 --- a/git/remote.py +++ b/git/remote.py @@ -32,7 +32,6 @@ import re import os -import sys __all__ = ('RemoteProgress', 'PushInfo', 'FetchInfo', 'Remote') @@ -329,7 +328,8 @@ def _from_line(cls, repo, line, fetch_line): # always use actual type if we get absolute paths # Will always be the case if something is fetched outside of refs/remotes (if its not a tag) ref_path = remote_local_ref - if ref_type is not TagReference and not remote_local_ref.startswith(RemoteReference._common_path_default + "/"): + if ref_type is not TagReference and not \ + remote_local_ref.startswith(RemoteReference._common_path_default + "/"): ref_type = Reference # END downgrade remote reference elif ref_type is TagReference and 'tags/' in remote_local_ref: diff --git a/git/repo/__init__.py b/git/repo/__init__.py index 09051bd4c..3ae97e660 100644 --- a/git/repo/__init__.py +++ b/git/repo/__init__.py @@ -1,3 +1,3 @@ """Initialize the Repo package""" - -from base import * +from __future__ import absolute_import +from .base import * diff --git a/git/repo/base.py b/git/repo/base.py index 174f29aad..d1af26e21 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -164,9 +164,6 @@ def __ne__(self, rhs): def __hash__(self): return hash(self.git_dir) - def __repr__(self): - return "%s(%r)" % (type(self).__name__, self.git_dir) - # Description property def _get_description(self): filename = join(self.git_dir, 'description') @@ -666,7 +663,7 @@ def init(cls, path=None, mkdir=True, **kwargs): # git command automatically chdir into the directory git = Git(path) - output = git.init(**kwargs) + git.init(**kwargs) return Repo(path) @classmethod diff --git a/git/test/lib/asserts.py b/git/test/lib/asserts.py index 351901dc1..6f6d8960f 100644 --- a/git/test/lib/asserts.py +++ b/git/test/lib/asserts.py @@ -5,7 +5,6 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import re -import unittest from nose import tools from nose.tools import * import stat diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 341f57890..a18f22ef9 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -75,7 +75,7 @@ def _rmtree_onerror(osremove, fullpath, exec_info): if os.name != 'nt' or osremove is not os.remove: raise - os.chmod(fullpath, 0777) + os.chmod(fullpath, 0o777) os.remove(fullpath) @@ -194,26 +194,27 @@ def remote_repo_creator(self): gd = Git().daemon(temp_dir, as_process=True) # yes, I know ... fortunately, this is always going to work if sleep time is just large enough time.sleep(0.5) - except Exception as err: + except Exception: gd = None # end # try to list remotes to diagnoes whether the server is up try: rw_repo.git.ls_remote(d_remote) - except GitCommandError, e: + except GitCommandError as e: # We assume in good faith that we didn't start the daemon - but make sure we kill it anyway # Of course we expect it to work here already, but maybe there are timing constraints # on some platforms ? if gd is not None: os.kill(gd.proc.pid, 15) - print str(e) + print(str(e)) if os.name == 'nt': - raise AssertionError( - 'git-daemon needs to run this test, but windows does not have one. Otherwise, run: git-daemon "%s"' % temp_dir) + msg = "git-daemon needs to run this test, but windows does not have one. " + msg += 'Otherwise, run: git-daemon "%s"' % temp_dir + raise AssertionError(msg) else: - raise AssertionError( - 'Please start a git-daemon to run this test, execute: git-daemon "%s"' % temp_dir) + msg = 'Please start a git-daemon to run this test, execute: git-daemon "%s"' % temp_dir + raise AssertionError(msg) # END make assertion # END catch ls remote error diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index e92e2b2df..928821eda 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -50,7 +50,8 @@ def setUp(self): repo_path = os.environ.get(k_env_git_repo) if repo_path is None: logging.info( - "You can set the %s environment variable to a .git repository of your choice - defaulting to the gitpython repository", k_env_git_repo) + ("You can set the %s environment variable to a .git repository of" % k_env_git_repo) + + "your choice - defaulting to the gitpython repository") repo_path = os.path.dirname(__file__) # end set some repo path self.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB) diff --git a/git/test/performance/test_odb.py b/git/test/performance/test_odb.py index 9d8572605..1b570fa76 100644 --- a/git/test/performance/test_odb.py +++ b/git/test/performance/test_odb.py @@ -61,9 +61,10 @@ def test_random_access(self): # END for each bloblist elapsed = time() - st - print >> sys.stderr, "%s: Retrieved %i blob (%i KiB) and their data in %g s ( %f blobs / s, %f KiB / s )" % ( - type(repo.odb), nb, data_bytes / 1000, elapsed, nb / elapsed, (data_bytes / 1000) / elapsed) + msg = "%s: Retrieved %i blob (%i KiB) and their data in %g s ( %f blobs / s, %f KiB / s )"\ + % (type(repo.odb), nb, data_bytes / 1000, elapsed, nb / elapsed, (data_bytes / 1000) / elapsed) results[2].append(elapsed) + print >> sys.stderr, msg # END for each repo type # final results diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index facf9eed5..18f19db39 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -44,8 +44,9 @@ def test_large_data_streaming(self, rwrepo): fsize_kib = os.path.getsize(db_file) / 1000 size_kib = size / 1000 - print >> sys.stderr, "Added %i KiB (filesize = %i KiB) of %s data to loose odb in %f s ( %f Write KiB / s)" % ( - size_kib, fsize_kib, desc, elapsed_add, size_kib / elapsed_add) + msg = "Added %i KiB (filesize = %i KiB) of %s data to loose odb in %f s ( %f Write KiB / s)" + msg %= (size_kib, fsize_kib, desc, elapsed_add, size_kib / elapsed_add) + print >> sys.stderr, msg # reading all at once st = time() @@ -55,8 +56,9 @@ def test_large_data_streaming(self, rwrepo): stream.seek(0) assert shadata == stream.getvalue() - print >> sys.stderr, "Read %i KiB of %s data at once from loose odb in %f s ( %f Read KiB / s)" % ( - size_kib, desc, elapsed_readall, size_kib / elapsed_readall) + msg = "Read %i KiB of %s data at once from loose odb in %f s ( %f Read KiB / s)" + msg %= (size_kib, desc, elapsed_readall, size_kib / elapsed_readall) + print >> sys.stderr, msg # reading in chunks of 1 MiB cs = 512 * 1000 @@ -99,8 +101,9 @@ def test_large_data_streaming(self, rwrepo): # as its the same sha, we reuse our path fsize_kib = os.path.getsize(db_file) / 1000 - print >> sys.stderr, "Added %i KiB (filesize = %i KiB) of %s data to using git-hash-object in %f s ( %f Write KiB / s)" % ( - size_kib, fsize_kib, desc, gelapsed_add, size_kib / gelapsed_add) + msg = "Added %i KiB (filesize = %i KiB) of %s data to using git-hash-object in %f s ( %f Write KiB / s)" + msg %= (size_kib, fsize_kib, desc, gelapsed_add, size_kib / gelapsed_add) + print >> sys.stderr, msg # compare ... print >> sys.stderr, "Git-Python is %f %% faster than git when adding big %s files" % ( @@ -126,8 +129,9 @@ def test_large_data_streaming(self, rwrepo): break # END read stream gelapsed_readchunks = time() - st - print >> sys.stderr, "Read %i KiB of %s data in %i KiB chunks from git-cat-file in %f s ( %f Read KiB / s)" % ( - size_kib, desc, cs_kib, gelapsed_readchunks, size_kib / gelapsed_readchunks) + msg = "Read %i KiB of %s data in %i KiB chunks from git-cat-file in %f s ( %f Read KiB / s)" + msg %= (size_kib, desc, cs_kib, gelapsed_readchunks, size_kib / gelapsed_readchunks) + print >> sys.stderr, msg # compare print >> sys.stderr, "Git-Python is %f %% faster than git when reading big %s files in chunks" % ( diff --git a/git/test/test_actor.py b/git/test/test_actor.py index 5ccf1d2ee..ee9684554 100644 --- a/git/test/test_actor.py +++ b/git/test/test_actor.py @@ -4,7 +4,6 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -import os from git.test.lib import * from git import * diff --git a/git/test/test_base.py b/git/test/test_base.py index d1b579841..ea241f4cb 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -5,15 +5,12 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import git.objects.base as base -import git.refs as refs import os from git.test.lib import * from git import * -from itertools import chain from git.objects.util import get_object_type_by_name from gitdb.util import hex_to_bin -import tempfile class TestBase(TestBase): diff --git a/git/test/test_blob.py b/git/test/test_blob.py index ddd2893f6..cf45d82ae 100644 --- a/git/test/test_blob.py +++ b/git/test/test_blob.py @@ -6,7 +6,6 @@ from git.test.lib import * from git import * -from gitdb.util import hex_to_bin class TestBlob(TestBase): diff --git a/git/test/test_config.py b/git/test/test_config.py index 0e5396a32..3e435c476 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -74,7 +74,7 @@ def test_base(self): num_options = 0 # test reader methods - assert r_config._is_initialized == False + assert r_config._is_initialized is False for section in r_config.sections(): num_sections += 1 for option in r_config.options(section): @@ -93,7 +93,7 @@ def test_base(self): self.failUnlessRaises(IOError, r_config.remove_section, section) # END for each section assert num_sections and num_options - assert r_config._is_initialized == True + assert r_config._is_initialized is True # get value which doesnt exist, with default default = "my default value" diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 151a3d149..8e2cef4b0 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -54,7 +54,7 @@ def test_diff_patch_format(self): for fixture_name in fixtures: diff_proc = StringProcessAdapter(fixture(fixture_name)) - diffs = Diff._index_from_patch_format(self.rorepo, diff_proc.stdout) + Diff._index_from_patch_format(self.rorepo, diff_proc.stdout) # END for each fixture def test_diff_interface(self): diff --git a/git/test/test_index.py b/git/test/test_index.py index 3f85ea902..08dfdd123 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -7,13 +7,14 @@ from git.test.lib import * from git import * from gitdb.util import hex_to_bin -import inspect import os import sys import tempfile -import glob import shutil -from stat import * +from stat import ( + S_ISLNK, + ST_MODE +) from StringIO import StringIO from gitdb.base import IStream @@ -60,7 +61,7 @@ def _assert_entries(self, entries): for entry in entries: assert isinstance(entry, BaseIndexEntry) assert not os.path.isabs(entry.path) - assert not "\\" in entry.path + assert "\\" not in entry.path # END for each entry def test_index_file_base(self): @@ -70,11 +71,10 @@ def test_index_file_base(self): assert index.version > 0 # test entry - last_val = None entry = index.entries.itervalues().next() for attr in ("path", "ctime", "mtime", "dev", "inode", "mode", "uid", "gid", "size", "binsha", "hexsha", "stage"): - val = getattr(entry, attr) + getattr(entry, attr) # END for each method # test update @@ -100,7 +100,6 @@ def _cmp_tree_index(self, tree, index): if isinstance(tree, str): tree = self.rorepo.commit(tree).tree - num_blobs = 0 blist = list() for blob in tree.traverse(predicate=lambda e, d: e.type == "blob", branch_first=False): assert (blob.path, 0) in index.entries @@ -240,7 +239,7 @@ def test_index_file_diffing(self, rw_repo): # resetting the head will leave the index in a different state, and the # diff will yield a few changes cur_head_commit = rw_repo.head.reference.commit - ref = rw_repo.head.reset('HEAD~6', index=True, working_tree=False) + rw_repo.head.reset('HEAD~6', index=True, working_tree=False) # diff against same index is 0 diff = index.diff() @@ -468,7 +467,7 @@ def mixed_iterator(): entries = index.reset(new_commit).add( [os.path.abspath(os.path.join('lib', 'git', 'head.py'))] * 2, fprogress=self._fprogress_add) self._assert_entries(entries) - assert entries[0].mode & 0644 == 0644 + assert entries[0].mode & 0o644 == 0o644 # would fail, test is too primitive to handle this case # self._assert_fprogress(entries) self._reset_progress() @@ -492,9 +491,9 @@ def mixed_iterator(): # add new file new_file_relapath = "my_new_file" - new_file_path = self._make_file(new_file_relapath, "hello world", rw_repo) + self._make_file(new_file_relapath, "hello world", rw_repo) entries = index.reset(new_commit).add( - [BaseIndexEntry((010644, null_bin_sha, 0, new_file_relapath))], fprogress=self._fprogress_add) + [BaseIndexEntry((0o10644, null_bin_sha, 0, new_file_relapath))], fprogress=self._fprogress_add) self._assert_entries(entries) self._assert_fprogress(entries) assert len(entries) == 1 and entries[0].hexsha != null_hex_sha @@ -519,7 +518,7 @@ def mixed_iterator(): fake_symlink_relapath = "my_fake_symlink" link_target = "/etc/that" fake_symlink_path = self._make_file(fake_symlink_relapath, link_target, rw_repo) - fake_entry = BaseIndexEntry((0120000, null_bin_sha, 0, fake_symlink_relapath)) + fake_entry = BaseIndexEntry((0o120000, null_bin_sha, 0, fake_symlink_relapath)) entries = index.reset(new_commit).add([fake_entry], fprogress=self._fprogress_add) self._assert_entries(entries) self._assert_fprogress(entries) @@ -527,7 +526,7 @@ def mixed_iterator(): assert len(entries) == 1 and S_ISLNK(entries[0].mode) # assure this also works with an alternate method - full_index_entry = IndexEntry.from_base(BaseIndexEntry((0120000, entries[0].binsha, 0, entries[0].path))) + full_index_entry = IndexEntry.from_base(BaseIndexEntry((0o120000, entries[0].binsha, 0, entries[0].path))) entry_key = index.entry_key(full_index_entry) index.reset(new_commit) @@ -605,7 +604,7 @@ def make_paths(): for fid in range(3): fname = 'newfile%i' % fid open(fname, 'wb').write("abcd") - yield Blob(rw_repo, Blob.NULL_BIN_SHA, 0100644, fname) + yield Blob(rw_repo, Blob.NULL_BIN_SHA, 0o100644, fname) # END for each new file # END path producer paths = list(make_paths()) @@ -627,7 +626,7 @@ def make_paths(): files = (arela, brela) for fkey in keys: - assert not fkey in index.entries + assert fkey not in index.entries index.add(files, write=True) nc = index.commit("2 files committed", head=False) @@ -637,7 +636,7 @@ def make_paths(): # just the index index.reset(paths=(arela, afile)) - assert not akey in index.entries + assert akey not in index.entries assert bkey in index.entries # now with working tree - files on disk as well as entries must be recreated @@ -690,10 +689,10 @@ def test_index_bare_add(self, rw_bare_repo): filename = 'my-imaginary-file' istream = rw_bare_repo.odb.store( IStream(Blob.type, filesize, fileobj)) - entry = BaseIndexEntry((100644, istream.binsha, 0, filename)) + entry = BaseIndexEntry((0o100644, istream.binsha, 0, filename)) try: rw_bare_repo.index.add([entry]) - except AssertionError, e: + except AssertionError: self.fail("Adding to the index of a bare repo is not allowed.") # Adding using a path should still require a non-bare repository. @@ -701,6 +700,6 @@ def test_index_bare_add(self, rw_bare_repo): path = os.path.join('git', 'test', 'test_index.py') try: rw_bare_repo.index.add([path]) - except Exception, e: + except Exception as e: asserted = "does not have a working tree" in e.message assert asserted, "Adding using a filename is not correctly asserted." diff --git a/git/test/test_refs.py b/git/test/test_refs.py index c4f7077b7..4df3fa8a2 100644 --- a/git/test/test_refs.py +++ b/git/test/test_refs.py @@ -155,10 +155,10 @@ def test_refs(self): assert len(types_found) >= 3 def test_is_valid(self): - assert Reference(self.rorepo, 'refs/doesnt/exist').is_valid() == False + assert not Reference(self.rorepo, 'refs/doesnt/exist').is_valid() assert self.rorepo.head.is_valid() assert self.rorepo.head.reference.is_valid() - assert SymbolicReference(self.rorepo, 'hellothere').is_valid() == False + assert not SymbolicReference(self.rorepo, 'hellothere').is_valid() def test_orig_head(self): assert type(self.rorepo.head.orig_head()) == SymbolicReference diff --git a/git/test/test_remote.py b/git/test/test_remote.py index c9329f257..d49a90612 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -259,7 +259,6 @@ def get_info(res, remote, name): def _assert_push_and_pull(self, remote, rw_repo, remote_repo): # push our changes lhead = rw_repo.head - lindex = rw_repo.index # assure we are on master and it is checked out where the remote is try: lhead.reference = rw_repo.heads.master @@ -448,7 +447,8 @@ def test_creation_and_removal(self, bare_rw_repo): def test_fetch_info(self): # assure we can handle remote-tracking branches - fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of git://github.com/gitpython-developers/GitPython" + fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of " + fetch_info_line_fmt += "git://github.com/gitpython-developers/GitPython" remote_info_line_fmt = "* [new branch] nomatter -> %s" fi = FetchInfo._from_line(self.rorepo, remote_info_line_fmt % "local/master", diff --git a/git/test/test_repo.py b/git/test/test_repo.py index d40696700..3f1a3a3cc 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -7,7 +7,6 @@ TestBase, with_rw_repo, fixture, - GIT_REPO, assert_false, assert_equal, assert_true, @@ -15,7 +14,7 @@ from git import * from git.util import join_path_native from git.exc import BadObject -from gitdb.util import hex_to_bin, bin_to_hex +from gitdb.util import bin_to_hex import os import sys @@ -143,7 +142,7 @@ def test_init(self): for path in (git_dir_rela, git_dir_abs): r = Repo.init(path=path, bare=True) assert isinstance(r, Repo) - assert r.bare == True + assert r.bare is True assert os.path.isdir(r.git_dir) self._assert_empty_repo(r) @@ -179,7 +178,7 @@ def test_init(self): os.makedirs(git_dir_rela) os.chdir(git_dir_rela) r = Repo.init(bare=False) - r.bare == False + assert r.bare is False self._assert_empty_repo(r) finally: @@ -230,7 +229,7 @@ def test_is_dirty(self): # END index orig_val = self.rorepo._bare self.rorepo._bare = True - assert self.rorepo.is_dirty() == False + assert self.rorepo.is_dirty() is False self.rorepo._bare = orig_val def test_head(self): @@ -280,7 +279,7 @@ def test_blame_real(self): for item in self.rorepo.head.commit.tree.traverse( predicate=lambda i, d: i.type == 'blob' and i.path.endswith('.py')): c += 1 - b = self.rorepo.blame(self.rorepo.head, item.path) + self.rorepo.blame(self.rorepo.head, item.path) # END for each item to traverse assert c @@ -503,7 +502,7 @@ def test_rev_parse(self): assert obj.type == ref.object.type num_resolved += 1 except BadObject: - print "failed on %s" % path_section + print ("failed on %s" % path_section) # is fine, in case we have something like 112, which belongs to remotes/rname/merge-requests/112 pass # END exception handling diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 9c0085e88..e3223c428 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -32,7 +32,7 @@ class TestRootProgress(RootUpdateProgress): """Just prints messages, for now without checking the correctness of the states""" def update(self, op, index, max_count, message=''): - print message + print(message) prog = TestRootProgress() @@ -107,7 +107,6 @@ def _do_base_tests(self, rwrepo): # END handle bare repo # make the old into a new - this doesn't work as the name changed - prev_parent_commit = smold.parent_commit self.failUnlessRaises(ValueError, smold.set_parent_commit, self.k_subm_current) # the sha is properly updated smold.set_parent_commit(self.k_subm_changed + "~1") @@ -343,7 +342,6 @@ def _do_base_tests(self, rwrepo): # rename a module nmp = join_path_native("new", "module", "dir") + "/" # new module path pmp = nsm.path - abspmp = nsm.abspath assert nsm.move(nmp) is nsm nmp = nmp[:-1] # cut last / nmpl = to_native_path_linux(nmp) diff --git a/git/test/test_tree.py b/git/test/test_tree.py index 2c740f1ad..adcb854f4 100644 --- a/git/test/test_tree.py +++ b/git/test/test_tree.py @@ -7,10 +7,7 @@ import os from git.test.lib import * from git import * -from git.objects.fun import ( - traverse_tree_recursive, - traverse_trees_recursive -) + from cStringIO import StringIO diff --git a/git/test/test_util.py b/git/test/test_util.py index 1ba855af1..28aefa610 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -4,7 +4,6 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -import os import tempfile from git.util import * diff --git a/git/util.py b/git/util.py index 0408e3847..c29ed70bc 100644 --- a/git/util.py +++ b/git/util.py @@ -17,6 +17,8 @@ # Handle once test-cases are back up and running. from exc import GitCommandError +# Most of these are unused here, but are for use by git-python modules so these +# don't see gitdb all the time. Flake of course doesn't like it. from gitdb.util import ( make_sha, LockedFD, @@ -130,7 +132,7 @@ def finalize_process(proc): """Wait for the process (clone, fetch, pull or push) and handle its errors accordingly""" try: proc.wait() - except GitCommandError, e: + except GitCommandError: # if a push has rejected items, the command has non-zero return status # a return status of 128 indicates a connection error - reraise the previous one if proc.poll() == 128: diff --git a/requirements.txt b/requirements.txt index c9260b122..eedd64662 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ GitPython -gitdb>=0.6.0 +gitdb>=0.6.1 diff --git a/setup.py b/setup.py index 33f59c01c..5a4dd9e3e 100755 --- a/setup.py +++ b/setup.py @@ -66,7 +66,7 @@ def _stamp_version(filename): else: print >> sys.stderr, "WARNING: Couldn't find version line in file %s" % filename -install_requires = ['gitdb >= 0.6.0'] +install_requires = ['gitdb >= 0.6.1'] setup( name="GitPython", @@ -81,7 +81,7 @@ def _stamp_version(filename): package_data={'git.test': ['fixtures/*']}, package_dir={'git': 'git'}, license="BSD License", - requires=['gitdb (>=0.6.0)'], + requires=['gitdb (>=0.6.1)'], install_requires=install_requires, test_requirements=['mock', 'nose'] + install_requires, zip_safe=False, diff --git a/tox.ini b/tox.ini index 4d8273576..2b743870c 100644 --- a/tox.ini +++ b/tox.ini @@ -17,4 +17,6 @@ commands = {posargs} [flake8] #show-source = True +ignore = E265,F403 +max-line-length = 120 exclude = .tox,.venv,build,dist,doc,git/ext/ From 1b9d3b961bdf79964b883d3179f085d8835e528d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 14:25:39 +0100 Subject: [PATCH 0017/2790] Removed 'from X import *' whereever possible --- git/test/lib/__init__.py | 5 ++--- git/test/lib/asserts.py | 20 +++++++++++++---- git/test/performance/lib.py | 4 +++- git/test/performance/test_commit.py | 4 ++-- git/test/performance/test_odb.py | 2 +- git/test/performance/test_streams.py | 15 ++++++++----- git/test/performance/test_utils.py | 6 ++--- git/test/test_actor.py | 5 ++--- git/test/test_base.py | 14 ++++++++++-- git/test/test_blob.py | 7 ++++-- git/test/test_commit.py | 14 ++++++++++-- git/test/test_config.py | 9 ++++++-- git/test/test_db.py | 4 ++-- git/test/test_diff.py | 16 +++++++++++--- git/test/test_fun.py | 7 ++++-- git/test/test_index.py | 19 ++++++++++++++-- git/test/test_reflog.py | 10 +++++++-- git/test/test_refs.py | 17 +++++++++++--- git/test/test_remote.py | 20 +++++++++++++++-- git/test/test_repo.py | 33 ++++++++++++++++++++-------- git/test/test_stats.py | 10 ++++++--- git/test/test_submodule.py | 7 ++++-- git/test/test_tree.py | 7 ++++-- git/test/test_util.py | 21 ++++++++++++++---- 24 files changed, 209 insertions(+), 67 deletions(-) diff --git a/git/test/lib/__init__.py b/git/test/lib/__init__.py index 26ea13a35..033a11044 100644 --- a/git/test/lib/__init__.py +++ b/git/test/lib/__init__.py @@ -5,9 +5,8 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import inspect -from mock import * -from asserts import * -from helper import * +from .asserts import * +from .helper import * __all__ = [name for name, obj in locals().items() if not (name.startswith('_') or inspect.ismodule(obj))] diff --git a/git/test/lib/asserts.py b/git/test/lib/asserts.py index 6f6d8960f..98751d4dc 100644 --- a/git/test/lib/asserts.py +++ b/git/test/lib/asserts.py @@ -5,15 +5,27 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import re -from nose import tools -from nose.tools import * import stat __all__ = ['assert_instance_of', 'assert_not_instance_of', 'assert_none', 'assert_not_none', 'assert_match', 'assert_not_match', 'assert_mode_644', - 'assert_mode_755'] + tools.__all__ - + 'assert_mode_755', + 'assert_equal', 'assert_not_equal', 'assert_raises', 'patch', 'raises', + 'assert_true', 'assert_false'] + +from nose.tools import ( + assert_equal, + assert_not_equal, + assert_raises, + raises, + assert_true, + assert_false +) + +from mock import ( + patch +) def assert_instance_of(expected, actual, msg=None): """Verify that object is an instance of expected """ diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index 928821eda..5c138f177 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -1,6 +1,8 @@ """Contains library functions""" import os -from git.test.lib import * +from git.test.lib import ( + TestBase +) from gitdb.test.lib import skip_on_travis_ci import shutil import tempfile diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index c256a75c2..257442eae 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -4,8 +4,8 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from lib import * -from git import * +from .lib import TestBigRepoRW +from git import Commit from gitdb import IStream from git.test.test_commit import assert_commit_serialization from cStringIO import StringIO diff --git a/git/test/performance/test_odb.py b/git/test/performance/test_odb.py index 1b570fa76..779adb001 100644 --- a/git/test/performance/test_odb.py +++ b/git/test/performance/test_odb.py @@ -3,7 +3,7 @@ from time import time import sys -from lib import ( +from .lib import ( TestBigRepoR ) diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index 18f19db39..48527f0e2 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -1,20 +1,23 @@ """Performance data streaming performance""" - -from git.test.lib import * -from gitdb import * -from gitdb.util import bin_to_hex - from time import time import os import sys import subprocess +from git.test.lib import ( + with_rw_repo +) +from gitdb.util import bin_to_hex from gitdb.test.lib import make_memory_file -from lib import ( +from .lib import ( TestBigRepoR ) +from gitdb import ( + LooseObjectDB, + IStream +) class TestObjDBPerformance(TestBigRepoR): diff --git a/git/test/performance/test_utils.py b/git/test/performance/test_utils.py index e7c33aa22..0bd470988 100644 --- a/git/test/performance/test_utils.py +++ b/git/test/performance/test_utils.py @@ -2,7 +2,7 @@ from time import time import sys -from lib import ( +from .lib import ( TestBigRepoR ) @@ -93,14 +93,14 @@ def test_instantiation(self): # tuple and tuple direct st = time() for i in xrange(ni): - t = (1, 2, 3, 4) + (1, 2, 3, 4) # END for each item elapsed = time() - st print >> sys.stderr, "Created %i tuples (1,2,3,4) in %f s ( %f tuples / s)" % (ni, elapsed, ni / elapsed) st = time() for i in xrange(ni): - t = tuple((1, 2, 3, 4)) + tuple((1, 2, 3, 4)) # END for each item elapsed = time() - st print >> sys.stderr, "Created %i tuples tuple((1,2,3,4)) in %f s ( %f tuples / s)" % (ni, elapsed, ni / elapsed) diff --git a/git/test/test_actor.py b/git/test/test_actor.py index ee9684554..d79673f82 100644 --- a/git/test/test_actor.py +++ b/git/test/test_actor.py @@ -4,9 +4,8 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * - +from git.test.lib import assert_equal +from git import Actor class TestActor(object): diff --git a/git/test/test_base.py b/git/test/test_base.py index ea241f4cb..a14d46806 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -7,8 +7,18 @@ import git.objects.base as base import os -from git.test.lib import * -from git import * +from git.test.lib import ( + TestBase, + assert_raises, + with_rw_repo, + with_rw_and_rw_remote_repo +) +from git import ( + Blob, + Tree, + Commit, + TagObject +) from git.objects.util import get_object_type_by_name from gitdb.util import hex_to_bin diff --git a/git/test/test_blob.py b/git/test/test_blob.py index cf45d82ae..b529e80fb 100644 --- a/git/test/test_blob.py +++ b/git/test/test_blob.py @@ -4,8 +4,11 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * +from git.test.lib import ( + TestBase, + assert_equal +) +from git import Blob class TestBlob(TestBase): diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 22a302c69..961ae44f6 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -5,8 +5,18 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * +from git.test.lib import ( + TestBase, + assert_equal, + assert_not_equal, + with_rw_repo, + fixture_path, + StringProcessAdapter +) +from git import ( + Commit, + Actor, +) from gitdb import IStream from gitdb.util import hex_to_bin diff --git a/git/test/test_config.py b/git/test/test_config.py index 3e435c476..f470b143c 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -4,8 +4,13 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * +from git.test.lib import ( + TestCase, + fixture_path +) +from git import ( + GitConfigParser +) import StringIO from copy import copy from ConfigParser import NoSectionError diff --git a/git/test/test_db.py b/git/test/test_db.py index b53c42094..5dcf592a8 100644 --- a/git/test/test_db.py +++ b/git/test/test_db.py @@ -3,8 +3,8 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git.db import * +from git.test.lib import TestBase +from git.db import GitCmdObjectDB from gitdb.util import bin_to_hex from git.exc import BadObject import os diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 8e2cef4b0..adac5ed43 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -4,9 +4,19 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * - +from git.test.lib import ( + TestBase, + StringProcessAdapter, + fixture, + assert_equal, + assert_true, + +) + +from git import ( + Diff, + DiffIndex +) class TestDiff(TestBase): diff --git a/git/test/test_fun.py b/git/test/test_fun.py index 5fa0c77b7..bf178aaab 100644 --- a/git/test/test_fun.py +++ b/git/test/test_fun.py @@ -1,4 +1,7 @@ -from git.test.lib import * +from git.test.lib import ( + TestBase, + with_rw_repo +) from git.objects.fun import ( traverse_tree_recursive, traverse_trees_recursive, @@ -78,7 +81,7 @@ def mktree(self, odb, entries): @with_rw_repo('0.1.6') def test_three_way_merge(self, rwrepo): def mkfile(name, sha, executable=0): - return (sha, S_IFREG | 0644 | executable * 0111, name) + return (sha, S_IFREG | 0o644 | executable * 0o111, name) def mkcommit(name, sha): return (sha, S_IFDIR | S_IFLNK, name) diff --git a/git/test/test_index.py b/git/test/test_index.py index 08dfdd123..2eef4b5d7 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -4,8 +4,23 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * +from git.test.lib import ( + TestBase, + fixture_path, + fixture, + with_rw_repo +) +from git import ( + IndexFile, + BlobFilter, + UnmergedEntriesError, + Tree, + Object, + Diff, + GitCommandError, + CheckoutError, + +) from gitdb.util import hex_to_bin import os import sys diff --git a/git/test/test_reflog.py b/git/test/test_reflog.py index c281aa445..4efb8025b 100644 --- a/git/test/test_reflog.py +++ b/git/test/test_reflog.py @@ -1,6 +1,12 @@ -from git.test.lib import * +from git.test.lib import ( + TestBase, + fixture_path +) from git.objects import IndexObject -from git.refs import * +from git.refs import ( + RefLogEntry, + RefLog +) from git.util import Actor import tempfile diff --git a/git/test/test_refs.py b/git/test/test_refs.py index 4df3fa8a2..af33765ae 100644 --- a/git/test/test_refs.py +++ b/git/test/test_refs.py @@ -4,9 +4,20 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from mock import * -from git.test.lib import * -from git import * +from git.test.lib import ( + TestBase, + with_rw_repo +) +from git import ( + Reference, + Head, + TagReference, + RemoteReference, + Commit, + SymbolicReference, + GitCommandError, + RefLog +) import git.refs as refs from git.util import Actor from git.objects.tag import TagObject diff --git a/git/test/test_remote.py b/git/test/test_remote.py index d49a90612..a8d5179aa 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -4,8 +4,24 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * +from git.test.lib import ( + TestBase, + with_rw_repo, + with_rw_and_rw_remote_repo +) +from git import ( + RemoteProgress, + FetchInfo, + Reference, + SymbolicReference, + Head, + Commit, + PushInfo, + RemoteReference, + TagReference, + Remote, + GitCommandError +) from git.util import IterableList import tempfile import shutil diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 3f1a3a3cc..f6b46a6eb 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -3,15 +3,30 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import (patch, - TestBase, - with_rw_repo, - fixture, - assert_false, - assert_equal, - assert_true, - raises) -from git import * +from git.test.lib import ( + patch, + TestBase, + with_rw_repo, + fixture, + assert_false, + assert_equal, + assert_true, + raises +) +from git import ( + InvalidGitRepositoryError, + Repo, + NoSuchPathError, + Head, + Commit, + Tree, + IndexFile, + Git, + Reference, + GitDB, + Submodule, + GitCmdObjectDB +) from git.util import join_path_native from git.exc import BadObject from gitdb.util import bin_to_hex diff --git a/git/test/test_stats.py b/git/test/test_stats.py index d827c6802..c4535b751 100644 --- a/git/test/test_stats.py +++ b/git/test/test_stats.py @@ -4,13 +4,17 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git import * +from git.test.lib import ( + TestBase, + fixture, + assert_equal +) +from git import Stats class TestStats(TestBase): - def test__list_from_string(self): + def test_list_from_string(self): output = fixture('diff_numstat') stats = Stats._list_from_string(self.rorepo, output) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index e3223c428..ec3459e4f 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -1,8 +1,11 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import * -from git.exc import * +from git.test.lib import ( + TestBase, + with_rw_repo +) +from git.exc import InvalidGitRepositoryError from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress from git.util import to_native_path_linux, join_path_native diff --git a/git/test/test_tree.py b/git/test/test_tree.py index adcb854f4..d2e3606b0 100644 --- a/git/test/test_tree.py +++ b/git/test/test_tree.py @@ -5,8 +5,11 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os -from git.test.lib import * -from git import * +from git.test.lib import TestBase +from git import ( + Tree, + Blob +) from cStringIO import StringIO diff --git a/git/test/test_util.py b/git/test/test_util.py index 28aefa610..888eb4eee 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -6,10 +6,23 @@ import tempfile -from git.util import * -from git.test.lib import * -from git.objects.util import * -from git import * +from git.test.lib import ( + TestBase, + assert_equal +) +from git.util import ( + LockFile, + BlockingLockFile, + get_user_id, + Actor, + IterableList +) +from git.objects.util import ( + altz_to_utctz_str, + utctz_to_altz, + verify_utctz, + parse_date, +) from git.cmd import dashify import time From 6f55c17f48d7608072199496fbcefa33f2e97bf0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 15:39:28 +0100 Subject: [PATCH 0018/2790] Replaced ordered dict with standard version; used logging module All performance tests still print to stderr, but do so in a py3 compatible way --- doc/source/conf.py | 1 - git/cmd.py | 11 +- git/config.py | 8 +- git/objects/commit.py | 14 +- git/objects/submodule/base.py | 12 +- git/objects/submodule/root.py | 8 +- git/odict.py | 1545 +------------------------- git/refs/tag.py | 4 +- git/test/lib/asserts.py | 1 + git/test/lib/helper.py | 4 +- git/test/performance/test_commit.py | 16 +- git/test/performance/test_odb.py | 14 +- git/test/performance/test_streams.py | 35 +- git/test/performance/test_utils.py | 44 +- git/test/test_actor.py | 1 + git/test/test_commit.py | 5 +- git/test/test_config.py | 1 - git/test/test_diff.py | 1 + git/test/test_git.py | 4 +- git/test/test_index.py | 1 - setup.py | 8 +- 21 files changed, 122 insertions(+), 1616 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 2da09c669..942996b0b 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -21,7 +21,6 @@ # absolute, like shown here. #sys.path.append(os.path.abspath('.')) sys.path.insert(0, os.path.abspath('../..')) -print sys.path # General configuration # --------------------- diff --git a/git/cmd.py b/git/cmd.py index d024b4097..c355eacf9 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -6,6 +6,7 @@ import os import sys +import logging from util import ( LazyMixin, stream_copy @@ -22,6 +23,8 @@ 'with_exceptions', 'as_process', 'output_stream') +log = logging.getLogger('git.cmd') + __all__ = ('Git', ) @@ -334,7 +337,7 @@ def execute(self, command, If you add additional keyword arguments to the signature of this method, you must update the execute_kwargs tuple housed in this module.""" if self.GIT_PYTHON_TRACE and (self.GIT_PYTHON_TRACE != 'full' or as_process): - print(' '.join(command)) + log.info(' '.join(command)) # Allow the user to have the command executed in their working dir. if with_keep_cwd or self._working_dir is None: @@ -389,11 +392,11 @@ def execute(self, command, if self.GIT_PYTHON_TRACE == 'full': cmdstr = " ".join(command) if stderr_value: - print("%s -> %d; stdout: '%s'; stderr: '%s'" % (cmdstr, status, stdout_value, stderr_value)) + log.info("%s -> %d; stdout: '%s'; stderr: '%s'", cmdstr, status, stdout_value, stderr_value) elif stdout_value: - print("%s -> %d; stdout: '%s'" % (cmdstr, status, stdout_value)) + log.info("%s -> %d; stdout: '%s'", cmdstr, status, stdout_value) else: - print("%s -> %d" % (cmdstr, status)) + log.info("%s -> %d", cmdstr, status) # END handle debug printing if with_exceptions and status != 0: diff --git a/git/config.py b/git/config.py index 51337db4c..6a85760c2 100644 --- a/git/config.py +++ b/git/config.py @@ -9,6 +9,7 @@ import re import ConfigParser as cp import inspect +import logging from git.odict import OrderedDict from git.util import LockFile @@ -16,6 +17,9 @@ __all__ = ('GitConfigParser', 'SectionConstraint') +log = logging.getLogger('git.config') + + class MetaParserBuilder(type): """Utlity class wrapping base-class methods into decorators that assure read-only properties""" @@ -186,8 +190,8 @@ def __del__(self): try: try: self.write() - except IOError as e: - print("Exception during destruction of GitConfigParser: %s" % str(e)) + except IOError: + log.error("Exception during destruction of GitConfigParser", exc_info=True) finally: self._lock._release_lock() diff --git a/git/objects/commit.py b/git/objects/commit.py index 4a4a314c7..9c7336953 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -31,7 +31,9 @@ altzone ) import os -import sys +import logging + +log = logging.getLogger('git.objects.commit') __all__ = ('Commit', ) @@ -473,16 +475,16 @@ def _deserialize(self, stream): try: self.author.name = self.author.name.decode(self.encoding) except UnicodeDecodeError: - print >> sys.stderr, "Failed to decode author name '%s' using encoding %s" % ( - self.author.name, self.encoding) + log.error("Failed to decode author name '%s' using encoding %s", self.author.name, self.encoding, + exc_info=True) # END handle author's encoding # decode committer name try: self.committer.name = self.committer.name.decode(self.encoding) except UnicodeDecodeError: - print >> sys.stderr, "Failed to decode committer name '%s' using encoding %s" % ( - self.committer.name, self.encoding) + log.error("Failed to decode committer name '%s' using encoding %s", self.committer.name, self.encoding, + exc_info=True) # END handle author's encoding # a stream from our data simply gives us the plain message @@ -491,7 +493,7 @@ def _deserialize(self, stream): try: self.message = self.message.decode(self.encoding) except UnicodeDecodeError: - print >> sys.stderr, "Failed to decode message '%s' using encoding %s" % (self.message, self.encoding) + log.error("Failed to decode message '%s' using encoding %s", self.message, self.encoding, exc_info=True) # END exception handling return self diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 6951fd63f..d6f8982bb 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -27,11 +27,14 @@ import git import os -import sys +import logging __all__ = ["Submodule", "UpdateProgress"] +log = logging.getLogger('git.objects.submodule.base') + + class UpdateProgress(RemoteProgress): """Class providing detailed progress information to the caller who should @@ -408,7 +411,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= mrepo.head.set_reference(local_branch, logmsg="submodule: attaching head to %s" % local_branch) mrepo.head.ref.set_tracking_branch(remote_branch) except IndexError: - print >> sys.stderr, "Warning: Failed to checkout tracking branch %s" % self.branch_path + log.warn("Failed to checkout tracking branch %s", self.branch_path) # END handle tracking branch # NOTE: Have to write the repo config file as well, otherwise @@ -437,11 +440,10 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= binsha = rcommit.binsha hexsha = rcommit.hexsha else: - print >> sys.stderr, "%s a tracking branch was not set for local branch '%s'" % ( - msg_base, mrepo.head.ref) + log.error("%s a tracking branch was not set for local branch '%s'", msg_base, mrepo.head.ref) # END handle remote ref else: - print >> sys.stderr, "%s there was no local tracking branch" % msg_base + log.error("%s there was no local tracking branch", msg_base) # END handle detached head # END handle to_latest_revision option diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index 871cc21c4..708749c7b 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -5,10 +5,12 @@ from git.exc import InvalidGitRepositoryError import git -import sys +import logging __all__ = ["RootModule", "RootUpdateProgress"] +log = logging.getLogger('git.objects.submodule.root') + class RootUpdateProgress(UpdateProgress): @@ -247,8 +249,8 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= # this way, it will be checked out in the next step # This will change the submodule relative to us, so # the user will be able to commit the change easily - print >> sys.stderr, "WARNING: Current sha %s was not contained in the tracking\ - branch at the new remote, setting it the the remote's tracking branch" % sm.hexsha + log.warn("Current sha %s was not contained in the tracking\ + branch at the new remote, setting it the the remote's tracking branch", sm.hexsha) sm.binsha = rref.commit.binsha # END reset binsha diff --git a/git/odict.py b/git/odict.py index c505b7fd2..f003d14ec 100644 --- a/git/odict.py +++ b/git/odict.py @@ -1,1535 +1,10 @@ -# odict.py -# An Ordered Dictionary object -# Copyright (C) 2005 Nicola Larosa, Michael Foord -# E-mail: nico AT tekNico DOT net, fuzzyman AT voidspace DOT org DOT uk - -# This software is licensed under the terms of the BSD license. -# http://www.voidspace.org.uk/python/license.shtml -# Basically you're free to copy, modify, distribute and relicense it, -# So long as you keep a copy of the license with it. - -# Documentation at http://www.voidspace.org.uk/python/odict.html -# For information about bugfixes, updates and support, please join the -# Pythonutils mailing list: -# http://groups.google.com/group/pythonutils/ -# Comments, suggestions and bug reports welcome. - -"""A dict that keeps keys in insertion order""" -from __future__ import generators - -__author__ = ('Nicola Larosa ,' - 'Michael Foord ') - -__docformat__ = "restructuredtext en" - -__revision__ = '$Id: odict.py 129 2005-09-12 18:15:28Z teknico $' - -__version__ = '0.2.2' - -__all__ = ['OrderedDict', 'SequenceOrderedDict'] - -import sys -INTP_VER = sys.version_info[:2] -if INTP_VER < (2, 2): - raise RuntimeError("Python v.2.2 or later required") - -import types -import warnings - - -class OrderedDict(dict): - - """ - A class of dictionary that keeps the insertion order of keys. - - All appropriate methods return keys, items, or values in an ordered way. - - All normal dictionary methods are available. Update and comparison is - restricted to other OrderedDict objects. - - Various sequence methods are available, including the ability to explicitly - mutate the key ordering. - - __contains__ tests: - - >>> d = OrderedDict(((1, 3),)) - >>> 1 in d - 1 - >>> 4 in d - 0 - - __getitem__ tests: - - >>> OrderedDict(((1, 3), (3, 2), (2, 1)))[2] - 1 - >>> OrderedDict(((1, 3), (3, 2), (2, 1)))[4] - Traceback (most recent call last): - KeyError: 4 - - __len__ tests: - - >>> len(OrderedDict()) - 0 - >>> len(OrderedDict(((1, 3), (3, 2), (2, 1)))) - 3 - - get tests: - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.get(1) - 3 - >>> d.get(4) is None - 1 - >>> d.get(4, 5) - 5 - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1)]) - - has_key tests: - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.has_key(1) - 1 - >>> d.has_key(4) - 0 - """ - - def __init__(self, init_val=(), strict=False): - """ - Create a new ordered dictionary. Cannot init from a normal dict, - nor from kwargs, since items order is undefined in those cases. - - If the ``strict`` keyword argument is ``True`` (``False`` is the - default) then when doing slice assignment - the ``OrderedDict`` you are - assigning from *must not* contain any keys in the remaining dict. - - >>> OrderedDict() - OrderedDict([]) - >>> OrderedDict({1: 1}) - Traceback (most recent call last): - TypeError: undefined order, cannot get items from dict - >>> OrderedDict({1: 1}.items()) - OrderedDict([(1, 1)]) - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1)]) - >>> OrderedDict(d) - OrderedDict([(1, 3), (3, 2), (2, 1)]) - """ - self.strict = strict - dict.__init__(self) - if isinstance(init_val, OrderedDict): - self._sequence = init_val.keys() - dict.update(self, init_val) - elif isinstance(init_val, dict): - # we lose compatibility with other ordered dict types this way - raise TypeError('undefined order, cannot get items from dict') - else: - self._sequence = [] - self.update(init_val) - -### Special methods ### - - def __delitem__(self, key): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> del d[3] - >>> d - OrderedDict([(1, 3), (2, 1)]) - >>> del d[3] - Traceback (most recent call last): - KeyError: 3 - >>> d[3] = 2 - >>> d - OrderedDict([(1, 3), (2, 1), (3, 2)]) - >>> del d[0:1] - >>> d - OrderedDict([(2, 1), (3, 2)]) - """ - if isinstance(key, types.SliceType): - # FIXME: efficiency? - keys = self._sequence[key] - for entry in keys: - dict.__delitem__(self, entry) - del self._sequence[key] - else: - # do the dict.__delitem__ *first* as it raises - # the more appropriate error - dict.__delitem__(self, key) - self._sequence.remove(key) - - def __eq__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d == OrderedDict(d) - True - >>> d == OrderedDict(((1, 3), (2, 1), (3, 2))) - False - >>> d == OrderedDict(((1, 0), (3, 2), (2, 1))) - False - >>> d == OrderedDict(((0, 3), (3, 2), (2, 1))) - False - >>> d == dict(d) - False - >>> d == False - False - """ - if isinstance(other, OrderedDict): - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() == other.items()) - else: - return False - - def __lt__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> c < d - True - >>> d < c - False - >>> d < dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() < other.items()) - - def __le__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> e = OrderedDict(d) - >>> c <= d - True - >>> d <= c - False - >>> d <= dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - >>> d <= e - True - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() <= other.items()) - - def __ne__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d != OrderedDict(d) - False - >>> d != OrderedDict(((1, 3), (2, 1), (3, 2))) - True - >>> d != OrderedDict(((1, 0), (3, 2), (2, 1))) - True - >>> d == OrderedDict(((0, 3), (3, 2), (2, 1))) - False - >>> d != dict(d) - True - >>> d != False - True - """ - if isinstance(other, OrderedDict): - # FIXME: efficiency? - # Generate both item lists for each compare - return not (self.items() == other.items()) - else: - return True - - def __gt__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> d > c - True - >>> c > d - False - >>> d > dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() > other.items()) - - def __ge__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> e = OrderedDict(d) - >>> c >= d - False - >>> d >= c - True - >>> d >= dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - >>> e >= d - True - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() >= other.items()) - - def __repr__(self): - """ - Used for __repr__ and __str__ - - >>> r1 = repr(OrderedDict((('a', 'b'), ('c', 'd'), ('e', 'f')))) - >>> r1 - "OrderedDict([('a', 'b'), ('c', 'd'), ('e', 'f')])" - >>> r2 = repr(OrderedDict((('a', 'b'), ('e', 'f'), ('c', 'd')))) - >>> r2 - "OrderedDict([('a', 'b'), ('e', 'f'), ('c', 'd')])" - >>> r1 == str(OrderedDict((('a', 'b'), ('c', 'd'), ('e', 'f')))) - True - >>> r2 == str(OrderedDict((('a', 'b'), ('e', 'f'), ('c', 'd')))) - True - """ - return '%s([%s])' % (self.__class__.__name__, ', '.join( - ['(%r, %r)' % (key, self[key]) for key in self._sequence])) - - def __setitem__(self, key, val): - """ - Allows slice assignment, so long as the slice is an OrderedDict - >>> d = OrderedDict() - >>> d['a'] = 'b' - >>> d['b'] = 'a' - >>> d[3] = 12 - >>> d - OrderedDict([('a', 'b'), ('b', 'a'), (3, 12)]) - >>> d[:] = OrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - OrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d[::2] = OrderedDict(((7, 8), (9, 10))) - >>> d - OrderedDict([(7, 8), (2, 3), (9, 10)]) - >>> d = OrderedDict(((0, 1), (1, 2), (2, 3), (3, 4))) - >>> d[1:3] = OrderedDict(((1, 2), (5, 6), (7, 8))) - >>> d - OrderedDict([(0, 1), (1, 2), (5, 6), (7, 8), (3, 4)]) - >>> d = OrderedDict(((0, 1), (1, 2), (2, 3), (3, 4)), strict=True) - >>> d[1:3] = OrderedDict(((1, 2), (5, 6), (7, 8))) - >>> d - OrderedDict([(0, 1), (1, 2), (5, 6), (7, 8), (3, 4)]) - - >>> a = OrderedDict(((0, 1), (1, 2), (2, 3)), strict=True) - >>> a[3] = 4 - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[::1] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[:2] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]) - Traceback (most recent call last): - ValueError: slice assignment must be from unique keys - >>> a = OrderedDict(((0, 1), (1, 2), (2, 3))) - >>> a[3] = 4 - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[::1] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[:2] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[::-1] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(3, 4), (2, 3), (1, 2), (0, 1)]) - - >>> d = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> d[:1] = 3 - Traceback (most recent call last): - TypeError: slice assignment requires an OrderedDict - - >>> d = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> d[:1] = OrderedDict([(9, 8)]) - >>> d - OrderedDict([(9, 8), (1, 2), (2, 3), (3, 4)]) - """ - if isinstance(key, types.SliceType): - if not isinstance(val, OrderedDict): - # FIXME: allow a list of tuples? - raise TypeError('slice assignment requires an OrderedDict') - keys = self._sequence[key] - # NOTE: Could use ``range(*key.indices(len(self._sequence)))`` - indexes = range(len(self._sequence))[key] - if key.step is None: - # NOTE: new slice may not be the same size as the one being - # overwritten ! - # NOTE: What is the algorithm for an impossible slice? - # e.g. d[5:3] - pos = key.start or 0 - del self[key] - newkeys = val.keys() - for k in newkeys: - if k in self: - if self.strict: - raise ValueError('slice assignment must be from ' - 'unique keys') - else: - # NOTE: This removes duplicate keys *first* - # so start position might have changed? - del self[k] - self._sequence = (self._sequence[:pos] + newkeys + - self._sequence[pos:]) - dict.update(self, val) - else: - # extended slice - length of new slice must be the same - # as the one being replaced - if len(keys) != len(val): - raise ValueError('attempt to assign sequence of size %s ' - 'to extended slice of size %s' % (len(val), len(keys))) - # FIXME: efficiency? - del self[key] - item_list = zip(indexes, val.items()) - # smallest indexes first - higher indexes not guaranteed to - # exist - item_list.sort() - for pos, (newkey, newval) in item_list: - if self.strict and newkey in self: - raise ValueError('slice assignment must be from unique' - ' keys') - self.insert(pos, newkey, newval) - else: - if key not in self: - self._sequence.append(key) - dict.__setitem__(self, key, val) - - def __getitem__(self, key): - """ - Allows slicing. Returns an OrderedDict if you slice. - >>> b = OrderedDict([(7, 0), (6, 1), (5, 2), (4, 3), (3, 4), (2, 5), (1, 6)]) - >>> b[::-1] - OrderedDict([(1, 6), (2, 5), (3, 4), (4, 3), (5, 2), (6, 1), (7, 0)]) - >>> b[2:5] - OrderedDict([(5, 2), (4, 3), (3, 4)]) - >>> type(b[2:4]) - - """ - if isinstance(key, types.SliceType): - # FIXME: does this raise the error we want? - keys = self._sequence[key] - # FIXME: efficiency? - return OrderedDict([(entry, self[entry]) for entry in keys]) - else: - return dict.__getitem__(self, key) - - __str__ = __repr__ - - def __setattr__(self, name, value): - """ - Implemented so that accesses to ``sequence`` raise a warning and are - diverted to the new ``setkeys`` method. - """ - if name == 'sequence': - warnings.warn('Use of the sequence attribute is deprecated.' - ' Use the keys method instead.', DeprecationWarning) - # NOTE: doesn't return anything - self.setkeys(value) - else: - # FIXME: do we want to allow arbitrary setting of attributes? - # Or do we want to manage it? - object.__setattr__(self, name, value) - - def __getattr__(self, name): - """ - Implemented so that access to ``sequence`` raises a warning. - - >>> d = OrderedDict() - >>> d.sequence - [] - """ - if name == 'sequence': - warnings.warn('Use of the sequence attribute is deprecated.' - ' Use the keys method instead.', DeprecationWarning) - # NOTE: Still (currently) returns a direct reference. Need to - # because code that uses sequence will expect to be able to - # mutate it in place. - return self._sequence - else: - # raise the appropriate error - raise AttributeError("OrderedDict has no '%s' attribute" % name) - - def __deepcopy__(self, memo): - """ - To allow deepcopy to work with OrderedDict. - - >>> from copy import deepcopy - >>> a = OrderedDict([(1, 1), (2, 2), (3, 3)]) - >>> a['test'] = {} - >>> b = deepcopy(a) - >>> b == a - True - >>> b is a - False - >>> a['test'] is b['test'] - False - """ - from copy import deepcopy - return self.__class__(deepcopy(self.items(), memo), self.strict) - - -### Read-only methods ### - - def copy(self): - """ - >>> OrderedDict(((1, 3), (3, 2), (2, 1))).copy() - OrderedDict([(1, 3), (3, 2), (2, 1)]) - """ - return OrderedDict(self) - - def items(self): - """ - ``items`` returns a list of tuples representing all the - ``(key, value)`` pairs in the dictionary. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.items() - [(1, 3), (3, 2), (2, 1)] - >>> d.clear() - >>> d.items() - [] - """ - return zip(self._sequence, self.values()) - - def keys(self): - """ - Return a list of keys in the ``OrderedDict``. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.keys() - [1, 3, 2] - """ - return self._sequence[:] - - def values(self, values=None): - """ - Return a list of all the values in the OrderedDict. - - Optionally you can pass in a list of values, which will replace the - current list. The value list must be the same len as the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.values() - [3, 2, 1] - """ - return [self[key] for key in self._sequence] - - def iteritems(self): - """ - >>> ii = OrderedDict(((1, 3), (3, 2), (2, 1))).iteritems() - >>> ii.next() - (1, 3) - >>> ii.next() - (3, 2) - >>> ii.next() - (2, 1) - >>> ii.next() - Traceback (most recent call last): - StopIteration - """ - - def make_iter(self=self): - keys = self.iterkeys() - while True: - key = keys.next() - yield (key, self[key]) - return make_iter() - - def iterkeys(self): - """ - >>> ii = OrderedDict(((1, 3), (3, 2), (2, 1))).iterkeys() - >>> ii.next() - 1 - >>> ii.next() - 3 - >>> ii.next() - 2 - >>> ii.next() - Traceback (most recent call last): - StopIteration - """ - return iter(self._sequence) - - __iter__ = iterkeys - - def itervalues(self): - """ - >>> iv = OrderedDict(((1, 3), (3, 2), (2, 1))).itervalues() - >>> iv.next() - 3 - >>> iv.next() - 2 - >>> iv.next() - 1 - >>> iv.next() - Traceback (most recent call last): - StopIteration - """ - - def make_iter(self=self): - keys = self.iterkeys() - while True: - yield self[keys.next()] - return make_iter() - -### Read-write methods ### - - def clear(self): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.clear() - >>> d - OrderedDict([]) - """ - dict.clear(self) - self._sequence = [] - - def pop(self, key, *args): - """ - No dict.pop in Python 2.2, gotta reimplement it - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.pop(3) - 2 - >>> d - OrderedDict([(1, 3), (2, 1)]) - >>> d.pop(4) - Traceback (most recent call last): - KeyError: 4 - >>> d.pop(4, 0) - 0 - >>> d.pop(4, 0, 1) - Traceback (most recent call last): - TypeError: pop expected at most 2 arguments, got 3 - """ - if len(args) > 1: - raise TypeError('pop expected at most 2 arguments, got %s' % (len(args) + 1)) - if key in self: - val = self[key] - del self[key] - else: - try: - val = args[0] - except IndexError: - raise KeyError(key) - return val - - def popitem(self, i=-1): - """ - Delete and return an item specified by index, not a random one as in - dict. The index is -1 by default (the last item). - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.popitem() - (2, 1) - >>> d - OrderedDict([(1, 3), (3, 2)]) - >>> d.popitem(0) - (1, 3) - >>> OrderedDict().popitem() - Traceback (most recent call last): - KeyError: 'popitem(): dictionary is empty' - >>> d.popitem(2) - Traceback (most recent call last): - IndexError: popitem(): index 2 not valid - """ - if not self._sequence: - raise KeyError('popitem(): dictionary is empty') - try: - key = self._sequence[i] - except IndexError: - raise IndexError('popitem(): index %s not valid' % i) - return (key, self.pop(key)) - - def setdefault(self, key, defval=None): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.setdefault(1) - 3 - >>> d.setdefault(4) is None - True - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1), (4, None)]) - >>> d.setdefault(5, 0) - 0 - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1), (4, None), (5, 0)]) - """ - if key in self: - return self[key] - else: - self[key] = defval - return defval - - def update(self, from_od): - """ - Update from another OrderedDict or sequence of (key, value) pairs - - >>> d = OrderedDict(((1, 0), (0, 1))) - >>> d.update(OrderedDict(((1, 3), (3, 2), (2, 1)))) - >>> d - OrderedDict([(1, 3), (0, 1), (3, 2), (2, 1)]) - >>> d.update({4: 4}) - Traceback (most recent call last): - TypeError: undefined order, cannot get items from dict - >>> d.update((4, 4)) - Traceback (most recent call last): - TypeError: cannot convert dictionary update sequence element "4" to a 2-item sequence - """ - if isinstance(from_od, OrderedDict): - for key, val in from_od.items(): - self[key] = val - elif isinstance(from_od, dict): - # we lose compatibility with other ordered dict types this way - raise TypeError('undefined order, cannot get items from dict') - else: - # FIXME: efficiency? - # sequence of 2-item sequences, or error - for item in from_od: - try: - key, val = item - except TypeError: - raise TypeError('cannot convert dictionary update' - ' sequence element "%s" to a 2-item sequence' % item) - self[key] = val - - def rename(self, old_key, new_key): - """ - Rename the key for a given value, without modifying sequence order. - - For the case where new_key already exists this raise an exception, - since if new_key exists, it is ambiguous as to what happens to the - associated values, and the position of new_key in the sequence. - - >>> od = OrderedDict() - >>> od['a'] = 1 - >>> od['b'] = 2 - >>> od.items() - [('a', 1), ('b', 2)] - >>> od.rename('b', 'c') - >>> od.items() - [('a', 1), ('c', 2)] - >>> od.rename('c', 'a') - Traceback (most recent call last): - ValueError: New key already exists: 'a' - >>> od.rename('d', 'b') - Traceback (most recent call last): - KeyError: 'd' - """ - if new_key == old_key: - # no-op - return - if new_key in self: - raise ValueError("New key already exists: %r" % new_key) - # rename sequence entry - value = self[old_key] - old_idx = self._sequence.index(old_key) - self._sequence[old_idx] = new_key - # rename internal dict entry - dict.__delitem__(self, old_key) - dict.__setitem__(self, new_key, value) - - def setitems(self, items): - """ - This method allows you to set the items in the dict. - - It takes a list of tuples - of the same sort returned by the ``items`` - method. - - >>> d = OrderedDict() - >>> d.setitems(((3, 1), (2, 3), (1, 2))) - >>> d - OrderedDict([(3, 1), (2, 3), (1, 2)]) - """ - self.clear() - # FIXME: this allows you to pass in an OrderedDict as well :-) - self.update(items) - - def setkeys(self, keys): - """ - ``setkeys`` all ows you to pass in a new list of keys which will - replace the current set. This must contain the same set of keys, but - need not be in the same order. - - If you pass in new keys that don't match, a ``KeyError`` will be - raised. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.keys() - [1, 3, 2] - >>> d.setkeys((1, 2, 3)) - >>> d - OrderedDict([(1, 3), (2, 1), (3, 2)]) - >>> d.setkeys(['a', 'b', 'c']) - Traceback (most recent call last): - KeyError: 'Keylist is not the same as current keylist.' - """ - # FIXME: Efficiency? (use set for Python 2.4 :-) - # NOTE: list(keys) rather than keys[:] because keys[:] returns - # a tuple, if keys is a tuple. - kcopy = list(keys) - kcopy.sort() - self._sequence.sort() - if kcopy != self._sequence: - raise KeyError('Keylist is not the same as current keylist.') - # NOTE: This makes the _sequence attribute a new object, instead - # of changing it in place. - # FIXME: efficiency? - self._sequence = list(keys) - - def setvalues(self, values): - """ - You can pass in a list of values, which will replace the - current list. The value list must be the same len as the OrderedDict. - - (Or a ``ValueError`` is raised.) - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.setvalues((1, 2, 3)) - >>> d - OrderedDict([(1, 1), (3, 2), (2, 3)]) - >>> d.setvalues([6]) - Traceback (most recent call last): - ValueError: Value list is not the same length as the OrderedDict. - """ - if len(values) != len(self): - # FIXME: correct error to raise? - raise ValueError('Value list is not the same length as the ' - 'OrderedDict.') - self.update(zip(self, values)) - -### Sequence Methods ### - - def index(self, key): - """ - Return the position of the specified key in the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.index(3) - 1 - >>> d.index(4) - Traceback (most recent call last): - ValueError: list.index(x): x not in list - """ - return self._sequence.index(key) - - def insert(self, index, key, value): - """ - Takes ``index``, ``key``, and ``value`` as arguments. - - Sets ``key`` to ``value``, so that ``key`` is at position ``index`` in - the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.insert(0, 4, 0) - >>> d - OrderedDict([(4, 0), (1, 3), (3, 2), (2, 1)]) - >>> d.insert(0, 2, 1) - >>> d - OrderedDict([(2, 1), (4, 0), (1, 3), (3, 2)]) - >>> d.insert(8, 8, 1) - >>> d - OrderedDict([(2, 1), (4, 0), (1, 3), (3, 2), (8, 1)]) - """ - if key in self: - # FIXME: efficiency? - del self[key] - self._sequence.insert(index, key) - dict.__setitem__(self, key, value) - - def reverse(self): - """ - Reverse the order of the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.reverse() - >>> d - OrderedDict([(2, 1), (3, 2), (1, 3)]) - """ - self._sequence.reverse() - - def sort(self, *args, **kwargs): - """ - Sort the key order in the OrderedDict. - - This method takes the same arguments as the ``list.sort`` method on - your version of Python. - - >>> d = OrderedDict(((4, 1), (2, 2), (3, 3), (1, 4))) - >>> d.sort() - >>> d - OrderedDict([(1, 4), (2, 2), (3, 3), (4, 1)]) - """ - self._sequence.sort(*args, **kwargs) - - -class Keys(object): - # FIXME: should this object be a subclass of list? - - """ - Custom object for accessing the keys of an OrderedDict. - - Can be called like the normal ``OrderedDict.keys`` method, but also - supports indexing and sequence methods. - """ - - def __init__(self, main): - self._main = main - - def __call__(self): - """Pretend to be the keys method.""" - return self._main._keys() - - def __getitem__(self, index): - """Fetch the key at position i.""" - # NOTE: this automatically supports slicing :-) - return self._main._sequence[index] - - def __setitem__(self, index, name): - """ - You cannot assign to keys, but you can do slice assignment to re-order - them. - - You can only do slice assignment if the new set of keys is a reordering - of the original set. - """ - if isinstance(index, types.SliceType): - # FIXME: efficiency? - # check length is the same - indexes = range(len(self._main._sequence))[index] - if len(indexes) != len(name): - raise ValueError('attempt to assign sequence of size %s ' - 'to slice of size %s' % (len(name), len(indexes))) - # check they are the same keys - # FIXME: Use set - old_keys = self._main._sequence[index] - new_keys = list(name) - old_keys.sort() - new_keys.sort() - if old_keys != new_keys: - raise KeyError('Keylist is not the same as current keylist.') - orig_vals = [self._main[k] for k in name] - del self._main[index] - vals = zip(indexes, name, orig_vals) - vals.sort() - for i, k, v in vals: - if self._main.strict and k in self._main: - raise ValueError('slice assignment must be from ' - 'unique keys') - self._main.insert(i, k, v) - else: - raise ValueError('Cannot assign to keys') - - ### following methods pinched from UserList and adapted ### - def __repr__(self): - return repr(self._main._sequence) - - # FIXME: do we need to check if we are comparing with another ``Keys`` - # object? (like the __cast method of UserList) - def __lt__(self, other): - return self._main._sequence < other - - def __le__(self, other): - return self._main._sequence <= other - - def __eq__(self, other): - return self._main._sequence == other - - def __ne__(self, other): - return self._main._sequence != other - - def __gt__(self, other): - return self._main._sequence > other - - def __ge__(self, other): - return self._main._sequence >= other - # FIXME: do we need __cmp__ as well as rich comparisons? - - def __cmp__(self, other): - return cmp(self._main._sequence, other) - - def __contains__(self, item): - return item in self._main._sequence - - def __len__(self): - return len(self._main._sequence) - - def __iter__(self): - return self._main.iterkeys() - - def count(self, item): - return self._main._sequence.count(item) - - def index(self, item, *args): - return self._main._sequence.index(item, *args) - - def reverse(self): - self._main._sequence.reverse() - - def sort(self, *args, **kwds): - self._main._sequence.sort(*args, **kwds) - - def __mul__(self, n): - return self._main._sequence * n - __rmul__ = __mul__ - - def __add__(self, other): - return self._main._sequence + other - - def __radd__(self, other): - return other + self._main._sequence - - ## following methods not implemented for keys ## - def __delitem__(self, i): - raise TypeError('Can\'t delete items from keys') - - def __iadd__(self, other): - raise TypeError('Can\'t add in place to keys') - - def __imul__(self, n): - raise TypeError('Can\'t multiply keys in place') - - def append(self, item): - raise TypeError('Can\'t append items to keys') - - def insert(self, i, item): - raise TypeError('Can\'t insert items into keys') - - def pop(self, i=-1): - raise TypeError('Can\'t pop items from keys') - - def remove(self, item): - raise TypeError('Can\'t remove items from keys') - - def extend(self, other): - raise TypeError('Can\'t extend keys') - - -class Items(object): - - """ - Custom object for accessing the items of an OrderedDict. - - Can be called like the normal ``OrderedDict.items`` method, but also - supports indexing and sequence methods. - """ - - def __init__(self, main): - self._main = main - - def __call__(self): - """Pretend to be the items method.""" - return self._main._items() - - def __getitem__(self, index): - """Fetch the item at position i.""" - if isinstance(index, types.SliceType): - # fetching a slice returns an OrderedDict - return self._main[index].items() - key = self._main._sequence[index] - return (key, self._main[key]) - - def __setitem__(self, index, item): - """Set item at position i to item.""" - if isinstance(index, types.SliceType): - # NOTE: item must be an iterable (list of tuples) - self._main[index] = OrderedDict(item) - else: - # FIXME: Does this raise a sensible error? - orig = self._main.keys[index] - key, value = item - if self._main.strict and key in self and (key != orig): - raise ValueError('slice assignment must be from ' - 'unique keys') - # delete the current one - del self._main[self._main._sequence[index]] - self._main.insert(index, key, value) - - def __delitem__(self, i): - """Delete the item at position i.""" - key = self._main._sequence[i] - if isinstance(i, types.SliceType): - for k in key: - # FIXME: efficiency? - del self._main[k] - else: - del self._main[key] - - ### following methods pinched from UserList and adapted ### - def __repr__(self): - return repr(self._main.items()) - - # FIXME: do we need to check if we are comparing with another ``Items`` - # object? (like the __cast method of UserList) - def __lt__(self, other): - return self._main.items() < other - - def __le__(self, other): - return self._main.items() <= other - - def __eq__(self, other): - return self._main.items() == other - - def __ne__(self, other): - return self._main.items() != other - - def __gt__(self, other): - return self._main.items() > other - - def __ge__(self, other): - return self._main.items() >= other - - def __cmp__(self, other): - return cmp(self._main.items(), other) - - def __contains__(self, item): - return item in self._main.items() - - def __len__(self): - return len(self._main._sequence) # easier :-) - - def __iter__(self): - return self._main.iteritems() - - def count(self, item): - return self._main.items().count(item) - - def index(self, item, *args): - return self._main.items().index(item, *args) - - def reverse(self): - self._main.reverse() - - def sort(self, *args, **kwds): - self._main.sort(*args, **kwds) - - def __mul__(self, n): - return self._main.items() * n - __rmul__ = __mul__ - - def __add__(self, other): - return self._main.items() + other - - def __radd__(self, other): - return other + self._main.items() - - def append(self, item): - """Add an item to the end.""" - # FIXME: this is only append if the key isn't already present - key, value = item - self._main[key] = value - - def insert(self, i, item): - key, value = item - self._main.insert(i, key, value) - - def pop(self, i=-1): - key = self._main._sequence[i] - return (key, self._main.pop(key)) - - def remove(self, item): - key, value = item - try: - assert value == self._main[key] - except (KeyError, AssertionError): - raise ValueError('ValueError: list.remove(x): x not in list') - else: - del self._main[key] - - def extend(self, other): - # FIXME: is only a true extend if none of the keys already present - for item in other: - key, value = item - self._main[key] = value - - def __iadd__(self, other): - self.extend(other) - - ## following methods not implemented for items ## - - def __imul__(self, n): - raise TypeError('Can\'t multiply items in place') - - -class Values(object): - - """ - Custom object for accessing the values of an OrderedDict. - - Can be called like the normal ``OrderedDict.values`` method, but also - supports indexing and sequence methods. - """ - - def __init__(self, main): - self._main = main - - def __call__(self): - """Pretend to be the values method.""" - return self._main._values() - - def __getitem__(self, index): - """Fetch the value at position i.""" - if isinstance(index, types.SliceType): - return [self._main[key] for key in self._main._sequence[index]] - else: - return self._main[self._main._sequence[index]] - - def __setitem__(self, index, value): - """ - Set the value at position i to value. - - You can only do slice assignment to values if you supply a sequence of - equal length to the slice you are replacing. - """ - if isinstance(index, types.SliceType): - keys = self._main._sequence[index] - if len(keys) != len(value): - raise ValueError('attempt to assign sequence of size %s ' - 'to slice of size %s' % (len(value), len(keys))) - # FIXME: efficiency? Would be better to calculate the indexes - # directly from the slice object - # NOTE: the new keys can collide with existing keys (or even - # contain duplicates) - these will overwrite - for key, val in zip(keys, value): - self._main[key] = val - else: - self._main[self._main._sequence[index]] = value - - ### following methods pinched from UserList and adapted ### - def __repr__(self): - return repr(self._main.values()) - - # FIXME: do we need to check if we are comparing with another ``Values`` - # object? (like the __cast method of UserList) - def __lt__(self, other): - return self._main.values() < other - - def __le__(self, other): - return self._main.values() <= other - - def __eq__(self, other): - return self._main.values() == other - - def __ne__(self, other): - return self._main.values() != other - - def __gt__(self, other): - return self._main.values() > other - - def __ge__(self, other): - return self._main.values() >= other - - def __cmp__(self, other): - return cmp(self._main.values(), other) - - def __contains__(self, item): - return item in self._main.values() - - def __len__(self): - return len(self._main._sequence) # easier :-) - - def __iter__(self): - return self._main.itervalues() - - def count(self, item): - return self._main.values().count(item) - - def index(self, item, *args): - return self._main.values().index(item, *args) - - def reverse(self): - """Reverse the values""" - vals = self._main.values() - vals.reverse() - # FIXME: efficiency - self[:] = vals - - def sort(self, *args, **kwds): - """Sort the values.""" - vals = self._main.values() - vals.sort(*args, **kwds) - self[:] = vals - - def __mul__(self, n): - return self._main.values() * n - __rmul__ = __mul__ - - def __add__(self, other): - return self._main.values() + other - - def __radd__(self, other): - return other + self._main.values() - - ## following methods not implemented for values ## - def __delitem__(self, i): - raise TypeError('Can\'t delete items from values') - - def __iadd__(self, other): - raise TypeError('Can\'t add in place to values') - - def __imul__(self, n): - raise TypeError('Can\'t multiply values in place') - - def append(self, item): - raise TypeError('Can\'t append items to values') - - def insert(self, i, item): - raise TypeError('Can\'t insert items into values') - - def pop(self, i=-1): - raise TypeError('Can\'t pop items from values') - - def remove(self, item): - raise TypeError('Can\'t remove items from values') - - def extend(self, other): - raise TypeError('Can\'t extend values') - - -class SequenceOrderedDict(OrderedDict): - - """ - Experimental version of OrderedDict that has a custom object for ``keys``, - ``values``, and ``items``. - - These are callable sequence objects that work as methods, or can be - manipulated directly as sequences. - - Test for ``keys``, ``items`` and ``values``. - - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.keys - [1, 2, 3] - >>> d.keys() - [1, 2, 3] - >>> d.setkeys((3, 2, 1)) - >>> d - SequenceOrderedDict([(3, 4), (2, 3), (1, 2)]) - >>> d.setkeys((1, 2, 3)) - >>> d.keys[0] - 1 - >>> d.keys[:] - [1, 2, 3] - >>> d.keys[-1] - 3 - >>> d.keys[-2] - 2 - >>> d.keys[0:2] = [2, 1] - >>> d - SequenceOrderedDict([(2, 3), (1, 2), (3, 4)]) - >>> d.keys.reverse() - >>> d.keys - [3, 1, 2] - >>> d.keys = [1, 2, 3] - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.keys = [3, 1, 2] - >>> d - SequenceOrderedDict([(3, 4), (1, 2), (2, 3)]) - >>> a = SequenceOrderedDict() - >>> b = SequenceOrderedDict() - >>> a.keys == b.keys - 1 - >>> a['a'] = 3 - >>> a.keys == b.keys - 0 - >>> b['a'] = 3 - >>> a.keys == b.keys - 1 - >>> b['b'] = 3 - >>> a.keys == b.keys - 0 - >>> a.keys > b.keys - 0 - >>> a.keys < b.keys - 1 - >>> 'a' in a.keys - 1 - >>> len(b.keys) - 2 - >>> 'c' in d.keys - 0 - >>> 1 in d.keys - 1 - >>> [v for v in d.keys] - [3, 1, 2] - >>> d.keys.sort() - >>> d.keys - [1, 2, 3] - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4)), strict=True) - >>> d.keys[::-1] = [1, 2, 3] - >>> d - SequenceOrderedDict([(3, 4), (2, 3), (1, 2)]) - >>> d.keys[:2] - [3, 2] - >>> d.keys[:2] = [1, 3] - Traceback (most recent call last): - KeyError: 'Keylist is not the same as current keylist.' - - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.values - [2, 3, 4] - >>> d.values() - [2, 3, 4] - >>> d.setvalues((4, 3, 2)) - >>> d - SequenceOrderedDict([(1, 4), (2, 3), (3, 2)]) - >>> d.values[::-1] - [2, 3, 4] - >>> d.values[0] - 4 - >>> d.values[-2] - 3 - >>> del d.values[0] - Traceback (most recent call last): - TypeError: Can't delete items from values - >>> d.values[::2] = [2, 4] - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> 7 in d.values - 0 - >>> len(d.values) - 3 - >>> [val for val in d.values] - [2, 3, 4] - >>> d.values[-1] = 2 - >>> d.values.count(2) - 2 - >>> d.values.index(2) - 0 - >>> d.values[-1] = 7 - >>> d.values - [2, 3, 7] - >>> d.values.reverse() - >>> d.values - [7, 3, 2] - >>> d.values.sort() - >>> d.values - [2, 3, 7] - >>> d.values.append('anything') - Traceback (most recent call last): - TypeError: Can't append items to values - >>> d.values = (1, 2, 3) - >>> d - SequenceOrderedDict([(1, 1), (2, 2), (3, 3)]) - - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.items() - [(1, 2), (2, 3), (3, 4)] - >>> d.setitems([(3, 4), (2 ,3), (1, 2)]) - >>> d - SequenceOrderedDict([(3, 4), (2, 3), (1, 2)]) - >>> d.items[0] - (3, 4) - >>> d.items[:-1] - [(3, 4), (2, 3)] - >>> d.items[1] = (6, 3) - >>> d.items - [(3, 4), (6, 3), (1, 2)] - >>> d.items[1:2] = [(9, 9)] - >>> d - SequenceOrderedDict([(3, 4), (9, 9), (1, 2)]) - >>> del d.items[1:2] - >>> d - SequenceOrderedDict([(3, 4), (1, 2)]) - >>> (3, 4) in d.items - 1 - >>> (4, 3) in d.items - 0 - >>> len(d.items) - 2 - >>> [v for v in d.items] - [(3, 4), (1, 2)] - >>> d.items.count((3, 4)) - 1 - >>> d.items.index((1, 2)) - 1 - >>> d.items.index((2, 1)) - Traceback (most recent call last): - ValueError: list.index(x): x not in list - >>> d.items.reverse() - >>> d.items - [(1, 2), (3, 4)] - >>> d.items.reverse() - >>> d.items.sort() - >>> d.items - [(1, 2), (3, 4)] - >>> d.items.append((5, 6)) - >>> d.items - [(1, 2), (3, 4), (5, 6)] - >>> d.items.insert(0, (0, 0)) - >>> d.items - [(0, 0), (1, 2), (3, 4), (5, 6)] - >>> d.items.insert(-1, (7, 8)) - >>> d.items - [(0, 0), (1, 2), (3, 4), (7, 8), (5, 6)] - >>> d.items.pop() - (5, 6) - >>> d.items - [(0, 0), (1, 2), (3, 4), (7, 8)] - >>> d.items.remove((1, 2)) - >>> d.items - [(0, 0), (3, 4), (7, 8)] - >>> d.items.extend([(1, 2), (5, 6)]) - >>> d.items - [(0, 0), (3, 4), (7, 8), (1, 2), (5, 6)] - """ - - def __init__(self, init_val=(), strict=True): - OrderedDict.__init__(self, init_val, strict=strict) - self._keys = self.keys - self._values = self.values - self._items = self.items - self.keys = Keys(self) - self.values = Values(self) - self.items = Items(self) - self._att_dict = { - 'keys': self.setkeys, - 'items': self.setitems, - 'values': self.setvalues, - } - - def __setattr__(self, name, value): - """Protect keys, items, and values.""" - if '_att_dict' not in self.__dict__: - object.__setattr__(self, name, value) - else: - try: - fun = self._att_dict[name] - except KeyError: - OrderedDict.__setattr__(self, name, value) - else: - fun(value) - -if __name__ == '__main__': - if INTP_VER < (2, 3): - raise RuntimeError("Tests require Python v.2.3 or later") - # turn off warnings for tests - warnings.filterwarnings('ignore') - # run the code tests in doctest format - import doctest - m = sys.modules.get('__main__') - globs = m.__dict__.copy() - globs.update({ - 'INTP_VER': INTP_VER, - }) - doctest.testmod(m, globs=globs) +try: + from collections import OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict + except ImportError: + import warnings + warnings.warn("git-python needs the ordereddict module installed in python below 2.6 and below.") + warnings.warn("Using standard dictionary as substitute, and cause reordering when writing git config") + OrderedDict = dict diff --git a/git/refs/tag.py b/git/refs/tag.py index 50d2b2afd..6509c8911 100644 --- a/git/refs/tag.py +++ b/git/refs/tag.py @@ -13,9 +13,9 @@ class TagReference(Reference): information in a tag object:: tagref = TagReference.list_items(repo)[0] - print tagref.commit.message + print(tagref.commit.message) if tagref.tag is not None: - print tagref.tag.message""" + print(tagref.tag.message)""" __slots__ = tuple() _common_path_default = "refs/tags" diff --git a/git/test/lib/asserts.py b/git/test/lib/asserts.py index 98751d4dc..0f2fd99a4 100644 --- a/git/test/lib/asserts.py +++ b/git/test/lib/asserts.py @@ -27,6 +27,7 @@ patch ) + def assert_instance_of(expected, actual, msg=None): """Verify that object is an instance of expected """ assert isinstance(actual, expected), msg diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index a18f22ef9..9c935ce01 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -3,7 +3,7 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php - +from __future__ import print_function import os import sys from git import Repo, Remote, GitCommandError, Git @@ -111,7 +111,7 @@ def repo_creator(self): try: return func(self, rw_repo) except: - print >> sys.stderr, "Keeping repo after failure: %s" % repo_dir + print("Keeping repo after failure: %s" % repo_dir, file=sys.stderr) repo_dir = None raise finally: diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index 257442eae..a890c833b 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -3,7 +3,7 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php - +from __future__ import print_function from .lib import TestBigRepoRW from git import Commit from gitdb import IStream @@ -46,8 +46,8 @@ def test_iteration(self): # END for each object # END for each commit elapsed_time = time() - st - print >> sys.stderr, "Traversed %i Trees and a total of %i unchached objects in %s [s] ( %f objs/s )" % ( - nc, no, elapsed_time, no / elapsed_time) + print("Traversed %i Trees and a total of %i unchached objects in %s [s] ( %f objs/s )" + % (nc, no, elapsed_time, no / elapsed_time), file=sys.stderr) def test_commit_traversal(self): # bound to cat-file parsing performance @@ -58,7 +58,8 @@ def test_commit_traversal(self): self._query_commit_info(c) # END for each traversed commit elapsed_time = time() - st - print >> sys.stderr, "Traversed %i Commits in %s [s] ( %f commits/s )" % (nc, elapsed_time, nc / elapsed_time) + print("Traversed %i Commits in %s [s] ( %f commits/s )" + % (nc, elapsed_time, nc / elapsed_time), file=sys.stderr) def test_commit_iteration(self): # bound to stream parsing performance @@ -69,7 +70,8 @@ def test_commit_iteration(self): self._query_commit_info(c) # END for each traversed commit elapsed_time = time() - st - print >> sys.stderr, "Iterated %i Commits in %s [s] ( %f commits/s )" % (nc, elapsed_time, nc / elapsed_time) + print("Iterated %i Commits in %s [s] ( %f commits/s )" + % (nc, elapsed_time, nc / elapsed_time), file=sys.stderr) def test_commit_serialization(self): assert_commit_serialization(self.gitrwrepo, self.gitrwrepo.head, True) @@ -97,5 +99,5 @@ def test_commit_serialization(self): # END commit creation elapsed = time() - st - print >> sys.stderr, "Serialized %i commits to loose objects in %f s ( %f commits / s )" % ( - nc, elapsed, nc / elapsed) + print("Serialized %i commits to loose objects in %f s ( %f commits / s )" + % (nc, elapsed, nc / elapsed), file=sys.stderr) diff --git a/git/test/performance/test_odb.py b/git/test/performance/test_odb.py index 779adb001..b14e6db08 100644 --- a/git/test/performance/test_odb.py +++ b/git/test/performance/test_odb.py @@ -1,5 +1,5 @@ """Performance tests for object store""" - +from __future__ import print_function from time import time import sys @@ -20,8 +20,8 @@ def test_random_access(self): nc = len(commits) elapsed = time() - st - print >> sys.stderr, "%s: Retrieved %i commits from ObjectStore in %g s ( %f commits / s )" % ( - type(repo.odb), nc, elapsed, nc / elapsed) + print("%s: Retrieved %i commits from ObjectStore in %g s ( %f commits / s )" + % (type(repo.odb), nc, elapsed, nc / elapsed), file=sys.stderr) results[0].append(elapsed) # GET TREES @@ -42,8 +42,8 @@ def test_random_access(self): # END for each commit elapsed = time() - st - print >> sys.stderr, "%s: Retrieved %i objects from %i commits in %g s ( %f objects / s )" % ( - type(repo.odb), nt, len(commits), elapsed, nt / elapsed) + print("%s: Retrieved %i objects from %i commits in %g s ( %f objects / s )" + % (type(repo.odb), nt, len(commits), elapsed, nt / elapsed), file=sys.stderr) results[1].append(elapsed) # GET BLOBS @@ -63,11 +63,11 @@ def test_random_access(self): msg = "%s: Retrieved %i blob (%i KiB) and their data in %g s ( %f blobs / s, %f KiB / s )"\ % (type(repo.odb), nb, data_bytes / 1000, elapsed, nb / elapsed, (data_bytes / 1000) / elapsed) + print(msg, file=sys.stderr) results[2].append(elapsed) - print >> sys.stderr, msg # END for each repo type # final results for test_name, a, b in results: - print >> sys.stderr, "%s: %f s vs %f s, pure is %f times slower" % (test_name, a, b, b / a) + print("%s: %f s vs %f s, pure is %f times slower" % (test_name, a, b, b / a), file=sys.stderr) # END for each result diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index 48527f0e2..ff664c100 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -1,4 +1,6 @@ """Performance data streaming performance""" +from __future__ import print_function + from time import time import os import sys @@ -19,6 +21,7 @@ IStream ) + class TestObjDBPerformance(TestBigRepoR): large_data_size_bytes = 1000 * 1000 * 10 # some MiB should do it @@ -32,11 +35,11 @@ def test_large_data_streaming(self, rwrepo): for randomize in range(2): desc = (randomize and 'random ') or '' - print >> sys.stderr, "Creating %s data ..." % desc + print("Creating %s data ..." % desc, file=sys.stderr) st = time() size, stream = make_memory_file(self.large_data_size_bytes, randomize) elapsed = time() - st - print >> sys.stderr, "Done (in %f s)" % elapsed + print("Done (in %f s)" % elapsed, file=sys.stderr) # writing - due to the compression it will seem faster than it is st = time() @@ -49,7 +52,7 @@ def test_large_data_streaming(self, rwrepo): size_kib = size / 1000 msg = "Added %i KiB (filesize = %i KiB) of %s data to loose odb in %f s ( %f Write KiB / s)" msg %= (size_kib, fsize_kib, desc, elapsed_add, size_kib / elapsed_add) - print >> sys.stderr, msg + print(msg, file=sys.stderr) # reading all at once st = time() @@ -61,7 +64,7 @@ def test_large_data_streaming(self, rwrepo): assert shadata == stream.getvalue() msg = "Read %i KiB of %s data at once from loose odb in %f s ( %f Read KiB / s)" msg %= (size_kib, desc, elapsed_readall, size_kib / elapsed_readall) - print >> sys.stderr, msg + print(msg, file=sys.stderr) # reading in chunks of 1 MiB cs = 512 * 1000 @@ -80,8 +83,8 @@ def test_large_data_streaming(self, rwrepo): assert ''.join(chunks) == stream.getvalue() cs_kib = cs / 1000 - print >> sys.stderr, "Read %i KiB of %s data in %i KiB chunks from loose odb in %f s ( %f Read KiB / s)" % ( - size_kib, desc, cs_kib, elapsed_readchunks, size_kib / elapsed_readchunks) + print("Read %i KiB of %s data in %i KiB chunks from loose odb in %f s ( %f Read KiB / s)" + % (size_kib, desc, cs_kib, elapsed_readchunks, size_kib / elapsed_readchunks), file=sys.stderr) # del db file so git has something to do os.remove(db_file) @@ -106,22 +109,22 @@ def test_large_data_streaming(self, rwrepo): fsize_kib = os.path.getsize(db_file) / 1000 msg = "Added %i KiB (filesize = %i KiB) of %s data to using git-hash-object in %f s ( %f Write KiB / s)" msg %= (size_kib, fsize_kib, desc, gelapsed_add, size_kib / gelapsed_add) - print >> sys.stderr, msg + print(msg, file=sys.stderr) # compare ... - print >> sys.stderr, "Git-Python is %f %% faster than git when adding big %s files" % ( - 100.0 - (elapsed_add / gelapsed_add) * 100, desc) + print("Git-Python is %f %% faster than git when adding big %s files" + % (100.0 - (elapsed_add / gelapsed_add) * 100, desc), file=sys.stderr) # read all st = time() s, t, size, data = rwrepo.git.get_object_data(gitsha) gelapsed_readall = time() - st - print >> sys.stderr, "Read %i KiB of %s data at once using git-cat-file in %f s ( %f Read KiB / s)" % ( - size_kib, desc, gelapsed_readall, size_kib / gelapsed_readall) + print("Read %i KiB of %s data at once using git-cat-file in %f s ( %f Read KiB / s)" + % (size_kib, desc, gelapsed_readall, size_kib / gelapsed_readall), file=sys.stderr) # compare - print >> sys.stderr, "Git-Python is %f %% faster than git when reading big %sfiles" % ( - 100.0 - (elapsed_readall / gelapsed_readall) * 100, desc) + print("Git-Python is %f %% faster than git when reading big %sfiles" + % (100.0 - (elapsed_readall / gelapsed_readall) * 100, desc), file=sys.stderr) # read chunks st = time() @@ -134,9 +137,9 @@ def test_large_data_streaming(self, rwrepo): gelapsed_readchunks = time() - st msg = "Read %i KiB of %s data in %i KiB chunks from git-cat-file in %f s ( %f Read KiB / s)" msg %= (size_kib, desc, cs_kib, gelapsed_readchunks, size_kib / gelapsed_readchunks) - print >> sys.stderr, msg + print(msg, file=sys.stderr) # compare - print >> sys.stderr, "Git-Python is %f %% faster than git when reading big %s files in chunks" % ( - 100.0 - (elapsed_readchunks / gelapsed_readchunks) * 100, desc) + print ("Git-Python is %f %% faster than git when reading big %s files in chunks" + % (100.0 - (elapsed_readchunks / gelapsed_readchunks) * 100, desc), file=sys.stderr) # END for each randomization factor diff --git a/git/test/performance/test_utils.py b/git/test/performance/test_utils.py index 0bd470988..af8e8047d 100644 --- a/git/test/performance/test_utils.py +++ b/git/test/performance/test_utils.py @@ -1,4 +1,5 @@ """Performance of utilities""" +from __future__ import print_function from time import time import sys @@ -43,8 +44,8 @@ def __init__(self): cli.attr # END for each access elapsed = time() - st - print >> sys.stderr, "Accessed %s.attr %i times in %s s ( %f acc / s)" % ( - cls.__name__, ni, elapsed, ni / elapsed) + print("Accessed %s.attr %i times in %s s ( %f acc / s)" + % (cls.__name__, ni, elapsed, ni / elapsed), file=sys.stderr) # END for each class type # check num of sequence-acceses @@ -59,8 +60,8 @@ def __init__(self): # END for elapsed = time() - st na = ni * 3 - print >> sys.stderr, "Accessed %s[x] %i times in %s s ( %f acc / s)" % ( - cls.__name__, na, elapsed, na / elapsed) + print("Accessed %s[x] %i times in %s s ( %f acc / s)" + % (cls.__name__, na, elapsed, na / elapsed), file=sys.stderr) # END for each sequence def test_instantiation(self): @@ -85,8 +86,8 @@ def test_instantiation(self): # END handle empty cls # END for each item elapsed = time() - st - print >> sys.stderr, "Created %i %ss of size %i in %f s ( %f inst / s)" % ( - ni, cls.__name__, mni, elapsed, ni / elapsed) + print("Created %i %ss of size %i in %f s ( %f inst / s)" + % (ni, cls.__name__, mni, elapsed, ni / elapsed), file=sys.stderr) # END for each type # END for each item count @@ -96,14 +97,16 @@ def test_instantiation(self): (1, 2, 3, 4) # END for each item elapsed = time() - st - print >> sys.stderr, "Created %i tuples (1,2,3,4) in %f s ( %f tuples / s)" % (ni, elapsed, ni / elapsed) + print("Created %i tuples (1,2,3,4) in %f s ( %f tuples / s)" + % (ni, elapsed, ni / elapsed), file=sys.stderr) st = time() for i in xrange(ni): tuple((1, 2, 3, 4)) # END for each item elapsed = time() - st - print >> sys.stderr, "Created %i tuples tuple((1,2,3,4)) in %f s ( %f tuples / s)" % (ni, elapsed, ni / elapsed) + print("Created %i tuples tuple((1,2,3,4)) in %f s ( %f tuples / s)" + % (ni, elapsed, ni / elapsed), file=sys.stderr) def test_unpacking_vs_indexing(self): ni = 1000000 @@ -116,24 +119,24 @@ def test_unpacking_vs_indexing(self): one, two, three, four = sequence # END for eac iteration elapsed = time() - st - print >> sys.stderr, "Unpacked %i %ss of size %i in %f s ( %f acc / s)" % ( - ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed) + print("Unpacked %i %ss of size %i in %f s ( %f acc / s)" + % (ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed), file=sys.stderr) st = time() for i in xrange(ni): one, two, three, four = sequence[0], sequence[1], sequence[2], sequence[3] # END for eac iteration elapsed = time() - st - print >> sys.stderr, "Unpacked %i %ss of size %i individually in %f s ( %f acc / s)" % ( - ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed) + print("Unpacked %i %ss of size %i individually in %f s ( %f acc / s)" + % (ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed), file=sys.stderr) st = time() for i in xrange(ni): one, two = sequence[0], sequence[1] # END for eac iteration elapsed = time() - st - print >> sys.stderr, "Unpacked %i %ss of size %i individually (2 of 4) in %f s ( %f acc / s)" % ( - ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed) + print("Unpacked %i %ss of size %i individually (2 of 4) in %f s ( %f acc / s)" + % (ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed), file=sys.stderr) # END for each sequence def test_large_list_vs_iteration(self): @@ -150,14 +153,16 @@ def slow_iter(ni): i # END for each item elapsed = time() - st - print >> sys.stderr, "Iterated %i items from list in %f s ( %f acc / s)" % (ni, elapsed, ni / elapsed) + print("Iterated %i items from list in %f s ( %f acc / s)" + % (ni, elapsed, ni / elapsed), file=sys.stderr) st = time() for i in slow_iter(ni): i # END for each item elapsed = time() - st - print >> sys.stderr, "Iterated %i items from iterator in %f s ( %f acc / s)" % (ni, elapsed, ni / elapsed) + print("Iterated %i items from iterator in %f s ( %f acc / s)" + % (ni, elapsed, ni / elapsed), file=sys.stderr) # END for each number of iterations def test_type_vs_inst_class(self): @@ -173,12 +178,13 @@ class NewType(object): inst.__class__() # END for each item elapsed = time() - st - print >> sys.stderr, "Created %i items using inst.__class__ in %f s ( %f items / s)" % ( - ni, elapsed, ni / elapsed) + print("Created %i items using inst.__class__ in %f s ( %f items / s)" + % (ni, elapsed, ni / elapsed), file=sys.stderr) st = time() for i in xrange(ni): type(inst)() # END for each item elapsed = time() - st - print >> sys.stderr, "Created %i items using type(inst)() in %f s ( %f items / s)" % (ni, elapsed, ni / elapsed) + print("Created %i items using type(inst)() in %f s ( %f items / s)" + % (ni, elapsed, ni / elapsed), file=sys.stderr) diff --git a/git/test/test_actor.py b/git/test/test_actor.py index d79673f82..9ba0aeba7 100644 --- a/git/test/test_actor.py +++ b/git/test/test_actor.py @@ -7,6 +7,7 @@ from git.test.lib import assert_equal from git import Actor + class TestActor(object): def test_from_string_should_separate_name_and_email(self): diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 961ae44f6..bfad6fd6b 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -4,6 +4,7 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +from __future__ import print_function from git.test.lib import ( TestBase, @@ -72,8 +73,8 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False) elapsed = time.time() - st if print_performance_info: - print >> sys.stderr, "Serialized %i and deserialized %i commits in %f s ( (%f, %f) commits / s" % ( - ns, nds, elapsed, ns / elapsed, nds / elapsed) + print("Serialized %i and deserialized %i commits in %f s ( (%f, %f) commits / s" + % (ns, nds, elapsed, ns / elapsed, nds / elapsed), file=sys.stderr) # END handle performance info diff --git a/git/test/test_config.py b/git/test/test_config.py index f470b143c..d1c8e72fd 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -64,7 +64,6 @@ def test_read_write(self): file_obj.seek(0) r_config = GitConfigParser(file_obj, read_only=True) - # print file_obj.getvalue() assert r_config.has_section(sname) assert r_config.has_option(sname, oname) assert r_config.get(sname, oname) == val diff --git a/git/test/test_diff.py b/git/test/test_diff.py index adac5ed43..3453f6a8a 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -18,6 +18,7 @@ DiffIndex ) + class TestDiff(TestBase): def _assert_diff_format(self, diffs): diff --git a/git/test/test_git.py b/git/test/test_git.py index 9c8bb490d..553f8d1b5 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -50,7 +50,9 @@ def test_it_transforms_kwargs_into_git_command_arguments(self): assert_equal(["--max-count"], self.git.transform_kwargs(**{'max_count': True})) assert_equal(["--max-count=5"], self.git.transform_kwargs(**{'max_count': 5})) - assert_equal(["-s", "-t"], self.git.transform_kwargs(**{'s': True, 't': True})) + # order is undefined + res = self.git.transform_kwargs(**{'s': True, 't': True}) + assert ['-s', '-t'] == res or ['-t', '-s'] == res def test_it_executes_git_to_shell_and_returns_result(self): assert_match('^git version [\d\.]{2}.*$', self.git.execute(["git", "version"])) diff --git a/git/test/test_index.py b/git/test/test_index.py index 2eef4b5d7..15fff8d4e 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -19,7 +19,6 @@ Diff, GitCommandError, CheckoutError, - ) from gitdb.util import hex_to_bin import os diff --git a/setup.py b/setup.py index 5a4dd9e3e..e1f770583 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import print_function try: from setuptools import setup, find_packages except ImportError: @@ -49,7 +50,7 @@ def _stamp_version(filename): try: f = open(filename, 'r') except (IOError, OSError): - print >> sys.stderr, "Couldn't find file %s to stamp version" % filename + print("Couldn't find file %s to stamp version" % filename, file=sys.stderr) return # END handle error, usually happens during binary builds for line in f: @@ -64,9 +65,12 @@ def _stamp_version(filename): f.writelines(out) f.close() else: - print >> sys.stderr, "WARNING: Couldn't find version line in file %s" % filename + print("WARNING: Couldn't find version line in file %s" % filename, file=sys.stderr) install_requires = ['gitdb >= 0.6.1'] +if sys.version_info[:2] < (2, 7): + install_requires.append('ordereddict') +# end setup( name="GitPython", From 1de8af907dbced4fde64ee2c7f57527fc43ad1cc Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 16:07:02 +0100 Subject: [PATCH 0019/2790] Removed unnecessary (non-gitpython) tests and fixed flake8 --- git/__init__.py | 1 + git/exc.py | 2 +- git/index/__init__.py | 2 +- git/objects/__init__.py | 1 + git/objects/blob.py | 6 +- git/objects/tree.py | 8 +- git/refs/__init__.py | 14 +-- git/refs/head.py | 4 +- git/refs/symbolic.py | 1 + git/repo/__init__.py | 1 + git/repo/base.py | 15 ++- git/test/lib/__init__.py | 1 + git/test/performance/test_utils.py | 190 ----------------------------- git/util.py | 13 +- tox.ini | 4 +- 15 files changed, 39 insertions(+), 224 deletions(-) delete mode 100644 git/test/performance/test_utils.py diff --git a/git/__init__.py b/git/__init__.py index 5580c9a6b..5630b91d0 100644 --- a/git/__init__.py +++ b/git/__init__.py @@ -3,6 +3,7 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +# flake8: noqa import os import sys diff --git a/git/exc.py b/git/exc.py index f1fcf9b3a..ba57c624e 100644 --- a/git/exc.py +++ b/git/exc.py @@ -5,7 +5,7 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php """ Module containing all exceptions thrown througout the git package, """ -from gitdb.exc import * +from gitdb.exc import * # NOQA class InvalidGitRepositoryError(Exception): diff --git a/git/index/__init__.py b/git/index/__init__.py index c5080d2e7..2516f01f8 100644 --- a/git/index/__init__.py +++ b/git/index/__init__.py @@ -1,5 +1,5 @@ """Initialize the index package""" - +# flake8: noqa from __future__ import absolute_import from .base import * diff --git a/git/objects/__init__.py b/git/objects/__init__.py index 1fe881f3b..70fc52cb4 100644 --- a/git/objects/__init__.py +++ b/git/objects/__init__.py @@ -1,6 +1,7 @@ """ Import all submodules main classes into the package space """ +# flake8: noqa from __future__ import absolute_import import inspect from .base import * diff --git a/git/objects/blob.py b/git/objects/blob.py index 5f00a1ff2..b05e5b846 100644 --- a/git/objects/blob.py +++ b/git/objects/blob.py @@ -17,9 +17,9 @@ class Blob(base.IndexObject): type = "blob" # valid blob modes - executable_mode = 0100755 - file_mode = 0100644 - link_mode = 0120000 + executable_mode = 0o100755 + file_mode = 0o100644 + link_mode = 0o120000 __slots__ = tuple() diff --git a/git/objects/tree.py b/git/objects/tree.py index beb5f1fdd..c77e6056c 100644 --- a/git/objects/tree.py +++ b/git/objects/tree.py @@ -119,10 +119,10 @@ class Tree(IndexObject, diff.Diffable, util.Traversable, util.Serializable): __slots__ = "_cache" # actual integer ids for comparison - commit_id = 016 # equals stat.S_IFDIR | stat.S_IFLNK - a directory link - blob_id = 010 - symlink_id = 012 - tree_id = 004 + commit_id = 0o16 # equals stat.S_IFDIR | stat.S_IFLNK - a directory link + blob_id = 0o10 + symlink_id = 0o12 + tree_id = 0o04 _map_id_to_type = { commit_id: Submodule, diff --git a/git/refs/__init__.py b/git/refs/__init__.py index 0281121ae..ded8b1f7c 100644 --- a/git/refs/__init__.py +++ b/git/refs/__init__.py @@ -1,4 +1,4 @@ - +# flake8: noqa from __future__ import absolute_import # import all modules in order, fix the names they require from .symbolic import * @@ -7,16 +7,4 @@ from .tag import * from .remote import * -# name fixes -from . import head -head.RemoteReference = RemoteReference -del(head) - - -from . import symbolic -for item in (HEAD, Head, RemoteReference, TagReference, Reference, SymbolicReference): - setattr(symbolic, item.__name__, item) -del(symbolic) - - from .log import * diff --git a/git/refs/head.py b/git/refs/head.py index acdd37d6b..25c994a3e 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -81,7 +81,7 @@ def reset(self, commit='HEAD', index=True, working_tree=False, try: self.repo.git.reset(mode, commit, add_arg, paths, **kwargs) - except GitCommandError, e: + except GitCommandError as e: # git nowadays may use 1 as status to indicate there are still unstaged # modifications after the reset if e.status != 1: @@ -134,6 +134,7 @@ def set_tracking_branch(self, remote_reference): :param remote_reference: The remote reference to track or None to untrack any references :return: self""" + from .remote import RemoteReference if remote_reference is not None and not isinstance(remote_reference, RemoteReference): raise ValueError("Incorrect parameter type: %r" % remote_reference) # END handle type @@ -156,6 +157,7 @@ def tracking_branch(self): """ :return: The remote_reference we are tracking, or None if we are not a tracking branch""" + from .remote import RemoteReference reader = self.config_reader() if reader.has_option(self.k_config_remote) and reader.has_option(self.k_config_remote_ref): ref = Head(self.repo, Head.to_full_path(reader.get_value(self.k_config_remote_ref))) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 2fa58d123..e0f5531a1 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -625,6 +625,7 @@ def from_path(cls, repo, path): # Names like HEAD are inserted after the refs module is imported - we have an import dependency # cycle and don't want to import these names in-function + from . import HEAD, Head, RemoteReference, TagReference, Reference for ref_type in (HEAD, Head, RemoteReference, TagReference, Reference, SymbolicReference): try: instance = ref_type(repo, path) diff --git a/git/repo/__init__.py b/git/repo/__init__.py index 3ae97e660..5619aa692 100644 --- a/git/repo/__init__.py +++ b/git/repo/__init__.py @@ -1,3 +1,4 @@ """Initialize the Repo package""" +# flake8: noqa from __future__ import absolute_import from .base import * diff --git a/git/repo/base.py b/git/repo/base.py index d1af26e21..dcf981523 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -6,13 +6,22 @@ from git.exc import InvalidGitRepositoryError, NoSuchPathError from git.cmd import Git +from git.refs import ( + HEAD, + Head, + Reference, + TagReference, +) +from git.objects import ( + Submodule, + RootModule, + Commit +) from git.util import ( Actor, finalize_process ) -from git.refs import * from git.index import IndexFile -from git.objects import * from git.config import GitConfigParser from git.remote import ( Remote, @@ -659,7 +668,7 @@ def init(cls, path=None, mkdir=True, **kwargs): :return: ``git.Repo`` (the newly created repo)""" if mkdir and path and not os.path.exists(path): - os.makedirs(path, 0755) + os.makedirs(path, 0o755) # git command automatically chdir into the directory git = Git(path) diff --git a/git/test/lib/__init__.py b/git/test/lib/__init__.py index 033a11044..87e267520 100644 --- a/git/test/lib/__init__.py +++ b/git/test/lib/__init__.py @@ -4,6 +4,7 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +# flake8: noqa import inspect from .asserts import * from .helper import * diff --git a/git/test/performance/test_utils.py b/git/test/performance/test_utils.py deleted file mode 100644 index af8e8047d..000000000 --- a/git/test/performance/test_utils.py +++ /dev/null @@ -1,190 +0,0 @@ -"""Performance of utilities""" -from __future__ import print_function -from time import time -import sys - -from .lib import ( - TestBigRepoR -) - - -class TestUtilPerformance(TestBigRepoR): - - def test_access(self): - # compare dict vs. slot access - class Slotty(object): - __slots__ = "attr" - - def __init__(self): - self.attr = 1 - - class Dicty(object): - - def __init__(self): - self.attr = 1 - - class BigSlotty(object): - __slots__ = ('attr', ) + tuple('abcdefghijk') - - def __init__(self): - for attr in self.__slots__: - setattr(self, attr, 1) - - class BigDicty(object): - - def __init__(self): - for attr in BigSlotty.__slots__: - setattr(self, attr, 1) - - ni = 1000000 - for cls in (Slotty, Dicty, BigSlotty, BigDicty): - cli = cls() - st = time() - for i in xrange(ni): - cli.attr - # END for each access - elapsed = time() - st - print("Accessed %s.attr %i times in %s s ( %f acc / s)" - % (cls.__name__, ni, elapsed, ni / elapsed), file=sys.stderr) - # END for each class type - - # check num of sequence-acceses - for cls in (list, tuple): - x = 10 - st = time() - s = cls(range(x)) - for i in xrange(ni): - s[0] - s[1] - s[2] - # END for - elapsed = time() - st - na = ni * 3 - print("Accessed %s[x] %i times in %s s ( %f acc / s)" - % (cls.__name__, na, elapsed, na / elapsed), file=sys.stderr) - # END for each sequence - - def test_instantiation(self): - ni = 100000 - max_num_items = 4 - for mni in range(max_num_items + 1): - for cls in (tuple, list): - st = time() - for i in xrange(ni): - if mni == 0: - cls() - elif mni == 1: - cls((1,)) - elif mni == 2: - cls((1, 2)) - elif mni == 3: - cls((1, 2, 3)) - elif mni == 4: - cls((1, 2, 3, 4)) - else: - cls(x for x in xrange(mni)) - # END handle empty cls - # END for each item - elapsed = time() - st - print("Created %i %ss of size %i in %f s ( %f inst / s)" - % (ni, cls.__name__, mni, elapsed, ni / elapsed), file=sys.stderr) - # END for each type - # END for each item count - - # tuple and tuple direct - st = time() - for i in xrange(ni): - (1, 2, 3, 4) - # END for each item - elapsed = time() - st - print("Created %i tuples (1,2,3,4) in %f s ( %f tuples / s)" - % (ni, elapsed, ni / elapsed), file=sys.stderr) - - st = time() - for i in xrange(ni): - tuple((1, 2, 3, 4)) - # END for each item - elapsed = time() - st - print("Created %i tuples tuple((1,2,3,4)) in %f s ( %f tuples / s)" - % (ni, elapsed, ni / elapsed), file=sys.stderr) - - def test_unpacking_vs_indexing(self): - ni = 1000000 - list_items = [1, 2, 3, 4] - tuple_items = (1, 2, 3, 4) - - for sequence in (list_items, tuple_items): - st = time() - for i in xrange(ni): - one, two, three, four = sequence - # END for eac iteration - elapsed = time() - st - print("Unpacked %i %ss of size %i in %f s ( %f acc / s)" - % (ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed), file=sys.stderr) - - st = time() - for i in xrange(ni): - one, two, three, four = sequence[0], sequence[1], sequence[2], sequence[3] - # END for eac iteration - elapsed = time() - st - print("Unpacked %i %ss of size %i individually in %f s ( %f acc / s)" - % (ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed), file=sys.stderr) - - st = time() - for i in xrange(ni): - one, two = sequence[0], sequence[1] - # END for eac iteration - elapsed = time() - st - print("Unpacked %i %ss of size %i individually (2 of 4) in %f s ( %f acc / s)" - % (ni, type(sequence).__name__, len(sequence), elapsed, ni / elapsed), file=sys.stderr) - # END for each sequence - - def test_large_list_vs_iteration(self): - # what costs more: alloc/realloc of lists, or the cpu strain of iterators ? - def slow_iter(ni): - for i in xrange(ni): - yield i - # END slow iter - be closer to the real world - - # alloc doesn't play a role here it seems - for ni in (500, 1000, 10000, 20000, 40000): - st = time() - for i in list(xrange(ni)): - i - # END for each item - elapsed = time() - st - print("Iterated %i items from list in %f s ( %f acc / s)" - % (ni, elapsed, ni / elapsed), file=sys.stderr) - - st = time() - for i in slow_iter(ni): - i - # END for each item - elapsed = time() - st - print("Iterated %i items from iterator in %f s ( %f acc / s)" - % (ni, elapsed, ni / elapsed), file=sys.stderr) - # END for each number of iterations - - def test_type_vs_inst_class(self): - class NewType(object): - pass - - # lets see which way is faster - inst = NewType() - - ni = 1000000 - st = time() - for i in xrange(ni): - inst.__class__() - # END for each item - elapsed = time() - st - print("Created %i items using inst.__class__ in %f s ( %f items / s)" - % (ni, elapsed, ni / elapsed), file=sys.stderr) - - st = time() - for i in xrange(ni): - type(inst)() - # END for each item - elapsed = time() - st - print("Created %i items using type(inst)() in %f s ( %f items / s)" - % (ni, elapsed, ni / elapsed), file=sys.stderr) diff --git a/git/util.py b/git/util.py index c29ed70bc..fecd9fa26 100644 --- a/git/util.py +++ b/git/util.py @@ -19,7 +19,7 @@ # Most of these are unused here, but are for use by git-python modules so these # don't see gitdb all the time. Flake of course doesn't like it. -from gitdb.util import ( +from gitdb.util import ( # NOQA make_sha, LockedFD, file_contents_ro, @@ -84,14 +84,13 @@ def join_path(a, *p): return path -def to_native_path_windows(path): - return path.replace('/', '\\') - +if sys.platform.startswith('win'): + def to_native_path_windows(path): + return path.replace('/', '\\') -def to_native_path_linux(path): - return path.replace('\\', '/') + def to_native_path_linux(path): + return path.replace('\\', '/') -if sys.platform.startswith('win'): to_native_path = to_native_path_windows else: # no need for any work on linux diff --git a/tox.ini b/tox.ini index 2b743870c..b50d77fa1 100644 --- a/tox.ini +++ b/tox.ini @@ -17,6 +17,8 @@ commands = {posargs} [flake8] #show-source = True -ignore = E265,F403 +#E265 = it can't deal with my #{ section sections +#F403 = from module import * in __init__ +ignore = E265 max-line-length = 120 exclude = .tox,.venv,build,dist,doc,git/ext/ From 3936084cdd336ce7db7d693950e345eeceab93a5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 16:17:44 +0100 Subject: [PATCH 0020/2790] And apparently, I broken travis ... this should cure it --- .travis.yml | 5 +---- tox.ini | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index c56b9d43f..c1b71110a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,16 +12,13 @@ install: - git fetch --tags - pip install coveralls - # for now we have to make sure there is a master branch - at some point we should just have it by default - - git branch master 0.3 - # generate some reflog as git-python tests need it (in 0.3) - git checkout 0.3 - git reset --hard HEAD~1 - git reset --hard HEAD~1 - git reset --hard HEAD~1 - git reset --hard origin/0.3 - - git checkout master + - git checkout -b master - git reset --hard HEAD~1 - git reset --hard HEAD~1 - git reset --hard HEAD~1 diff --git a/tox.ini b/tox.ini index b50d77fa1..6c562a1d1 100644 --- a/tox.ini +++ b/tox.ini @@ -17,8 +17,7 @@ commands = {posargs} [flake8] #show-source = True -#E265 = it can't deal with my #{ section sections -#F403 = from module import * in __init__ +# E265 = comment blocks like @{ section, which it can't handle ignore = E265 max-line-length = 120 exclude = .tox,.venv,build,dist,doc,git/ext/ From f6aa8d116eb33293c0a9d6d600eb7c32832758b9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 19:14:33 +0100 Subject: [PATCH 0021/2790] initial set of adjustments to make (most) imports work. More to come, especially when it's about strings --- README.md | 4 ---- doc/source/changes.rst | 1 + git/cmd.py | 14 ++++++++------ git/compat.py | 19 +++++++++++++++++++ git/config.py | 6 +++++- git/db.py | 11 +++++------ git/diff.py | 6 +++--- git/index/base.py | 11 +++++------ git/index/fun.py | 8 ++++---- git/index/typ.py | 9 ++++----- git/objects/__init__.py | 7 ++++--- git/objects/base.py | 2 +- git/objects/blob.py | 3 +-- git/objects/commit.py | 15 +++++++-------- git/objects/submodule/base.py | 6 +++--- git/objects/submodule/root.py | 7 +++++-- git/objects/submodule/util.py | 2 +- git/objects/tag.py | 6 +++--- git/objects/tree.py | 16 +++++++--------- git/refs/head.py | 8 +++----- git/refs/reference.py | 3 ++- git/refs/remote.py | 3 ++- git/refs/symbolic.py | 3 ++- git/refs/tag.py | 2 +- git/remote.py | 29 +++++++++++++++-------------- git/repo/base.py | 2 +- git/repo/fun.py | 4 +++- git/test/lib/asserts.py | 18 ++++++++---------- git/test/lib/helper.py | 6 +++--- git/test/performance/test_commit.py | 2 +- git/test/test_commit.py | 2 +- git/test/test_fun.py | 2 +- git/test/test_index.py | 2 +- git/test/test_repo.py | 2 +- git/test/test_tree.py | 2 +- git/util.py | 5 +++-- tox.ini | 2 +- 37 files changed, 136 insertions(+), 114 deletions(-) create mode 100644 git/compat.py diff --git a/README.md b/README.md index 4b6781849..1bc6430e0 100644 --- a/README.md +++ b/README.md @@ -83,10 +83,6 @@ In short, I want to make a new release of 0.3 with all contributions and fixes i The goals I have set for myself, in order, are as follows, all on branch 0.3. -* bring the test suite back online to work with the most commonly used git version -* merge all open pull requests, may there be a test-case or not, back. If something breaks, fix it if possible or let the contributor know -* conform git-python's structure and toolchain to the one used in my [other OSS projects](https://github.com/Byron/bcore) -* evaluate all open issues and close them if possible * evaluate python 3.3 compatibility and establish it if possible While that is happening, I will try hard to foster community around the project. This means being more responsive on the mailing list and in issues, as well as setting up clear guide lines about the [contribution](http://rfc.zeromq.org/spec:22) and maintenance workflow. diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 924743bd1..84437884d 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -6,6 +6,7 @@ Changelog ===== * When fetching, pulling or pushing, and an error occours, it will not be reported on stdout anymore. However, if there is a fatal error, it will still result in a GitCommandError to be thrown. This goes hand in hand with improved fetch result parsing. * Code Cleanup (in preparation for python 3 support) + * Applied autopep8 and cleaned up code * Using python logging module instead of print statments to signal certain kinds of errors diff --git a/git/cmd.py b/git/cmd.py index c355eacf9..b9e4bc09e 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -7,18 +7,20 @@ import os import sys import logging -from util import ( - LazyMixin, - stream_copy -) -from exc import GitCommandError - from subprocess import ( call, Popen, PIPE ) + +from .util import ( + LazyMixin, + stream_copy +) +from .exc import GitCommandError + + execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', 'with_exceptions', 'as_process', 'output_stream') diff --git a/git/compat.py b/git/compat.py new file mode 100644 index 000000000..52fc599ca --- /dev/null +++ b/git/compat.py @@ -0,0 +1,19 @@ +#-*-coding:utf-8-*- +# config.py +# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors +# +# This module is part of GitPython and is released under +# the BSD License: http://www.opensource.org/licenses/bsd-license.php +"""utilities to help provide compatibility with python 3""" + +from gitdb.utils.compat import ( # noqa + PY3, + xrange, + MAXSIZE, + izip, +) + +from gitdb.utils.encoding import ( # noqa + string_types, + text_type +) diff --git a/git/config.py b/git/config.py index 6a85760c2..685dbed80 100644 --- a/git/config.py +++ b/git/config.py @@ -7,7 +7,11 @@ configuration files""" import re -import ConfigParser as cp +try: + import ConfigParser as cp +except ImportError: + # PY3 + import configparser as cp import inspect import logging diff --git a/git/db.py b/git/db.py index ab39f6c5f..c4e198585 100644 --- a/git/db.py +++ b/git/db.py @@ -1,14 +1,8 @@ """Module with our own gitdb implementation - it uses the git command""" -from exc import ( - GitCommandError, - BadObject -) - from gitdb.base import ( OInfo, OStream ) - from gitdb.util import ( bin_to_hex, hex_to_bin @@ -16,6 +10,11 @@ from gitdb.db import GitDB from gitdb.db import LooseObjectDB +from .exc import ( + GitCommandError, + BadObject +) + __all__ = ('GitCmdObjectDB', 'GitDB') diff --git a/git/diff.py b/git/diff.py index 5325ad6ba..b3e7245bc 100644 --- a/git/diff.py +++ b/git/diff.py @@ -3,13 +3,13 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php - import re -from objects.blob import Blob -from objects.util import mode_str_to_int from gitdb.util import hex_to_bin +from .objects.blob import Blob +from .objects.util import mode_str_to_int + __all__ = ('Diffable', 'DiffIndex', 'Diff') diff --git a/git/index/base.py b/git/index/base.py index fdcfcd12f..91dcea420 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -8,16 +8,16 @@ import sys import subprocess import glob -from cStringIO import StringIO +from io import StringIO from stat import S_ISLNK -from typ import ( +from .typ import ( BaseIndexEntry, IndexEntry, ) -from util import ( +from .util import ( TemporaryFileSwap, post_clear_cache, default_index, @@ -25,7 +25,6 @@ ) import git.diff as diff - from git.exc import ( GitCommandError, CheckoutError @@ -40,6 +39,7 @@ ) from git.objects.util import Serializable +from git.compat import izip from git.util import ( LazyMixin, @@ -49,7 +49,7 @@ to_native_path_linux, ) -from fun import ( +from .fun import ( entry_key, write_cache, read_cache, @@ -62,7 +62,6 @@ from gitdb.base import IStream from gitdb.db import MemoryDB from gitdb.util import to_bin_sha -from itertools import izip __all__ = ('IndexFile', 'CheckoutError') diff --git a/git/index/fun.py b/git/index/fun.py index eec90519c..004f992e6 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -12,7 +12,7 @@ S_IFGITLINK = S_IFLNK | S_IFDIR # a submodule -from cStringIO import StringIO +from io import StringIO from git.util import IndexFileSHA1Writer from git.exc import UnmergedEntriesError @@ -22,7 +22,7 @@ traverse_trees_recursive ) -from typ import ( +from .typ import ( BaseIndexEntry, IndexEntry, CE_NAMEMASK, @@ -30,7 +30,7 @@ ) CE_NAMEMASK_INV = ~CE_NAMEMASK -from util import ( +from .util import ( pack, unpack ) @@ -49,7 +49,7 @@ def stat_mode_to_index_mode(mode): return S_IFLNK if S_ISDIR(mode) or S_IFMT(mode) == S_IFGITLINK: # submodules return S_IFGITLINK - return S_IFREG | 0644 | (mode & 0100) # blobs with or without executable bit + return S_IFREG | 0o644 | (mode & 0o100) # blobs with or without executable bit def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1Writer): diff --git a/git/index/typ.py b/git/index/typ.py index 222252c55..692e1e18d 100644 --- a/git/index/typ.py +++ b/git/index/typ.py @@ -1,15 +1,14 @@ """Module with additional types used by the index""" -from util import ( +from binascii import b2a_hex + +from .util import ( pack, unpack ) +from git.objects import Blob -from binascii import ( - b2a_hex, -) -from git.objects import Blob __all__ = ('BlobFilter', 'BaseIndexEntry', 'IndexEntry') #{ Invariants diff --git a/git/objects/__init__.py b/git/objects/__init__.py index 70fc52cb4..ee6428761 100644 --- a/git/objects/__init__.py +++ b/git/objects/__init__.py @@ -7,9 +7,10 @@ from .base import * # Fix import dependency - add IndexObject to the util module, so that it can be # imported by the submodule.base -from .submodule import util -util.IndexObject = IndexObject -util.Object = Object +from .submodule import util as smutil +smutil.IndexObject = IndexObject +smutil.Object = Object +del(smutil) from .submodule.base import * from .submodule.root import * diff --git a/git/objects/base.py b/git/objects/base.py index 20147e578..1f0d57524 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -3,8 +3,8 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +from .util import get_object_type_by_name from git.util import LazyMixin, join_path_native, stream_copy -from util import get_object_type_by_name from gitdb.util import ( bin_to_hex, basename diff --git a/git/objects/blob.py b/git/objects/blob.py index b05e5b846..322f6992b 100644 --- a/git/objects/blob.py +++ b/git/objects/blob.py @@ -3,9 +3,8 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php - from mimetypes import guess_type -import base +from . import base __all__ = ('Blob', ) diff --git a/git/objects/commit.py b/git/objects/commit.py index 9c7336953..5b6b9a33a 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -4,6 +4,8 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +from gitdb import IStream +from gitdb.util import hex_to_bin from git.util import ( Actor, Iterable, @@ -11,26 +13,23 @@ finalize_process ) from git.diff import Diffable -from tree import Tree -from gitdb import IStream -from cStringIO import StringIO -import base -from gitdb.util import ( - hex_to_bin -) -from util import ( +from .tree import Tree +from . import base +from .util import ( Traversable, Serializable, parse_date, altz_to_utctz_str, parse_actor_and_date ) + from time import ( time, altzone ) import os +from io import StringIO import logging log = logging.getLogger('git.objects.commit') diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index d6f8982bb..5ccebd4ce 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -1,5 +1,5 @@ -import util -from util import ( +from . import util +from .util import ( mkhead, sm_name, sm_section, @@ -8,7 +8,7 @@ find_first_remote_branch ) from git.objects.util import Traversable -from StringIO import StringIO # need a dict to set bloody .name field +from io import StringIO # need a dict to set bloody .name field from git.util import ( Iterable, join_path_native, diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index 708749c7b..8c9afff17 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -1,5 +1,8 @@ -from base import Submodule, UpdateProgress -from util import ( +from .base import ( + Submodule, + UpdateProgress +) +from .util import ( find_first_remote_branch ) from git.exc import InvalidGitRepositoryError diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py index 01bd03b3b..cb84ccb1f 100644 --- a/git/objects/submodule/util.py +++ b/git/objects/submodule/util.py @@ -1,7 +1,7 @@ import git from git.exc import InvalidGitRepositoryError from git.config import GitConfigParser -from StringIO import StringIO +from io import StringIO import weakref __all__ = ('sm_section', 'sm_name', 'mkhead', 'unbare_repo', 'find_first_remote_branch', diff --git a/git/objects/tag.py b/git/objects/tag.py index 3c3795790..5e76e230d 100644 --- a/git/objects/tag.py +++ b/git/objects/tag.py @@ -4,12 +4,12 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php """ Module containing all object based types. """ -import base -from gitdb.util import hex_to_bin -from util import ( +from . import base +from .util import ( get_object_type_by_name, parse_actor_and_date ) +from gitdb.util import hex_to_bin __all__ = ("TagObject", ) diff --git a/git/objects/tree.py b/git/objects/tree.py index c77e6056c..a216322b5 100644 --- a/git/objects/tree.py +++ b/git/objects/tree.py @@ -3,22 +3,20 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -import util -from base import IndexObject from git.util import join_path -from blob import Blob -from submodule.base import Submodule import git.diff as diff +from gitdb.util import to_bin_sha -from fun import ( +from . import util +from .base import IndexObject +from .blob import Blob +from .submodule.base import Submodule + +from .fun import ( tree_entries_from_data, tree_to_stream ) -from gitdb.util import ( - to_bin_sha, -) - __all__ = ("TreeModifier", "Tree") diff --git a/git/refs/head.py b/git/refs/head.py index 25c994a3e..0a14158c8 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -1,12 +1,10 @@ -from symbolic import SymbolicReference -from reference import Reference - from git.config import SectionConstraint - from git.util import join_path - from git.exc import GitCommandError +from .symbolic import SymbolicReference +from .reference import Reference + __all__ = ["HEAD", "Head"] diff --git a/git/refs/reference.py b/git/refs/reference.py index b07ac0cd7..8741ebb95 100644 --- a/git/refs/reference.py +++ b/git/refs/reference.py @@ -1,8 +1,9 @@ -from symbolic import SymbolicReference from git.util import ( LazyMixin, Iterable, ) +from .symbolic import SymbolicReference + __all__ = ["Reference"] diff --git a/git/refs/remote.py b/git/refs/remote.py index e3827ad96..b692e6df6 100644 --- a/git/refs/remote.py +++ b/git/refs/remote.py @@ -1,7 +1,8 @@ -from head import Head from git.util import join_path from gitdb.util import join +from .head import Head + import os diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index e0f5531a1..0cd04e07e 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -1,4 +1,5 @@ import os + from git.objects import Object, Commit from git.util import ( join_path, @@ -19,7 +20,7 @@ LockedFD ) -from log import RefLog +from .log import RefLog __all__ = ["SymbolicReference"] diff --git a/git/refs/tag.py b/git/refs/tag.py index 6509c8911..3334e53c1 100644 --- a/git/refs/tag.py +++ b/git/refs/tag.py @@ -1,4 +1,4 @@ -from reference import Reference +from .reference import Reference __all__ = ["TagReference", "Tag"] diff --git a/git/remote.py b/git/remote.py index 44b7ffaa7..9ebc52fe7 100644 --- a/git/remote.py +++ b/git/remote.py @@ -5,33 +5,34 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php # Module implementing a remote object allowing easy access to git remotes +import re +import os -from exc import GitCommandError -from ConfigParser import NoOptionError -from config import SectionConstraint - -from git.util import ( - LazyMixin, - Iterable, - IterableList, - RemoteProgress +from .exc import GitCommandError +from .config import ( + SectionConstraint, + cp, ) - -from refs import ( +from .refs import ( Reference, RemoteReference, SymbolicReference, TagReference ) + +from git.util import ( + LazyMixin, + Iterable, + IterableList, + RemoteProgress +) from git.util import ( join_path, finalize_process ) from gitdb.util import join -import re -import os __all__ = ('RemoteProgress', 'PushInfo', 'FetchInfo', 'Remote') @@ -390,7 +391,7 @@ def __getattr__(self, attr): # even though a slot of the same name exists try: return self._config_reader.get(attr) - except NoOptionError: + except cp.NoOptionError: return super(Remote, self).__getattr__(attr) # END handle exception diff --git a/git/repo/base.py b/git/repo/base.py index dcf981523..e5ae76231 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -40,7 +40,7 @@ hex_to_bin ) -from fun import ( +from .fun import ( rev_parse, is_git_dir, find_git_dir, diff --git a/git/repo/fun.py b/git/repo/fun.py index b89055177..d08e5fede 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -1,5 +1,7 @@ """Package with general repository related functions""" import os +from string import digits + from gitdb.exc import BadObject from git.refs import SymbolicReference from git.objects import Object @@ -11,7 +13,7 @@ hex_to_bin, bin_to_hex ) -from string import digits + __all__ = ('rev_parse', 'is_git_dir', 'touch', 'read_gitfile', 'find_git_dir', 'name_to_object', 'short_to_long', 'deref_tag', 'to_commit') diff --git a/git/test/lib/asserts.py b/git/test/lib/asserts.py index 0f2fd99a4..60a888b3b 100644 --- a/git/test/lib/asserts.py +++ b/git/test/lib/asserts.py @@ -7,13 +7,6 @@ import re import stat -__all__ = ['assert_instance_of', 'assert_not_instance_of', - 'assert_none', 'assert_not_none', - 'assert_match', 'assert_not_match', 'assert_mode_644', - 'assert_mode_755', - 'assert_equal', 'assert_not_equal', 'assert_raises', 'patch', 'raises', - 'assert_true', 'assert_false'] - from nose.tools import ( assert_equal, assert_not_equal, @@ -23,9 +16,14 @@ assert_false ) -from mock import ( - patch -) +from mock import patch + +__all__ = ['assert_instance_of', 'assert_not_instance_of', + 'assert_none', 'assert_not_none', + 'assert_match', 'assert_not_match', 'assert_mode_644', + 'assert_mode_755', + 'assert_equal', 'assert_not_equal', 'assert_raises', 'patch', 'raises', + 'assert_true', 'assert_false'] def assert_instance_of(expected, actual, msg=None): diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 9c935ce01..0ea4fc7e6 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -11,7 +11,7 @@ import time import tempfile import shutil -import cStringIO +import io GIT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) @@ -46,8 +46,8 @@ class StringProcessAdapter(object): Its tailored to work with the test system only""" def __init__(self, input_string): - self.stdout = cStringIO.StringIO(input_string) - self.stderr = cStringIO.StringIO() + self.stdout = io.StringIO(input_string) + self.stderr = io.StringIO() def wait(self): return 0 diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index a890c833b..fed6ef18e 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -8,7 +8,7 @@ from git import Commit from gitdb import IStream from git.test.test_commit import assert_commit_serialization -from cStringIO import StringIO +from io import StringIO from time import time import sys diff --git a/git/test/test_commit.py b/git/test/test_commit.py index bfad6fd6b..84f81f212 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -21,7 +21,7 @@ from gitdb import IStream from gitdb.util import hex_to_bin -from cStringIO import StringIO +from io import StringIO import time import sys import re diff --git a/git/test/test_fun.py b/git/test/test_fun.py index bf178aaab..4093065de 100644 --- a/git/test/test_fun.py +++ b/git/test/test_fun.py @@ -24,7 +24,7 @@ ) from git.index import IndexFile -from cStringIO import StringIO +from io import StringIO class TestFun(TestBase): diff --git a/git/test/test_index.py b/git/test/test_index.py index 15fff8d4e..74bdac532 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -30,7 +30,7 @@ ST_MODE ) -from StringIO import StringIO +from io import StringIO from gitdb.base import IStream from git.objects import Blob from git.index.typ import ( diff --git a/git/test/test_repo.py b/git/test/test_repo.py index f6b46a6eb..41c1c8f10 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -35,7 +35,7 @@ import sys import tempfile import shutil -from cStringIO import StringIO +from io import StringIO class TestRepo(TestBase): diff --git a/git/test/test_tree.py b/git/test/test_tree.py index d2e3606b0..3b89abee5 100644 --- a/git/test/test_tree.py +++ b/git/test/test_tree.py @@ -11,7 +11,7 @@ Blob ) -from cStringIO import StringIO +from io import StringIO class TestTree(TestBase): diff --git a/git/util.py b/git/util.py index fecd9fa26..b3a228835 100644 --- a/git/util.py +++ b/git/util.py @@ -15,7 +15,8 @@ # NOTE: Some of the unused imports might be used/imported by others. # Handle once test-cases are back up and running. -from exc import GitCommandError +from .exc import GitCommandError +from .compat import MAXSIZE # Most of these are unused here, but are for use by git-python modules so these # don't see gitdb all the time. Flake of course doesn't like it. @@ -548,7 +549,7 @@ class BlockingLockFile(LockFile): can never be obtained.""" __slots__ = ("_check_interval", "_max_block_time") - def __init__(self, file_path, check_interval_s=0.3, max_block_time_s=sys.maxint): + def __init__(self, file_path, check_interval_s=0.3, max_block_time_s=MAXSIZE): """Configure the instance :parm check_interval_s: diff --git a/tox.ini b/tox.ini index 6c562a1d1..a3509756d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26,py27,flake8 +envlist = py26,py27,py33,py34,flake8 [testenv] commands = nosetests {posargs} From ae2ff0f9d704dc776a1934f72a339da206a9fff4 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 4 Jan 2015 19:50:28 +0100 Subject: [PATCH 0022/2790] Dum brute force conversion of all types. However, StringIO really is ByteIO in most cases, and py2.7 should run but doesn't. This should be made work first. --- git/cmd.py | 6 +++--- git/compat.py | 11 +++++++++-- git/config.py | 12 ++++++++---- git/index/base.py | 14 +++++++++----- git/objects/commit.py | 7 ++++--- git/objects/fun.py | 6 +++++- git/objects/submodule/base.py | 3 ++- git/objects/tree.py | 3 ++- git/refs/log.py | 6 +++++- git/refs/symbolic.py | 3 ++- git/repo/base.py | 9 +++++---- git/repo/fun.py | 1 + git/test/lib/helper.py | 8 +++++--- git/test/performance/test_commit.py | 9 ++++++--- git/test/test_commit.py | 12 ++++++++---- git/test/test_config.py | 3 ++- git/test/test_index.py | 3 ++- git/test/test_remote.py | 5 +++-- git/test/test_repo.py | 3 ++- git/test/test_submodule.py | 3 ++- git/test/test_util.py | 3 ++- 21 files changed, 87 insertions(+), 43 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index b9e4bc09e..aa5e3a252 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -19,7 +19,7 @@ stream_copy ) from .exc import GitCommandError - +from git.compat import text_type execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', 'with_exceptions', 'as_process', @@ -435,7 +435,7 @@ def transform_kwargs(self, split_single_char_options=False, **kwargs): @classmethod def __unpack_args(cls, arg_list): if not isinstance(arg_list, (list, tuple)): - if isinstance(arg_list, unicode): + if isinstance(arg_list, text_type): return [arg_list.encode('utf-8')] return [str(arg_list)] @@ -443,7 +443,7 @@ def __unpack_args(cls, arg_list): for arg in arg_list: if isinstance(arg_list, (list, tuple)): outlist.extend(cls.__unpack_args(arg)) - elif isinstance(arg_list, unicode): + elif isinstance(arg_list, text_type): outlist.append(arg_list.encode('utf-8')) # END recursion else: diff --git a/git/compat.py b/git/compat.py index 52fc599ca..611005a10 100644 --- a/git/compat.py +++ b/git/compat.py @@ -5,15 +5,22 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php """utilities to help provide compatibility with python 3""" +# flake8: noqa -from gitdb.utils.compat import ( # noqa +from gitdb.utils.compat import ( PY3, xrange, MAXSIZE, izip, ) -from gitdb.utils.encoding import ( # noqa +from gitdb.utils.encoding import ( string_types, text_type ) + +if PY3: + import io + FileType = io.IOBase +else: + FileType = file diff --git a/git/config.py b/git/config.py index 685dbed80..34fe290ba 100644 --- a/git/config.py +++ b/git/config.py @@ -17,6 +17,10 @@ from git.odict import OrderedDict from git.util import LockFile +from git.compat import ( + string_types, + FileType +) __all__ = ('GitConfigParser', 'SectionConstraint') @@ -175,7 +179,7 @@ def __init__(self, file_or_files, read_only=True): "Write-ConfigParsers can operate on a single file only, multiple files have been passed") # END single file check - if not isinstance(file_or_files, basestring): + if not isinstance(file_or_files, string_types): file_or_files = file_or_files.name # END get filename from handle/stream # initialize lock base - we want to write @@ -333,7 +337,7 @@ def write(self): close_fp = False # we have a physical file on disk, so get a lock - if isinstance(fp, (basestring, file)): + if isinstance(fp, string_types + (FileType, )): self._lock._obtain_lock() # END get lock for physical files @@ -391,7 +395,7 @@ def get_value(self, section, option, default=None): return default raise - types = (long, float) + types = (int, float) for numtype in types: try: val = numtype(valuestr) @@ -412,7 +416,7 @@ def get_value(self, section, option, default=None): if vl == 'true': return True - if not isinstance(valuestr, basestring): + if not isinstance(valuestr, string_types): raise TypeError("Invalid value type: only int, long, float and str are allowed", valuestr) return valuestr diff --git a/git/index/base.py b/git/index/base.py index 91dcea420..25ac121c4 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -39,7 +39,11 @@ ) from git.objects.util import Serializable -from git.compat import izip +from git.compat import ( + izip, + xrange, + string_types, +) from git.util import ( LazyMixin, @@ -541,7 +545,7 @@ def _preprocess_add_items(self, items): entries = list() for item in items: - if isinstance(item, basestring): + if isinstance(item, string_types): paths.append(self._to_relative_path(item)) elif isinstance(item, (Blob, Submodule)): entries.append(BaseIndexEntry.from_blob(item)) @@ -752,7 +756,7 @@ def _items_to_rela_paths(self, items): for item in items: if isinstance(item, (BaseIndexEntry, (Blob, Submodule))): paths.append(self._to_relative_path(item.path)) - elif isinstance(item, basestring): + elif isinstance(item, string_types): paths.append(self._to_relative_path(item)) else: raise TypeError("Invalid item type: %r" % item) @@ -1004,7 +1008,7 @@ def handle_stderr(proc, iter_checked_out_files): handle_stderr(proc, rval_iter) return rval_iter else: - if isinstance(paths, basestring): + if isinstance(paths, string_types): paths = [paths] # make sure we have our entries loaded before we start checkout_index @@ -1140,7 +1144,7 @@ def diff(self, other=diff.Diffable.Index, paths=None, create_patch=False, **kwar # index against anything but None is a reverse diff with the respective # item. Handle existing -R flags properly. Transform strings to the object # so that we can call diff on it - if isinstance(other, basestring): + if isinstance(other, string_types): other = self.repo.rev_parse(other) # END object conversion diff --git a/git/objects/commit.py b/git/objects/commit.py index 5b6b9a33a..c9d7ddc86 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -23,6 +23,7 @@ altz_to_utctz_str, parse_actor_and_date ) +from git.compat import text_type from time import ( time, @@ -378,7 +379,7 @@ def _serialize(self, stream): a = self.author aname = a.name - if isinstance(aname, unicode): + if isinstance(aname, text_type): aname = aname.encode(self.encoding) # END handle unicode in name @@ -390,7 +391,7 @@ def _serialize(self, stream): # encode committer aname = c.name - if isinstance(aname, unicode): + if isinstance(aname, text_type): aname = aname.encode(self.encoding) # END handle unicode in name write(fmt % ("committer", aname, c.email, @@ -408,7 +409,7 @@ def _serialize(self, stream): write("\n") # write plain bytes, be sure its encoded according to our encoding - if isinstance(self.message, unicode): + if isinstance(self.message, text_type): write(self.message.encode(self.encoding)) else: write(self.message) diff --git a/git/objects/fun.py b/git/objects/fun.py index 416a52e61..db2ec7c22 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -1,5 +1,9 @@ """Module with functions which are supposed to be as fast as possible""" from stat import S_ISDIR +from git.compat import ( + xrange, + text_type +) __all__ = ('tree_to_stream', 'tree_entries_from_data', 'traverse_trees_recursive', 'traverse_tree_recursive') @@ -28,7 +32,7 @@ def tree_to_stream(entries, write): # hence we must convert to an utf8 string for it to work properly. # According to my tests, this is exactly what git does, that is it just # takes the input literally, which appears to be utf8 on linux. - if isinstance(name, unicode): + if isinstance(name, text_type): name = name.encode("utf8") write("%s %s\0%s" % (mode_str, name, binsha)) # END for each item diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 5ccebd4ce..69bf748a3 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -22,6 +22,7 @@ InvalidGitRepositoryError, NoSuchPathError ) +from git.compat import string_types import stat import git @@ -93,7 +94,7 @@ def __init__(self, repo, binsha, mode=None, path=None, name=None, parent_commit= if url is not None: self._url = url if branch_path is not None: - assert isinstance(branch_path, basestring) + assert isinstance(branch_path, string_types) self._branch_path = branch_path if name is not None: self._name = name diff --git a/git/objects/tree.py b/git/objects/tree.py index a216322b5..6776a15e7 100644 --- a/git/objects/tree.py +++ b/git/objects/tree.py @@ -11,6 +11,7 @@ from .base import IndexObject from .blob import Blob from .submodule.base import Submodule +from git.compat import string_types from .fun import ( tree_entries_from_data, @@ -232,7 +233,7 @@ def __getitem__(self, item): info = self._cache[item] return self._map_id_to_type[info[1] >> 12](self.repo, info[0], info[1], join_path(self.path, info[2])) - if isinstance(item, basestring): + if isinstance(item, string_types): # compatability return self.__div__(item) # END index is basestring diff --git a/git/refs/log.py b/git/refs/log.py index e3f3363c3..94e071046 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -17,6 +17,10 @@ Serializable, altz_to_utctz_str, ) +from git.compat import ( + xrange, + string_types +) import time import re @@ -170,7 +174,7 @@ def iter_entries(cls, stream): :param stream: file-like object containing the revlog in its native format or basestring instance pointing to a file to read""" new_entry = RefLogEntry.from_line - if isinstance(stream, basestring): + if isinstance(stream, string_types): stream = file_contents_ro_filepath(stream) # END handle stream type while True: diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 0cd04e07e..624b1a091 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -19,6 +19,7 @@ hex_to_bin, LockedFD ) +from git.compat import string_types from .log import RefLog @@ -274,7 +275,7 @@ def set_reference(self, ref, logmsg=None): elif isinstance(ref, Object): obj = ref write_value = ref.hexsha - elif isinstance(ref, basestring): + elif isinstance(ref, string_types): try: obj = self.repo.rev_parse(ref + "^{}") # optionally deref tags write_value = obj.hexsha diff --git a/git/repo/base.py b/git/repo/base.py index e5ae76231..f92a85ce3 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -47,6 +47,7 @@ read_gitfile, touch, ) +from git.compat import text_type import os import sys @@ -176,11 +177,11 @@ def __hash__(self): # Description property def _get_description(self): filename = join(self.git_dir, 'description') - return file(filename).read().rstrip() + return open(filename).read().rstrip() def _set_description(self, descr): filename = join(self.git_dir, 'description') - file(filename, 'w').write(descr + '\n') + open(filename, 'w').write(descr + '\n') description = property(_get_description, _set_description, doc="the project's description") @@ -389,7 +390,7 @@ def commit(self, rev=None): if rev is None: return self.head.commit else: - return self.rev_parse(unicode(rev) + "^0") + return self.rev_parse(text_type(rev) + "^0") def iter_trees(self, *args, **kwargs): """:return: Iterator yielding Tree objects @@ -412,7 +413,7 @@ def tree(self, rev=None): if rev is None: return self.head.commit.tree else: - return self.rev_parse(unicode(rev) + "^{tree}") + return self.rev_parse(text_type(rev) + "^{tree}") def iter_commits(self, rev=None, paths='', **kwargs): """A list of Commit objects representing the history of a given ref/commit diff --git a/git/repo/fun.py b/git/repo/fun.py index d08e5fede..64b9b4a9b 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -13,6 +13,7 @@ hex_to_bin, bin_to_hex ) +from git.compat import xrange __all__ = ('rev_parse', 'is_git_dir', 'touch', 'read_gitfile', 'find_git_dir', 'name_to_object', diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 0ea4fc7e6..43079dbea 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -6,13 +6,15 @@ from __future__ import print_function import os import sys -from git import Repo, Remote, GitCommandError, Git from unittest import TestCase import time import tempfile import shutil import io +from git import Repo, Remote, GitCommandError, Git +from git.compat import string_types + GIT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) __all__ = ( @@ -89,7 +91,7 @@ def with_rw_repo(working_tree_ref, bare=False): To make working with relative paths easier, the cwd will be set to the working dir of the repository. """ - assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout" + assert isinstance(working_tree_ref, string_types), "Decorator requires ref name for working tree checkout" def argument_passer(func): def repo_creator(self): @@ -152,7 +154,7 @@ def case(self, rw_repo, rw_remote_repo) See working dir info in with_rw_repo :note: We attempt to launch our own invocation of git-daemon, which will be shutdown at the end of the test. """ - assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout" + assert isinstance(working_tree_ref, string_types), "Decorator requires ref name for working tree checkout" def argument_passer(func): def remote_repo_creator(self): diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index fed6ef18e..a55b6d43c 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -4,13 +4,16 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php from __future__ import print_function +from io import StringIO +from time import time +import sys + from .lib import TestBigRepoRW from git import Commit from gitdb import IStream +from git.compat import xrange from git.test.test_commit import assert_commit_serialization -from io import StringIO -from time import time -import sys + class TestPerformance(TestBigRepoRW): diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 84f81f212..adf1cb107 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -20,6 +20,10 @@ ) from gitdb import IStream from gitdb.util import hex_to_bin +from git.compat import ( + string_types, + text_type +) from io import StringIO import time @@ -129,7 +133,7 @@ def test_unicode_actor(self): assert len(name) == 9 special = Actor._from_string(u"%s " % name) assert special.name == name - assert isinstance(special.name, unicode) + assert isinstance(special.name, text_type) def test_traversal(self): start = self.rorepo.commit("a4d06724202afccd2b5c54f81bcf2bf26dea7fff") @@ -250,7 +254,7 @@ def test_iter_parents(self): def test_base(self): name_rev = self.rorepo.head.commit.name_rev - assert isinstance(name_rev, basestring) + assert isinstance(name_rev, string_types) @with_rw_repo('HEAD', bare=True) def test_serialization(self, rwrepo): @@ -263,8 +267,8 @@ def test_serialization_unicode_support(self): # create a commit with unicode in the message, and the author's name # Verify its serialization and deserialization cmt = self.rorepo.commit('0.1.6') - assert isinstance(cmt.message, unicode) # it automatically decodes it as such - assert isinstance(cmt.author.name, unicode) # same here + assert isinstance(cmt.message, text_type) # it automatically decodes it as such + assert isinstance(cmt.author.name, text_type) # same here cmt.message = "üäêèß".decode("utf-8") assert len(cmt.message) == 5 diff --git a/git/test/test_config.py b/git/test/test_config.py index d1c8e72fd..ef0707e96 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -11,6 +11,7 @@ from git import ( GitConfigParser ) +from git.compat import string_types import StringIO from copy import copy from ConfigParser import NoSectionError @@ -85,7 +86,7 @@ def test_base(self): num_options += 1 val = r_config.get(section, option) val_typed = r_config.get_value(section, option) - assert isinstance(val_typed, (bool, long, float, basestring)) + assert isinstance(val_typed, (bool, int, float, ) + string_types) assert val assert "\n" not in option assert "\n" not in val diff --git a/git/test/test_index.py b/git/test/test_index.py index 74bdac532..70d70a057 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -20,6 +20,7 @@ GitCommandError, CheckoutError, ) +from git.compat import string_types from gitdb.util import hex_to_bin import os import sys @@ -343,7 +344,7 @@ def test_index_file_diffing(self, rw_repo): index.checkout(test_file) except CheckoutError as e: assert len(e.failed_files) == 1 and e.failed_files[0] == os.path.basename(test_file) - assert (len(e.failed_files) == len(e.failed_reasons)) and isinstance(e.failed_reasons[0], basestring) + assert (len(e.failed_files) == len(e.failed_reasons)) and isinstance(e.failed_reasons[0], string_types) assert len(e.valid_files) == 0 assert open(test_file).read().endswith(append_data) else: diff --git a/git/test/test_remote.py b/git/test/test_remote.py index a8d5179aa..75dc19c5f 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -23,6 +23,7 @@ GitCommandError ) from git.util import IterableList +from git.compat import string_types import tempfile import shutil import os @@ -97,7 +98,7 @@ def _do_test_fetch_result(self, results, remote): # self._print_fetchhead(remote.repo) assert len(results) > 0 and isinstance(results[0], FetchInfo) for info in results: - assert isinstance(info.note, basestring) + assert isinstance(info.note, string_types) if isinstance(info.ref, Reference): assert info.flags != 0 # END reference type flags handling @@ -113,7 +114,7 @@ def _do_test_push_result(self, results, remote): assert len(results) > 0 and isinstance(results[0], PushInfo) for info in results: assert info.flags - assert isinstance(info.summary, basestring) + assert isinstance(info.summary, string_types) if info.old_commit is not None: assert isinstance(info.old_commit, Commit) if info.flags & info.ERROR: diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 41c1c8f10..f33fe4674 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -30,6 +30,7 @@ from git.util import join_path_native from git.exc import BadObject from gitdb.util import bin_to_hex +from git.compat import string_types import os import sys @@ -286,7 +287,7 @@ def test_should_display_blame_information(self, git): # test the 'lines per commit' entries tlist = b[0][1] assert_true(tlist) - assert_true(isinstance(tlist[0], basestring)) + assert_true(isinstance(tlist[0], string_types)) assert_true(len(tlist) < sum(len(t) for t in tlist)) # test for single-char bug def test_blame_real(self): diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index ec3459e4f..8c1580fe1 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -9,6 +9,7 @@ from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress from git.util import to_native_path_linux, join_path_native +from git.compat import string_types import shutil import git import sys @@ -76,7 +77,7 @@ def _do_base_tests(self, rwrepo): self.failUnlessRaises(InvalidGitRepositoryError, getattr, sm, 'branch') # branch_path works, as its just a string - assert isinstance(sm.branch_path, basestring) + assert isinstance(sm.branch_path, string_types) # some commits earlier we still have a submodule, but its at a different commit smold = Submodule.iter_items(rwrepo, self.k_subm_changed).next() diff --git a/git/test/test_util.py b/git/test/test_util.py index 888eb4eee..c6ca6920b 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -24,6 +24,7 @@ parse_date, ) from git.cmd import dashify +from git.compat import string_types import time @@ -104,7 +105,7 @@ def assert_rval(rval, veri_time, offset=0): # now that we are here, test our conversion functions as well utctz = altz_to_utctz_str(offset) - assert isinstance(utctz, basestring) + assert isinstance(utctz, string_types) assert utctz_to_altz(verify_utctz(utctz)) == offset # END assert rval utility From bc8c91200a7fb2140aadd283c66b5ab82f9ad61e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 10:09:51 +0100 Subject: [PATCH 0023/2790] Fixed io types to make tests work on PY2 once again. Now it's about going through PY3 issues --- git/compat.py | 3 ++- git/index/base.py | 6 ++++-- git/index/fun.py | 4 ++-- git/objects/commit.py | 6 +++--- git/objects/submodule/base.py | 6 +++--- git/objects/submodule/util.py | 4 ++-- git/refs/log.py | 2 +- git/test/fixtures/git_config_global | 1 + git/test/lib/helper.py | 4 ++-- git/test/performance/test_commit.py | 4 ++-- git/test/test_commit.py | 12 ++++++------ git/test/test_config.py | 4 ++-- git/test/test_fun.py | 4 ++-- git/test/test_index.py | 6 +++--- git/test/test_repo.py | 14 +++++++------- git/test/test_tree.py | 6 +++--- 16 files changed, 45 insertions(+), 41 deletions(-) diff --git a/git/compat.py b/git/compat.py index 611005a10..a95c56674 100644 --- a/git/compat.py +++ b/git/compat.py @@ -16,7 +16,8 @@ from gitdb.utils.encoding import ( string_types, - text_type + text_type, + force_bytes ) if PY3: diff --git a/git/index/base.py b/git/index/base.py index 25ac121c4..a994e7b6c 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -8,7 +8,7 @@ import sys import subprocess import glob -from io import StringIO +from io import BytesIO from stat import S_ISLNK @@ -43,6 +43,7 @@ izip, xrange, string_types, + force_bytes ) from git.util import ( @@ -562,7 +563,8 @@ def _store_path(self, filepath, fprogress): st = os.lstat(filepath) # handles non-symlinks as well stream = None if S_ISLNK(st.st_mode): - stream = StringIO(os.readlink(filepath)) + # in PY3, readlink is string, but we need bytes. In PY2, it's just OS encoded bytes, we assume UTF-8 + stream = BytesIO(force_bytes(os.readlink(filepath), encoding='utf-8')) else: stream = open(filepath, 'rb') # END handle stream diff --git a/git/index/fun.py b/git/index/fun.py index 004f992e6..0e49ae8d7 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -12,7 +12,7 @@ S_IFGITLINK = S_IFLNK | S_IFDIR # a submodule -from io import StringIO +from io import BytesIO from git.util import IndexFileSHA1Writer from git.exc import UnmergedEntriesError @@ -218,7 +218,7 @@ def write_tree_from_cache(entries, odb, sl, si=0): # END for each entry # finally create the tree - sio = StringIO() + sio = BytesIO() tree_to_stream(tree_items, sio.write) sio.seek(0) diff --git a/git/objects/commit.py b/git/objects/commit.py index c9d7ddc86..79d460ad9 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -30,7 +30,7 @@ altzone ) import os -from io import StringIO +from io import BytesIO import logging log = logging.getLogger('git.objects.commit') @@ -133,7 +133,7 @@ def _set_cache_(self, attr): if attr in Commit.__slots__: # read the data in a chunk, its faster - then provide a file wrapper binsha, typename, self.size, stream = self.repo.odb.stream(self.binsha) - self._deserialize(StringIO(stream.read())) + self._deserialize(BytesIO(stream.read())) else: super(Commit, self)._set_cache_(attr) # END handle attrs @@ -345,7 +345,7 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, committer, committer_time, committer_offset, message, parent_commits, conf_encoding) - stream = StringIO() + stream = BytesIO() new_commit._serialize(stream) streamlen = stream.tell() stream.seek(0) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 69bf748a3..0fb3f35fc 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -8,7 +8,7 @@ find_first_remote_branch ) from git.objects.util import Traversable -from io import StringIO # need a dict to set bloody .name field +from io import BytesIO # need a dict to set bloody .name field from git.util import ( Iterable, join_path_native, @@ -187,8 +187,8 @@ def _clear_cache(self): @classmethod def _sio_modules(cls, parent_commit): - """:return: Configuration file as StringIO - we only access it through the respective blob's data""" - sio = StringIO(parent_commit.tree[cls.k_modules_file].data_stream.read()) + """:return: Configuration file as BytesIO - we only access it through the respective blob's data""" + sio = BytesIO(parent_commit.tree[cls.k_modules_file].data_stream.read()) sio.name = cls.k_modules_file return sio diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py index cb84ccb1f..5604dec72 100644 --- a/git/objects/submodule/util.py +++ b/git/objects/submodule/util.py @@ -1,7 +1,7 @@ import git from git.exc import InvalidGitRepositoryError from git.config import GitConfigParser -from io import StringIO +from io import BytesIO import weakref __all__ = ('sm_section', 'sm_name', 'mkhead', 'unbare_repo', 'find_first_remote_branch', @@ -83,7 +83,7 @@ def flush_to_index(self): """Flush changes in our configuration file to the index""" assert self._smref is not None # should always have a file here - assert not isinstance(self._file_or_files, StringIO) + assert not isinstance(self._file_or_files, BytesIO) sm = self._smref() if sm is not None: diff --git a/git/refs/log.py b/git/refs/log.py index 94e071046..f397548e9 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -85,7 +85,7 @@ def from_line(cls, line): :param line: line without trailing newline :raise ValueError: If line could not be parsed""" try: - info, msg = line.split('\t', 2) + info, msg = line.split('\t', 1) except ValueError: raise ValueError("line is missing tab separator") # END handle first plit diff --git a/git/test/fixtures/git_config_global b/git/test/fixtures/git_config_global index 1a55397f6..56fbd3b3b 100644 --- a/git/test/fixtures/git_config_global +++ b/git/test/fixtures/git_config_global @@ -1,3 +1,4 @@ +# just a comment [alias] st = status ci = commit diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 43079dbea..bc9c351ab 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -48,8 +48,8 @@ class StringProcessAdapter(object): Its tailored to work with the test system only""" def __init__(self, input_string): - self.stdout = io.StringIO(input_string) - self.stderr = io.StringIO() + self.stdout = io.BytesIO(input_string) + self.stderr = io.BytesIO() def wait(self): return 0 diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index a55b6d43c..9e8c1325f 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -4,7 +4,7 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php from __future__ import print_function -from io import StringIO +from io import BytesIO from time import time import sys @@ -93,7 +93,7 @@ def test_commit_serialization(self): hc.committer, hc.committed_date, hc.committer_tz_offset, str(i), parents=hc.parents, encoding=hc.encoding) - stream = StringIO() + stream = BytesIO() cm._serialize(stream) slen = stream.tell() stream.seek(0) diff --git a/git/test/test_commit.py b/git/test/test_commit.py index adf1cb107..5f45e59d1 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -25,7 +25,7 @@ text_type ) -from io import StringIO +from io import BytesIO import time import sys import re @@ -44,7 +44,7 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False) # assert that we deserialize commits correctly, hence we get the same # sha on serialization - stream = StringIO() + stream = BytesIO() cm._serialize(stream) ns += 1 streamlen = stream.tell() @@ -59,7 +59,7 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False) cm.message, cm.parents, cm.encoding) assert nc.parents == cm.parents - stream = StringIO() + stream = BytesIO() nc._serialize(stream) ns += 1 streamlen = stream.tell() @@ -276,7 +276,7 @@ def test_serialization_unicode_support(self): cmt.author.name = "äüß".decode("utf-8") assert len(cmt.author.name) == 3 - cstream = StringIO() + cstream = BytesIO() cmt._serialize(cstream) cstream.seek(0) assert len(cstream.getvalue()) @@ -316,7 +316,7 @@ def test_gpgsig(self): cmt.gpgsig = "" assert cmt.gpgsig != fixture_sig - cstream = StringIO() + cstream = BytesIO() cmt._serialize(cstream) assert re.search(r"^gpgsig $", cstream.getvalue(), re.MULTILINE) @@ -326,6 +326,6 @@ def test_gpgsig(self): assert cmt.gpgsig == "" cmt.gpgsig = None - cstream = StringIO() + cstream = BytesIO() cmt._serialize(cstream) assert not re.search(r"^gpgsig ", cstream.getvalue(), re.MULTILINE) diff --git a/git/test/test_config.py b/git/test/test_config.py index ef0707e96..0301c54fb 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -12,7 +12,7 @@ GitConfigParser ) from git.compat import string_types -import StringIO +import io from copy import copy from ConfigParser import NoSectionError @@ -21,7 +21,7 @@ class TestBase(TestCase): def _to_memcache(self, file_path): fp = open(file_path, "r") - sio = StringIO.StringIO(fp.read()) + sio = io.BytesIO(fp.read()) sio.name = file_path return sio diff --git a/git/test/test_fun.py b/git/test/test_fun.py index 4093065de..9d3e749eb 100644 --- a/git/test/test_fun.py +++ b/git/test/test_fun.py @@ -24,7 +24,7 @@ ) from git.index import IndexFile -from io import StringIO +from io import BytesIO class TestFun(TestBase): @@ -72,7 +72,7 @@ def test_aggressive_tree_merge(self): def mktree(self, odb, entries): """create a tree from the given tree entries and safe it to the database""" - sio = StringIO() + sio = BytesIO() tree_to_stream(entries, sio.write) sio.seek(0) istream = odb.store(IStream(str_tree_type, len(sio.getvalue()), sio)) diff --git a/git/test/test_index.py b/git/test/test_index.py index 70d70a057..38cc35639 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -31,7 +31,7 @@ ST_MODE ) -from io import StringIO +from io import BytesIO from gitdb.base import IStream from git.objects import Blob from git.index.typ import ( @@ -698,9 +698,9 @@ def test_index_bare_add(self, rw_bare_repo): # instead of throwing the Exception we are expecting. This is # a quick hack to make this test fail when expected. rw_bare_repo._working_tree_dir = None - contents = 'This is a StringIO file' + contents = b'This is a BytesIO file' filesize = len(contents) - fileobj = StringIO(contents) + fileobj = BytesIO(contents) filename = 'my-imaginary-file' istream = rw_bare_repo.odb.store( IStream(Blob.type, filesize, fileobj)) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index f33fe4674..ae824086b 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -36,7 +36,7 @@ import sys import tempfile import shutil -from io import StringIO +from io import BytesIO class TestRepo(TestBase): @@ -362,22 +362,22 @@ def test_comparison_and_hash(self): def test_git_cmd(self): # test CatFileContentStream, just to be very sure we have no fencepost errors # last \n is the terminating newline that it expects - l1 = "0123456789\n" - l2 = "abcdefghijklmnopqrstxy\n" - l3 = "z\n" - d = "%s%s%s\n" % (l1, l2, l3) + l1 = b"0123456789\n" + l2 = b"abcdefghijklmnopqrstxy\n" + l3 = b"z\n" + d = b"%s%s%s\n" % (l1, l2, l3) l1p = l1[:5] # full size # size is without terminating newline def mkfull(): - return Git.CatFileContentStream(len(d) - 1, StringIO(d)) + return Git.CatFileContentStream(len(d) - 1, BytesIO(d)) ts = 5 def mktiny(): - return Git.CatFileContentStream(ts, StringIO(d)) + return Git.CatFileContentStream(ts, BytesIO(d)) # readlines no limit s = mkfull() diff --git a/git/test/test_tree.py b/git/test/test_tree.py index 3b89abee5..72bda4855 100644 --- a/git/test/test_tree.py +++ b/git/test/test_tree.py @@ -11,7 +11,7 @@ Blob ) -from io import StringIO +from io import BytesIO class TestTree(TestBase): @@ -30,7 +30,7 @@ def test_serializable(self): orig_data = tree.data_stream.read() orig_cache = tree._cache - stream = StringIO() + stream = BytesIO() tree._serialize(stream) assert stream.getvalue() == orig_data @@ -82,7 +82,7 @@ def test_serializable(self): mod.set_done() # multiple times are okay # serialize, its different now - stream = StringIO() + stream = BytesIO() testtree._serialize(stream) stream.seek(0) assert stream.getvalue() != orig_data From 1ef4552404ba3bc92554a6c57793ee889523e3a8 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Jan 2015 08:46:31 -0500 Subject: [PATCH 0024/2790] BF: allow log line to have no msg (Close #225) --- git/refs/log.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/git/refs/log.py b/git/refs/log.py index e3f3363c3..07465e6fb 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -80,11 +80,15 @@ def from_line(cls, line): """:return: New RefLogEntry instance from the given revlog line. :param line: line without trailing newline :raise ValueError: If line could not be parsed""" - try: - info, msg = line.split('\t', 2) - except ValueError: - raise ValueError("line is missing tab separator") - # END handle first plit + fields = line.split('\t', 1) + if len(fields) == 1: + info, msg = fields[0], None + elif len(fields) == 2: + info, msg = fields + else: + raise ValueError("Line must have up to two TAB-separated fields." + " Got %s" % repr(line)) + # END handle first split oldhexsha = info[:40] newhexsha = info[41:81] for hexsha in (oldhexsha, newhexsha): From 04357d0d46fee938a618b64daed1716606e05ca5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 15:53:46 +0100 Subject: [PATCH 0025/2790] Intermediate commit: test_config and test_actor works Kind of tackling the tasks step by step, picking low-hanging fruit first, or the ones that everyone depends on --- doc/source/changes.rst | 4 ++++ git/cmd.py | 44 +++++++++++++++++++++++++---------------- git/compat.py | 32 +++++++++++++++++++++++++++++- git/config.py | 42 ++++++++++++++++++++------------------- git/objects/util.py | 16 +++++++-------- git/refs/symbolic.py | 15 ++++++++------ git/remote.py | 11 ++++++----- git/test/test_config.py | 13 ++++++------ 8 files changed, 114 insertions(+), 63 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 84437884d..cf528b280 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,10 @@ Changelog ========= +0.3.4 - python 3 support +======================== +* Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes. + 0.3.3 ===== * When fetching, pulling or pushing, and an error occours, it will not be reported on stdout anymore. However, if there is a fatal error, it will still result in a GitCommandError to be thrown. This goes hand in hand with improved fetch result parsing. diff --git a/git/cmd.py b/git/cmd.py index aa5e3a252..c536b43c5 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -19,7 +19,11 @@ stream_copy ) from .exc import GitCommandError -from git.compat import text_type +from git.compat import ( + text_type, + string_types, + defenc +) execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', 'with_exceptions', 'as_process', @@ -373,9 +377,9 @@ def execute(self, command, if output_stream is None: stdout_value, stderr_value = proc.communicate() # strip trailing "\n" - if stdout_value.endswith("\n"): + if stdout_value.endswith(b"\n"): stdout_value = stdout_value[:-1] - if stderr_value.endswith("\n"): + if stderr_value.endswith(b"\n"): stderr_value = stderr_value[:-1] status = proc.returncode else: @@ -394,9 +398,9 @@ def execute(self, command, if self.GIT_PYTHON_TRACE == 'full': cmdstr = " ".join(command) if stderr_value: - log.info("%s -> %d; stdout: '%s'; stderr: '%s'", cmdstr, status, stdout_value, stderr_value) + log.info("%s -> %d; stdout: '%s'; stderr: '%s'", cmdstr, status, stdout_value.decode(defenc), stderr_value.decode(defenc)) elif stdout_value: - log.info("%s -> %d; stdout: '%s'", cmdstr, status, stdout_value) + log.info("%s -> %d; stdout: '%s'", cmdstr, status, stdout_value.decode(defenc)) else: log.info("%s -> %d", cmdstr, status) # END handle debug printing @@ -436,7 +440,7 @@ def transform_kwargs(self, split_single_char_options=False, **kwargs): def __unpack_args(cls, arg_list): if not isinstance(arg_list, (list, tuple)): if isinstance(arg_list, text_type): - return [arg_list.encode('utf-8')] + return [arg_list.encode(defenc)] return [str(arg_list)] outlist = list() @@ -444,7 +448,7 @@ def __unpack_args(cls, arg_list): if isinstance(arg_list, (list, tuple)): outlist.extend(cls.__unpack_args(arg)) elif isinstance(arg_list, text_type): - outlist.append(arg_list.encode('utf-8')) + outlist.append(arg_list.encode(defenc)) # END recursion else: outlist.append(str(arg)) @@ -569,14 +573,20 @@ def _parse_object_header(self, header_line): raise ValueError("Failed to parse header: %r" % header_line) return (tokens[0], tokens[1], int(tokens[2])) - def __prepare_ref(self, ref): - # required for command to separate refs on stdin - refstr = str(ref) # could be ref-object - if refstr.endswith("\n"): - return refstr - return refstr + "\n" + def _prepare_ref(self, ref): + # required for command to separate refs on stdin, as bytes + refstr = ref + if isinstance(ref, bytes): + # Assume 40 bytes hexsha - bin-to-ascii for some reason returns bytes, not text + refstr = ref.decode('ascii') + elif not isinstance(ref, string_types): + refstr = str(ref) # could be ref-object + + if not refstr.endswith("\n"): + refstr += "\n" + return refstr.encode(defenc) - def __get_persistent_cmd(self, attr_name, cmd_name, *args, **kwargs): + def _get_persistent_cmd(self, attr_name, cmd_name, *args, **kwargs): cur_val = getattr(self, attr_name) if cur_val is not None: return cur_val @@ -589,7 +599,7 @@ def __get_persistent_cmd(self, attr_name, cmd_name, *args, **kwargs): return cmd def __get_object_header(self, cmd, ref): - cmd.stdin.write(self.__prepare_ref(ref)) + cmd.stdin.write(self._prepare_ref(ref)) cmd.stdin.flush() return self._parse_object_header(cmd.stdout.readline()) @@ -601,7 +611,7 @@ def get_object_header(self, ref): once and reuses the command in subsequent calls. :return: (hexsha, type_string, size_as_int)""" - cmd = self.__get_persistent_cmd("cat_file_header", "cat_file", batch_check=True) + cmd = self._get_persistent_cmd("cat_file_header", "cat_file", batch_check=True) return self.__get_object_header(cmd, ref) def get_object_data(self, ref): @@ -618,7 +628,7 @@ def stream_object_data(self, ref): :return: (hexsha, type_string, size_as_int, stream) :note: This method is not threadsafe, you need one independent Command instance per thread to be safe !""" - cmd = self.__get_persistent_cmd("cat_file_all", "cat_file", batch=True) + cmd = self._get_persistent_cmd("cat_file_all", "cat_file", batch=True) hexsha, typename, size = self.__get_object_header(cmd, ref) return (hexsha, typename, size, self.CatFileContentStream(size, cmd.stdout)) diff --git a/git/compat.py b/git/compat.py index a95c56674..4a892ad29 100644 --- a/git/compat.py +++ b/git/compat.py @@ -7,6 +7,8 @@ """utilities to help provide compatibility with python 3""" # flake8: noqa +import sys + from gitdb.utils.compat import ( PY3, xrange, @@ -17,11 +19,39 @@ from gitdb.utils.encoding import ( string_types, text_type, - force_bytes + force_bytes, + force_text ) +defenc = sys.getdefaultencoding() if PY3: import io FileType = io.IOBase else: FileType = file + # usually, this is just ascii, which might not enough for our encoding needs + # Unless it's set specifically, we override it to be utf-8 + if defenc == 'ascii': + defenc = 'utf-8' + + +def with_metaclass(meta, *bases): + """copied from https://github.com/Byron/bcore/blob/master/src/python/butility/future.py#L15""" + class metaclass(meta): + __call__ = type.__call__ + __init__ = type.__init__ + + def __new__(cls, name, nbases, d): + if nbases is None: + return type.__new__(cls, name, (), d) + # There may be clients who rely on this attribute to be set to a reasonable value, which is why + # we set the __metaclass__ attribute explicitly + if not PY3 and '___metaclass__' not in d: + d['__metaclass__'] = meta + # end + return meta(name, bases, d) + # end + # end metaclass + return metaclass(meta.__name__ + 'Helper', None, {}) + # end handle py2 + diff --git a/git/config.py b/git/config.py index 34fe290ba..988547a0e 100644 --- a/git/config.py +++ b/git/config.py @@ -14,12 +14,15 @@ import configparser as cp import inspect import logging +import abc from git.odict import OrderedDict from git.util import LockFile from git.compat import ( string_types, - FileType + FileType, + defenc, + with_metaclass ) __all__ = ('GitConfigParser', 'SectionConstraint') @@ -28,7 +31,7 @@ log = logging.getLogger('git.config') -class MetaParserBuilder(type): +class MetaParserBuilder(abc.ABCMeta): """Utlity class wrapping base-class methods into decorators that assure read-only properties""" def __new__(metacls, name, bases, clsdict): @@ -39,7 +42,7 @@ def __new__(metacls, name, bases, clsdict): if kmm in clsdict: mutating_methods = clsdict[kmm] for base in bases: - methods = (t for t in inspect.getmembers(base, inspect.ismethod) if not t[0].startswith("_")) + methods = (t for t in inspect.getmembers(base, inspect.isroutine) if not t[0].startswith("_")) for name, method in methods: if name in clsdict: continue @@ -112,7 +115,7 @@ def config(self): return self._config -class GitConfigParser(cp.RawConfigParser, object): +class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, object)): """Implements specifics required to read git style configuration files. @@ -128,7 +131,6 @@ class GitConfigParser(cp.RawConfigParser, object): :note: The config is case-sensitive even when queried, hence section and option names must match perfectly.""" - __metaclass__ = MetaParserBuilder #{ Configuration # The lock type determines the type of lock to use in new configuration readers. @@ -150,7 +152,6 @@ class GitConfigParser(cp.RawConfigParser, object): # list of RawConfigParser methods able to change the instance _mutating_methods_ = ("add_section", "remove_section", "remove_option", "set") - __slots__ = ("_sections", "_defaults", "_file_or_files", "_read_only", "_is_initialized", '_lock') def __init__(self, file_or_files, read_only=True): """Initialize a configuration reader to read the given file_or_files and to @@ -162,12 +163,12 @@ def __init__(self, file_or_files, read_only=True): :param read_only: If True, the ConfigParser may only read the data , but not change it. If False, only a single file path or file object may be given.""" - super(GitConfigParser, self).__init__() - # initialize base with ordered dictionaries to be sure we write the same - # file back - self._sections = OrderedDict() - self._defaults = OrderedDict() + cp.RawConfigParser.__init__(self, dict_type=OrderedDict) + # Used in python 3, needs to stay in sync with sections for underlying implementation to work + if not hasattr(self, '_proxies'): + self._proxies = self._dict() + self._file_or_files = file_or_files self._read_only = read_only self._is_initialized = False @@ -222,7 +223,8 @@ def _read(self, fp, fpname): lineno = 0 e = None # None, or an exception while True: - line = fp.readline() + # we assume to read binary ! + line = fp.readline().decode(defenc) if not line: break lineno = lineno + 1 @@ -242,9 +244,9 @@ def _read(self, fp, fpname): elif sectname == cp.DEFAULTSECT: cursect = self._defaults else: - # THE ONLY LINE WE CHANGED ! - cursect = OrderedDict((('__name__', sectname),)) + cursect = self._dict((('__name__', sectname),)) self._sections[sectname] = cursect + self._proxies[sectname] = None # So sections can't start with a continuation line optname = None # no section header in the file? @@ -295,7 +297,7 @@ def read(self): # assume a path if it is not a file-object if not hasattr(file_object, "seek"): try: - fp = open(file_object) + fp = open(file_object, 'rb') close_fp = True except IOError: continue @@ -314,16 +316,17 @@ def _write(self, fp): """Write an .ini-format representation of the configuration state in git compatible format""" def write_section(name, section_dict): - fp.write("[%s]\n" % name) + fp.write(("[%s]\n" % name).encode(defenc)) for (key, value) in section_dict.items(): if key != "__name__": - fp.write("\t%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) + fp.write(("\t%s = %s\n" % (key, str(value).replace('\n', '\n\t'))).encode(defenc)) # END if key is not __name__ # END section writing if self._defaults: write_section(cp.DEFAULTSECT, self._defaults) - map(lambda t: write_section(t[0], t[1]), self._sections.items()) + for name, value in self._sections.items(): + write_section(name, value) @needs_values def write(self): @@ -371,8 +374,7 @@ def _assure_writable(self, method_name): @set_dirty_and_flush_changes def add_section(self, section): """Assures added options will stay in order""" - super(GitConfigParser, self).add_section(section) - self._sections[section] = OrderedDict() + return super(GitConfigParser, self).add_section(section) @property def read_only(self): diff --git a/git/objects/util.py b/git/objects/util.py index fdf9622be..cefef862d 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -46,17 +46,17 @@ def get_object_type_by_name(object_type_name): :param object_type_name: Member of TYPES :raise ValueError: In case object_type_name is unknown""" - if object_type_name == "commit": - import commit + if object_type_name == b"commit": + from . import commit return commit.Commit - elif object_type_name == "tag": - import tag + elif object_type_name == b"tag": + from . import tag return tag.TagObject - elif object_type_name == "blob": - import blob + elif object_type_name == b"blob": + from . import blob return blob.Blob - elif object_type_name == "tree": - import tree + elif object_type_name == b"tree": + from . import tree return tree.Tree else: raise ValueError("Cannot handle unknown object type: %s" % object_type_name) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 624b1a091..1ac9ac65e 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -19,7 +19,9 @@ hex_to_bin, LockedFD ) -from git.compat import string_types +from git.compat import ( + string_types, +) from .log import RefLog @@ -79,10 +81,10 @@ def _get_packed_refs_path(cls, repo): @classmethod def _iter_packed_refs(cls, repo): - """Returns an iterator yielding pairs of sha1/path pairs for the corresponding refs. + """Returns an iterator yielding pairs of sha1/path pairs (as bytes) for the corresponding refs. :note: The packed refs file will be kept open as long as we iterate""" try: - fp = open(cls._get_packed_refs_path(repo), 'rb') + fp = open(cls._get_packed_refs_path(repo), 'rt') for line in fp: line = line.strip() if not line: @@ -123,12 +125,12 @@ def dereference_recursive(cls, repo, ref_path): @classmethod def _get_ref_info(cls, repo, ref_path): - """Return: (sha, target_ref_path) if available, the sha the file at + """Return: (str(sha), str(target_ref_path)) if available, the sha the file at rela_path points to, or None. target_ref_path is the reference we point to, or None""" tokens = None try: - fp = open(join(repo.git_dir, ref_path), 'r') + fp = open(join(repo.git_dir, ref_path), 'rt') value = fp.read().rstrip() fp.close() # Don't only split on spaces, but on whitespace, which allows to parse lines like @@ -141,7 +143,8 @@ def _get_ref_info(cls, repo, ref_path): for sha, path in cls._iter_packed_refs(repo): if path != ref_path: continue - tokens = (sha, path) + # sha will be used as + tokens = sha, path break # END for each packed ref # END handle packed refs diff --git a/git/remote.py b/git/remote.py index 9ebc52fe7..63f21c4e3 100644 --- a/git/remote.py +++ b/git/remote.py @@ -32,6 +32,7 @@ finalize_process ) from gitdb.util import join +from git.compat import defenc __all__ = ('RemoteProgress', 'PushInfo', 'FetchInfo', 'Remote') @@ -46,16 +47,16 @@ def digest_process_messages(fh, progress): :param fh: File handle to read from :return: list(line, ...) list of lines without linebreaks that did not contain progress information""" - line_so_far = '' + line_so_far = b'' dropped_lines = list() while True: - char = fh.read(1) + char = fh.read(1) # reads individual single byte strings if not char: break - if char in ('\r', '\n') and line_so_far: - dropped_lines.extend(progress._parse_progress_line(line_so_far)) - line_so_far = '' + if char in (b'\r', b'\n') and line_so_far: + dropped_lines.extend(progress._parse_progress_line(line_so_far.decode(defenc))) + line_so_far = b'' else: line_so_far += char # END process parsed line diff --git a/git/test/test_config.py b/git/test/test_config.py index 0301c54fb..f02754d51 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -11,16 +11,17 @@ from git import ( GitConfigParser ) -from git.compat import string_types +from git.compat import ( + string_types, +) import io from copy import copy -from ConfigParser import NoSectionError - +from git.config import cp class TestBase(TestCase): def _to_memcache(self, file_path): - fp = open(file_path, "r") + fp = open(file_path, "rb") sio = io.BytesIO(fp.read()) sio.name = file_path return sio @@ -39,7 +40,7 @@ def test_read_write(self): w_config.write() # enforce writing # we stripped lines when reading, so the results differ - assert file_obj.getvalue() != file_obj_orig.getvalue() + assert file_obj.getvalue() and file_obj.getvalue() != file_obj_orig.getvalue() # creating an additional config writer must fail due to exclusive access self.failUnlessRaises(IOError, GitConfigParser, file_obj, read_only=False) @@ -105,4 +106,4 @@ def test_base(self): assert r_config.get_value("doesnt", "exist", default) == default # it raises if there is no default though - self.failUnlessRaises(NoSectionError, r_config.get_value, "doesnt", "exist") + self.failUnlessRaises(cp.NoSectionError, r_config.get_value, "doesnt", "exist") From 3d0556a31916a709e9da3eafb92fc6b8bf69896c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 16:10:50 +0100 Subject: [PATCH 0026/2790] Added test of #147 to verify it works. Applied a few more fixes to commit implementation, possibly not the last --- git/objects/commit.py | 25 +++++++++---------------- git/test/test_base.py | 11 +++++++++++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/git/objects/commit.py b/git/objects/commit.py index 79d460ad9..5ad7902bb 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -373,40 +373,33 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, def _serialize(self, stream): write = stream.write - write("tree %s\n" % self.tree) + write(("tree %s\n" % self.tree).encode('ascii')) for p in self.parents: - write("parent %s\n" % p) + write(("parent %s\n" % p).encode('ascii')) a = self.author aname = a.name - if isinstance(aname, text_type): - aname = aname.encode(self.encoding) - # END handle unicode in name - c = self.committer fmt = "%s %s <%s> %s %s\n" - write(fmt % ("author", aname, a.email, + write((fmt % ("author", aname, a.email, self.authored_date, - altz_to_utctz_str(self.author_tz_offset))) + altz_to_utctz_str(self.author_tz_offset))).encode(self.encoding)) # encode committer aname = c.name - if isinstance(aname, text_type): - aname = aname.encode(self.encoding) - # END handle unicode in name - write(fmt % ("committer", aname, c.email, + write((fmt % ("committer", aname, c.email, self.committed_date, - altz_to_utctz_str(self.committer_tz_offset))) + altz_to_utctz_str(self.committer_tz_offset))).encode(self.encoding)) if self.encoding != self.default_encoding: - write("encoding %s\n" % self.encoding) + write(("encoding %s\n" % self.encoding).encode('ascii')) if self.gpgsig: write("gpgsig") for sigline in self.gpgsig.rstrip("\n").split("\n"): - write(" " + sigline + "\n") + write((" " + sigline + "\n").encode('ascii')) - write("\n") + write(b"\n") # write plain bytes, be sure its encoded according to our encoding if isinstance(self.message, text_type): diff --git a/git/test/test_base.py b/git/test/test_base.py index a14d46806..edacbd809 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -1,3 +1,4 @@ +#-*-coding:utf-8-*- # test_base.py # Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors # @@ -106,3 +107,13 @@ def test_with_rw_remote_and_rw_repo(self, rw_repo, rw_remote_repo): assert not rw_repo.config_reader("repository").getboolean("core", "bare") assert rw_remote_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib')) + + @with_rw_repo('0.1.6') + def test_add_unicode(self, rw_repo): + filename = u"שלום.txt" + + file_path = os.path.join(rw_repo.working_dir, filename) + open(file_path, "wb").write('something') + + rw_repo.git.add(rw_repo.working_dir) + rw_repo.index.commit('message') From 8a308613467a1510f8dac514624abae4e10c0779 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 16:44:54 +0100 Subject: [PATCH 0027/2790] Fixes test_blob and improved commit writing/reading --- git/compat.py | 4 +++- git/objects/commit.py | 44 +++++++++++++++++++++++-------------------- git/objects/fun.py | 26 ++++++++++++------------- 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/git/compat.py b/git/compat.py index 4a892ad29..f11d14239 100644 --- a/git/compat.py +++ b/git/compat.py @@ -27,12 +27,15 @@ if PY3: import io FileType = io.IOBase + def byte_ord(b): + return b else: FileType = file # usually, this is just ascii, which might not enough for our encoding needs # Unless it's set specifically, we override it to be utf-8 if defenc == 'ascii': defenc = 'utf-8' + byte_ord = ord def with_metaclass(meta, *bases): @@ -54,4 +57,3 @@ def __new__(cls, name, nbases, d): # end metaclass return metaclass(meta.__name__ + 'Helper', None, {}) # end handle py2 - diff --git a/git/objects/commit.py b/git/objects/commit.py index 5ad7902bb..f8b5c969b 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -419,23 +419,25 @@ def _deserialize(self, stream): next_line = None while True: parent_line = readline() - if not parent_line.startswith('parent'): + if not parent_line.startswith(b'parent'): next_line = parent_line break # END abort reading parents - self.parents.append(type(self)(self.repo, hex_to_bin(parent_line.split()[-1]))) + self.parents.append(type(self)(self.repo, hex_to_bin(parent_line.split()[-1].decode('ascii')))) # END for each parent line self.parents = tuple(self.parents) - self.author, self.authored_date, self.author_tz_offset = parse_actor_and_date(next_line) - self.committer, self.committed_date, self.committer_tz_offset = parse_actor_and_date(readline()) + # we don't know actual author encoding before we have parsed it, so keep the lines around + author_line = next_line + committer_line = readline() # we might run into one or more mergetag blocks, skip those for now next_line = readline() - while next_line.startswith('mergetag '): + while next_line.startswith(b'mergetag '): next_line = readline() while next_line.startswith(' '): next_line = readline() + # end skip mergetags # now we can have the encoding line, or an empty line followed by the optional # message. @@ -444,39 +446,40 @@ def _deserialize(self, stream): # read headers enc = next_line buf = enc.strip() - while buf != "": - if buf[0:10] == "encoding ": - self.encoding = buf[buf.find(' ') + 1:] - elif buf[0:7] == "gpgsig ": - sig = buf[buf.find(' ') + 1:] + "\n" + while buf: + if buf[0:10] == b"encoding ": + self.encoding = buf[buf.find(' ') + 1:].decode('ascii') + elif buf[0:7] == b"gpgsig ": + sig = buf[buf.find(b' ') + 1:] + b"\n" is_next_header = False while True: sigbuf = readline() - if sigbuf == "": + if not sigbuf: break - if sigbuf[0:1] != " ": + if sigbuf[0:1] != b" ": buf = sigbuf.strip() is_next_header = True break sig += sigbuf[1:] - self.gpgsig = sig.rstrip("\n") + # end read all signature + self.gpgsig = sig.rstrip(b"\n").decode('ascii') if is_next_header: continue buf = readline().strip() - # decode the authors name + try: - self.author.name = self.author.name.decode(self.encoding) + self.author, self.authored_date, self.author_tz_offset = \ + parse_actor_and_date(author_line.decode(self.encoding)) except UnicodeDecodeError: - log.error("Failed to decode author name '%s' using encoding %s", self.author.name, self.encoding, + log.error("Failed to decode author line '%s' using encoding %s", author_line, self.encoding, exc_info=True) - # END handle author's encoding - # decode committer name try: - self.committer.name = self.committer.name.decode(self.encoding) + self.committer, self.committed_date, self.committer_tz_offset = \ + parse_actor_and_date(committer_line.decode(self.encoding)) except UnicodeDecodeError: - log.error("Failed to decode committer name '%s' using encoding %s", self.committer.name, self.encoding, + log.error("Failed to decode committer line '%s' using encoding %s", committer_line, self.encoding, exc_info=True) # END handle author's encoding @@ -488,6 +491,7 @@ def _deserialize(self, stream): except UnicodeDecodeError: log.error("Failed to decode message '%s' using encoding %s", self.message, self.encoding, exc_info=True) # END exception handling + return self #} END serializable implementation diff --git a/git/objects/fun.py b/git/objects/fun.py index db2ec7c22..f92a4c062 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -1,6 +1,9 @@ """Module with functions which are supposed to be as fast as possible""" from stat import S_ISDIR from git.compat import ( + byte_ord, + force_bytes, + defenc, xrange, text_type ) @@ -17,13 +20,13 @@ def tree_to_stream(entries, write): bit_mask = 7 # 3 bits set for binsha, mode, name in entries: - mode_str = '' + mode_str = b'' for i in xrange(6): mode_str = chr(((mode >> (i * 3)) & bit_mask) + ord_zero) + mode_str # END for each 8 octal value # git slices away the first octal if its zero - if mode_str[0] == '0': + if byte_ord(mode_str[0]) == ord_zero: mode_str = mode_str[1:] # END save a byte @@ -33,16 +36,16 @@ def tree_to_stream(entries, write): # According to my tests, this is exactly what git does, that is it just # takes the input literally, which appears to be utf8 on linux. if isinstance(name, text_type): - name = name.encode("utf8") - write("%s %s\0%s" % (mode_str, name, binsha)) + name = name.encode(defenc) + write(b''.join(mode_str, b' ', name, b'\0', binsha)) # END for each item - def tree_entries_from_data(data): """Reads the binary representation of a tree and returns tuples of Tree items - :param data: data block with tree data + :param data: data block with tree data (as bytes) :return: list(tuple(binsha, mode, tree_relative_path), ...)""" ord_zero = ord('0') + space_ord = ord(' ') len_data = len(data) i = 0 out = list() @@ -52,10 +55,10 @@ def tree_entries_from_data(data): # read mode # Some git versions truncate the leading 0, some don't # The type will be extracted from the mode later - while data[i] != ' ': + while byte_ord(data[i]) != space_ord: # move existing mode integer up one level being 3 bits # and add the actual ordinal value of the character - mode = (mode << 3) + (ord(data[i]) - ord_zero) + mode = (mode << 3) + (byte_ord(data[i]) - ord_zero) i += 1 # END while reading mode @@ -65,7 +68,7 @@ def tree_entries_from_data(data): # parse name, it is NULL separated ns = i - while data[i] != '\0': + while byte_ord(data[i]) != 0: i += 1 # END while not reached NULL @@ -73,12 +76,9 @@ def tree_entries_from_data(data): # Only use the respective unicode object if the byte stream was encoded name = data[ns:i] try: - name_enc = name.decode("utf-8") + name = name.decode(defenc) except UnicodeDecodeError: pass - else: - if len(name) > len(name_enc): - name = name_enc # END handle encoding # byte is NULL, get next 20 From e1060a2a8c90c0730c3541811df8f906dac510a7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 17:59:22 +0100 Subject: [PATCH 0028/2790] test_commit works once again --- doc/source/changes.rst | 1 + git/cmd.py | 7 ++++++- git/config.py | 7 ++++++- git/diff.py | 2 +- git/objects/base.py | 7 ++++--- git/objects/commit.py | 4 ++-- git/objects/fun.py | 3 +-- git/refs/symbolic.py | 2 +- git/repo/base.py | 17 +++++++++------- git/test/test_commit.py | 44 +++++++++++++++++++++-------------------- 10 files changed, 55 insertions(+), 39 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index cf528b280..06a73f41d 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -5,6 +5,7 @@ Changelog 0.3.4 - python 3 support ======================== * Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes. +* Id attribute of Commit objects is now `hexsha`, instead of `binsha`. The latter makes no sense in python 3 and I see no application of it anyway besides its artificial usage in test cases. 0.3.3 ===== diff --git a/git/cmd.py b/git/cmd.py index c536b43c5..2bff33109 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -320,6 +320,7 @@ def execute(self, command, always be created with a pipe due to issues with subprocess. This merely is a workaround as data will be copied from the output pipe to the given output stream directly. + Judging from the implementation, you shouldn't use this flag ! :param subprocess_kwargs: Keyword arguments to be passed to subprocess.Popen. Please note that @@ -411,9 +412,13 @@ def execute(self, command, else: raise GitCommandError(command, status, stderr_value) + + if isinstance(stdout_value, bytes): # could also be output_stream + stdout_value = stdout_value.decode(defenc) + # Allow access to the command's status code if with_extended_output: - return (status, stdout_value, stderr_value) + return (status, stdout_value, stderr_value.decode(defenc)) else: return stdout_value diff --git a/git/config.py b/git/config.py index 988547a0e..7917bc5a1 100644 --- a/git/config.py +++ b/git/config.py @@ -201,6 +201,11 @@ def __del__(self): self.write() except IOError: log.error("Exception during destruction of GitConfigParser", exc_info=True) + except ReferenceError: + # This happens in PY3 ... and usually means that some state cannot be written + # as the sections dict cannot be iterated + # Usually when shutting down the interpreter, don'y know how to fix this + pass finally: self._lock._release_lock() @@ -345,7 +350,7 @@ def write(self): # END get lock for physical files if not hasattr(fp, "seek"): - fp = open(self._file_or_files, "w") + fp = open(self._file_or_files, "wb") close_fp = True else: fp.seek(0) diff --git a/git/diff.py b/git/diff.py index b3e7245bc..1692d83e6 100644 --- a/git/diff.py +++ b/git/diff.py @@ -195,7 +195,7 @@ class Diff(object): """, re.VERBOSE | re.MULTILINE) # can be used for comparisons NULL_HEX_SHA = "0" * 40 - NULL_BIN_SHA = "\0" * 20 + NULL_BIN_SHA = b"\0" * 20 __slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "new_file", "deleted_file", "rename_from", "rename_to", "diff") diff --git a/git/objects/base.py b/git/objects/base.py index 1f0d57524..004e3981e 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -21,7 +21,7 @@ class Object(LazyMixin): """Implements an Object which may be Blobs, Trees, Commits and Tags""" NULL_HEX_SHA = '0' * 40 - NULL_BIN_SHA = '\0' * 20 + NULL_BIN_SHA = b'\0' * 20 TYPES = (dbtyp.str_blob_type, dbtyp.str_tree_type, dbtyp.str_commit_type, dbtyp.str_tag_type) __slots__ = ("repo", "binsha", "size") @@ -94,7 +94,7 @@ def __hash__(self): def __str__(self): """:return: string of our SHA1 as understood by all git commands""" - return bin_to_hex(self.binsha) + return self.hexsha def __repr__(self): """:return: string with pythonic representation of our object""" @@ -103,7 +103,8 @@ def __repr__(self): @property def hexsha(self): """:return: 40 byte hex version of our 20 byte binary sha""" - return bin_to_hex(self.binsha) + # b2a_hex produces bytes + return bin_to_hex(self.binsha).decode('ascii') @property def data_stream(self): diff --git a/git/objects/commit.py b/git/objects/commit.py index f8b5c969b..53af22cd4 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -62,7 +62,7 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable): "author", "authored_date", "author_tz_offset", "committer", "committed_date", "committer_tz_offset", "message", "parents", "encoding", "gpgsig") - _id_attribute_ = "binsha" + _id_attribute_ = "hexsha" def __init__(self, repo, binsha, tree=None, author=None, authored_date=None, author_tz_offset=None, committer=None, committed_date=None, committer_tz_offset=None, @@ -395,7 +395,7 @@ def _serialize(self, stream): write(("encoding %s\n" % self.encoding).encode('ascii')) if self.gpgsig: - write("gpgsig") + write(b"gpgsig") for sigline in self.gpgsig.rstrip("\n").split("\n"): write((" " + sigline + "\n").encode('ascii')) diff --git a/git/objects/fun.py b/git/objects/fun.py index f92a4c062..610bdb5ce 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -2,7 +2,6 @@ from stat import S_ISDIR from git.compat import ( byte_ord, - force_bytes, defenc, xrange, text_type @@ -37,7 +36,7 @@ def tree_to_stream(entries, write): # takes the input literally, which appears to be utf8 on linux. if isinstance(name, text_type): name = name.encode(defenc) - write(b''.join(mode_str, b' ', name, b'\0', binsha)) + write(b''.join((mode_str, b' ', name, b'\0', binsha))) # END for each item def tree_entries_from_data(data): diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 1ac9ac65e..252462a92 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -308,7 +308,7 @@ def set_reference(self, ref, logmsg=None): lfd = LockedFD(fpath) fd = lfd.open(write=True, stream=True) - fd.write(write_value) + fd.write(write_value.encode('ascii')) lfd.commit() # Adjust the reflog diff --git a/git/repo/base.py b/git/repo/base.py index f92a85ce3..27c640ff6 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -47,7 +47,10 @@ read_gitfile, touch, ) -from git.compat import text_type +from git.compat import ( + text_type, + defenc +) import os import sys @@ -177,11 +180,11 @@ def __hash__(self): # Description property def _get_description(self): filename = join(self.git_dir, 'description') - return open(filename).read().rstrip() + return open(filename, 'rb').read().rstrip().decode(defenc) def _set_description(self, descr): filename = join(self.git_dir, 'description') - open(filename, 'w').write(descr + '\n') + open(filename, 'wb').write((descr + '\n').encode(defenc)) description = property(_get_description, _set_description, doc="the project's description") @@ -464,8 +467,8 @@ def _get_alternates(self): if os.path.exists(alternates_path): try: - f = open(alternates_path) - alts = f.read() + f = open(alternates_path, 'rb') + alts = f.read().decode(defenc) finally: f.close() return alts.strip().splitlines() @@ -489,8 +492,8 @@ def _set_alternates(self, alts): os.remove(alternates_path) else: try: - f = open(alternates_path, 'w') - f.write("\n".join(alts)) + f = open(alternates_path, 'wb') + f.write("\n".join(alts).encode(defenc)) finally: f.close() # END file handling diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 5f45e59d1..37a54092f 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -51,7 +51,7 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False) stream.seek(0) istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream)) - assert istream.hexsha == cm.hexsha + assert istream.hexsha == cm.hexsha.encode('ascii') nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree, cm.author, cm.authored_date, cm.author_tz_offset, @@ -129,7 +129,7 @@ def check_entries(d): def test_unicode_actor(self): # assure we can parse unicode actors correctly - name = "Üäöß ÄußÉ".decode("utf-8") + name = u"Üäöß ÄußÉ" assert len(name) == 9 special = Actor._from_string(u"%s " % name) assert special.name == name @@ -146,13 +146,13 @@ def test_traversal(self): # basic branch first, depth first dfirst = start.traverse(branch_first=False) bfirst = start.traverse(branch_first=True) - assert dfirst.next() == p0 - assert dfirst.next() == p00 + assert next(dfirst) == p0 + assert next(dfirst) == p00 - assert bfirst.next() == p0 - assert bfirst.next() == p1 - assert bfirst.next() == p00 - assert bfirst.next() == p10 + assert next(bfirst) == p0 + assert next(bfirst) == p1 + assert next(bfirst) == p00 + assert next(bfirst) == p10 # at some point, both iterations should stop assert list(bfirst)[-1] == first @@ -161,19 +161,19 @@ def test_traversal(self): assert len(l[0]) == 2 # ignore self - assert start.traverse(ignore_self=False).next() == start + assert next(start.traverse(ignore_self=False)) == start # depth assert len(list(start.traverse(ignore_self=False, depth=0))) == 1 # prune - assert start.traverse(branch_first=1, prune=lambda i, d: i == p0).next() == p1 + assert next(start.traverse(branch_first=1, prune=lambda i, d: i == p0)) == p1 # predicate - assert start.traverse(branch_first=1, predicate=lambda i, d: i == p1).next() == p1 + assert next(start.traverse(branch_first=1, predicate=lambda i, d: i == p1)) == p1 # traversal should stop when the beginning is reached - self.failUnlessRaises(StopIteration, first.traverse().next) + self.failUnlessRaises(StopIteration, next, first.traverse()) # parents of the first commit should be empty ( as the only parent has a null # sha ) @@ -210,7 +210,7 @@ def test_rev_list_bisect_all(self): first_parent=True, bisect_all=True) - commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs)) + commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs.encode('ascii'))) expected_ids = ( '7156cece3c49544abb6bf7a0c218eb36646fad6d', '1f66cfbbce58b4b552b041707a12d437cc5f400a', @@ -224,8 +224,10 @@ def test_count(self): assert self.rorepo.tag('refs/tags/0.1.5').commit.count() == 143 def test_list(self): + # This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string + # with actual 20 byte bytes. This usage makes no sense anyway assert isinstance(Commit.list_items(self.rorepo, '0.1.5', max_count=5)[ - hex_to_bin('5117c9c8a4d3af19a9958677e45cda9269de1541')], Commit) + '5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit) def test_str(self): commit = Commit(self.rorepo, Commit.NULL_BIN_SHA) @@ -247,12 +249,12 @@ def test_iter_parents(self): c = self.rorepo.commit('0.1.5') for skip in (0, 1): piter = c.iter_parents(skip=skip) - first_parent = piter.next() + first_parent = next(piter) assert first_parent != c assert first_parent == c.parents[0] # END for each - def test_base(self): + def test_name_rev(self): name_rev = self.rorepo.head.commit.name_rev assert isinstance(name_rev, string_types) @@ -270,10 +272,10 @@ def test_serialization_unicode_support(self): assert isinstance(cmt.message, text_type) # it automatically decodes it as such assert isinstance(cmt.author.name, text_type) # same here - cmt.message = "üäêèß".decode("utf-8") + cmt.message = u"üäêèß" assert len(cmt.message) == 5 - cmt.author.name = "äüß".decode("utf-8") + cmt.author.name = u"äüß" assert len(cmt.author.name) == 3 cstream = BytesIO() @@ -292,7 +294,7 @@ def test_serialization_unicode_support(self): def test_gpgsig(self): cmt = self.rorepo.commit() - cmt._deserialize(open(fixture_path('commit_with_gpgsig'))) + cmt._deserialize(open(fixture_path('commit_with_gpgsig'), 'rb')) fixture_sig = """-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) @@ -318,7 +320,7 @@ def test_gpgsig(self): cstream = BytesIO() cmt._serialize(cstream) - assert re.search(r"^gpgsig $", cstream.getvalue(), re.MULTILINE) + assert re.search(r"^gpgsig $", cstream.getvalue().decode('ascii'), re.MULTILINE) cstream.seek(0) cmt.gpgsig = None @@ -328,4 +330,4 @@ def test_gpgsig(self): cmt.gpgsig = None cstream = BytesIO() cmt._serialize(cstream) - assert not re.search(r"^gpgsig ", cstream.getvalue(), re.MULTILINE) + assert not re.search(r"^gpgsig ", cstream.getvalue().decode('ascii'), re.MULTILINE) From 31b3673bdb9d8fb7feea8ae887be455c4a880f76 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 18:03:08 +0100 Subject: [PATCH 0029/2790] test_diff works --- git/diff.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/git/diff.py b/git/diff.py index 1692d83e6..3c4e8529f 100644 --- a/git/diff.py +++ b/git/diff.py @@ -10,6 +10,8 @@ from .objects.blob import Blob from .objects.util import mode_str_to_int +from git.compat import defenc + __all__ = ('Diffable', 'DiffIndex', 'Diff') @@ -294,7 +296,7 @@ def _index_from_patch_format(cls, repo, stream): :param stream: result of 'git diff' as a stream (supporting file protocol) :return: git.DiffIndex """ # for now, we have to bake the stream - text = stream.read() + text = stream.read().decode(defenc) index = DiffIndex() diff_header = cls.re_header.match @@ -323,6 +325,7 @@ def _index_from_raw_format(cls, repo, stream): # :100644 100644 687099101... 37c5e30c8... M .gitignore index = DiffIndex() for line in stream: + line = line.decode(defenc) if not line.startswith(":"): continue # END its not a valid diff line From 4a67e4e49c4e7b82e416067df69c72656213e886 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 18:21:49 +0100 Subject: [PATCH 0030/2790] test_fun works --- git/compat.py | 3 +++ git/index/fun.py | 9 +++++---- git/objects/fun.py | 5 +++-- git/test/test_fun.py | 12 ++++++------ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/git/compat.py b/git/compat.py index f11d14239..b92054184 100644 --- a/git/compat.py +++ b/git/compat.py @@ -29,6 +29,8 @@ FileType = io.IOBase def byte_ord(b): return b + def bchr(n): + return bytes([n]) else: FileType = file # usually, this is just ascii, which might not enough for our encoding needs @@ -36,6 +38,7 @@ def byte_ord(b): if defenc == 'ascii': defenc = 'utf-8' byte_ord = ord + bchr = chr def with_metaclass(meta, *bases): diff --git a/git/index/fun.py b/git/index/fun.py index 0e49ae8d7..3e66a7ba7 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -37,6 +37,7 @@ from gitdb.base import IStream from gitdb.typ import str_tree_type +from git.compat import defenc __all__ = ('write_cache', 'read_cache', 'write_tree_from_cache', 'entry_key', 'stat_mode_to_index_mode', 'S_IFGITLINK') @@ -86,9 +87,9 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1 flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0], entry[8], entry[9], entry[10], entry[1], flags)) - write(path) + write(path.encode(defenc)) real_size = ((tell() - beginoffset + 8) & ~7) - write("\0" * ((beginoffset + real_size) - tell())) + write(b"\0" * ((beginoffset + real_size) - tell())) # END for each entry # write previously cached extensions data @@ -102,7 +103,7 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1 def read_header(stream): """Return tuple(version_long, num_entries) from the given stream""" type_id = stream.read(4) - if type_id != "DIRC": + if type_id != b"DIRC": raise AssertionError("Invalid index file header: %r" % type_id) version, num_entries = unpack(">LL", stream.read(4 * 2)) @@ -142,7 +143,7 @@ def read_cache(stream): (dev, ino, mode, uid, gid, size, sha, flags) = \ unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2)) path_size = flags & CE_NAMEMASK - path = read(path_size) + path = read(path_size).decode(defenc) real_size = ((tell() - beginoffset + 8) & ~7) read((beginoffset + real_size) - tell()) diff --git a/git/objects/fun.py b/git/objects/fun.py index 610bdb5ce..ba8dbcf46 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -4,7 +4,8 @@ byte_ord, defenc, xrange, - text_type + text_type, + bchr ) __all__ = ('tree_to_stream', 'tree_entries_from_data', 'traverse_trees_recursive', @@ -21,7 +22,7 @@ def tree_to_stream(entries, write): for binsha, mode, name in entries: mode_str = b'' for i in xrange(6): - mode_str = chr(((mode >> (i * 3)) & bit_mask) + ord_zero) + mode_str + mode_str = bchr(((mode >> (i * 3)) & bit_mask) + ord_zero) + mode_str # END for each 8 octal value # git slices away the first octal if its zero diff --git a/git/test/test_fun.py b/git/test/test_fun.py index 9d3e749eb..40d040b97 100644 --- a/git/test/test_fun.py +++ b/git/test/test_fun.py @@ -30,7 +30,7 @@ class TestFun(TestBase): def _assert_index_entries(self, entries, trees): - index = IndexFile.from_tree(self.rorepo, *[self.rorepo.tree(bin_to_hex(t)) for t in trees]) + index = IndexFile.from_tree(self.rorepo, *[self.rorepo.tree(bin_to_hex(t).decode('ascii')) for t in trees]) assert entries assert len(index.entries) == len(entries) for entry in entries: @@ -91,9 +91,9 @@ def assert_entries(entries, num_entries, has_conflict=False): assert has_conflict == (len([e for e in entries if e.stage != 0]) > 0) mktree = self.mktree - shaa = "\1" * 20 - shab = "\2" * 20 - shac = "\3" * 20 + shaa = b"\1" * 20 + shab = b"\2" * 20 + shac = b"\3" * 20 odb = rwrepo.odb @@ -256,6 +256,6 @@ def test_tree_traversal_single(self): assert entries # END for each commit - def test_tree_entries_from_data(self): + def test_tree_entries_from_data_with_failing_name_decode(self): r = tree_entries_from_data(b'100644 \x9f\0aaa') - assert r == [('aaa', 33188, '\x9f')], r + assert r == [(b'aaa', 33188, b'\x9f')], r From 7297ff651c3cc6abf648b3fe730c2b5b1f3edbd3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 5 Jan 2015 18:30:30 +0100 Subject: [PATCH 0031/2790] test_git works --- git/test/test_git.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index 553f8d1b5..8087d6f8b 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -1,3 +1,4 @@ +#-*-coding:utf-8-*- # test_git.py # Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors # @@ -32,12 +33,12 @@ def test_call_process_calls_execute(self, git): assert_equal(git.call_args, ((['git', 'version'],), {})) def test_call_unpack_args_unicode(self): - args = Git._Git__unpack_args(u'Unicode' + unichr(40960)) - assert_equal(args, ['Unicode\xea\x80\x80']) + args = Git._Git__unpack_args(u'Unicode€™') + assert_equal(args, [b'Unicode\xe2\x82\xac\xe2\x84\xa2']) def test_call_unpack_args(self): - args = Git._Git__unpack_args(['git', 'log', '--', u'Unicode' + unichr(40960)]) - assert_equal(args, ['git', 'log', '--', 'Unicode\xea\x80\x80']) + args = Git._Git__unpack_args(['git', 'log', '--', u'Unicode€™']) + assert_equal(args, [b'git', b'log', b'--', b'Unicode\xe2\x82\xac\xe2\x84\xa2']) @raises(GitCommandError) def test_it_raises_errors(self): @@ -75,13 +76,13 @@ def test_persistent_cat_file_command(self): import subprocess as sp hexsha = "b2339455342180c7cc1e9bba3e9f181f7baa5167" g = self.git.cat_file(batch_check=True, istream=sp.PIPE, as_process=True) - g.stdin.write("b2339455342180c7cc1e9bba3e9f181f7baa5167\n") + g.stdin.write(b"b2339455342180c7cc1e9bba3e9f181f7baa5167\n") g.stdin.flush() obj_info = g.stdout.readline() # read header + data g = self.git.cat_file(batch=True, istream=sp.PIPE, as_process=True) - g.stdin.write("b2339455342180c7cc1e9bba3e9f181f7baa5167\n") + g.stdin.write(b"b2339455342180c7cc1e9bba3e9f181f7baa5167\n") g.stdin.flush() obj_info_two = g.stdout.readline() assert obj_info == obj_info_two @@ -92,7 +93,7 @@ def test_persistent_cat_file_command(self): g.stdout.read(1) # now we should be able to read a new object - g.stdin.write("b2339455342180c7cc1e9bba3e9f181f7baa5167\n") + g.stdin.write(b"b2339455342180c7cc1e9bba3e9f181f7baa5167\n") g.stdin.flush() assert g.stdout.readline() == obj_info From 45c1c99a22e95d730d3096c339d97181d314d6ca Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 10:43:25 +0100 Subject: [PATCH 0032/2790] test_index works --- git/compat.py | 4 ++++ git/config.py | 9 ++++++++- git/index/base.py | 23 ++++++++++++----------- git/index/fun.py | 2 +- git/index/typ.py | 2 +- git/repo/base.py | 5 ++++- git/test/test_index.py | 37 +++++++++++++++++++------------------ git/util.py | 9 +++------ 8 files changed, 52 insertions(+), 39 deletions(-) diff --git a/git/compat.py b/git/compat.py index b92054184..5c330e5be 100644 --- a/git/compat.py +++ b/git/compat.py @@ -31,6 +31,8 @@ def byte_ord(b): return b def bchr(n): return bytes([n]) + def mviter(d): + return d.values() else: FileType = file # usually, this is just ascii, which might not enough for our encoding needs @@ -39,6 +41,8 @@ def bchr(n): defenc = 'utf-8' byte_ord = ord bchr = chr + def mviter(d): + return d.itervalues() def with_metaclass(meta, *bases): diff --git a/git/config.py b/git/config.py index 7917bc5a1..96991b841 100644 --- a/git/config.py +++ b/git/config.py @@ -99,6 +99,13 @@ def __init__(self, config, section): self._config = config self._section_name = section + def __del__(self): + # Yes, for some reason, we have to call it explicitly for it to work in PY3 ! + # Apparently __del__ doesn't get call anymore if refcount becomes 0 + # Ridiculous ... . + self._config.__del__() + # del self._config + def __getattr__(self, attr): if attr in self._valid_attrs_: return lambda *args, **kwargs: self._call_config(attr, *args, **kwargs) @@ -193,7 +200,7 @@ def __del__(self): """Write pending changes if required and release locks""" # checking for the lock here makes sure we do not raise during write() # in case an invalid parser was created who could not get a lock - if self.read_only or not self._lock._has_lock(): + if self.read_only or (self._lock and not self._lock._has_lock()): return try: diff --git a/git/index/base.py b/git/index/base.py index a994e7b6c..cc8834698 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -43,7 +43,9 @@ izip, xrange, string_types, - force_bytes + force_bytes, + defenc, + mviter ) from git.util import ( @@ -105,7 +107,7 @@ def __init__(self, repo, file_path=None): repository's index on demand.""" self.repo = repo self.version = self._VERSION - self._extension_data = '' + self._extension_data = b'' self._file_path = file_path or self._index_path() def _set_cache_(self, attr): @@ -165,9 +167,7 @@ def _deserialize(self, stream): def _entries_sorted(self): """:return: list of entries, in a sorted fashion, first by path, then by stage""" - entries_sorted = self.entries.values() - entries_sorted.sort(key=lambda e: (e.path, e.stage)) # use path/stage as sort key - return entries_sorted + return sorted(self.entries.values(), key=lambda e: (e.path, e.stage)) def _serialize(self, stream, ignore_tree_extension_data=False): entries = self._entries_sorted() @@ -399,7 +399,7 @@ def _write_path_to_stdin(self, proc, filepath, item, fmakeexc, fprogress, fprogress(filepath, False, item) rval = None try: - proc.stdin.write("%s\n" % filepath) + proc.stdin.write(("%s\n" % filepath).encode(defenc)) except IOError: # pipe broke, usually because some error happend raise fmakeexc() @@ -418,7 +418,7 @@ def iter_blobs(self, predicate=lambda t: True): Function(t) returning True if tuple(stage, Blob) should be yielded by the iterator. A default filter, the BlobFilter, allows you to yield blobs only if they match a given list of paths. """ - for entry in self.entries.itervalues(): + for entry in mviter(self.entries): blob = entry.to_blob(self.repo) blob.size = entry.size output = (entry.stage, blob) @@ -443,7 +443,7 @@ def unmerged_blobs(self): for stage, blob in self.iter_blobs(is_unmerged_blob): path_map.setdefault(blob.path, list()).append((stage, blob)) # END for each unmerged blob - for l in path_map.itervalues(): + for l in mviter(path_map): l.sort() return path_map @@ -860,7 +860,7 @@ def move(self, items, skip_errors=False, **kwargs): # parse result - first 0:n/2 lines are 'checking ', the remaining ones # are the 'renaming' ones which we parse - for ln in xrange(len(mvlines) / 2, len(mvlines)): + for ln in xrange(int(len(mvlines) / 2), len(mvlines)): tokens = mvlines[ln].split(' to ') assert len(tokens) == 2, "Too many tokens in %s" % mvlines[ln] @@ -958,6 +958,7 @@ def handle_stderr(proc, iter_checked_out_files): if not stderr: return # line contents: + stderr = stderr.decode(defenc) # git-checkout-index: this already exists failed_files = list() failed_reasons = list() @@ -1006,7 +1007,7 @@ def handle_stderr(proc, iter_checked_out_files): proc = self.repo.git.checkout_index(*args, **kwargs) proc.wait() fprogress(None, True, None) - rval_iter = (e.path for e in self.entries.itervalues()) + rval_iter = (e.path for e in mviter(self.entries)) handle_stderr(proc, rval_iter) return rval_iter else: @@ -1036,7 +1037,7 @@ def handle_stderr(proc, iter_checked_out_files): dir = co_path if not dir.endswith('/'): dir += '/' - for entry in self.entries.itervalues(): + for entry in mviter(self.entries): if entry.path.startswith(dir): p = entry.path self._write_path_to_stdin(proc, p, p, make_exc, diff --git a/git/index/fun.py b/git/index/fun.py index 3e66a7ba7..f0dee961e 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -73,7 +73,7 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1 # header version = 2 - write("DIRC") + write(b"DIRC") write(pack(">LL", version, len(entries))) # body diff --git a/git/index/typ.py b/git/index/typ.py index 692e1e18d..0998ecb07 100644 --- a/git/index/typ.py +++ b/git/index/typ.py @@ -75,7 +75,7 @@ def binsha(self): @property def hexsha(self): """hex version of our sha""" - return b2a_hex(self[1]) + return b2a_hex(self[1]).decode('ascii') @property def stage(self): diff --git a/git/repo/base.py b/git/repo/base.py index 27c640ff6..3e0e51cc0 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -732,7 +732,10 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): # sure repo = cls(os.path.abspath(path), odbt=odbt) if repo.remotes: - repo.remotes[0].config_writer.set_value('url', repo.remotes[0].url.replace("\\\\", "\\").replace("\\", "/")) + writer = repo.remotes[0].config_writer + writer.set_value('url', repo.remotes[0].url.replace("\\\\", "\\").replace("\\", "/")) + # PY3: be sure cleanup is performed and lock is released + del writer # END handle remote repo return repo diff --git a/git/test/test_index.py b/git/test/test_index.py index 38cc35639..d81d08ef4 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -48,7 +48,7 @@ def __init__(self, *args): def _assert_fprogress(self, entries): assert len(entries) == len(self._fprogress_map) - for path, call_count in self._fprogress_map.iteritems(): + for path, call_count in self._fprogress_map.items(): assert call_count == 2 # END for each item in progress map self._reset_progress() @@ -86,7 +86,7 @@ def test_index_file_base(self): assert index.version > 0 # test entry - entry = index.entries.itervalues().next() + entry = next(iter(index.entries.values())) for attr in ("path", "ctime", "mtime", "dev", "inode", "mode", "uid", "gid", "size", "binsha", "hexsha", "stage"): getattr(entry, attr) @@ -100,7 +100,7 @@ def test_index_file_base(self): # test stage index_merge = IndexFile(self.rorepo, fixture_path("index_merge")) assert len(index_merge.entries) == 106 - assert len(list(e for e in index_merge.entries.itervalues() if e.stage != 0)) + assert len(list(e for e in index_merge.entries.values() if e.stage != 0)) # write the data - it must match the original tmpfile = tempfile.mktemp() @@ -167,7 +167,7 @@ def test_index_file_from_tree(self, rw_repo): assert unmerged_blob_map # pick the first blob at the first stage we find and use it as resolved version - three_way_index.resolve_blobs(l[0][1] for l in unmerged_blob_map.itervalues()) + three_way_index.resolve_blobs(l[0][1] for l in unmerged_blob_map.values()) tree = three_way_index.write_tree() assert isinstance(tree, Tree) num_blobs = 0 @@ -201,7 +201,7 @@ def test_index_merge_tree(self, rw_repo): # Add a change with a NULL sha that should conflict with next_commit. We # pretend there was a change, but we do not even bother adding a proper # sha for it ( which makes things faster of course ) - manifest_fake_entry = BaseIndexEntry((manifest_entry[0], "\0" * 20, 0, manifest_entry[3])) + manifest_fake_entry = BaseIndexEntry((manifest_entry[0], b"\0" * 20, 0, manifest_entry[3])) # try write flag self._assert_entries(rw_repo.index.add([manifest_fake_entry], write=False)) # add actually resolves the null-hex-sha for us as a feature, but we can @@ -236,7 +236,7 @@ def test_index_merge_tree(self, rw_repo): # now make a proper three way merge with unmerged entries unmerged_tree = IndexFile.from_tree(rw_repo, parent_commit, tree, next_commit) unmerged_blobs = unmerged_tree.unmerged_blobs() - assert len(unmerged_blobs) == 1 and unmerged_blobs.keys()[0] == manifest_key[0] + assert len(unmerged_blobs) == 1 and list(unmerged_blobs.keys())[0] == manifest_key[0] @with_rw_repo('0.1.6') def test_index_file_diffing(self, rw_repo): @@ -295,7 +295,7 @@ def test_index_file_diffing(self, rw_repo): assert index.diff(None) # reset the working copy as well to current head,to pull 'back' as well - new_data = "will be reverted" + new_data = b"will be reverted" file_path = os.path.join(rw_repo.working_tree_dir, "CHANGES") fp = open(file_path, "wb") fp.write(new_data) @@ -312,7 +312,7 @@ def test_index_file_diffing(self, rw_repo): # test full checkout test_file = os.path.join(rw_repo.working_tree_dir, "CHANGES") - open(test_file, 'ab').write("some data") + open(test_file, 'ab').write(b"some data") rval = index.checkout(None, force=True, fprogress=self._fprogress) assert 'CHANGES' in list(rval) self._assert_fprogress([None]) @@ -336,7 +336,7 @@ def test_index_file_diffing(self, rw_repo): self.failUnlessRaises(CheckoutError, index.checkout, paths=["doesnt/exist"]) # checkout file with modifications - append_data = "hello" + append_data = b"hello" fp = open(test_file, "ab") fp.write(append_data) fp.close() @@ -346,13 +346,13 @@ def test_index_file_diffing(self, rw_repo): assert len(e.failed_files) == 1 and e.failed_files[0] == os.path.basename(test_file) assert (len(e.failed_files) == len(e.failed_reasons)) and isinstance(e.failed_reasons[0], string_types) assert len(e.valid_files) == 0 - assert open(test_file).read().endswith(append_data) + assert open(test_file, 'rb').read().endswith(append_data) else: raise AssertionError("Exception CheckoutError not thrown") # if we force it it should work index.checkout(test_file, force=True) - assert not open(test_file).read().endswith(append_data) + assert not open(test_file, 'rb').read().endswith(append_data) # checkout directory shutil.rmtree(os.path.join(rw_repo.working_tree_dir, "lib")) @@ -379,14 +379,15 @@ def test_index_mutation(self, rw_repo): uname = "Some Developer" umail = "sd@company.com" - rw_repo.config_writer().set_value("user", "name", uname) - rw_repo.config_writer().set_value("user", "email", umail) + writer = rw_repo.config_writer() + writer.set_value("user", "name", uname) + writer.set_value("user", "email", umail) # remove all of the files, provide a wild mix of paths, BaseIndexEntries, # IndexEntries def mixed_iterator(): count = 0 - for entry in index.entries.itervalues(): + for entry in index.entries.values(): type_id = count % 4 if type_id == 0: # path yield entry.path @@ -500,7 +501,7 @@ def mixed_iterator(): # mode 0 not allowed null_hex_sha = Diff.NULL_HEX_SHA - null_bin_sha = "\0" * 20 + null_bin_sha = b"\0" * 20 self.failUnlessRaises(ValueError, index.reset( new_commit).add, [BaseIndexEntry((0, null_bin_sha, 0, "doesntmatter"))]) @@ -526,7 +527,7 @@ def mixed_iterator(): assert S_ISLNK(index.entries[index.entry_key("my_real_symlink", 0)].mode) # we expect only the target to be written - assert index.repo.odb.stream(entries[0].binsha).read() == target + assert index.repo.odb.stream(entries[0].binsha).read().decode('ascii') == target # END real symlink test # add fake symlink and assure it checks-our as symlink @@ -618,7 +619,7 @@ def make_paths(): for fid in range(3): fname = 'newfile%i' % fid - open(fname, 'wb').write("abcd") + open(fname, 'wb').write(b"abcd") yield Blob(rw_repo, Blob.NULL_BIN_SHA, 0o100644, fname) # END for each new file # END path producer @@ -716,5 +717,5 @@ def test_index_bare_add(self, rw_bare_repo): try: rw_bare_repo.index.add([path]) except Exception as e: - asserted = "does not have a working tree" in e.message + asserted = "does not have a working tree" in str(e) assert asserted, "Adding using a filename is not correctly asserted." diff --git a/git/util.py b/git/util.py index b3a228835..4de736d3a 100644 --- a/git/util.py +++ b/git/util.py @@ -446,7 +446,7 @@ class IndexFileSHA1Writer(object): def __init__(self, f): self.f = f - self.sha1 = make_sha("") + self.sha1 = make_sha(b"") def write(self, data): self.sha1.update(data) @@ -490,10 +490,7 @@ def _lock_file_path(self): def _has_lock(self): """:return: True if we have a lock and if the lockfile still exists :raise AssertionError: if our lock-file does not exist""" - if not self._owns_lock: - return False - - return True + return self._owns_lock def _obtain_lock_or_raise(self): """Create a lock file as flag for other instances, mark our instance as lock-holder @@ -531,7 +528,7 @@ def _release_lock(self): # on bloody windows, the file needs write permissions to be removable. # Why ... if os.name == 'nt': - os.chmod(lfp, int("0777", 8)) + os.chmod(lfp, 0o777) # END handle win32 os.remove(lfp) except OSError: From b5a37564b6eec05b98c2efa5edcd1460a2df02aa Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 11:02:31 +0100 Subject: [PATCH 0033/2790] test_reflog works --- git/refs/log.py | 22 +++++++++++++--------- git/test/test_reflog.py | 5 +++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/git/refs/log.py b/git/refs/log.py index f397548e9..c3019d39e 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -19,7 +19,8 @@ ) from git.compat import ( xrange, - string_types + string_types, + defenc ) import time @@ -38,9 +39,8 @@ class RefLogEntry(tuple): def __repr__(self): """Representation of ourselves in git reflog format""" act = self.actor - name = act.name.encode('utf-8') time = self.time - return self._fmt % (self.oldhexsha, self.newhexsha, name, act.email, + return self._fmt % (self.oldhexsha, self.newhexsha, act.name, act.email, time[0], altz_to_utctz_str(time[1]), self.message) @property @@ -82,8 +82,9 @@ def new(self, oldhexsha, newhexsha, actor, time, tz_offset, message): @classmethod def from_line(cls, line): """:return: New RefLogEntry instance from the given revlog line. - :param line: line without trailing newline + :param line: line bytes without trailing newline :raise ValueError: If line could not be parsed""" + line = line.decode(defenc) try: info, msg = line.split('\t', 1) except ValueError: @@ -253,15 +254,18 @@ def append_entry(cls, config_reader, filepath, oldbinsha, newbinsha, message): # END handle sha type assure_directory_exists(filepath, is_file=True) committer = isinstance(config_reader, Actor) and config_reader or Actor.committer(config_reader) - entry = RefLogEntry( - (bin_to_hex(oldbinsha), bin_to_hex(newbinsha), committer, (int(time.time()), time.altzone), message)) + entry = RefLogEntry(( + bin_to_hex(oldbinsha).decode('ascii'), + bin_to_hex(newbinsha).decode('ascii'), + committer, (int(time.time()), time.altzone), message + )) lf = LockFile(filepath) lf._obtain_lock_or_raise() - fd = open(filepath, 'a') + fd = open(filepath, 'ab') try: - fd.write(repr(entry)) + fd.write(repr(entry).encode(defenc)) finally: fd.close() lf._release_lock() @@ -286,7 +290,7 @@ def _serialize(self, stream): # write all entries for e in self: - write(repr(e)) + write(repr(e).encode(defenc)) # END for each entry def _deserialize(self, stream): diff --git a/git/test/test_reflog.py b/git/test/test_reflog.py index 4efb8025b..3571e0839 100644 --- a/git/test/test_reflog.py +++ b/git/test/test_reflog.py @@ -8,6 +8,7 @@ RefLog ) from git.util import Actor +from gitdb.util import hex_to_bin import tempfile import shutil @@ -51,7 +52,7 @@ def test_base(self): assert len(reflog) # iter_entries works with path and with stream - assert len(list(RefLog.iter_entries(open(rlp_master)))) + assert len(list(RefLog.iter_entries(open(rlp_master, 'rb')))) assert len(list(RefLog.iter_entries(rlp_master))) # raise on invalid revlog @@ -65,7 +66,7 @@ def test_base(self): self.failUnlessRaises(ValueError, RefLog().write) # test serialize and deserialize - results must match exactly - binsha = chr(255) * 20 + binsha = hex_to_bin(('f' * 40).encode('ascii')) msg = "my reflog message" cr = self.rorepo.config_reader() for rlp in (rlp_head, rlp_master): From a83eee5bcee64eeb000dd413ab55aa98dcc8c7f2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 11:14:19 +0100 Subject: [PATCH 0034/2790] test_refs works --- git/objects/tag.py | 6 ++++-- git/refs/symbolic.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/git/objects/tag.py b/git/objects/tag.py index 5e76e230d..c86844478 100644 --- a/git/objects/tag.py +++ b/git/objects/tag.py @@ -10,6 +10,7 @@ parse_actor_and_date ) from gitdb.util import hex_to_bin +from git.compat import defenc __all__ = ("TagObject", ) @@ -52,11 +53,12 @@ def _set_cache_(self, attr): """Cache all our attributes at once""" if attr in TagObject.__slots__: ostream = self.repo.odb.stream(self.binsha) - lines = ostream.read().splitlines() + lines = ostream.read().decode(defenc).splitlines() obj, hexsha = lines[0].split(" ") # object type_token, type_name = lines[1].split(" ") # type - self.object = get_object_type_by_name(type_name)(self.repo, hex_to_bin(hexsha)) + self.object = \ + get_object_type_by_name(type_name.encode('ascii'))(self.repo, hex_to_bin(hexsha)) self.tag = lines[2][4:] # tag diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 252462a92..45a123855 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -21,6 +21,7 @@ ) from git.compat import ( string_types, + defenc ) from .log import RefLog @@ -429,6 +430,7 @@ def delete(cls, repo, path): # in the line # If we deleted the last line and this one is a tag-reference object, # we drop it as well + line = line.decode(defenc) if (line.startswith('#') or full_ref_path not in line) and \ (not dropped_last_line or dropped_last_line and not line.startswith('^')): new_lines.append(line) @@ -446,7 +448,7 @@ def delete(cls, repo, path): if made_change: # write-binary is required, otherwise windows will # open the file in text mode and change LF to CRLF ! - open(pack_file_path, 'wb').writelines(new_lines) + open(pack_file_path, 'wb').writelines(l.encode(defenc) for l in new_lines) # END write out file # END open exception handling # END handle deletion @@ -478,7 +480,7 @@ def _create(cls, repo, path, resolve, reference, force, logmsg=None): target_data = target.path if not resolve: target_data = "ref: " + target_data - existing_data = open(abs_ref_path, 'rb').read().strip() + existing_data = open(abs_ref_path, 'rb').read().decode(defenc).strip() if existing_data != target_data: raise OSError("Reference at %r does already exist, pointing to %r, requested was %r" % (full_ref_path, existing_data, target_data)) From 60e54133aa1105a1270f0a42e74813f75cd2dc46 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 12:22:16 +0100 Subject: [PATCH 0035/2790] test_remote works And I have to wonder why git-daemon serves under py2.7, but really wants receive-pack to be allowed under 3.4. Maybe it's a repository override which for some reason doesn't work in py3.4 ? Maybe because the change is not flushed ? --- git/cmd.py | 2 +- git/exc.py | 10 ++++++---- git/remote.py | 10 ++++++---- git/repo/fun.py | 2 +- git/test/lib/helper.py | 11 +++++++---- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 2bff33109..aac7ffb73 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -120,7 +120,7 @@ def wait(self): :raise GitCommandError: if the return status is not 0""" status = self.proc.wait() if status != 0: - raise GitCommandError(self.args, status, self.proc.stderr.read()) + raise GitCommandError(self.args, status, self.proc.stderr.read().decode(defenc)) # END status handling return status # END auto interrupt diff --git a/git/exc.py b/git/exc.py index ba57c624e..67fb9894d 100644 --- a/git/exc.py +++ b/git/exc.py @@ -29,10 +29,12 @@ def __init__(self, command, status, stderr=None, stdout=None): self.command = command def __str__(self): - ret = "'%s' returned exit status %i: %s" % \ - (' '.join(str(i) for i in self.command), self.status, self.stderr) - if self.stdout is not None: - ret += "\nstdout: %s" % self.stdout + ret = "'%s' returned with exit code %i" % \ + (' '.join(str(i) for i in self.command), self.status) + if self.stderr: + ret += "\nstderr: '%s'" % self.stderr + if self.stdout: + ret += "\nstdout: '%s'" % self.stdout return ret diff --git a/git/remote.py b/git/remote.py index 63f21c4e3..484bc0310 100644 --- a/git/remote.py +++ b/git/remote.py @@ -138,7 +138,7 @@ def remote_ref(self): @classmethod def _from_line(cls, remote, line): """Create a new PushInfo instance as parsed from line which is expected to be like - refs/heads/master:refs/heads/master 05d2687..1d0568e""" + refs/heads/master:refs/heads/master 05d2687..1d0568e as bytes""" control_character, from_to, summary = line.split('\t', 3) flags = 0 @@ -522,6 +522,7 @@ def update(self, **kwargs): def _get_fetch_info_from_stderr(self, proc, progress): # skip first line as it is some remote info we are not interested in + # TODO: Use poll() to process stdout and stderr at same time output = IterableList('name') # lines which are no progress are fetch info lines @@ -544,8 +545,8 @@ def _get_fetch_info_from_stderr(self, proc, progress): # END for each line # read head information - fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'r') - fetch_head_info = fp.readlines() + fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') + fetch_head_info = [l.decode(defenc) for l in fp.readlines()] fp.close() # NOTE: We assume to fetch at least enough progress lines to allow matching each fetch head line with it. @@ -562,10 +563,12 @@ def _get_push_info(self, proc, progress): # we hope stdout can hold all the data, it should ... # read the lines manually as it will use carriage returns between the messages # to override the previous one. This is why we read the bytes manually + # TODO: poll() on file descriptors to know what to read next, process streams concurrently digest_process_messages(proc.stderr, progress) output = IterableList('name') for line in proc.stdout.readlines(): + line = line.decode(defenc) try: output.append(PushInfo._from_line(self, line)) except ValueError: @@ -573,7 +576,6 @@ def _get_push_info(self, proc, progress): pass # END exception handling # END for each line - finalize_process(proc) return output diff --git a/git/repo/fun.py b/git/repo/fun.py index 64b9b4a9b..ac0fa6f15 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -21,7 +21,7 @@ def touch(filename): - fp = open(filename, "a") + fp = open(filename, "ab") fp.close() diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index bc9c351ab..eea594e73 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -193,7 +193,7 @@ def remote_repo_creator(self): temp_dir = os.path.dirname(_mktemp()) # On windows, this will fail ... we deal with failures anyway and default to telling the user to do it try: - gd = Git().daemon(temp_dir, as_process=True) + gd = Git().daemon(temp_dir, enable='receive-pack', as_process=True) # yes, I know ... fortunately, this is always going to work if sleep time is just large enough time.sleep(0.5) except Exception: @@ -215,7 +215,8 @@ def remote_repo_creator(self): msg += 'Otherwise, run: git-daemon "%s"' % temp_dir raise AssertionError(msg) else: - msg = 'Please start a git-daemon to run this test, execute: git-daemon "%s"' % temp_dir + msg = 'Please start a git-daemon to run this test, execute: git daemon --enable=receive-pack "%s"' + msg %= temp_dir raise AssertionError(msg) # END make assertion # END catch ls remote error @@ -227,7 +228,8 @@ def remote_repo_creator(self): return func(self, rw_repo, rw_remote_repo) finally: # gd.proc.kill() ... no idea why that doesn't work - os.kill(gd.proc.pid, 15) + if gd is not None: + os.kill(gd.proc.pid, 15) os.chdir(prev_cwd) rw_repo.git.clear_cache() @@ -235,7 +237,8 @@ def remote_repo_creator(self): shutil.rmtree(repo_dir, onerror=_rmtree_onerror) shutil.rmtree(remote_repo_dir, onerror=_rmtree_onerror) - gd.proc.wait() + if gd is not None: + gd.proc.wait() # END cleanup # END bare repo creator remote_repo_creator.__name__ = func.__name__ From a05e49d2419d65c59c65adf5cd8c05f276550e1d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 14:05:30 +0100 Subject: [PATCH 0036/2790] test_repo works --- doc/source/changes.rst | 1 + git/cmd.py | 17 +++++++++------- git/config.py | 14 +++++++++++-- git/exc.py | 6 ++++-- git/objects/submodule/base.py | 31 ++++++++++++++++++++-------- git/refs/head.py | 1 + git/repo/base.py | 5 +++-- git/repo/fun.py | 2 +- git/test/lib/helper.py | 1 + git/test/test_index.py | 1 + git/test/test_refs.py | 6 ++++-- git/test/test_repo.py | 28 +++++++++++++++++--------- git/test/test_submodule.py | 38 +++++++++++++++++++++++++---------- 13 files changed, 106 insertions(+), 45 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 06a73f41d..3b62ddc84 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -6,6 +6,7 @@ Changelog ======================== * Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes. * Id attribute of Commit objects is now `hexsha`, instead of `binsha`. The latter makes no sense in python 3 and I see no application of it anyway besides its artificial usage in test cases. +* **IMPORTANT**: If you were using the config_writer(), you implicitly relied on __del__ to work as expected to flush changes. To be sure changes are flushed under PY3, you will have to call the new `release()` method to trigger a flush. For some reason, __del__ is not called necessarily anymore when a symbol goes out of scope. 0.3.3 ===== diff --git a/git/cmd.py b/git/cmd.py index aac7ffb73..9b85b14a1 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -22,7 +22,8 @@ from git.compat import ( text_type, string_types, - defenc + defenc, + PY3 ) execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', @@ -372,8 +373,8 @@ def execute(self, command, # Wait for the process to return status = 0 - stdout_value = '' - stderr_value = '' + stdout_value = b'' + stderr_value = b'' try: if output_stream is None: stdout_value, stderr_value = proc.communicate() @@ -388,7 +389,7 @@ def execute(self, command, stdout_value = output_stream stderr_value = proc.stderr.read() # strip trailing "\n" - if stderr_value.endswith("\n"): + if stderr_value.endswith(b"\n"): stderr_value = stderr_value[:-1] status = proc.wait() # END stdout handling @@ -444,7 +445,9 @@ def transform_kwargs(self, split_single_char_options=False, **kwargs): @classmethod def __unpack_args(cls, arg_list): if not isinstance(arg_list, (list, tuple)): - if isinstance(arg_list, text_type): + # This is just required for unicode conversion, as subprocess can't handle it + # However, in any other case, passing strings (usually utf-8 encoded) is totally fine + if not PY3 and isinstance(arg_list, unicode): return [arg_list.encode(defenc)] return [str(arg_list)] @@ -452,7 +455,7 @@ def __unpack_args(cls, arg_list): for arg in arg_list: if isinstance(arg_list, (list, tuple)): outlist.extend(cls.__unpack_args(arg)) - elif isinstance(arg_list, text_type): + elif not PY3 and isinstance(arg_list, unicode): outlist.append(arg_list.encode(defenc)) # END recursion else: @@ -509,8 +512,8 @@ def _call_process(self, method, *args, **kwargs): # Prepare the argument list opt_args = self.transform_kwargs(**kwargs) - ext_args = self.__unpack_args([a for a in args if a is not None]) + args = opt_args + ext_args def make_call(): diff --git a/git/config.py b/git/config.py index 96991b841..c7e8b7ac9 100644 --- a/git/config.py +++ b/git/config.py @@ -103,8 +103,7 @@ def __del__(self): # Yes, for some reason, we have to call it explicitly for it to work in PY3 ! # Apparently __del__ doesn't get call anymore if refcount becomes 0 # Ridiculous ... . - self._config.__del__() - # del self._config + self._config.release() def __getattr__(self, attr): if attr in self._valid_attrs_: @@ -121,6 +120,10 @@ def config(self): """return: Configparser instance we constrain""" return self._config + def release(self): + """Equivalent to GitConfigParser.release(), which is called on our underlying parser instance""" + return self._config.release() + class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, object)): @@ -198,6 +201,13 @@ def __init__(self, file_or_files, read_only=True): def __del__(self): """Write pending changes if required and release locks""" + # NOTE: only consistent in PY2 + self.release() + + def release(self): + """Flush changes and release the configuration write lock. This instance must not be used anymore afterwards. + In Python 3, it's required to explicitly release locks and flush changes, as __del__ is not called + deterministically anymore.""" # checking for the lock here makes sure we do not raise during write() # in case an invalid parser was created who could not get a lock if self.read_only or (self._lock and not self._lock._has_lock()): diff --git a/git/exc.py b/git/exc.py index 67fb9894d..42191c62d 100644 --- a/git/exc.py +++ b/git/exc.py @@ -7,6 +7,8 @@ from gitdb.exc import * # NOQA +from git.compat import defenc + class InvalidGitRepositoryError(Exception): @@ -32,9 +34,9 @@ def __str__(self): ret = "'%s' returned with exit code %i" % \ (' '.join(str(i) for i in self.command), self.status) if self.stderr: - ret += "\nstderr: '%s'" % self.stderr + ret += "\nstderr: '%s'" % self.stderr.decode(defenc) if self.stdout: - ret += "\nstdout: '%s'" % self.stdout + ret += "\nstdout: '%s'" % self.stdout.decode(defenc) return ret diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 0fb3f35fc..0ec6f6567 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -17,7 +17,10 @@ rmtree ) -from git.config import SectionConstraint +from git.config import ( + SectionConstraint, + cp +) from git.exc import ( InvalidGitRepositoryError, NoSuchPathError @@ -302,6 +305,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): writer.set_value(cls.k_head_option, br.path) sm._branch_path = br.path # END handle path + writer.release() del(writer) # we deliberatly assume that our head matches our index ! @@ -419,7 +423,9 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= # the default implementation will be offended and not update the repository # Maybe this is a good way to assure it doesn't get into our way, but # we want to stay backwards compatible too ... . Its so redundant ! - self.repo.config_writer().set_value(sm_section(self.name), 'url', self.url) + writer = self.repo.config_writer() + writer.set_value(sm_section(self.name), 'url', self.url) + writer.release() # END handle dry_run # END handle initalization @@ -576,6 +582,7 @@ def move(self, module_path, configuration=True, module=True): writer = self.config_writer(index=index) # auto-write writer.set_value('path', module_path) self.path = module_path + writer.release() del(writer) # END handle configuration flag except Exception: @@ -700,8 +707,12 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): # now git config - need the config intact, otherwise we can't query # inforamtion anymore - self.repo.config_writer().remove_section(sm_section(self.name)) - self.config_writer().remove_section() + writer = self.repo.config_writer() + writer.remove_section(sm_section(self.name)) + writer.release() + writer = self.config_writer() + writer.remove_section() + writer.release() # END delete configuration # void our data not to delay invalid access @@ -800,14 +811,18 @@ def exists(self): """ :return: True if the submodule exists, False otherwise. Please note that a submodule may exist (in the .gitmodules file) even though its module - doesn't exist""" + doesn't exist on disk""" # keep attributes for later, and restore them if we have no valid data # this way we do not actually alter the state of the object loc = locals() for attr in self._cache_attrs: - if hasattr(self, attr): - loc[attr] = getattr(self, attr) - # END if we have the attribute cache + try: + if hasattr(self, attr): + loc[attr] = getattr(self, attr) + # END if we have the attribute cache + except cp.NoSectionError: + # on PY3, this can happen apparently ... don't know why this doesn't happen on PY2 + pass # END for each attr self._clear_cache() diff --git a/git/refs/head.py b/git/refs/head.py index 0a14158c8..750d15b6b 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -148,6 +148,7 @@ def set_tracking_branch(self, remote_reference): writer.set_value(self.k_config_remote, remote_reference.remote_name) writer.set_value(self.k_config_remote_ref, Head.to_full_path(remote_reference.remote_head)) # END handle ref value + writer.release() return self diff --git a/git/repo/base.py b/git/repo/base.py index 3e0e51cc0..2a63492bf 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -551,6 +551,7 @@ def untracked_files(self): prefix = "?? " untracked_files = list() for line in proc.stdout: + line = line.decode(defenc) if not line.startswith(prefix): continue filename = line[len(prefix):].rstrip('\n') @@ -735,7 +736,7 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): writer = repo.remotes[0].config_writer writer.set_value('url', repo.remotes[0].url.replace("\\\\", "\\").replace("\\", "/")) # PY3: be sure cleanup is performed and lock is released - del writer + writer.release() # END handle remote repo return repo @@ -767,7 +768,7 @@ def clone_from(cls, url, to_path, progress=None, **kwargs): def archive(self, ostream, treeish=None, prefix=None, **kwargs): """Archive the tree at the given revision. - :parm ostream: file compatible stream object to which the archive will be written + :parm ostream: file compatible stream object to which the archive will be written as bytes :parm treeish: is the treeish name/id, defaults to active branch :parm prefix: is the optional prefix to prepend to each filename in the archive :parm kwargs: diff --git a/git/repo/fun.py b/git/repo/fun.py index ac0fa6f15..233666c93 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -150,7 +150,7 @@ def to_commit(obj): def rev_parse(repo, rev): """ :return: Object at the given revision, either Commit, Tag, Tree or Blob - :param rev: git-rev-parse compatible revision specification, please see + :param rev: git-rev-parse compatible revision specification as string, please see http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html for details :note: Currently there is no access to the rev-log, rev-specs may only contain diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index eea594e73..bd6795128 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -179,6 +179,7 @@ def remote_repo_creator(self): pass crw.set(section, "receivepack", True) # release lock + crw.release() del(crw) # initialize the remote - first do it as local remote and pull, then diff --git a/git/test/test_index.py b/git/test/test_index.py index d81d08ef4..f7504b322 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -382,6 +382,7 @@ def test_index_mutation(self, rw_repo): writer = rw_repo.config_writer() writer.set_value("user", "name", uname) writer.set_value("user", "email", umail) + writer.release() # remove all of the files, provide a wild mix of paths, BaseIndexEntries, # IndexEntries diff --git a/git/test/test_refs.py b/git/test/test_refs.py index af33765ae..14b91cfeb 100644 --- a/git/test/test_refs.py +++ b/git/test/test_refs.py @@ -105,9 +105,11 @@ def test_heads(self, rwrepo): tv = "testopt" writer.set_value(tv, 1) assert writer.get_value(tv) == 1 - del(writer) + writer.release() assert head.config_reader().get_value(tv) == 1 - head.config_writer().remove_option(tv) + writer = head.config_writer() + writer.remove_option(tv) + writer.release() # after the clone, we might still have a tracking branch setup head.set_tracking_branch(None) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index ae824086b..f216039ed 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -30,7 +30,10 @@ from git.util import join_path_native from git.exc import BadObject from gitdb.util import bin_to_hex -from git.compat import string_types +from git.compat import ( + string_types, + defenc +) import os import sys @@ -259,13 +262,16 @@ def test_tag(self): assert self.rorepo.tag('refs/tags/0.1.5').commit def test_archive(self): - tmpfile = os.tmpfile() - self.rorepo.archive(tmpfile, '0.1.5') - assert tmpfile.tell() + tmpfile = tempfile.mktemp(suffix='archive-test') + stream = open(tmpfile, 'wb') + self.rorepo.archive(stream, '0.1.5') + assert stream.tell() + stream.close() + os.remove(tmpfile) @patch.object(Git, '_call_process') def test_should_display_blame_information(self, git): - git.return_value = fixture('blame') + git.return_value = fixture('blame').decode(defenc) b = self.rorepo.blame('master', 'lib/git.py') assert_equal(13, len(b)) assert_equal(2, len(b[0])) @@ -336,6 +342,7 @@ def test_config_writer(self): try: writer = self.rorepo.config_writer(config_level) assert not writer.read_only + writer.release() except IOError: # its okay not to get a writer for some configuration files if we # have no permissions @@ -350,7 +357,8 @@ def test_creation_deletion(self): tag = self.rorepo.create_tag("new_tag", "HEAD~2") self.rorepo.delete_tag(tag) - self.rorepo.config_writer() + writer = self.rorepo.config_writer() + writer.release() remote = self.rorepo.create_remote("new_remote", "git@server:repo.git") self.rorepo.delete_remote(remote) @@ -365,7 +373,7 @@ def test_git_cmd(self): l1 = b"0123456789\n" l2 = b"abcdefghijklmnopqrstxy\n" l3 = b"z\n" - d = b"%s%s%s\n" % (l1, l2, l3) + d = l1 + l2 + l3 + b"\n" l1p = l1[:5] @@ -382,7 +390,7 @@ def mktiny(): # readlines no limit s = mkfull() lines = s.readlines() - assert len(lines) == 3 and lines[-1].endswith('\n') + assert len(lines) == 3 and lines[-1].endswith(b'\n') assert s._stream.tell() == len(d) # must have scrubbed to the end # realines line limit @@ -566,7 +574,7 @@ def test_rev_parse(self): # try partial parsing max_items = 40 for i, binsha in enumerate(self.rorepo.odb.sha_iter()): - assert rev_parse(bin_to_hex(binsha)[:8 - (i % 2)]).binsha == binsha + assert rev_parse(bin_to_hex(binsha)[:8 - (i % 2)].decode('ascii')).binsha == binsha if i > max_items: # this is rather slow currently, as rev_parse returns an object # which requires accessing packs, it has some additional overhead @@ -645,6 +653,6 @@ def test_git_file(self, rwrepo): assert os.path.abspath(git_file_repo.git_dir) == real_path_abs # Test using an absolute gitdir path in the .git file. - open(git_file_path, 'wb').write('gitdir: %s\n' % real_path_abs) + open(git_file_path, 'wb').write(('gitdir: %s\n' % real_path_abs).encode('ascii')) git_file_repo = Repo(rwrepo.working_tree_dir) assert os.path.abspath(git_file_repo.git_dir) == real_path_abs diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 8c1580fe1..499d6bacf 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -99,7 +99,7 @@ def _do_base_tests(self, rwrepo): # for faster checkout, set the url to the local path new_smclone_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path)) writer.set_value('url', new_smclone_path) - del(writer) + writer.release() assert sm.config_reader().get_value('url') == new_smclone_path assert sm.url == new_smclone_path # END handle bare repo @@ -196,7 +196,9 @@ def _do_base_tests(self, rwrepo): # adjust the path of the submodules module to point to the local destination new_csmclone_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path, csm.path)) - csm.config_writer().set_value('url', new_csmclone_path) + writer = csm.config_writer() + writer.set_value('url', new_csmclone_path) + writer.release() assert csm.url == new_csmclone_path # dry-run does nothing @@ -257,8 +259,12 @@ def _do_base_tests(self, rwrepo): # NOTE: As we did a few updates in the meanwhile, the indices were reset # Hence we create some changes csm.set_parent_commit(csm.repo.head.commit) - sm.config_writer().set_value("somekey", "somevalue") - csm.config_writer().set_value("okey", "ovalue") + writer = sm.config_writer() + writer.set_value("somekey", "somevalue") + writer.release() + writer = csm.config_writer() + writer.set_value("okey", "ovalue") + writer.release() self.failUnlessRaises(InvalidGitRepositoryError, sm.remove) # if we remove the dirty index, it would work sm.module().index.reset() @@ -406,7 +412,8 @@ def test_root_module(self, rwrepo): assert len(rm.list_items(rm.module())) == 1 rm.config_reader() - rm.config_writer() + w = rm.config_writer() + w.release() # deep traversal gitdb / async rsmsp = [sm.path for sm in rm.traverse()] @@ -431,8 +438,9 @@ def test_root_module(self, rwrepo): assert not sm.module_exists() # was never updated after rwrepo's clone # assure we clone from a local source - sm.config_writer().set_value( - 'url', to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path))) + writer = sm.config_writer() + writer.set_value('url', to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path))) + writer.release() # dry-run does nothing sm.update(recursive=False, dry_run=True, progress=prog) @@ -440,7 +448,9 @@ def test_root_module(self, rwrepo): sm.update(recursive=False) assert sm.module_exists() - sm.config_writer().set_value('path', fp) # change path to something with prefix AFTER url change + writer = sm.config_writer() + writer.set_value('path', fp) # change path to something with prefix AFTER url change + writer.release() # update fails as list_items in such a situations cannot work, as it cannot # find the entry at the changed path @@ -504,7 +514,9 @@ def test_root_module(self, rwrepo): # repository at the different url nsm.set_parent_commit(csmremoved) nsmurl = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, rsmsp[0])) - nsm.config_writer().set_value('url', nsmurl) + writer = nsm.config_writer() + writer.set_value('url', nsmurl) + writer.release() csmpathchange = rwrepo.index.commit("changed url") nsm.set_parent_commit(csmpathchange) @@ -532,7 +544,9 @@ def test_root_module(self, rwrepo): nsmm = nsm.module() prev_commit = nsmm.head.commit for branch in ("some_virtual_branch", cur_branch.name): - nsm.config_writer().set_value(Submodule.k_head_option, git.Head.to_full_path(branch)) + writer = nsm.config_writer() + writer.set_value(Submodule.k_head_option, git.Head.to_full_path(branch)) + writer.release() csmbranchchange = rwrepo.index.commit("changed branch to %s" % branch) nsm.set_parent_commit(csmbranchchange) # END for each branch to change @@ -560,7 +574,9 @@ def test_root_module(self, rwrepo): assert nsm.exists() and nsm.module_exists() and len(nsm.children()) >= 1 # assure we pull locally only nsmc = nsm.children()[0] - nsmc.config_writer().set_value('url', async_url) + writer = nsmc.config_writer() + writer.set_value('url', async_url) + writer.release() rm.update(recursive=True, progress=prog, dry_run=True) # just to run the code rm.update(recursive=True, progress=prog) From 8f219b53f339fc0133800fac96deaf75eb4f9bf6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 14:09:17 +0100 Subject: [PATCH 0037/2790] test_stat works --- git/test/test_stats.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git/test/test_stats.py b/git/test/test_stats.py index c4535b751..eb8b9ddae 100644 --- a/git/test/test_stats.py +++ b/git/test/test_stats.py @@ -10,12 +10,12 @@ assert_equal ) from git import Stats - +from git.compat import defenc class TestStats(TestBase): def test_list_from_string(self): - output = fixture('diff_numstat') + output = fixture('diff_numstat').decode(defenc) stats = Stats._list_from_string(self.rorepo, output) assert_equal(2, stats.total['files']) From 4cfc682ff87d3629b31e0196004d1954810b206c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 14:11:48 +0100 Subject: [PATCH 0038/2790] test_submodule works --- git/objects/base.py | 2 +- git/test/test_base.py | 2 +- git/test/test_submodule.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/git/objects/base.py b/git/objects/base.py index 004e3981e..3f595d9dc 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -60,7 +60,7 @@ def new_from_sha(cls, repo, sha1): :param sha1: 20 byte binary sha1""" if sha1 == cls.NULL_BIN_SHA: # the NULL binsha is always the root commit - return get_object_type_by_name('commit')(repo, sha1) + return get_object_type_by_name(b'commit')(repo, sha1) # END handle special case oinfo = repo.odb.info(sha1) inst = get_object_type_by_name(oinfo.type)(repo, oinfo.binsha) diff --git a/git/test/test_base.py b/git/test/test_base.py index edacbd809..9ae2dd2bc 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -86,7 +86,7 @@ def test_get_object_type_by_name(self): assert base.Object in get_object_type_by_name(tname).mro() # END for each known type - assert_raises(ValueError, get_object_type_by_name, "doesntexist") + assert_raises(ValueError, get_object_type_by_name, b"doesntexist") def test_object_resolution(self): # objects must be resolved to shas so they compare equal diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 499d6bacf..99996ce33 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -80,7 +80,7 @@ def _do_base_tests(self, rwrepo): assert isinstance(sm.branch_path, string_types) # some commits earlier we still have a submodule, but its at a different commit - smold = Submodule.iter_items(rwrepo, self.k_subm_changed).next() + smold = next(Submodule.iter_items(rwrepo, self.k_subm_changed)) assert smold.binsha != sm.binsha assert smold != sm # the name changed From 95bb489a50f6c254f49ba4562d423dbf2201554f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 14:20:58 +0100 Subject: [PATCH 0039/2790] test_tree works --- doc/source/changes.rst | 1 + git/objects/tree.py | 12 ++++++++++-- git/test/test_tree.py | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 3b62ddc84..bb301f87c 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -7,6 +7,7 @@ Changelog * Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes. * Id attribute of Commit objects is now `hexsha`, instead of `binsha`. The latter makes no sense in python 3 and I see no application of it anyway besides its artificial usage in test cases. * **IMPORTANT**: If you were using the config_writer(), you implicitly relied on __del__ to work as expected to flush changes. To be sure changes are flushed under PY3, you will have to call the new `release()` method to trigger a flush. For some reason, __del__ is not called necessarily anymore when a symbol goes out of scope. +* The `Tree` now has a `.join('name')` method which is equivalent to `tree / 'name'` 0.3.3 ===== diff --git a/git/objects/tree.py b/git/objects/tree.py index 6776a15e7..f9bee01ea 100644 --- a/git/objects/tree.py +++ b/git/objects/tree.py @@ -159,7 +159,7 @@ def _iter_convert_to_object(self, iterable): raise TypeError("Unknown mode %o found in tree data for path '%s'" % (mode, path)) # END for each item - def __div__(self, file): + def join(self, file): """Find the named object in this tree's contents :return: ``git.Blob`` or ``git.Tree`` or ``git.Submodule`` @@ -192,6 +192,14 @@ def __div__(self, file): raise KeyError(msg % file) # END handle long paths + def __div__(self, file): + """For PY2 only""" + return self.join(file) + + def __truediv__(self, file): + """For PY3 only""" + return self.join(file) + @property def trees(self): """:return: list(Tree, ...) list of trees directly below this tree""" @@ -235,7 +243,7 @@ def __getitem__(self, item): if isinstance(item, string_types): # compatability - return self.__div__(item) + return self.join(item) # END index is basestring raise TypeError("Invalid index type: %r" % item) diff --git a/git/test/test_tree.py b/git/test/test_tree.py index 72bda4855..246584ee7 100644 --- a/git/test/test_tree.py +++ b/git/test/test_tree.py @@ -138,6 +138,7 @@ def test_traverse(self): # END check for slash # slashes in paths are supported as well + # NOTE: on py3, / doesn't work with strings anymore ... assert root[item.path] == item == root / item.path # END for each item assert found_slash From 725bde98d5cf680a087b6cb47a11dc469cfe956c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 14:28:32 +0100 Subject: [PATCH 0040/2790] test_base works --- git/test/test_base.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/git/test/test_base.py b/git/test/test_base.py index 9ae2dd2bc..301384ef1 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -4,10 +4,10 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php - -import git.objects.base as base import os +import tempfile +import git.objects.base as base from git.test.lib import ( TestBase, assert_raises, @@ -69,10 +69,13 @@ def test_base_object(self): data = data_stream.read() assert data - tmpfile = os.tmpfile() + tmpfilename = tempfile.mktemp(suffix='test-stream') + tmpfile = open(tmpfilename, 'wb+') assert item == item.stream_data(tmpfile) tmpfile.seek(0) assert tmpfile.read() == data + tmpfile.close() + os.remove(tmpfilename) # END stream to file directly # END for each object type to create @@ -113,7 +116,7 @@ def test_add_unicode(self, rw_repo): filename = u"שלום.txt" file_path = os.path.join(rw_repo.working_dir, filename) - open(file_path, "wb").write('something') + open(file_path, "wb").write(b'something') rw_repo.git.add(rw_repo.working_dir) rw_repo.index.commit('message') From 02e942b7c603163c87509195d76b2117c4997119 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 14:29:46 +0100 Subject: [PATCH 0041/2790] test_streams works However, there is a performance regression in test-odb --- git/test/performance/test_streams.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index ff664c100..aecb77284 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -80,7 +80,7 @@ def test_large_data_streaming(self, rwrepo): elapsed_readchunks = time() - st stream.seek(0) - assert ''.join(chunks) == stream.getvalue() + assert b''.join(chunks) == stream.getvalue() cs_kib = cs / 1000 print("Read %i KiB of %s data in %i KiB chunks from loose odb in %f s ( %f Read KiB / s)" From e0c65d6638698f4e3a9e726efca8c0bcf466cd62 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 15:38:20 +0100 Subject: [PATCH 0042/2790] Make flake8 happy --- git/cmd.py | 7 +++---- git/config.py | 4 ++-- git/objects/commit.py | 8 ++++---- git/objects/fun.py | 1 + git/refs/log.py | 2 +- git/refs/symbolic.py | 2 +- git/test/performance/test_commit.py | 1 - git/test/test_commit.py | 1 - git/test/test_config.py | 1 + git/test/test_stats.py | 1 + git/test/test_tree.py | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 9b85b14a1..7a670c46e 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -20,7 +20,6 @@ ) from .exc import GitCommandError from git.compat import ( - text_type, string_types, defenc, PY3 @@ -400,7 +399,8 @@ def execute(self, command, if self.GIT_PYTHON_TRACE == 'full': cmdstr = " ".join(command) if stderr_value: - log.info("%s -> %d; stdout: '%s'; stderr: '%s'", cmdstr, status, stdout_value.decode(defenc), stderr_value.decode(defenc)) + log.info("%s -> %d; stdout: '%s'; stderr: '%s'", + cmdstr, status, stdout_value.decode(defenc), stderr_value.decode(defenc)) elif stdout_value: log.info("%s -> %d; stdout: '%s'", cmdstr, status, stdout_value.decode(defenc)) else: @@ -413,8 +413,7 @@ def execute(self, command, else: raise GitCommandError(command, status, stderr_value) - - if isinstance(stdout_value, bytes): # could also be output_stream + if isinstance(stdout_value, bytes): # could also be output_stream stdout_value = stdout_value.decode(defenc) # Allow access to the command's status code diff --git a/git/config.py b/git/config.py index c7e8b7ac9..eefab2997 100644 --- a/git/config.py +++ b/git/config.py @@ -178,7 +178,7 @@ def __init__(self, file_or_files, read_only=True): # Used in python 3, needs to stay in sync with sections for underlying implementation to work if not hasattr(self, '_proxies'): self._proxies = self._dict() - + self._file_or_files = file_or_files self._read_only = read_only self._is_initialized = False @@ -206,7 +206,7 @@ def __del__(self): def release(self): """Flush changes and release the configuration write lock. This instance must not be used anymore afterwards. - In Python 3, it's required to explicitly release locks and flush changes, as __del__ is not called + In Python 3, it's required to explicitly release locks and flush changes, as __del__ is not called deterministically anymore.""" # checking for the lock here makes sure we do not raise during write() # in case an invalid parser was created who could not get a lock diff --git a/git/objects/commit.py b/git/objects/commit.py index 53af22cd4..8f93d1b90 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -382,14 +382,14 @@ def _serialize(self, stream): c = self.committer fmt = "%s %s <%s> %s %s\n" write((fmt % ("author", aname, a.email, - self.authored_date, - altz_to_utctz_str(self.author_tz_offset))).encode(self.encoding)) + self.authored_date, + altz_to_utctz_str(self.author_tz_offset))).encode(self.encoding)) # encode committer aname = c.name write((fmt % ("committer", aname, c.email, - self.committed_date, - altz_to_utctz_str(self.committer_tz_offset))).encode(self.encoding)) + self.committed_date, + altz_to_utctz_str(self.committer_tz_offset))).encode(self.encoding)) if self.encoding != self.default_encoding: write(("encoding %s\n" % self.encoding).encode('ascii')) diff --git a/git/objects/fun.py b/git/objects/fun.py index ba8dbcf46..c04f80b5d 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -40,6 +40,7 @@ def tree_to_stream(entries, write): write(b''.join((mode_str, b' ', name, b'\0', binsha))) # END for each item + def tree_entries_from_data(data): """Reads the binary representation of a tree and returns tuples of Tree items :param data: data block with tree data (as bytes) diff --git a/git/refs/log.py b/git/refs/log.py index c3019d39e..69189b515 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -256,7 +256,7 @@ def append_entry(cls, config_reader, filepath, oldbinsha, newbinsha, message): committer = isinstance(config_reader, Actor) and config_reader or Actor.committer(config_reader) entry = RefLogEntry(( bin_to_hex(oldbinsha).decode('ascii'), - bin_to_hex(newbinsha).decode('ascii'), + bin_to_hex(newbinsha).decode('ascii'), committer, (int(time.time()), time.altzone), message )) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 45a123855..cbb129d47 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -144,7 +144,7 @@ def _get_ref_info(cls, repo, ref_path): for sha, path in cls._iter_packed_refs(repo): if path != ref_path: continue - # sha will be used as + # sha will be used tokens = sha, path break # END for each packed ref diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index 9e8c1325f..7d3e87c4c 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -15,7 +15,6 @@ from git.test.test_commit import assert_commit_serialization - class TestPerformance(TestBigRepoRW): # ref with about 100 commits in its history diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 37a54092f..1f0f8c561 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -19,7 +19,6 @@ Actor, ) from gitdb import IStream -from gitdb.util import hex_to_bin from git.compat import ( string_types, text_type diff --git a/git/test/test_config.py b/git/test/test_config.py index f02754d51..546a2fe17 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -18,6 +18,7 @@ from copy import copy from git.config import cp + class TestBase(TestCase): def _to_memcache(self, file_path): diff --git a/git/test/test_stats.py b/git/test/test_stats.py index eb8b9ddae..884ab1abd 100644 --- a/git/test/test_stats.py +++ b/git/test/test_stats.py @@ -12,6 +12,7 @@ from git import Stats from git.compat import defenc + class TestStats(TestBase): def test_list_from_string(self): diff --git a/git/test/test_tree.py b/git/test/test_tree.py index 246584ee7..7a16b7776 100644 --- a/git/test/test_tree.py +++ b/git/test/test_tree.py @@ -138,7 +138,7 @@ def test_traverse(self): # END check for slash # slashes in paths are supported as well - # NOTE: on py3, / doesn't work with strings anymore ... + # NOTE: on py3, / doesn't work with strings anymore ... assert root[item.path] == item == root / item.path # END for each item assert found_slash From 1527b5734c0f2821fd6f38c1a1d70723a4bb88ab Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 15:40:35 +0100 Subject: [PATCH 0043/2790] fixed test_git --- git/test/test_git.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index 8087d6f8b..532e66594 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -34,11 +34,11 @@ def test_call_process_calls_execute(self, git): def test_call_unpack_args_unicode(self): args = Git._Git__unpack_args(u'Unicode€™') - assert_equal(args, [b'Unicode\xe2\x82\xac\xe2\x84\xa2']) + assert_equal(args, ['Unicode\u20ac\u2122']) def test_call_unpack_args(self): args = Git._Git__unpack_args(['git', 'log', '--', u'Unicode€™']) - assert_equal(args, [b'git', b'log', b'--', b'Unicode\xe2\x82\xac\xe2\x84\xa2']) + assert_equal(args, ['git', 'log', '--', 'Unicode\u20ac\u2122']) @raises(GitCommandError) def test_it_raises_errors(self): From c8cf69b6f8bd73525b5375bd73f1fc79ae322a82 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 16:06:23 +0100 Subject: [PATCH 0044/2790] Fixed test_git once again --- git/test/test_git.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index 532e66594..502e6091d 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -17,6 +17,8 @@ from git import (Git, GitCommandError) +from git.compat import PY3 + class TestGit(TestBase): @@ -34,11 +36,19 @@ def test_call_process_calls_execute(self, git): def test_call_unpack_args_unicode(self): args = Git._Git__unpack_args(u'Unicode€™') - assert_equal(args, ['Unicode\u20ac\u2122']) + if PY3: + mangled_value = 'Unicode\u20ac\u2122' + else: + mangled_value = 'Unicode\xe2\x82\xac\xe2\x84\xa2' + assert_equal(args, [mangled_value]) def test_call_unpack_args(self): args = Git._Git__unpack_args(['git', 'log', '--', u'Unicode€™']) - assert_equal(args, ['git', 'log', '--', 'Unicode\u20ac\u2122']) + if PY3: + mangled_value = 'Unicode\u20ac\u2122' + else: + mangled_value = 'Unicode\xe2\x82\xac\xe2\x84\xa2' + assert_equal(args, ['git', 'log', '--', mangled_value]) @raises(GitCommandError) def test_it_raises_errors(self): From 68f8a43d1b643318732f30ee1cd75e1d315a4537 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 16:09:47 +0100 Subject: [PATCH 0045/2790] Bumped version to 0.3.4 --- VERSION | 2 +- doc/source/changes.rst | 2 +- setup.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 1c09c74e2..42045acae 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.3 +0.3.4 diff --git a/doc/source/changes.rst b/doc/source/changes.rst index bb301f87c..b7479e4fe 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,7 +2,7 @@ Changelog ========= -0.3.4 - python 3 support +0.3.4 - Python 3 Support ======================== * Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes. * Id attribute of Commit objects is now `hexsha`, instead of `binsha`. The latter makes no sense in python 3 and I see no application of it anyway besides its artificial usage in test cases. diff --git a/setup.py b/setup.py index e1f770583..bdd4a4234 100755 --- a/setup.py +++ b/setup.py @@ -112,8 +112,8 @@ def _stamp_version(filename): "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", - # "Programming Language :: Python :: 3", - # "Programming Language :: Python :: 3.3", - # "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", ] ) From 5c12ff49fc91e66f30c5dc878f5d764d08479558 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 16:12:55 +0100 Subject: [PATCH 0046/2790] Adjusted travis to test for python 3 as well --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index c1b71110a..14af19091 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ language: python python: - "2.6" - "2.7" + - "3.3" + - "3.4" # - "pypy" - won't work as smmap doesn't work (see gitdb/.travis.yml for details) git: # a higher depth is needed for most of the tests - must be high enough to not actually be shallow From c824bcd73de8a7035f7e55ab3375ee0b6ab28c46 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 16:22:14 +0100 Subject: [PATCH 0047/2790] Fixed log implementation for py3 When merging, I accidentally removed the py3 adjustments --- git/refs/log.py | 1 + 1 file changed, 1 insertion(+) diff --git a/git/refs/log.py b/git/refs/log.py index 7708dd73d..8ce98d309 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -84,6 +84,7 @@ def from_line(cls, line): """:return: New RefLogEntry instance from the given revlog line. :param line: line bytes without trailing newline :raise ValueError: If line could not be parsed""" + line = line.decode(defenc) fields = line.split('\t', 1) if len(fields) == 1: info, msg = fields[0], None From 5d0ad081ca0e723ba2a12c876b4cd1574485c726 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 16:58:40 +0100 Subject: [PATCH 0048/2790] Improved windows test suite. Also added code to show how to deal with #147 --- git/test/test_base.py | 13 ++++++++++++- git/test/test_git.py | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/git/test/test_base.py b/git/test/test_base.py index 301384ef1..f581138b2 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -118,5 +118,16 @@ def test_add_unicode(self, rw_repo): file_path = os.path.join(rw_repo.working_dir, filename) open(file_path, "wb").write(b'something') - rw_repo.git.add(rw_repo.working_dir) + + if os.name == 'nt': + # on windows, there is no way this works, see images on + # https://github.com/gitpython-developers/GitPython/issues/147#issuecomment-68881897 + # Therefore, it must be added using the python implementation + rw_repo.index.add([file_path]) + # However, when the test winds down, rmtree fails to delete this file, which is recognized + # as ??? only. + else: + # on posix, we can just add unicode files without problems + rw_repo.git.add(rw_repo.working_dir) + # end rw_repo.index.commit('message') diff --git a/git/test/test_git.py b/git/test/test_git.py index 502e6091d..f25fa21a8 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -121,11 +121,16 @@ def test_version(self): def test_cmd_override(self): prev_cmd = self.git.GIT_PYTHON_GIT_EXECUTABLE + if os.name == 'nt': + exc = GitCommandError + else: + exc = OSError + # end handle windows case try: # set it to something that doens't exist, assure it raises type(self.git).GIT_PYTHON_GIT_EXECUTABLE = os.path.join( "some", "path", "which", "doesn't", "exist", "gitbinary") - self.failUnlessRaises(OSError, self.git.version) + self.failUnlessRaises(exc, self.git.version) finally: type(self.git).GIT_PYTHON_GIT_EXECUTABLE = prev_cmd # END undo adjustment From b18fd3fd13d0a1de0c3067292796e011f0f01a05 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 17:20:44 +0100 Subject: [PATCH 0049/2790] Bumped gitdb requirement. This should help getting the latest version --- git/test/test_base.py | 3 +-- requirements.txt | 2 +- setup.py | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/git/test/test_base.py b/git/test/test_base.py index f581138b2..91b9d0053 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -118,9 +118,8 @@ def test_add_unicode(self, rw_repo): file_path = os.path.join(rw_repo.working_dir, filename) open(file_path, "wb").write(b'something') - if os.name == 'nt': - # on windows, there is no way this works, see images on + # on windows, there is no way this works, see images on # https://github.com/gitpython-developers/GitPython/issues/147#issuecomment-68881897 # Therefore, it must be added using the python implementation rw_repo.index.add([file_path]) diff --git a/requirements.txt b/requirements.txt index eedd64662..19fd5a087 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ GitPython -gitdb>=0.6.1 +gitdb>=0.6.2 diff --git a/setup.py b/setup.py index bdd4a4234..0baf477bf 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ def _stamp_version(filename): else: print("WARNING: Couldn't find version line in file %s" % filename, file=sys.stderr) -install_requires = ['gitdb >= 0.6.1'] +install_requires = ['gitdb >= 0.6.2'] if sys.version_info[:2] < (2, 7): install_requires.append('ordereddict') # end @@ -85,7 +85,7 @@ def _stamp_version(filename): package_data={'git.test': ['fixtures/*']}, package_dir={'git': 'git'}, license="BSD License", - requires=['gitdb (>=0.6.1)'], + requires=['gitdb (>=0.6.2)'], install_requires=install_requires, test_requirements=['mock', 'nose'] + install_requires, zip_safe=False, From a182be6716d24fb49cb4517898b67ffcdfb5bca4 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 17:30:29 +0100 Subject: [PATCH 0050/2790] Updated readme to better represent current state And to trigger travis to build and work ... --- README.md | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/README.md b/README.md index 1bc6430e0..ab2545d3b 100644 --- a/README.md +++ b/README.md @@ -69,31 +69,15 @@ New BSD License. See the LICENSE file. [![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=0.3)](https://coveralls.io/r/gitpython-developers/GitPython?branch=0.3) [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) - -The project was idle for 2 years, the last release (v0.3.2 RC1) was made on July 2011. Reason for this might have been the project's dependency on me as sole active maintainer, which is an issue in itself. - Now that there seems to be a massive user base, this should be motivation enough to let git-python return to a proper state, which means * no open pull requests * no open issues describing bugs -In short, I want to make a new release of 0.3 with all contributions and fixes included, foster community building to facilitate contributions. - -#### PRESENT GOALS - -The goals I have set for myself, in order, are as follows, all on branch 0.3. - -* evaluate python 3.3 compatibility and establish it if possible - -While that is happening, I will try hard to foster community around the project. This means being more responsive on the mailing list and in issues, as well as setting up clear guide lines about the [contribution](http://rfc.zeromq.org/spec:22) and maintenance workflow. - #### FUTURE GOALS There has been a lot of work in the master branch, which is the direction I want git-python to go. Namely, it should be able to freely mix and match the back-end used, depending on your requirements and environment. -* restructure master to match my [OSS standard](https://github.com/Byron/bcore) -* review code base and bring test-suite back online -* establish python 3.3 compatibility -* make it work similarly to 0.3, but with the option to swap for at least one additional backend +* make new master work similarly to 0.3, but with the option to swap for at least one additional backend * make a 1.0 release * add backends as required From 1bfb44c62d15a45ca4d47b4cc482ebddb8d0ae4f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 17:55:42 +0100 Subject: [PATCH 0051/2790] Fixed up travis to checkout master now --- .travis.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14af19091..004129e11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,18 +14,12 @@ install: - git fetch --tags - pip install coveralls - # generate some reflog as git-python tests need it (in 0.3) - - git checkout 0.3 + # generate some reflog as git-python tests need it (in master) + - git checkout master - git reset --hard HEAD~1 - git reset --hard HEAD~1 - git reset --hard HEAD~1 - - git reset --hard origin/0.3 - - git checkout -b master - - git reset --hard HEAD~1 - - git reset --hard HEAD~1 - - git reset --hard HEAD~1 - - git reset --hard origin/0.3 - - git checkout 0.3 + - git reset --hard origin/master # as commits are performed with the default user, it needs to be set for travis too - git config --global user.email "travis@ci.com" From a6e4a6416162a698d87ba15693f2e7434beac644 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 18:49:44 +0100 Subject: [PATCH 0052/2790] Fixed up coverage configuration Also improved sublime text project --- .coveragerc | 7 +-- etc/sublime-text/git-python.sublime-project | 55 +++++++++------------ 2 files changed, 25 insertions(+), 37 deletions(-) diff --git a/.coveragerc b/.coveragerc index 410ffc520..e2b6256e9 100644 --- a/.coveragerc +++ b/.coveragerc @@ -3,8 +3,5 @@ source = git ; to make nosetests happy [report] -omit = - */yaml* - */tests/* - */python?.?/* - */site-packages/nose/* \ No newline at end of file +include = */git/* +omit = */git/ext/* diff --git a/etc/sublime-text/git-python.sublime-project b/etc/sublime-text/git-python.sublime-project index d3b692892..3dab9f656 100644 --- a/etc/sublime-text/git-python.sublime-project +++ b/etc/sublime-text/git-python.sublime-project @@ -15,7 +15,11 @@ "folder_exclude_patterns" : [ ".git", "cover", - "git/ext" + "git/ext", + "dist", + ".tox", + "doc/build", + "*.egg-info" ] }, // GITDB @@ -32,40 +36,27 @@ "folder_exclude_patterns" : [ ".git", "cover", - "gitdb/ext" + "gitdb/ext", + "dist", + "doc/build", + ".tox", ] }, // // SMMAP // //////// - // { - // "follow_symlinks": true, - // "path": "../../git/ext/gitdb/gitdb/ext/smmap", - // "file_exclude_patterns" : [ - // "*.sublime-workspace", - // ".git", - // ".noseids", - // ".coverage" - // ], - // "folder_exclude_patterns" : [ - // ".git", - // "cover", - // ] - // }, - // // ASYNC - // //////// - // { - // "follow_symlinks": true, - // "path": "../../git/ext/gitdb/gitdb/ext/async", - // "file_exclude_patterns" : [ - // "*.sublime-workspace", - // ".git", - // ".noseids", - // ".coverage" - // ], - // "folder_exclude_patterns" : [ - // ".git", - // "cover", - // ] - // }, + { + "follow_symlinks": true, + "path": "../../git/ext/gitdb/gitdb/ext/smmap", + "file_exclude_patterns" : [ + "*.sublime-workspace", + ".git", + ".noseids", + ".coverage" + ], + "folder_exclude_patterns" : [ + ".git", + "cover", + ] + }, ] } From fce04b7e4e6e1377aa7f07da985bb68671d36ba4 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jan 2015 21:00:41 +0100 Subject: [PATCH 0053/2790] Updated branch in coverage description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab2545d3b..40553b1a0 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ New BSD License. See the LICENSE file. ### DEVELOPMENT STATUS [![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg?branch=0.3)](https://travis-ci.org/gitpython-developers/GitPython) -[![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=0.3)](https://coveralls.io/r/gitpython-developers/GitPython?branch=0.3) +[![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=master)](https://coveralls.io/r/gitpython-developers/GitPython?branch=master) [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) Now that there seems to be a massive user base, this should be motivation enough to let git-python return to a proper state, which means From d437078d8f95cb98f905162b2b06d04545806c59 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 08:59:34 +0100 Subject: [PATCH 0054/2790] Added flake8 testing to travis Fixes #177 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 004129e11..4f77dbcaf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ git: install: - git submodule update --init --recursive - git fetch --tags - - pip install coveralls + - pip install coveralls flake8 # generate some reflog as git-python tests need it (in master) - git checkout master @@ -26,5 +26,6 @@ install: - git config --global user.name "Travis Runner" script: - nosetests -v --with-coverage + - flake8 after_success: - coveralls From 3efacd7aea48c93e0a42c1e83bf3c96e9e50f178 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 09:06:52 +0100 Subject: [PATCH 0055/2790] This should fix flake8 on py3 See #177 --- git/cmd.py | 4 +++- git/compat.py | 2 ++ git/test/performance/test_streams.py | 2 +- git/test/test_repo.py | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 7a670c46e..4a49bc1b1 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -22,7 +22,9 @@ from git.compat import ( string_types, defenc, - PY3 + PY3, + # just to satisfy flake8 on py3 + unicode ) execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', diff --git a/git/compat.py b/git/compat.py index 5c330e5be..1ea2119e1 100644 --- a/git/compat.py +++ b/git/compat.py @@ -33,6 +33,7 @@ def bchr(n): return bytes([n]) def mviter(d): return d.values() + unicode = str else: FileType = file # usually, this is just ascii, which might not enough for our encoding needs @@ -41,6 +42,7 @@ def mviter(d): defenc = 'utf-8' byte_ord = ord bchr = chr + unicode = unicode def mviter(d): return d.itervalues() diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index aecb77284..6e23b01da 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -140,6 +140,6 @@ def test_large_data_streaming(self, rwrepo): print(msg, file=sys.stderr) # compare - print ("Git-Python is %f %% faster than git when reading big %s files in chunks" + print("Git-Python is %f %% faster than git when reading big %s files in chunks" % (100.0 - (elapsed_readchunks / gelapsed_readchunks) * 100, desc), file=sys.stderr) # END for each randomization factor diff --git a/git/test/test_repo.py b/git/test/test_repo.py index f216039ed..eb831ce38 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -526,7 +526,7 @@ def test_rev_parse(self): assert obj.type == ref.object.type num_resolved += 1 except BadObject: - print ("failed on %s" % path_section) + print("failed on %s" % path_section) # is fine, in case we have something like 112, which belongs to remotes/rname/merge-requests/112 pass # END exception handling From a4b8e467e44bc1ca1ebf481ac2dfc1baaf9688dc Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 09:08:57 +0100 Subject: [PATCH 0056/2790] Once again, make flake8 happy --- git/test/performance/test_streams.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index 6e23b01da..4b1738cdf 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -141,5 +141,5 @@ def test_large_data_streaming(self, rwrepo): # compare print("Git-Python is %f %% faster than git when reading big %s files in chunks" - % (100.0 - (elapsed_readchunks / gelapsed_readchunks) * 100, desc), file=sys.stderr) + % (100.0 - (elapsed_readchunks / gelapsed_readchunks) * 100, desc), file=sys.stderr) # END for each randomization factor From d83f6e84cbeb45dce4576a9a4591446afefa50b2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 09:29:20 +0100 Subject: [PATCH 0057/2790] Make sure we ignore WindowsErrors too, in case the process is already dead Fixes #140 --- git/cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/cmd.py b/git/cmd.py index 4a49bc1b1..ef370fe22 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -103,7 +103,7 @@ def __del__(self): try: os.kill(self.proc.pid, 2) # interrupt signal self.proc.wait() # ensure process goes away - except OSError: + except (OSError, WindowsError): pass # ignore error when process already died except AttributeError: # try windows From 491440543571b07c849c0ef9c4ebf5c27f263bc0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 11:18:07 +0100 Subject: [PATCH 0058/2790] Implemented non-blocking operations using poll() Next up is using threads --- doc/source/changes.rst | 5 +++ git/cmd.py | 96 ++++++++++++++++++++++++++++++++++++++++++ git/index/base.py | 19 ++++----- git/remote.py | 66 +++++++++++------------------ git/repo/base.py | 13 +++--- git/util.py | 8 ++++ 6 files changed, 149 insertions(+), 58 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index b7479e4fe..4983b3d04 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,11 @@ Changelog ========= +0.3.5 - Bugfixes +================ +* push/pull/fetch operations will not block anymore +* A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+ + 0.3.4 - Python 3 Support ======================== * Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes. diff --git a/git/cmd.py b/git/cmd.py index ef370fe22..3cb334b6f 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -6,6 +6,7 @@ import os import sys +import select import logging from subprocess import ( call, @@ -36,9 +37,104 @@ __all__ = ('Git', ) +# ============================================================================== +## @name Utilities +# ------------------------------------------------------------------------------ +# Documentation +## @{ + +def handle_process_output(process, stdout_handler, stderr_handler, finalizer): + """Registers for notifications to lean that process output is ready to read, and dispatches lines to + the respective line handlers. We are able to handle carriage returns in case progress is sent by that + mean. For performance reasons, we only apply this to stderr. + This function returns once the finalizer returns + :return: result of finalizer + :param process: subprocess.Popen instance + :param stdout_handler: f(stdout_line_string), or None + :param stderr_hanlder: f(stderr_line_string), or None + :param finalizer: f(proc) - wait for proc to finish""" + def read_line_fast(stream): + return stream.readline() + + def read_line_slow(stream): + line = b'' + while True: + char = stream.read(1) # reads individual single byte strings + if not char: + break + + if char in (b'\r', b'\n') and line: + break + else: + line += char + # END process parsed line + # END while file is not done reading + return line + # end + + fdmap = { process.stdout.fileno() : (process.stdout, stdout_handler, read_line_fast), + process.stderr.fileno() : (process.stderr, stderr_handler, read_line_slow) } + + if hasattr(select, 'poll'): + def dispatch_line(fd): + stream, handler, readline = fdmap[fd] + # this can possibly block for a while, but since we wake-up with at least one or more lines to handle, + # we are good ... + line = readline(stream).decode(defenc) + if line and handler: + handler(line) + return line + # end dispatch helper + + # poll is preferred, as select is limited to file handles up to 1024 ... . Not an issue for us though, + # as we deal with relatively blank processes + poll = select.poll() + READ_ONLY = select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR + CLOSED = select.POLLHUP | select.POLLERR + + poll.register(process.stdout, READ_ONLY) + poll.register(process.stderr, READ_ONLY) + + closed_streams = set() + while True: + # no timeout + poll_result = poll.poll() + for fd, result in poll_result: + if result & CLOSED: + closed_streams.add(fd) + else: + dispatch_line(fd) + # end handle closed stream + # end for each poll-result tuple + + if len(closed_streams) == len(fdmap): + break + # end its all done + # end endless loop + + # Depelete all remaining buffers + for fno, _ in fdmap.items(): + while True: + line = dispatch_line(fno) + if not line: + break + # end deplete buffer + # end for each file handle + else: + # Oh ... probably we are on windows. select.select() can only handle sockets, we have files + # The only reliable way to do this now is to use threads and wait for both to finish + # Since the finalizer is expected to wait, we don't have to introduce our own wait primitive + raise NotImplementedError() + # end + + return finalizer(process) + + def dashify(string): return string.replace('_', '-') +## -- End Utilities -- @} + class Git(LazyMixin): diff --git a/git/index/base.py b/git/index/base.py index cc8834698..66fd5b1fb 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -287,11 +287,11 @@ def from_tree(cls, repo, *treeish, **kwargs): changes according to the amount of trees. If 1 Tree is given, it will just be read into a new index If 2 Trees are given, they will be merged into a new index using a - two way merge algorithm. Tree 1 is the 'current' tree, tree 2 is the 'other' - one. It behaves like a fast-forward. - If 3 Trees are given, a 3-way merge will be performed with the first tree - being the common ancestor of tree 2 and tree 3. Tree 2 is the 'current' tree, - tree 3 is the 'other' one + two way merge algorithm. Tree 1 is the 'current' tree, tree 2 is the 'other' + one. It behaves like a fast-forward. + If 3 Trees are given, a 3-way merge will be performed with the first tree + being the common ancestor of tree 2 and tree 3. Tree 2 is the 'current' tree, + tree 3 is the 'other' one :param kwargs: Additional arguments passed to git-read-tree @@ -882,14 +882,11 @@ def move(self, items, skip_errors=False, **kwargs): def commit(self, message, parent_commits=None, head=True, author=None, committer=None): """Commit the current default index file, creating a commit object. - For more information on the arguments, see tree.commit. - :note: - If you have manually altered the .entries member of this instance, - don't forget to write() your changes to disk beforehand. - :return: - Commit object representing the new commit""" + :note: If you have manually altered the .entries member of this instance, + don't forget to write() your changes to disk beforehand. + :return: Commit object representing the new commit""" tree = self.write_tree() return Commit.create_from_tree(self.repo, tree, message, parent_commits, head, author=author, committer=committer) diff --git a/git/remote.py b/git/remote.py index 484bc0310..85f4ebf23 100644 --- a/git/remote.py +++ b/git/remote.py @@ -31,6 +31,7 @@ join_path, finalize_process ) +from git.cmd import handle_process_output from gitdb.util import join from git.compat import defenc @@ -39,31 +40,6 @@ #{ Utilities - -def digest_process_messages(fh, progress): - """Read progress messages from file-like object fh, supplying the respective - progress messages to the progress instance. - - :param fh: File handle to read from - :return: list(line, ...) list of lines without linebreaks that did - not contain progress information""" - line_so_far = b'' - dropped_lines = list() - while True: - char = fh.read(1) # reads individual single byte strings - if not char: - break - - if char in (b'\r', b'\n') and line_so_far: - dropped_lines.extend(progress._parse_progress_line(line_so_far.decode(defenc))) - line_so_far = b'' - else: - line_so_far += char - # END process parsed line - # END while file is not done reading - return dropped_lines - - def add_progress(kwargs, git, progress): """Add the --progress flag to the given kwargs dict if supported by the git command. If the actual progress in the given progress instance is not @@ -532,17 +508,24 @@ def _get_fetch_info_from_stderr(self, proc, progress): # Basically we want all fetch info lines which appear to be in regular form, and thus have a # command character. Everything else we ignore, cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys()) - for line in digest_process_messages(proc.stderr, progress): - if line.startswith('fatal:'): - raise GitCommandError(("Error when fetching: %s" % line,), 2) - # END handle special messages - for cmd in cmds: - if line[1] == cmd: - fetch_info_lines.append(line) - continue - # end find command code - # end for each comand code we know - # END for each line + + progress_handler = progress.new_message_handler() + def my_progress_handler(line): + for pline in progress_handler(line): + if line.startswith('fatal:'): + raise GitCommandError(("Error when fetching: %s" % line,), 2) + # END handle special messages + for cmd in cmds: + if line[1] == cmd: + fetch_info_lines.append(line) + continue + # end find command code + # end for each comand code we know + # end for each line progress didn't handle + # end + + # We are only interested in stderr here ... + handle_process_output(proc, None, my_progress_handler, finalize_process) # read head information fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') @@ -555,7 +538,6 @@ def _get_fetch_info_from_stderr(self, proc, progress): output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info)) - finalize_process(proc) return output def _get_push_info(self, proc, progress): @@ -564,11 +546,10 @@ def _get_push_info(self, proc, progress): # read the lines manually as it will use carriage returns between the messages # to override the previous one. This is why we read the bytes manually # TODO: poll() on file descriptors to know what to read next, process streams concurrently - digest_process_messages(proc.stderr, progress) - + progress_handler = progress.new_message_handler() output = IterableList('name') - for line in proc.stdout.readlines(): - line = line.decode(defenc) + + def stdout_handler(line): try: output.append(PushInfo._from_line(self, line)) except ValueError: @@ -576,7 +557,8 @@ def _get_push_info(self, proc, progress): pass # END exception handling # END for each line - finalize_process(proc) + + handle_process_output(proc, stdout_handler, progress_handler, finalize_process) return output def fetch(self, refspec=None, progress=None, **kwargs): diff --git a/git/repo/base.py b/git/repo/base.py index 2a63492bf..e8db3540f 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -5,7 +5,10 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php from git.exc import InvalidGitRepositoryError, NoSuchPathError -from git.cmd import Git +from git.cmd import ( + Git, + handle_process_output +) from git.refs import ( HEAD, Head, @@ -25,7 +28,6 @@ from git.config import GitConfigParser from git.remote import ( Remote, - digest_process_messages, add_progress ) @@ -711,9 +713,10 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): proc = git.clone(url, path, with_extended_output=True, as_process=True, v=True, **add_progress(kwargs, git, progress)) if progress: - digest_process_messages(proc.stderr, progress) - # END handle progress - finalize_process(proc) + handle_process_output(proc, None, progress.new_message_handler(), finalize_process) + else: + finalize_process(proc) + # end handle progress finally: if prev_cwd is not None: os.chdir(prev_cwd) diff --git a/git/util.py b/git/util.py index 4de736d3a..34b09d328 100644 --- a/git/util.py +++ b/git/util.py @@ -249,6 +249,14 @@ def _parse_progress_line(self, line): # END for each sub line return failed_lines + def new_message_handler(self): + """:return: a progress handler suitable for handle_process_output(), passing lines on to this Progress + handler in a suitable format""" + def handler(line): + return self._parse_progress_line(line.rstrip()) + # end + return handler + def line_dropped(self, line): """Called whenever a line could not be understood and was therefore dropped.""" pass From c86bea60dde4016dd850916aa2e0db5260e1ff61 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 11:41:15 +0100 Subject: [PATCH 0059/2790] Implemented threaded version of pipe-draining --- git/cmd.py | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 3cb334b6f..5ba5edb47 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -8,6 +8,7 @@ import sys import select import logging +import threading from subprocess import ( call, Popen, @@ -72,12 +73,8 @@ def read_line_slow(stream): return line # end - fdmap = { process.stdout.fileno() : (process.stdout, stdout_handler, read_line_fast), - process.stderr.fileno() : (process.stderr, stderr_handler, read_line_slow) } - - if hasattr(select, 'poll'): - def dispatch_line(fd): - stream, handler, readline = fdmap[fd] + def dispatch_line(fno): + stream, handler, readline = fdmap[fno] # this can possibly block for a while, but since we wake-up with at least one or more lines to handle, # we are good ... line = readline(stream).decode(defenc) @@ -85,9 +82,22 @@ def dispatch_line(fd): handler(line) return line # end dispatch helper + # end + + def deplete_buffer(fno): + while True: + line = dispatch_line(fno) + if not line: + break + # end deplete buffer + # end + + fdmap = { process.stdout.fileno() : (process.stdout, stdout_handler, read_line_fast), + process.stderr.fileno() : (process.stderr, stderr_handler, read_line_slow) } - # poll is preferred, as select is limited to file handles up to 1024 ... . Not an issue for us though, - # as we deal with relatively blank processes + if hasattr(select, 'poll'): + # poll is preferred, as select is limited to file handles up to 1024 ... . This could otherwise be + # an issue for us, as it matters how many handles or own process has poll = select.poll() READ_ONLY = select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR CLOSED = select.POLLHUP | select.POLLERR @@ -113,18 +123,23 @@ def dispatch_line(fd): # end endless loop # Depelete all remaining buffers - for fno, _ in fdmap.items(): - while True: - line = dispatch_line(fno) - if not line: - break - # end deplete buffer + for fno in fdmap.keys(): + deplete_buffer(fno) # end for each file handle else: # Oh ... probably we are on windows. select.select() can only handle sockets, we have files # The only reliable way to do this now is to use threads and wait for both to finish # Since the finalizer is expected to wait, we don't have to introduce our own wait primitive - raise NotImplementedError() + # NO: It's not enough unfortunately, and we will have to sync the threads + threads = list() + for fno in fdmap.keys(): + t = threading.Thread(target = lambda: deplete_buffer(fno)) + threads.append(t) + t.start() + # end + for t in threads: + t.join() + # end # end return finalizer(process) From 763ef75d12f0ad6e4b79a7df304c7b5f1b5a11f2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 12:32:45 +0100 Subject: [PATCH 0060/2790] Using a wait-group seems to properly sync the threads for buffer depletion --- git/cmd.py | 20 ++++++++++++-------- git/util.py | 32 +++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 5ba5edb47..e03d0cdc0 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -18,7 +18,8 @@ from .util import ( LazyMixin, - stream_copy + stream_copy, + WaitGroup ) from .exc import GitCommandError from git.compat import ( @@ -84,12 +85,14 @@ def dispatch_line(fno): # end dispatch helper # end - def deplete_buffer(fno): + def deplete_buffer(fno, wg=None): while True: line = dispatch_line(fno) if not line: break # end deplete buffer + if wg: + wg.done() # end fdmap = { process.stdout.fileno() : (process.stdout, stdout_handler, read_line_fast), @@ -131,15 +134,16 @@ def deplete_buffer(fno): # The only reliable way to do this now is to use threads and wait for both to finish # Since the finalizer is expected to wait, we don't have to introduce our own wait primitive # NO: It's not enough unfortunately, and we will have to sync the threads - threads = list() + wg = WaitGroup() for fno in fdmap.keys(): - t = threading.Thread(target = lambda: deplete_buffer(fno)) - threads.append(t) + wg.add(1) + t = threading.Thread(target = lambda: deplete_buffer(fno, wg)) t.start() # end - for t in threads: - t.join() - # end + # NOTE: Just joining threads can possibly fail as there is a gap between .start() and when it's + # actually started, which could make the wait() call to just return because the thread is not yet + # active + wg.wait() # end return finalizer(process) diff --git a/git/util.py b/git/util.py index 34b09d328..e211ca41d 100644 --- a/git/util.py +++ b/git/util.py @@ -12,6 +12,7 @@ import shutil import platform import getpass +import threading # NOTE: Some of the unused imports might be used/imported by others. # Handle once test-cases are back up and running. @@ -32,7 +33,7 @@ __all__ = ("stream_copy", "join_path", "to_native_path_windows", "to_native_path_linux", "join_path_native", "Stats", "IndexFileSHA1Writer", "Iterable", "IterableList", "BlockingLockFile", "LockFile", 'Actor', 'get_user_id', 'assure_directory_exists', - 'RemoteProgress', 'rmtree') + 'RemoteProgress', 'rmtree', 'WaitGroup') #{ Utility Methods @@ -699,3 +700,32 @@ def iter_items(cls, repo, *args, **kwargs): raise NotImplementedError("To be implemented by Subclass") #} END classes + + +class WaitGroup(object): + """WaitGroup is like Go sync.WaitGroup. + + Without all the useful corner cases. + By Peter Teichman, taken from https://gist.github.com/pteichman/84b92ae7cef0ab98f5a8 + """ + def __init__(self): + self.count = 0 + self.cv = threading.Condition() + + def add(self, n): + self.cv.acquire() + self.count += n + self.cv.release() + + def done(self): + self.cv.acquire() + self.count -= 1 + if self.count == 0: + self.cv.notify_all() + self.cv.release() + + def wait(self): + self.cv.acquire() + while self.count > 0: + self.cv.wait() + self.cv.release() From 87a6ffa13ae2951a168cde5908c7a94b16562b96 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 12:37:49 +0100 Subject: [PATCH 0061/2790] Fix flake8 --- git/cmd.py | 20 ++++++++++---------- git/remote.py | 6 ++++-- git/util.py | 10 +++++----- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index e03d0cdc0..f847166ce 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -46,8 +46,8 @@ ## @{ def handle_process_output(process, stdout_handler, stderr_handler, finalizer): - """Registers for notifications to lean that process output is ready to read, and dispatches lines to - the respective line handlers. We are able to handle carriage returns in case progress is sent by that + """Registers for notifications to lean that process output is ready to read, and dispatches lines to + the respective line handlers. We are able to handle carriage returns in case progress is sent by that mean. For performance reasons, we only apply this to stderr. This function returns once the finalizer returns :return: result of finalizer @@ -77,7 +77,7 @@ def read_line_slow(stream): def dispatch_line(fno): stream, handler, readline = fdmap[fno] # this can possibly block for a while, but since we wake-up with at least one or more lines to handle, - # we are good ... + # we are good ... line = readline(stream).decode(defenc) if line and handler: handler(line) @@ -93,13 +93,13 @@ def deplete_buffer(fno, wg=None): # end deplete buffer if wg: wg.done() - # end + # end - fdmap = { process.stdout.fileno() : (process.stdout, stdout_handler, read_line_fast), - process.stderr.fileno() : (process.stderr, stderr_handler, read_line_slow) } + fdmap = {process.stdout.fileno(): (process.stdout, stdout_handler, read_line_fast), + process.stderr.fileno(): (process.stderr, stderr_handler, read_line_slow)} if hasattr(select, 'poll'): - # poll is preferred, as select is limited to file handles up to 1024 ... . This could otherwise be + # poll is preferred, as select is limited to file handles up to 1024 ... . This could otherwise be # an issue for us, as it matters how many handles or own process has poll = select.poll() READ_ONLY = select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR @@ -137,10 +137,10 @@ def deplete_buffer(fno, wg=None): wg = WaitGroup() for fno in fdmap.keys(): wg.add(1) - t = threading.Thread(target = lambda: deplete_buffer(fno, wg)) + t = threading.Thread(target=lambda: deplete_buffer(fno, wg)) t.start() # end - # NOTE: Just joining threads can possibly fail as there is a gap between .start() and when it's + # NOTE: Just joining threads can possibly fail as there is a gap between .start() and when it's # actually started, which could make the wait() call to just return because the thread is not yet # active wg.wait() @@ -148,7 +148,7 @@ def deplete_buffer(fno, wg=None): return finalizer(process) - + def dashify(string): return string.replace('_', '-') diff --git a/git/remote.py b/git/remote.py index 85f4ebf23..87db5dd4b 100644 --- a/git/remote.py +++ b/git/remote.py @@ -40,6 +40,7 @@ #{ Utilities + def add_progress(kwargs, git, progress): """Add the --progress flag to the given kwargs dict if supported by the git command. If the actual progress in the given progress instance is not @@ -510,6 +511,7 @@ def _get_fetch_info_from_stderr(self, proc, progress): cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys()) progress_handler = progress.new_message_handler() + def my_progress_handler(line): for pline in progress_handler(line): if line.startswith('fatal:'): @@ -520,11 +522,11 @@ def my_progress_handler(line): fetch_info_lines.append(line) continue # end find command code - # end for each comand code we know + # end for each comand code we know # end for each line progress didn't handle # end - # We are only interested in stderr here ... + # We are only interested in stderr here ... handle_process_output(proc, None, my_progress_handler, finalize_process) # read head information diff --git a/git/util.py b/git/util.py index e211ca41d..4d1ea8d65 100644 --- a/git/util.py +++ b/git/util.py @@ -251,7 +251,7 @@ def _parse_progress_line(self, line): return failed_lines def new_message_handler(self): - """:return: a progress handler suitable for handle_process_output(), passing lines on to this Progress + """:return: a progress handler suitable for handle_process_output(), passing lines on to this Progress handler in a suitable format""" def handler(line): return self._parse_progress_line(line.rstrip()) @@ -704,26 +704,26 @@ def iter_items(cls, repo, *args, **kwargs): class WaitGroup(object): """WaitGroup is like Go sync.WaitGroup. - + Without all the useful corner cases. By Peter Teichman, taken from https://gist.github.com/pteichman/84b92ae7cef0ab98f5a8 """ def __init__(self): self.count = 0 self.cv = threading.Condition() - + def add(self, n): self.cv.acquire() self.count += n self.cv.release() - + def done(self): self.cv.acquire() self.count -= 1 if self.count == 0: self.cv.notify_all() self.cv.release() - + def wait(self): self.cv.acquire() while self.count > 0: From 4fd7b945dfca73caf00883d4cf43740edb7516df Mon Sep 17 00:00:00 2001 From: firm1 Date: Thu, 4 Sep 2014 03:38:08 +0200 Subject: [PATCH 0062/2790] add support of utf8 --- git/refs/log.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/git/refs/log.py b/git/refs/log.py index 8ce98d309..c6f9a218d 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -32,7 +32,6 @@ class RefLogEntry(tuple): """Named tuple allowing easy access to the revlog data fields""" - _fmt = "%s %s %s <%s> %i %s\t%s\n" _re_hexsha_only = re.compile('^[0-9A-Fa-f]{40}$') __slots__ = tuple() @@ -40,9 +39,8 @@ def __repr__(self): """Representation of ourselves in git reflog format""" act = self.actor time = self.time - return self._fmt % (self.oldhexsha, self.newhexsha, act.name, act.email, - time[0], altz_to_utctz_str(time[1]), self.message) - + return u"{0} {1} {2} <{3}> {4!s} {5}\t{6}\n".format(self.oldhexsha, self.newhexsha, act.name, act.email, + time[0], altz_to_utctz_str(time[1]), self.message).encode("utf-8") @property def oldhexsha(self): """The hexsha to the commit the ref pointed to before the change""" @@ -267,7 +265,6 @@ def append_entry(cls, config_reader, filepath, oldbinsha, newbinsha, message): lf = LockFile(filepath) lf._obtain_lock_or_raise() - fd = open(filepath, 'ab') try: fd.write(repr(entry).encode(defenc)) From 28bda3aaa19955d1c172bd86d62478bee024bf7b Mon Sep 17 00:00:00 2001 From: firm1 Date: Sat, 6 Sep 2014 03:12:38 +0200 Subject: [PATCH 0063/2790] suppression des prefixes de commit --- git/objects/commit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/objects/commit.py b/git/objects/commit.py index 8f93d1b90..f2ce91ca0 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -358,7 +358,7 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, # as well ... import git.refs try: - repo.head.set_commit(new_commit, logmsg="commit: %s" % message) + repo.head.set_commit(new_commit, logmsg=message) except ValueError: # head is not yet set to the ref our HEAD points to # Happens on first commit From 1dec7a822424bbe58b7b2a7787b1ea32683a9c19 Mon Sep 17 00:00:00 2001 From: firm1 Date: Wed, 7 Jan 2015 11:42:57 +0100 Subject: [PATCH 0064/2790] add tests for commit by actor --- git/test/test_index.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/git/test/test_index.py b/git/test/test_index.py index f7504b322..a0d1ffbc8 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -444,6 +444,22 @@ def mixed_iterator(): assert new_commit.parents[0] == cur_commit assert len(new_commit.parents) == 1 assert cur_head.commit == cur_commit + + # commit with other actor + cur_commit = cur_head.commit + + my_author = Actor("An author", "author@example.com") + my_committer = Actor("An committer", "committer@example.com") + commit_actor = index.commit(commit_message, author=my_author, committer=my_committer) + assert cur_commit != commit_actor + assert commit_actor.author.name == "An author" + assert commit_actor.author.email == "author@example.com" + assert commit_actor.committer.name == "An committer" + assert commit_actor.committer.email == "committer@example.com" + assert commit_actor.message == commit_message + assert commit_actor.parents[0] == cur_commit + assert len(new_commit.parents) == 1 + assert cur_head.commit == cur_commit # same index, no parents commit_message = "index without parents" From 0d4b4ea9c84198a9b6003611a3af00ee677d09a6 Mon Sep 17 00:00:00 2001 From: firm1 Date: Wed, 7 Jan 2015 11:49:50 +0100 Subject: [PATCH 0065/2790] add documentation --- doc/source/tutorial.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index d9b35fda9..3f45b70dc 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -297,7 +297,10 @@ Access objects and add/remove entries. Commit the changes:: # Access the entries directly index.add(['my_new_file']) # add a new file to the index index.remove(['dir/existing_file']) - new_commit = index.commit("my commit message") + new_commit = index.commit("my commit message") # commit by commit message first + my_author = Actor("An author", "author@example.com") + my_committer = Actor("A committer", "committer@example.com") + next_commit = index.commit("my commit message", author=my_author, commiter=my_committer) # commit by commit message and author and committer Create new indices from other trees or as result of a merge. Write that result to a new index file:: From b6ed8d46c72366e111b9a97a7c238ef4af3bf4dc Mon Sep 17 00:00:00 2001 From: firm1 Date: Wed, 7 Jan 2015 13:51:48 +0100 Subject: [PATCH 0066/2790] fix pep8 --- git/refs/log.py | 10 ++++++++-- git/test/test_index.py | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/git/refs/log.py b/git/refs/log.py index c6f9a218d..ec19c1e89 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -39,8 +39,14 @@ def __repr__(self): """Representation of ourselves in git reflog format""" act = self.actor time = self.time - return u"{0} {1} {2} <{3}> {4!s} {5}\t{6}\n".format(self.oldhexsha, self.newhexsha, act.name, act.email, - time[0], altz_to_utctz_str(time[1]), self.message).encode("utf-8") + return u"{0} {1} {2} <{3}> {4!s} {5}\t{6}\n".format(self.oldhexsha, + self.newhexsha, + act.name, + act.email, + time[0], + altz_to_utctz_str(time[1]), + self.message).encode("utf-8") + @property def oldhexsha(self): """The hexsha to the commit the ref pointed to before the change""" diff --git a/git/test/test_index.py b/git/test/test_index.py index a0d1ffbc8..f7d1cc6a6 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -10,6 +10,7 @@ fixture, with_rw_repo ) +from git.util import Actor from git import ( IndexFile, BlobFilter, @@ -444,10 +445,10 @@ def mixed_iterator(): assert new_commit.parents[0] == cur_commit assert len(new_commit.parents) == 1 assert cur_head.commit == cur_commit - + # commit with other actor cur_commit = cur_head.commit - + my_author = Actor("An author", "author@example.com") my_committer = Actor("An committer", "committer@example.com") commit_actor = index.commit(commit_message, author=my_author, committer=my_committer) From c6ee00d0dadcd7b10d60a2985db4fe137ca7cfed Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 15:22:59 +0100 Subject: [PATCH 0067/2790] Made sure commits accept unicode or unicode characters --- git/refs/log.py | 17 ++++++++++++++--- git/test/test_index.py | 14 ++++++++------ git/util.py | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/git/refs/log.py b/git/refs/log.py index ec19c1e89..f8dc88da5 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -18,6 +18,7 @@ altz_to_utctz_str, ) from git.compat import ( + PY3, xrange, string_types, defenc @@ -37,6 +38,16 @@ class RefLogEntry(tuple): def __repr__(self): """Representation of ourselves in git reflog format""" + res = self.format() + if PY3: + return res + else: + # repr must return a string, which it will auto-encode from unicode using the default encoding. + # This usually fails, so we encode ourselves + return res.encode(defenc) + + def format(self): + """:return: a string suitable to be placed in a reflog file""" act = self.actor time = self.time return u"{0} {1} {2} <{3}> {4!s} {5}\t{6}\n".format(self.oldhexsha, @@ -45,7 +56,7 @@ def __repr__(self): act.email, time[0], altz_to_utctz_str(time[1]), - self.message).encode("utf-8") + self.message) @property def oldhexsha(self): @@ -273,7 +284,7 @@ def append_entry(cls, config_reader, filepath, oldbinsha, newbinsha, message): lf._obtain_lock_or_raise() fd = open(filepath, 'ab') try: - fd.write(repr(entry).encode(defenc)) + fd.write(entry.format().encode(defenc)) finally: fd.close() lf._release_lock() @@ -298,7 +309,7 @@ def _serialize(self, stream): # write all entries for e in self: - write(repr(e).encode(defenc)) + write(e.format().encode(defenc)) # END for each entry def _deserialize(self, stream): diff --git a/git/test/test_index.py b/git/test/test_index.py index f7d1cc6a6..4fdd3d1bf 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -1,3 +1,4 @@ +#-*-coding:utf-8-*- # test_index.py # Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors # @@ -433,7 +434,7 @@ def mixed_iterator(): # TEST COMMITTING # commit changed index cur_commit = cur_head.commit - commit_message = "commit default head" + commit_message = u"commit default head by Frèderic Çaufl€" new_commit = index.commit(commit_message, head=False) assert cur_commit != new_commit @@ -449,18 +450,19 @@ def mixed_iterator(): # commit with other actor cur_commit = cur_head.commit - my_author = Actor("An author", "author@example.com") - my_committer = Actor("An committer", "committer@example.com") + my_author = Actor(u"Frèderic Çaufl€", "author@example.com") + my_committer = Actor(u"Committing Frèderic Çaufl€", "committer@example.com") commit_actor = index.commit(commit_message, author=my_author, committer=my_committer) assert cur_commit != commit_actor - assert commit_actor.author.name == "An author" + assert commit_actor.author.name == u"Frèderic Çaufl€" assert commit_actor.author.email == "author@example.com" - assert commit_actor.committer.name == "An committer" + assert commit_actor.committer.name == u"Committing Frèderic Çaufl€" assert commit_actor.committer.email == "committer@example.com" assert commit_actor.message == commit_message assert commit_actor.parents[0] == cur_commit assert len(new_commit.parents) == 1 - assert cur_head.commit == cur_commit + assert cur_head.commit == commit_actor + assert cur_head.log()[-1].actor == my_committer # same index, no parents commit_message = "index without parents" diff --git a/git/util.py b/git/util.py index 4d1ea8d65..b1f3b38dc 100644 --- a/git/util.py +++ b/git/util.py @@ -328,7 +328,7 @@ def __str__(self): return self.name def __repr__(self): - return '">' % (self.name, self.email) + return u'">' % (self.name, self.email) @classmethod def _from_string(cls, string): From 36cdfd3209909163549850709d7f12fdf1316434 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jan 2015 20:00:06 +0100 Subject: [PATCH 0068/2790] Made improvements to assure test-cases don't leak file handles At least leakage is considerably reduced. Additionally, a test-case was added which triggers failure if auto-disposal of resources wouldn't work. Fixes #60 --- .travis.yml | 3 +++ git/cmd.py | 22 ++++++++++++++++------ git/refs/log.py | 1 + git/repo/base.py | 4 ++++ git/test/lib/helper.py | 5 +++++ git/test/performance/lib.py | 11 +++++++++++ git/test/test_repo.py | 17 +++++++++++++++++ 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f77dbcaf..112df6cf7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,9 @@ install: - git config --global user.email "travis@ci.com" - git config --global user.name "Travis Runner" script: + # Make sure we limit open handles to see if we are leaking them + - ulimit -n 64 + - ulimit -n - nosetests -v --with-coverage - flake8 after_success: diff --git a/git/cmd.py b/git/cmd.py index f847166ce..9bd955536 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -38,6 +38,9 @@ __all__ = ('Git', ) +if sys.platform != 'win32': + WindowsError = OSError + # ============================================================================== ## @name Utilities @@ -203,11 +206,18 @@ def __init__(self, proc, args): self.args = args def __del__(self): - self.proc.stdout.close() - self.proc.stderr.close() + if self.proc is None: + return + + proc = self.proc + self.proc = None + if proc.stdin: + proc.stdin.close() + proc.stdout.close() + proc.stderr.close() # did the process finish already so we have a return code ? - if self.proc.poll() is not None: + if proc.poll() is not None: return # can be that nothing really exists anymore ... @@ -216,8 +226,8 @@ def __del__(self): # try to kill it try: - os.kill(self.proc.pid, 2) # interrupt signal - self.proc.wait() # ensure process goes away + os.kill(proc.pid, 2) # interrupt signal + proc.wait() # ensure process goes away except (OSError, WindowsError): pass # ignore error when process already died except AttributeError: @@ -225,7 +235,7 @@ def __del__(self): # for some reason, providing None for stdout/stderr still prints something. This is why # we simply use the shell and redirect to nul. Its slower than CreateProcess, question # is whether we really want to see all these messages. Its annoying no matter what. - call(("TASKKILL /F /T /PID %s 2>nul 1>nul" % str(self.proc.pid)), shell=True) + call(("TASKKILL /F /T /PID %s 2>nul 1>nul" % str(proc.pid)), shell=True) # END exception handling def __getattr__(self, attr): diff --git a/git/refs/log.py b/git/refs/log.py index f8dc88da5..fed136087 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -204,6 +204,7 @@ def iter_entries(cls, stream): return yield new_entry(line.strip()) # END endless loop + stream.close() @classmethod def entry_at(cls, filepath, index): diff --git a/git/repo/base.py b/git/repo/base.py index e8db3540f..934a6f03e 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -168,6 +168,10 @@ def __init__(self, path=None, odbt=DefaultDBType): args.append(self.git) self.odb = odbt(*args) + def __del__(self): + if self.git: + self.git.clear_cache() + def __eq__(self, rhs): if isinstance(rhs, Repo): return self.git_dir == rhs.git_dir diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index bd6795128..6c9f33c68 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -279,6 +279,11 @@ def setUpClass(cls): """ cls.rorepo = Repo(GIT_REPO) + @classmethod + def tearDownClass(cls): + cls.rorepo.git.clear_cache() + cls.rorepo.git = None + def _make_file(self, rela_path, data, repo=None): """ Create a file at the given path relative to our repository, filled diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index 5c138f177..46a198d46 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -59,6 +59,12 @@ def setUp(self): self.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB) self.puregitrorepo = Repo(repo_path, odbt=GitDB) + def tearDown(self): + self.gitrorepo.git.clear_cache() + self.gitrorepo = None + self.puregitrorepo.git.clear_cache() + self.puregitrorepo = None + class TestBigRepoRW(TestBigRepoR): @@ -78,7 +84,12 @@ def setUp(self): self.puregitrwrepo = Repo(dirname, odbt=GitDB) def tearDown(self): + super(TestBigRepoRW, self).tearDown() if self.gitrwrepo is not None: shutil.rmtree(self.gitrwrepo.working_dir) + self.gitrwrepo.git.clear_cache() + self.gitrwrepo = None + self.puregitrwrepo.git.clear_cache() + self.puregitrwrepo = None #} END base classes diff --git a/git/test/test_repo.py b/git/test/test_repo.py index eb831ce38..260f7d689 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -656,3 +656,20 @@ def test_git_file(self, rwrepo): open(git_file_path, 'wb').write(('gitdir: %s\n' % real_path_abs).encode('ascii')) git_file_repo = Repo(rwrepo.working_tree_dir) assert os.path.abspath(git_file_repo.git_dir) == real_path_abs + + def test_file_handle_leaks(self): + def last_commit(repo, rev, path): + commit = next(repo.iter_commits(rev, path, max_count=1)) + commit.tree[path] + + # This is based on this comment + # https://github.com/gitpython-developers/GitPython/issues/60#issuecomment-23558741 + # And we expect to set max handles to a low value, like 64 + # You should set ulimit -n X, see .travis.yml + # The loops below would easily create 500 handles if these would leak (4 pipes + multiple mapped files) + for i in range(64): + for repo_type in (GitCmdObjectDB, GitDB): + repo = Repo(self.rorepo.working_tree_dir, odbt=repo_type) + last_commit(repo, 'master', 'git/test/test_base.py') + # end for each repository type + # end for each iteration From c7887c66483ffa9a839ecf1a53c5ef718dcd1d2d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 09:21:25 +0100 Subject: [PATCH 0069/2790] Improve error handling of fetch/pull line parsing Fixes #48 --- git/cmd.py | 7 ++++++- git/remote.py | 2 +- git/repo/base.py | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 9bd955536..d0190adfb 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -83,7 +83,12 @@ def dispatch_line(fno): # we are good ... line = readline(stream).decode(defenc) if line and handler: - handler(line) + try: + handler(line) + except Exception: + # Keep reading, have to pump the lines empty nontheless + log.error("Line handler exception on line: %s", line, exc_info=True) + # end return line # end dispatch helper # end diff --git a/git/remote.py b/git/remote.py index 87db5dd4b..4d2490048 100644 --- a/git/remote.py +++ b/git/remote.py @@ -518,7 +518,7 @@ def my_progress_handler(line): raise GitCommandError(("Error when fetching: %s" % line,), 2) # END handle special messages for cmd in cmds: - if line[1] == cmd: + if len(line) > 1 and line[0] == ' ' and line[1] == cmd: fetch_info_lines.append(line) continue # end find command code diff --git a/git/repo/base.py b/git/repo/base.py index 934a6f03e..34fe40467 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -113,7 +113,7 @@ def __init__(self, path=None, odbt=DefaultDBType): :raise NoSuchPathError: :return: git.Repo """ epath = os.path.abspath(os.path.expandvars(os.path.expanduser(path or os.getcwd()))) - + self.git = None # should be set for __del__ not to fail in case we raise if not os.path.exists(epath): raise NoSuchPathError(epath) From f7b7eb6245e7d7c4535975268a9be936e2c59dc8 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 09:45:50 +0100 Subject: [PATCH 0070/2790] Added Remote.exists() method, and test. Fixes #229 --- git/remote.py | 13 +++++++++++++ git/repo/base.py | 5 ++++- git/test/test_repo.py | 7 ++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/git/remote.py b/git/remote.py index 4d2490048..deddd1f41 100644 --- a/git/remote.py +++ b/git/remote.py @@ -397,6 +397,19 @@ def __ne__(self, other): def __hash__(self): return hash(self.name) + def exists(self): + """:return: True if this is a valid, existing remote. + Valid remotes have an entry in the repository's configuration""" + try: + self.config_reader.get('url') + return True + except cp.NoOptionError: + # we have the section at least ... + return True + except cp.NoSectionError: + return False + # end + @classmethod def iter_items(cls, repo): """:return: Iterator yielding Remote objects of the given repository""" diff --git a/git/repo/base.py b/git/repo/base.py index 34fe40467..7bd2be48c 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -250,7 +250,10 @@ def remotes(self): def remote(self, name='origin'): """:return: Remote with the specified name :raise ValueError: if no remote with such a name exists""" - return Remote(self, name) + r = Remote(self, name) + if not r.exists(): + raise ValueError("Remote named '%s' didn't exist" % name) + return r #{ Submodules diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 260f7d689..e0be20740 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -25,7 +25,8 @@ Reference, GitDB, Submodule, - GitCmdObjectDB + GitCmdObjectDB, + Remote ) from git.util import join_path_native from git.exc import BadObject @@ -673,3 +674,7 @@ def last_commit(repo, rev, path): last_commit(repo, 'master', 'git/test/test_base.py') # end for each repository type # end for each iteration + + def test_remote_method(self): + self.failUnlessRaises(ValueError, self.rorepo.remote, 'foo-blue') + assert isinstance(self.rorepo.remote(name='origin'), Remote) From 27b4efed7a435153f18598796473b3fba06c513d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 10:14:15 +0100 Subject: [PATCH 0071/2790] Added assertion to better detect diff issues. Helps fixing #35 Also, the production status was changed to 'stable', which should have been done much earlier. --- git/diff.py | 1 + git/remote.py | 2 +- git/test/test_diff.py | 2 +- setup.py | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/git/diff.py b/git/diff.py index 3c4e8529f..b59c264c0 100644 --- a/git/diff.py +++ b/git/diff.py @@ -302,6 +302,7 @@ def _index_from_patch_format(cls, repo, stream): diff_header = cls.re_header.match for diff in ('\n' + text).split('\ndiff --git')[1:]: header = diff_header(diff) + assert header is not None, "Failed to parse diff header from " % diff a_path, b_path, similarity_index, rename_from, rename_to, \ old_mode, new_mode, new_file_mode, deleted_file_mode, \ diff --git a/git/remote.py b/git/remote.py index deddd1f41..ce0ed363f 100644 --- a/git/remote.py +++ b/git/remote.py @@ -404,7 +404,7 @@ def exists(self): self.config_reader.get('url') return True except cp.NoOptionError: - # we have the section at least ... + # we have the section at least ... return True except cp.NoSectionError: return False diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 3453f6a8a..c5183089f 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -80,7 +80,7 @@ def test_diff_interface(self): for other in (None, commit.Index, commit.parents[0]): for paths in (None, "CHANGES", ("CHANGES", "lib")): for create_patch in range(2): - diff_index = diff_item.diff(other, paths, create_patch) + diff_index = diff_item.diff(other=other, paths=paths, create_patch=create_patch) assert isinstance(diff_index, DiffIndex) if diff_index: diff --git a/setup.py b/setup.py index 0baf477bf..16a47526d 100755 --- a/setup.py +++ b/setup.py @@ -97,8 +97,8 @@ def _stamp_version(filename): # "Development Status :: 1 - Planning", # "Development Status :: 2 - Pre-Alpha", # "Development Status :: 3 - Alpha", - "Development Status :: 4 - Beta", - # "Development Status :: 5 - Production/Stable", + # "Development Status :: 4 - Beta", + "Development Status :: 5 - Production/Stable", # "Development Status :: 6 - Mature", # "Development Status :: 7 - Inactive", "Environment :: Console", From 987f9bbd08446de3f9d135659f2e36ad6c9d14fb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 11:13:41 +0100 Subject: [PATCH 0072/2790] Added support for rename detection in raw mode (which is the default). Fixes #36 --- doc/source/changes.rst | 1 + git/diff.py | 14 ++++++++------ git/test/fixtures/diff_rename_raw | 1 + git/test/test_diff.py | 9 +++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 git/test/fixtures/diff_rename_raw diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 4983b3d04..bd7687400 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -5,6 +5,7 @@ Changelog 0.3.5 - Bugfixes ================ * push/pull/fetch operations will not block anymore +* diff() can now properly detect renames, both in patch and raw format. Previously it only worked when create_patch was True. * A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+ 0.3.4 - Python 3 Support diff --git a/git/diff.py b/git/diff.py index b59c264c0..24e47bad9 100644 --- a/git/diff.py +++ b/git/diff.py @@ -73,9 +73,9 @@ def diff(self, other=Index, paths=None, create_patch=False, **kwargs): args.append("--abbrev=40") # we need full shas args.append("--full-index") # get full index paths, not only filenames + args.append("-M") # check for renames, in both formats if create_patch: args.append("-p") - args.append("-M") # check for renames else: args.append("--raw") @@ -318,14 +318,11 @@ def _index_from_patch_format(cls, repo, stream): @classmethod def _index_from_raw_format(cls, repo, stream): """Create a new DiffIndex from the given stream which must be in raw format. - :note: - This format is inherently incapable of detecting renames, hence we only - modify, delete and add files :return: git.DiffIndex""" # handles # :100644 100644 687099101... 37c5e30c8... M .gitignore index = DiffIndex() - for line in stream: + for line in stream.readlines(): line = line.decode(defenc) if not line.startswith(":"): continue @@ -336,6 +333,8 @@ def _index_from_raw_format(cls, repo, stream): b_path = path deleted_file = False new_file = False + rename_from = None + rename_to = None # NOTE: We cannot conclude from the existance of a blob to change type # as diffs with the working do not have blobs yet @@ -345,10 +344,13 @@ def _index_from_raw_format(cls, repo, stream): elif change_type == 'A': a_blob_id = None new_file = True + elif change_type[0] == 'R': # parses RXXX, where XXX is a confidence value + a_path, b_path = path.split('\t', 1) + rename_from, rename_to = a_path, b_path # END add/remove handling diff = Diff(repo, a_path, b_path, a_blob_id, b_blob_id, old_mode, new_mode, - new_file, deleted_file, None, None, '') + new_file, deleted_file, rename_from, rename_to, '') index.append(diff) # END for each line diff --git a/git/test/fixtures/diff_rename_raw b/git/test/fixtures/diff_rename_raw new file mode 100644 index 000000000..92d06d22e --- /dev/null +++ b/git/test/fixtures/diff_rename_raw @@ -0,0 +1 @@ +:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 R100 this that diff --git a/git/test/test_diff.py b/git/test/test_diff.py index c5183089f..ce0f64f22 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -56,6 +56,15 @@ def test_diff_with_rename(self): assert_equal(diff.rename_from, 'AUTHORS') assert_equal(diff.rename_to, 'CONTRIBUTORS') + output = StringProcessAdapter(fixture('diff_rename_raw')) + diffs = Diff._index_from_raw_format(self.rorepo, output.stdout) + assert len(diffs) == 1 + diff = diffs[0] + assert diff.renamed + assert diff.rename_from == 'this' + assert diff.rename_to == 'that' + assert len(list(diffs.iter_change_type('R'))) == 1 + def test_diff_patch_format(self): # test all of the 'old' format diffs for completness - it should at least # be able to deal with it From de4cfcc4a1fcb24b72a31c5feff8c67d2ff930fc Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 11:45:21 +0100 Subject: [PATCH 0073/2790] Added test to verify blame commits can have multiple lines. See #47 --- git/test/test_repo.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index e0be20740..9755ea1e8 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -299,12 +299,16 @@ def test_should_display_blame_information(self, git): def test_blame_real(self): c = 0 + nml = 0 # amount of multi-lines per blame for item in self.rorepo.head.commit.tree.traverse( predicate=lambda i, d: i.type == 'blob' and i.path.endswith('.py')): c += 1 - self.rorepo.blame(self.rorepo.head, item.path) + + for b in self.rorepo.blame(self.rorepo.head, item.path): + nml += int(len(b[1]) > 1) # END for each item to traverse - assert c + assert c, "Should have executed at least one blame command" + assert nml, "There should at least be one blame commit that contains multiple lines" def test_untracked_files(self): base = self.rorepo.working_tree_dir From 46889d1dce4506813206a8004f6c3e514f22b679 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 12:10:49 +0100 Subject: [PATCH 0074/2790] Auto-update odb caches after fetch or pull. Fixes #34 --- doc/source/changes.rst | 1 + git/remote.py | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index bd7687400..b4535a69d 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -6,6 +6,7 @@ Changelog ================ * push/pull/fetch operations will not block anymore * diff() can now properly detect renames, both in patch and raw format. Previously it only worked when create_patch was True. +* repo.odb.update_cache() is now called automatically after fetch and pull operations. In case you did that in your own code, you might want to remove your line to prevent a double-update that causes unnecessary IO. * A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+ 0.3.4 - Python 3 Support diff --git a/git/remote.py b/git/remote.py index ce0ed363f..1500f3d15 100644 --- a/git/remote.py +++ b/git/remote.py @@ -610,7 +610,9 @@ def fetch(self, refspec=None, progress=None, **kwargs): args = [refspec] proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, v=True, **kwargs) - return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) + res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) + self.repo.odb.update_cache() + return res def pull(self, refspec=None, progress=None, **kwargs): """Pull changes from the given branch, being the same as a fetch followed @@ -622,7 +624,9 @@ def pull(self, refspec=None, progress=None, **kwargs): :return: Please see 'fetch' method """ kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) - return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) + res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) + self.repo.odb.update_cache() + return res def push(self, refspec=None, progress=None, **kwargs): """Push changes from source branch in refspec to target branch in refspec. From e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 12:19:56 +0100 Subject: [PATCH 0075/2790] Fixed PY3 support. Apparently, thanks to an incorrect version check, PY3 ended up using a git command object database by default. This is now fixed. Additionally, the update_cache code was adjusted to check for method-existence, as it's valid to use object databases which simply don't have a caching mechanism (like the git command object database) --- git/remote.py | 6 ++++-- git/repo/base.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/git/remote.py b/git/remote.py index 1500f3d15..746a78199 100644 --- a/git/remote.py +++ b/git/remote.py @@ -611,7 +611,8 @@ def fetch(self, refspec=None, progress=None, **kwargs): proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, v=True, **kwargs) res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) - self.repo.odb.update_cache() + if hasattr(self.repo.odb, 'update_cache'): + self.repo.odb.update_cache() return res def pull(self, refspec=None, progress=None, **kwargs): @@ -625,7 +626,8 @@ def pull(self, refspec=None, progress=None, **kwargs): kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) - self.repo.odb.update_cache() + if hasattr(self.repo.odb, 'update_cache'): + self.repo.odb.update_cache() return res def push(self, refspec=None, progress=None, **kwargs): diff --git a/git/repo/base.py b/git/repo/base.py index 7bd2be48c..a84f617d0 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -59,7 +59,7 @@ import re DefaultDBType = GitDB -if sys.version_info[1] < 5: # python 2.4 compatiblity +if sys.version_info[:2] < (2, 5): # python 2.4 compatiblity DefaultDBType = GitCmdObjectDB # END handle python 2.4 From fc94b89dabd9df49631cbf6b18800325f3521864 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 12:29:57 +0100 Subject: [PATCH 0076/2790] And finally, PY3 support should be restored. Forgot to fix the test, which used the same broken version_info condition --- git/test/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 9755ea1e8..9d9f727f6 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -620,7 +620,7 @@ def test_rev_parse(self): def test_repo_odbtype(self): target_type = GitDB - if sys.version_info[1] < 5: + if sys.version_info[:2] < (2, 5): target_type = GitCmdObjectDB assert isinstance(self.rorepo.odb, target_type) From b08651e5ae2bffef5e4fb44fbdd7d467715e3b73 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 17:07:01 +0100 Subject: [PATCH 0077/2790] Improved handling of name-resolution, which will not mangle names anymore. Previously, an unresolvable ref name like HEAD would end up as HEX and was presented as BadObject error, even though that exception is for invalid shas only. Now BadName is thrown, which converts into a more useful error message. Improves #105 --- git/repo/fun.py | 9 ++++++--- git/test/test_repo.py | 27 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/git/repo/fun.py b/git/repo/fun.py index 233666c93..f83422600 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -2,7 +2,10 @@ import os from string import digits -from gitdb.exc import BadObject +from gitdb.exc import ( + BadObject, + BadName +) from git.refs import SymbolicReference from git.objects import Object from gitdb.util import ( @@ -83,7 +86,7 @@ def name_to_object(repo, name, return_ref=False): :return: object specified by the given name, hexshas ( short and long ) as well as references are supported :param return_ref: if name specifies a reference, we will return the reference - instead of the object. Otherwise it will raise BadObject + instead of the object. Otherwise it will raise BadObject or BadName """ hexsha = None @@ -119,7 +122,7 @@ def name_to_object(repo, name, return_ref=False): # tried everything ? fail if hexsha is None: - raise BadObject(name) + raise BadName(name) # END assert hexsha was found return Object.new_from_sha(repo, hex_to_bin(hexsha)) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 9d9f727f6..1b3f3ed4c 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -26,8 +26,10 @@ GitDB, Submodule, GitCmdObjectDB, - Remote + Remote, + BadName ) +from git.repo.fun import touch from git.util import join_path_native from git.exc import BadObject from gitdb.util import bin_to_hex @@ -35,6 +37,7 @@ string_types, defenc ) +from gitdb.test.lib import with_rw_directory import os import sys @@ -682,3 +685,25 @@ def last_commit(repo, rev, path): def test_remote_method(self): self.failUnlessRaises(ValueError, self.rorepo.remote, 'foo-blue') assert isinstance(self.rorepo.remote(name='origin'), Remote) + + @with_rw_directory + def test_empty_repo(self, rw_dir): + """Assure we can handle empty repositories""" + r = Repo.init(rw_dir, mkdir=False) + # It's ok not to be able to iterate a commit, as there is none + self.failUnlessRaises(ValueError, r.iter_commits) + assert r.active_branch.name == 'master' + assert not r.active_branch.is_valid(), "Branch is yet to be born" + + # actually, when trying to create a new branch without a commit, git itself fails + # We should, however, not fail ungracefully + self.failUnlessRaises(BadName, r.create_head, 'foo') + + new_file_path = os.path.join(rw_dir, "new_file.ext") + touch(new_file_path) + r.index.add([new_file_path]) + r.index.commit("initial commit") + + # Now a branch should be creatable + nb = r.create_head('foo') + assert nb.is_valid() From 723d20f1156530b122e9785f5efc6ebf2b838fe0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 17:53:18 +0100 Subject: [PATCH 0078/2790] Improved empty-repo test Helps to clarify #55 --- git/test/test_repo.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 1b3f3ed4c..dddfcd906 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -89,7 +89,7 @@ def test_tree_from_revision(self): assert self.rorepo.tree(tree) == tree # try from invalid revision that does not exist - self.failUnlessRaises(BadObject, self.rorepo.tree, 'hello world') + self.failUnlessRaises(BadName, self.rorepo.tree, 'hello world') def test_commit_from_revision(self): commit = self.rorepo.commit('0.1.4') @@ -533,7 +533,7 @@ def test_rev_parse(self): obj = self._assert_rev_parse(path_section) assert obj.type == ref.object.type num_resolved += 1 - except BadObject: + except (BadName, BadObject): print("failed on %s" % path_section) # is fine, in case we have something like 112, which belongs to remotes/rname/merge-requests/112 pass @@ -698,6 +698,9 @@ def test_empty_repo(self, rw_dir): # actually, when trying to create a new branch without a commit, git itself fails # We should, however, not fail ungracefully self.failUnlessRaises(BadName, r.create_head, 'foo') + self.failUnlessRaises(BadName, r.create_head, 'master') + # It's expected to not be able to access a tree + self.failUnlessRaises(ValueError, r.tree) new_file_path = os.path.join(rw_dir, "new_file.ext") touch(new_file_path) From 1d52f98935b70cda4eede4d52cdad4e3b886f639 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 17:58:58 +0100 Subject: [PATCH 0079/2790] Updated submodule to latest commit, hopefully fixing travis --- git/ext/gitdb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/ext/gitdb b/git/ext/gitdb index ff7615321..f2233fbf4 160000 --- a/git/ext/gitdb +++ b/git/ext/gitdb @@ -1 +1 @@ -Subproject commit ff7615321ee31d981a171f7677a56a971c554059 +Subproject commit f2233fbf40f3f69309ce5cc714e99fcbdcd33ec3 From 1531d789df97dbf1ed3f5b0340bbf39918d9fe48 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 8 Jan 2015 18:09:38 +0100 Subject: [PATCH 0080/2790] Now finally, tests should be working on travis too. Now handling the new exception BadName as well --- git/refs/symbolic.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index cbb129d47..b5a81ee01 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -8,7 +8,10 @@ assure_directory_exists ) -from gitdb.exc import BadObject +from gitdb.exc import ( + BadObject, + BadName +) from gitdb.util import ( join, dirname, @@ -201,7 +204,7 @@ def set_commit(self, commit, logmsg=None): else: try: invalid_type = self.repo.rev_parse(commit).type != Commit.type - except BadObject: + except (BadObject, BadName): raise ValueError("Invalid object: %s" % commit) # END handle exception # END verify type @@ -283,7 +286,7 @@ def set_reference(self, ref, logmsg=None): try: obj = self.repo.rev_parse(ref + "^{}") # optionally deref tags write_value = obj.hexsha - except BadObject: + except (BadObject, BadName): raise ValueError("Could not extract object from %s" % ref) # END end try string else: From 17f5d13a7a741dcbb2a30e147bdafe929cff4697 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 9 Jan 2015 12:49:03 +0100 Subject: [PATCH 0081/2790] Added test to assure blame can deal with binary patches. Fixes #74 --- git/cmd.py | 10 +++++++-- git/repo/base.py | 36 ++++++++++++++++++++++++++------- git/test/fixtures/blame_binary | Bin 0 -> 14807 bytes git/test/test_repo.py | 13 ++++++------ 4 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 git/test/fixtures/blame_binary diff --git a/git/cmd.py b/git/cmd.py index d0190adfb..668d8f4a4 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -31,7 +31,7 @@ ) execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', - 'with_exceptions', 'as_process', + 'with_exceptions', 'as_process', 'stdout_as_string', 'output_stream') log = logging.getLogger('git.cmd') @@ -411,6 +411,7 @@ def execute(self, command, with_exceptions=True, as_process=False, output_stream=None, + stdout_as_string=True, **subprocess_kwargs ): """Handles executing the command on the shell and consumes and returns @@ -454,6 +455,11 @@ def execute(self, command, output pipe to the given output stream directly. Judging from the implementation, you shouldn't use this flag ! + :param stdout_as_string: + if False, the commands standard output will be bytes. Otherwise, it will be + decoded into a string using the default encoding (usually utf-8). + The latter can fail, if the output contains binary data. + :param subprocess_kwargs: Keyword arguments to be passed to subprocess.Popen. Please note that some of the valid kwargs are already set by this method, the ones you @@ -545,7 +551,7 @@ def execute(self, command, else: raise GitCommandError(command, status, stderr_value) - if isinstance(stdout_value, bytes): # could also be output_stream + if isinstance(stdout_value, bytes) and stdout_as_string: # could also be output_stream stdout_value = stdout_value.decode(defenc) # Allow access to the command's status code diff --git a/git/repo/base.py b/git/repo/base.py index a84f617d0..dbca46979 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -587,14 +587,28 @@ def blame(self, rev, file): A list of tuples associating a Commit object with a list of lines that changed within the given commit. The Commit objects will be given in order of appearance.""" - data = self.git.blame(rev, '--', file, p=True) + data = self.git.blame(rev, '--', file, p=True, stdout_as_string=False) commits = dict() blames = list() info = None - for line in data.splitlines(False): - parts = self.re_whitespace.split(line, 1) - firstpart = parts[0] + keepends = True + for line in data.splitlines(keepends): + try: + line = line.rstrip().decode(defenc) + except UnicodeDecodeError: + firstpart = '' + is_binary = True + else: + # As we don't have an idea when the binary data ends, as it could contain multiple newlines + # in the process. So we rely on being able to decode to tell us what is is. + # This can absolutely fail even on text files, but even if it does, we should be fine treating it + # as binary instead + parts = self.re_whitespace.split(line, 1) + firstpart = parts[0] + is_binary = False + # end handle decode of line + if self.re_hexsha_only.search(firstpart): # handles # 634396b2f541a9f2d58b00be1a07f0c358b999b3 1 1 7 - indicates blame-data start @@ -651,10 +665,18 @@ def blame(self, rev, file): message=info['summary']) commits[sha] = c # END if commit objects needs initial creation - m = self.re_tab_full_line.search(line) - text, = m.groups() + if not is_binary: + if line and line[0] == '\t': + line = line[1:] + else: + # NOTE: We are actually parsing lines out of binary data, which can lead to the + # binary being split up along the newline separator. We will append this to the blame + # we are currently looking at, even though it should be concatenated with the last line + # we have seen. + pass + # end handle line contents blames[-1][0] = c - blames[-1][1].append(text) + blames[-1][1].append(line) info = {'id': sha} # END if we collected commit info # END distinguish filename,summary,rest diff --git a/git/test/fixtures/blame_binary b/git/test/fixtures/blame_binary new file mode 100644 index 0000000000000000000000000000000000000000..db78205b6a690ebe5a8a99ac5b9844c8ce2d3d86 GIT binary patch literal 14807 zcmeHOZ)_Y#6`xDuCUKM4LH$q!q1zBQfh4}Ob3UJyG_q4)*(h;vW1EIb)pT!f&$r}m z_qx01*d;-Z+#sDU7H)w`RRyXLNR$t>A1V|OL{3^MhA#xv4+TXi;-Ahmk*rd+X$dvI zw>#^*TQ|m)Q2DZB&!69$_ujmDGdCm6>?mriD;rCwiELLQ6HjQJv3NEfOC*%+z7D0U zvojl0dXi~1DRtm4*{qbDoM}lzT3WFkT`{ELoUY{sd2d0{^U{Izgk>6f!R#F++^(91 zgFb_!7c{9O-Wlue>52FBERmm*cE>tmv1afVbjQ(_x3E;RLL)VvU^{g+ep7a-P*AK1 zDXkmGn$u><$WS4x=QTrtnO4zm-uT-OZhp9)vB+A+Cf6{=S`bfwaE?hRG4^Rh8IkkB zzAvR7OCA3*Q5!>~5q=~hJ>zJA^WoHq;YJo$UTUO?<{3<3O^B3J;M~#19k1-+Mt!rN zL1$2rqRt=?Ugs6PbRCGXt%N&JWd`z)0UGAiBm#2l%{9VZ|&W${`CkkmZ z&x?+=Oy4fZ(>(UgBV4bK?DB0x5%QyEZB&=rmxO%1KEgqL8%U7|oadF5?2{!=Urg{5 zuGdHYYgSgf_I660%^QU#$~ey`j#488y*(*;ttSNwVSmQfq-rIa^@W0I_>`c&3y>%8 zAX^Icy`j4LK(oqQ6^|Z1b|lq**k94$4wu&-HsKyg3>A5$Ue|W4x-JV65@|(Fdi`($ z_z8du$Y+t$FXvvw$qvTakhjJWLA)E~K|~5$MI_p15$pX5*buJn^V)470&GE)5H}%4 zOSTow>*;7_BA)@KfJN1{xAWGgYOU;WtcllIZruU;T7 z#hW*-p1n)zf_~aVE+En@`6A-~JNWz5f3t%|fMz+3I*mSyw!-S@r9>tL-^rMY|s$7ZBRsVs*_Xml!h&$|4{S6KBh2oRyx%BeTzso9GpFaLs$UMa}asRbGRZgV-W z5oaZJZGWoTGW~6@yw{U{Q&tDA$(51oa^=8ps(<=$aS?}l%G94y+G<(re&ls zUL$YAUDAh=}f)%mXix(?!r9AIhL`5bSD%0HeOZ0`XeBjwxDsE0_9LEl zr0~S+uxuE@m4O@N*Zrwm<$>9ja~n}vNzGyqdLMtSO5L7WY&!tH#kPZP+Uur=+_c|K zA4ZD4OmF))*!zYS+ioJC$q{k>?=Ut;$LjOfsI-Ghzo!!JMA-ZsmHMc3kxF#yJ^w07 zmZ_d(MTIVRZB@5z6PJOHYLcUC88(<#CUCRgDd9rY_ECqAG{x2=Tq2I?8BJ1irmkwX zl*P9OMNiB$G)XZsK6Fl*l447WHCifYhGVb(!XqIiaN!}0@fwnLw%I!+-IjD?Ov&q+ zJ!r+X2h}FbqPESf)MoE-BaCYM7!7ty-DvRRNF?#41q~<72pUMbr=n1w)6mf^39h)@ zNH^~k2$S3<+=tvF?nHWl5l9tiUWhz(oJGc4Bdwd(Z7Wtsa9}{^- zdfqGw0n1>z+JrH^z^g!r=&;y|dLJx!<2t5#bAoM`! zfzShY_Q2NdY^47yeM5ai9?z$GIXwbU)RSDzo#dk>#mcZptmKSG&uEraWHY_=HLd&h zfa8G%h-~sYj+fjJnITP<9MF`-V-q&RtU=JVaowTv36!%%ybo})1fKvbXa!qyD|0}# zx*`ys5~u~V?pnHrvrVwma@Z(a&)Ff}D3%|#Ra0xQZh%$Rn&T6w!3$d&RwXH zjG$3=DuBNMoLw7X>z@7TFx8VxJ0&;_qUp(A+7n<5F|7JNbOKaP2b@aEc)-w}al1^W@Z>rvzcr>GpMRAaA8EPJLEo!TlrWq<;?(OZ^i&+%a95tFQ>G=$yz5SYf(lLwt z5r=p2IFE5xiYMY}-9cr#G#YJhr+?d0qiU4VGT5$uVr{$4nG7$f#5!DWjIf2fOEW)K zw}@hwaqkis_t$7%bl)g7avh_kR%P7H$MC|Ywor4vd>yZ8_1F8FUBU>zId2bX*!0}3 js)6EdgD%P20lh73Y4h^8Eq}xEx2k2^B&G<<>COKE)~al{ literal 0 HcmV?d00001 diff --git a/git/test/test_repo.py b/git/test/test_repo.py index dddfcd906..e2342b3cc 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -33,10 +33,7 @@ from git.util import join_path_native from git.exc import BadObject from gitdb.util import bin_to_hex -from git.compat import ( - string_types, - defenc -) +from git.compat import string_types from gitdb.test.lib import with_rw_directory import os @@ -275,7 +272,7 @@ def test_archive(self): @patch.object(Git, '_call_process') def test_should_display_blame_information(self, git): - git.return_value = fixture('blame').decode(defenc) + git.return_value = fixture('blame') b = self.rorepo.blame('master', 'lib/git.py') assert_equal(13, len(b)) assert_equal(2, len(b[0])) @@ -283,7 +280,6 @@ def test_should_display_blame_information(self, git): assert_equal(hash(b[0][0]), hash(b[9][0])) c = b[0][0] assert_true(git.called) - assert_equal(git.call_args, (('blame', 'master', '--', 'lib/git.py'), {'p': True})) assert_equal('634396b2f541a9f2d58b00be1a07f0c358b999b3', c.hexsha) assert_equal('Tom Preston-Werner', c.author.name) @@ -300,6 +296,11 @@ def test_should_display_blame_information(self, git): assert_true(isinstance(tlist[0], string_types)) assert_true(len(tlist) < sum(len(t) for t in tlist)) # test for single-char bug + # BINARY BLAME + git.return_value = fixture('blame_binary') + blames = self.rorepo.blame('master', 'rps') + assert len(blames) == 2 + def test_blame_real(self): c = 0 nml = 0 # amount of multi-lines per blame From 0d9f1495004710b77767393a29f33df76d7b0fb5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 9 Jan 2015 13:15:09 +0100 Subject: [PATCH 0082/2790] Added test to verify binary diffs are working as well. Related to #74 --- git/test/fixtures/diff_patch_binary | 3 +++ git/test/fixtures/diff_raw_binary | 1 + git/test/test_diff.py | 10 ++++++++++ 3 files changed, 14 insertions(+) create mode 100644 git/test/fixtures/diff_patch_binary create mode 100644 git/test/fixtures/diff_raw_binary diff --git a/git/test/fixtures/diff_patch_binary b/git/test/fixtures/diff_patch_binary new file mode 100644 index 000000000..c92ccd6eb --- /dev/null +++ b/git/test/fixtures/diff_patch_binary @@ -0,0 +1,3 @@ +diff --git a/rps b/rps +index f4567df37451b230b1381b1bc9c2bcad76e08a3c..736bd596a36924d30b480942e9475ce0d734fa0d 100755 +Binary files a/rps and b/rps differ diff --git a/git/test/fixtures/diff_raw_binary b/git/test/fixtures/diff_raw_binary new file mode 100644 index 000000000..d4673fa41 --- /dev/null +++ b/git/test/fixtures/diff_raw_binary @@ -0,0 +1 @@ +:100755 100755 f4567df37451b230b1381b1bc9c2bcad76e08a3c 736bd596a36924d30b480942e9475ce0d734fa0d M rps diff --git a/git/test/test_diff.py b/git/test/test_diff.py index ce0f64f22..ebf9527a9 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -65,6 +65,16 @@ def test_diff_with_rename(self): assert diff.rename_to == 'that' assert len(list(diffs.iter_change_type('R'))) == 1 + def test_binary_diff(self): + for method, file_name in ((Diff._index_from_patch_format, 'diff_patch_binary'), + (Diff._index_from_raw_format, 'diff_raw_binary')): + res = method(None, StringProcessAdapter(fixture(file_name)).stdout) + assert len(res) == 1 + assert len(list(res.iter_change_type('M'))) == 1 + if res[0].diff: + assert res[0].diff == "Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text" + # end for each method to test + def test_diff_patch_format(self): # test all of the 'old' format diffs for completness - it should at least # be able to deal with it From 18caa610d50b92331485013584f5373804dd0416 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 9 Jan 2015 13:15:09 +0100 Subject: [PATCH 0083/2790] Added test to verify binary diffs are working as well. Related to #74 --- git/diff.py | 30 ++++++--- git/objects/base.py | 3 +- git/test/fixtures/diff_index_patch | 100 +++++++++++++++++++++++++++++ git/test/test_diff.py | 12 ++++ 4 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 git/test/fixtures/diff_index_patch diff --git a/git/diff.py b/git/diff.py index 24e47bad9..f10bd1cdd 100644 --- a/git/diff.py +++ b/git/diff.py @@ -183,8 +183,8 @@ class Diff(object): # precompiled regex re_header = re.compile(r""" - #^diff[ ]--git - [ ]a/(?P.+?)[ ]b/(?P.+?)\n + ^diff[ ]--git + [ ](?:a/)?(?P.+?)[ ](?:b/)?(?P.+?)\n (?:^similarity[ ]index[ ](?P\d+)%\n ^rename[ ]from[ ](?P\S+)\n ^rename[ ]to[ ](?P\S+)(?:\n|$))? @@ -298,20 +298,30 @@ def _index_from_patch_format(cls, repo, stream): # for now, we have to bake the stream text = stream.read().decode(defenc) index = DiffIndex() - - diff_header = cls.re_header.match - for diff in ('\n' + text).split('\ndiff --git')[1:]: - header = diff_header(diff) - assert header is not None, "Failed to parse diff header from " % diff - + previous_header = None + for header in cls.re_header.finditer(text): a_path, b_path, similarity_index, rename_from, rename_to, \ old_mode, new_mode, new_file_mode, deleted_file_mode, \ a_blob_id, b_blob_id, b_mode = header.groups() new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode) + # Our only means to find the actual text is to see what has not been matched by our regex, + # and then retro-actively assin it to our index + if previous_header is not None: + index[-1].diff = text[previous_header.end():header.start()] + # end assign actual diff + + # Make sure the mode is set if the path is set. Otherwise the resulting blob is invalid + # We just use the one mode we should have parsed index.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id, - old_mode or deleted_file_mode, new_mode or new_file_mode or b_mode, - new_file, deleted_file, rename_from, rename_to, diff[header.end():])) + old_mode or deleted_file_mode or b_mode, new_mode or new_file_mode or b_mode, + new_file, deleted_file, rename_from, rename_to, None)) + + previous_header = header + # end for each header we parse + if index: + index[-1].diff = text[header.end():] + # end assign last diff return index diff --git a/git/objects/base.py b/git/objects/base.py index 3f595d9dc..eb59b0a91 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -158,7 +158,8 @@ def _set_cache_(self, attr): if attr in IndexObject.__slots__: # they cannot be retrieved lateron ( not without searching for them ) raise AttributeError( - "path and mode attributes must have been set during %s object creation" % type(self).__name__) + "Attribute '%s' unset: path and mode attributes must have been set during %s object creation" + % (attr, type(self).__name__)) else: super(IndexObject, self)._set_cache_(attr) # END hanlde slot attribute diff --git a/git/test/fixtures/diff_index_patch b/git/test/fixtures/diff_index_patch new file mode 100644 index 000000000..a5a8cff24 --- /dev/null +++ b/git/test/fixtures/diff_index_patch @@ -0,0 +1,100 @@ +diff --git a/etc/sublime-text/git-python.sublime-project b/etc/sublime-text/git-python.sublime-project +index 3dab9f6562ecb0408d9ece8dd63cc4461d280113..9c99a2cff7dc918fbbb61cd57d5d98750a1ef6c5 100644 +--- a/etc/sublime-text/git-python.sublime-project ++++ b/etc/sublime-text/git-python.sublime-project +@@ -23,7 +23,7 @@ + ] + }, + // GITDB +- //////// ++ // //////// + { + "follow_symlinks": true, + "path": "../../git/ext/gitdb", +@@ -42,8 +42,8 @@ + ".tox", + ] + }, +- // // SMMAP +- // //////// ++ // // // SMMAP ++ // // //////// + { + "follow_symlinks": true, + "path": "../../git/ext/gitdb/gitdb/ext/smmap", +diff --git a/git/diff.py b/git/diff.py +index 24e47bad9d79534d3cf474fec4f79e6fef122bb1..c1ad532e0217e293906bcfef43c523d6a8e21568 100644 +--- a/git/diff.py ++++ b/git/diff.py +@@ -302,13 +302,21 @@ class Diff(object): + diff_header = cls.re_header.match + for diff in ('\n' + text).split('\ndiff --git')[1:]: + header = diff_header(diff) +- assert header is not None, "Failed to parse diff header from " % diff ++ assert header is not None, "Failed to parse diff header from '%s'" % diff + + a_path, b_path, similarity_index, rename_from, rename_to, \ + old_mode, new_mode, new_file_mode, deleted_file_mode, \ + a_blob_id, b_blob_id, b_mode = header.groups() + new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode) + ++ # if a_path.startswith('a/'): ++ # a_path = a_path[2:] ++ # if b_path.startswith('b/'): ++ # b_path = b_path[2:] ++ ++ for item in (a_path, b_path, a_blob_id, b_blob_id, old_mode, deleted_file_mode, new_mode, new_file_mode, b_mode, new_file, deleted_file, rename_from, rename_to, diff[header.end():]): ++ print( "####") ++ print(item) + index.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id, + old_mode or deleted_file_mode, new_mode or new_file_mode or b_mode, + new_file, deleted_file, rename_from, rename_to, diff[header.end():])) +diff --git a/git/ext/gitdb b/git/ext/gitdb +index f2233fbf40f3f69309ce5cc714e99fcbdcd33ec3..a88a777df3909a61be97f1a7b1194dad6de25702 160000 +--- a/git/ext/gitdb ++++ b/git/ext/gitdb +@@ -1 +1 @@ +-Subproject commit f2233fbf40f3f69309ce5cc714e99fcbdcd33ec3 ++Subproject commit a88a777df3909a61be97f1a7b1194dad6de25702-dirty +diff --git a/git/test/fixtures/diff_patch_binary b/git/test/fixtures/diff_patch_binary +new file mode 100644 +index 0000000000000000000000000000000000000000..c92ccd6ebc92a871d38ad7cb8a48bcdb1a5dbc33 +--- /dev/null ++++ b/git/test/fixtures/diff_patch_binary +@@ -0,0 +1,3 @@ ++diff --git a/rps b/rps ++index f4567df37451b230b1381b1bc9c2bcad76e08a3c..736bd596a36924d30b480942e9475ce0d734fa0d 100755 ++Binary files a/rps and b/rps differ +diff --git a/git/test/fixtures/diff_raw_binary b/git/test/fixtures/diff_raw_binary +new file mode 100644 +index 0000000000000000000000000000000000000000..d4673fa41ee8413384167fc7b9f25e4daf18a53a +--- /dev/null ++++ b/git/test/fixtures/diff_raw_binary +@@ -0,0 +1 @@ ++:100755 100755 f4567df37451b230b1381b1bc9c2bcad76e08a3c 736bd596a36924d30b480942e9475ce0d734fa0d M rps +diff --git a/git/test/test_diff.py b/git/test/test_diff.py +index ce0f64f2261bd8de063233108caac1f26742c1fd..4de26f8884fd048ac7f10007f2bf7c7fa3fa60f4 100644 +--- a/git/test/test_diff.py ++++ b/git/test/test_diff.py +@@ -65,6 +65,21 @@ class TestDiff(TestBase): + assert diff.rename_to == 'that' + assert len(list(diffs.iter_change_type('R'))) == 1 + ++ def test_binary_diff(self): ++ for method, file_name in ((Diff._index_from_patch_format, 'diff_patch_binary'), ++ (Diff._index_from_raw_format, 'diff_raw_binary')): ++ res = method(None, StringProcessAdapter(fixture(file_name)).stdout) ++ assert len(res) == 1 ++ assert len(list(res.iter_change_type('M'))) == 1 ++ if res[0].diff: ++ assert res[0].diff == "Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text" ++ assert isinstance(str(res[0]), str), "This call should just work" ++ # end for each method to test ++ ++ def test_diff_index(self): ++ res = self.rorepo.index.diff('17f5d13a7a741dcbb2a30e147bdafe929cff4697', create_patch=True) ++ assert len(res) == 3 ++ + def test_diff_patch_format(self): + # test all of the 'old' format diffs for completness - it should at least + # be able to deal with it diff --git a/git/test/test_diff.py b/git/test/test_diff.py index ebf9527a9..c59117efc 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -73,8 +73,20 @@ def test_binary_diff(self): assert len(list(res.iter_change_type('M'))) == 1 if res[0].diff: assert res[0].diff == "Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text" + assert isinstance(str(res[0]), str), "This call should just work" # end for each method to test + def test_diff_index(self): + output = StringProcessAdapter(fixture('diff_index_patch')) + res = Diff._index_from_patch_format(None, output.stdout) + assert len(res) == 6 + for dr in res: + assert dr.diff + # end for each diff + + dr = res[3] + assert dr.diff.endswith("+Binary files a/rps and b/rps differ\n") + def test_diff_patch_format(self): # test all of the 'old' format diffs for completness - it should at least # be able to deal with it From 85a5a8c6a931f8b3a220ed61750d1f9758d0810a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 9 Jan 2015 16:54:33 +0100 Subject: [PATCH 0084/2790] Fixed mode-handling in Diff creation, and added assertions to catch this in future There is still some work todo in terms of how we handle the encoding --- git/diff.py | 7 +++++-- git/test/test_diff.py | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/git/diff.py b/git/diff.py index f10bd1cdd..595a8247a 100644 --- a/git/diff.py +++ b/git/diff.py @@ -217,10 +217,12 @@ def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode, if a_blob_id is None: self.a_blob = None else: + assert self.a_mode self.a_blob = Blob(repo, hex_to_bin(a_blob_id), mode=self.a_mode, path=a_path) if b_blob_id is None: self.b_blob = None else: + assert self.b_mode self.b_blob = Blob(repo, hex_to_bin(b_blob_id), mode=self.b_mode, path=b_path) self.new_file = new_file @@ -313,8 +315,9 @@ def _index_from_patch_format(cls, repo, stream): # Make sure the mode is set if the path is set. Otherwise the resulting blob is invalid # We just use the one mode we should have parsed - index.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id, - old_mode or deleted_file_mode or b_mode, new_mode or new_file_mode or b_mode, + a_mode = old_mode or deleted_file_mode or (a_path and (b_mode or new_mode or new_file_mode)) + b_mode = b_mode or new_mode or new_file_mode or (b_path and a_mode) + index.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id, a_mode, b_mode, new_file, deleted_file, rename_from, rename_to, None)) previous_header = header diff --git a/git/test/test_diff.py b/git/test/test_diff.py index c59117efc..498f05863 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -73,7 +73,7 @@ def test_binary_diff(self): assert len(list(res.iter_change_type('M'))) == 1 if res[0].diff: assert res[0].diff == "Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text" - assert isinstance(str(res[0]), str), "This call should just work" + assert str(res[0]), "This call should just work" # end for each method to test def test_diff_index(self): @@ -82,6 +82,7 @@ def test_diff_index(self): assert len(res) == 6 for dr in res: assert dr.diff + assert str(dr), "Diff to string conversion should be possible" # end for each diff dr = res[3] @@ -129,6 +130,9 @@ def test_diff_interface(self): assert len(diff_set) == 1 assert diff_index[0] == diff_index[0] assert not (diff_index[0] != diff_index[0]) + + for dr in diff_index: + assert str(dr), "Diff to string conversion should be possible" # END diff index checking # END for each patch option # END for each path option From c767b5206f1e9c8536110dda4d515ebb9242bbeb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 9 Jan 2015 17:14:32 +0100 Subject: [PATCH 0085/2790] Now Diff.__str__ works correctly in all python versions. Additionally, unicode handling was improved to the point where we deal with all diff(create_path=True) data as binary. Therefore we don't claim to know all encodings of all textfiles in the world, even though we still assume that everything git throws at us is utf-8 encoded. Fixes #113 --- git/diff.py | 36 +++++++++++++++++++++++++++++------- git/test/test_diff.py | 4 ++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/git/diff.py b/git/diff.py index 595a8247a..dfee00e22 100644 --- a/git/diff.py +++ b/git/diff.py @@ -10,7 +10,10 @@ from .objects.blob import Blob from .objects.util import mode_str_to_int -from git.compat import defenc +from git.compat import ( + defenc, + PY3 +) __all__ = ('Diffable', 'DiffIndex', 'Diff') @@ -194,7 +197,7 @@ class Diff(object): (?:^deleted[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? - """, re.VERBOSE | re.MULTILINE) + """.encode('ascii'), re.VERBOSE | re.MULTILINE) # can be used for comparisons NULL_HEX_SHA = "0" * 40 NULL_BIN_SHA = b"\0" * 20 @@ -280,11 +283,21 @@ def __str__(self): msg += '\nfile renamed to %r' % self.rename_to if self.diff: msg += '\n---' - msg += self.diff + try: + msg += self.diff.decode(defenc) + except UnicodeDecodeError: + msg += 'OMITTED BINARY DATA' + # end handle encoding msg += '\n---' # END diff info - return h + msg + # Python2 sillyness: have to assure we convert our likely to be unicode object to a string with the + # right encoding. Otherwise it tries to convert it using ascii, which may fail ungracefully + res = h + msg + if not PY3: + res = res.encode(defenc) + # end + return res @property def renamed(self): @@ -298,7 +311,7 @@ def _index_from_patch_format(cls, repo, stream): :param stream: result of 'git diff' as a stream (supporting file protocol) :return: git.DiffIndex """ # for now, we have to bake the stream - text = stream.read().decode(defenc) + text = stream.read() index = DiffIndex() previous_header = None for header in cls.re_header.finditer(text): @@ -317,8 +330,17 @@ def _index_from_patch_format(cls, repo, stream): # We just use the one mode we should have parsed a_mode = old_mode or deleted_file_mode or (a_path and (b_mode or new_mode or new_file_mode)) b_mode = b_mode or new_mode or new_file_mode or (b_path and a_mode) - index.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id, a_mode, b_mode, - new_file, deleted_file, rename_from, rename_to, None)) + index.append(Diff(repo, + a_path and a_path.decode(defenc), + b_path and b_path.decode(defenc), + a_blob_id and a_blob_id.decode(defenc), + b_blob_id and b_blob_id.decode(defenc), + a_mode and a_mode.decode(defenc), + b_mode and b_mode.decode(defenc), + new_file, deleted_file, + rename_from and rename_from.decode(defenc), + rename_to and rename_to.decode(defenc), + None)) previous_header = header # end for each header we parse diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 498f05863..42972603e 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -72,7 +72,7 @@ def test_binary_diff(self): assert len(res) == 1 assert len(list(res.iter_change_type('M'))) == 1 if res[0].diff: - assert res[0].diff == "Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text" + assert res[0].diff == b"Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text" assert str(res[0]), "This call should just work" # end for each method to test @@ -86,7 +86,7 @@ def test_diff_index(self): # end for each diff dr = res[3] - assert dr.diff.endswith("+Binary files a/rps and b/rps differ\n") + assert dr.diff.endswith(b"+Binary files a/rps and b/rps differ\n") def test_diff_patch_format(self): # test all of the 'old' format diffs for completness - it should at least From a0cb95c5df7a559633c48f5b0f200599c4a62091 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 9 Jan 2015 17:58:53 +0100 Subject: [PATCH 0086/2790] Added test for complex blame revision query. It works as expected by me at least. Related to #71 --- git/test/fixtures/blame_complex_revision | 177 +++++++++++++++++++++++ git/test/test_repo.py | 7 + 2 files changed, 184 insertions(+) create mode 100644 git/test/fixtures/blame_complex_revision diff --git a/git/test/fixtures/blame_complex_revision b/git/test/fixtures/blame_complex_revision new file mode 100644 index 000000000..e2de6d374 --- /dev/null +++ b/git/test/fixtures/blame_complex_revision @@ -0,0 +1,177 @@ +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 1 1 83 +author Sebastian Thiel +author-mail +author-time 1420715996 +author-tz +0100 +committer Sebastian Thiel +committer-mail +committer-time 1420716149 +committer-tz +0100 +summary Fixed PY3 support. +boundary +filename README.md + ## GitPython +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 2 2 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 3 3 + GitPython is a python library used to interact with git repositories, high-level like git-porcelain, or low-level like git-plumbing. +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 4 4 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 5 5 + It provides abstractions of git objects for easy access of repository data, and additionally allows you to access the git repository more directly using either a pure python implementation, or the faster, but more resource intensive git command implementation. +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 6 6 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 7 7 + The object database implementation is optimized for handling large quantities of objects and large datasets, which is achieved by using low-level structures and data streaming. +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 8 8 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 9 9 + ### REQUIREMENTS +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 10 10 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 11 11 + * Git ( tested with 1.8.3.4 ) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 12 12 + * Python Nose - used for running the tests +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 13 13 + - Tested with nose 1.3.0 +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 14 14 + * Mock by Michael Foord used for tests +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 15 15 + - Tested with 1.0.1 +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 16 16 + * Coverage - used for tests coverage +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 17 17 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 18 18 + The list of dependencies are listed in /requirements.txt and /test-requirements.txt. The installer takes care of installing them for you though. +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 19 19 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 20 20 + ### INSTALL +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 21 21 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 22 22 + [![Latest Version](https://pypip.in/version/GitPython/badge.svg)](https://pypi.python.org/pypi/GitPython/) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 23 23 + [![Supported Python Versions](https://pypip.in/py_versions/GitPython/badge.svg)](https://pypi.python.org/pypi/GitPython/) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 24 24 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 25 25 + If you have downloaded the source code: +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 26 26 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 27 27 + python setup.py install +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 28 28 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 29 29 + or if you want to obtain a copy from the Pypi repository: +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 30 30 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 31 31 + pip install gitpython +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 32 32 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 33 33 + Both commands will install the required package dependencies. +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 34 34 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 35 35 + A distribution package can be obtained for manual installation at: +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 36 36 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 37 37 + http://pypi.python.org/pypi/GitPython +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 38 38 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 39 39 + ### RUNNING TESTS +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 40 40 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 41 41 + The easiest way to run test is by using [tox](https://pypi.python.org/pypi/tox) a wrapper around virtualenv. It will take care of setting up environnements with the proper dependencies installed and execute test commands. To install it simply: +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 42 42 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 43 43 + pip install tox +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 44 44 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 45 45 + Then run: +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 46 46 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 47 47 + tox +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 48 48 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 49 49 + ### SOURCE +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 50 50 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 51 51 + GitPython's git repo is available on GitHub, which can be browsed at [github](https://github.com/gitpython-developers/GitPython) and cloned like that: +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 52 52 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 53 53 + git clone git://github.com/gitpython-developers/GitPython.git git-python +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 54 54 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 55 55 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 56 56 + ### INFRASTRUCTURE +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 57 57 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 58 58 + * [User Documentation](http://gitpython.readthedocs.org) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 59 59 + * [Mailing List](http://groups.google.com/group/git-python) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 60 60 + * [Issue Tracker](https://github.com/gitpython-developers/GitPython/issues) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 61 61 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 62 62 + ### LICENSE +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 63 63 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 64 64 + New BSD License. See the LICENSE file. +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 65 65 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 66 66 + ### DEVELOPMENT STATUS +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 67 67 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 68 68 + [![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg?branch=0.3)](https://travis-ci.org/gitpython-developers/GitPython) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 69 69 + [![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=master)](https://coveralls.io/r/gitpython-developers/GitPython?branch=master) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 70 70 + [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 71 71 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 72 72 + Now that there seems to be a massive user base, this should be motivation enough to let git-python return to a proper state, which means +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 73 73 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 74 74 + * no open pull requests +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 75 75 + * no open issues describing bugs +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 76 76 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 77 77 + #### FUTURE GOALS +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 78 78 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 79 79 + There has been a lot of work in the master branch, which is the direction I want git-python to go. Namely, it should be able to freely mix and match the back-end used, depending on your requirements and environment. +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 80 80 + +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 81 81 + * make new master work similarly to 0.3, but with the option to swap for at least one additional backend +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 82 82 + * make a 1.0 release +e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 83 83 + * add backends as required diff --git a/git/test/test_repo.py b/git/test/test_repo.py index e2342b3cc..25acbec96 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -314,6 +314,13 @@ def test_blame_real(self): assert c, "Should have executed at least one blame command" assert nml, "There should at least be one blame commit that contains multiple lines" + @patch.object(Git, '_call_process') + def test_blame_complex_revision(self, git): + git.return_value = fixture('blame_complex_revision') + res = self.rorepo.blame("HEAD~10..HEAD", "README.md") + assert len(res) == 1 + assert len(res[0][1]) == 83, "Unexpected amount of parsed blame lines" + def test_untracked_files(self): base = self.rorepo.working_tree_dir files = (join_path_native(base, "__test_myfile"), From b825dc74773ffa5c7a45b48d72616b222ad2023e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 10 Jan 2015 13:59:29 +0100 Subject: [PATCH 0087/2790] Implemented multi-line parsing of git-config to the point where a sepcific test-file is working. This brings us much closer to what git can do, and should at least prevent errors while reading configuration files (which would break a lot of features, like handling of remotes since these rely reading configuration files). Fixes #112 --- git/config.py | 105 +++++++----- git/test/fixtures/git_config_with_comments | 183 +++++++++++++++++++++ git/test/test_config.py | 22 ++- 3 files changed, 271 insertions(+), 39 deletions(-) create mode 100644 git/test/fixtures/git_config_with_comments diff --git a/git/config.py b/git/config.py index eefab2997..5828a1c16 100644 --- a/git/config.py +++ b/git/config.py @@ -22,7 +22,8 @@ string_types, FileType, defenc, - with_metaclass + with_metaclass, + PY3 ) __all__ = ('GitConfigParser', 'SectionConstraint') @@ -243,7 +244,21 @@ def _read(self, fp, fpname): cursect = None # None, or a dictionary optname = None lineno = 0 + is_multi_line = False e = None # None, or an exception + + def string_decode(v): + if v[-1] == '\\': + v = v[:-1] + # end cut trailing escapes to prevent decode error + + if PY3: + return v.encode(defenc).decode('unicode_escape') + else: + return v.decode('string_escape') + # end + # end + while True: # we assume to read binary ! line = fp.readline().decode(defenc) @@ -256,46 +271,60 @@ def _read(self, fp, fpname): if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": # no leading whitespace continue - else: - # is it a section header? - mo = self.SECTCRE.match(line.strip()) + + # is it a section header? + mo = self.SECTCRE.match(line.strip()) + if not is_multi_line and mo: + sectname = mo.group('header').strip() + if sectname in self._sections: + cursect = self._sections[sectname] + elif sectname == cp.DEFAULTSECT: + cursect = self._defaults + else: + cursect = self._dict((('__name__', sectname),)) + self._sections[sectname] = cursect + self._proxies[sectname] = None + # So sections can't start with a continuation line + optname = None + # no section header in the file? + elif cursect is None: + raise cp.MissingSectionHeaderError(fpname, lineno, line) + # an option line? + elif not is_multi_line: + mo = self.OPTCRE.match(line) if mo: - sectname = mo.group('header').strip() - if sectname in self._sections: - cursect = self._sections[sectname] - elif sectname == cp.DEFAULTSECT: - cursect = self._defaults - else: - cursect = self._dict((('__name__', sectname),)) - self._sections[sectname] = cursect - self._proxies[sectname] = None - # So sections can't start with a continuation line - optname = None - # no section header in the file? - elif cursect is None: - raise cp.MissingSectionHeaderError(fpname, lineno, line) - # an option line? + # We might just have handled the last line, which could contain a quotation we want to remove + optname, vi, optval = mo.group('option', 'vi', 'value') + if vi in ('=', ':') and ';' in optval: + pos = optval.find(';') + if pos != -1 and optval[pos - 1].isspace(): + optval = optval[:pos] + optval = optval.strip() + if optval == '""': + optval = '' + # end handle empty string + optname = self.optionxform(optname.rstrip()) + if len(optval) > 1 and optval[0] == '"' and optval[-1] != '"': + is_multi_line = True + optval = string_decode(optval[1:]) + # end handle multi-line + cursect[optname] = optval else: - mo = self.OPTCRE.match(line) - if mo: - optname, vi, optval = mo.group('option', 'vi', 'value') - if vi in ('=', ':') and ';' in optval: - pos = optval.find(';') - if pos != -1 and optval[pos - 1].isspace(): - optval = optval[:pos] - optval = optval.strip() - if optval == '""': - optval = '' - optname = self.optionxform(optname.rstrip()) - cursect[optname] = optval - else: - if not e: - e = cp.ParsingError(fpname) - e.append(lineno, repr(line)) - # END - # END ? - # END ? + if not e: + e = cp.ParsingError(fpname) + e.append(lineno, repr(line)) + print(lineno, line) + continue + else: + line = line.rstrip() + if line.endswith('"'): + is_multi_line = False + line = line[:-1] + # end handle quotations + cursect[optname] += string_decode(line) + # END parse section or option # END while reading + # if any parsing errors occurred, raise an exception if e: raise e diff --git a/git/test/fixtures/git_config_with_comments b/git/test/fixtures/git_config_with_comments new file mode 100644 index 000000000..e9d4443da --- /dev/null +++ b/git/test/fixtures/git_config_with_comments @@ -0,0 +1,183 @@ +[user] + name = Cody Veal + email = cveal05@gmail.com + +[github] + user = cjhveal + +[advice] + statusHints = false + +[alias] + # add + a = add + aa = add --all + ap = add --patch + + aliases = !git config --list | grep 'alias\\.' | sed 's/alias\\.\\([^=]*\\)=\\(.*\\)/\\1\\\t => \\2/' | sort + + # branch + br = branch + branches = branch -av + cp = cherry-pick + diverges = !bash -c 'diff -u <(git rev-list --first-parent "${1}") <(git rev-list --first-parent "${2:-HEAD}"g | sed -ne \"s/^ //p\" | head -1' - + track = checkout -t + nb = checkout -b + + # commit + amend = commit --amend -C HEAD + c = commit + ca = commit --amend + cm = commit --message + msg = commit --allow-empty -m + + co = checkout + + # diff + d = diff --color-words # diff by word + ds = diff --staged --color-words + dd = diff --color-words=. # diff by char + dds = diff --staged --color-words=. + dl = diff # diff by line + dls = diff --staged + + h = help + + # log + authors = "!git log --pretty=format:%aN | sort | uniq -c | sort -rn" + lc = log ORIG_HEAD.. --stat --no-merges + lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative + lol = log --graph --decorate --pretty=oneline --abbrev-commit + lola = log --graph --decorate --pretty=oneline --abbrev-commit --all + + # merge + m = merge + mm = merge --no-ff + ours = "!f() { git checkout --ours $@ && git add $@; }; f" + theirs = "!f() { git checkout --theirs $@ && git add $@; }; f" + + # push/pull + l = pull + p = push + sync = !git pull && git push + + # remotes + prune-remotes = "!for remote in `git remote`; do git remote prune $remote; done" + r = remote + + # rebase + rb = rebase + rba = rebase --abort + rbc = rebase --continue + rbs = rebase --skip + + # reset + rh = reset --hard + rhh = reset HEAD --hard + uncommit = reset --soft HEAD^ + unstage = reset HEAD -- + unpush = push -f origin HEAD^:master + + # stash + ss = stash + sl = stash list + sp = stash pop + sd = stash drop + snapshot = !git stash save "snapshot: $(date)" && git stash apply "stash@{0}" + + # status + s = status --short --branch + st = status + + # submodule + sm = submodule + sma = submodule add + smu = submodule update --init + pup = !git pull && git submodule init && git submodule update + + # file level ignoring + assume = update-index --assume-unchanged + unassume = update-index --no-assume-unchanged + assumed = "!git ls-files -v | grep ^h | cut -c 3-" + + +[apply] + whitespace = fix + +[color] + ui = auto + +[color "branch"] + current = yellow reverse + local = yellow + remote = green + +[color "diff"] + meta = yellow + frag = magenta + old = red bold + new = green bold + whitespace = red reverse + +[color "status"] + added = green + changed = yellow + untracked = cyan + +[core] + editor = /usr/bin/vim + excludesfile = ~/.gitignore_global + attributesfile = ~/.gitattributes + +[diff] + renames = copies + mnemonicprefix = true + +[diff "zip"] + textconv = unzip -c -a + +[merge] + log = true + +[merge "railsschema"] + name = newer Rails schema version + driver = "ruby -e '\n\ + system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n\ + b = File.read(%(%A))\n\ + b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n>+ .*/) do\n\ + %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n\ + end\n\ + File.open(%(%A), %(w)) {|f| f.write(b)}\n\ + exit 1 if b.include?(%(<)*%L)'" + +[merge "gemfilelock"] + name = relocks the gemfile.lock + driver = bundle lock + +[pager] + color = true + +[push] + default = upstream + +[rerere] + enabled = true + +[url "git@github.com:"] + insteadOf = "gh:" + pushInsteadOf = "github:" + pushInsteadOf = "git://github.com/" + +[url "git://github.com/"] + insteadOf = "github:" + +[url "git@gist.github.com:"] + insteadOf = "gst:" + pushInsteadOf = "gist:" + pushInsteadOf = "git://gist.github.com/" + +[url "git://gist.github.com/"] + insteadOf = "gist:" + +[url "git@heroku.com:"] + insteadOf = "heroku:" diff --git a/git/test/test_config.py b/git/test/test_config.py index 546a2fe17..9000c07ff 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -3,10 +3,13 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +# The test test_multi_line_config requires whitespace (especially tabs) to remain +# flake8: noqa from git.test.lib import ( TestCase, - fixture_path + fixture_path, + assert_equal ) from git import ( GitConfigParser @@ -72,6 +75,23 @@ def test_read_write(self): assert r_config.get(sname, oname) == val # END for each filename + def test_multi_line_config(self): + file_obj = self._to_memcache(fixture_path("git_config_with_comments")) + config = GitConfigParser(file_obj, read_only=False) + ev = r"""ruby -e ' + system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B) + b = File.read(%(%A)) + b.sub!(/^<+ .*\nActiveRecord::Schema\.define.:version => (\d+). do\n=+\nActiveRecord::Schema\.define.:version => (\d+). do\n>+ .*/) do + %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do) + end + File.open(%(%A), %(w)) {|f| f.write(b)} + exit 1 if b.include?(%(<)*%L)'""" + assert_equal(config.get('merge "railsschema"', 'driver'), ev) + assert_equal(config.get('alias', 'lg'), + "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset'" + " --abbrev-commit --date=relative") + assert len(config.sections()) == 23 + def test_base(self): path_repo = fixture_path("git_config") path_global = fixture_path("git_config_global") From bfce49feb0be6c69f7fffc57ebdd22b6da241278 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 10 Jan 2015 14:09:58 +0100 Subject: [PATCH 0088/2790] rewrote test-string to have a chance to make flake8 happy. That way, flake won't have to completely ignore issues it might have in other portions of this file. --- git/test/test_config.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/git/test/test_config.py b/git/test/test_config.py index 9000c07ff..6851b2a14 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -3,8 +3,6 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -# The test test_multi_line_config requires whitespace (especially tabs) to remain -# flake8: noqa from git.test.lib import ( TestCase, @@ -78,14 +76,15 @@ def test_read_write(self): def test_multi_line_config(self): file_obj = self._to_memcache(fixture_path("git_config_with_comments")) config = GitConfigParser(file_obj, read_only=False) - ev = r"""ruby -e ' - system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B) - b = File.read(%(%A)) - b.sub!(/^<+ .*\nActiveRecord::Schema\.define.:version => (\d+). do\n=+\nActiveRecord::Schema\.define.:version => (\d+). do\n>+ .*/) do - %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do) - end - File.open(%(%A), %(w)) {|f| f.write(b)} - exit 1 if b.include?(%(<)*%L)'""" + ev = "ruby -e '\n" + ev += " system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n" + ev += " b = File.read(%(%A))\n" + ev += " b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\." + ev += "define.:version => (\\d+). do\\n>+ .*/) do\n" + ev += " %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n" + ev += " end\n" + ev += " File.open(%(%A), %(w)) {|f| f.write(b)}\n" + ev += " exit 1 if b.include?(%(<)*%L)'" assert_equal(config.get('merge "railsschema"', 'driver'), ev) assert_equal(config.get('alias', 'lg'), "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset'" From 96c6ab4f7572fd5ca8638f3cb6e342d5000955e7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 10 Jan 2015 18:22:48 +0100 Subject: [PATCH 0089/2790] Added search_parent_directories keyword argument to Repo type. Now by default, we will not walk up the directory structure and possibly find git directories that the user didn't intend to find. If required, that kind of behaviour can be turned back on. Fixes #65 --- doc/source/changes.rst | 1 + git/repo/base.py | 10 ++++------ git/repo/fun.py | 29 +++++++++-------------------- git/test/performance/lib.py | 4 ++-- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index b4535a69d..67384eb91 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -8,6 +8,7 @@ Changelog * diff() can now properly detect renames, both in patch and raw format. Previously it only worked when create_patch was True. * repo.odb.update_cache() is now called automatically after fetch and pull operations. In case you did that in your own code, you might want to remove your line to prevent a double-update that causes unnecessary IO. * A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+ +* `Repo(path)` will not automatically search upstream anymore and find any git directory on its way up. If you need that behaviour, you can turn it back on using the new `search_parent_directories=True` flag when constructing a `Repo` object. 0.3.4 - Python 3 Support ======================== diff --git a/git/repo/base.py b/git/repo/base.py index dbca46979..97e49aa28 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -46,7 +46,6 @@ rev_parse, is_git_dir, find_git_dir, - read_gitfile, touch, ) from git.compat import ( @@ -96,7 +95,7 @@ class Repo(object): # represents the configuration level of a configuration file config_level = ("system", "global", "repository") - def __init__(self, path=None, odbt=DefaultDBType): + def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False): """Create a new Repo instance :param path: is the path to either the root git directory or the bare git repo:: @@ -128,15 +127,14 @@ def __init__(self, path=None, odbt=DefaultDBType): self.git_dir = curpath self._working_tree_dir = os.path.dirname(curpath) break + gitpath = find_git_dir(join(curpath, '.git')) if gitpath is not None: self.git_dir = gitpath self._working_tree_dir = curpath break - gitpath = read_gitfile(curpath) - if gitpath: - self.git_dir = gitpath - self._working_tree_dir = curpath + + if not search_parent_directories: break curpath, dummy = os.path.split(curpath) if not dummy: diff --git a/git/repo/fun.py b/git/repo/fun.py index f83422600..a0dc5ce9a 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -19,8 +19,8 @@ from git.compat import xrange -__all__ = ('rev_parse', 'is_git_dir', 'touch', 'read_gitfile', 'find_git_dir', 'name_to_object', - 'short_to_long', 'deref_tag', 'to_commit') +__all__ = ('rev_parse', 'is_git_dir', 'touch', 'find_git_dir', 'name_to_object', 'short_to_long', 'deref_tag', + 'to_commit') def touch(filename): @@ -44,32 +44,21 @@ def is_git_dir(d): def find_git_dir(d): if is_git_dir(d): return d - elif isfile(d): + + try: with open(d) as fp: content = fp.read().rstrip() + except (IOError, OSError): + # it's probably not a file + pass + else: if content.startswith('gitdir: '): d = join(dirname(d), content[8:]) return find_git_dir(d) + # end handle exception return None -def read_gitfile(f): - """ This is taken from the git setup.c:read_gitfile function. - :return gitdir path or None if gitfile is invalid.""" - if f is None: - return None - try: - line = open(f, 'r').readline().rstrip() - except (OSError, IOError): - # File might not exist or is unreadable - ignore - return None - # end handle file access - if line[0:8] != 'gitdir: ': - return None - path = os.path.realpath(line[8:]) - return path if is_git_dir(path) else None - - def short_to_long(odb, hexsha): """:return: long hexadecimal sha1 from the given less-than-40 byte hexsha or None if no candidate could be found. diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index 46a198d46..bb3f7a998 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -56,8 +56,8 @@ def setUp(self): "your choice - defaulting to the gitpython repository") repo_path = os.path.dirname(__file__) # end set some repo path - self.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB) - self.puregitrorepo = Repo(repo_path, odbt=GitDB) + self.gitrorepo = Repo(repo_path, odbt=GitCmdObjectDB, search_parent_directories=True) + self.puregitrorepo = Repo(repo_path, odbt=GitDB, search_parent_directories=True) def tearDown(self): self.gitrorepo.git.clear_cache() From 6e8aa9b0aefc30ee5807c2b2cf433a38555b7e0b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 10 Jan 2015 19:20:22 +0100 Subject: [PATCH 0090/2790] Repo.init() now supports paths with a '~' in it, or environment variables in general. Fixes #83 --- git/repo/base.py | 11 ++++++++--- git/repo/fun.py | 8 +++++--- git/test/test_repo.py | 10 ++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index 97e49aa28..1dcb80ed8 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -66,6 +66,10 @@ __all__ = ('Repo', ) +def _expand_path(p): + return os.path.abspath(os.path.expandvars(os.path.expanduser(p))) + + class Repo(object): """Represents a git repository and allows you to query references, @@ -111,7 +115,7 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ - epath = os.path.abspath(os.path.expandvars(os.path.expanduser(path or os.getcwd()))) + epath = _expand_path(path or os.getcwd()) self.git = None # should be set for __del__ not to fail in case we raise if not os.path.exists(epath): raise NoSuchPathError(epath) @@ -133,7 +137,7 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals self.git_dir = gitpath self._working_tree_dir = curpath break - + if not search_parent_directories: break curpath, dummy = os.path.split(curpath) @@ -700,7 +704,8 @@ def init(cls, path=None, mkdir=True, **kwargs): keyword arguments serving as additional options to the git-init command :return: ``git.Repo`` (the newly created repo)""" - + if path: + path = _expand_path(path) if mkdir and path and not os.path.exists(path): os.makedirs(path, 0o755) diff --git a/git/repo/fun.py b/git/repo/fun.py index a0dc5ce9a..1ee11ffcc 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -19,7 +19,7 @@ from git.compat import xrange -__all__ = ('rev_parse', 'is_git_dir', 'touch', 'find_git_dir', 'name_to_object', 'short_to_long', 'deref_tag', +__all__ = ('rev_parse', 'is_git_dir', 'touch', 'find_git_dir', 'name_to_object', 'short_to_long', 'deref_tag', 'to_commit') @@ -53,8 +53,10 @@ def find_git_dir(d): pass else: if content.startswith('gitdir: '): - d = join(dirname(d), content[8:]) - return find_git_dir(d) + path = content[8:] + if not os.path.isabs(path): + path = join(dirname(d), path) + return find_git_dir(path) # end handle exception return None diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 25acbec96..0153d8866 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -383,6 +383,16 @@ def test_comparison_and_hash(self): assert self.rorepo == self.rorepo and not (self.rorepo != self.rorepo) assert len(set((self.rorepo, self.rorepo))) == 1 + @with_rw_directory + def test_tilde_in_repo_path(self, rw_dir): + ph = os.environ['HOME'] + try: + os.environ['HOME'] = rw_dir + Repo.init(os.path.join(rw_dir, 'test.git'), bare=True) + finally: + os.environ['HOME'] = ph + # end assure HOME gets reset to what it was + def test_git_cmd(self): # test CatFileContentStream, just to be very sure we have no fencepost errors # last \n is the terminating newline that it expects From becf5efbfc4aee2677e29e1c8cbd756571cb649d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 10 Jan 2015 19:23:39 +0100 Subject: [PATCH 0091/2790] Fixed test to actually use tilde and environment variables respectively. Related to #83 --- git/test/test_repo.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 0153d8866..3abd9cd0e 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -384,13 +384,17 @@ def test_comparison_and_hash(self): assert len(set((self.rorepo, self.rorepo))) == 1 @with_rw_directory - def test_tilde_in_repo_path(self, rw_dir): + def test_tilde_and_env_vars_in_repo_path(self, rw_dir): ph = os.environ['HOME'] try: os.environ['HOME'] = rw_dir - Repo.init(os.path.join(rw_dir, 'test.git'), bare=True) + Repo.init(os.path.join('~', 'test.git'), bare=True) + + os.environ['FOO'] = rw_dir + Repo.init(os.path.join('$FOO', 'test.git'), bare=True) finally: os.environ['HOME'] = ph + del os.environ['FOO'] # end assure HOME gets reset to what it was def test_git_cmd(self): From 597bc56a32e1b709eefa4e573f11387d04629f0d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 10 Jan 2015 19:50:14 +0100 Subject: [PATCH 0092/2790] Added 'user' configuration level. Fixes #160 --- git/repo/base.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/git/repo/base.py b/git/repo/base.py index 1dcb80ed8..c009b9f68 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -97,7 +97,7 @@ class Repo(object): # invariants # represents the configuration level of a configuration file - config_level = ("system", "global", "repository") + config_level = ("system", "user", "global", "repository") def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False): """Create a new Repo instance @@ -353,6 +353,13 @@ def _get_config_path(self, config_level): if config_level == "system": return "/etc/gitconfig" + elif config_level == "user": + for evar in ("XDG_CONFIG_HOME", "HOME"): + if evar not in os.environ: + continue + return os.path.join(os.environ[evar], '.config/git/config') + # end for each evar to check + raise AssertionError("Didn't find a single HOME related environment variable") elif config_level == "global": return os.path.normpath(os.path.expanduser("~/.gitconfig")) elif config_level == "repository": From e84300df7deed9abf248f79526a5b41fd2f7f76e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 10 Jan 2015 20:21:10 +0100 Subject: [PATCH 0093/2790] Added twitch/youtube information to Readme --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 40553b1a0..454c30a3a 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,12 @@ GitPython's git repo is available on GitHub, which can be browsed at [github](ht git clone git://github.com/gitpython-developers/GitPython.git git-python +### Live Coding + +You can watch me fix issues or implement new features [live on Twitch][twitch-channel], or have a look at [past recordings on youtube][youtube-playlist] + +* [Live on Twitch][twitch-channel] (just follow the channel to be notified when a session starts) +* [Archive on Youtube][youtube-playlist] ### INFRASTRUCTURE @@ -81,3 +87,7 @@ There has been a lot of work in the master branch, which is the direction I want * make new master work similarly to 0.3, but with the option to swap for at least one additional backend * make a 1.0 release * add backends as required + + +[twitch-channel]: http://www.twitch.tv/byronimo/profile +[youtube-playlist]: http://www.twitch.tv/byronimo/profile \ No newline at end of file From acd82464a11f3c2d3edc1d152d028a142da31a9f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 12 Jan 2015 10:20:23 +0100 Subject: [PATCH 0094/2790] Re-implemented 'user' config level based on suggestion by @jzempel The point is that XDG_CONFIG_HOME is meant to point at the '.config' directory, whereas '.config' has to be added only if HOME is used instead. Fixes #160 --- git/repo/base.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index c009b9f68..5a93a5a2f 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -354,12 +354,8 @@ def _get_config_path(self, config_level): if config_level == "system": return "/etc/gitconfig" elif config_level == "user": - for evar in ("XDG_CONFIG_HOME", "HOME"): - if evar not in os.environ: - continue - return os.path.join(os.environ[evar], '.config/git/config') - # end for each evar to check - raise AssertionError("Didn't find a single HOME related environment variable") + config_home = os.environ.get("XDG_CONFIG_HOME") or join(os.environ.get("HOME", '~'), ".config") + return os.path.expanduser(join(config_home, "git", "config")) elif config_level == "global": return os.path.normpath(os.path.expanduser("~/.gitconfig")) elif config_level == "repository": From dfb0a9c4bca590efaa86f8edc3fdb62bd536bce7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 12 Jan 2015 10:25:10 +0100 Subject: [PATCH 0095/2790] Added specific test for roughly checking configuration paths. For some reason, I didn't trust the existing one as it tests that code more indirectly. Related to #160 --- .gitignore | 2 +- git/repo/base.py | 2 +- git/test/test_repo.py | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 787b3d442..ce8d0b1b9 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,6 @@ cover/ /doc/_build nbproject *.sublime-workspace - +.DS_Store /*egg-info /.tox diff --git a/git/repo/base.py b/git/repo/base.py index 5a93a5a2f..d6e555530 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -354,7 +354,7 @@ def _get_config_path(self, config_level): if config_level == "system": return "/etc/gitconfig" elif config_level == "user": - config_home = os.environ.get("XDG_CONFIG_HOME") or join(os.environ.get("HOME", '~'), ".config") + config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join(os.environ.get("HOME", '~'), ".config") return os.path.expanduser(join(config_home, "git", "config")) elif config_level == "global": return os.path.normpath(os.path.expanduser("~/.gitconfig")) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 3abd9cd0e..046b20a70 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -365,6 +365,11 @@ def test_config_writer(self): pass # END for each config level + def test_config_level_paths(self): + for config_level in self.rorepo.config_level: + assert self.rorepo._get_config_path(config_level) + # end for each config level + def test_creation_deletion(self): # just a very quick test to assure it generally works. There are # specialized cases in the test_refs module From 43e430d7fa5298f6db6b1649c1a77c208bacf2fc Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 12 Jan 2015 11:14:06 +0100 Subject: [PATCH 0096/2790] Repo paths are now converted to real paths, as well as all paths involved in index related work. That way, we don't try to compare a real-path to a non-real one, which would make the implementation think a file is not actually part of the repository. Fixes #224 --- git/index/base.py | 1 + git/repo/base.py | 8 ++++---- git/test/lib/helper.py | 10 +++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/git/index/base.py b/git/index/base.py index 66fd5b1fb..c6e57f13a 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -535,6 +535,7 @@ def _to_relative_path(self, path): if it is not within our git direcotory""" if not os.path.isabs(path): return path + path = os.path.realpath(path) relative_path = path.replace(self.repo.working_tree_dir + os.sep, "") if relative_path == path: raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir)) diff --git a/git/repo/base.py b/git/repo/base.py index d6e555530..d20d699ab 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -128,14 +128,14 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals # walk up the path to find the .git dir while curpath: if is_git_dir(curpath): - self.git_dir = curpath - self._working_tree_dir = os.path.dirname(curpath) + self.git_dir = os.path.realpath(curpath) + self._working_tree_dir = os.path.dirname(self.git_dir) break gitpath = find_git_dir(join(curpath, '.git')) if gitpath is not None: - self.git_dir = gitpath - self._working_tree_dir = curpath + self.git_dir = os.path.realpath(gitpath) + self._working_tree_dir = os.path.realpath(curpath) break if not search_parent_directories: diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 6c9f33c68..a0b8dc15b 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -62,10 +62,14 @@ def wait(self): def _mktemp(*args): - """Wrapper around default tempfile.mktemp to fix an osx issue""" + """Wrapper around default tempfile.mktemp to fix an osx issue + :note: the OSX special case was removed as it was unclear why that was needed in the first place. It seems + to be just fine without it. However, if we leave this special case, and if TMPDIR is set to something custom, + prefixing /private/ will lead to incorrect paths on OSX.""" tdir = tempfile.mktemp(*args) - if sys.platform == 'darwin': - tdir = '/private' + tdir + # See :note: above to learn why this is comented out. + # if sys.platform == 'darwin': + # tdir = '/private' + tdir return tdir From ede325d15ba9cba0e7fe9ee693085fd5db966629 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 12 Jan 2015 11:16:52 +0100 Subject: [PATCH 0097/2790] Removed all previously added invocations of os.path.realpath as it wasn't required afterall. Turns out that the now removed `read_gitfile` functions applied os.path.realpath which caused the issue described in #224. Fixes #224 --- git/index/base.py | 1 - git/repo/base.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/git/index/base.py b/git/index/base.py index c6e57f13a..66fd5b1fb 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -535,7 +535,6 @@ def _to_relative_path(self, path): if it is not within our git direcotory""" if not os.path.isabs(path): return path - path = os.path.realpath(path) relative_path = path.replace(self.repo.working_tree_dir + os.sep, "") if relative_path == path: raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir)) diff --git a/git/repo/base.py b/git/repo/base.py index d20d699ab..d6efbd587 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -128,14 +128,14 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals # walk up the path to find the .git dir while curpath: if is_git_dir(curpath): - self.git_dir = os.path.realpath(curpath) + self.git_dir = curpath self._working_tree_dir = os.path.dirname(self.git_dir) break gitpath = find_git_dir(join(curpath, '.git')) if gitpath is not None: - self.git_dir = os.path.realpath(gitpath) - self._working_tree_dir = os.path.realpath(curpath) + self.git_dir = gitpath + self._working_tree_dir = curpath break if not search_parent_directories: From e7671110bc865786ffe61cf9b92bf43c03759229 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 12 Jan 2015 12:25:53 +0100 Subject: [PATCH 0098/2790] Removed os.path.realpath invocations as they are not necessary if paths are used consistently. This will save IOPs, and make the code easier to understand (I suppose). Related to #224 --- git/index/base.py | 10 ++++++++-- git/test/lib/helper.py | 4 ++-- git/test/test_index.py | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/git/index/base.py b/git/index/base.py index 66fd5b1fb..db0c3cdaf 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -579,8 +579,14 @@ def _entries_for_paths(self, paths, path_rewriter, fprogress, entries): entries_added = list() if path_rewriter: for path in paths: - abspath = os.path.abspath(path) - gitrelative_path = abspath[len(self.repo.working_tree_dir) + 1:] + if os.path.isabs(path): + abspath = path + gitrelative_path = path[len(self.repo.working_tree_dir) + 1:] + else: + gitrelative_path = path + abspath = os.path.join(self.repo.working_tree_dir, gitrelative_path) + # end obtain relative and absolute paths + blob = Blob(self.repo, Blob.NULL_BIN_SHA, stat_mode_to_index_mode(os.stat(abspath).st_mode), to_native_path_linux(gitrelative_path)) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index a0b8dc15b..c5c5a6201 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -63,11 +63,11 @@ def wait(self): def _mktemp(*args): """Wrapper around default tempfile.mktemp to fix an osx issue - :note: the OSX special case was removed as it was unclear why that was needed in the first place. It seems + :note: the OSX special case was removed as it was unclear why that was needed in the first place. It seems to be just fine without it. However, if we leave this special case, and if TMPDIR is set to something custom, prefixing /private/ will lead to incorrect paths on OSX.""" tdir = tempfile.mktemp(*args) - # See :note: above to learn why this is comented out. + # See :note: above to learn why this is comented out. # if sys.platform == 'darwin': # tdir = '/private' + tdir return tdir diff --git a/git/test/test_index.py b/git/test/test_index.py index 4fdd3d1bf..021a8cd99 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -501,7 +501,7 @@ def mixed_iterator(): # same file entries = index.reset(new_commit).add( - [os.path.abspath(os.path.join('lib', 'git', 'head.py'))] * 2, fprogress=self._fprogress_add) + [os.path.join(rw_repo.working_tree_dir, 'lib', 'git', 'head.py')] * 2, fprogress=self._fprogress_add) self._assert_entries(entries) assert entries[0].mode & 0o644 == 0o644 # would fail, test is too primitive to handle this case From e8eae18dcc360e6ab96c2291982bd4306adc01b9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 12 Jan 2015 14:55:31 +0100 Subject: [PATCH 0099/2790] IndexFile.commit() now runs pre-commit and post-commit hooks. However, it does so only on posix. The test-case will run on posix only as well. Please note that in theory, even on windows we will attempt to run hooks, even though I am not sure that this will actually work. Fixes #81 --- doc/source/changes.rst | 3 ++- git/cmd.py | 2 +- git/exc.py | 20 +++++++++++++----- git/index/base.py | 8 +++++-- git/index/fun.py | 47 +++++++++++++++++++++++++++++++++++++++--- git/test/test_index.py | 21 +++++++++++++++++++ 6 files changed, 89 insertions(+), 12 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 67384eb91..a64143c57 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -7,8 +7,9 @@ Changelog * push/pull/fetch operations will not block anymore * diff() can now properly detect renames, both in patch and raw format. Previously it only worked when create_patch was True. * repo.odb.update_cache() is now called automatically after fetch and pull operations. In case you did that in your own code, you might want to remove your line to prevent a double-update that causes unnecessary IO. -* A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+ * `Repo(path)` will not automatically search upstream anymore and find any git directory on its way up. If you need that behaviour, you can turn it back on using the new `search_parent_directories=True` flag when constructing a `Repo` object. +* IndexFile.commit() now runs the `pre-commit` and `post-commit` hooks. Verified to be working on posix systems only. +* A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+ 0.3.4 - Python 3 Support ======================== diff --git a/git/cmd.py b/git/cmd.py index 668d8f4a4..2c76710ca 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -502,7 +502,7 @@ def execute(self, command, # Prevent cmd prompt popups on windows by using a shell ... . # See https://github.com/gitpython-developers/GitPython/pull/126 shell=sys.platform == 'win32', - close_fds=(os.name == 'posix'), # unsupported on linux + close_fds=(os.name == 'posix'), # unsupported on windows **subprocess_kwargs ) if as_process: diff --git a/git/exc.py b/git/exc.py index 42191c62d..d9b7cbd20 100644 --- a/git/exc.py +++ b/git/exc.py @@ -11,17 +11,14 @@ class InvalidGitRepositoryError(Exception): - """ Thrown if the given repository appears to have an invalid format. """ class NoSuchPathError(OSError): - """ Thrown if a path could not be access by the system. """ class GitCommandError(Exception): - """ Thrown if execution of the git command fails with non-zero status code. """ def __init__(self, command, status, stderr=None, stdout=None): @@ -41,7 +38,6 @@ def __str__(self): class CheckoutError(Exception): - """Thrown if a file could not be checked out from the index as it contained changes. @@ -71,6 +67,20 @@ class CacheError(Exception): class UnmergedEntriesError(CacheError): - """Thrown if an operation cannot proceed as there are still unmerged entries in the cache""" + + +class HookExecutionError(Exception): + """Thrown if a hook exits with a non-zero exit code. It provides access to the exit code and the string returned + via standard output""" + + def __init__(self, command, status, stdout, stderr): + self.command = command + self.status = status + self.stdout = stdout + self.stderr = stderr + + def __str__(self): + return ("'%s' hook returned with exit code %i\nstdout: '%s'\nstderr: '%s'" + % (self.command, self.status, self.stdout, self.stderr)) diff --git a/git/index/base.py b/git/index/base.py index db0c3cdaf..7002385ce 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -63,7 +63,8 @@ aggressive_tree_merge, write_tree_from_cache, stat_mode_to_index_mode, - S_IFGITLINK + S_IFGITLINK, + run_commit_hook ) from gitdb.base import IStream @@ -893,9 +894,12 @@ def commit(self, message, parent_commits=None, head=True, author=None, committer :note: If you have manually altered the .entries member of this instance, don't forget to write() your changes to disk beforehand. :return: Commit object representing the new commit""" + run_commit_hook('pre-commit', self) tree = self.write_tree() - return Commit.create_from_tree(self.repo, tree, message, parent_commits, + rval = Commit.create_from_tree(self.repo, tree, message, parent_commits, head, author=author, committer=committer) + run_commit_hook('post-commit', self) + return rval @classmethod def _flush_stdin_and_wait(cls, proc, ignore_stdout=False): diff --git a/git/index/fun.py b/git/index/fun.py index f0dee961e..38ad843bf 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -13,9 +13,14 @@ S_IFGITLINK = S_IFLNK | S_IFDIR # a submodule from io import BytesIO +import os +import subprocess from git.util import IndexFileSHA1Writer -from git.exc import UnmergedEntriesError +from git.exc import ( + UnmergedEntriesError, + HookExecutionError +) from git.objects.fun import ( tree_to_stream, traverse_tree_recursive, @@ -37,10 +42,46 @@ from gitdb.base import IStream from gitdb.typ import str_tree_type -from git.compat import defenc +from git.compat import ( + defenc, + force_text +) __all__ = ('write_cache', 'read_cache', 'write_tree_from_cache', 'entry_key', - 'stat_mode_to_index_mode', 'S_IFGITLINK') + 'stat_mode_to_index_mode', 'S_IFGITLINK', 'run_commit_hook', 'hook_path') + + +def hook_path(name, git_dir): + """:return: path to the given named hook in the given git repository directory""" + return os.path.join(git_dir, 'hooks', name) + + +def run_commit_hook(name, index): + """Run the commit hook of the given name. Silently ignores hooks that do not exist. + :param name: name of hook, like 'pre-commit' + :param index: IndexFile instance + :raises HookExecutionError: """ + hp = hook_path(name, index.repo.git_dir) + if not os.access(hp, os.X_OK): + return + + env = os.environ.copy() + env['GIT_INDEX_FILE'] = index.path + env['GIT_EDITOR'] = ':' + cmd = subprocess.Popen(hp, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + close_fds=(os.name == 'posix')) + stdout, stderr = cmd.communicate() + cmd.stdout.close() + cmd.stderr.close() + + if cmd.returncode != 0: + stdout = force_text(stdout, defenc) + stderr = force_text(stderr, defenc) + raise HookExecutionError(hp, cmd.returncode, stdout, stderr) + # end handle return code def stat_mode_to_index_mode(mode): diff --git a/git/test/test_index.py b/git/test/test_index.py index 021a8cd99..2be776cd0 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -12,6 +12,7 @@ with_rw_repo ) from git.util import Actor +from git.exc import HookExecutionError from git import ( IndexFile, BlobFilter, @@ -40,6 +41,7 @@ BaseIndexEntry, IndexEntry ) +from git.index.fun import hook_path class TestIndex(TestBase): @@ -665,6 +667,25 @@ def make_paths(): assert fkey not in index.entries index.add(files, write=True) + if os.name != 'nt': + hp = hook_path('pre-commit', index.repo.git_dir) + with open(hp, "wt") as fp: + fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1") + # end + os.chmod(hp, 0o544) + try: + index.commit("This should fail") + except HookExecutionError as err: + assert err.status == 1 + assert err.command == hp + assert err.stdout == 'stdout\n' + assert err.stderr == 'stderr\n' + assert str(err) + else: + raise AssertionError("Should have cought a HookExecutionError") + # end exception handling + os.remove(hp) + # end hook testing nc = index.commit("2 files committed", head=False) for fkey in keys: From a2d39529eea4d0ecfcd65a2d245284174cd2e0aa Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 12 Jan 2015 20:50:55 +0100 Subject: [PATCH 0100/2790] Bumped version to 0.3.5, required latest gitdb (v0.6.4) --- VERSION | 2 +- setup.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 42045acae..c2c0004f0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.4 +0.3.5 diff --git a/setup.py b/setup.py index 16a47526d..d35301ae8 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ def _stamp_version(filename): else: print("WARNING: Couldn't find version line in file %s" % filename, file=sys.stderr) -install_requires = ['gitdb >= 0.6.2'] +install_requires = ['gitdb >= 0.6.4'] if sys.version_info[:2] < (2, 7): install_requires.append('ordereddict') # end @@ -85,7 +85,7 @@ def _stamp_version(filename): package_data={'git.test': ['fixtures/*']}, package_dir={'git': 'git'}, license="BSD License", - requires=['gitdb (>=0.6.2)'], + requires=['gitdb (>=0.6.4)'], install_requires=install_requires, test_requirements=['mock', 'nose'] + install_requires, zip_safe=False, From e973e6f829de5dd1c09d0db39d232230e7eb01d8 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 13 Jan 2015 20:00:21 +0100 Subject: [PATCH 0101/2790] Added `Repo.merge_base(...)` implementation, including test-case. Fixes #169 --- doc/source/changes.rst | 5 +++++ git/repo/base.py | 36 +++++++++++++++++++++++++++++++++++- git/test/test_repo.py | 24 +++++++++++++++++++++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index a64143c57..e18b07cee 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,11 @@ Changelog ========= +0.3.6 - Features +================ +* Added `Repo.merge_base()` implementation. See the `respective issue on github `_ +* A list of all issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+ + 0.3.5 - Bugfixes ================ * push/pull/fetch operations will not block anymore diff --git a/git/repo/base.py b/git/repo/base.py index d6efbd587..f5ed24796 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -4,7 +4,11 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.exc import InvalidGitRepositoryError, NoSuchPathError +from git.exc import ( + InvalidGitRepositoryError, + NoSuchPathError, + GitCommandError +) from git.cmd import ( Git, handle_process_output @@ -456,6 +460,36 @@ def iter_commits(self, rev=None, paths='', **kwargs): return Commit.iter_items(self, rev, paths, **kwargs) + def merge_base(self, *rev, **kwargs): + """Find the closest common ancestor for the given revision (e.g. Commits, Tags, References, etc). + :param rev: At least two revs to find the common ancestor for. + :param kwargs: Additional arguments to be passed to the repo.git.merge_base() command which does all the work. + :return: A list of Commit objects. If --all was not specified as kwarg, the list will have at max one Commit, + or is empty if no common merge base exists. + :raises ValueError: If not at least two revs are provided + """ + if len(rev) < 2: + raise ValueError("Please specify at least two revs, got only %i" % len(rev)) + # end handle input + + res = list() + try: + lines = self.git.merge_base(*rev, **kwargs).splitlines() + except GitCommandError as err: + if err.status == 128: + raise + # end handle invalid rev + # Status code 1 is returned if there is no merge-base + # (see https://github.com/git/git/blob/master/builtin/merge-base.c#L16) + return res + # end exception handling + + for line in lines: + res.append(self.commit(line)) + # end for each merge-base + + return res + def _get_daemon_export(self): filename = join(self.git_dir, self.DAEMON_EXPORT_FILE) return os.path.exists(filename) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 046b20a70..a782cefac 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -27,7 +27,8 @@ Submodule, GitCmdObjectDB, Remote, - BadName + BadName, + GitCommandError ) from git.repo.fun import touch from git.util import join_path_native @@ -737,3 +738,24 @@ def test_empty_repo(self, rw_dir): # Now a branch should be creatable nb = r.create_head('foo') assert nb.is_valid() + + def test_merge_base(self): + repo = self.rorepo + c1 = 'f6aa8d1' + c2 = repo.commit('d46e3fe') + c3 = '763ef75' + self.failUnlessRaises(ValueError, repo.merge_base) + self.failUnlessRaises(ValueError, repo.merge_base, 'foo') + + # two commit merge-base + res = repo.merge_base(c1, c2) + assert isinstance(res, list) and len(res) == 1 and isinstance(res[0], Commit) + assert res[0].hexsha.startswith('3936084') + + for kw in ('a', 'all'): + res = repo.merge_base(c1, c2, c3, **{kw: True}) + assert isinstance(res, list) and len(res) == 1 + # end for eaech keyword signalling all merge-bases to be returned + + # Test for no merge base - can't do as we have + self.failUnlessRaises(GitCommandError, repo.merge_base, c1, 'ffffff') From be074c655ad53927541fc6443eed8b0c2550e415 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 13 Jan 2015 20:28:24 +0100 Subject: [PATCH 0102/2790] Fixed youtube playlist link [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 454c30a3a..57e9bbc9e 100644 --- a/README.md +++ b/README.md @@ -90,4 +90,4 @@ There has been a lot of work in the master branch, which is the direction I want [twitch-channel]: http://www.twitch.tv/byronimo/profile -[youtube-playlist]: http://www.twitch.tv/byronimo/profile \ No newline at end of file +[youtube-playlist]: https://www.youtube.com/playlist?list=PLMHbQxe1e9MnoEcLhn6Yhv5KAvpWkJbL0 \ No newline at end of file From 619c989915b568e4737951fafcbae14cd06d6ea6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 14 Jan 2015 12:46:51 +0100 Subject: [PATCH 0103/2790] GitConfigParser now respects and merges 'include' sections We implement it as described in this article: http://stackoverflow.com/questions/1557183/is-it-possible-to-include-a-file-in-your-gitconfig Thus we handle * cycles * relative and absolute include paths * write-backs in case of writable GitConfigParser instances Fixes #201 --- .gitmodules | 2 +- git/config.py | 83 ++++++++++++++++++++++++++++++------ git/repo/base.py | 4 +- git/test/fixtures/git_config | 3 ++ git/test/test_config.py | 68 ++++++++++++++++++++++++++++- 5 files changed, 143 insertions(+), 17 deletions(-) diff --git a/.gitmodules b/.gitmodules index 612c39d95..4a3f37c25 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "gitdb"] - path = git/ext/gitdb url = https://github.com/gitpython-developers/gitdb.git + path = git/ext/gitdb diff --git a/git/config.py b/git/config.py index 5828a1c16..4c4cb4912 100644 --- a/git/config.py +++ b/git/config.py @@ -15,6 +15,7 @@ import inspect import logging import abc +import os from git.odict import OrderedDict from git.util import LockFile @@ -164,7 +165,7 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, obje # list of RawConfigParser methods able to change the instance _mutating_methods_ = ("add_section", "remove_section", "remove_option", "set") - def __init__(self, file_or_files, read_only=True): + def __init__(self, file_or_files, read_only=True, merge_includes=True): """Initialize a configuration reader to read the given file_or_files and to possibly allow changes to it by setting read_only False @@ -173,7 +174,13 @@ def __init__(self, file_or_files, read_only=True): :param read_only: If True, the ConfigParser may only read the data , but not change it. - If False, only a single file path or file object may be given.""" + If False, only a single file path or file object may be given. We will write back the changes + when they happen, or when the ConfigParser is released. This will not happen if other + configuration files have been included + :param merge_includes: if True, we will read files mentioned in [include] sections and merge their + contents into ours. This makes it impossible to write back an individual configuration file. + Thus, if you want to modify a single conifguration file, turn this off to leave the original + dataset unaltered when reading it.""" cp.RawConfigParser.__init__(self, dict_type=OrderedDict) # Used in python 3, needs to stay in sync with sections for underlying implementation to work @@ -183,6 +190,7 @@ def __init__(self, file_or_files, read_only=True): self._file_or_files = file_or_files self._read_only = read_only self._is_initialized = False + self._merge_includes = merge_includes self._lock = None if not read_only: @@ -313,7 +321,6 @@ def string_decode(v): if not e: e = cp.ParsingError(fpname) e.append(lineno, repr(line)) - print(lineno, line) continue else: line = line.rstrip() @@ -329,6 +336,9 @@ def string_decode(v): if e: raise e + def _has_includes(self): + return self._merge_includes and self.has_section('include') + def read(self): """Reads the data stored in the files we have been initialized with. It will ignore files that cannot be read, possibly leaving an empty configuration @@ -337,18 +347,25 @@ def read(self): :raise IOError: if a file cannot be handled""" if self._is_initialized: return + self._is_initialized = True - files_to_read = self._file_or_files - if not isinstance(files_to_read, (tuple, list)): - files_to_read = [files_to_read] - - for file_object in files_to_read: - fp = file_object + if not isinstance(self._file_or_files, (tuple, list)): + files_to_read = [self._file_or_files] + else: + files_to_read = list(self._file_or_files) + # end assure we have a copy of the paths to handle + + seen = set(files_to_read) + num_read_include_files = 0 + while files_to_read: + file_path = files_to_read.pop(0) + fp = file_path close_fp = False + # assume a path if it is not a file-object - if not hasattr(file_object, "seek"): + if not hasattr(fp, "seek"): try: - fp = open(file_object, 'rb') + fp = open(file_path, 'rb') close_fp = True except IOError: continue @@ -360,8 +377,33 @@ def read(self): if close_fp: fp.close() # END read-handling - # END for each file object to read - self._is_initialized = True + + # Read includes and append those that we didn't handle yet + # We expect all paths to be normalized and absolute (and will assure that is the case) + if self._has_includes(): + for _, include_path in self.items('include'): + if not os.path.isabs(include_path): + if not close_fp: + continue + # end ignore relative paths if we don't know the configuration file path + assert os.path.isabs(file_path), "Need absolute paths to be sure our cycle checks will work" + include_path = os.path.join(os.path.dirname(file_path), include_path) + # end make include path absolute + include_path = os.path.normpath(include_path) + if include_path in seen or not os.access(include_path, os.R_OK): + continue + seen.add(include_path) + files_to_read.append(include_path) + num_read_include_files += 1 + # each include path in configuration file + # end handle includes + # END for each file object to read + + # If there was no file included, we can safely write back (potentially) the configuration file + # without altering it's meaning + if num_read_include_files == 0: + self._merge_includes = False + # end def _write(self, fp): """Write an .ini-format representation of the configuration state in @@ -379,6 +421,10 @@ def write_section(name, section_dict): for name, value in self._sections.items(): write_section(name, value) + def items(self, section_name): + """:return: list((option, value), ...) pairs of all items in the given section""" + return [(k, v) for k, v in super(GitConfigParser, self).items(section_name) if k != '__name__'] + @needs_values def write(self): """Write changes to our file, if there are changes at all @@ -387,6 +433,17 @@ def write(self): a file lock""" self._assure_writable("write") + if isinstance(self._file_or_files, (list, tuple)): + raise AssertionError("Cannot write back if there is not exactly a single file to write to, have %i files" + % len(self._file_or_files)) + # end assert multiple files + + if self._has_includes(): + log.debug("Skipping write-back of confiuration file as include files were merged in." + + "Set merge_includes=False to prevent this.") + return + # end + fp = self._file_or_files close_fp = False diff --git a/git/repo/base.py b/git/repo/base.py index f5ed24796..155a674f1 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -359,11 +359,11 @@ def _get_config_path(self, config_level): return "/etc/gitconfig" elif config_level == "user": config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join(os.environ.get("HOME", '~'), ".config") - return os.path.expanduser(join(config_home, "git", "config")) + return os.path.normpath(os.path.expanduser(join(config_home, "git", "config"))) elif config_level == "global": return os.path.normpath(os.path.expanduser("~/.gitconfig")) elif config_level == "repository": - return join(self.git_dir, "config") + return os.path.normpath(join(self.git_dir, "config")) raise ValueError("Invalid configuration level: %r" % config_level) diff --git a/git/test/fixtures/git_config b/git/test/fixtures/git_config index ff8e71143..c9945cd50 100644 --- a/git/test/fixtures/git_config +++ b/git/test/fixtures/git_config @@ -27,3 +27,6 @@ [branch "mainline_performance"] remote = mainline merge = refs/heads/master +[include] + path = doesntexist.cfg + abspath = /usr/bin/foodoesntexist.bar \ No newline at end of file diff --git a/git/test/test_config.py b/git/test/test_config.py index 6851b2a14..9a44d9e38 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -7,8 +7,9 @@ from git.test.lib import ( TestCase, fixture_path, - assert_equal + assert_equal, ) +from gitdb.test.lib import with_rw_directory from git import ( GitConfigParser ) @@ -16,6 +17,7 @@ string_types, ) import io +import os from copy import copy from git.config import cp @@ -127,3 +129,67 @@ def test_base(self): # it raises if there is no default though self.failUnlessRaises(cp.NoSectionError, r_config.get_value, "doesnt", "exist") + + @with_rw_directory + def test_config_include(self, rw_dir): + def write_test_value(cw, value): + cw.set_value(value, 'value', value) + # end + + def check_test_value(cr, value): + assert cr.get_value(value, 'value') == value + # end + + # PREPARE CONFIG FILE A + fpa = os.path.join(rw_dir, 'a') + cw = GitConfigParser(fpa, read_only=False) + write_test_value(cw, 'a') + + fpb = os.path.join(rw_dir, 'b') + fpc = os.path.join(rw_dir, 'c') + cw.set_value('include', 'relative_path_b', 'b') + cw.set_value('include', 'doesntexist', 'foobar') + cw.set_value('include', 'relative_cycle_a_a', 'a') + cw.set_value('include', 'absolute_cycle_a_a', fpa) + cw.release() + assert os.path.exists(fpa) + + # PREPARE CONFIG FILE B + cw = GitConfigParser(fpb, read_only=False) + write_test_value(cw, 'b') + cw.set_value('include', 'relative_cycle_b_a', 'a') + cw.set_value('include', 'absolute_cycle_b_a', fpa) + cw.set_value('include', 'relative_path_c', 'c') + cw.set_value('include', 'absolute_path_c', fpc) + cw.release() + + # PREPARE CONFIG FILE C + cw = GitConfigParser(fpc, read_only=False) + write_test_value(cw, 'c') + cw.release() + + cr = GitConfigParser(fpa, read_only=True) + for tv in ('a', 'b', 'c'): + check_test_value(cr, tv) + # end for each test to verify + assert len(cr.items('include')) == 8, "Expected all include sections to be merged" + cr.release() + + # test writable config writers - assure write-back doesn't involve includes + cw = GitConfigParser(fpa, read_only=False, merge_includes=True) + tv = 'x' + write_test_value(cw, tv) + cw.release() + + cr = GitConfigParser(fpa, read_only=True) + self.failUnlessRaises(cp.NoSectionError, check_test_value, cr, tv) + cr.release() + + # But can make it skip includes alltogether, and thus allow write-backs + cw = GitConfigParser(fpa, read_only=False, merge_includes=False) + write_test_value(cw, tv) + cw.release() + + cr = GitConfigParser(fpa, read_only=True) + check_test_value(cr, tv) + cr.release() From aa1b156ee96f5aabdca153c152ec6e3215fdf16f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 14 Jan 2015 16:23:17 +0100 Subject: [PATCH 0104/2790] Added 'path' keyword argument to Repo.archive(). This allows sub-trees to be archived as well, and makes `.archive()` feature complete. Fixes #67 --- doc/source/changes.rst | 1 + git/repo/base.py | 11 +++++++++-- git/test/test_repo.py | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index e18b07cee..d81f90a6b 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -5,6 +5,7 @@ Changelog 0.3.6 - Features ================ * Added `Repo.merge_base()` implementation. See the `respective issue on github `_ +* `[include]` sections in git configuration files are now respected * A list of all issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+ 0.3.5 - Bugfixes diff --git a/git/repo/base.py b/git/repo/base.py index 155a674f1..afff9471d 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -846,7 +846,10 @@ def archive(self, ostream, treeish=None, prefix=None, **kwargs): :parm kwargs: Additional arguments passed to git-archive NOTE: Use the 'format' argument to define the kind of format. Use - specialized ostreams to write any format supported by python + specialized ostreams to write any format supported by python. + + You may specify the special 'path' keyword, which may either be a repository-relative + path to a directory or file to place into the archive, or a list or tuple of multipe paths. :raise GitCommandError: in case something went wrong :return: self""" @@ -855,8 +858,12 @@ def archive(self, ostream, treeish=None, prefix=None, **kwargs): if prefix and 'prefix' not in kwargs: kwargs['prefix'] = prefix kwargs['output_stream'] = ostream + path = kwargs.pop('path', list()) + if not isinstance(path, (tuple, list)): + path = [path] + # end assure paths is list - self.git.archive(treeish, **kwargs) + self.git.archive(treeish, *path, **kwargs) return self rev_parse = rev_parse diff --git a/git/test/test_repo.py b/git/test/test_repo.py index a782cefac..226c1d268 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -266,7 +266,7 @@ def test_tag(self): def test_archive(self): tmpfile = tempfile.mktemp(suffix='archive-test') stream = open(tmpfile, 'wb') - self.rorepo.archive(stream, '0.1.5') + self.rorepo.archive(stream, '0.1.6', path='doc') assert stream.tell() stream.close() os.remove(tmpfile) From 53e5fb3733e491925a01e9da6243e93c2e4214c1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 14 Jan 2015 17:12:28 +0100 Subject: [PATCH 0105/2790] An attempt to help the threaded reading to not show spurious errors anymore. It does not necessarily seem to work, but at least we don't access a dict concurrently anymore. --- git/cmd.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 2c76710ca..ccce086e4 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -77,8 +77,7 @@ def read_line_slow(stream): return line # end - def dispatch_line(fno): - stream, handler, readline = fdmap[fno] + def dispatch_line(stream, handler, readline): # this can possibly block for a while, but since we wake-up with at least one or more lines to handle, # we are good ... line = readline(stream).decode(defenc) @@ -93,9 +92,9 @@ def dispatch_line(fno): # end dispatch helper # end - def deplete_buffer(fno, wg=None): + def deplete_buffer(stream, handler, readline, wg=None): while True: - line = dispatch_line(fno) + line = dispatch_line(stream, handler, readline) if not line: break # end deplete buffer @@ -124,7 +123,7 @@ def deplete_buffer(fno, wg=None): if result & CLOSED: closed_streams.add(fd) else: - dispatch_line(fd) + dispatch_line(*fdmap[fd]) # end handle closed stream # end for each poll-result tuple @@ -134,8 +133,8 @@ def deplete_buffer(fno, wg=None): # end endless loop # Depelete all remaining buffers - for fno in fdmap.keys(): - deplete_buffer(fno) + for stream, handler, readline in fdmap.values(): + deplete_buffer(stream, handler, readline) # end for each file handle else: # Oh ... probably we are on windows. select.select() can only handle sockets, we have files @@ -145,7 +144,8 @@ def deplete_buffer(fno, wg=None): wg = WaitGroup() for fno in fdmap.keys(): wg.add(1) - t = threading.Thread(target=lambda: deplete_buffer(fno, wg)) + stream, handler, readline = fdmap[fno] + t = threading.Thread(target=lambda: deplete_buffer(stream, handler, readline, wg)) t.start() # end # NOTE: Just joining threads can possibly fail as there is a gap between .start() and when it's From 6569c4849197c9475d85d05205c55e9ef28950c1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 14 Jan 2015 17:47:44 +0100 Subject: [PATCH 0106/2790] Fixed some doc strings to build correctly with sphinx Fixes #7 [ci skip] --- git/cmd.py | 6 +++--- git/index/fun.py | 9 ++++----- git/refs/head.py | 1 + git/refs/remote.py | 3 ++- git/remote.py | 12 +++++------- git/repo/base.py | 26 ++++++++++++-------------- git/util.py | 7 +++++-- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index ccce086e4..4ceebb4ca 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -769,10 +769,10 @@ def get_object_data(self, ref): return (hexsha, typename, size, data) def stream_object_data(self, ref): - """As get_object_header, but returns the data as a stream + """ As get_object_header, but returns the data as a stream + :return: (hexsha, type_string, size_as_int, stream) - :note: This method is not threadsafe, you need one independent Command instance - per thread to be safe !""" + :note: This method is not threadsafe, you need one independent Command instance per thread to be safe !""" cmd = self._get_persistent_cmd("cat_file_all", "cat_file", batch=True) hexsha, typename, size = self.__get_object_header(cmd, ref) return (hexsha, typename, size, self.CatFileContentStream(size, cmd.stdout)) diff --git a/git/index/fun.py b/git/index/fun.py index 38ad843bf..f07cf7dc3 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -166,11 +166,10 @@ def entry_key(*entry): def read_cache(stream): """Read a cache file from the given stream :return: tuple(version, entries_dict, extension_data, content_sha) - * version is the integer version number - * entries dict is a dictionary which maps IndexEntry instances to a path - at a stage - * extension_data is '' or 4 bytes of type + 4 bytes of size + size bytes - * content_sha is a 20 byte sha on all cache file contents""" + * version is the integer version number + * entries dict is a dictionary which maps IndexEntry instances to a path at a stage + * extension_data is '' or 4 bytes of type + 4 bytes of size + size bytes + * content_sha is a 20 byte sha on all cache file contents""" version, num_entries = read_header(stream) count = 0 entries = dict() diff --git a/git/refs/head.py b/git/refs/head.py index 750d15b6b..18dac3497 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -114,6 +114,7 @@ class Head(Reference): @classmethod def delete(cls, repo, *heads, **kwargs): """Delete the given heads + :param force: If True, the heads will be deleted even if they are not yet merged into the main development stream. diff --git a/git/refs/remote.py b/git/refs/remote.py index b692e6df6..1f256b752 100644 --- a/git/refs/remote.py +++ b/git/refs/remote.py @@ -25,7 +25,8 @@ def iter_items(cls, repo, common_path=None, remote=None): @classmethod def delete(cls, repo, *refs, **kwargs): - """Delete the given remote references. + """Delete the given remote references + :note: kwargs are given for compatability with the base class method as we should not narrow the signature.""" diff --git a/git/remote.py b/git/remote.py index 746a78199..541f3c9ec 100644 --- a/git/remote.py +++ b/git/remote.py @@ -398,8 +398,9 @@ def __hash__(self): return hash(self.name) def exists(self): - """:return: True if this is a valid, existing remote. - Valid remotes have an entry in the repository's configuration""" + """ + :return: True if this is a valid, existing remote. + Valid remotes have an entry in the repository's configuration""" try: self.config_reader.get('url') return True @@ -429,7 +430,7 @@ def refs(self): :return: IterableList of RemoteReference objects. It is prefixed, allowing you to omit the remote path portion, i.e.:: - remote.refs.master # yields RemoteReference('/refs/remotes/origin/master')""" + remote.refs.master # yields RemoteReference('/refs/remotes/origin/master')""" out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name) out_refs.extend(RemoteReference.list_items(self.repo, remote=self.name)) assert out_refs, "Remote %s did not have any references" % self.name @@ -463,11 +464,8 @@ def create(cls, repo, name, url, **kwargs): :param repo: Repository instance that is to receive the new remote :param name: Desired name of the remote :param url: URL which corresponds to the remote's name - :param kwargs: - Additional arguments to be passed to the git-remote add command - + :param kwargs: Additional arguments to be passed to the git-remote add command :return: New Remote instance - :raise GitCommandError: in case an origin with that name already exists""" repo.git.remote("add", name, url, **kwargs) return cls(repo, name) diff --git a/git/repo/base.py b/git/repo/base.py index afff9471d..6d9af6d47 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -461,7 +461,8 @@ def iter_commits(self, rev=None, paths='', **kwargs): return Commit.iter_items(self, rev, paths, **kwargs) def merge_base(self, *rev, **kwargs): - """Find the closest common ancestor for the given revision (e.g. Commits, Tags, References, etc). + """Find the closest common ancestor for the given revision (e.g. Commits, Tags, References, etc) + :param rev: At least two revs to find the common ancestor for. :param kwargs: Additional arguments to be passed to the repo.git.merge_base() command which does all the work. :return: A list of Commit objects. If --all was not specified as kwarg, the list will have at max one Commit, @@ -814,16 +815,13 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): def clone(self, path, progress=None, **kwargs): """Create a clone from this repository. - :param path: - is the full path of the new repo (traditionally ends with ./.git). + :param path: is the full path of the new repo (traditionally ends with ./.git). :param progress: See 'git.remote.Remote.push'. - :param kwargs: - odbt = ObjectDatabase Type, allowing to determine the object database - implementation used by the returned Repo instance - - All remaining keyword arguments are given to the git-clone command + * odbt = ObjectDatabase Type, allowing to determine the object database + implementation used by the returned Repo instance + * All remaining keyword arguments are given to the git-clone command :return: ``git.Repo`` (the newly cloned repo)""" return self._clone(self.git, self.git_dir, path, type(self.odb), progress, **kwargs) @@ -840,16 +838,16 @@ def clone_from(cls, url, to_path, progress=None, **kwargs): def archive(self, ostream, treeish=None, prefix=None, **kwargs): """Archive the tree at the given revision. + :parm ostream: file compatible stream object to which the archive will be written as bytes :parm treeish: is the treeish name/id, defaults to active branch :parm prefix: is the optional prefix to prepend to each filename in the archive - :parm kwargs: - Additional arguments passed to git-archive - NOTE: Use the 'format' argument to define the kind of format. Use - specialized ostreams to write any format supported by python. + :parm kwargs: Additional arguments passed to git-archive - You may specify the special 'path' keyword, which may either be a repository-relative - path to a directory or file to place into the archive, or a list or tuple of multipe paths. + * Use the 'format' argument to define the kind of format. Use + specialized ostreams to write any format supported by python. + * You may specify the special **path** keyword, which may either be a repository-relative + path to a directory or file to place into the archive, or a list or tuple of multipe paths. :raise GitCommandError: in case something went wrong :return: self""" diff --git a/git/util.py b/git/util.py index b1f3b38dc..010130cbc 100644 --- a/git/util.py +++ b/git/util.py @@ -40,6 +40,7 @@ def rmtree(path): """Remove the given recursively. + :note: we use shutil rmtree but adjust its behaviour to see whether files that couldn't be deleted are read-only. Windows will not remove them in that case""" def onerror(func, path, exc_info): @@ -251,8 +252,10 @@ def _parse_progress_line(self, line): return failed_lines def new_message_handler(self): - """:return: a progress handler suitable for handle_process_output(), passing lines on to this Progress - handler in a suitable format""" + """ + :return: + a progress handler suitable for handle_process_output(), passing lines on to this Progress + handler in a suitable format""" def handler(line): return self._parse_progress_line(line.rstrip()) # end From a41a8b93167a59cd074eb3175490cd61c45b6f6a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 15 Jan 2015 15:40:55 +0100 Subject: [PATCH 0107/2790] Added sphinx build process to end of travis test chain --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 112df6cf7..1fda20189 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ git: install: - git submodule update --init --recursive - git fetch --tags - - pip install coveralls flake8 + - pip install coveralls flake8 sphinx # generate some reflog as git-python tests need it (in master) - git checkout master @@ -30,5 +30,6 @@ script: - ulimit -n - nosetests -v --with-coverage - flake8 + - cd doc && make html after_success: - coveralls From 27c31e2fde54c0587c032ccffdaa7c4ddf5b2ae5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 15 Jan 2015 16:03:47 +0100 Subject: [PATCH 0108/2790] Added the first submodule will no longer cause an IOError. This is verified by the respective test. Fixes #117 --- git/objects/submodule/base.py | 2 +- git/test/test_submodule.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 0ec6f6567..0bd349997 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -159,7 +159,7 @@ def _config_parser(cls, repo, parent_commit, read_only): if not repo.bare and parent_matches_head: fp_module = cls.k_modules_file fp_module_path = os.path.join(repo.working_tree_dir, fp_module) - if not os.path.isfile(fp_module_path): + if read_only and not os.path.isfile(fp_module_path): raise IOError("%s file was not accessible" % fp_module_path) # END handle existance fp_module = fp_module_path diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 99996ce33..524a69bfe 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -582,3 +582,10 @@ def test_root_module(self, rwrepo): # gitdb: has either 1 or 2 submodules depending on the version assert len(nsm.children()) >= 1 and nsmc.module_exists() + + @with_rw_repo(k_no_subm_tag, bare=False) + def test_first_submodule(self, rwrepo): + assert len(list(rwrepo.iter_submodules())) == 0 + sm = rwrepo.create_submodule('first', 'submodules/first', rwrepo.git_dir, no_checkout=True) + assert sm.exists() and sm.module_exists() + rwrepo.index.commit("Added submodule") From b259098782c2248f6160d2b36d42672d6925023a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 15 Jan 2015 16:21:07 +0100 Subject: [PATCH 0109/2790] For some reason, the new submodule test still broke on py3 Adjusted code to not check for .gitmodules existence anymore, we will deal with it. Fixes #117 --- git/objects/submodule/base.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 0bd349997..ae45e3dbd 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -159,9 +159,6 @@ def _config_parser(cls, repo, parent_commit, read_only): if not repo.bare and parent_matches_head: fp_module = cls.k_modules_file fp_module_path = os.path.join(repo.working_tree_dir, fp_module) - if read_only and not os.path.isfile(fp_module_path): - raise IOError("%s file was not accessible" % fp_module_path) - # END handle existance fp_module = fp_module_path else: try: From 508807e59ce9d6c3574d314d502e82238e3e606c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 15 Jan 2015 16:49:39 +0100 Subject: [PATCH 0110/2790] Submodule.add() can now handle absolute module paths in agreement to the doc string. Previously, it would say it can handle absolute module paths, but didn't actually do so. A test-case was improved to check for this case. Fixes #161 --- git/objects/submodule/base.py | 11 +++++++++++ git/test/test_submodule.py | 14 +++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index ae45e3dbd..92b0c8e80 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -238,6 +238,17 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): path = path[:-1] # END handle trailing slash + if os.path.isabs(path): + working_tree_linux = to_native_path_linux(repo.working_tree_dir) + if not path.startswith(working_tree_linux): + raise ValueError("Submodule checkout path '%s' needs to be within the parents repository at '%s'" + % (working_tree_linux, path)) + path = path[len(working_tree_linux) + 1:] + if not path: + raise ValueError("Absolute submodule path '%s' didn't yield a valid relative path" % path) + # end verify converted relative path makes sense + # end convert to a relative path + # assure we never put backslashes into the url, as some operating systems # like it ... if url is not None: diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 524a69bfe..75edf6e53 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -586,6 +586,14 @@ def test_root_module(self, rwrepo): @with_rw_repo(k_no_subm_tag, bare=False) def test_first_submodule(self, rwrepo): assert len(list(rwrepo.iter_submodules())) == 0 - sm = rwrepo.create_submodule('first', 'submodules/first', rwrepo.git_dir, no_checkout=True) - assert sm.exists() and sm.module_exists() - rwrepo.index.commit("Added submodule") + + for sm_name, sm_path in (('first', 'submodules/first'), + ('second', os.path.join(rwrepo.working_tree_dir, 'submodules/second'))): + sm = rwrepo.create_submodule(sm_name, sm_path, rwrepo.git_dir, no_checkout=True) + assert sm.exists() and sm.module_exists() + rwrepo.index.commit("Added submodule " + sm_name) + # end for each submodule path to add + + self.failUnlessRaises(ValueError, rwrepo.create_submodule, 'fail', os.path.expanduser('~')) + self.failUnlessRaises(ValueError, rwrepo.create_submodule, 'fail-too', + rwrepo.working_tree_dir + os.path.sep) From 26fc5866f6ed994f3b9d859a3255b10d04ee653d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 15 Jan 2015 18:05:48 +0100 Subject: [PATCH 0111/2790] Verified that it apparently is impossible to add empty submodules using git-python. This is the case with `git submodule add` as well. This makes sense as an empty git repository doesn't have a commit, which needs to be specified as SHA in the parent repositories tree entry for the respective submodule. When manually adding the empty submodule to the .gitmodules file, git-python will throw another error related to the inability to find the submodule in the index. Even if an iteration would be possible, git-python would now throw a BadName exception, which clearly indicates that the 'HEAD' revision is invalid (as it doesn't point to any commit). Fixes #152 Fixes #105 --- git/test/test_submodule.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 75edf6e53..2be0e7950 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -1,19 +1,21 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +import shutil +import sys +import os + +import git from git.test.lib import ( TestBase, with_rw_repo ) +from gitdb.test.lib import with_rw_directory from git.exc import InvalidGitRepositoryError from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress from git.util import to_native_path_linux, join_path_native from git.compat import string_types -import shutil -import git -import sys -import os from nose import SkipTest @@ -597,3 +599,17 @@ def test_first_submodule(self, rwrepo): self.failUnlessRaises(ValueError, rwrepo.create_submodule, 'fail', os.path.expanduser('~')) self.failUnlessRaises(ValueError, rwrepo.create_submodule, 'fail-too', rwrepo.working_tree_dir + os.path.sep) + + @with_rw_directory + def test_add_empty_repo(self, rwdir): + parent_dir = os.path.join(rwdir, 'parent') + os.mkdir(parent_dir) + empty_repo_dir = os.path.join(rwdir, 'empty-repo') + + parent = git.Repo.init(parent_dir) + git.Repo.init(empty_repo_dir) + + for checkout_mode in range(2): + self.failUnlessRaises(ValueError, parent.create_submodule, 'empty', 'empty', + url=empty_repo_dir, no_checkout=checkout_mode) + # end for each checkout mode From a9a5414300a245b6e93ea4f39fbca792c3ec753f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 15 Jan 2015 19:16:08 +0100 Subject: [PATCH 0112/2790] Fixed previously failing test It actually revealed a bug in the implementation of Submodule.add, which just showed in python 3 for the wrong reasons. Thankfully, failing tests after all allowed to get this issue fixed ... . --- git/objects/submodule/base.py | 4 ++-- git/test/test_submodule.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 92b0c8e80..e055cb8c4 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -256,7 +256,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): # END assure url correctness # INSTANTIATE INTERMEDIATE SM - sm = cls(repo, cls.NULL_BIN_SHA, cls.k_default_mode, path, name) + sm = cls(repo, cls.NULL_BIN_SHA, cls.k_default_mode, path, name, url='invalid-temporary') if sm.exists(): # reretrieve submodule from tree try: @@ -298,7 +298,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): if not branch_is_default: kwargs['b'] = br.name # END setup checkout-branch - mrepo = git.Repo.clone_from(url, path, **kwargs) + mrepo = git.Repo.clone_from(url, os.path.join(repo.working_tree_dir, path), **kwargs) # END verify url # update configuration and index diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 2be0e7950..3e3a97d88 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -610,6 +610,7 @@ def test_add_empty_repo(self, rwdir): git.Repo.init(empty_repo_dir) for checkout_mode in range(2): - self.failUnlessRaises(ValueError, parent.create_submodule, 'empty', 'empty', - url=empty_repo_dir, no_checkout=checkout_mode) + name = 'empty' + str(checkout_mode) + self.failUnlessRaises(ValueError, parent.create_submodule, name, name, + url=empty_repo_dir, no_checkout=checkout_mode and True or False) # end for each checkout mode From 34802014ca0c9546e73292260aab5e4017ffcd9a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 16 Jan 2015 11:58:15 +0100 Subject: [PATCH 0113/2790] Added debug code to keep lines fed into progress handler and the contents of FETCH_HEAD. This data will be written into the git-repository itself, prefixed with the number of the operation. Thus, a test-run with exactly one fetch operation would look like this afterwards: ls -l .git total 96 -----> -rw-r--r-- 1 byron staff 141B Jan 16 11:54 000_debug_git-python_FETCH_HEAD <----- -----> -rw-r--r-- 1 byron staff 180B Jan 16 11:54 000_debug_git-python_stderr <----- -rw-r--r-- 1 byron staff 487B Jan 16 11:54 FETCH_HEAD -rw-r--r-- 1 byron staff 22B Jan 16 11:54 HEAD -rw-r--r-- 1 byron staff 41B Jan 16 11:54 ORIG_HEAD drwxr-xr-x 2 byron staff 68B Jan 16 11:54 branches/ -rw-r--r-- 1 byron staff 560B Jan 16 11:54 config -rw-r--r-- 1 byron staff 73B Jan 16 11:54 description drwxr-xr-x 11 byron staff 374B Jan 16 11:54 hooks/ -rw-r--r-- 1 byron staff 13K Jan 16 11:54 index drwxr-xr-x 3 byron staff 102B Jan 16 11:54 info/ drwxr-xr-x 4 byron staff 136B Jan 16 11:54 logs/ drwxr-xr-x 12 byron staff 408B Jan 16 11:54 objects/ -rw-r--r-- 1 byron staff 1.2K Jan 16 11:54 packed-refs drwxr-xr-x 5 byron staff 170B Jan 16 11:54 refs/ [ci skip] --- git/remote.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/git/remote.py b/git/remote.py index 541f3c9ec..216858c03 100644 --- a/git/remote.py +++ b/git/remote.py @@ -338,7 +338,7 @@ class Remote(LazyMixin, Iterable): NOTE: When querying configuration, the configuration accessor will be cached to speed up subsequent accesses.""" - __slots__ = ("repo", "name", "_config_reader") + __slots__ = ("repo", "name", "_config_reader", "fetch_no") _id_attribute_ = "name" def __init__(self, repo, name): @@ -348,6 +348,7 @@ def __init__(self, repo, name): :param name: the name of the remote, i.e. 'origin'""" self.repo = repo self.name = name + self.fetch_no = 0 if os.name == 'nt': # some oddity: on windows, python 2.5, it for some reason does not realize @@ -523,7 +524,9 @@ def _get_fetch_info_from_stderr(self, proc, progress): progress_handler = progress.new_message_handler() + stderr_fetch = open(join(self.repo.git_dir, '%03i_debug_git-python_stderr' % self.fetch_no), 'wb') def my_progress_handler(line): + stderr_fetch.write((line + '\n').encode(defenc)) for pline in progress_handler(line): if line.startswith('fatal:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) @@ -539,8 +542,12 @@ def my_progress_handler(line): # We are only interested in stderr here ... handle_process_output(proc, None, my_progress_handler, finalize_process) + stderr_fetch.close() # read head information + import shutil + shutil.copyfile(join(self.repo.git_dir, 'FETCH_HEAD'), join(self.repo.git_dir, '%03i_debug_git-python_FETCH_HEAD' % self.fetch_no)) + self.fetch_no += 1 fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') fetch_head_info = [l.decode(defenc) for l in fp.readlines()] fp.close() From 503b62bd76ee742bd18a1803dac76266fa8901bc Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 16 Jan 2015 17:43:52 +0100 Subject: [PATCH 0114/2790] Implemented more tests and made use of .git files when adding submodules There is some more work to do, as renames and updates still have to be adjusted accordinlgy. Relates #233 --- git/objects/submodule/base.py | 39 ++++++++++++++++++++++++---- git/test/test_submodule.py | 48 ++++++++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index e055cb8c4..13183e29e 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -127,6 +127,10 @@ def _get_intermediate_items(self, item): return list() # END handle intermeditate items + @classmethod + def _need_gitfile_submodules(cls, git): + return git.version_info[:3] >= (1, 8, 0) + def __eq__(self, other): """Compare with another submodule""" # we may only compare by name as this should be the ID they are hashed with @@ -157,9 +161,7 @@ def _config_parser(cls, repo, parent_commit, read_only): access of the config parser""" parent_matches_head = repo.head.commit == parent_commit if not repo.bare and parent_matches_head: - fp_module = cls.k_modules_file - fp_module_path = os.path.join(repo.working_tree_dir, fp_module) - fp_module = fp_module_path + fp_module = os.path.join(repo.working_tree_dir, cls.k_modules_file) else: try: fp_module = cls._sio_modules(parent_commit) @@ -198,6 +200,23 @@ def _config_parser_constrained(self, read_only): parser.set_submodule(self) return SectionConstraint(parser, sm_section(self.name)) + @classmethod + def _module_abspath(cls, parent_repo, path, name): + if cls._need_gitfile_submodules(parent_repo.git): + return os.path.join(parent_repo.git_dir, 'modules', name) + else: + return os.path.join(parent_repo.working_tree_dir, path) + # end + + @classmethod + def _write_git_file(cls, working_tree_dir, module_abspath, overwrite_existing=False): + """Writes a .git file containing a (preferably) relative path to the actual git module repository. + It is an error if the module_abspath cannot be made into a relative path, relative to the working_tree_dir + :param working_tree_dir: directory to write the .git file into + :param module_abspath: absolute path to the bare repository + :param overwrite_existing: if True, we may rewrite existing .git files, otherwise we raise""" + raise NotImplementedError + #{ Edit Interface @classmethod @@ -298,7 +317,17 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): if not branch_is_default: kwargs['b'] = br.name # END setup checkout-branch - mrepo = git.Repo.clone_from(url, os.path.join(repo.working_tree_dir, path), **kwargs) + module_abspath = cls._module_abspath(repo, path, name) + module_checkout_path = module_abspath + if cls._need_gitfile_submodules(repo.git): + kwargs['separate_git_dir'] = module_abspath + module_abspath_dir = os.path.dirname(module_abspath) + if not os.path.isdir(module_abspath_dir): + os.makedirs(module_abspath_dir) + module_checkout_path = os.path.join(repo.working_tree_dir, path) + # end + + mrepo = git.Repo.clone_from(url, module_checkout_path, **kwargs) # END verify url # update configuration and index @@ -390,7 +419,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= import git # there is no git-repository yet - but delete empty paths - module_path = join_path_native(self.repo.working_tree_dir, self.path) + module_path = self._module_abspath(self.repo, self.path, self.name) if not dry_run and os.path.isdir(module_path): try: os.rmdir(module_path) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 3e3a97d88..484e73ae3 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -16,6 +16,7 @@ from git.objects.submodule.root import RootModule, RootUpdateProgress from git.util import to_native_path_linux, join_path_native from git.compat import string_types +from git.repo.fun import find_git_dir from nose import SkipTest @@ -602,11 +603,9 @@ def test_first_submodule(self, rwrepo): @with_rw_directory def test_add_empty_repo(self, rwdir): - parent_dir = os.path.join(rwdir, 'parent') - os.mkdir(parent_dir) empty_repo_dir = os.path.join(rwdir, 'empty-repo') - parent = git.Repo.init(parent_dir) + parent = git.Repo.init(os.path.join(rwdir, 'parent')) git.Repo.init(empty_repo_dir) for checkout_mode in range(2): @@ -614,3 +613,46 @@ def test_add_empty_repo(self, rwdir): self.failUnlessRaises(ValueError, parent.create_submodule, name, name, url=empty_repo_dir, no_checkout=checkout_mode and True or False) # end for each checkout mode + + def _submodule_url(https://github.com/self): + return os.path.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap') + + @with_rw_directory + def test_git_submodules(self, rwdir): + parent = git.Repo.init(os.path.join(rwdir, 'parent')) + parent.git.submodule('add', self._submodule_url(), 'module') + parent.index.commit("added submodule") + + assert len(parent.submodules) == 1 + sm = parent.submodules[0] + + assert sm.exists() and sm.module_exists() + + # test move and rename + # TODO + + @with_rw_directory + def test_git_submodule_compatibility(self, rwdir): + parent = git.Repo.init(os.path.join(rwdir, 'parent')) + empty_file = os.path.join(parent.working_tree_dir, "empty") + with open(empty_file, 'wb') as fp: + fp.close() + parent.index.add([empty_file]) + parent.index.commit("initial commit - can't yet add submodules to empty parent dir") + + sm_path = 'submodules/intermediate/one' + sm = parent.create_submodule('mymodules/myname', sm_path, url=self._submodule_url()) + parent.index.commit("added submodule") + + # As git is backwards compatible itself, it would still recognize what we do here ... unless we really + # muss it up. That's the only reason why the test is still here ... . + assert len(parent.git.submodule().splitlines()) == 1 + + module_repo_path = os.path.join(sm.module().working_tree_dir, '.git') + assert module_repo_path.startswith(os.path.join(parent.working_tree_dir, sm_path)) + if not sm._need_gitfile_submodules(parent.git): + assert os.path.isdir(module_repo_path) + else: + assert os.path.isfile(module_repo_path) + assert find_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid" + # end verify submodule 'style' From 67680a0877f01177dc827beb49c83a9174cdb736 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 17 Jan 2015 12:38:21 +0100 Subject: [PATCH 0115/2790] Assured Submodule.(update|move) are dealing with .git files appropriately. However, a simple test-case still fails for reasons not yet understood. There is more to be fixed here - .remove() still fails. --- git/objects/submodule/base.py | 152 ++++++++++++++++++++-------------- git/test/test_submodule.py | 14 ++++ 2 files changed, 106 insertions(+), 60 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 13183e29e..fb6e97751 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -25,7 +25,10 @@ InvalidGitRepositoryError, NoSuchPathError ) -from git.compat import string_types +from git.compat import ( + string_types, + defenc +) import stat import git @@ -209,13 +212,64 @@ def _module_abspath(cls, parent_repo, path, name): # end @classmethod - def _write_git_file(cls, working_tree_dir, module_abspath, overwrite_existing=False): + def _clone_repo(cls, repo, url, path, name, **kwargs): + """:return: Repo instance of newly cloned repository + :param repo: our parent repository + :param url: url to clone from + :param path: repository-relative path to the submodule checkout location + :param name: canonical of the submodule + :param kwrags: additinoal arguments given to git.clone""" + module_abspath = cls._module_abspath(repo, path, name) + module_checkout_path = module_abspath + if cls._need_gitfile_submodules(repo.git): + kwargs['separate_git_dir'] = module_abspath + module_abspath_dir = os.path.dirname(module_abspath) + if not os.path.isdir(module_abspath_dir): + os.makedirs(module_abspath_dir) + module_checkout_path = os.path.join(repo.working_tree_dir, path) + # end + + clone = git.Repo.clone_from(url, module_checkout_path, **kwargs) + if cls._need_gitfile_submodules(repo.git): + cls._write_git_file(module_checkout_path, module_abspath) + # end + return clone + + @classmethod + def _to_relative_path(cls, parent_repo, path): + """:return: a path guaranteed to be relative to the given parent-repository + :raise ValueError: if path is not contained in the parent repository's working tree""" + path = to_native_path_linux(path) + if path.endswith('/'): + path = path[:-1] + # END handle trailing slash + + if os.path.isabs(path): + working_tree_linux = to_native_path_linux(parent_repo.working_tree_dir) + if not path.startswith(working_tree_linux): + raise ValueError("Submodule checkout path '%s' needs to be within the parents repository at '%s'" + % (working_tree_linux, path)) + path = path[len(working_tree_linux) + 1:] + if not path: + raise ValueError("Absolute submodule path '%s' didn't yield a valid relative path" % path) + # end verify converted relative path makes sense + # end convert to a relative path + + return path + + @classmethod + def _write_git_file(cls, working_tree_dir, module_abspath): """Writes a .git file containing a (preferably) relative path to the actual git module repository. It is an error if the module_abspath cannot be made into a relative path, relative to the working_tree_dir + :note: will overwrite existing files ! :param working_tree_dir: directory to write the .git file into :param module_abspath: absolute path to the bare repository - :param overwrite_existing: if True, we may rewrite existing .git files, otherwise we raise""" - raise NotImplementedError + """ + git_file = os.path.join(working_tree_dir, '.git') + rela_path = os.path.relpath(module_abspath, start=working_tree_dir) + fp = open(git_file, 'wb') + fp.write(("gitdir: %s" % rela_path).encode(defenc)) + fp.close() #{ Edit Interface @@ -252,21 +306,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): raise InvalidGitRepositoryError("Cannot add submodules to bare repositories") # END handle bare repos - path = to_native_path_linux(path) - if path.endswith('/'): - path = path[:-1] - # END handle trailing slash - - if os.path.isabs(path): - working_tree_linux = to_native_path_linux(repo.working_tree_dir) - if not path.startswith(working_tree_linux): - raise ValueError("Submodule checkout path '%s' needs to be within the parents repository at '%s'" - % (working_tree_linux, path)) - path = path[len(working_tree_linux) + 1:] - if not path: - raise ValueError("Absolute submodule path '%s' didn't yield a valid relative path" % path) - # end verify converted relative path makes sense - # end convert to a relative path + path = cls._to_relative_path(repo, path) # assure we never put backslashes into the url, as some operating systems # like it ... @@ -317,17 +357,9 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): if not branch_is_default: kwargs['b'] = br.name # END setup checkout-branch - module_abspath = cls._module_abspath(repo, path, name) - module_checkout_path = module_abspath - if cls._need_gitfile_submodules(repo.git): - kwargs['separate_git_dir'] = module_abspath - module_abspath_dir = os.path.dirname(module_abspath) - if not os.path.isdir(module_abspath_dir): - os.makedirs(module_abspath_dir) - module_checkout_path = os.path.join(repo.working_tree_dir, path) - # end - - mrepo = git.Repo.clone_from(url, module_checkout_path, **kwargs) + + # _clone_repo(cls, repo, url, path, name, **kwargs): + mrepo = cls._clone_repo(repo, url, path, name, **kwargs) # END verify url # update configuration and index @@ -416,7 +448,6 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= if not init: return self # END early abort if init is not allowed - import git # there is no git-repository yet - but delete empty paths module_path = self._module_abspath(self.repo, self.path, self.name) @@ -433,7 +464,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= progress.update(BEGIN | CLONE, 0, 1, prefix + "Cloning %s to %s in submodule %r" % (self.url, module_path, self.name)) if not dry_run: - mrepo = git.Repo.clone_from(self.url, module_path, n=True) + mrepo = self._clone_repo(self.repo, self.url, self.path, self.name, n=True) # END handle dry-run progress.update(END | CLONE, 0, 1, prefix + "Done cloning to %s" % module_path) @@ -533,16 +564,15 @@ def move(self, module_path, configuration=True, module=True): the repository at our current path, changing the configuration, as well as adjusting our index entry accordingly. - :param module_path: the path to which to move our module, given as - repository-relative path. Intermediate directories will be created + :param module_path: the path to which to move our module in the parent repostory's working tree, + given as repository-relative or absolute path. Intermediate directories will be created accordingly. If the path already exists, it must be empty. - Trailling (back)slashes are removed automatically + Trailing (back)slashes are removed automatically :param configuration: if True, the configuration will be adjusted to let the submodule point to the given path. :param module: if True, the repository managed by this submodule - will be moved, not the configuration. This will effectively - leave your repository in an inconsistent state unless the configuration - and index already point to the target location. + will be moved as well. If False, we don't move the submodule's checkout, which may leave + the parent repository in an inconsistent state. :return: self :raise ValueError: if the module path existed and was not empty, or was a file :note: Currently the method is not atomic, and it could leave the repository @@ -552,53 +582,55 @@ def move(self, module_path, configuration=True, module=True): raise ValueError("You must specify to move at least the module or the configuration of the submodule") # END handle input - module_path = to_native_path_linux(module_path) - if module_path.endswith('/'): - module_path = module_path[:-1] - # END handle trailing slash + module_checkout_path = self._to_relative_path(self.repo, module_path) # VERIFY DESTINATION - if module_path == self.path: + if module_checkout_path == self.path: return self # END handle no change - dest_path = join_path_native(self.repo.working_tree_dir, module_path) - if os.path.isfile(dest_path): - raise ValueError("Cannot move repository onto a file: %s" % dest_path) + module_checkout_abspath = join_path_native(self.repo.working_tree_dir, module_checkout_path) + if os.path.isfile(module_checkout_abspath): + raise ValueError("Cannot move repository onto a file: %s" % module_checkout_abspath) # END handle target files index = self.repo.index - tekey = index.entry_key(module_path, 0) + tekey = index.entry_key(module_checkout_path, 0) # if the target item already exists, fail if configuration and tekey in index.entries: - raise ValueError("Index entry for target path did alredy exist") + raise ValueError("Index entry for target path did already exist") # END handle index key already there # remove existing destination if module: - if os.path.exists(dest_path): - if len(os.listdir(dest_path)): + if os.path.exists(module_checkout_abspath): + if len(os.listdir(module_checkout_abspath)): raise ValueError("Destination module directory was not empty") - # END handle non-emptyness + # END handle non-emptiness - if os.path.islink(dest_path): - os.remove(dest_path) + if os.path.islink(module_checkout_abspath): + os.remove(module_checkout_abspath) else: - os.rmdir(dest_path) + os.rmdir(module_checkout_abspath) # END handle link else: # recreate parent directories # NOTE: renames() does that now pass - # END handle existance + # END handle existence # END handle module # move the module into place if possible cur_path = self.abspath renamed_module = False if module and os.path.exists(cur_path): - os.renames(cur_path, dest_path) + os.renames(cur_path, module_checkout_abspath) renamed_module = True + + if self._need_gitfile_submodules(self.repo.git): + module_abspath = self._module_abspath(self.repo, self.path, self.name) + self._write_git_file(module_checkout_abspath, module_abspath) + # end handle git file rewrite # END move physical module # rename the index entry - have to manipulate the index directly as @@ -609,7 +641,7 @@ def move(self, module_path, configuration=True, module=True): ekey = index.entry_key(self.path, 0) entry = index.entries[ekey] del(index.entries[ekey]) - nentry = git.IndexEntry(entry[:3] + (module_path,) + entry[4:]) + nentry = git.IndexEntry(entry[:3] + (module_checkout_path,) + entry[4:]) index.entries[tekey] = nentry except KeyError: raise InvalidGitRepositoryError("Submodule's entry at %r did not exist" % (self.path)) @@ -617,14 +649,14 @@ def move(self, module_path, configuration=True, module=True): # update configuration writer = self.config_writer(index=index) # auto-write - writer.set_value('path', module_path) - self.path = module_path + writer.set_value('path', module_checkout_path) + self.path = module_checkout_path writer.release() del(writer) # END handle configuration flag except Exception: if renamed_module: - os.renames(dest_path, cur_path) + os.renames(module_checkout_abspath, cur_path) # END undo module renaming raise # END handle undo rename diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 484e73ae3..bb4885024 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -656,3 +656,17 @@ def test_git_submodule_compatibility(self, rwdir): assert os.path.isfile(module_repo_path) assert find_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid" # end verify submodule 'style' + + # test move + new_sm_path = 'submodules/one' + sm.set_parent_commit(parent.commit()) + sm.move(new_sm_path) + assert sm.exists() + assert sm.module_exists() + + # remove + sm.remove() + assert sm.exist() + sm_module_path = sm.module().git_dir + assert sm.module_exists() + assert os.path.isdir(sm_module_path) From c7b16ade191bb753ebadb45efe6be7386f67351d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 17 Jan 2015 15:53:55 +0100 Subject: [PATCH 0116/2790] Submodule.remove() now deals with .git files correctly. A simple test verifies this at least. --- git/objects/submodule/base.py | 44 +++++++++++++++++++++++------------ git/repo/base.py | 8 +++++-- git/test/test_submodule.py | 10 ++++---- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index fb6e97751..ee10aa7d3 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -19,6 +19,7 @@ from git.config import ( SectionConstraint, + GitConfigParser, cp ) from git.exc import ( @@ -231,7 +232,7 @@ def _clone_repo(cls, repo, url, path, name, **kwargs): clone = git.Repo.clone_from(url, module_checkout_path, **kwargs) if cls._need_gitfile_submodules(repo.git): - cls._write_git_file(module_checkout_path, module_abspath) + cls._write_git_file_and_module_config(module_checkout_path, module_abspath) # end return clone @@ -258,10 +259,13 @@ def _to_relative_path(cls, parent_repo, path): return path @classmethod - def _write_git_file(cls, working_tree_dir, module_abspath): + def _write_git_file_and_module_config(cls, working_tree_dir, module_abspath): """Writes a .git file containing a (preferably) relative path to the actual git module repository. It is an error if the module_abspath cannot be made into a relative path, relative to the working_tree_dir :note: will overwrite existing files ! + :note: as we rewrite both the git file as well as the module configuration, we might fail on the configuration + and will not roll back changes done to the git file. This should be a non-issue, but may easily be fixed + if it becomes one :param working_tree_dir: directory to write the .git file into :param module_abspath: absolute path to the bare repository """ @@ -271,6 +275,10 @@ def _write_git_file(cls, working_tree_dir, module_abspath): fp.write(("gitdir: %s" % rela_path).encode(defenc)) fp.close() + writer = GitConfigParser(os.path.join(module_abspath, 'config'), read_only=False, merge_includes=False) + writer.set_value('core', 'worktree', os.path.relpath(working_tree_dir, start=module_abspath)) + writer.release() + #{ Edit Interface @classmethod @@ -629,7 +637,7 @@ def move(self, module_path, configuration=True, module=True): if self._need_gitfile_submodules(self.repo.git): module_abspath = self._module_abspath(self.repo, self.path, self.name) - self._write_git_file(module_checkout_abspath, module_abspath) + self._write_git_file_and_module_config(module_checkout_abspath, module_abspath) # end handle git file rewrite # END move physical module @@ -668,7 +676,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): """Remove this submodule from the repository. This will remove our entry from the .gitmodules file and the entry in the .git/config file. - :param module: If True, the module we point to will be deleted + :param module: If True, the module checkout we point to will be deleted as well. If the module is currently on a commit which is not part of any branch in the remote, if the currently checked out branch working tree, or untracked files, @@ -687,15 +695,25 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): we would usually throw :return: self :note: doesn't work in bare repositories + :note: doesn't work atomically, as failure to remove any part of the submodule will leave + an inconsistent state :raise InvalidGitRepositoryError: thrown if the repository cannot be deleted :raise OSError: if directories or files could not be removed""" if not (module + configuration): raise ValueError("Need to specify to delete at least the module, or the configuration") - # END handle params + # END handle parameters + + # Recursively remove children of this submodule + for csm in self.children(): + csm.remove(module, force, configuration, dry_run) + del(csm) + # end - # DELETE MODULE REPOSITORY - ########################## + # DELETE REPOSITORY WORKING TREE + ################################ if module and self.module_exists(): + mod = self.module() + git_dir = mod.git_dir if force: # take the fast lane and just delete everything in our module path # TODO: If we run into permission problems, we have a highly inconsistent @@ -715,7 +733,6 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): # END apply deletion method else: # verify we may delete our module - mod = self.module() if mod.is_dirty(untracked_files=True): raise InvalidGitRepositoryError( "Cannot delete module at %s with any modifications, unless force is specified" @@ -747,12 +764,6 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): del(remote) # END for each remote - # gently remove all submodule repositories - for sm in self.children(): - sm.remove(module=True, force=False, configuration=False, dry_run=dry_run) - del(sm) - # END for each child-submodule - # finally delete our own submodule if not dry_run: wtd = mod.working_tree_dir @@ -760,6 +771,10 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): rmtree(wtd) # END delete tree if possible # END handle force + + if os.path.isdir(git_dir): + rmtree(git_dir) + # end handle separate bare repository # END handle module deletion # DELETE CONFIGURATION @@ -786,7 +801,6 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): # void our data not to delay invalid access self._clear_cache() - return self def set_parent_commit(self, commit, check=True): diff --git a/git/repo/base.py b/git/repo/base.py index 6d9af6d47..74e72aa56 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -131,14 +131,18 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals # walk up the path to find the .git dir while curpath: + # ABOUT os.path.NORMPATH + # It's important to normalize the paths, as submodules will otherwise initialize their + # repo instances with paths that depend on path-portions that will not exist after being + # removed. It's just cleaner. if is_git_dir(curpath): - self.git_dir = curpath + self.git_dir = os.path.normpath(curpath) self._working_tree_dir = os.path.dirname(self.git_dir) break gitpath = find_git_dir(join(curpath, '.git')) if gitpath is not None: - self.git_dir = gitpath + self.git_dir = os.path.normpath(gitpath) self._working_tree_dir = curpath break diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index bb4885024..764121237 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -665,8 +665,10 @@ def test_git_submodule_compatibility(self, rwdir): assert sm.module_exists() # remove - sm.remove() - assert sm.exist() sm_module_path = sm.module().git_dir - assert sm.module_exists() - assert os.path.isdir(sm_module_path) + sm.remove() + assert not sm.exists() + assert not sm.module_exists() + assert not os.path.isdir(sm_module_path) + + From ae2b59625e9bde14b1d2d476e678326886ab1552 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 17 Jan 2015 16:30:56 +0100 Subject: [PATCH 0117/2790] Made sure dry-run is properly implemented in Submodule.remove() The root-submodule test is still failing though, this time even earlier than before --- git/objects/submodule/base.py | 20 +++++++++++++------- git/test/test_submodule.py | 11 +++++++---- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index ee10aa7d3..15ba8a0d0 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -672,7 +672,7 @@ def move(self, module_path, configuration=True, module=True): return self @unbare_repo - def remove(self, module=True, force=False, configuration=True, dry_run=False): + def remove(self, module=True, force=False, configuration=True, dry_run=False, _is_recursive=False): """Remove this submodule from the repository. This will remove our entry from the .gitmodules file and the entry in the .git/config file. @@ -705,7 +705,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): # Recursively remove children of this submodule for csm in self.children(): - csm.remove(module, force, configuration, dry_run) + csm.remove(module, force, configuration, dry_run, _is_recursive=True) del(csm) # end @@ -772,7 +772,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): # END delete tree if possible # END handle force - if os.path.isdir(git_dir): + if not dry_run and os.path.isdir(git_dir): rmtree(git_dir) # end handle separate bare repository # END handle module deletion @@ -781,22 +781,28 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): ###################### if configuration and not dry_run: # first the index-entry - index = self.repo.index + parent_index = self.repo.index try: - del(index.entries[index.entry_key(self.path, 0)]) + del(parent_index.entries[parent_index.entry_key(self.path, 0)]) except KeyError: pass # END delete entry - index.write() + parent_index.write() # now git config - need the config intact, otherwise we can't query - # inforamtion anymore + # information anymore writer = self.repo.config_writer() writer.remove_section(sm_section(self.name)) writer.release() writer = self.config_writer() writer.remove_section() writer.release() + + # Assure we don't leave the parent repository in a dirty state, and commit our changes + # It's important for recursive, unforced, deletions to work as expected + if _is_recursive: + self.module().index.commit("Removed submodule '%s'" % self.name) + # end # END delete configuration # void our data not to delay invalid access diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 764121237..ace7ab07c 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -666,9 +666,12 @@ def test_git_submodule_compatibility(self, rwdir): # remove sm_module_path = sm.module().git_dir - sm.remove() - assert not sm.exists() - assert not sm.module_exists() - assert not os.path.isdir(sm_module_path) + + for dry_run in (True, False): + sm.remove(dry_run=dry_run) + assert sm.exists() == dry_run + assert sm.module_exists() == dry_run + assert os.path.isdir(sm_module_path) == dry_run + # end for each dry-run mode From c15a6e1923a14bc760851913858a3942a4193cdb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 17 Jan 2015 17:19:06 +0100 Subject: [PATCH 0118/2790] Submodule.remove() now seems to work properly, nearly all tests are back. This also means that now we seem to be able to properly handle .git files in submodules Related to #233 --- git/objects/submodule/base.py | 38 ++++++++++++++++++----------------- git/repo/base.py | 4 ++-- git/test/test_submodule.py | 17 ++++++++++++---- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 15ba8a0d0..26bdd54e3 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -572,14 +572,14 @@ def move(self, module_path, configuration=True, module=True): the repository at our current path, changing the configuration, as well as adjusting our index entry accordingly. - :param module_path: the path to which to move our module in the parent repostory's working tree, + :param module_path: the path to which to move our module in the parent repostory's working tree, given as repository-relative or absolute path. Intermediate directories will be created accordingly. If the path already exists, it must be empty. Trailing (back)slashes are removed automatically :param configuration: if True, the configuration will be adjusted to let the submodule point to the given path. :param module: if True, the repository managed by this submodule - will be moved as well. If False, we don't move the submodule's checkout, which may leave + will be moved as well. If False, we don't move the submodule's checkout, which may leave the parent repository in an inconsistent state. :return: self :raise ValueError: if the module path existed and was not empty, or was a file @@ -672,7 +672,7 @@ def move(self, module_path, configuration=True, module=True): return self @unbare_repo - def remove(self, module=True, force=False, configuration=True, dry_run=False, _is_recursive=False): + def remove(self, module=True, force=False, configuration=True, dry_run=False): """Remove this submodule from the repository. This will remove our entry from the .gitmodules file and the entry in the .git/config file. @@ -695,7 +695,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False, _i we would usually throw :return: self :note: doesn't work in bare repositories - :note: doesn't work atomically, as failure to remove any part of the submodule will leave + :note: doesn't work atomically, as failure to remove any part of the submodule will leave an inconsistent state :raise InvalidGitRepositoryError: thrown if the repository cannot be deleted :raise OSError: if directories or files could not be removed""" @@ -704,10 +704,17 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False, _i # END handle parameters # Recursively remove children of this submodule + nc = 0 for csm in self.children(): - csm.remove(module, force, configuration, dry_run, _is_recursive=True) + nc += 1 + csm.remove(module, force, configuration, dry_run) del(csm) - # end + # end + if nc > 0: + # Assure we don't leave the parent repository in a dirty state, and commit our changes + # It's important for recursive, unforced, deletions to work as expected + self.module().index.commit("Removed submodule '%s'" % self.name) + # end handle recursion # DELETE REPOSITORY WORKING TREE ################################ @@ -733,7 +740,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False, _i # END apply deletion method else: # verify we may delete our module - if mod.is_dirty(untracked_files=True): + if mod.is_dirty(index=True, working_tree=True, untracked_files=True): raise InvalidGitRepositoryError( "Cannot delete module at %s with any modifications, unless force is specified" % mod.working_tree_dir) @@ -743,7 +750,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False, _i # NOTE: If the user pulled all the time, the remote heads might # not have been updated, so commits coming from the remote look # as if they come from us. But we stay strictly read-only and - # don't fetch beforhand. + # don't fetch beforehand. for remote in mod.remotes: num_branches_with_new_commits = 0 rrefs = remote.refs @@ -794,15 +801,10 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False, _i writer = self.repo.config_writer() writer.remove_section(sm_section(self.name)) writer.release() + writer = self.config_writer() writer.remove_section() writer.release() - - # Assure we don't leave the parent repository in a dirty state, and commit our changes - # It's important for recursive, unforced, deletions to work as expected - if _is_recursive: - self.module().index.commit("Removed submodule '%s'" % self.name) - # end # END delete configuration # void our data not to delay invalid access @@ -875,16 +877,16 @@ def module(self): :raise InvalidGitRepositoryError: if a repository was not available. This could also mean that it was not yet initialized""" # late import to workaround circular dependencies - module_path = self.abspath + module_checkout_abspath = self.abspath try: - repo = git.Repo(module_path) + repo = git.Repo(module_checkout_abspath) if repo != self.repo: return repo # END handle repo uninitialized except (InvalidGitRepositoryError, NoSuchPathError): - raise InvalidGitRepositoryError("No valid repository at %s" % self.path) + raise InvalidGitRepositoryError("No valid repository at %s" % module_checkout_abspath) else: - raise InvalidGitRepositoryError("Repository at %r was not yet checked out" % module_path) + raise InvalidGitRepositoryError("Repository at %r was not yet checked out" % module_checkout_abspath) # END handle exceptions def module_exists(self): diff --git a/git/repo/base.py b/git/repo/base.py index 74e72aa56..f3dd05b3c 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -132,8 +132,8 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals # walk up the path to find the .git dir while curpath: # ABOUT os.path.NORMPATH - # It's important to normalize the paths, as submodules will otherwise initialize their - # repo instances with paths that depend on path-portions that will not exist after being + # It's important to normalize the paths, as submodules will otherwise initialize their + # repo instances with paths that depend on path-portions that will not exist after being # removed. It's just cleaner. if is_git_dir(curpath): self.git_dir = os.path.normpath(curpath) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index ace7ab07c..dc6c8a1ae 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -508,7 +508,11 @@ def test_root_module(self, rwrepo): rm.update(recursive=False, dry_run=True) assert os.path.isdir(smp) - rm.update(recursive=False) + # when removing submodules, we may get new commits as nested submodules are auto-committing changes + # to allow deletions without force, as the index would be dirty otherwise. + # QUESTION: Why does this seem to work in test_git_submodule_compatibility() ? + self.failUnlessRaises(InvalidGitRepositoryError, rm.update, recursive=False, force_remove=False) + rm.update(recursive=False, force_remove=True) assert not os.path.isdir(smp) # change url @@ -664,14 +668,19 @@ def test_git_submodule_compatibility(self, rwdir): assert sm.exists() assert sm.module_exists() + # Add additional submodule level + sm.module().create_submodule('nested-submodule', 'nested-submodule/working-tree', + url=self._submodule_url()) + sm.module().index.commit("added nested submodule") + # Fails because there are new commits, compared to the remote we cloned from + self.failUnlessRaises(InvalidGitRepositoryError, sm.remove, dry_run=True) + # remove sm_module_path = sm.module().git_dir for dry_run in (True, False): - sm.remove(dry_run=dry_run) + sm.remove(dry_run=dry_run, force=True) assert sm.exists() == dry_run assert sm.module_exists() == dry_run assert os.path.isdir(sm_module_path) == dry_run # end for each dry-run mode - - From d4ce247c0380e3806e47b5b3e2b66c29c3ab2680 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 12:34:17 +0100 Subject: [PATCH 0119/2790] Basic submodule tests are working once again ! After all, it was easier than expected. It seems that previous assertions the test made should have never been true to begin with. Thus we might have improved the test thanks to our improved implementation. Fixes #233 --- git/objects/submodule/base.py | 28 ++++++++++++++++++---------- git/test/test_submodule.py | 26 +++++++++++++++----------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 26bdd54e3..3e3eed784 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -458,23 +458,24 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= # END early abort if init is not allowed # there is no git-repository yet - but delete empty paths - module_path = self._module_abspath(self.repo, self.path, self.name) - if not dry_run and os.path.isdir(module_path): + checkout_module_abspath = self.abspath + if not dry_run and os.path.isdir(checkout_module_abspath): try: - os.rmdir(module_path) + os.rmdir(checkout_module_abspath) except OSError: - raise OSError("Module directory at %r does already exist and is non-empty" % module_path) + raise OSError("Module directory at %r does already exist and is non-empty" + % checkout_module_abspath) # END handle OSError # END handle directory removal # don't check it out at first - nonetheless it will create a local # branch according to the remote-HEAD if possible progress.update(BEGIN | CLONE, 0, 1, prefix + "Cloning %s to %s in submodule %r" % - (self.url, module_path, self.name)) + (self.url, checkout_module_abspath, self.name)) if not dry_run: mrepo = self._clone_repo(self.repo, self.url, self.path, self.name, n=True) # END handle dry-run - progress.update(END | CLONE, 0, 1, prefix + "Done cloning to %s" % module_path) + progress.update(END | CLONE, 0, 1, prefix + "Done cloning to %s" % checkout_module_abspath) if not dry_run: # see whether we have a valid branch to checkout @@ -784,6 +785,10 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): # end handle separate bare repository # END handle module deletion + # void our data not to delay invalid access + if not dry_run: + self._clear_cache() + # DELETE CONFIGURATION ###################### if configuration and not dry_run: @@ -807,8 +812,6 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): writer.release() # END delete configuration - # void our data not to delay invalid access - self._clear_cache() return self def set_parent_commit(self, commit, check=True): @@ -840,10 +843,15 @@ def set_parent_commit(self, commit, check=True): # END handle checking mode # update our sha, it could have changed - self.binsha = pctree[self.path].binsha + # If check is False, we might see a parent-commit that doens't even contain the submodule anymore. + # in that case, mark our sha as being NULL + try: + self.binsha = pctree[self.path].binsha + except KeyError: + self.binsha = self.NULL_BIN_SHA + # end self._clear_cache() - return self @unbare_repo diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index dc6c8a1ae..7fe882e1c 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -1,6 +1,5 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -import shutil import sys import os @@ -18,8 +17,6 @@ from git.compat import string_types from git.repo.fun import find_git_dir -from nose import SkipTest - # Change the configuration if possible to prevent the underlying memory manager # to keep file handles open. On windows we get problems as they are not properly # closed due to mmap bugs on windows (as it appears) @@ -46,7 +43,7 @@ def update(self, op, index, max_count, message=''): class TestSubmodule(TestBase): - k_subm_current = "468cad66ff1f80ddaeee4123c24e4d53a032c00d" + k_subm_current = "c15a6e1923a14bc760851913858a3942a4193cdb" k_subm_changed = "394ed7006ee5dc8bddfd132b64001d5dfc0ffdd3" k_no_subm_tag = "0.1.6" @@ -67,7 +64,7 @@ def _do_base_tests(self, rwrepo): assert sm.path == 'git/ext/gitdb' assert sm.path != sm.name # in our case, we have ids there, which don't equal the path - assert sm.url == 'git://github.com/gitpython-developers/gitdb.git' + assert sm.url.endswith('github.com/gitpython-developers/gitdb.git') assert sm.branch_path == 'refs/heads/master' # the default ... assert sm.branch_name == 'master' assert sm.parent_commit == rwrepo.head.commit @@ -184,7 +181,9 @@ def _do_base_tests(self, rwrepo): assert sm.module().head.ref.tracking_branch() is not None # delete the whole directory and re-initialize - shutil.rmtree(sm.abspath) + assert len(sm.children()) != 0 + # shutil.rmtree(sm.abspath) + sm.remove(force=True, configuration=False) assert len(sm.children()) == 0 # dry-run does nothing sm.update(dry_run=True, recursive=False, progress=prog) @@ -277,9 +276,12 @@ def _do_base_tests(self, rwrepo): # enforce the submodule to be checked out at the right spot as well. csm.update() + assert csm.module_exists() + assert csm.exists() + assert os.path.isdir(csm.module().working_tree_dir) # this would work - assert sm.remove(dry_run=True) is sm + assert sm.remove(force=True, dry_run=True) is sm assert sm.module_exists() sm.remove(force=True, dry_run=True) assert sm.module_exists() @@ -291,17 +293,20 @@ def _do_base_tests(self, rwrepo): # forcibly delete the child repository prev_count = len(sm.children()) - assert csm.remove(force=True) is csm + self.failUnlessRaises(ValueError, csm.remove, force=True) + # We removed sm, which removed all submodules. Howver, the instance we have + # still points to the commit prior to that, where it still existed + csm.set_parent_commit(csm.repo.commit(), check=False) assert not csm.exists() assert not csm.module_exists() - assert len(sm.children()) == prev_count - 1 + assert len(sm.children()) == prev_count # now we have a changed index, as configuration was altered. # fix this sm.module().index.reset(working_tree=True) # now delete only the module of the main submodule assert sm.module_exists() - sm.remove(configuration=False) + sm.remove(configuration=False, force=True) assert sm.exists() assert not sm.module_exists() assert sm.config_reader().get_value('url') @@ -391,7 +396,6 @@ def _do_base_tests(self, rwrepo): @with_rw_repo(k_subm_current) def test_base_rw(self, rwrepo): - raise SkipTest("Disabled as long as it fails and submodule support wasn't overhauled") self._do_base_tests(rwrepo) @with_rw_repo(k_subm_current, bare=True) From a223c7b7730c53c3fa1e4c019bd3daefbb8fd74b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 13:52:54 +0100 Subject: [PATCH 0120/2790] Submodule.move() fixed to deal with 'non-gitfile' clones appropriately. Improved a test to assure multiple update(init=False|True) calls don't throw. Fixes #93 --- git/objects/submodule/base.py | 2 +- git/test/test_submodule.py | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 3e3eed784..1d05609da 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -636,7 +636,7 @@ def move(self, module_path, configuration=True, module=True): os.renames(cur_path, module_checkout_abspath) renamed_module = True - if self._need_gitfile_submodules(self.repo.git): + if os.path.isfile(os.path.join(module_checkout_abspath, '.git')): module_abspath = self._module_abspath(self.repo, self.path, self.name) self._write_git_file_and_module_config(module_checkout_abspath, module_abspath) # end handle git file rewrite diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 7fe882e1c..7cd86bd95 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -377,8 +377,6 @@ def _do_base_tests(self, rwrepo): assert nsm.path == pmp assert rwrepo.submodules[0].path == pmp - # TODO lowprio: test remaining exceptions ... for now its okay, the code looks right - # REMOVE 'EM ALL ################ # if a submodule's repo has no remotes, it can't be added without an explicit url @@ -636,8 +634,20 @@ def test_git_submodules(self, rwdir): assert sm.exists() and sm.module_exists() - # test move and rename - # TODO + clone = git.Repo.clone_from(self._submodule_url(), + os.path.join(parent.working_tree_dir, 'existing-subrepository')) + sm2 = parent.create_submodule('nongit-file-submodule', clone.working_tree_dir) + assert len(parent.submodules) == 2 + + for _ in range(2): + for init in (False, True): + sm.update(init=init) + sm2.update(init=init) + # end for each init state + # end for each iteration + + sm.move(sm.path + '_moved') + sm2.move(sm2.path + '_moved') @with_rw_directory def test_git_submodule_compatibility(self, rwdir): From 20863cfe4a1b0c5bea18677470a969073570e41c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 16:57:11 +0100 Subject: [PATCH 0121/2790] Implemented Submodule.rename() A test verifies it's truly working. Related to #238 --- doc/source/changes.rst | 2 + git/config.py | 22 +++++++++- git/objects/submodule/base.py | 82 +++++++++++++++++++++++++++++++++-- git/repo/base.py | 9 ++++ git/test/test_config.py | 13 ++++++ git/test/test_repo.py | 2 + git/test/test_submodule.py | 23 ++++++++++ 7 files changed, 147 insertions(+), 6 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index d81f90a6b..2277c4b7e 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -6,6 +6,8 @@ Changelog ================ * Added `Repo.merge_base()` implementation. See the `respective issue on github `_ * `[include]` sections in git configuration files are now respected +* Added `GitConfigParser.rename_section()` +* Added `Submodule.rename()` * A list of all issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+ 0.3.5 - Bugfixes diff --git a/git/config.py b/git/config.py index 4c4cb4912..f41a86e67 100644 --- a/git/config.py +++ b/git/config.py @@ -478,8 +478,6 @@ def _assure_writable(self, method_name): if self.read_only: raise IOError("Cannot execute non-constant method %s.%s" % (self, method_name)) - @needs_values - @set_dirty_and_flush_changes def add_section(self, section): """Assures added options will stay in order""" return super(GitConfigParser, self).add_section(section) @@ -546,3 +544,23 @@ def set_value(self, section, option, value): if not self.has_section(section): self.add_section(section) self.set(section, option, str(value)) + + def rename_section(self, section, new_name): + """rename the given section to new_name + :raise ValueError: if section doesn't exit + :raise ValueError: if a section with new_name does already exist + :return: this instance + """ + if not self.has_section(section): + raise ValueError("Source section '%s' doesn't exist" % section) + if self.has_section(new_name): + raise ValueError("Destination section '%s' already exists" % new_name) + + super(GitConfigParser, self).add_section(new_name) + for k, v in self.items(section): + self.set(new_name, k, str(v)) + # end for each value to copy + + # This call writes back the changes, which is why we don't have the respective decorator + self.remove_section(section) + return self diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 1d05609da..f5ff457db 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -109,7 +109,12 @@ def __init__(self, repo, binsha, mode=None, path=None, name=None, parent_commit= def _set_cache_(self, attr): if attr == '_parent_commit': # set a default value, which is the root tree of the current head - self._parent_commit = self.repo.commit() + try: + self._parent_commit = self.repo.commit() + except ValueError: + # This fails in an empty repository. + self._parent_commit = None + # end exception handling elif attr in ('path', '_url', '_branch_path'): reader = self.config_reader() # default submodule values @@ -163,7 +168,13 @@ def _config_parser(cls, repo, parent_commit, read_only): :raise IOError: If the .gitmodules file cannot be found, either locally or in the repository at the given parent commit. Otherwise the exception would be delayed until the first access of the config parser""" - parent_matches_head = repo.head.commit == parent_commit + try: + parent_matches_head = repo.head.commit == parent_commit + except ValueError: + # We are most likely in an empty repository, so the HEAD doesn't point to a valid ref + parent_matches_head = True + # end + if not repo.bare and parent_matches_head: fp_module = os.path.join(repo.working_tree_dir, cls.k_modules_file) else: @@ -370,6 +381,14 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): mrepo = cls._clone_repo(repo, url, path, name, **kwargs) # END verify url + # It's important to add the URL to the parent config, to let `git submodule` know. + # otherwise there is a '-' character in front of the submodule listing + # a38efa84daef914e4de58d1905a500d8d14aaf45 mymodule (v0.9.0-1-ga38efa8) + # -a38efa84daef914e4de58d1905a500d8d14aaf45 submodules/intermediate/one + writer = sm.repo.config_writer() + writer.set_value(sm_section(name), 'url', url) + writer.release() + # update configuration and index index = sm.repo.index writer = sm.config_writer(index=index, write=False) @@ -386,11 +405,23 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): del(writer) # we deliberatly assume that our head matches our index ! - pcommit = repo.head.commit - sm._parent_commit = pcommit + parent_repo_is_empty = False + try: + sm._parent_commit = repo.head.commit + except ValueError: + parent_repo_is_empty = True + # Can't set this yet, if the parent repo is empty. + # end sm.binsha = mrepo.head.commit.binsha index.add([sm], write=True) + if parent_repo_is_empty: + # The user is expected to make a commit, and this submodule will initialize itself when + # _parent_commit is required + del sm._parent_commit + log.debug("Will not set _parent_commit now as the parent repository has no commit yet.") + # end + return sm def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, @@ -875,6 +906,49 @@ def config_writer(self, index=None, write=True): writer.config._auto_write = write return writer + @unbare_repo + def rename(self, new_name): + """Rename this submodule + :note: This method takes care of renaming the submodule in various places, such as + + * $parent_git_dir/config + * $working_tree_dir/.gitmodules + * (git >=v1.8.0: move submodule repository to new name) + + As .gitmodules will be changed, you would need to make a commit afterwards. The changed .gitmodules file + will already be added to the index + + :return: this submodule instance + """ + if self.name == new_name: + return self + + # .git/config + pw = self.repo.config_writer() + # As we ourselves didn't write anything about submodules into the parent .git/config, we will not require + # it to exist, and just ignore missing entries + if pw.has_section(sm_section(self.name)): + pw.rename_section(sm_section(self.name), sm_section(new_name)) + # end + pw.release() + + # .gitmodules + cw = self.config_writer().config + cw.rename_section(sm_section(self.name), sm_section(new_name)) + cw.release() + + self._name = new_name + + # .git/modules + mod = self.module() + if mod.has_separate_working_tree(): + module_abspath = self._module_abspath(self.repo, self.path, new_name) + os.renames(mod.git_dir, module_abspath) + self._write_git_file_and_module_config(mod.working_tree_dir, module_abspath) + # end move separate git repository + + return self + #} END edit interface #{ Query Interface diff --git a/git/repo/base.py b/git/repo/base.py index f3dd05b3c..9ddb1ce81 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -868,6 +868,15 @@ def archive(self, ostream, treeish=None, prefix=None, **kwargs): self.git.archive(treeish, *path, **kwargs) return self + def has_separate_working_tree(self): + """:return: True if our git_dir is not at the root of our working_tree_dir, but a .git file with a + platform agnositic symbolic link. Our git_dir will be whereever the .git file points to + :note: bare repositories will always return False here + """ + if self.bare: + return False + return os.path.isfile(os.path.join(self.working_tree_dir, '.git')) + rev_parse = rev_parse def __repr__(self): diff --git a/git/test/test_config.py b/git/test/test_config.py index 9a44d9e38..286d151e3 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -193,3 +193,16 @@ def check_test_value(cr, value): cr = GitConfigParser(fpa, read_only=True) check_test_value(cr, tv) cr.release() + + def test_rename(self): + file_obj = self._to_memcache(fixture_path('git_config')) + cw = GitConfigParser(file_obj, read_only=False, merge_includes=False) + + self.failUnlessRaises(ValueError, cw.rename_section, "doesntexist", "foo") + self.failUnlessRaises(ValueError, cw.rename_section, "core", "include") + + nn = "bee" + assert cw.rename_section('core', nn) is cw + assert not cw.has_section('core') + assert len(cw.items(nn)) == 4 + cw.release() diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 226c1d268..c583fcae4 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -164,6 +164,7 @@ def test_init(self): r = Repo.init(path=path, bare=True) assert isinstance(r, Repo) assert r.bare is True + assert not r.has_separate_working_tree() assert os.path.isdir(r.git_dir) self._assert_empty_repo(r) @@ -200,6 +201,7 @@ def test_init(self): os.chdir(git_dir_rela) r = Repo.init(bare=False) assert r.bare is False + assert not r.has_separate_working_tree() self._assert_empty_repo(r) finally: diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 7cd86bd95..813b15da8 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -670,8 +670,10 @@ def test_git_submodule_compatibility(self, rwdir): assert module_repo_path.startswith(os.path.join(parent.working_tree_dir, sm_path)) if not sm._need_gitfile_submodules(parent.git): assert os.path.isdir(module_repo_path) + assert not sm.module().has_separate_working_tree() else: assert os.path.isfile(module_repo_path) + assert sm.module().has_separate_working_tree() assert find_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid" # end verify submodule 'style' @@ -689,6 +691,8 @@ def test_git_submodule_compatibility(self, rwdir): # Fails because there are new commits, compared to the remote we cloned from self.failUnlessRaises(InvalidGitRepositoryError, sm.remove, dry_run=True) + # TODO: rename nested submodule + # remove sm_module_path = sm.module().git_dir @@ -698,3 +702,22 @@ def test_git_submodule_compatibility(self, rwdir): assert sm.module_exists() == dry_run assert os.path.isdir(sm_module_path) == dry_run # end for each dry-run mode + + @with_rw_directory + def test_rename(self, rwdir): + parent = git.Repo.init(os.path.join(rwdir, 'parent')) + sm_name = 'mymodules/myname' + sm = parent.create_submodule(sm_name, 'submodules/intermediate/one', url=self._submodule_url()) + parent.index.commit("Added submodule") + assert sm._parent_commit is not None + + assert sm.rename(sm_name) is sm and sm.name == sm_name + + new_sm_name = "shortname" + assert sm.rename(new_sm_name) is sm + assert sm.exists() + + sm_mod = sm.module() + if os.path.isfile(os.path.join(sm_mod.working_tree_dir, '.git')) == sm._need_gitfile_submodules(parent.git): + assert sm_mod.git_dir.endswith(".git/modules/" + new_sm_name) + # end From aaa84341f876927b545abdc674c811d60af00561 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 17:04:50 +0100 Subject: [PATCH 0122/2790] Submodule.move() will auto-rename the submodule if the name was equal to the path Fixes #238 --- git/objects/submodule/base.py | 6 ++++++ git/test/test_submodule.py | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index f5ff457db..285d24235 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -675,6 +675,7 @@ def move(self, module_path, configuration=True, module=True): # rename the index entry - have to manipulate the index directly as # git-mv cannot be used on submodules ... yeah + previous_sm_path = self.path try: if configuration: try: @@ -701,6 +702,11 @@ def move(self, module_path, configuration=True, module=True): raise # END handle undo rename + # Auto-rename submodule if it's name was 'default', that is, the checkout directory + if previous_sm_path == self.name: + self.rename(module_checkout_path) + # end + return self @unbare_repo diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 813b15da8..767d84196 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -707,12 +707,15 @@ def test_git_submodule_compatibility(self, rwdir): def test_rename(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) sm_name = 'mymodules/myname' - sm = parent.create_submodule(sm_name, 'submodules/intermediate/one', url=self._submodule_url()) + sm = parent.create_submodule(sm_name, sm_name, url=self._submodule_url()) parent.index.commit("Added submodule") assert sm._parent_commit is not None assert sm.rename(sm_name) is sm and sm.name == sm_name + new_path = 'renamed/myname' + assert sm.move(new_path).name == new_path + new_sm_name = "shortname" assert sm.rename(new_sm_name) is sm assert sm.exists() From d5054fdb1766cb035a1186c3cef4a14472fee98d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 17:47:16 +0100 Subject: [PATCH 0123/2790] Fixed configuration file test - release call was missing. Once again, __del__ is not being called as usual anymore in python 3 ... . --- git/test/test_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/git/test/test_config.py b/git/test/test_config.py index 286d151e3..fc2b87b68 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -73,6 +73,7 @@ def test_read_write(self): assert r_config.has_section(sname) assert r_config.has_option(sname, oname) assert r_config.get(sname, oname) == val + w_config.release() # END for each filename def test_multi_line_config(self): From df95149198744c258ed6856044ac5e79e6b81404 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 18:10:16 +0100 Subject: [PATCH 0124/2790] Improved unicode handling when using os.environ or GitConfigParser Assured unicode values are supported when reading the configuration, and when getting author/committer information from the environment. Fixes #237 --- git/config.py | 12 +++++++++--- git/test/test_index.py | 3 ++- git/util.py | 12 ++++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/git/config.py b/git/config.py index f41a86e67..ed61bf934 100644 --- a/git/config.py +++ b/git/config.py @@ -23,6 +23,7 @@ string_types, FileType, defenc, + force_text, with_metaclass, PY3 ) @@ -412,7 +413,7 @@ def write_section(name, section_dict): fp.write(("[%s]\n" % name).encode(defenc)) for (key, value) in section_dict.items(): if key != "__name__": - fp.write(("\t%s = %s\n" % (key, str(value).replace('\n', '\n\t'))).encode(defenc)) + fp.write(("\t%s = %s\n" % (key, self._value_to_string(value).replace('\n', '\n\t'))).encode(defenc)) # END if key is not __name__ # END section writing @@ -529,6 +530,11 @@ def get_value(self, section, option, default=None): return valuestr + def _value_to_string(self, value): + if isinstance(value, (int, float, bool)): + return str(value) + return force_text(value) + @needs_values @set_dirty_and_flush_changes def set_value(self, section, option, value): @@ -543,7 +549,7 @@ def set_value(self, section, option, value): to a string""" if not self.has_section(section): self.add_section(section) - self.set(section, option, str(value)) + self.set(section, option, self._value_to_string(value)) def rename_section(self, section, new_name): """rename the given section to new_name @@ -558,7 +564,7 @@ def rename_section(self, section, new_name): super(GitConfigParser, self).add_section(new_name) for k, v in self.items(section): - self.set(new_name, k, str(v)) + self.set(new_name, k, self._value_to_string(v)) # end for each value to copy # This call writes back the changes, which is why we don't have the respective decorator diff --git a/git/test/test_index.py b/git/test/test_index.py index 2be776cd0..0569f40fe 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -381,12 +381,13 @@ def test_index_mutation(self, rw_repo): num_entries = len(index.entries) cur_head = rw_repo.head - uname = "Some Developer" + uname = u"Thomas Müller" umail = "sd@company.com" writer = rw_repo.config_writer() writer.set_value("user", "name", uname) writer.set_value("user", "email", umail) writer.release() + assert writer.get_value("user", "name") == uname # remove all of the files, provide a wild mix of paths, BaseIndexEntries, # IndexEntries diff --git a/git/util.py b/git/util.py index 010130cbc..5385455a7 100644 --- a/git/util.py +++ b/git/util.py @@ -17,7 +17,11 @@ # NOTE: Some of the unused imports might be used/imported by others. # Handle once test-cases are back up and running. from .exc import GitCommandError -from .compat import MAXSIZE +from .compat import ( + MAXSIZE, + defenc, + PY3 +) # Most of these are unused here, but are for use by git-python modules so these # don't see gitdb all the time. Flake of course doesn't like it. @@ -364,7 +368,11 @@ def _main_actor(cls, env_name, env_email, config_reader=None): for attr, evar, cvar, default in (('name', env_name, cls.conf_name, default_name), ('email', env_email, cls.conf_email, default_email)): try: - setattr(actor, attr, os.environ[evar]) + val = os.environ[evar] + if not PY3: + val = val.decode(defenc) + # end assure we don't get 'invalid strings' + setattr(actor, attr, val) except KeyError: if config_reader is not None: setattr(actor, attr, config_reader.get_value('user', cvar, default)) From 048ffa58468521c043de567f620003457b8b3dbe Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 18:36:33 +0100 Subject: [PATCH 0125/2790] Improved installation docs to mention `pip`, not `easy_install` Fixes #235 [ci skip] --- doc/source/intro.rst | 19 +++++++------------ git/repo/base.py | 5 +++-- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/doc/source/intro.rst b/doc/source/intro.rst index 8dac28047..b767ccd79 100644 --- a/doc/source/intro.rst +++ b/doc/source/intro.rst @@ -17,9 +17,6 @@ Requirements It should also work with older versions, but it may be that some operations involving remotes will not work as expected. * `GitDB`_ - a pure python git database implementation - - * `async`_ - asynchronous task scheduling - * `Python Nose`_ - used for running the tests * `Mock by Michael Foord`_ used for tests. Requires version 0.5 @@ -27,29 +24,27 @@ Requirements .. _Python Nose: http://code.google.com/p/python-nose/ .. _Mock by Michael Foord: http://www.voidspace.org.uk/python/mock.html .. _GitDB: http://pypi.python.org/pypi/gitdb -.. _async: http://pypi.python.org/pypi/async Installing GitPython ==================== Installing GitPython is easily done using -`setuptools`_. Assuming it is +`pip`_. Assuming it is installed, just run the following from the command-line: .. sourcecode:: none - # easy_install GitPython + # pip install gitpython This command will download the latest version of GitPython from the `Python Package Index `_ and install it -to your system. More information about ``easy_install`` and pypi can be found +to your system. More information about ``pip`` and pypi can be found here: -* `setuptools`_ -* `install setuptools `_ +* `install pip `_ * `pypi `_ -.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools +.. _pip: https://pip.pypa.io/en/latest/installing.html Alternatively, you can install from the distribution using the ``setup.py`` script: @@ -58,7 +53,7 @@ script: # python setup.py install -.. note:: In this case, you have to manually install `GitDB`_ and `async`_ as well. It would be recommended to use the :ref:`git source repository ` in that case. +.. note:: In this case, you have to manually install `GitDB`_ as well. It would be recommended to use the :ref:`git source repository ` in that case. Getting Started =============== @@ -84,7 +79,7 @@ GitPython's git repo is available on GitHub, which can be browsed at: and cloned using:: - $ git clone git://github.com/gitpython-developers/GitPython.git git-python + $ git clone https://github.com/gitpython-developers/GitPython git-python Initialize all submodules to obtain the required dependencies with:: diff --git a/git/repo/base.py b/git/repo/base.py index 9ddb1ce81..ef12473bb 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -869,8 +869,9 @@ def archive(self, ostream, treeish=None, prefix=None, **kwargs): return self def has_separate_working_tree(self): - """:return: True if our git_dir is not at the root of our working_tree_dir, but a .git file with a - platform agnositic symbolic link. Our git_dir will be whereever the .git file points to + """ + :return: True if our git_dir is not at the root of our working_tree_dir, but a .git file with a + platform agnositic symbolic link. Our git_dir will be whereever the .git file points to :note: bare repositories will always return False here """ if self.bare: From e395ac90bf088ad6b5de7dadb6531a6e7f3f4f3f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Jan 2015 18:53:40 +0100 Subject: [PATCH 0126/2790] Added tutorial about initializing a repository. Additionally, for this and future examples, there is a test_doc.py suite to contain all code mentioned in the docs. That way, we know if things stop working. Fixes #236 --- doc/source/tutorial.rst | 16 ++++++++++++++++ git/test/test_docs.py | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 git/test/test_docs.py diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 3f45b70dc..4921d07b0 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -415,6 +415,22 @@ The previous approach would brutally overwrite the user's changes in the working repo.heads.master.checkout() # checkout the branch using git-checkout repo.heads.other_branch.checkout() +Initializing a repository +************************* + +In this example, we will initialize an empty repository, add an empty file to the index, and commit the change:: + + repo_dir = 'my-new-repo' + file_name = os.path.join(repo_dir, 'new-file') + + r = git.Repo.init(repo_dir) + # This function just creates an empty file ... + touch(file_name) + r.index.add([file_name]) + r.index.commit("initial commit") + +Please have a look at the individual methods as they usually support a vast amount of arguments to customize their behavior. + Using git directly ****************** In case you are missing functionality as it has not been wrapped, you may conveniently use the git command directly. It is owned by each repository instance:: diff --git a/git/test/test_docs.py b/git/test/test_docs.py new file mode 100644 index 000000000..5ebae5136 --- /dev/null +++ b/git/test/test_docs.py @@ -0,0 +1,26 @@ +#-*-coding:utf-8-*- +# test_git.py +# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors +# +# This module is part of GitPython and is released under +# the BSD License: http://www.opensource.org/licenses/bsd-license.php +import os + +import git +from git.test.lib import TestBase +from gitdb.test.lib import with_rw_directory +from git.repo.fun import touch + + +class TestGit(TestBase): + + @with_rw_directory + def test_add_file_and_commit(self, rw_dir): + repo_dir = os.path.join(rw_dir, 'my-new-repo') + file_name = os.path.join(repo_dir, 'new-file') + + r = git.Repo.init(repo_dir) + # This function just creates an empty file ... + touch(file_name) + r.index.add([file_name]) + r.index.commit("initial commit") From fe2fbc5913258ef8379852c6d45fcf226b09900b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 20 Jan 2015 10:05:25 +0100 Subject: [PATCH 0127/2790] Remote.fetch|pull() will not use poll/threads anymore as only stderr is read. This simplification should improve performance and remove issues like those in #232. NOTE: Debug code is still contained here --- git/remote.py | 13 +++++++++---- git/test/test_remote.py | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/git/remote.py b/git/remote.py index 216858c03..5d9cba1b9 100644 --- a/git/remote.py +++ b/git/remote.py @@ -525,8 +525,10 @@ def _get_fetch_info_from_stderr(self, proc, progress): progress_handler = progress.new_message_handler() stderr_fetch = open(join(self.repo.git_dir, '%03i_debug_git-python_stderr' % self.fetch_no), 'wb') - def my_progress_handler(line): - stderr_fetch.write((line + '\n').encode(defenc)) + for line in proc.stderr: + line = line.decode(defenc) + stderr_fetch.write((line).encode(defenc)) + line = line.rstrip() for pline in progress_handler(line): if line.startswith('fatal:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) @@ -541,12 +543,13 @@ def my_progress_handler(line): # end # We are only interested in stderr here ... - handle_process_output(proc, None, my_progress_handler, finalize_process) + finalize_process(proc) stderr_fetch.close() # read head information import shutil - shutil.copyfile(join(self.repo.git_dir, 'FETCH_HEAD'), join(self.repo.git_dir, '%03i_debug_git-python_FETCH_HEAD' % self.fetch_no)) + shutil.copyfile(join(self.repo.git_dir, 'FETCH_HEAD'), + join(self.repo.git_dir, '%03i_debug_git-python_FETCH_HEAD' % self.fetch_no)) self.fetch_no += 1 fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') fetch_head_info = [l.decode(defenc) for l in fp.readlines()] @@ -615,6 +618,7 @@ def fetch(self, refspec=None, progress=None, **kwargs): args = [refspec] proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, v=True, **kwargs) + proc.stdout.close() res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() @@ -630,6 +634,7 @@ def pull(self, refspec=None, progress=None, **kwargs): :return: Please see 'fetch' method """ kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) + proc.stdout.close() res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 75dc19c5f..110f1fa5c 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -348,6 +348,7 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo): new_head = Head.create(rw_repo, "my_new_branch") progress = TestRemoteProgress() res = remote.push(new_head, progress) + assert len(res) > 0 assert res[0].flags & PushInfo.NEW_HEAD progress.make_assertion() self._do_test_push_result(res, remote) From ea29541e213df928d356b3c12d4d074001395d3c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 20 Jan 2015 11:43:20 +0100 Subject: [PATCH 0128/2790] Another take on fixing the current concurrent read implementation in git.cmd There have been rather obvious errors in there, as we forgot to unregister the filehandles. Now we will read from a buffer ourselves, which should be faster and ideally, doesn't lead to spurious errors anymore. Related to #232 --- git/cmd.py | 111 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 34 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 4ceebb4ca..80a30410c 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -9,6 +9,9 @@ import select import logging import threading +import errno +import mmap + from subprocess import ( call, Popen, @@ -26,6 +29,7 @@ string_types, defenc, PY3, + bchr, # just to satisfy flake8 on py3 unicode ) @@ -41,6 +45,13 @@ if sys.platform != 'win32': WindowsError = OSError +if PY3: + _bchr = bchr +else: + def _bchr(c): + return c +# get custom byte character handling + # ============================================================================== ## @name Utilities @@ -58,52 +69,73 @@ def handle_process_output(process, stdout_handler, stderr_handler, finalizer): :param stdout_handler: f(stdout_line_string), or None :param stderr_hanlder: f(stderr_line_string), or None :param finalizer: f(proc) - wait for proc to finish""" - def read_line_fast(stream): - return stream.readline() - - def read_line_slow(stream): + def parse_lines_from_buffer(fno, buf): line = b'' - while True: - char = stream.read(1) # reads individual single byte strings - if not char: - break + bi = 0 + lb = len(buf) + while bi < lb: + char = _bchr(buf[bi]) + bi += 1 if char in (b'\r', b'\n') and line: - break + yield bi, line + line = b'' else: line += char # END process parsed line # END while file is not done reading - return line # end - def dispatch_line(stream, handler, readline): - # this can possibly block for a while, but since we wake-up with at least one or more lines to handle, - # we are good ... - line = readline(stream).decode(defenc) - if line and handler: - try: - handler(line) - except Exception: - # Keep reading, have to pump the lines empty nontheless - log.error("Line handler exception on line: %s", line, exc_info=True) - # end - return line + def read_lines_from_fno(fno, last_buf_list): + buf = os.read(fno, mmap.PAGESIZE) + buf = last_buf_list[0] + buf + + bi = 0 + for bi, line in parse_lines_from_buffer(fno, buf): + yield line + # for each line to parse from the buffer + + # keep remainder + last_buf_list[0] = buf[bi:] + + def dispatch_single_line(line, handler): + line = line.decode(defenc) + if line and handler: + try: + handler(line) + except Exception: + # Keep reading, have to pump the lines empty nontheless + log.error("Line handler exception on line: %s", line, exc_info=True) + # end # end dispatch helper + # end single line helper + + def dispatch_lines(fno, handler, buf_list): + lc = 0 + for line in read_lines_from_fno(fno, buf_list): + dispatch_single_line(line, handler) + lc += 1 + # for each line + return lc # end - def deplete_buffer(stream, handler, readline, wg=None): + def deplete_buffer(fno, handler, buf_list, wg=None): while True: - line = dispatch_line(stream, handler, readline) - if not line: + line_count = dispatch_lines(fno, handler, buf_list) + if line_count == 0: break # end deplete buffer + + if buf_list[0]: + dispatch_single_line(buf_list[0], handler) + # end + if wg: wg.done() # end - fdmap = {process.stdout.fileno(): (process.stdout, stdout_handler, read_line_fast), - process.stderr.fileno(): (process.stderr, stderr_handler, read_line_slow)} + fdmap = {process.stdout.fileno(): (stdout_handler, [b'']), + process.stderr.fileno(): (stderr_handler, [b''])} if hasattr(select, 'poll'): # poll is preferred, as select is limited to file handles up to 1024 ... . This could otherwise be @@ -118,12 +150,20 @@ def deplete_buffer(stream, handler, readline, wg=None): closed_streams = set() while True: # no timeout - poll_result = poll.poll() + + try: + poll_result = poll.poll() + except select.error as e: + if e.args[0] == errno.EINTR: + continue + raise + # end handle poll exception + for fd, result in poll_result: if result & CLOSED: closed_streams.add(fd) else: - dispatch_line(*fdmap[fd]) + dispatch_lines(fd, *fdmap[fd]) # end handle closed stream # end for each poll-result tuple @@ -133,19 +173,22 @@ def deplete_buffer(stream, handler, readline, wg=None): # end endless loop # Depelete all remaining buffers - for stream, handler, readline in fdmap.values(): - deplete_buffer(stream, handler, readline) + for fno, (handler, buf_list) in fdmap.items(): + deplete_buffer(fno, handler, buf_list) # end for each file handle + + for fno in fdmap.keys(): + poll.unregister(fno) + # end don't forget to unregister ! else: # Oh ... probably we are on windows. select.select() can only handle sockets, we have files # The only reliable way to do this now is to use threads and wait for both to finish # Since the finalizer is expected to wait, we don't have to introduce our own wait primitive # NO: It's not enough unfortunately, and we will have to sync the threads wg = WaitGroup() - for fno in fdmap.keys(): + for fno, (handler, buf_list) in fdmap.items(): wg.add(1) - stream, handler, readline = fdmap[fno] - t = threading.Thread(target=lambda: deplete_buffer(stream, handler, readline, wg)) + t = threading.Thread(target=lambda: deplete_buffer(fno, handler, buf_list, wg)) t.start() # end # NOTE: Just joining threads can possibly fail as there is a gap between .start() and when it's From 9fbae711b76a4f2fa9345f43da6d2cdedd75d6c3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 20 Jan 2015 20:56:33 +0100 Subject: [PATCH 0129/2790] Greatly improved possible safety of Submodule.update(), which is used by default. Previously, the implementation would gladly reset new commits in submodules, and/or reset a dirty working tree. Now the new force_reset/force flag has to be specified explicitly to get back to the old behaviour. All submodule tests except for one are working. --- git/config.py | 4 +- git/exc.py | 11 ++++ git/objects/submodule/base.py | 71 ++++++++++++++++----- git/objects/submodule/root.py | 22 ++++--- git/repo/fun.py | 2 +- git/test/test_submodule.py | 113 +++++++++++++++++++++++++--------- git/util.py | 5 +- 7 files changed, 170 insertions(+), 58 deletions(-) diff --git a/git/config.py b/git/config.py index ed61bf934..38dd1b444 100644 --- a/git/config.py +++ b/git/config.py @@ -546,10 +546,12 @@ def set_value(self, section, option, value): :param option: Name of the options whose value to set :param value: Value to set the option to. It must be a string or convertible - to a string""" + to a string + :return: this instance""" if not self.has_section(section): self.add_section(section) self.set(section, option, self._value_to_string(value)) + return self def rename_section(self, section, new_name): """rename the given section to new_name diff --git a/git/exc.py b/git/exc.py index d9b7cbd20..7ee6726e8 100644 --- a/git/exc.py +++ b/git/exc.py @@ -84,3 +84,14 @@ def __init__(self, command, status, stdout, stderr): def __str__(self): return ("'%s' hook returned with exit code %i\nstdout: '%s'\nstderr: '%s'" % (self.command, self.status, self.stdout, self.stderr)) + + +class RepositoryDirtyError(Exception): + """Thrown whenever an operation on a repository fails as it has uncommited changes that would be overwritten""" + + def __init__(self, repo, message): + self.repo = repo + self.message = message + + def __str__(self): + return "Operation cannot be performed on %r: %s" % (self.repo, self.message) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 285d24235..64773411d 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -24,7 +24,8 @@ ) from git.exc import ( InvalidGitRepositoryError, - NoSuchPathError + NoSuchPathError, + RepositoryDirtyError ) from git.compat import ( string_types, @@ -36,6 +37,7 @@ import os import logging +import tempfile __all__ = ["Submodule", "UpdateProgress"] @@ -424,8 +426,8 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): return sm - def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, - dry_run=False): + def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, dry_run=False, + force=False): """Update the repository of this submodule to point to the checkout we point at with the binsha of this instance. @@ -440,6 +442,12 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= :param progress: UpdateProgress instance or None of no progress should be shown :param dry_run: if True, the operation will only be simulated, but not performed. All performed operations are read-only + :param force: + If True, we may reset heads even if the repository in question is dirty. Additinoally we will be allowed + to set a tracking branch which is ahead of its remote branch back into the past or the location of the + remote branch. This will essentially 'forget' commits. + If False, local tracking branches that are in the future of their respective remote branches will simply + not be moved. :note: does nothing in bare repositories :note: method is definitely not atomic if recurisve is True :return: self""" @@ -565,23 +573,45 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= # update the working tree # handles dry_run if mrepo is not None and mrepo.head.commit.binsha != binsha: + # We must assure that our destination sha (the one to point to) is in the future of our current head. + # Otherwise, we will reset changes that might have been done on the submodule, but were not yet pushed + # We also handle the case that history has been rewritten, leaving no merge-base. In that case + # we behave conservatively, protecting possible changes the user had done + may_reset = True + if mrepo.head.commit.binsha != self.NULL_BIN_SHA: + base_commit = mrepo.merge_base(mrepo.head.commit, hexsha) + if len(base_commit) == 0 or base_commit[0].hexsha == hexsha: + if force: + log.debug("Will force checkout or reset on local branch that is possibly in the future of" + + "the commit it will be checked out to, effectively 'forgetting' new commits") + else: + log.info("Skipping %s on branch '%s' of submodule repo '%s' as it contains un-pushed commits", + is_detached and "checkout" or "reset", mrepo.head, mrepo) + may_reset = False + # end handle force + # end handle if we are in the future + + if may_reset and not force and mrepo.is_dirty(index=True, working_tree=True, untracked_files=True): + raise RepositoryDirtyError(mrepo, "Cannot reset a dirty repository") + # end handle force and dirty state + # end handle empty repo + + # end verify future/past progress.update(BEGIN | UPDWKTREE, 0, 1, prefix + "Updating working tree at %s for submodule %r to revision %s" % (self.path, self.name, hexsha)) - if not dry_run: + + if not dry_run and may_reset: if is_detached: # NOTE: for now we force, the user is no supposed to change detached # submodules anyway. Maybe at some point this becomes an option, to # properly handle user modifications - see below for future options # regarding rebase and merge. - mrepo.git.checkout(hexsha, force=True) + mrepo.git.checkout(hexsha, force=force) else: - # TODO: allow to specify a rebase, merge, or reset - # TODO: Warn if the hexsha forces the tracking branch off the remote - # branch - this should be prevented when setting the branch option mrepo.head.reset(hexsha, index=True, working_tree=True) # END handle checkout - # END handle dry_run + # if we may reset/checkout progress.update(END | UPDWKTREE, 0, 1, prefix + "Done updating working tree for submodule %r" % self.name) # END update to new commit only if needed @@ -591,7 +621,8 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= # in dry_run mode, the module might not exist if mrepo is not None: for submodule in self.iter_items(self.module()): - submodule.update(recursive, init, to_latest_revision, progress=progress, dry_run=dry_run) + submodule.update(recursive, init, to_latest_revision, progress=progress, dry_run=dry_run, + force=force) # END handle recursive update # END handle dry run # END for each submodule @@ -748,7 +779,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): csm.remove(module, force, configuration, dry_run) del(csm) # end - if nc > 0: + if not dry_run and nc > 0: # Assure we don't leave the parent repository in a dirty state, and commit our changes # It's important for recursive, unforced, deletions to work as expected self.module().index.commit("Removed submodule '%s'" % self.name) @@ -854,8 +885,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): def set_parent_commit(self, commit, check=True): """Set this instance to use the given commit whose tree is supposed to contain the .gitmodules blob. - - :param commit: Commit'ish reference pointing at the root_tree + :param commit: Commit'ish reference pointing at the root_tree, or None always point to the most recent commit :param check: if True, relatively expensive checks will be performed to verify validity of the submodule. :raise ValueError: if the commit's tree didn't contain the .gitmodules blob. @@ -939,7 +969,7 @@ def rename(self, new_name): pw.release() # .gitmodules - cw = self.config_writer().config + cw = self.config_writer(write=False).config cw.rename_section(sm_section(self.name), sm_section(new_name)) cw.release() @@ -948,9 +978,16 @@ def rename(self, new_name): # .git/modules mod = self.module() if mod.has_separate_working_tree(): - module_abspath = self._module_abspath(self.repo, self.path, new_name) - os.renames(mod.git_dir, module_abspath) - self._write_git_file_and_module_config(mod.working_tree_dir, module_abspath) + destination_module_abspath = self._module_abspath(self.repo, self.path, new_name) + source_dir = mod.git_dir + # Let's be sure the submodule name is not so obviously tied to a directory + if destination_module_abspath.startswith(mod.git_dir): + tmp_dir = self._module_abspath(self.repo, self.path, os.path.basename(tempfile.mkdtemp())) + os.renames(source_dir, tmp_dir) + source_dir = tmp_dir + # end handle self-containment + os.renames(source_dir, destination_module_abspath) + self._write_git_file_and_module_config(mod.working_tree_dir, destination_module_abspath) # end move separate git repository return self diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index 8c9afff17..352e0f8ba 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -61,7 +61,7 @@ def _clear_cache(self): #{ Interface def update(self, previous_commit=None, recursive=True, force_remove=False, init=True, - to_latest_revision=False, progress=None, dry_run=False): + to_latest_revision=False, progress=None, dry_run=False, force_reset=False): """Update the submodules of this repository to the current HEAD commit. This method behaves smartly by determining changes of the path of a submodules repository, next to changes to the to-be-checked-out commit or the branch to be @@ -80,10 +80,16 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= :param init: If we encounter a new module which would need to be initialized, then do it. :param to_latest_revision: If True, instead of checking out the revision pointed to by this submodule's sha, the checked out tracking branch will be merged with the - newest remote branch fetched from the repository's origin + latest remote branch fetched from the repository's origin. + Unless force_reset is specified, a local tracking branch will never be reset into its past, therefore + the remote branch must be in the future for this to have an effect. + :param force_reset: if True, submodules may checkout or reset their branch even if the repository has + pending changes that would be overwritten, or if the local tracking branch is in the future of the + remote tracking branch and would be reset into its past. :param progress: RootUpdateProgress instance or None if no progress should be sent :param dry_run: if True, operations will not actually be performed. Progress messages - will change accordingly to indicate the WOULD DO state of the operation.""" + will change accordingly to indicate the WOULD DO state of the operation. + :return: self""" if self.repo.bare: raise InvalidGitRepositoryError("Cannot update submodules in bare repositories") # END handle bare @@ -134,9 +140,7 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= # of previous module. Trigger the cache to be updated before that progress.update(op, i, len_rrsm, prefix + "Removing submodule %r at %s" % (rsm.name, rsm.abspath)) rsm._parent_commit = repo.head.commit - if not dry_run: - rsm.remove(configuration=False, module=True, force=force_remove) - # END handle dry-run + rsm.remove(configuration=False, module=True, force=force_remove, dry_run=dry_run) if i == len_rrsm - 1: op |= END @@ -311,7 +315,7 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= for sm in sms: # update the submodule using the default method sm.update(recursive=False, init=init, to_latest_revision=to_latest_revision, - progress=progress, dry_run=dry_run) + progress=progress, dry_run=dry_run, force=force_reset) # update recursively depth first - question is which inconsitent # state will be better in case it fails somewhere. Defective branch @@ -322,11 +326,13 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= if sm.module_exists(): type(self)(sm.module()).update(recursive=True, force_remove=force_remove, init=init, to_latest_revision=to_latest_revision, - progress=progress, dry_run=dry_run) + progress=progress, dry_run=dry_run, force_reset=force_reset) # END handle dry_run # END handle recursive # END for each submodule to update + return self + def module(self): """:return: the actual repository containing the submodules""" return self.repo diff --git a/git/repo/fun.py b/git/repo/fun.py index 1ee11ffcc..2a1270be7 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -296,7 +296,7 @@ def rev_parse(repo, rev): raise ValueError("Invalid token: %r" % token) # END end handle tag except (IndexError, AttributeError): - raise BadObject("Invalid Revision in %s" % rev) + raise BadName("Invalid revision spec '%s' - not enough parent commits to reach '%s%i'" % (rev, token, num)) # END exception handling # END parse loop diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 767d84196..06036f53d 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -10,12 +10,18 @@ with_rw_repo ) from gitdb.test.lib import with_rw_directory -from git.exc import InvalidGitRepositoryError +from git.exc import ( + InvalidGitRepositoryError, + RepositoryDirtyError +) from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress from git.util import to_native_path_linux, join_path_native from git.compat import string_types -from git.repo.fun import find_git_dir +from git.repo.fun import ( + find_git_dir, + touch +) # Change the configuration if possible to prevent the underlying memory manager # to keep file handles open. On windows we get problems as they are not properly @@ -35,8 +41,8 @@ class TestRootProgress(RootUpdateProgress): """Just prints messages, for now without checking the correctness of the states""" - def update(self, op, index, max_count, message=''): - print(message) + def update(self, op, cur_count, max_count, message=''): + print(op, cur_count, max_count, message) prog = TestRootProgress() @@ -225,12 +231,14 @@ def _do_base_tests(self, rwrepo): # END for each repo to reset # dry run does nothing - sm.update(recursive=True, dry_run=True, progress=prog) + self.failUnlessRaises(RepositoryDirtyError, sm.update, recursive=True, dry_run=True, progress=prog) + sm.update(recursive=True, dry_run=True, progress=prog, force=True) for repo in smods: assert repo.head.commit != repo.head.ref.tracking_branch().commit # END for each repo to check - sm.update(recursive=True, to_latest_revision=True) + self.failUnlessRaises(RepositoryDirtyError, sm.update, recursive=True, to_latest_revision=True) + sm.update(recursive=True, to_latest_revision=True, force=True) for repo in smods: assert repo.head.commit == repo.head.ref.tracking_branch().commit # END for each repo to check @@ -480,8 +488,8 @@ def test_root_module(self, rwrepo): #================ nsmn = "newsubmodule" nsmp = "submrepo" - async_url = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, rsmsp[0], rsmsp[1])) - nsm = Submodule.add(rwrepo, nsmn, nsmp, url=async_url) + subrepo_url = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, rsmsp[0], rsmsp[1])) + nsm = Submodule.add(rwrepo, nsmn, nsmp, url=subrepo_url) csmadded = rwrepo.index.commit("Added submodule").hexsha # make sure we don't keep the repo reference nsm.set_parent_commit(csmadded) assert nsm.module_exists() @@ -507,7 +515,7 @@ def test_root_module(self, rwrepo): # an update will remove the module # not in dry_run - rm.update(recursive=False, dry_run=True) + rm.update(recursive=False, dry_run=True, force_remove=True) assert os.path.isdir(smp) # when removing submodules, we may get new commits as nested submodules are auto-committing changes @@ -517,9 +525,29 @@ def test_root_module(self, rwrepo): rm.update(recursive=False, force_remove=True) assert not os.path.isdir(smp) - # change url - #============= - # to the first repository, this way we have a fast checkout, and a completely different + # 'apply work' to the nested submodule and assure this is not removed/altered during updates + # Need to commit first, otherwise submodule.update wouldn't have a reason to change the head + nsm_file = os.path.join(nsm.module().working_tree_dir, 'new-file') + # We cannot expect is_dirty to even run as we wouldn't reset a head to the same location + assert nsm.module().head.commit.hexsha == nsm.hexsha + touch(nsm_file) + nsm.module().index.add([nsm]) + nsm.module().index.commit("added new file") + rm.update(recursive=False, dry_run=True, progress=prog) # would not change head, and thus doens't fail + # Everything we can do from now on will trigger the 'future' check, so no is_dirty() check will even run + # This would only run if our local branch is in the past and we have uncommitted changes + + prev_commit = nsm.module().head.commit + rm.update(recursive=False, dry_run=False, progress=prog) + assert prev_commit == nsm.module().head.commit, "head shouldn't change, as it is in future of remote branch" + + # this kills the new file + rm.update(recursive=True, progress=prog, force_reset=True) + assert prev_commit != nsm.module().head.commit, "head changed, as the remote url and its commit changed" + + # change url ... + #=============== + # ... to the first repository, this way we have a fast checkout, and a completely different # repository at the different url nsm.set_parent_commit(csmremoved) nsmurl = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, rsmsp[0])) @@ -529,15 +557,17 @@ def test_root_module(self, rwrepo): csmpathchange = rwrepo.index.commit("changed url") nsm.set_parent_commit(csmpathchange) + # Now nsm head is in the future of the tracked remote branch prev_commit = nsm.module().head.commit # dry-run does nothing rm.update(recursive=False, dry_run=True, progress=prog) assert nsm.module().remotes.origin.url != nsmurl - rm.update(recursive=False, progress=prog) + rm.update(recursive=False, progress=prog, force_reset=True) assert nsm.module().remotes.origin.url == nsmurl - # head changed, as the remote url and its commit changed - assert prev_commit != nsm.module().head.commit + assert prev_commit != nsm.module().head.commit, "Should now point to gitdb" + assert len(rwrepo.submodules) == 1 + assert not rwrepo.submodules[0].children()[0].module_exists(), "nested submodule should not be checked out" # add the submodule's changed commit to the index, which is what the # user would do @@ -584,7 +614,7 @@ def test_root_module(self, rwrepo): # assure we pull locally only nsmc = nsm.children()[0] writer = nsmc.config_writer() - writer.set_value('url', async_url) + writer.set_value('url', subrepo_url) writer.release() rm.update(recursive=True, progress=prog, dry_run=True) # just to run the code rm.update(recursive=True, progress=prog) @@ -652,16 +682,15 @@ def test_git_submodules(self, rwdir): @with_rw_directory def test_git_submodule_compatibility(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) - empty_file = os.path.join(parent.working_tree_dir, "empty") - with open(empty_file, 'wb') as fp: - fp.close() - parent.index.add([empty_file]) - parent.index.commit("initial commit - can't yet add submodules to empty parent dir") - sm_path = 'submodules/intermediate/one' sm = parent.create_submodule('mymodules/myname', sm_path, url=self._submodule_url()) parent.index.commit("added submodule") + def assert_exists(sm, value=True): + assert sm.exists() == value + assert sm.module_exists() == value + # end + # As git is backwards compatible itself, it would still recognize what we do here ... unless we really # muss it up. That's the only reason why the test is still here ... . assert len(parent.git.submodule().splitlines()) == 1 @@ -681,25 +710,47 @@ def test_git_submodule_compatibility(self, rwdir): new_sm_path = 'submodules/one' sm.set_parent_commit(parent.commit()) sm.move(new_sm_path) - assert sm.exists() - assert sm.module_exists() + assert_exists(sm) # Add additional submodule level - sm.module().create_submodule('nested-submodule', 'nested-submodule/working-tree', - url=self._submodule_url()) + csm = sm.module().create_submodule('nested-submodule', 'nested-submodule/working-tree', + url=self._submodule_url()) sm.module().index.commit("added nested submodule") + sm_head_commit = sm.module().commit() + csm.set_parent_commit(sm_head_commit) + assert_exists(csm) + # Fails because there are new commits, compared to the remote we cloned from self.failUnlessRaises(InvalidGitRepositoryError, sm.remove, dry_run=True) - - # TODO: rename nested submodule + assert_exists(sm) + assert sm.module().commit() == sm_head_commit + assert_exists(csm) + + # rename nested submodule + # This name would move itself one level deeper - needs special handling internally + new_name = csm.name + '/mine' + assert csm.rename(new_name).name == new_name + assert_exists(csm) + + # keep_going evaluation + rsm = parent.submodule_update() + assert_exists(sm) + assert_exists(csm) + csm_writer = csm.config_writer().set_value('url', 'foo') + csm_writer.release() + csm.repo.index.commit("Have to commit submodule change for algorithm to pick it up") + csm.set_parent_commit(csm.repo.commit()) + assert csm.url == 'foo' + + self.failUnlessRaises(Exception, rsm.update, recursive=True, to_latest_revision=True, progress=prog) + assert_exists(csm) # remove sm_module_path = sm.module().git_dir for dry_run in (True, False): sm.remove(dry_run=dry_run, force=True) - assert sm.exists() == dry_run - assert sm.module_exists() == dry_run + assert_exists(sm, value=dry_run) assert os.path.isdir(sm_module_path) == dry_run # end for each dry-run mode @@ -712,12 +763,14 @@ def test_rename(self, rwdir): assert sm._parent_commit is not None assert sm.rename(sm_name) is sm and sm.name == sm_name + assert not sm.repo.is_dirty(index=True, working_tree=False, untracked_files=False) new_path = 'renamed/myname' assert sm.move(new_path).name == new_path new_sm_name = "shortname" assert sm.rename(new_sm_name) is sm + assert sm.repo.is_dirty(index=True, working_tree=False, untracked_files=False) assert sm.exists() sm_mod = sm.module() diff --git a/git/util.py b/git/util.py index 5385455a7..8cab0b994 100644 --- a/git/util.py +++ b/git/util.py @@ -251,7 +251,10 @@ def _parse_progress_line(self, line): message = message[:-len(done_token)] # END end message handling - self.update(op_code, cur_count, max_count, message) + self.update(op_code, + cur_count and float(cur_count), + max_count and float(max_count), + message) # END for each sub line return failed_lines From 80701fc6f4bf74d3c6176d76563894ff0f3b32bb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 20 Jan 2015 21:35:28 +0100 Subject: [PATCH 0130/2790] Submodule.parent_commit() now automatically points to repo.head unless it was set before. That way, you don't always have to keep the parent commit uptodate when changing the repo, which can lead to errors which are hard to debug and make no sense to the user, who previously never set parent_commit (yet it matters thanks to the cache). --- git/objects/submodule/base.py | 65 ++++++++++++++++++++--------------- git/test/test_submodule.py | 10 +++--- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 64773411d..b8924291d 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -98,8 +98,7 @@ def __init__(self, repo, binsha, mode=None, path=None, name=None, parent_commit= :param branch_path: full (relative) path to ref to checkout when cloning the remote repository""" super(Submodule, self).__init__(repo, binsha, mode, path) self.size = 0 - if parent_commit is not None: - self._parent_commit = parent_commit + self._parent_commit = parent_commit if url is not None: self._url = url if branch_path is not None: @@ -109,18 +108,15 @@ def __init__(self, repo, binsha, mode=None, path=None, name=None, parent_commit= self._name = name def _set_cache_(self, attr): - if attr == '_parent_commit': - # set a default value, which is the root tree of the current head - try: - self._parent_commit = self.repo.commit() - except ValueError: - # This fails in an empty repository. - self._parent_commit = None - # end exception handling - elif attr in ('path', '_url', '_branch_path'): + if attr in ('path', '_url', '_branch_path'): reader = self.config_reader() # default submodule values - self.path = reader.get_value('path') + try: + self.path = reader.get_value('path') + except cp.NoSectionError: + raise ValueError("This submodule instance does not exist anymore in '%s' file" + % os.path.join(self.repo.working_tree_dir, '.gitmodules')) + # end self._url = reader.get_value('url') # git-python extension values - optional self._branch_path = reader.get_value(self.k_head_option, git.Head.to_full_path(self.k_head_default)) @@ -170,16 +166,19 @@ def _config_parser(cls, repo, parent_commit, read_only): :raise IOError: If the .gitmodules file cannot be found, either locally or in the repository at the given parent commit. Otherwise the exception would be delayed until the first access of the config parser""" - try: - parent_matches_head = repo.head.commit == parent_commit - except ValueError: - # We are most likely in an empty repository, so the HEAD doesn't point to a valid ref - parent_matches_head = True - # end + parent_matches_head = True + if parent_commit is not None: + try: + parent_matches_head = repo.head.commit == parent_commit + except ValueError: + # We are most likely in an empty repository, so the HEAD doesn't point to a valid ref + pass + # end hanlde parent_commit if not repo.bare and parent_matches_head: fp_module = os.path.join(repo.working_tree_dir, cls.k_modules_file) else: + assert parent_commit is not None, "need valid parent_commit in bare repositories" try: fp_module = cls._sio_modules(parent_commit) except KeyError: @@ -213,7 +212,12 @@ def _sio_modules(cls, parent_commit): def _config_parser_constrained(self, read_only): """:return: Config Parser constrained to our submodule in read or write mode""" - parser = self._config_parser(self.repo, self._parent_commit, read_only) + try: + pc = self.parent_commit + except ValueError: + pc = None + # end hande empty parent repository + parser = self._config_parser(self.repo, pc, read_only) parser.set_submodule(self) return SectionConstraint(parser, sm_section(self.name)) @@ -407,9 +411,10 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): del(writer) # we deliberatly assume that our head matches our index ! - parent_repo_is_empty = False + try: - sm._parent_commit = repo.head.commit + repo.head.commit + parent_repo_is_empty = False except ValueError: parent_repo_is_empty = True # Can't set this yet, if the parent repo is empty. @@ -418,9 +423,6 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): index.add([sm], write=True) if parent_repo_is_empty: - # The user is expected to make a commit, and this submodule will initialize itself when - # _parent_commit is required - del sm._parent_commit log.debug("Will not set _parent_commit now as the parent repository has no commit yet.") # end @@ -885,13 +887,18 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): def set_parent_commit(self, commit, check=True): """Set this instance to use the given commit whose tree is supposed to contain the .gitmodules blob. - :param commit: Commit'ish reference pointing at the root_tree, or None always point to the most recent commit + :param commit: Commit'ish reference pointing at the root_tree, or None to always point to the + most recent commit :param check: if True, relatively expensive checks will be performed to verify validity of the submodule. :raise ValueError: if the commit's tree didn't contain the .gitmodules blob. :raise ValueError: if the parent commit didn't store this submodule under the current path :return: self""" + if commit is None: + self._parent_commit = None + return self + # end handle None pcommit = self.repo.commit(commit) pctree = pcommit.tree if self.k_modules_file not in pctree: @@ -1036,7 +1043,7 @@ def exists(self): if hasattr(self, attr): loc[attr] = getattr(self, attr) # END if we have the attribute cache - except cp.NoSectionError: + except (cp.NoSectionError, ValueError): # on PY3, this can happen apparently ... don't know why this doesn't happen on PY2 pass # END for each attr @@ -1086,6 +1093,8 @@ def url(https://github.com/self): def parent_commit(self): """:return: Commit instance with the tree containing the .gitmodules file :note: will always point to the current head's commit if it was not set explicitly""" + if self._parent_commit is None: + return self.repo.commit() return self._parent_commit @property @@ -1157,7 +1166,9 @@ def iter_items(cls, repo, parent_commit='HEAD'): # fill in remaining info - saves time as it doesn't have to be parsed again sm._name = n - sm._parent_commit = pc + if pc != repo.commit(): + sm._parent_commit = pc + # end set only if not most recent ! sm._branch_path = git.Head.to_full_path(b) sm._url = u diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 06036f53d..047e0049d 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -320,9 +320,11 @@ def _do_base_tests(self, rwrepo): assert sm.config_reader().get_value('url') # delete the rest + sm_path = sm.path sm.remove() assert not sm.exists() assert not sm.module_exists() + self.failUnlessRaises(ValueError, getattr, sm, 'path') assert len(rwrepo.submodules) == 0 @@ -359,11 +361,11 @@ def _do_base_tests(self, rwrepo): # MOVE MODULE ############# - # invalid inptu + # invalid input self.failUnlessRaises(ValueError, nsm.move, 'doesntmatter', module=False, configuration=False) # renaming to the same path does nothing - assert nsm.move(sm.path) is nsm + assert nsm.move(sm_path) is nsm # rename a module nmp = join_path_native("new", "module", "dir") + "/" # new module path @@ -708,7 +710,6 @@ def assert_exists(sm, value=True): # test move new_sm_path = 'submodules/one' - sm.set_parent_commit(parent.commit()) sm.move(new_sm_path) assert_exists(sm) @@ -717,7 +718,6 @@ def assert_exists(sm, value=True): url=self._submodule_url()) sm.module().index.commit("added nested submodule") sm_head_commit = sm.module().commit() - csm.set_parent_commit(sm_head_commit) assert_exists(csm) # Fails because there are new commits, compared to the remote we cloned from @@ -739,7 +739,6 @@ def assert_exists(sm, value=True): csm_writer = csm.config_writer().set_value('url', 'foo') csm_writer.release() csm.repo.index.commit("Have to commit submodule change for algorithm to pick it up") - csm.set_parent_commit(csm.repo.commit()) assert csm.url == 'foo' self.failUnlessRaises(Exception, rsm.update, recursive=True, to_latest_revision=True, progress=prog) @@ -760,7 +759,6 @@ def test_rename(self, rwdir): sm_name = 'mymodules/myname' sm = parent.create_submodule(sm_name, sm_name, url=self._submodule_url()) parent.index.commit("Added submodule") - assert sm._parent_commit is not None assert sm.rename(sm_name) is sm and sm.name == sm_name assert not sm.repo.is_dirty(index=True, working_tree=False, untracked_files=False) From e4921139819c7949abaad6cc5679232a0fbb0632 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 20 Jan 2015 22:03:44 +0100 Subject: [PATCH 0131/2790] Impemented keep_going flag for `Submodule.update()` Fixes #50 --- git/objects/submodule/base.py | 305 ++++++++++++------------ git/objects/submodule/root.py | 421 ++++++++++++++++++---------------- git/test/test_submodule.py | 7 +- 3 files changed, 381 insertions(+), 352 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index b8924291d..7f06a7b16 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -429,7 +429,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): return sm def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, dry_run=False, - force=False): + force=False, keep_going=False): """Update the repository of this submodule to point to the checkout we point at with the binsha of this instance. @@ -450,6 +450,10 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= remote branch. This will essentially 'forget' commits. If False, local tracking branches that are in the future of their respective remote branches will simply not be moved. + :param keep_going: if True, we will ignore but log all errors, and keep going recursively. + Unless dry_run is set as well, keep_going could cause subsequent/inherited errors you wouldn't see + otherwise. + In conjunction with dry_run, it can be useful to anticipate all errors when updating submodules :note: does nothing in bare repositories :note: method is definitely not atomic if recurisve is True :return: self""" @@ -470,152 +474,158 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= mrepo = None # END init mrepo - # ASSURE REPO IS PRESENT AND UPTODATE - ##################################### try: - mrepo = self.module() - rmts = mrepo.remotes - len_rmts = len(rmts) - for i, remote in enumerate(rmts): - op = FETCH - if i == 0: - op |= BEGIN - # END handle start - - progress.update(op, i, len_rmts, prefix + "Fetching remote %s of submodule %r" % (remote, self.name)) - #=============================== + # ASSURE REPO IS PRESENT AND UPTODATE + ##################################### + try: + mrepo = self.module() + rmts = mrepo.remotes + len_rmts = len(rmts) + for i, remote in enumerate(rmts): + op = FETCH + if i == 0: + op |= BEGIN + # END handle start + + progress.update(op, i, len_rmts, prefix + "Fetching remote %s of submodule %r" % (remote, self.name)) + #=============================== + if not dry_run: + remote.fetch(progress=progress) + # END handle dry-run + #=============================== + if i == len_rmts - 1: + op |= END + # END handle end + progress.update(op, i, len_rmts, prefix + "Done fetching remote of submodule %r" % self.name) + # END fetch new data + except InvalidGitRepositoryError: + if not init: + return self + # END early abort if init is not allowed + + # there is no git-repository yet - but delete empty paths + checkout_module_abspath = self.abspath + if not dry_run and os.path.isdir(checkout_module_abspath): + try: + os.rmdir(checkout_module_abspath) + except OSError: + raise OSError("Module directory at %r does already exist and is non-empty" + % checkout_module_abspath) + # END handle OSError + # END handle directory removal + + # don't check it out at first - nonetheless it will create a local + # branch according to the remote-HEAD if possible + progress.update(BEGIN | CLONE, 0, 1, prefix + "Cloning url '%s' to '%s' in submodule %r" % + (self.url, checkout_module_abspath, self.name)) if not dry_run: - remote.fetch(progress=progress) + mrepo = self._clone_repo(self.repo, self.url, self.path, self.name, n=True) # END handle dry-run - #=============================== - if i == len_rmts - 1: - op |= END - # END handle end - progress.update(op, i, len_rmts, prefix + "Done fetching remote of submodule %r" % self.name) - # END fetch new data - except InvalidGitRepositoryError: - if not init: - return self - # END early abort if init is not allowed + progress.update(END | CLONE, 0, 1, prefix + "Done cloning to %s" % checkout_module_abspath) - # there is no git-repository yet - but delete empty paths - checkout_module_abspath = self.abspath - if not dry_run and os.path.isdir(checkout_module_abspath): - try: - os.rmdir(checkout_module_abspath) - except OSError: - raise OSError("Module directory at %r does already exist and is non-empty" - % checkout_module_abspath) - # END handle OSError - # END handle directory removal - - # don't check it out at first - nonetheless it will create a local - # branch according to the remote-HEAD if possible - progress.update(BEGIN | CLONE, 0, 1, prefix + "Cloning %s to %s in submodule %r" % - (self.url, checkout_module_abspath, self.name)) - if not dry_run: - mrepo = self._clone_repo(self.repo, self.url, self.path, self.name, n=True) - # END handle dry-run - progress.update(END | CLONE, 0, 1, prefix + "Done cloning to %s" % checkout_module_abspath) - - if not dry_run: - # see whether we have a valid branch to checkout - try: - # find a remote which has our branch - we try to be flexible - remote_branch = find_first_remote_branch(mrepo.remotes, self.branch_name) - local_branch = mkhead(mrepo, self.branch_path) - - # have a valid branch, but no checkout - make sure we can figure - # that out by marking the commit with a null_sha - local_branch.set_object(util.Object(mrepo, self.NULL_BIN_SHA)) - # END initial checkout + branch creation - - # make sure HEAD is not detached - mrepo.head.set_reference(local_branch, logmsg="submodule: attaching head to %s" % local_branch) - mrepo.head.ref.set_tracking_branch(remote_branch) - except IndexError: - log.warn("Failed to checkout tracking branch %s", self.branch_path) - # END handle tracking branch - - # NOTE: Have to write the repo config file as well, otherwise - # the default implementation will be offended and not update the repository - # Maybe this is a good way to assure it doesn't get into our way, but - # we want to stay backwards compatible too ... . Its so redundant ! - writer = self.repo.config_writer() - writer.set_value(sm_section(self.name), 'url', self.url) - writer.release() + if not dry_run: + # see whether we have a valid branch to checkout + try: + # find a remote which has our branch - we try to be flexible + remote_branch = find_first_remote_branch(mrepo.remotes, self.branch_name) + local_branch = mkhead(mrepo, self.branch_path) + + # have a valid branch, but no checkout - make sure we can figure + # that out by marking the commit with a null_sha + local_branch.set_object(util.Object(mrepo, self.NULL_BIN_SHA)) + # END initial checkout + branch creation + + # make sure HEAD is not detached + mrepo.head.set_reference(local_branch, logmsg="submodule: attaching head to %s" % local_branch) + mrepo.head.ref.set_tracking_branch(remote_branch) + except IndexError: + log.warn("Failed to checkout tracking branch %s", self.branch_path) + # END handle tracking branch + + # NOTE: Have to write the repo config file as well, otherwise + # the default implementation will be offended and not update the repository + # Maybe this is a good way to assure it doesn't get into our way, but + # we want to stay backwards compatible too ... . Its so redundant ! + writer = self.repo.config_writer() + writer.set_value(sm_section(self.name), 'url', self.url) + writer.release() + # END handle dry_run + # END handle initalization + + # DETERMINE SHAS TO CHECKOUT + ############################ + binsha = self.binsha + hexsha = self.hexsha + if mrepo is not None: + # mrepo is only set if we are not in dry-run mode or if the module existed + is_detached = mrepo.head.is_detached # END handle dry_run - # END handle initalization - - # DETERMINE SHAS TO CHECKOUT - ############################ - binsha = self.binsha - hexsha = self.hexsha - if mrepo is not None: - # mrepo is only set if we are not in dry-run mode or if the module existed - is_detached = mrepo.head.is_detached - # END handle dry_run - - if mrepo is not None and to_latest_revision: - msg_base = "Cannot update to latest revision in repository at %r as " % mrepo.working_dir - if not is_detached: - rref = mrepo.head.ref.tracking_branch() - if rref is not None: - rcommit = rref.commit - binsha = rcommit.binsha - hexsha = rcommit.hexsha - else: - log.error("%s a tracking branch was not set for local branch '%s'", msg_base, mrepo.head.ref) - # END handle remote ref - else: - log.error("%s there was no local tracking branch", msg_base) - # END handle detached head - # END handle to_latest_revision option - - # update the working tree - # handles dry_run - if mrepo is not None and mrepo.head.commit.binsha != binsha: - # We must assure that our destination sha (the one to point to) is in the future of our current head. - # Otherwise, we will reset changes that might have been done on the submodule, but were not yet pushed - # We also handle the case that history has been rewritten, leaving no merge-base. In that case - # we behave conservatively, protecting possible changes the user had done - may_reset = True - if mrepo.head.commit.binsha != self.NULL_BIN_SHA: - base_commit = mrepo.merge_base(mrepo.head.commit, hexsha) - if len(base_commit) == 0 or base_commit[0].hexsha == hexsha: - if force: - log.debug("Will force checkout or reset on local branch that is possibly in the future of" + - "the commit it will be checked out to, effectively 'forgetting' new commits") + + if mrepo is not None and to_latest_revision: + msg_base = "Cannot update to latest revision in repository at %r as " % mrepo.working_dir + if not is_detached: + rref = mrepo.head.ref.tracking_branch() + if rref is not None: + rcommit = rref.commit + binsha = rcommit.binsha + hexsha = rcommit.hexsha else: - log.info("Skipping %s on branch '%s' of submodule repo '%s' as it contains un-pushed commits", - is_detached and "checkout" or "reset", mrepo.head, mrepo) - may_reset = False - # end handle force - # end handle if we are in the future - - if may_reset and not force and mrepo.is_dirty(index=True, working_tree=True, untracked_files=True): - raise RepositoryDirtyError(mrepo, "Cannot reset a dirty repository") - # end handle force and dirty state - # end handle empty repo - - # end verify future/past - progress.update(BEGIN | UPDWKTREE, 0, 1, prefix + - "Updating working tree at %s for submodule %r to revision %s" - % (self.path, self.name, hexsha)) - - if not dry_run and may_reset: - if is_detached: - # NOTE: for now we force, the user is no supposed to change detached - # submodules anyway. Maybe at some point this becomes an option, to - # properly handle user modifications - see below for future options - # regarding rebase and merge. - mrepo.git.checkout(hexsha, force=force) + log.error("%s a tracking branch was not set for local branch '%s'", msg_base, mrepo.head.ref) + # END handle remote ref else: - mrepo.head.reset(hexsha, index=True, working_tree=True) - # END handle checkout - # if we may reset/checkout - progress.update(END | UPDWKTREE, 0, 1, prefix + "Done updating working tree for submodule %r" % self.name) - # END update to new commit only if needed + log.error("%s there was no local tracking branch", msg_base) + # END handle detached head + # END handle to_latest_revision option + + # update the working tree + # handles dry_run + if mrepo is not None and mrepo.head.commit.binsha != binsha: + # We must assure that our destination sha (the one to point to) is in the future of our current head. + # Otherwise, we will reset changes that might have been done on the submodule, but were not yet pushed + # We also handle the case that history has been rewritten, leaving no merge-base. In that case + # we behave conservatively, protecting possible changes the user had done + may_reset = True + if mrepo.head.commit.binsha != self.NULL_BIN_SHA: + base_commit = mrepo.merge_base(mrepo.head.commit, hexsha) + if len(base_commit) == 0 or base_commit[0].hexsha == hexsha: + if force: + log.debug("Will force checkout or reset on local branch that is possibly in the future of" + + "the commit it will be checked out to, effectively 'forgetting' new commits") + else: + log.info("Skipping %s on branch '%s' of submodule repo '%s' as it contains un-pushed commits", + is_detached and "checkout" or "reset", mrepo.head, mrepo) + may_reset = False + # end handle force + # end handle if we are in the future + + if may_reset and not force and mrepo.is_dirty(index=True, working_tree=True, untracked_files=True): + raise RepositoryDirtyError(mrepo, "Cannot reset a dirty repository") + # end handle force and dirty state + # end handle empty repo + + # end verify future/past + progress.update(BEGIN | UPDWKTREE, 0, 1, prefix + + "Updating working tree at %s for submodule %r to revision %s" + % (self.path, self.name, hexsha)) + + if not dry_run and may_reset: + if is_detached: + # NOTE: for now we force, the user is no supposed to change detached + # submodules anyway. Maybe at some point this becomes an option, to + # properly handle user modifications - see below for future options + # regarding rebase and merge. + mrepo.git.checkout(hexsha, force=force) + else: + mrepo.head.reset(hexsha, index=True, working_tree=True) + # END handle checkout + # if we may reset/checkout + progress.update(END | UPDWKTREE, 0, 1, prefix + "Done updating working tree for submodule %r" % self.name) + # END update to new commit only if needed + except Exception as err: + if not keep_going: + raise + log.error(str(err)) + # end handle keep_going # HANDLE RECURSION ################## @@ -624,7 +634,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= if mrepo is not None: for submodule in self.iter_items(self.module()): submodule.update(recursive, init, to_latest_revision, progress=progress, dry_run=dry_run, - force=force) + force=force, keep_going=keep_going) # END handle recursive update # END handle dry run # END for each submodule @@ -887,13 +897,16 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): def set_parent_commit(self, commit, check=True): """Set this instance to use the given commit whose tree is supposed to contain the .gitmodules blob. - :param commit: Commit'ish reference pointing at the root_tree, or None to always point to the + + :param commit: + Commit'ish reference pointing at the root_tree, or None to always point to the most recent commit - :param check: if True, relatively expensive checks will be performed to verify + :param check: + if True, relatively expensive checks will be performed to verify validity of the submodule. :raise ValueError: if the commit's tree didn't contain the .gitmodules blob. - :raise ValueError: if the parent commit didn't store this submodule under the - current path + :raise ValueError: + if the parent commit didn't store this submodule under the current path :return: self""" if commit is None: self._parent_commit = None @@ -976,7 +989,7 @@ def rename(self, new_name): pw.release() # .gitmodules - cw = self.config_writer(write=False).config + cw = self.config_writer(write=True).config cw.rename_section(sm_section(self.name), sm_section(new_name)) cw.release() diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index 352e0f8ba..dd023d464 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -61,7 +61,8 @@ def _clear_cache(self): #{ Interface def update(self, previous_commit=None, recursive=True, force_remove=False, init=True, - to_latest_revision=False, progress=None, dry_run=False, force_reset=False): + to_latest_revision=False, progress=None, dry_run=False, force_reset=False, + keep_going=False): """Update the submodules of this repository to the current HEAD commit. This method behaves smartly by determining changes of the path of a submodules repository, next to changes to the to-be-checked-out commit or the branch to be @@ -89,6 +90,10 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= :param progress: RootUpdateProgress instance or None if no progress should be sent :param dry_run: if True, operations will not actually be performed. Progress messages will change accordingly to indicate the WOULD DO state of the operation. + :param keep_going: if True, we will ignore but log all errors, and keep going recursively. + Unless dry_run is set as well, keep_going could cause subsequent/inherited errors you wouldn't see + otherwise. + In conjunction with dry_run, it can be useful to anticipate all errors when updating submodules :return: self""" if self.repo.bare: raise InvalidGitRepositoryError("Cannot update submodules in bare repositories") @@ -104,218 +109,225 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= repo = self.repo - # SETUP BASE COMMIT - ################### - cur_commit = repo.head.commit - if previous_commit is None: - try: - previous_commit = repo.commit(repo.head.log_entry(-1).oldhexsha) - if previous_commit.binsha == previous_commit.NULL_BIN_SHA: - raise IndexError - # END handle initial commit - except IndexError: - # in new repositories, there is no previous commit - previous_commit = cur_commit - # END exception handling - else: - previous_commit = repo.commit(previous_commit) # obtain commit object - # END handle previous commit - - psms = self.list_items(repo, parent_commit=previous_commit) - sms = self.list_items(repo) - spsms = set(psms) - ssms = set(sms) - - # HANDLE REMOVALS - ################### - rrsm = (spsms - ssms) - len_rrsm = len(rrsm) - for i, rsm in enumerate(rrsm): - op = REMOVE - if i == 0: - op |= BEGIN - # END handle begin - - # fake it into thinking its at the current commit to allow deletion - # of previous module. Trigger the cache to be updated before that - progress.update(op, i, len_rrsm, prefix + "Removing submodule %r at %s" % (rsm.name, rsm.abspath)) - rsm._parent_commit = repo.head.commit - rsm.remove(configuration=False, module=True, force=force_remove, dry_run=dry_run) - - if i == len_rrsm - 1: - op |= END - # END handle end - progress.update(op, i, len_rrsm, prefix + "Done removing submodule %r" % rsm.name) - # END for each removed submodule - - # HANDLE PATH RENAMES - ##################### - # url changes + branch changes - csms = (spsms & ssms) - len_csms = len(csms) - for i, csm in enumerate(csms): - psm = psms[csm.name] - sm = sms[csm.name] - - # PATH CHANGES - ############## - if sm.path != psm.path and psm.module_exists(): - progress.update(BEGIN | PATHCHANGE, i, len_csms, prefix + - "Moving repository of submodule %r from %s to %s" % (sm.name, psm.abspath, sm.abspath)) - # move the module to the new path - if not dry_run: - psm.move(sm.path, module=True, configuration=False) - # END handle dry_run - progress.update( - END | PATHCHANGE, i, len_csms, prefix + "Done moving repository of submodule %r" % sm.name) - # END handle path changes - - if sm.module_exists(): - # HANDLE URL CHANGE - ################### - if sm.url != psm.url: - # Add the new remote, remove the old one - # This way, if the url just changes, the commits will not - # have to be re-retrieved - nn = '__new_origin__' - smm = sm.module() - rmts = smm.remotes - - # don't do anything if we already have the url we search in place - if len([r for r in rmts if r.url == sm.url]) == 0: - progress.update(BEGIN | URLCHANGE, i, len_csms, prefix + - "Changing url of submodule %r from %s to %s" % (sm.name, psm.url, sm.url)) + try: + # SETUP BASE COMMIT + ################### + cur_commit = repo.head.commit + if previous_commit is None: + try: + previous_commit = repo.commit(repo.head.log_entry(-1).oldhexsha) + if previous_commit.binsha == previous_commit.NULL_BIN_SHA: + raise IndexError + # END handle initial commit + except IndexError: + # in new repositories, there is no previous commit + previous_commit = cur_commit + # END exception handling + else: + previous_commit = repo.commit(previous_commit) # obtain commit object + # END handle previous commit + + psms = self.list_items(repo, parent_commit=previous_commit) + sms = self.list_items(repo) + spsms = set(psms) + ssms = set(sms) + + # HANDLE REMOVALS + ################### + rrsm = (spsms - ssms) + len_rrsm = len(rrsm) + + for i, rsm in enumerate(rrsm): + op = REMOVE + if i == 0: + op |= BEGIN + # END handle begin + + # fake it into thinking its at the current commit to allow deletion + # of previous module. Trigger the cache to be updated before that + progress.update(op, i, len_rrsm, prefix + "Removing submodule %r at %s" % (rsm.name, rsm.abspath)) + rsm._parent_commit = repo.head.commit + rsm.remove(configuration=False, module=True, force=force_remove, dry_run=dry_run) + + if i == len_rrsm - 1: + op |= END + # END handle end + progress.update(op, i, len_rrsm, prefix + "Done removing submodule %r" % rsm.name) + # END for each removed submodule + + # HANDLE PATH RENAMES + ##################### + # url changes + branch changes + csms = (spsms & ssms) + len_csms = len(csms) + for i, csm in enumerate(csms): + psm = psms[csm.name] + sm = sms[csm.name] + + # PATH CHANGES + ############## + if sm.path != psm.path and psm.module_exists(): + progress.update(BEGIN | PATHCHANGE, i, len_csms, prefix + + "Moving repository of submodule %r from %s to %s" % (sm.name, psm.abspath, sm.abspath)) + # move the module to the new path + if not dry_run: + psm.move(sm.path, module=True, configuration=False) + # END handle dry_run + progress.update( + END | PATHCHANGE, i, len_csms, prefix + "Done moving repository of submodule %r" % sm.name) + # END handle path changes + if sm.module_exists(): + # HANDLE URL CHANGE + ################### + if sm.url != psm.url: + # Add the new remote, remove the old one + # This way, if the url just changes, the commits will not + # have to be re-retrieved + nn = '__new_origin__' + smm = sm.module() + rmts = smm.remotes + + # don't do anything if we already have the url we search in place + if len([r for r in rmts if r.url == sm.url]) == 0: + progress.update(BEGIN | URLCHANGE, i, len_csms, prefix + + "Changing url of submodule %r from %s to %s" % (sm.name, psm.url, sm.url)) + + if not dry_run: + assert nn not in [r.name for r in rmts] + smr = smm.create_remote(nn, sm.url) + smr.fetch(progress=progress) + + # If we have a tracking branch, it should be available + # in the new remote as well. + if len([r for r in smr.refs if r.remote_head == sm.branch_name]) == 0: + raise ValueError( + "Submodule branch named %r was not available in new submodule remote at %r" + % (sm.branch_name, sm.url) + ) + # END head is not detached + + # now delete the changed one + rmt_for_deletion = None + for remote in rmts: + if remote.url == psm.url: + rmt_for_deletion = remote + break + # END if urls match + # END for each remote + + # if we didn't find a matching remote, but have exactly one, + # we can safely use this one + if rmt_for_deletion is None: + if len(rmts) == 1: + rmt_for_deletion = rmts[0] + else: + # if we have not found any remote with the original url + # we may not have a name. This is a special case, + # and its okay to fail here + # Alternatively we could just generate a unique name and leave all + # existing ones in place + raise InvalidGitRepositoryError( + "Couldn't find original remote-repo at url %r" % psm.url) + # END handle one single remote + # END handle check we found a remote + + orig_name = rmt_for_deletion.name + smm.delete_remote(rmt_for_deletion) + # NOTE: Currently we leave tags from the deleted remotes + # as well as separate tracking branches in the possibly totally + # changed repository ( someone could have changed the url to + # another project ). At some point, one might want to clean + # it up, but the danger is high to remove stuff the user + # has added explicitly + + # rename the new remote back to what it was + smr.rename(orig_name) + + # early on, we verified that the our current tracking branch + # exists in the remote. Now we have to assure that the + # sha we point to is still contained in the new remote + # tracking branch. + smsha = sm.binsha + found = False + rref = smr.refs[self.branch_name] + for c in rref.commit.traverse(): + if c.binsha == smsha: + found = True + break + # END traverse all commits in search for sha + # END for each commit + + if not found: + # adjust our internal binsha to use the one of the remote + # this way, it will be checked out in the next step + # This will change the submodule relative to us, so + # the user will be able to commit the change easily + log.warn("Current sha %s was not contained in the tracking\ + branch at the new remote, setting it the the remote's tracking branch", sm.hexsha) + sm.binsha = rref.commit.binsha + # END reset binsha + + # NOTE: All checkout is performed by the base implementation of update + # END handle dry_run + progress.update( + END | URLCHANGE, i, len_csms, prefix + "Done adjusting url of submodule %r" % (sm.name)) + # END skip remote handling if new url already exists in module + # END handle url + + # HANDLE PATH CHANGES + ##################### + if sm.branch_path != psm.branch_path: + # finally, create a new tracking branch which tracks the + # new remote branch + progress.update(BEGIN | BRANCHCHANGE, i, len_csms, prefix + + "Changing branch of submodule %r from %s to %s" + % (sm.name, psm.branch_path, sm.branch_path)) if not dry_run: - assert nn not in [r.name for r in rmts] - smr = smm.create_remote(nn, sm.url) - smr.fetch(progress=progress) - - # If we have a tracking branch, it should be available - # in the new remote as well. - if len([r for r in smr.refs if r.remote_head == sm.branch_name]) == 0: - raise ValueError( - "Submodule branch named %r was not available in new submodule remote at %r" - % (sm.branch_name, sm.url) - ) - # END head is not detached - - # now delete the changed one - rmt_for_deletion = None - for remote in rmts: - if remote.url == psm.url: - rmt_for_deletion = remote - break - # END if urls match - # END for each remote - - # if we didn't find a matching remote, but have exactly one, - # we can safely use this one - if rmt_for_deletion is None: - if len(rmts) == 1: - rmt_for_deletion = rmts[0] - else: - # if we have not found any remote with the original url - # we may not have a name. This is a special case, - # and its okay to fail here - # Alternatively we could just generate a unique name and leave all - # existing ones in place - raise InvalidGitRepositoryError( - "Couldn't find original remote-repo at url %r" % psm.url) - # END handle one single remote - # END handle check we found a remote - - orig_name = rmt_for_deletion.name - smm.delete_remote(rmt_for_deletion) - # NOTE: Currently we leave tags from the deleted remotes - # as well as separate tracking branches in the possibly totally - # changed repository ( someone could have changed the url to - # another project ). At some point, one might want to clean - # it up, but the danger is high to remove stuff the user - # has added explicitly - - # rename the new remote back to what it was - smr.rename(orig_name) - - # early on, we verified that the our current tracking branch - # exists in the remote. Now we have to assure that the - # sha we point to is still contained in the new remote - # tracking branch. - smsha = sm.binsha - found = False - rref = smr.refs[self.branch_name] - for c in rref.commit.traverse(): - if c.binsha == smsha: - found = True - break - # END traverse all commits in search for sha - # END for each commit - - if not found: - # adjust our internal binsha to use the one of the remote - # this way, it will be checked out in the next step - # This will change the submodule relative to us, so - # the user will be able to commit the change easily - log.warn("Current sha %s was not contained in the tracking\ - branch at the new remote, setting it the the remote's tracking branch", sm.hexsha) - sm.binsha = rref.commit.binsha - # END reset binsha - - # NOTE: All checkout is performed by the base implementation of update + smm = sm.module() + smmr = smm.remotes + try: + tbr = git.Head.create(smm, sm.branch_name, logmsg='branch: Created from HEAD') + except OSError: + # ... or reuse the existing one + tbr = git.Head(smm, sm.branch_path) + # END assure tracking branch exists + + tbr.set_tracking_branch(find_first_remote_branch(smmr, sm.branch_name)) + # figure out whether the previous tracking branch contains + # new commits compared to the other one, if not we can + # delete it. + try: + tbr = find_first_remote_branch(smmr, psm.branch_name) + if len(smm.git.cherry(tbr, psm.branch)) == 0: + psm.branch.delete(smm, psm.branch) + # END delete original tracking branch if there are no changes + except InvalidGitRepositoryError: + # ignore it if the previous branch couldn't be found in the + # current remotes, this just means we can't handle it + pass + # END exception handling + + # NOTE: All checkout is done in the base implementation of update # END handle dry_run - progress.update( - END | URLCHANGE, i, len_csms, prefix + "Done adjusting url of submodule %r" % (sm.name)) - # END skip remote handling if new url already exists in module - # END handle url - - # HANDLE PATH CHANGES - ##################### - if sm.branch_path != psm.branch_path: - # finally, create a new tracking branch which tracks the - # new remote branch - progress.update(BEGIN | BRANCHCHANGE, i, len_csms, prefix + - "Changing branch of submodule %r from %s to %s" - % (sm.name, psm.branch_path, sm.branch_path)) - if not dry_run: - smm = sm.module() - smmr = smm.remotes - try: - tbr = git.Head.create(smm, sm.branch_name, logmsg='branch: Created from HEAD') - except OSError: - # ... or reuse the existing one - tbr = git.Head(smm, sm.branch_path) - # END assure tracking branch exists - - tbr.set_tracking_branch(find_first_remote_branch(smmr, sm.branch_name)) - # figure out whether the previous tracking branch contains - # new commits compared to the other one, if not we can - # delete it. - try: - tbr = find_first_remote_branch(smmr, psm.branch_name) - if len(smm.git.cherry(tbr, psm.branch)) == 0: - psm.branch.delete(smm, psm.branch) - # END delete original tracking branch if there are no changes - except InvalidGitRepositoryError: - # ignore it if the previous branch couldn't be found in the - # current remotes, this just means we can't handle it - pass - # END exception handling - - # NOTE: All checkout is done in the base implementation of update - # END handle dry_run - progress.update( - END | BRANCHCHANGE, i, len_csms, prefix + "Done changing branch of submodule %r" % sm.name) - # END handle branch - # END handle - # END for each common submodule + progress.update( + END | BRANCHCHANGE, i, len_csms, prefix + "Done changing branch of submodule %r" % sm.name) + # END handle branch + # END handle + # END for each common submodule + except Exception as err: + if not keep_going: + raise + log.error(str(err)) + # end handle keep_going # FINALLY UPDATE ALL ACTUAL SUBMODULES ###################################### for sm in sms: # update the submodule using the default method sm.update(recursive=False, init=init, to_latest_revision=to_latest_revision, - progress=progress, dry_run=dry_run, force=force_reset) + progress=progress, dry_run=dry_run, force=force_reset, keep_going=keep_going) # update recursively depth first - question is which inconsitent # state will be better in case it fails somewhere. Defective branch @@ -326,7 +338,8 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= if sm.module_exists(): type(self)(sm.module()).update(recursive=True, force_remove=force_remove, init=init, to_latest_revision=to_latest_revision, - progress=progress, dry_run=dry_run, force_reset=force_reset) + progress=progress, dry_run=dry_run, force_reset=force_reset, + keep_going=keep_going) # END handle dry_run # END handle recursive # END for each submodule to update diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 047e0049d..b9502f753 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -731,18 +731,21 @@ def assert_exists(sm, value=True): new_name = csm.name + '/mine' assert csm.rename(new_name).name == new_name assert_exists(csm) + assert csm.repo.is_dirty(index=True, working_tree=False), "index must contain changed .gitmodules file" + csm.repo.index.commit("renamed module") # keep_going evaluation rsm = parent.submodule_update() assert_exists(sm) assert_exists(csm) - csm_writer = csm.config_writer().set_value('url', 'foo') + csm_writer = csm.config_writer().set_value('url', 'bar') csm_writer.release() csm.repo.index.commit("Have to commit submodule change for algorithm to pick it up") - assert csm.url == 'foo' + assert csm.url == 'bar' self.failUnlessRaises(Exception, rsm.update, recursive=True, to_latest_revision=True, progress=prog) assert_exists(csm) + rsm.update(recursive=True, to_latest_revision=True, progress=prog, keep_going=True) # remove sm_module_path = sm.module().git_dir From bb0f3d78d6980a1d43f05cb17a8da57a196a34f3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 20 Jan 2015 22:13:45 +0100 Subject: [PATCH 0132/2790] Fixed flake8 and a minor test regression. The latter happened as now BadName is thrown, instead of BadObject. Changes.rst was marked accordingly --- doc/source/changes.rst | 1 + git/objects/submodule/base.py | 38 ++++++++++++++++++----------------- git/objects/submodule/root.py | 11 +++++----- git/test/test_repo.py | 4 ++-- git/test/test_submodule.py | 4 ++-- git/util.py | 6 +++--- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 2277c4b7e..60fe9725d 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -8,6 +8,7 @@ Changelog * `[include]` sections in git configuration files are now respected * Added `GitConfigParser.rename_section()` * Added `Submodule.rename()` +* **POSSIBLY BREAKING CHANGE**: As `rev_parse` will now throw `BadName` as well as `BadObject`, client code will have to catch both exception types. * A list of all issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+ 0.3.5 - Bugfixes diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 7f06a7b16..4b2fc0c00 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -116,7 +116,7 @@ def _set_cache_(self, attr): except cp.NoSectionError: raise ValueError("This submodule instance does not exist anymore in '%s' file" % os.path.join(self.repo.working_tree_dir, '.gitmodules')) - # end + # end self._url = reader.get_value('url') # git-python extension values - optional self._branch_path = reader.get_value(self.k_head_option, git.Head.to_full_path(self.k_head_default)) @@ -411,7 +411,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): del(writer) # we deliberatly assume that our head matches our index ! - + try: repo.head.commit parent_repo_is_empty = False @@ -429,7 +429,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): return sm def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, dry_run=False, - force=False, keep_going=False): + force=False, keep_going=False): """Update the repository of this submodule to point to the checkout we point at with the binsha of this instance. @@ -444,14 +444,14 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= :param progress: UpdateProgress instance or None of no progress should be shown :param dry_run: if True, the operation will only be simulated, but not performed. All performed operations are read-only - :param force: + :param force: If True, we may reset heads even if the repository in question is dirty. Additinoally we will be allowed - to set a tracking branch which is ahead of its remote branch back into the past or the location of the + to set a tracking branch which is ahead of its remote branch back into the past or the location of the remote branch. This will essentially 'forget' commits. - If False, local tracking branches that are in the future of their respective remote branches will simply + If False, local tracking branches that are in the future of their respective remote branches will simply not be moved. - :param keep_going: if True, we will ignore but log all errors, and keep going recursively. - Unless dry_run is set as well, keep_going could cause subsequent/inherited errors you wouldn't see + :param keep_going: if True, we will ignore but log all errors, and keep going recursively. + Unless dry_run is set as well, keep_going could cause subsequent/inherited errors you wouldn't see otherwise. In conjunction with dry_run, it can be useful to anticipate all errors when updating submodules :note: does nothing in bare repositories @@ -487,7 +487,8 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= op |= BEGIN # END handle start - progress.update(op, i, len_rmts, prefix + "Fetching remote %s of submodule %r" % (remote, self.name)) + progress.update(op, i, len_rmts, prefix + "Fetching remote %s of submodule %r" + % (remote, self.name)) #=============================== if not dry_run: remote.fetch(progress=progress) @@ -589,11 +590,11 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= base_commit = mrepo.merge_base(mrepo.head.commit, hexsha) if len(base_commit) == 0 or base_commit[0].hexsha == hexsha: if force: - log.debug("Will force checkout or reset on local branch that is possibly in the future of" + - "the commit it will be checked out to, effectively 'forgetting' new commits") + log.debug("Will force checkout or reset on local branch that is possibly in the future of" + + "the commit it will be checked out to, effectively 'forgetting' new commits") else: - log.info("Skipping %s on branch '%s' of submodule repo '%s' as it contains un-pushed commits", - is_detached and "checkout" or "reset", mrepo.head, mrepo) + log.info("Skipping %s on branch '%s' of submodule repo '%s' as it contains " + + "un-pushed commits", is_detached and "checkout" or "reset", mrepo.head, mrepo) may_reset = False # end handle force # end handle if we are in the future @@ -619,7 +620,8 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= mrepo.head.reset(hexsha, index=True, working_tree=True) # END handle checkout # if we may reset/checkout - progress.update(END | UPDWKTREE, 0, 1, prefix + "Done updating working tree for submodule %r" % self.name) + progress.update(END | UPDWKTREE, 0, 1, prefix + "Done updating working tree for submodule %r" + % self.name) # END update to new commit only if needed except Exception as err: if not keep_going: @@ -633,7 +635,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= # in dry_run mode, the module might not exist if mrepo is not None: for submodule in self.iter_items(self.module()): - submodule.update(recursive, init, to_latest_revision, progress=progress, dry_run=dry_run, + submodule.update(recursive, init, to_latest_revision, progress=progress, dry_run=dry_run, force=force, keep_going=keep_going) # END handle recursive update # END handle dry run @@ -898,14 +900,14 @@ def set_parent_commit(self, commit, check=True): """Set this instance to use the given commit whose tree is supposed to contain the .gitmodules blob. - :param commit: - Commit'ish reference pointing at the root_tree, or None to always point to the + :param commit: + Commit'ish reference pointing at the root_tree, or None to always point to the most recent commit :param check: if True, relatively expensive checks will be performed to verify validity of the submodule. :raise ValueError: if the commit's tree didn't contain the .gitmodules blob. - :raise ValueError: + :raise ValueError: if the parent commit didn't store this submodule under the current path :return: self""" if commit is None: diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index dd023d464..7042e99c6 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -85,13 +85,13 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= Unless force_reset is specified, a local tracking branch will never be reset into its past, therefore the remote branch must be in the future for this to have an effect. :param force_reset: if True, submodules may checkout or reset their branch even if the repository has - pending changes that would be overwritten, or if the local tracking branch is in the future of the + pending changes that would be overwritten, or if the local tracking branch is in the future of the remote tracking branch and would be reset into its past. :param progress: RootUpdateProgress instance or None if no progress should be sent :param dry_run: if True, operations will not actually be performed. Progress messages will change accordingly to indicate the WOULD DO state of the operation. - :param keep_going: if True, we will ignore but log all errors, and keep going recursively. - Unless dry_run is set as well, keep_going could cause subsequent/inherited errors you wouldn't see + :param keep_going: if True, we will ignore but log all errors, and keep going recursively. + Unless dry_run is set as well, keep_going could cause subsequent/inherited errors you wouldn't see otherwise. In conjunction with dry_run, it can be useful to anticipate all errors when updating submodules :return: self""" @@ -136,7 +136,7 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= ################### rrsm = (spsms - ssms) len_rrsm = len(rrsm) - + for i, rsm in enumerate(rrsm): op = REMOVE if i == 0: @@ -168,7 +168,8 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= ############## if sm.path != psm.path and psm.module_exists(): progress.update(BEGIN | PATHCHANGE, i, len_csms, prefix + - "Moving repository of submodule %r from %s to %s" % (sm.name, psm.abspath, sm.abspath)) + "Moving repository of submodule %r from %s to %s" + % (sm.name, psm.abspath, sm.abspath)) # move the module to the new path if not dry_run: psm.move(sm.path, module=True, configuration=False) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index c583fcae4..c32dbdbff 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -591,8 +591,8 @@ def test_rev_parse(self): commit = rev_parse(first_rev) assert len(commit.parents) == 0 assert commit.hexsha == first_rev - self.failUnlessRaises(BadObject, rev_parse, first_rev + "~") - self.failUnlessRaises(BadObject, rev_parse, first_rev + "^") + self.failUnlessRaises(BadName, rev_parse, first_rev + "~") + self.failUnlessRaises(BadName, rev_parse, first_rev + "^") # short SHA1 commit2 = rev_parse(first_rev[:20]) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index b9502f753..6a03fe26c 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -535,7 +535,7 @@ def test_root_module(self, rwrepo): touch(nsm_file) nsm.module().index.add([nsm]) nsm.module().index.commit("added new file") - rm.update(recursive=False, dry_run=True, progress=prog) # would not change head, and thus doens't fail + rm.update(recursive=False, dry_run=True, progress=prog) # would not change head, and thus doens't fail # Everything we can do from now on will trigger the 'future' check, so no is_dirty() check will even run # This would only run if our local branch is in the past and we have uncommitted changes @@ -691,7 +691,7 @@ def test_git_submodule_compatibility(self, rwdir): def assert_exists(sm, value=True): assert sm.exists() == value assert sm.module_exists() == value - # end + # end # As git is backwards compatible itself, it would still recognize what we do here ... unless we really # muss it up. That's the only reason why the test is still here ... . diff --git a/git/util.py b/git/util.py index 8cab0b994..06fefcc37 100644 --- a/git/util.py +++ b/git/util.py @@ -251,9 +251,9 @@ def _parse_progress_line(self, line): message = message[:-len(done_token)] # END end message handling - self.update(op_code, - cur_count and float(cur_count), - max_count and float(max_count), + self.update(op_code, + cur_count and float(cur_count), + max_count and float(max_count), message) # END for each sub line return failed_lines From 47ac37be2e0e14e958ad24dc8cba1fa4b7f78700 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 21 Jan 2015 08:52:23 +0100 Subject: [PATCH 0133/2790] Assured that branch changes are properly handled. Previously we could try to remove the branch we are on. Of course, we have a test-case elaborate enough to verify we don't destroy changes in submodules accidentally. Therefore I am confident that this implementation is correct. Fixes #49 --- git/objects/submodule/base.py | 12 ------- git/objects/submodule/root.py | 25 ++++++------- git/objects/submodule/util.py | 2 +- git/repo/fun.py | 1 + git/test/test_submodule.py | 67 +++++++++++++++++++++++++++++++++-- 5 files changed, 77 insertions(+), 30 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 4b2fc0c00..ebb66495d 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -411,21 +411,9 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False): del(writer) # we deliberatly assume that our head matches our index ! - - try: - repo.head.commit - parent_repo_is_empty = False - except ValueError: - parent_repo_is_empty = True - # Can't set this yet, if the parent repo is empty. - # end sm.binsha = mrepo.head.commit.binsha index.add([sm], write=True) - if parent_repo_is_empty: - log.debug("Will not set _parent_commit now as the parent repository has no commit yet.") - # end - return sm def update(self, recursive=False, init=True, to_latest_revision=False, progress=None, dry_run=False, diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index 7042e99c6..1c863f6fb 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -287,6 +287,11 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= if not dry_run: smm = sm.module() smmr = smm.remotes + # As the branch might not exist yet, we will have to fetch all remotes to be sure ... . + for remote in smmr: + remote.fetch(progress=progress) + # end for each remote + try: tbr = git.Head.create(smm, sm.branch_name, logmsg='branch: Created from HEAD') except OSError: @@ -295,21 +300,11 @@ def update(self, previous_commit=None, recursive=True, force_remove=False, init= # END assure tracking branch exists tbr.set_tracking_branch(find_first_remote_branch(smmr, sm.branch_name)) - # figure out whether the previous tracking branch contains - # new commits compared to the other one, if not we can - # delete it. - try: - tbr = find_first_remote_branch(smmr, psm.branch_name) - if len(smm.git.cherry(tbr, psm.branch)) == 0: - psm.branch.delete(smm, psm.branch) - # END delete original tracking branch if there are no changes - except InvalidGitRepositoryError: - # ignore it if the previous branch couldn't be found in the - # current remotes, this just means we can't handle it - pass - # END exception handling - - # NOTE: All checkout is done in the base implementation of update + # NOTE: All head-resetting is done in the base implementation of update + # but we will have to checkout the new branch here. As it still points to the currently + # checkout out commit, we don't do any harm. + # As we don't want to update working-tree or index, changing the ref is all there is to do + smm.head.reference = tbr # END handle dry_run progress.update( diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py index 5604dec72..8b9873fc7 100644 --- a/git/objects/submodule/util.py +++ b/git/objects/submodule/util.py @@ -49,7 +49,7 @@ def find_first_remote_branch(remotes, branch_name): continue # END exception handling # END for remote - raise InvalidGitRepositoryError("Didn't find remote branch %r in any of the given remotes", branch_name) + raise InvalidGitRepositoryError("Didn't find remote branch '%r' in any of the given remotes" % branch_name) #} END utilities diff --git a/git/repo/fun.py b/git/repo/fun.py index 2a1270be7..2321dbc87 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -26,6 +26,7 @@ def touch(filename): fp = open(filename, "ab") fp.close() + return filename def is_git_dir(d): diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 6a03fe26c..49ab25865 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -529,10 +529,9 @@ def test_root_module(self, rwrepo): # 'apply work' to the nested submodule and assure this is not removed/altered during updates # Need to commit first, otherwise submodule.update wouldn't have a reason to change the head - nsm_file = os.path.join(nsm.module().working_tree_dir, 'new-file') + touch(os.path.join(nsm.module().working_tree_dir, 'new-file')) # We cannot expect is_dirty to even run as we wouldn't reset a head to the same location assert nsm.module().head.commit.hexsha == nsm.hexsha - touch(nsm_file) nsm.module().index.add([nsm]) nsm.module().index.commit("added new file") rm.update(recursive=False, dry_run=True, progress=prog) # would not change head, and thus doens't fail @@ -778,3 +777,67 @@ def test_rename(self, rwdir): if os.path.isfile(os.path.join(sm_mod.working_tree_dir, '.git')) == sm._need_gitfile_submodules(parent.git): assert sm_mod.git_dir.endswith(".git/modules/" + new_sm_name) # end + + @with_rw_directory + def test_branch_renames(self, rw_dir): + # Setup initial sandbox: + # parent repo has one submodule, which has all the latest changes + source_url = self._submodule_url() + sm_source_repo = git.Repo.clone_from(source_url, os.path.join(rw_dir, 'sm-source')) + parent_repo = git.Repo.init(os.path.join(rw_dir, 'parent')) + sm = parent_repo.create_submodule('mysubmodule', 'subdir/submodule', + sm_source_repo.working_tree_dir, branch='master') + parent_repo.index.commit('added submodule') + assert sm.exists() + + # Create feature branch with one new commit in submodule source + sm_fb = sm_source_repo.create_head('feature') + sm_fb.checkout() + new_file = touch(os.path.join(sm_source_repo.working_tree_dir, 'new-file')) + sm_source_repo.index.add([new_file]) + sm.repo.index.commit("added new file") + + # change designated submodule checkout branch to the new upstream feature branch + smcw = sm.config_writer() + smcw.set_value('branch', sm_fb.name) + smcw.release() + assert sm.repo.is_dirty(index=True, working_tree=False) + sm.repo.index.commit("changed submodule branch to '%s'" % sm_fb) + + # verify submodule update with feature branch that leaves currently checked out branch in it's past + sm_mod = sm.module() + prev_commit = sm_mod.commit() + assert sm_mod.head.ref.name == 'master' + assert parent_repo.submodule_update() + assert sm_mod.head.ref.name == sm_fb.name + assert sm_mod.commit() == prev_commit, "Without to_latest_revision, we don't change the commit" + + assert parent_repo.submodule_update(to_latest_revision=True) + assert sm_mod.head.ref.name == sm_fb.name + assert sm_mod.commit() == sm_fb.commit + + # Create new branch which is in our past, and thus seemingly unrelated to the currently checked out one + # To make it even 'harder', we shall fork and create a new commit + sm_pfb = sm_source_repo.create_head('past-feature', commit='HEAD~20') + sm_pfb.checkout() + sm_source_repo.index.add([touch(os.path.join(sm_source_repo.working_tree_dir, 'new-file'))]) + sm_source_repo.index.commit("new file added, to past of '%r'" % sm_fb) + + # Change designated submodule checkout branch to a new commit in its own past + smcw = sm.config_writer() + smcw.set_value('branch', sm_pfb.path) + smcw.release() + sm.repo.index.commit("changed submodule branch to '%s'" % sm_pfb) + + # Test submodule updates - must fail if submodule is dirty + touch(os.path.join(sm_mod.working_tree_dir, 'unstaged file')) + # This doesn't fail as our own submodule binsha didn't change, and the reset is only triggered if + # to latest revision is True. + parent_repo.submodule_update(to_latest_revision=False) + sm_mod.head.ref.name == sm_pfb.name, "should have been switched to past head" + sm_mod.commit() == sm_fb.commit, "Head wasn't reset" + + self.failUnlessRaises(RepositoryDirtyError, parent_repo.submodule_update, to_latest_revision=True) + parent_repo.submodule_update(to_latest_revision=True, force_reset=True) + assert sm_mod.commit() == sm_pfb.commit, "Now head should have been reset" + assert sm_mod.head.ref.name == sm_pfb.name From 0ed61f72c611deb07e0368cebdc9f06da32150cd Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 21 Jan 2015 09:35:56 +0100 Subject: [PATCH 0134/2790] removed debug code --- git/remote.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/git/remote.py b/git/remote.py index 5d9cba1b9..dbb82796b 100644 --- a/git/remote.py +++ b/git/remote.py @@ -338,7 +338,7 @@ class Remote(LazyMixin, Iterable): NOTE: When querying configuration, the configuration accessor will be cached to speed up subsequent accesses.""" - __slots__ = ("repo", "name", "_config_reader", "fetch_no") + __slots__ = ("repo", "name", "_config_reader") _id_attribute_ = "name" def __init__(self, repo, name): @@ -348,7 +348,6 @@ def __init__(self, repo, name): :param name: the name of the remote, i.e. 'origin'""" self.repo = repo self.name = name - self.fetch_no = 0 if os.name == 'nt': # some oddity: on windows, python 2.5, it for some reason does not realize @@ -524,10 +523,8 @@ def _get_fetch_info_from_stderr(self, proc, progress): progress_handler = progress.new_message_handler() - stderr_fetch = open(join(self.repo.git_dir, '%03i_debug_git-python_stderr' % self.fetch_no), 'wb') for line in proc.stderr: line = line.decode(defenc) - stderr_fetch.write((line).encode(defenc)) line = line.rstrip() for pline in progress_handler(line): if line.startswith('fatal:'): @@ -544,13 +541,8 @@ def _get_fetch_info_from_stderr(self, proc, progress): # We are only interested in stderr here ... finalize_process(proc) - stderr_fetch.close() # read head information - import shutil - shutil.copyfile(join(self.repo.git_dir, 'FETCH_HEAD'), - join(self.repo.git_dir, '%03i_debug_git-python_FETCH_HEAD' % self.fetch_no)) - self.fetch_no += 1 fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') fetch_head_info = [l.decode(defenc) for l in fp.readlines()] fp.close() From e48e52001d5abad7b28a4ecadde63c78c3946339 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 21 Jan 2015 11:45:32 +0100 Subject: [PATCH 0135/2790] Initial set of documentation improvements, and a fix to the submodule tests. Now travisci tests should work once again. Related to #239 --- doc/source/changes.rst | 2 ++ doc/source/reference.rst | 3 +- doc/source/tutorial.rst | 72 +++++++++++++++++++++----------------- git/cmd.py | 2 +- git/objects/base.py | 7 ++-- git/test/test_docs.py | 49 +++++++++++++++++++++++--- git/test/test_submodule.py | 2 +- 7 files changed, 96 insertions(+), 41 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 60fe9725d..4f67c1bb9 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -7,6 +7,8 @@ Changelog * Added `Repo.merge_base()` implementation. See the `respective issue on github `_ * `[include]` sections in git configuration files are now respected * Added `GitConfigParser.rename_section()` +* DOCS: special members like `__init__` are now listed in the API documentation +* DOCS: tutorial section was revised entirely * Added `Submodule.rename()` * **POSSIBLY BREAKING CHANGE**: As `rev_parse` will now throw `BadName` as well as `BadObject`, client code will have to catch both exception types. * A list of all issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+ diff --git a/doc/source/reference.rst b/doc/source/reference.rst index 7adc53287..8e0e296bd 100644 --- a/doc/source/reference.rst +++ b/doc/source/reference.rst @@ -8,7 +8,8 @@ Objects.Base .. automodule:: git.objects.base :members: - :undoc-members: + :undoc-members: + :special-members: Objects.Blob ------------ diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 4921d07b0..adce59109 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -8,42 +8,54 @@ GitPython Tutorial ================== -GitPython provides object model access to your git repository. This tutorial is composed of multiple sections, each of which explains a real-life usecase. +GitPython provides object model access to your git repository. This tutorial is composed of multiple sections, each of which explains a real-life usecase. -Initialize a Repo object -************************ +Meet the Repo type +****************** -The first step is to create a ``Repo`` object to represent your repository:: +The first step is to create a :class:`git.Repo ` object to represent your repository. - from git import * - repo = Repo("/Users/mtrier/Development/git-python") - assert repo.bare == False +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: def test_init_repo_object + :end-before: # ![1-test_init_repo_object] -In the above example, the directory ``/Users/mtrier/Development/git-python`` is my working repository and contains the ``.git`` directory. You can also initialize GitPython with a *bare* repository:: +In the above example, the directory ``self.rorepo.working_tree_dir`` equals ``/Users/mtrier/Development/git-python`` and is my working repository which contains the ``.git`` directory. You can also initialize GitPython with a *bare* repository. - repo = Repo.init("/var/git/git-python.git", bare=True) - assert repo.bare == True +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [2-test_init_repo_object] + :end-before: # ![2-test_init_repo_object] -A repo object provides high-level access to your data, it allows you to create and delete heads, tags and remotes and access the configuration of the repository:: +A repo object provides high-level access to your data, it allows you to create and delete heads, tags and remotes and access the configuration of the repository. - repo.config_reader() # get a config reader for read-only access - repo.config_writer() # get a config writer to change configuration +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [3-test_init_repo_object] + :end-before: # ![3-test_init_repo_object] -Query the active branch, query untracked files or whether the repository data has been modified:: +Query the active branch, query untracked files or whether the repository data has been modified. - repo.is_dirty() - False - repo.untracked_files - ['my_untracked_file'] +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [4-test_init_repo_object] + :end-before: # ![4-test_init_repo_object] -Clone from existing repositories or initialize new empty ones:: +Clone from existing repositories or initialize new empty ones. - cloned_repo = repo.clone("to/this/path") - new_repo = Repo.init("path/for/new/repo") +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [5-test_init_repo_object] + :end-before: # ![5-test_init_repo_object] -Archive the repository contents to a tar file:: +Archive the repository contents to a tar file. + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [6-test_init_repo_object] + :end-before: # ![6-test_init_repo_object] - repo.archive(open("repo.tar",'w')) +.. todo repo paths, heads, remotes, submodules Object Databases @@ -418,16 +430,12 @@ The previous approach would brutally overwrite the user's changes in the working Initializing a repository ************************* -In this example, we will initialize an empty repository, add an empty file to the index, and commit the change:: - - repo_dir = 'my-new-repo' - file_name = os.path.join(repo_dir, 'new-file') +In this example, we will initialize an empty repository, add an empty file to the index, and commit the change. - r = git.Repo.init(repo_dir) - # This function just creates an empty file ... - touch(file_name) - r.index.add([file_name]) - r.index.commit("initial commit") +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: def test_add_file_and_commit + :end-before: # ![test_add_file_and_commit] Please have a look at the individual methods as they usually support a vast amount of arguments to customize their behavior. diff --git a/git/cmd.py b/git/cmd.py index 80a30410c..d6b29d913 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -295,7 +295,7 @@ def wait(self): :raise GitCommandError: if the return status is not 0""" status = self.proc.wait() if status != 0: - raise GitCommandError(self.args, status, self.proc.stderr.read().decode(defenc)) + raise GitCommandError(self.args, status, self.proc.stderr.read()) # END status handling return status # END auto interrupt diff --git a/git/objects/base.py b/git/objects/base.py index eb59b0a91..42876fc88 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -132,9 +132,11 @@ class IndexObject(Object): def __init__(self, repo, binsha, mode=None, path=None): """Initialize a newly instanced IndexObject + :param repo: is the Repo we are located in :param binsha: 20 byte sha1 - :param mode: is the stat compatible file mode as int, use the stat module + :param mode: + is the stat compatible file mode as int, use the stat module to evaluate the infomration :param path: is the path to the file in the file system, relative to the git repository root, i.e. @@ -149,7 +151,8 @@ def __init__(self, repo, binsha, mode=None, path=None): self.path = path def __hash__(self): - """:return: + """ + :return: Hash of our path as index items are uniquely identifyable by path, not by their data !""" return hash(self.path) diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 5ebae5136..6befb9eae 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -6,21 +6,62 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os -import git from git.test.lib import TestBase from gitdb.test.lib import with_rw_directory -from git.repo.fun import touch -class TestGit(TestBase): +class Tutorials(TestBase): + + @with_rw_directory + def test_init_repo_object(self, rw_dir): + from git import Repo + join = os.path.join + + # rorepo is a a Repo instance pointing to the git-python repository. + # For all you know, the first argument to Repo is a path to the repository + # you want to work with + repo = Repo(self.rorepo.working_tree_dir) + assert repo.bare == False + # ![1-test_init_repo_object] + + # [2-test_init_repo_object] + bare_empty_repo = Repo.init(join(rw_dir, 'bare-repo'), bare=True) + assert bare_empty_repo.bare == True + # ![2-test_init_repo_object] + + # [3-test_init_repo_object] + repo.config_reader() # get a config reader for read-only access + cw = repo.config_writer() # get a config writer to change configuration + cw.release() # call release() to be sure changes are written and locks are released + # ![3-test_init_repo_object] + + # [4-test_init_repo_object] + repo.is_dirty() + # False + repo.untracked_files + # ['my_untracked_file'] + # ![4-test_init_repo_object] + + # [5-test_init_repo_object] + assert repo.clone(join(rw_dir, 'to/this/path')).__class__ is Repo + assert Repo.init(join(rw_dir, 'path/for/new/repo')).__class__ is Repo + # ![5-test_init_repo_object] + + # [6-test_init_repo_object] + repo.archive(open(join(rw_dir, 'repo.tar'), 'w')) + # ![6-test_init_repo_object] @with_rw_directory def test_add_file_and_commit(self, rw_dir): + import git + repo_dir = os.path.join(rw_dir, 'my-new-repo') file_name = os.path.join(repo_dir, 'new-file') r = git.Repo.init(repo_dir) # This function just creates an empty file ... - touch(file_name) + open(file_name, 'wb').close() r.index.add([file_name]) r.index.commit("initial commit") + + # ![test_add_file_and_commit] diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 49ab25865..1d4cf1782 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -783,7 +783,7 @@ def test_branch_renames(self, rw_dir): # Setup initial sandbox: # parent repo has one submodule, which has all the latest changes source_url = self._submodule_url() - sm_source_repo = git.Repo.clone_from(source_url, os.path.join(rw_dir, 'sm-source')) + sm_source_repo = git.Repo.clone_from(source_url, os.path.join(rw_dir, 'sm-source'), b='master') parent_repo = git.Repo.init(os.path.join(rw_dir, 'parent')) sm = parent_repo.create_submodule('mysubmodule', 'subdir/submodule', sm_source_repo.working_tree_dir, branch='master') From e4d3809161fc54d6913c0c2c7f6a7b51eebe223f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 21 Jan 2015 18:34:58 +0100 Subject: [PATCH 0136/2790] Added advance usage examples to tutorial and made minor fixes. GIT_PYTHON_TRACE would actually fail (now) if we debugged archive operations. Related to #239 --- README.md | 2 + doc/source/reference.rst | 2 + doc/source/tutorial.rst | 97 ++++++++++++++++++----- git/cmd.py | 9 ++- git/objects/base.py | 2 +- git/objects/commit.py | 9 ++- git/objects/submodule/base.py | 2 +- git/refs/reference.py | 5 +- git/remote.py | 29 ++++--- git/repo/base.py | 6 +- git/test/fixtures/diff_rename | 4 +- git/test/test_diff.py | 6 +- git/test/test_docs.py | 142 ++++++++++++++++++++++++++++++++-- git/test/test_remote.py | 4 + tox.ini | 3 +- 15 files changed, 270 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 57e9bbc9e..bdc455b68 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,8 @@ New BSD License. See the LICENSE file. [![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg?branch=0.3)](https://travis-ci.org/gitpython-developers/GitPython) [![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=master)](https://coveralls.io/r/gitpython-developers/GitPython?branch=master) [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) +[![Issue Stats](http://www.issuestats.com/github/gitpython-developers/GitPython/badge/pr)](http://www.issuestats.com/github/gitpython-developers/GitPython) +[![Issue Stats](http://www.issuestats.com/github/gitpython-developers/GitPython/badge/issue)](http://www.issuestats.com/github/gitpython-developers/GitPython) Now that there seems to be a massive user base, this should be motivation enough to let git-python return to a proper state, which means diff --git a/doc/source/reference.rst b/doc/source/reference.rst index 8e0e296bd..7a73fc716 100644 --- a/doc/source/reference.rst +++ b/doc/source/reference.rst @@ -17,6 +17,7 @@ Objects.Blob .. automodule:: git.objects.blob :members: :undoc-members: + :special-members: Objects.Commit -------------- @@ -24,6 +25,7 @@ Objects.Commit .. automodule:: git.objects.commit :members: :undoc-members: + :special-members: Objects.Tag ----------- diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index adce59109..c6e5626b5 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -55,26 +55,67 @@ Archive the repository contents to a tar file. :start-after: # [6-test_init_repo_object] :end-before: # ![6-test_init_repo_object] -.. todo repo paths, heads, remotes, submodules - - -Object Databases -**************** -``Repo`` instances are powered by its object database instance which will be used when extracting any data, or when writing new objects. +Advanced Repo Usage +=================== -The type of the database determines certain performance characteristics, such as the quantity of objects that can be read per second, the resource usage when reading large data files, as well as the average memory footprint of your application. +And of course, there is much more you can do with this type, most of the following will be explained in greater detail in specific tutorials. -GitDB -===== -The GitDB is a pure-python implementation of the git object database. It is the default database to use in GitPython 0.3. Its uses less memory when handling huge files, but will be 2 to 5 times slower when extracting large quantities small of objects from densely packed repositories:: - - repo = Repo("path/to/repo", odbt=GitDB) +Query relevant repository paths ... + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [7-test_init_repo_object] + :end-before: # ![7-test_init_repo_object] + +:class:`Heads ` Heads are branches in git-speak. :class:`References ` are pointers to a specific commit or to other references. Heads and :class:`Tags ` are a kind of references. GitPython allows you to query them rather intuitively. + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [8-test_init_repo_object] + :end-before: # ![8-test_init_repo_object] + +You can also create new heads ... + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [9-test_init_repo_object] + :end-before: # ![9-test_init_repo_object] + +... and tags ... + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [10-test_init_repo_object] + :end-before: # ![10-test_init_repo_object] + +You can traverse down to :class:`git objects ` through references and other objects. Some objects like :class:`commits ` have additional meta-data to query. + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [11-test_init_repo_object] + :end-before: # ![11-test_init_repo_object] + +:class:`Remotes ` allow to handle fetch, pull and push operations, while providing optional real-time progress information to :class:`progress delegates `. + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [12-test_init_repo_object] + :end-before: # ![12-test_init_repo_object] + +The :class:`index ` is also called stage in git-speak. It is used to prepare new commits, and can be used to keep results of merge operations. Our index implementation allows to stream date into the index, which is useful for bare repositories that do not have a working tree. + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [13-test_init_repo_object] + :end-before: # ![13-test_init_repo_object] + +:class:`Submodules ` represent all aspects of git submodules, which allows you query all of their related information, and manipulate in various ways. + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [14-test_init_repo_object] + :end-before: # ![14-test_init_repo_object] -GitCmdObjectDB -============== -The git command database uses persistent git-cat-file instances to read repository information. These operate very fast under all conditions, but will consume additional memory for the process itself. When extracting large files, memory usage will be much higher than the one of the ``GitDB``:: - - repo = Repo("path/to/repo", odbt=GitCmdObjectDB) Examining References ******************** @@ -107,7 +148,7 @@ Access the reflog easily:: log[0] # first (i.e. oldest) reflog entry log[-1] # last (i.e. most recent) reflog entry -For more information on the reflog, see the ``RefLog`` type's documentation. +For more information on the reflog, see the :class:`git.RefLog ` type's documentation. Modifying References ******************** @@ -454,6 +495,26 @@ The special notion ``git.command(flag=True)`` will create a flag without value l If ``None`` is found in the arguments, it will be dropped silently. Lists and tuples passed as arguments will be unpacked recursively to individual arguments. Objects are converted to strings using the str(...) function. + +Object Databases +**************** +:class:`git.Repo ` instances are powered by its object database instance which will be used when extracting any data, or when writing new objects. + +The type of the database determines certain performance characteristics, such as the quantity of objects that can be read per second, the resource usage when reading large data files, as well as the average memory footprint of your application. + +GitDB +===== +The GitDB is a pure-python implementation of the git object database. It is the default database to use in GitPython 0.3. Its uses less memory when handling huge files, but will be 2 to 5 times slower when extracting large quantities small of objects from densely packed repositories:: + + repo = Repo("path/to/repo", odbt=GitDB) + + +GitCmdObjectDB +============== +The git command database uses persistent git-cat-file instances to read repository information. These operate very fast under all conditions, but will consume additional memory for the process itself. When extracting large files, memory usage will be much higher than the one of the ``GitDB``:: + + repo = Repo("path/to/repo", odbt=GitCmdObjectDB) + Git Command Debugging and Customization *************************************** diff --git a/git/cmd.py b/git/cmd.py index d6b29d913..55ed74dd0 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -579,11 +579,16 @@ def execute(self, command, if self.GIT_PYTHON_TRACE == 'full': cmdstr = " ".join(command) + + def as_text(stdout_value): + return not output_stream and stdout_value.decode(defenc) or '' + # end + if stderr_value: log.info("%s -> %d; stdout: '%s'; stderr: '%s'", - cmdstr, status, stdout_value.decode(defenc), stderr_value.decode(defenc)) + cmdstr, status, as_text(stdout_value), stderr_value.decode(defenc)) elif stdout_value: - log.info("%s -> %d; stdout: '%s'", cmdstr, status, stdout_value.decode(defenc)) + log.info("%s -> %d; stdout: '%s'", cmdstr, status, as_text(stdout_value)) else: log.info("%s -> %d", cmdstr, status) # END handle debug printing diff --git a/git/objects/base.py b/git/objects/base.py index 42876fc88..77d0ed635 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -135,7 +135,7 @@ def __init__(self, repo, binsha, mode=None, path=None): :param repo: is the Repo we are located in :param binsha: 20 byte sha1 - :param mode: + :param mode: is the stat compatible file mode as int, use the stat module to evaluate the infomration :param path: diff --git a/git/objects/commit.py b/git/objects/commit.py index f2ce91ca0..b9718694f 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -69,6 +69,7 @@ def __init__(self, repo, binsha, tree=None, author=None, authored_date=None, aut message=None, parents=None, encoding=None, gpgsig=None): """Instantiate a new Commit. All keyword arguments taking None as default will be implicitly set on first query. + :param binsha: 20 byte sha1 :param parents: tuple( Commit, ... ) is a tuple of commit ids or actual Commits @@ -97,7 +98,8 @@ def __init__(self, repo, binsha, tree=None, author=None, authored_date=None, aut dependency graph :return: git.Commit - :note: Timezone information is in the same format and in the same sign + :note: + Timezone information is in the same format and in the same sign as what time.altzone returns. The sign is inverted compared to git's UTC timezone.""" super(Commit, self).__init__(repo, binsha) @@ -296,6 +298,11 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, # empty repositories have no head commit parent_commits = list() # END handle parent commits + else: + for p in parent_commits: + if not isinstance(p, cls): + raise ValueError("Parent commit '%r' must be of type %s" % (p, cls)) + # end check parent commit types # END if parent commits are unset # retrieve all additional information, create a commit object, and diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index ebb66495d..cd7d4ec42 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -781,7 +781,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): csm.remove(module, force, configuration, dry_run) del(csm) # end - if not dry_run and nc > 0: + if configuration and not dry_run and nc > 0: # Assure we don't leave the parent repository in a dirty state, and commit our changes # It's important for recursive, unforced, deletions to work as expected self.module().index.commit("Removed submodule '%s'" % self.name) diff --git a/git/refs/reference.py b/git/refs/reference.py index 8741ebb95..3e132aeff 100644 --- a/git/refs/reference.py +++ b/git/refs/reference.py @@ -51,7 +51,8 @@ def __str__(self): #{ Interface def set_object(self, object, logmsg=None): - """Special version which checks if the head-log needs an update as well""" + """Special version which checks if the head-log needs an update as well + :return: self""" oldbinsha = None if logmsg is not None: head = self.repo.head @@ -78,6 +79,8 @@ def set_object(self, object, logmsg=None): self.repo.head.log_append(oldbinsha, logmsg) # END check if the head + return self + # NOTE: Don't have to overwrite properties as the will only work without a the log @property diff --git a/git/remote.py b/git/remote.py index dbb82796b..fcec52285 100644 --- a/git/remote.py +++ b/git/remote.py @@ -378,6 +378,8 @@ def _config_section_name(self): def _set_cache_(self, attr): if attr == "_config_reader": + # NOTE: This is cached as __getattr__ is overridden to return remote config values implicitly, such as + # in print(r.pushurl) self._config_reader = SectionConstraint(self.repo.config_reader(), self._config_section_name()) else: super(Remote, self)._set_cache_(attr) @@ -475,8 +477,13 @@ def create(cls, repo, name, url, **kwargs): @classmethod def remove(cls, repo, name): - """Remove the remote with the given name""" + """Remove the remote with the given name + :return: the passed remote name to remove + """ repo.git.remote("rm", name) + if isinstance(name, cls): + name._clear_cache() + return name # alias rm = remove @@ -489,11 +496,8 @@ def rename(self, new_name): self.repo.git.remote("rename", self.name, new_name) self.name = new_name - try: - del(self._config_reader) # it contains cached values, section names are different now - except AttributeError: - pass - # END handle exception + self._clear_cache() + return self def update(self, **kwargs): @@ -662,6 +666,13 @@ def config_reader(self): Hence you may simple type config.get("pushurl") to obtain the information""" return self._config_reader + def _clear_cache(self): + try: + del(self._config_reader) + except AttributeError: + pass + # END handle exception + @property def config_writer(self): """ @@ -676,9 +687,5 @@ def config_writer(self): writer = self.repo.config_writer() # clear our cache to assure we re-read the possibly changed configuration - try: - del(self._config_reader) - except AttributeError: - pass - # END handle exception + self._clear_cache() return SectionConstraint(writer, self._config_section_name()) diff --git a/git/repo/base.py b/git/repo/base.py index ef12473bb..ce8db7f7f 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -209,10 +209,8 @@ def _set_description(self, descr): @property def working_tree_dir(self): - """:return: The working tree directory of our git repository - :raise AssertionError: If we are a bare repository""" - if self._working_tree_dir is None: - raise AssertionError("Repository at %r is bare and does not have a working tree directory" % self.git_dir) + """:return: The working tree directory of our git repository. If this is a bare repository, None is returned. + """ return self._working_tree_dir @property diff --git a/git/test/fixtures/diff_rename b/git/test/fixtures/diff_rename index 13abae0ea..2d5241e33 100644 --- a/git/test/fixtures/diff_rename +++ b/git/test/fixtures/diff_rename @@ -8,5 +8,5 @@ committer Michael Trier 1229389391 -0500 diff --git a/AUTHORS b/CONTRIBUTORS similarity index 100% -rename from AUTHORS -rename to CONTRIBUTORS +rename from Jérôme +rename to müller diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 42972603e..f2ce14471 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -1,3 +1,4 @@ +#-*-coding:utf-8-*- # test_diff.py # Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors # @@ -53,8 +54,9 @@ def test_diff_with_rename(self): diff = diffs[0] assert_true(diff.renamed) - assert_equal(diff.rename_from, 'AUTHORS') - assert_equal(diff.rename_to, 'CONTRIBUTORS') + assert_equal(diff.rename_from, u'Jérôme') + assert_equal(diff.rename_to, u'müller') + assert isinstance(str(diff), str) output = StringProcessAdapter(fixture('diff_rename_raw')) diffs = Diff._index_from_raw_format(self.rorepo, output.stdout) diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 6befb9eae..9a04784de 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -21,14 +21,14 @@ def test_init_repo_object(self, rw_dir): # For all you know, the first argument to Repo is a path to the repository # you want to work with repo = Repo(self.rorepo.working_tree_dir) - assert repo.bare == False + assert not repo.bare # ![1-test_init_repo_object] # [2-test_init_repo_object] - bare_empty_repo = Repo.init(join(rw_dir, 'bare-repo'), bare=True) - assert bare_empty_repo.bare == True + bare_repo = Repo.init(join(rw_dir, 'bare-repo'), bare=True) + assert bare_repo.bare # ![2-test_init_repo_object] - + # [3-test_init_repo_object] repo.config_reader() # get a config reader for read-only access cw = repo.config_writer() # get a config writer to change configuration @@ -41,16 +41,142 @@ def test_init_repo_object(self, rw_dir): repo.untracked_files # ['my_untracked_file'] # ![4-test_init_repo_object] - + # [5-test_init_repo_object] - assert repo.clone(join(rw_dir, 'to/this/path')).__class__ is Repo + cloned_repo = repo.clone(join(rw_dir, 'to/this/path')) + assert cloned_repo.__class__ is Repo # clone an existing repository assert Repo.init(join(rw_dir, 'path/for/new/repo')).__class__ is Repo # ![5-test_init_repo_object] - + # [6-test_init_repo_object] - repo.archive(open(join(rw_dir, 'repo.tar'), 'w')) + repo.archive(open(join(rw_dir, 'repo.tar'), 'wb')) # ![6-test_init_repo_object] + # repository paths + # [7-test_init_repo_object] + assert os.path.isdir(cloned_repo.working_tree_dir) # directory with your work files + assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir) # directory containing the git repository + assert bare_repo.working_tree_dir is None # bare repositories have no working tree + # ![7-test_init_repo_object] + + # heads, tags and references + # heads are branches in git-speak + # [8-test_init_repo_object] + assert repo.head.ref == repo.heads.master # head is a symbolic reference pointing to master + assert repo.tags['0.3.5'] == repo.tag('refs/tags/0.3.5') # you can access tags in various ways too + assert repo.refs.master == repo.heads['master'] # .refs provides access to all refs, i.e. heads ... + assert repo.refs['origin/master'] == repo.remotes.origin.refs.master # ... remotes ... + assert repo.refs['0.3.5'] == repo.tags['0.3.5'] # ... and tags + # ![8-test_init_repo_object] + + # create a new head/branch + # [9-test_init_repo_object] + new_branch = cloned_repo.create_head('feature') # create a new branch ... + assert cloned_repo.active_branch != new_branch # which wasn't checked out yet ... + assert new_branch.commit == cloned_repo.active_branch.commit # and which points to the checked-out commit + # It's easy to let a branch point to the previous commit, without affecting anything else + # Each reference provides access to the git object it points to, usually commits + assert new_branch.set_commit('HEAD~1').commit == cloned_repo.active_branch.commit.parents[0] + # ![9-test_init_repo_object] + + # create a new tag reference + # [10-test_init_repo_object] + past = cloned_repo.create_tag('past', ref=new_branch, + message="This is a tag-object pointing to %s" % new_branch.name) + assert past.commit == new_branch.commit # the tag points to the specified commit + assert past.tag.message.startswith("This is") # and its object carries the message provided + + now = cloned_repo.create_tag('now') # This is a tag-reference. It may not carry meta-data + assert now.tag is None + # ![10-test_init_repo_object] + + # Object handling + # [11-test_init_repo_object] + assert now.commit.message != past.commit.message + # You can read objects directly through binary streams, no working tree required + assert (now.commit.tree / 'VERSION').data_stream.read().decode('ascii').startswith('0') + + # You can traverse trees as well to handle all contained files of a particular commit + file_count = 0 + tree_count = 0 + tree = past.commit.tree + for item in tree.traverse(): + file_count += item.type == 'blob' + tree_count += item.type == 'tree' + assert file_count and tree_count # we have accumulated all directories and files + assert len(tree.blobs) + len(tree.trees) == len(tree) # a tree is iterable itself to traverse its children + # ![11-test_init_repo_object] + + # remotes allow handling push, pull and fetch operations + # [12-test_init_repo_object] + from git import RemoteProgress + + class MyProgressPrinter(RemoteProgress): + def update(self, op_code, cur_count, max_count=None, message=''): + print(op_code, cur_count, max_count, cur_count / (max_count or 100.0), message or "NO MESSAGE") + # end + + assert len(cloned_repo.remotes) == 1 # we have been cloned, so there should be one remote + assert len(bare_repo.remotes) == 0 # this one was just initialized + origin = bare_repo.create_remote('origin', url=cloned_repo.working_tree_dir) + assert origin.exists() + for fetch_info in origin.fetch(progress=MyProgressPrinter()): + print("Updated %s to %s" % (fetch_info.ref, fetch_info.commit)) + # create a local branch at the latest fetched master. We specify the name statically, but you have all + # information to do it programatically as well. + bare_master = bare_repo.create_head('master', origin.refs.master) + bare_repo.head.set_reference(bare_master) + assert not bare_repo.delete_remote(origin).exists() + # push and pull behave very similarly + # ![12-test_init_repo_object] + + # index + # [13-test_init_repo_object] + assert new_branch.checkout() == cloned_repo.active_branch # checking out a branch adjusts the working tree + assert new_branch.commit == past.commit # Now the past is checked out + + new_file_path = os.path.join(cloned_repo.working_tree_dir, 'my-new-file') + open(new_file_path, 'wb').close() # create new file in working tree + cloned_repo.index.add([new_file_path]) # add it to the index + # Commit the changes to deviate masters history + cloned_repo.index.commit("Added a new file in the past - for later merege") + + # prepare a merge + master = cloned_repo.heads.master # right-hand side is ahead of us, in the future + merge_base = cloned_repo.merge_base(new_branch, master) # allwos for a three-way merge + cloned_repo.index.merge_tree(master, base=merge_base) # write the merge result into index + cloned_repo.index.commit("Merged past and now into future ;)", + parent_commits=(new_branch.commit, master.commit)) + + # now new_branch is ahead of master, which probably should be checked out and reset softly. + # note that all these operations didn't touch the working tree, as we managed it ourselves. + # This definitely requires you to know what you are doing :) ! + assert os.path.basename(new_file_path) in new_branch.commit.tree # new file is now in tree + master.commit = new_branch.commit # let master point to most recent commit + cloned_repo.head.reference = master # we adjusted just the reference, not the working tree or index + # ![13-test_init_repo_object] + + # submodules + + # [14-test_init_repo_object] + # create a new submodule and check it out on the spot, setup to track master branch of `bare_repo` + # As our GitPython repository has submodules already that point to github, make sure we don't + # interact with them + for sm in cloned_repo.submodules: + assert not sm.remove().exists() # after removal, the sm doesn't exist anymore + sm = cloned_repo.create_submodule('mysubrepo', 'path/to/subrepo', url=bare_repo.git_dir, branch='master') + + # .gitmodules was written and added to the index, which is now being committed + cloned_repo.index.commit("Added submodule") + assert sm.exists() and sm.module_exists() # this submodule is defintely available + sm.remove(module=True, configuration=False) # remove the working tree + assert sm.exists() and not sm.module_exists() # the submodule itself is still available + + # update all submodules, non-recursively to save time, this method is very powerful, go have a look + cloned_repo.submodule_update(recursive=False) + assert sm.module_exists() # The submodules working tree was checked out by update + # ![14-test_init_repo_object] + @with_rw_directory def test_add_file_and_commit(self, rw_dir): import git diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 110f1fa5c..d4a92ed4d 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -451,11 +451,15 @@ def test_creation_and_removal(self, bare_rw_repo): remote = Remote.create(bare_rw_repo, *arg_list) assert remote.name == "test_new_one" assert remote in bare_rw_repo.remotes + assert remote.exists() # create same one again self.failUnlessRaises(GitCommandError, Remote.create, bare_rw_repo, *arg_list) Remote.remove(bare_rw_repo, new_name) + assert remote.exists() # We still have a cache that doesn't know we were deleted by name + remote._clear_cache() + assert not remote.exists() # Cache should be renewed now. This is an issue ... for remote in bare_rw_repo.remotes: if remote.name == new_name: diff --git a/tox.ini b/tox.ini index a3509756d..bb1e9a85b 100644 --- a/tox.ini +++ b/tox.ini @@ -18,6 +18,7 @@ commands = {posargs} [flake8] #show-source = True # E265 = comment blocks like @{ section, which it can't handle -ignore = E265 +# W293 = Blank line contains whitespace +ignore = E265,W293 max-line-length = 120 exclude = .tox,.venv,build,dist,doc,git/ext/ From d565a874f29701531ce1fc0779592838040d3edf Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 21 Jan 2015 18:56:29 +0100 Subject: [PATCH 0137/2790] Fixed regression in test-suite for IndexFile Previously, it checked for AssertionErrors, now we have to implement need-unbare-repo check ourselves. --- doc/source/changes.rst | 7 ++++++- git/index/base.py | 8 +++++++- git/objects/submodule/base.py | 4 ++-- git/objects/submodule/util.py | 16 +--------------- git/test/test_index.py | 12 ++++++++---- git/util.py | 22 ++++++++++++++++++++-- 6 files changed, 44 insertions(+), 25 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 4f67c1bb9..2da3dad24 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -10,7 +10,12 @@ Changelog * DOCS: special members like `__init__` are now listed in the API documentation * DOCS: tutorial section was revised entirely * Added `Submodule.rename()` -* **POSSIBLY BREAKING CHANGE**: As `rev_parse` will now throw `BadName` as well as `BadObject`, client code will have to catch both exception types. +* **POSSIBLY BREAKING CHANGES** + + * As `rev_parse` will now throw `BadName` as well as `BadObject`, client code will have to catch both exception types. + * Repo.working_tree_dir now returns None if it is bare. Previously it raised AssertionError. + * IndexFile.add() previously raised AssertionError when paths where used with bare repository, now it raises InvalidGitRepositoryError + * A list of all issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+ 0.3.5 - Bugfixes diff --git a/git/index/base.py b/git/index/base.py index 7002385ce..b73edd6f3 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -27,7 +27,8 @@ import git.diff as diff from git.exc import ( GitCommandError, - CheckoutError + CheckoutError, + InvalidGitRepositoryError ) from git.objects import ( @@ -54,6 +55,7 @@ join_path_native, file_contents_ro, to_native_path_linux, + unbare_repo ) from .fun import ( @@ -346,6 +348,7 @@ def from_tree(cls, repo, *treeish, **kwargs): return index # UTILITIES + @unbare_repo def _iter_expand_paths(self, paths): """Expand the directories in list of paths to the corresponding paths accordingly, @@ -536,6 +539,8 @@ def _to_relative_path(self, path): if it is not within our git direcotory""" if not os.path.isabs(path): return path + if self.repo.bare: + raise InvalidGitRepositoryError("require non-bare repository") relative_path = path.replace(self.repo.working_tree_dir + os.sep, "") if relative_path == path: raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir)) @@ -575,6 +580,7 @@ def _store_path(self, filepath, fprogress): return BaseIndexEntry((stat_mode_to_index_mode(st.st_mode), istream.binsha, 0, to_native_path_linux(filepath))) + @unbare_repo @git_working_dir def _entries_for_paths(self, paths, path_rewriter, fprogress, entries): entries_added = list() diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index cd7d4ec42..94322a557 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -3,7 +3,6 @@ mkhead, sm_name, sm_section, - unbare_repo, SubmoduleConfigParser, find_first_remote_branch ) @@ -14,7 +13,8 @@ join_path_native, to_native_path_linux, RemoteProgress, - rmtree + rmtree, + unbare_repo ) from git.config import ( diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py index 8b9873fc7..0b4ce3c53 100644 --- a/git/objects/submodule/util.py +++ b/git/objects/submodule/util.py @@ -4,7 +4,7 @@ from io import BytesIO import weakref -__all__ = ('sm_section', 'sm_name', 'mkhead', 'unbare_repo', 'find_first_remote_branch', +__all__ = ('sm_section', 'sm_name', 'mkhead', 'find_first_remote_branch', 'SubmoduleConfigParser') #{ Utilities @@ -26,20 +26,6 @@ def mkhead(repo, path): return git.Head(repo, git.Head.to_full_path(path)) -def unbare_repo(func): - """Methods with this decorator raise InvalidGitRepositoryError if they - encounter a bare repository""" - - def wrapper(self, *args, **kwargs): - if self.repo.bare: - raise InvalidGitRepositoryError("Method '%s' cannot operate on bare repositories" % func.__name__) - # END bare method - return func(self, *args, **kwargs) - # END wrapper - wrapper.__name__ = func.__name__ - return wrapper - - def find_first_remote_branch(remotes, branch_name): """Find the remote branch matching the name of the given branch or raise InvalidGitRepositoryError""" for remote in remotes: diff --git a/git/test/test_index.py b/git/test/test_index.py index 0569f40fe..63f99f109 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -12,7 +12,10 @@ with_rw_repo ) from git.util import Actor -from git.exc import HookExecutionError +from git.exc import ( + HookExecutionError, + InvalidGitRepositoryError +) from git import ( IndexFile, BlobFilter, @@ -740,7 +743,8 @@ def test_index_bare_add(self, rw_bare_repo): # property rw_bare_repo.working_tree_dir will return '/tmp' # instead of throwing the Exception we are expecting. This is # a quick hack to make this test fail when expected. - rw_bare_repo._working_tree_dir = None + assert rw_bare_repo.working_tree_dir is None + assert rw_bare_repo.bare contents = b'This is a BytesIO file' filesize = len(contents) fileobj = BytesIO(contents) @@ -758,6 +762,6 @@ def test_index_bare_add(self, rw_bare_repo): path = os.path.join('git', 'test', 'test_index.py') try: rw_bare_repo.index.add([path]) - except Exception as e: - asserted = "does not have a working tree" in str(e) + except InvalidGitRepositoryError: + asserted = True assert asserted, "Adding using a filename is not correctly asserted." diff --git a/git/util.py b/git/util.py index 06fefcc37..02c54bc3e 100644 --- a/git/util.py +++ b/git/util.py @@ -16,7 +16,11 @@ # NOTE: Some of the unused imports might be used/imported by others. # Handle once test-cases are back up and running. -from .exc import GitCommandError +from .exc import ( + GitCommandError, + InvalidGitRepositoryError +) + from .compat import ( MAXSIZE, defenc, @@ -37,11 +41,25 @@ __all__ = ("stream_copy", "join_path", "to_native_path_windows", "to_native_path_linux", "join_path_native", "Stats", "IndexFileSHA1Writer", "Iterable", "IterableList", "BlockingLockFile", "LockFile", 'Actor', 'get_user_id', 'assure_directory_exists', - 'RemoteProgress', 'rmtree', 'WaitGroup') + 'RemoteProgress', 'rmtree', 'WaitGroup', 'unbare_repo') #{ Utility Methods +def unbare_repo(func): + """Methods with this decorator raise InvalidGitRepositoryError if they + encounter a bare repository""" + + def wrapper(self, *args, **kwargs): + if self.repo.bare: + raise InvalidGitRepositoryError("Method '%s' cannot operate on bare repositories" % func.__name__) + # END bare method + return func(self, *args, **kwargs) + # END wrapper + wrapper.__name__ = func.__name__ + return wrapper + + def rmtree(path): """Remove the given recursively. From 1287f69b42fa7d6b9d65abfef80899b22edfef55 Mon Sep 17 00:00:00 2001 From: Jonas Trappenberg Date: Tue, 20 Jan 2015 21:47:07 -0800 Subject: [PATCH 0138/2790] Fix some typos --- git/cmd.py | 4 ++-- git/remote.py | 2 +- git/test/test_remote.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 55ed74dd0..ef347925d 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -139,7 +139,7 @@ def deplete_buffer(fno, handler, buf_list, wg=None): if hasattr(select, 'poll'): # poll is preferred, as select is limited to file handles up to 1024 ... . This could otherwise be - # an issue for us, as it matters how many handles or own process has + # an issue for us, as it matters how many handles our own process has poll = select.poll() READ_ONLY = select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR CLOSED = select.POLLHUP | select.POLLERR @@ -731,7 +731,7 @@ def make_call(): import warnings msg = "WARNING: Automatically switched to use git.cmd as git executable" msg += ", which reduces performance by ~70%." - msg += "Its recommended to put git.exe into the PATH or to " + msg += "It is recommended to put git.exe into the PATH or to " msg += "set the %s " % self._git_exec_env_var msg += "environment variable to the executable's location" warnings.warn(msg) diff --git a/git/remote.py b/git/remote.py index fcec52285..c176b43b7 100644 --- a/git/remote.py +++ b/git/remote.py @@ -354,7 +354,7 @@ def __init__(self, repo, name): # that it has the config_writer property, but instead calls __getattr__ # which will not yield the expected results. 'pinging' the members # with a dir call creates the config_writer property that we require - # ... bugs like these make me wonder wheter python really wants to be used + # ... bugs like these make me wonder whether python really wants to be used # for production. It doesn't happen on linux though. dir(self) # END windows special handling diff --git a/git/test/test_remote.py b/git/test/test_remote.py index d4a92ed4d..bf2f76a86 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -163,11 +163,11 @@ def fetch_and_test(remote, **kwargs): def get_info(res, remote, name): return res["%s/%s" % (remote, name)] - # put remote head to master as it is garantueed to exist + # put remote head to master as it is guaranteed to exist remote_repo.head.reference = remote_repo.heads.master res = fetch_and_test(remote) - # all uptodate + # all up to date for info in res: assert info.flags & info.HEAD_UPTODATE From 261aedd2e13308755894405c7a76b72373dab879 Mon Sep 17 00:00:00 2001 From: Jonas Trappenberg Date: Tue, 20 Jan 2015 23:19:28 -0800 Subject: [PATCH 0139/2790] Add 'sshkey' context manager --- doc/source/tutorial.rst | 6 ++++ git/cmd.py | 76 ++++++++++++++++++++++++++++++++++++++++- scripts/ssh_wrapper.py | 9 +++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100755 scripts/ssh_wrapper.py diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index c6e5626b5..6ca0fd877 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -383,6 +383,12 @@ You can easily access configuration information for a remote by accessing option Change configuration for a specific remote only:: o.config_writer.set("pushurl", "other_url") + +You can also specify an SSH key to use for any operations on the remotes: + + private_key_file = project_dir+'id_rsa_deployment_key' + with repo.git.sshkey(private_key_file): + o.fetch() Submodule Handling diff --git a/git/cmd.py b/git/cmd.py index ef347925d..1022fc254 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -5,6 +5,7 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os +import os.path import sys import select import logging @@ -12,6 +13,7 @@ import errno import mmap +from contextlib import contextmanager from subprocess import ( call, Popen, @@ -223,7 +225,7 @@ class Git(LazyMixin): Set its value to 'full' to see details about the returned values. """ __slots__ = ("_working_dir", "cat_file_all", "cat_file_header", "_version_info", - "_git_options") + "_git_options", "_environment") # CONFIGURATION # The size in bytes read from stdout when copying git's output to another stream @@ -413,6 +415,9 @@ def __init__(self, working_dir=None): self._working_dir = working_dir self._git_options = () + # Extra environment variables to pass to git commands + self._environment = {} + # cached command slots self.cat_file_header = None self.cat_file_all = None @@ -536,6 +541,8 @@ def execute(self, command, # Start the process env = os.environ.copy() env["LC_MESSAGES"] = "C" + env.update(self._environment) + proc = Popen(command, env=env, cwd=cwd, @@ -608,6 +615,73 @@ def as_text(stdout_value): else: return stdout_value + def set_environment(self, **kwargs): + """ + Set environment variables for future git invocations. Return all changed + values in a format that can be passed back into this function to revert + the changes: + + ``Examples``:: + + old_env = self.set_environment(PWD='/tmp') + self.set_environment(**old_env) + + :param kwargs: environment variables to use for git processes + :return: dict that maps environment variables to their old values + """ + old_env = {} + for key, value in kwargs.iteritems(): + # set value if it is None + if value is not None: + if key in self._environment: + old_env[key] = self._environment[key] + else: + old_env[key] = None + self._environment[key] = value + # remove key from environment if its value is None + elif key in self._environment: + old_env[key] = self._environment[key] + del self._environment[key] + return old_env + + @contextmanager + def environment(self, **kwargs): + """ + A context manager around the above set_environment to restore the + environment back to its previous state after operation. + + ``Examples``:: + + with self.environment(GIT_SSH='/bin/ssh_wrapper'): + repo.remotes.origin.fetch() + + :param kwargs: see set_environment + """ + old_env = self.set_environment(**kwargs) + try: + yield + finally: + self.set_environment(**old_env) + + @contextmanager + def sshkey(self, sshkey_file): + """ + A context manager to temporarily set an SSH key for all operations that + run inside it. + + ``Examples``:: + + with self.environment(GIT_SSH=project_dir+'deployment_key'): + repo.remotes.origin.fetch() + + :param sshkey_file: Path to a private SSH key file + """ + this_dir = os.path.dirname(__file__) + ssh_wrapper = os.path.join(this_dir, '..', 'scripts', 'ssh_wrapper.py') + + with self.environment(GIT_SSH_KEY_FILE=sshkey_file, GIT_SSH=ssh_wrapper): + yield + def transform_kwargs(self, split_single_char_options=False, **kwargs): """Transforms Python style kwargs into git command line options.""" args = list() diff --git a/scripts/ssh_wrapper.py b/scripts/ssh_wrapper.py new file mode 100755 index 000000000..af657f606 --- /dev/null +++ b/scripts/ssh_wrapper.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +import os +import subprocess +import sys + +ssh_options = ['-i', os.environ['GIT_SSH_KEY_FILE']] +ret_code = subprocess.call(['ssh'] + ssh_options + sys.argv[1:]) +sys.exit(ret_code) From 34c0831453355e09222ccc6665782d7070f5ddab Mon Sep 17 00:00:00 2001 From: Jonas Trappenberg Date: Wed, 21 Jan 2015 21:50:46 -0800 Subject: [PATCH 0140/2790] Add method to query environment --- git/cmd.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git/cmd.py b/git/cmd.py index 1022fc254..65159f284 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -615,6 +615,9 @@ def as_text(stdout_value): else: return stdout_value + def environment(self): + return self._environment + def set_environment(self, **kwargs): """ Set environment variables for future git invocations. Return all changed From 2a9b2f22c6fb5bd3e30e674874dbc8aa7e5b00ae Mon Sep 17 00:00:00 2001 From: Jonas Trappenberg Date: Wed, 21 Jan 2015 21:51:10 -0800 Subject: [PATCH 0141/2790] Rename 'environment' and 'set_environment' --- git/cmd.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 65159f284..914424706 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -618,7 +618,7 @@ def as_text(stdout_value): def environment(self): return self._environment - def set_environment(self, **kwargs): + def update_environment(self, **kwargs): """ Set environment variables for future git invocations. Return all changed values in a format that can be passed back into this function to revert @@ -626,8 +626,8 @@ def set_environment(self, **kwargs): ``Examples``:: - old_env = self.set_environment(PWD='/tmp') - self.set_environment(**old_env) + old_env = self.update_environment(PWD='/tmp') + self.update_environment(**old_env) :param kwargs: environment variables to use for git processes :return: dict that maps environment variables to their old values @@ -648,23 +648,23 @@ def set_environment(self, **kwargs): return old_env @contextmanager - def environment(self, **kwargs): + def with_environment(self, **kwargs): """ - A context manager around the above set_environment to restore the + A context manager around the above update_environment to restore the environment back to its previous state after operation. ``Examples``:: - with self.environment(GIT_SSH='/bin/ssh_wrapper'): + with self.with_environment(GIT_SSH='/bin/ssh_wrapper'): repo.remotes.origin.fetch() - :param kwargs: see set_environment + :param kwargs: see update_environment """ - old_env = self.set_environment(**kwargs) + old_env = self.update_environment(**kwargs) try: yield finally: - self.set_environment(**old_env) + self.update_environment(**old_env) @contextmanager def sshkey(self, sshkey_file): @@ -682,7 +682,7 @@ def sshkey(self, sshkey_file): this_dir = os.path.dirname(__file__) ssh_wrapper = os.path.join(this_dir, '..', 'scripts', 'ssh_wrapper.py') - with self.environment(GIT_SSH_KEY_FILE=sshkey_file, GIT_SSH=ssh_wrapper): + with self.with_environment(GIT_SSH_KEY_FILE=sshkey_file, GIT_SSH=ssh_wrapper): yield def transform_kwargs(self, split_single_char_options=False, **kwargs): From 98a17a28a21fe5f06dd2da561839fdbaa1912c64 Mon Sep 17 00:00:00 2001 From: Jonas Trappenberg Date: Wed, 21 Jan 2015 22:26:52 -0800 Subject: [PATCH 0142/2790] Add SSH wrapper to MANIFEST.in --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 95b2e883f..4c02e39a3 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,7 +4,7 @@ include CHANGES include AUTHORS include README include requirements.txt +include scripts/ssh_wrapper.py graft git/test/fixtures graft git/test/performance - From 6f038611ff120f8283f0f1a56962f95b66730c72 Mon Sep 17 00:00:00 2001 From: Jonas Trappenberg Date: Wed, 21 Jan 2015 22:26:59 -0800 Subject: [PATCH 0143/2790] Add a few tests --- git/test/test_git.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/git/test/test_git.py b/git/test/test_git.py index f25fa21a8..85ee56c6b 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -153,3 +153,23 @@ def test_env_vars_passed_to_git(self): editor = 'non_existant_editor' with mock.patch.dict('os.environ', {'GIT_EDITOR': editor}): assert self.git.var("GIT_EDITOR") == editor + + def test_environment(self): + # sanity check + assert self.git.environment() == {} + + # make sure the context manager works and cleans up after itself + with self.git.with_environment(PWD='/tmp'): + assert self.git.environment() == {'PWD': '/tmp'} + + assert self.git.environment() == {} + + old_env = self.git.update_environment(VARKEY='VARVALUE') + # The returned dict can be used to revert the change, hence why it has + # an entry with value 'None'. + assert old_env == {'VARKEY': None} + assert self.git.environment() == {'VARKEY': 'VARVALUE'} + + new_env = self.git.update_environment(**old_env) + assert new_env == {'VARKEY': 'VARVALUE'} + assert self.git.environment() == {} From b54b9399920375f0bab14ff8495c0ea3f5fa1c33 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 12:40:07 +0100 Subject: [PATCH 0144/2790] Overhauled all tutorials, and placed them in a unit-test. That way they are protected from regression. Fixes #239 --- README.md | 2 +- doc/source/changes.rst | 19 +- doc/source/reference.rst | 26 +- doc/source/tutorial.rst | 448 ++++++++++++++-------------------- doc/source/whatsnew.rst | 34 --- git/diff.py | 4 +- git/ext/gitdb | 2 +- git/index/typ.py | 3 +- git/objects/submodule/base.py | 4 +- git/refs/symbolic.py | 2 +- git/remote.py | 2 +- git/repo/base.py | 20 +- git/repo/fun.py | 2 - git/test/lib/helper.py | 4 + git/test/test_docs.py | 288 +++++++++++++++++++++- git/test/test_submodule.py | 24 +- 16 files changed, 551 insertions(+), 333 deletions(-) diff --git a/README.md b/README.md index bdc455b68..0019dc179 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Then run: GitPython's git repo is available on GitHub, which can be browsed at [github](https://github.com/gitpython-developers/GitPython) and cloned like that: - git clone git://github.com/gitpython-developers/GitPython.git git-python + git clone https://github.com/gitpython-developers/GitPython ### Live Coding diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 2da3dad24..5b85e56ab 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -4,19 +4,22 @@ Changelog 0.3.6 - Features ================ -* Added `Repo.merge_base()` implementation. See the `respective issue on github `_ -* `[include]` sections in git configuration files are now respected -* Added `GitConfigParser.rename_section()` -* DOCS: special members like `__init__` are now listed in the API documentation -* DOCS: tutorial section was revised entirely -* Added `Submodule.rename()` +* **DOCS** + + * special members like `__init__` are now listed in the API documentation + * tutorial section was revised entirely, more advanced examples were added. + * **POSSIBLY BREAKING CHANGES** * As `rev_parse` will now throw `BadName` as well as `BadObject`, client code will have to catch both exception types. * Repo.working_tree_dir now returns None if it is bare. Previously it raised AssertionError. * IndexFile.add() previously raised AssertionError when paths where used with bare repository, now it raises InvalidGitRepositoryError - -* A list of all issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.6+-+Features%22+ + +* Added `Repo.merge_base()` implementation. See the `respective issue on github `_ +* `[include]` sections in git configuration files are now respected +* Added `GitConfigParser.rename_section()` +* Added `Submodule.rename()` +* A list of all issues can be found `on github `_ 0.3.5 - Bugfixes ================ diff --git a/doc/source/reference.rst b/doc/source/reference.rst index 7a73fc716..53fa86364 100644 --- a/doc/source/reference.rst +++ b/doc/source/reference.rst @@ -33,6 +33,7 @@ Objects.Tag .. automodule:: git.objects.tag :members: :undoc-members: + :special-members: Objects.Tree ------------ @@ -40,6 +41,7 @@ Objects.Tree .. automodule:: git.objects.tree :members: :undoc-members: + :special-members: Objects.Functions ----------------- @@ -47,6 +49,7 @@ Objects.Functions .. automodule:: git.objects.fun :members: :undoc-members: + :special-members: Objects.Submodule.base ---------------------- @@ -54,6 +57,7 @@ Objects.Submodule.base .. automodule:: git.objects.submodule.base :members: :undoc-members: + :special-members: Objects.Submodule.root ---------------------- @@ -61,6 +65,7 @@ Objects.Submodule.root .. automodule:: git.objects.submodule.root :members: :undoc-members: + :special-members: Objects.Submodule.util ---------------------- @@ -68,6 +73,7 @@ Objects.Submodule.util .. automodule:: git.objects.submodule.util :members: :undoc-members: + :special-members: Objects.Util ------------- @@ -75,6 +81,7 @@ Objects.Util .. automodule:: git.objects.util :members: :undoc-members: + :special-members: Index.Base ---------- @@ -82,6 +89,7 @@ Index.Base .. automodule:: git.index.base :members: :undoc-members: + :special-members: Index.Functions --------------- @@ -89,6 +97,7 @@ Index.Functions .. automodule:: git.index.fun :members: :undoc-members: + :special-members: Index.Types ----------- @@ -96,6 +105,7 @@ Index.Types .. automodule:: git.index.typ :members: :undoc-members: + :special-members: Index.Util ------------- @@ -103,6 +113,7 @@ Index.Util .. automodule:: git.index.util :members: :undoc-members: + :special-members: GitCmd ------ @@ -110,7 +121,7 @@ GitCmd .. automodule:: git.cmd :members: :undoc-members: - + :special-members: Config ------ @@ -118,6 +129,7 @@ Config .. automodule:: git.config :members: :undoc-members: + :special-members: Diff ---- @@ -125,6 +137,7 @@ Diff .. automodule:: git.diff :members: :undoc-members: + :special-members: Exceptions ---------- @@ -132,6 +145,7 @@ Exceptions .. automodule:: git.exc :members: :undoc-members: + :special-members: Refs.symbolic @@ -140,6 +154,7 @@ Refs.symbolic .. automodule:: git.refs.symbolic :members: :undoc-members: + :special-members: Refs.reference -------------- @@ -147,6 +162,7 @@ Refs.reference .. automodule:: git.refs.reference :members: :undoc-members: + :special-members: Refs.head --------- @@ -154,6 +170,7 @@ Refs.head .. automodule:: git.refs.head :members: :undoc-members: + :special-members: Refs.tag ------------ @@ -161,6 +178,7 @@ Refs.tag .. automodule:: git.refs.tag :members: :undoc-members: + :special-members: Refs.remote ------------ @@ -168,6 +186,7 @@ Refs.remote .. automodule:: git.refs.remote :members: :undoc-members: + :special-members: Refs.log ------------ @@ -175,6 +194,7 @@ Refs.log .. automodule:: git.refs.log :members: :undoc-members: + :special-members: Remote ------ @@ -182,6 +202,7 @@ Remote .. automodule:: git.remote :members: :undoc-members: + :special-members: Repo.Base --------- @@ -189,6 +210,7 @@ Repo.Base .. automodule:: git.repo.base :members: :undoc-members: + :special-members: Repo.Functions -------------- @@ -196,6 +218,7 @@ Repo.Functions .. automodule:: git.repo.fun :members: :undoc-members: + :special-members: Util ---- @@ -203,3 +226,4 @@ Util .. automodule:: git.util :members: :undoc-members: + :special-members: diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index c6e5626b5..4df0013c1 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -8,7 +8,9 @@ GitPython Tutorial ================== -GitPython provides object model access to your git repository. This tutorial is composed of multiple sections, each of which explains a real-life usecase. +GitPython provides object model access to your git repository. This tutorial is composed of multiple sections, most of which explains a real-life usecase. + +All code presented here originated from `test_docs.py `_ to assure correctness. Knowing this should also allow you to more easily run the code for your own testing purposes, all you need is a developer installation of git-python. Meet the Repo type ****************** @@ -17,7 +19,7 @@ The first step is to create a :class:`git.Repo ` object to r .. literalinclude:: ../../git/test/test_docs.py :language: python - :start-after: def test_init_repo_object + :start-after: # [1-test_init_repo_object] :end-before: # ![1-test_init_repo_object] In the above example, the directory ``self.rorepo.working_tree_dir`` equals ``/Users/mtrier/Development/git-python`` and is my working repository which contains the ``.git`` directory. You can also initialize GitPython with a *bare* repository. @@ -58,7 +60,7 @@ Archive the repository contents to a tar file. Advanced Repo Usage =================== -And of course, there is much more you can do with this type, most of the following will be explained in greater detail in specific tutorials. +And of course, there is much more you can do with this type, most of the following will be explained in greater detail in specific tutorials. Don't worry if you don't understand some of these examples right away, as they may require a thorough understanding of gits inner workings. Query relevant repository paths ... @@ -120,353 +122,280 @@ The :class:`index ` is also called stage in git-speak. Examining References ******************** -References are the tips of your commit graph from which you can easily examine the history of your project:: +:class:`References ` are the tips of your commit graph from which you can easily examine the history of your project. - heads = repo.heads - master = heads.master # lists can be accessed by name for convenience - master.commit # the commit pointed to by head called master - master.rename("new_name") # rename heads +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [1-test_references_and_objects] + :end-before: # ![1-test_references_and_objects] -Tags are (usually immutable) references to a commit and/or a tag object:: - - tags = repo.tags - tagref = tags[0] - tagref.tag # tags may have tag objects carrying additional information - tagref.commit # but they always point to commits - repo.delete_tag(tagref) # delete or - repo.create_tag("my_tag") # create tags using the repo for convenience +:class:`Tags ` are (usually immutable) references to a commit and/or a tag object. + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [2-test_references_and_objects] + :end-before: # ![2-test_references_and_objects] -A symbolic reference is a special case of a reference as it points to another reference instead of a commit:: +A :class:`symbolic reference ` is a special case of a reference as it points to another reference instead of a commit. - head = repo.head # the head points to the active branch/ref - master = head.reference # retrieve the reference the head points to - master.commit # from here you use it as any other reference +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [3-test_references_and_objects] + :end-before: # ![3-test_references_and_objects] -Access the reflog easily:: +Access the :class:`reflog ` easily. - log = master.log() - log[0] # first (i.e. oldest) reflog entry - log[-1] # last (i.e. most recent) reflog entry +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [4-test_references_and_objects] + :end-before: # ![4-test_references_and_objects] -For more information on the reflog, see the :class:`git.RefLog ` type's documentation. - Modifying References ******************** -You can easily create and delete reference types or modify where they point to:: +You can easily create and delete :class:`reference types ` or modify where they point to. - repo.delete_head('master') # delete an existing head - master = repo.create_head('master') # create a new one - master.commit = 'HEAD~10' # set branch to another commit without changing index or working tree +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [5-test_references_and_objects] + :end-before: # ![5-test_references_and_objects] -Create or delete tags the same way except you may not change them afterwards:: +Create or delete :class:`tags ` the same way except you may not change them afterwards. - new_tag = repo.create_tag('my_tag', 'my message') - repo.delete_tag(new_tag) +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [6-test_references_and_objects] + :end-before: # ![6-test_references_and_objects] -Change the symbolic reference to switch branches cheaply ( without adjusting the index or the working copy ):: +Change the :class:`symbolic reference ` to switch branches cheaply (without adjusting the index or the working tree). - new_branch = repo.create_head('new_branch') - repo.head.reference = new_branch +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [7-test_references_and_objects] + :end-before: # ![7-test_references_and_objects] Understanding Objects ********************* -An Object is anything storable in git's object database. Objects contain information about their type, their uncompressed size as well as the actual data. Each object is uniquely identified by a binary SHA1 hash, being 20 bytes in size. +An Object is anything storable in git's object database. Objects contain information about their type, their uncompressed size as well as the actual data. Each object is uniquely identified by a binary SHA1 hash, being 20 bytes in size, or 40 bytes in hexadecimal notation. -Git only knows 4 distinct object types being Blobs, Trees, Commits and Tags. +Git only knows 4 distinct object types being :class:`Blobs `, :class:`Trees `, :class:`Commits ` and :class:`Tags `. -In Git-Python, all objects can be accessed through their common base, compared and hashed. They are usually not instantiated directly, but through references or specialized repository functions:: +In GitPython, all objects can be accessed through their common base, can be compared and hashed. They are usually not instantiated directly, but through references or specialized repository functions. - hc = repo.head.commit - hct = hc.tree - hc != hct - hc != repo.tags[0] - hc == repo.head.reference.commit +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [8-test_references_and_objects] + :end-before: # ![8-test_references_and_objects] -Common fields are:: - - hct.type - 'tree' - hct.size - 166 - hct.hexsha - 'a95eeb2a7082212c197cabbf2539185ec74ed0e8' - hct.binsha - 'binary 20 byte sha1' +Common fields are ... + +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [9-test_references_and_objects] + :end-before: # ![9-test_references_and_objects] -Index Objects are objects that can be put into git's index. These objects are trees, blobs and submodules which additionally know about their path in the filesystem as well as their mode:: +:class:`Index objects ` are objects that can be put into git's index. These objects are trees, blobs and submodules which additionally know about their path in the file system as well as their mode. - hct.path # root tree has no path - '' - hct.trees[0].path # the first subdirectory has one though - 'dir' - htc.mode # trees have the mode of a linux directory - 040000 - '%o' % htc.blobs[0].mode # blobs have a specific mode though comparable to a standard linux fs - 100644 +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [10-test_references_and_objects] + :end-before: # ![10-test_references_and_objects] -Access blob data (or any object data) directly or using streams:: +Access :class:`blob ` data (or any object data) using streams. - htc.blobs[0].data_stream.read() # stream object to read data from - htc.blobs[0].stream_data(open("blob_data", "w")) # write data to given stream +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [11-test_references_and_objects] + :end-before: # ![11-test_references_and_objects] The Commit object ***************** -Commit objects contain information about a specific commit. Obtain commits using references as done in `Examining References`_ or as follows. - -Obtain commits at the specified revision:: - - repo.commit('master') - repo.commit('v0.1') - repo.commit('HEAD~10') - -Iterate 100 commits:: +:class:`Commit ` objects contain information about a specific commit. Obtain commits using references as done in `Examining References`_ or as follows. - repo.iter_commits('master', max_count=100) +Obtain commits at the specified revision -If you need paging, you can specify a number of commits to skip:: - - repo.iter_commits('master', max_count=10, skip=20) - -The above will return commits 21-30 from the commit list.:: - - headcommit = repo.head.commit +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [12-test_references_and_objects] + :end-before: # ![12-test_references_and_objects] - headcommit.hexsha - '207c0c4418115df0d30820ab1a9acd2ea4bf4431' +Iterate 50 commits, and if you need paging, you can specify a number of commits to skip. - headcommit.parents - (,) +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [13-test_references_and_objects] + :end-before: # ![13-test_references_and_objects] - headcommit.tree - +A commit object carries all sorts of meta-data - headcommit.author - "> +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [14-test_references_and_objects] + :end-before: # ![14-test_references_and_objects] - headcommit.authored_date # seconds since epoch - 1256291446 +Note: date time is represented in a ``seconds since epoch`` format. Conversion to human readable form can be accomplished with the various `time module `_ methods. - headcommit.committer - "> +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [15-test_references_and_objects] + :end-before: # ![15-test_references_and_objects] - headcommit.committed_date - 1256291446 +You can traverse a commit's ancestry by chaining calls to ``parents`` - headcommit.message - 'cleaned up a lot of test information. Fixed escaping so it works with - subprocess.' +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [16-test_references_and_objects] + :end-before: # ![16-test_references_and_objects] -Note: date time is represented in a ``seconds since epoch`` format. Conversion to human readable form can be accomplished with the various `time module `_ methods:: +The above corresponds to ``master^^^`` or ``master~3`` in git parlance. - import time - time.asctime(time.gmtime(headcommit.committed_date)) - 'Wed May 7 05:56:02 2008' +The Tree object +*************** - time.strftime("%a, %d %b %Y %H:%M", time.gmtime(headcommit.committed_date)) - 'Wed, 7 May 2008 05:56' +A :class:`tree ` records pointers to the contents of a directory. Let's say you want the root tree of the latest commit on the master branch -You can traverse a commit's ancestry by chaining calls to ``parents``:: +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [17-test_references_and_objects] + :end-before: # ![17-test_references_and_objects] - headcommit.parents[0].parents[0].parents[0] +Once you have a tree, you can get it's contents -The above corresponds to ``master^^^`` or ``master~3`` in git parlance. +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [18-test_references_and_objects] + :end-before: # ![18-test_references_and_objects] -The Tree object -*************** +It is useful to know that a tree behaves like a list with the ability to query entries by name -A tree records pointers to the contents of a directory. Let's say you want the root tree of the latest commit on the master branch:: +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [19-test_references_and_objects] + :end-before: # ![19-test_references_and_objects] - tree = repo.heads.master.commit.tree - +There is a convenience method that allows you to get a named sub-object from a tree with a syntax similar to how paths are written in a posix system - tree.hexsha - 'a006b5b1a8115185a228b7514cdcd46fed90dc92' +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [20-test_references_and_objects] + :end-before: # ![20-test_references_and_objects] -Once you have a tree, you can get the contents:: +You can also get a commit's root tree directly from the repository - tree.trees # trees are subdirectories - [] - - tree.blobs # blobs are files - [, - , - , - ] - -Its useful to know that a tree behaves like a list with the ability to query entries by name:: - - tree[0] == tree['dir'] # access by index and by sub-path - - for entry in tree: do_something_with(entry) - - blob = tree[0][0] - blob.name - 'file' - blob.path - 'dir/file' - blob.abspath - '/Users/mtrier/Development/git-python/dir/file' - >>>tree['dir/file'].binsha == blob.binsha - -There is a convenience method that allows you to get a named sub-object from a tree with a syntax similar to how paths are written in an unix system:: - - tree/"lib" - - tree/"dir/file" == blob - -You can also get a tree directly from the repository if you know its name:: - - repo.tree() - - - repo.tree("c1c7214dde86f76bc3e18806ac1f47c38b2b7a30") - - repo.tree('0.1.6') - +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [21-test_references_and_objects] + :end-before: # ![21-test_references_and_objects] -As trees only allow direct access to their direct entries, use the traverse method to obtain an iterator to traverse entries recursively:: +As trees allow direct access to their intermediate child entries only, use the traverse method to obtain an iterator to retrieve entries recursively - tree.traverse() - - for entry in tree.traverse(): do_something_with(entry) - +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [22-test_references_and_objects] + :end-before: # ![22-test_references_and_objects] -.. note:: If tree's return Submodule objects, they will assume that they exist at the current head's commit. The tree it originated from may be rooted at another commit though, which has to be told to the Submodule object using its ``set_parent_commit(my_commit)`` method. - +.. note:: If trees return Submodule objects, they will assume that they exist at the current head's commit. The tree it originated from may be rooted at another commit though, that it doesn't know. That is why the caller would have to set the submodule's owning or parent commit using the ``set_parent_commit(my_commit)`` method. The Index Object **************** -The git index is the stage containing changes to be written with the next commit or where merges finally have to take place. You may freely access and manipulate this information using the IndexFile Object:: - - index = repo.index +The git index is the stage containing changes to be written with the next commit or where merges finally have to take place. You may freely access and manipulate this information using the :class:`IndexFile ` object. +Modify the index with ease -Access objects and add/remove entries. Commit the changes:: - - for stage, blob in index.iter_blobs(): do_something(...) - # Access blob objects - for (path, stage), entry in index.entries.iteritems: pass - # Access the entries directly - index.add(['my_new_file']) # add a new file to the index - index.remove(['dir/existing_file']) - new_commit = index.commit("my commit message") # commit by commit message first - my_author = Actor("An author", "author@example.com") - my_committer = Actor("A committer", "committer@example.com") - next_commit = index.commit("my commit message", author=my_author, commiter=my_committer) # commit by commit message and author and committer +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [23-test_references_and_objects] + :end-before: # ![23-test_references_and_objects] -Create new indices from other trees or as result of a merge. Write that result to a new index file:: +Create new indices from other trees or as result of a merge. Write that result to a new index file for later inspection. - tmp_index = Index.from_tree(repo, 'HEAD~1') # load a tree into a temporary index - merge_index = Index.from_tree(repo, 'base', 'HEAD', 'some_branch') # merge two trees three-way - merge_index.write("merged_index") +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [24-test_references_and_objects] + :end-before: # ![24-test_references_and_objects] Handling Remotes **************** -Remotes are used as alias for a foreign repository to ease pushing to and fetching from them:: +:class:`Remotes ` are used as alias for a foreign repository to ease pushing to and fetching from them - test_remote = repo.create_remote('test', 'git@server:repo.git') - repo.delete_remote(test_remote) # create and delete remotes - origin = repo.remotes.origin # get default remote by name - origin.refs # local remote references - o = origin.rename('new_origin') # rename remotes - o.fetch() # fetch, pull and push from and to the remote - o.pull() - o.push() +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [25-test_references_and_objects] + :end-before: # ![25-test_references_and_objects] -You can easily access configuration information for a remote by accessing options as if they where attributes:: - - o.url - 'git@server:dummy_repo.git' - -Change configuration for a specific remote only:: - - o.config_writer.set("pushurl", "other_url") +You can easily access configuration information for a remote by accessing options as if they where attributes. The modification of remote configuration is more explicit though. +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [26-test_references_and_objects] + :end-before: # ![26-test_references_and_objects] Submodule Handling ****************** -Submodules can be conveniently handled using the methods provided by Git-Python, and as an added benefit, Git-Python provides functionality which behave smarter and less error prone than its original c-git implementation, that is Git-Python tries hard to keep your repository consistent when updating submodules recursively or adjusting the existing configuration. +:class:`Submodules ` can be conveniently handled using the methods provided by GitPython, and as an added benefit, GitPython provides functionality which behave smarter and less error prone than its original c-git implementation, that is GitPython tries hard to keep your repository consistent when updating submodules recursively or adjusting the existing configuration. -In the following brief example, you will learn about the very basics, assuming you operate on the Git-Python repository itself:: - - >>> repo = Repo('path/to/git-python/repository') - >>> sms = repo.submodules - [git.Submodule(name=gitdb, path=lib/git/ext/gitdb, url=git://github.com/gitpython-developers/GitPython.git, branch=master)] - >>> sm = sms[0] - >>> sm.name - 'gitdb' - >>> sm.module() # The module is the actual repository referenced by the submodule - /git-python/lib/git/ext/gitdb/.git"> - >>> sm.module_exists() - True - >>> sm.abspath == sm.module().working_tree_dir # the submodule's absolute path is the module's path - True - >>> sm.hexsha # Its sha defines the commit to checkout - '2ddc5bad224d8f545ef3bb2ab3df98dfe063c5b6' - >>> sm.exists() # yes, this submodule is valid and exists - True - >>> sm.config_reader().get_value('path') == sm.path # read its configuration conveniently - True - >>> sm.children() # query the submodule hierarchy - [git.Submodule(name=async, path=ext/async, url=git://github.com/gitpython-developers/async.git, branch=master)] - -In addition to the query functionality, you can move the submodule's repository to a different path <``move(...)``>, write its configuration <``config_writer().set_value(...)``>, update its working tree <``update(...)``>, and remove and add them <``remove(...)``, ``add(...)``>. +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [1-test_submodules] + :end-before: # ![1-test_submodules] + +In addition to the query functionality, you can move the submodule's repository to a different path <``move(...)``>, write its configuration <``config_writer().set_value(...).release()``>, update its working tree <``update(...)``>, and remove or add them <``remove(...)``, ``add(...)``>. If you obtained your submodule object by traversing a tree object which is not rooted at the head's commit, you have to inform the submodule about its actual commit to retrieve the data from by using the ``set_parent_commit(...)`` method. -The special ``RootModule`` type allows you to treat your master repository as root of a hierarchy of submodules, which allows very convenient submodule handling. Its ``update(...)`` method is reimplemented to provide an advanced way of updating submodules as they change their values. The update method will track changes and make sure your working tree and submodule checkouts stay consistent, which is very useful in case submodules get deleted or added to name just two of the handled cases. +The special :class:`RootModule ` type allows you to treat your master repository as root of a hierarchy of submodules, which allows very convenient submodule handling. Its ``update(...)`` method is reimplemented to provide an advanced way of updating submodules as they change their values over time. The update method will track changes and make sure your working tree and submodule checkouts stay consistent, which is very useful in case submodules get deleted or added to name just two of the handled cases. -Additionally, Git-Python adds functionality to track a specific branch, instead of just a commit. Supported by customized update methods, you are able to automatically update submodules to the latest revision available in the remote repository, as well as to keep track of changes and movements of these submodules. To use it, set the name of the branch you want to track to the ``submodule.$name.branch`` option of the *.gitmodules* file, and use Git-Python update methods on the resulting repository with the ``to_latest_revision`` parameter turned on. In the latter case, the sha of your submodule will be ignored, instead a local tracking branch will be updated to the respective remote branch automatically. The resulting behaviour is much like the one of svn::externals, which can be useful in times. +Additionally, GitPython adds functionality to track a specific branch, instead of just a commit. Supported by customized update methods, you are able to automatically update submodules to the latest revision available in the remote repository, as well as to keep track of changes and movements of these submodules. To use it, set the name of the branch you want to track to the ``submodule.$name.branch`` option of the *.gitmodules* file, and use GitPython update methods on the resulting repository with the ``to_latest_revision`` parameter turned on. In the latter case, the sha of your submodule will be ignored, instead a local tracking branch will be updated to the respective remote branch automatically, provided there are no local changes. The resulting behaviour is much like the one of svn::externals, which can be useful in times. Obtaining Diff Information ************************** -Diffs can generally be obtained by subclasses of ``Diffable`` as they provide the ``diff`` method. This operation yields a DiffIndex allowing you to easily access diff information about paths. +Diffs can generally be obtained by subclasses of :class:`Diffable ` as they provide the ``diff`` method. This operation yields a :class:`DiffIndex ` allowing you to easily access diff information about paths. -Diffs can be made between the Index and Trees, Index and the working tree, trees and trees as well as trees and the working copy. If commits are involved, their tree will be used implicitly:: +Diffs can be made between the Index and Trees, Index and the working tree, trees and trees as well as trees and the working copy. If commits are involved, their tree will be used implicitly. - hcommit = repo.head.commit - idiff = hcommit.diff() # diff tree against index - tdiff = hcommit.diff('HEAD~1') # diff tree against previous tree - wdiff = hcommit.diff(None) # diff tree against working tree - - index = repo.index - index.diff() # diff index against itself yielding empty diff - index.diff(None) # diff index against working copy - index.diff('HEAD') # diff index against current HEAD tree +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [27-test_references_and_objects] + :end-before: # ![27-test_references_and_objects] -The item returned is a DiffIndex which is essentially a list of Diff objects. It provides additional filtering to ease finding what you might be looking for:: +The item returned is a DiffIndex which is essentially a list of Diff objects. It provides additional filtering to ease finding what you might be looking for. - for diff_added in wdiff.iter_change_type('A'): do_something_with(diff_added) +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [28-test_references_and_objects] + :end-before: # ![28-test_references_and_objects] -Use the diff framework if you want to implement git-status like functionality. +Use the diff framework if you want to implement git-status like functionality. * A diff between the index and the commit's tree your HEAD points to - * use repo.index.diff(repo.head) + * use ``repo.index.diff(repo.head)`` * A diff between the index and the working tree - * use repo.index.diff(None) + * use ``repo.index.diff(None)`` * A list of untracked files - * use repo.untracked_files + * use ``repo.untracked_files`` - Switching Branches ****************** -To switch between branches, you effectively need to point your HEAD to the new branch head and reset your index and working copy to match. A simple manual way to do it is the following one:: +To switch between branches similar to ``git checkout``, you effectively need to point your HEAD symbolic reference to the new branch and reset your index and working copy to match. A simple manual way to do it is the following one - repo.head.reference = repo.heads.other_branch - repo.head.reset(index=True, working_tree=True) +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [29-test_references_and_objects] + :end-before: # ![29-test_references_and_objects] -The previous approach would brutally overwrite the user's changes in the working copy and index though and is less sophisticated than a git-checkout for instance which generally prevents you from destroying your work. Use the safer approach as follows:: +The previous approach would brutally overwrite the user's changes in the working copy and index though and is less sophisticated than a ``git-checkout``. The latter will generally prevent you from destroying your work. Use the safer approach as follows. - repo.heads.master.checkout() # checkout the branch using git-checkout - repo.heads.other_branch.checkout() +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [30-test_references_and_objects] + :end-before: # ![30-test_references_and_objects] Initializing a repository ************************* @@ -482,18 +411,19 @@ Please have a look at the individual methods as they usually support a vast amou Using git directly ****************** -In case you are missing functionality as it has not been wrapped, you may conveniently use the git command directly. It is owned by each repository instance:: +In case you are missing functionality as it has not been wrapped, you may conveniently use the :class:`git ` command directly. It is owned by each repository instance. - git = repo.git - git.checkout('head', b="my_new_branch") # default command - git.for_each_ref() # '-' becomes '_' when calling it +.. literalinclude:: ../../git/test/test_docs.py + :language: python + :start-after: # [31-test_references_and_objects] + :end-before: # ![31-test_references_and_objects] The return value will by default be a string of the standard output channel produced by the command. -Keyword arguments translate to short and long keyword arguments on the commandline. +Keyword arguments translate to short and long keyword arguments on the command-line. The special notion ``git.command(flag=True)`` will create a flag without value like ``command --flag``. -If ``None`` is found in the arguments, it will be dropped silently. Lists and tuples passed as arguments will be unpacked recursively to individual arguments. Objects are converted to strings using the str(...) function. +If ``None`` is found in the arguments, it will be dropped silently. Lists and tuples passed as arguments will be unpacked recursively to individual arguments. Objects are converted to strings using the ``str(...)`` function. Object Databases @@ -522,8 +452,8 @@ Using environment variables, you can further adjust the behaviour of the git com * **GIT_PYTHON_TRACE** - * If set to non-0, all executed git commands will be printed to stdout. - * if set to *full*, the executed git command will be printed along with its output. + * If set to non-0, all executed git commands will be logged using a python logger. + * if set to *full*, the executed git command and its output on stdout and stderr will be logged using a python logger. * **GIT_PYTHON_GIT_EXECUTABLE** @@ -532,7 +462,7 @@ Using environment variables, you can further adjust the behaviour of the git com And even more ... ***************** -There is more functionality in there, like the ability to archive repositories, get stats and logs, blame, and probably a few other things that were not mentioned here. +There is more functionality in there, like the ability to archive repositories, get stats and logs, blame, and probably a few other things that were not mentioned here. Check the unit tests for an in-depth introduction on how each function is supposed to be used. diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst index f71d88e60..e0d39b099 100644 --- a/doc/source/whatsnew.rst +++ b/doc/source/whatsnew.rst @@ -23,37 +23,3 @@ Reduced Memory Footprint Objects, such as commits, tags, trees and blobs now use 20 byte sha1 signatures internally, reducing their memory demands by 20 bytes per object, allowing you to keep more objects in memory at the same time. The internal caches of tree objects were improved to use less memory as well. - -################## -Upgrading from 0.2 -################## -GitPython 0.2 essentially behaves like GitPython 0.3 with a Repository using the ``GitCmdObjectDB`` instead of the ``GitDB`` as object database backend. Additionally it can be used more conveniently through implicit conversions and provides a feature set strikingly similar to 0.3. - -************************** -Why you should not upgrade -************************** -GitPython 0.3 in most cases will not run faster than GitPython 0.2, the opposite might be the case at it uses the pure python implementation by default. -There have been a few renames which will need additional adjustments in your code. - -Generally, if you only read git repositories, version 0.2 is sufficient and very well performing. - -********************** -Why you should upgrade -********************** -GitPython 0.2 has reached its end of line, and it is unlikely to receive more than contributed patches. 0.3 is the main development branch which will lead into the future. - -GitPython 0.3 provides memory usage optimization and is very flexible in the way it uses to access the object database. With minimal effort, 0.3 will be running as fast as 0.2. It marks the first step of more versions to come, and will improve over time. - -GitPython 0.3 is especially suitable for everyone who needs not only read, but also write access to a git repository. It is optimized to keep the memory consumption as low as possible, especially when handling large data sets. GitPython 0.3 operates on streams, not on possibly huge chunks of data. - - -************** -Guided Upgrade -************** -This guide should help to make the upgrade as painless as possible, hence it points out where to start, and what to look out for. - -* Have a look at https://github.com/gitpython-developers/GitPython/blob/0.3/doc/source/changes.rst -* Start applying the renames, generally the ``utils`` modules are now called ``util``, ``errors`` is called ``exc``. -* Search for occurrences of the ``sha`` property of object instances. A similar value can be obtained through the new ``hexsha`` property. The native sha1 value is the ``binsha`` though. -* Search for code which instantiates objects directly. Their initializer now requires a 20 byte binary Sha1, rev-specs cannot be used anymore. For a similar effect, either convert your hexadecimal shas to binary shas beforehand ( ``binascii.unhexlify`` for instance ), or use higher level functions such as ``Object.new``, ``Repo.commit`` or ``Repo.tree``. The latter ones takes rev-specs and hexadecimal sha1 hashes. - diff --git a/git/diff.py b/git/diff.py index dfee00e22..378823696 100644 --- a/git/diff.py +++ b/git/diff.py @@ -42,7 +42,7 @@ def _process_diff_args(self, args): def diff(self, other=Index, paths=None, create_patch=False, **kwargs): """Creates diffs between two items being trees, trees and index or an - index and the working tree. + index and the working tree. It will detect renames automatically. :param other: Is the item to compare us with. @@ -68,8 +68,6 @@ def diff(self, other=Index, paths=None, create_patch=False, **kwargs): :return: git.DiffIndex :note: - Rename detection will only work if create_patch is True. - On a bare repository, 'other' needs to be provided as Index or as as Tree/Commit, or a git command error will occour""" args = list() diff --git a/git/ext/gitdb b/git/ext/gitdb index f2233fbf4..b3237e804 160000 --- a/git/ext/gitdb +++ b/git/ext/gitdb @@ -1 +1 @@ -Subproject commit f2233fbf40f3f69309ce5cc714e99fcbdcd33ec3 +Subproject commit b3237e804ae313503f5479349f90066c356b1548 diff --git a/git/index/typ.py b/git/index/typ.py index 0998ecb07..70f56dd13 100644 --- a/git/index/typ.py +++ b/git/index/typ.py @@ -32,7 +32,8 @@ class BlobFilter(object): __slots__ = 'paths' def __init__(self, paths): - """:param paths: + """ + :param paths: tuple or list of paths which are either pointing to directories or to files relative to the current repository """ diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 94322a557..be243acc5 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -770,7 +770,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): an inconsistent state :raise InvalidGitRepositoryError: thrown if the repository cannot be deleted :raise OSError: if directories or files could not be removed""" - if not (module + configuration): + if not (module or configuration): raise ValueError("Need to specify to delete at least the module, or the configuration") # END handle parameters @@ -784,7 +784,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False): if configuration and not dry_run and nc > 0: # Assure we don't leave the parent repository in a dirty state, and commit our changes # It's important for recursive, unforced, deletions to work as expected - self.module().index.commit("Removed submodule '%s'" % self.name) + self.module().index.commit("Removed at least one of child-modules of '%s'" % self.name) # end handle recursion # DELETE REPOSITORY WORKING TREE diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index b5a81ee01..fed7006e6 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -264,7 +264,7 @@ def set_reference(self, ref, logmsg=None): symbolic one. :param ref: SymbolicReference instance, Object instance or refspec string - Only if the ref is a SymbolicRef instance, we will point to it. Everthiny + Only if the ref is a SymbolicRef instance, we will point to it. Everthing else is dereferenced to obtain the actual object. :param logmsg: If set to a string, the message will be used in the reflog. Otherwise, a reflog entry is not written for the changed reference. diff --git a/git/remote.py b/git/remote.py index fcec52285..c37d6c497 100644 --- a/git/remote.py +++ b/git/remote.py @@ -361,7 +361,7 @@ def __init__(self, repo, name): def __getattr__(self, attr): """Allows to call this instance like - remote.special( *args, **kwargs) to call git-remote special self.name""" + remote.special( \*args, \*\*kwargs) to call git-remote special self.name""" if attr == "_config_reader": return super(Remote, self).__getattr__(attr) diff --git a/git/repo/base.py b/git/repo/base.py index ce8db7f7f..61352a9ac 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -103,17 +103,23 @@ class Repo(object): # represents the configuration level of a configuration file config_level = ("system", "user", "global", "repository") + # Subclass configuration + # Subclasses may easily bring in their own custom types by placing a constructor or type here + GitCommandWrapperType = Git + def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False): """Create a new Repo instance - :param path: is the path to either the root git directory or the bare git repo:: + :param path: + the path to either the root git directory or the bare git repo:: - repo = Repo("/Users/mtrier/Development/git-python") - repo = Repo("/Users/mtrier/Development/git-python.git") - repo = Repo("~/Development/git-python.git") - repo = Repo("$REPOSITORIES/Development/git-python.git") + repo = Repo("/Users/mtrier/Development/git-python") + repo = Repo("/Users/mtrier/Development/git-python.git") + repo = Repo("~/Development/git-python.git") + repo = Repo("$REPOSITORIES/Development/git-python.git") - :param odbt: Object DataBase type - a type which is constructed by providing + :param odbt: + Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data :raise InvalidGitRepositoryError: @@ -170,7 +176,7 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals # END working dir handling self.working_dir = self._working_tree_dir or self.git_dir - self.git = Git(self.working_dir) + self.git = self.GitCommandWrapperType(self.working_dir) # special handling, in special times args = [join(self.git_dir, 'objects')] diff --git a/git/repo/fun.py b/git/repo/fun.py index 2321dbc87..1d551f046 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -148,8 +148,6 @@ def rev_parse(repo, rev): :param rev: git-rev-parse compatible revision specification as string, please see http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html for details - :note: Currently there is no access to the rev-log, rev-specs may only contain - topological tokens such ~ and ^. :raise BadObject: if the given revision could not be found :raise ValueError: If rev couldn't be parsed :raise IndexError: If invalid reflog index is specified""" diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index c5c5a6201..8300f2722 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -275,6 +275,10 @@ class TestBase(TestCase): of the project history ( to assure tests don't fail for others ). """ + def _small_repo_url(https://github.com/self): + """:return" a path to a small, clonable repository""" + return os.path.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap') + @classmethod def setUpClass(cls): """ diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 9a04784de..255662437 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -14,6 +14,7 @@ class Tutorials(TestBase): @with_rw_directory def test_init_repo_object(self, rw_dir): + # [1-test_init_repo_object] from git import Repo join = os.path.join @@ -36,9 +37,8 @@ def test_init_repo_object(self, rw_dir): # ![3-test_init_repo_object] # [4-test_init_repo_object] - repo.is_dirty() - # False - repo.untracked_files + assert not bare_repo.is_dirty() # check the dirty state + repo.untracked_files # retrieve a list of untracked files # ['my_untracked_file'] # ![4-test_init_repo_object] @@ -177,6 +177,288 @@ def update(self, op_code, cur_count, max_count=None, message=''): assert sm.module_exists() # The submodules working tree was checked out by update # ![14-test_init_repo_object] + @with_rw_directory + def test_references_and_objects(self, rw_dir): + # [1-test_references_and_objects] + import git + repo = git.Repo.clone_from(self._small_repo_url(), os.path.join(rw_dir, 'repo')) + + heads = repo.heads + master = heads.master # lists can be accessed by name for convenience + master.commit # the commit pointed to by head called master + master.rename('new_name') # rename heads + master.rename('master') + # ![1-test_references_and_objects] + + # [2-test_references_and_objects] + tags = repo.tags + tagref = tags[0] + tagref.tag # tags may have tag objects carrying additional information + tagref.commit # but they always point to commits + repo.delete_tag(tagref) # delete or + repo.create_tag("my_tag") # create tags using the repo for convenience + # ![2-test_references_and_objects] + + # [3-test_references_and_objects] + head = repo.head # the head points to the active branch/ref + master = head.reference # retrieve the reference the head points to + master.commit # from here you use it as any other reference + # ![3-test_references_and_objects] + + # [4-test_references_and_objects] + log = master.log() + log[0] # first (i.e. oldest) reflog entry + log[-1] # last (i.e. most recent) reflog entry + # ![4-test_references_and_objects] + + # [5-test_references_and_objects] + new_branch = repo.create_head('new') # create a new one + new_branch.commit = 'HEAD~10' # set branch to another commit without changing index or working trees + repo.delete_head(new_branch) # delete an existing head - only works if it is not checked out + # ![5-test_references_and_objects] + + # [6-test_references_and_objects] + new_tag = repo.create_tag('my_new_tag', message='my message') + # You cannot change the commit a tag points to. Tags need to be re-created + self.failUnlessRaises(AttributeError, setattr, new_tag, 'commit', repo.commit('HEAD~1')) + repo.delete_tag(new_tag) + # ![6-test_references_and_objects] + + # [7-test_references_and_objects] + new_branch = repo.create_head('another-branch') + repo.head.reference = new_branch + # ![7-test_references_and_objects] + + # [8-test_references_and_objects] + hc = repo.head.commit + hct = hc.tree + hc != hct + hc != repo.tags[0] + hc == repo.head.reference.commit + # ![8-test_references_and_objects] + + # [9-test_references_and_objects] + assert hct.type == 'tree' # preset string type, being a class attribute + assert hct.size > 0 # size in bytes + assert len(hct.hexsha) == 40 + assert len(hct.binsha) == 20 + # ![9-test_references_and_objects] + + # [10-test_references_and_objects] + assert hct.path == '' # root tree has no path + assert hct.trees[0].path != '' # the first contained item has one though + assert hct.mode == 0o40000 # trees have the mode of a linux directory + assert hct.blobs[0].mode == 0o100644 # blobs have a specific mode though comparable to a standard linux fs + # ![10-test_references_and_objects] + + # [11-test_references_and_objects] + hct.blobs[0].data_stream.read() # stream object to read data from + hct.blobs[0].stream_data(open(os.path.join(rw_dir, 'blob_data'), 'wb')) # write data to given stream + # ![11-test_references_and_objects] + + # [12-test_references_and_objects] + repo.commit('master') + repo.commit('v0.8.1') + repo.commit('HEAD~10') + # ![12-test_references_and_objects] + + # [13-test_references_and_objects] + fifty_first_commits = list(repo.iter_commits('master', max_count=50)) + assert len(fifty_first_commits) == 50 + # this will return commits 21-30 from the commit list as traversed backwards master + ten_commits_past_twenty = list(repo.iter_commits('master', max_count=10, skip=20)) + assert len(ten_commits_past_twenty) == 10 + assert fifty_first_commits[20:30] == ten_commits_past_twenty + # ![13-test_references_and_objects] + + # [14-test_references_and_objects] + headcommit = repo.head.commit + assert len(headcommit.hexsha) == 40 + assert len(headcommit.parents) > 0 + assert headcommit.tree.type == 'tree' + assert headcommit.author.name == 'Sebastian Thiel' + assert isinstance(headcommit.authored_date, int) + assert headcommit.committer.name == 'Sebastian Thiel' + assert isinstance(headcommit.committed_date, int) + assert headcommit.message != '' + # ![14-test_references_and_objects] + + # [15-test_references_and_objects] + import time + time.asctime(time.gmtime(headcommit.committed_date)) + time.strftime("%a, %d %b %Y %H:%M", time.gmtime(headcommit.committed_date)) + # ![15-test_references_and_objects] + + # [16-test_references_and_objects] + assert headcommit.parents[0].parents[0].parents[0] == repo.commit('master^^^') + # ![16-test_references_and_objects] + + # [17-test_references_and_objects] + tree = repo.heads.master.commit.tree + assert len(tree.hexsha) == 40 + # ![17-test_references_and_objects] + + # [18-test_references_and_objects] + assert len(tree.trees) > 0 # trees are subdirectories + assert len(tree.blobs) > 0 # blobs are files + assert len(tree.blobs) + len(tree.trees) == len(tree) + # ![18-test_references_and_objects] + + # [19-test_references_and_objects] + assert tree['smmap'] == tree / 'smmap' # access by index and by sub-path + for entry in tree: # intuitive iteration of tree members + print(entry) + blob = tree.trees[0].blobs[0] # let's get a blob in a sub-tree + assert blob.name + assert len(blob.path) < len(blob.abspath) + assert tree.trees[0].name + '/' + blob.name == blob.path # this is how the relative blob path is generated + assert tree[blob.path] == blob # you can use paths like 'dir/file' in tree[...] + # ![19-test_references_and_objects] + + # [20-test_references_and_objects] + assert tree / 'smmap' == tree['smmap'] + assert tree / blob.path == tree[blob.path] + # ![20-test_references_and_objects] + + # [21-test_references_and_objects] + # This example shows the various types of allowed ref-specs + assert repo.tree() == repo.head.commit.tree + past = repo.commit('HEAD~5') + assert repo.tree(past) == repo.tree(past.hexsha) + assert repo.tree('v0.8.1').type == 'tree' # yes, you can provide any refspec - works everywhere + # ![21-test_references_and_objects] + + # [22-test_references_and_objects] + assert len(tree) < len(list(tree.traverse())) + # ![22-test_references_and_objects] + + # [23-test_references_and_objects] + index = repo.index + # The index contains all blobs in a flat list + assert len(list(index.iter_blobs())) == len([o for o in repo.head.commit.tree.traverse() if o.type == 'blob']) + # Access blob objects + for (path, stage), entry in index.entries.items(): + pass + new_file_path = os.path.join(repo.working_tree_dir, 'new-file-name') + open(new_file_path, 'w').close() + index.add([new_file_path]) # add a new file to the index + index.remove(['LICENSE']) # remove an existing one + assert os.path.isfile(os.path.join(repo.working_tree_dir, 'LICENSE')) # working tree is untouched + + assert index.commit("my commit message").type == 'commit' # commit changed index + repo.active_branch.commit = repo.commit('HEAD~1') # forget last commit + + from git import Actor + author = Actor("An author", "author@example.com") + committer = Actor("A committer", "committer@example.com") + # commit by commit message and author and committer + index.commit("my commit message", author=author, committer=committer) + # ![23-test_references_and_objects] + + # [24-test_references_and_objects] + from git import IndexFile + # loads a tree into a temporary index, which exists just in memory + IndexFile.from_tree(repo, 'HEAD~1') + # merge two trees three-way into memory + merge_index = IndexFile.from_tree(repo, 'HEAD~10', 'HEAD', repo.merge_base('HEAD~10', 'HEAD')) + # and persist it + merge_index.write(os.path.join(rw_dir, 'merged_index')) + # ![24-test_references_and_objects] + + # [25-test_references_and_objects] + empty_repo = git.Repo.init(os.path.join(rw_dir, 'empty')) + origin = empty_repo.create_remote('origin', repo.remotes.origin.url) + assert origin.exists() + assert origin == empty_repo.remotes.origin == empty_repo.remotes['origin'] + origin.fetch() # assure we actually have data. fetch() returns useful information + # Setup a local tracking branch of a remote branch + empty_repo.create_head('master', origin.refs.master).set_tracking_branch(origin.refs.master) + origin.rename('new_origin') # rename remotes + # push and pull behaves similarly to `git push|pull` + origin.pull() + origin.push() + # assert not empty_repo.delete_remote(origin).exists() # create and delete remotes + # ![25-test_references_and_objects] + + # [26-test_references_and_objects] + assert origin.url == repo.remotes.origin.url + cw = origin.config_writer + cw.set("pushurl", "other_url") + cw.release() + + # Please note that in python 2, writing origin.config_writer.set(...) is totally safe. + # In py3 __del__ calls can be delayed, thus not writing changes in time. + # ![26-test_references_and_objects] + + # [27-test_references_and_objects] + hcommit = repo.head.commit + hcommit.diff() # diff tree against index + hcommit.diff('HEAD~1') # diff tree against previous tree + hcommit.diff(None) # diff tree against working tree + + index = repo.index + index.diff() # diff index against itself yielding empty diff + index.diff(None) # diff index against working copy + index.diff('HEAD') # diff index against current HEAD tree + # ![27-test_references_and_objects] + + # [28-test_references_and_objects] + # Traverse added Diff objects only + for diff_added in hcommit.diff('HEAD~1').iter_change_type('A'): + print(diff_added) + # ![28-test_references_and_objects] + + # [29-test_references_and_objects] + # Reset our working tree 10 commits into the past + past_branch = repo.create_head('past_branch', 'HEAD~10') + repo.head.reference = past_branch + assert not repo.head.is_detached + # reset the index and working tree to match the pointed-to commit + repo.head.reset(index=True, working_tree=True) + + # To detach your head, you have to point to a commit directy + repo.head.reference = repo.commit('HEAD~5') + assert repo.head.is_detached + # now our head points 15 commits into the past, whereas the working tree + # and index are 10 commits in the past + # ![29-test_references_and_objects] + + # [30-test_references_and_objects] + # checkout the branch using git-checkout. It will fail as the working tree appears dirty + self.failUnlessRaises(git.GitCommandError, repo.heads.master.checkout) + repo.heads.past_branch.checkout() + # ![30-test_references_and_objects] + + # [31-test_references_and_objects] + git = repo.git + git.checkout('head', b="my_new_branch") # create a new branch + git.branch('another-new-one') + git.branch('-D', 'another-new-one') # pass strings for full control over argument order + git.for_each_ref() # '-' becomes '_' when calling it + # ![31-test_references_and_objects] + + def test_submodules(self): + # [1-test_submodules] + repo = self.rorepo + sms = repo.submodules + + assert len(sms) == 1 + sm = sms[0] + assert sm.name == 'gitdb' # git-python has gitdb as single submodule ... + assert sm.children()[0].name == 'smmap' # ... which has smmap as single submodule + + # The module is the repository referenced by the submodule + assert sm.module_exists() # the module is available, which doesn't have to be the case. + assert sm.module().working_tree_dir.endswith('gitdb') + # the submodule's absolute path is the module's path + assert sm.abspath == sm.module().working_tree_dir + assert len(sm.hexsha) == 40 # Its sha defines the commit to checkout + assert sm.exists() # yes, this submodule is valid and exists + # read its configuration conveniently + assert sm.config_reader().get_value('path') == sm.path + assert len(sm.children()) == 1 # query the submodule hierarchy + # ![1-test_submodules] + @with_rw_directory def test_add_file_and_commit(self, rw_dir): import git diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 1d4cf1782..459e20303 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -264,6 +264,15 @@ def _do_base_tests(self, rwrepo): ######################## # must delete something self.failUnlessRaises(ValueError, csm.remove, module=False, configuration=False) + + # module() is supposed to point to gitdb, which has a child-submodule whose URL is still pointing + # to github. To save time, we will change it to + csm.set_parent_commit(csm.repo.head.commit) + cw = csm.config_writer() + cw.set_value('url', self._small_repo_url()) + cw.release() + csm.repo.index.commit("adjusted URL to point to local source, instead of the internet") + # We have modified the configuration, hence the index is dirty, and the # deletion will fail # NOTE: As we did a few updates in the meanwhile, the indices were reset @@ -651,13 +660,10 @@ def test_add_empty_repo(self, rwdir): url=empty_repo_dir, no_checkout=checkout_mode and True or False) # end for each checkout mode - def _submodule_url(https://github.com/self): - return os.path.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap') - @with_rw_directory def test_git_submodules(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) - parent.git.submodule('add', self._submodule_url(), 'module') + parent.git.submodule('add', self._small_repo_url(), 'module') parent.index.commit("added submodule") assert len(parent.submodules) == 1 @@ -665,7 +671,7 @@ def test_git_submodules(self, rwdir): assert sm.exists() and sm.module_exists() - clone = git.Repo.clone_from(self._submodule_url(), + clone = git.Repo.clone_from(self._small_repo_url(), os.path.join(parent.working_tree_dir, 'existing-subrepository')) sm2 = parent.create_submodule('nongit-file-submodule', clone.working_tree_dir) assert len(parent.submodules) == 2 @@ -684,7 +690,7 @@ def test_git_submodules(self, rwdir): def test_git_submodule_compatibility(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) sm_path = 'submodules/intermediate/one' - sm = parent.create_submodule('mymodules/myname', sm_path, url=self._submodule_url()) + sm = parent.create_submodule('mymodules/myname', sm_path, url=self._small_repo_url()) parent.index.commit("added submodule") def assert_exists(sm, value=True): @@ -714,7 +720,7 @@ def assert_exists(sm, value=True): # Add additional submodule level csm = sm.module().create_submodule('nested-submodule', 'nested-submodule/working-tree', - url=self._submodule_url()) + url=self._small_repo_url()) sm.module().index.commit("added nested submodule") sm_head_commit = sm.module().commit() assert_exists(csm) @@ -759,7 +765,7 @@ def assert_exists(sm, value=True): def test_rename(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) sm_name = 'mymodules/myname' - sm = parent.create_submodule(sm_name, sm_name, url=self._submodule_url()) + sm = parent.create_submodule(sm_name, sm_name, url=self._small_repo_url()) parent.index.commit("Added submodule") assert sm.rename(sm_name) is sm and sm.name == sm_name @@ -782,7 +788,7 @@ def test_rename(self, rwdir): def test_branch_renames(self, rw_dir): # Setup initial sandbox: # parent repo has one submodule, which has all the latest changes - source_url = self._submodule_url() + source_url = self._small_repo_url() sm_source_repo = git.Repo.clone_from(source_url, os.path.join(rw_dir, 'sm-source'), b='master') parent_repo = git.Repo.init(os.path.join(rw_dir, 'parent')) sm = parent_repo.create_submodule('mysubmodule', 'subdir/submodule', From 06bec1bcd1795192f4a4a274096f053afc8f80ec Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 15:22:39 +0100 Subject: [PATCH 0145/2790] Fetch now deals with custom refspecs much better. Even though the test-csae only verifies this spec: +refs/pull/*:refs/heads/pull/* I could locally verify that it indeed handles other ones just as well: +refs/pull/*:refs/pull/* Fixes #243 --- git/remote.py | 16 ++++++++++++---- .../fixtures/uncommon_branch_prefix_FETCH_HEAD | 6 ++++++ git/test/fixtures/uncommon_branch_prefix_stderr | 6 ++++++ git/test/test_docs.py | 2 +- git/test/test_remote.py | 16 +++++++++++++++- 5 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD create mode 100644 git/test/fixtures/uncommon_branch_prefix_stderr diff --git a/git/remote.py b/git/remote.py index c37d6c497..39d9dc4d4 100644 --- a/git/remote.py +++ b/git/remote.py @@ -14,6 +14,7 @@ cp, ) from .refs import ( + Head, Reference, RemoteReference, SymbolicReference, @@ -177,8 +178,9 @@ class FetchInfo(object): info.note # additional notes given by git-fetch intended for the user info.old_commit # if info.flags & info.FORCED_UPDATE|info.FAST_FORWARD, # field is set to the previous location of ref, otherwise None + info.remote_ref_path # The path from which we fetched on the remote. It's the remote's version of our info.ref """ - __slots__ = ('ref', 'old_commit', 'flags', 'note') + __slots__ = ('ref', 'old_commit', 'flags', 'note', 'remote_ref_path') NEW_TAG, NEW_HEAD, HEAD_UPTODATE, TAG_UPDATE, REJECTED, FORCED_UPDATE, \ FAST_FORWARD, ERROR = [1 << x for x in range(8)] @@ -193,7 +195,7 @@ class FetchInfo(object): '=': HEAD_UPTODATE, ' ': FAST_FORWARD} - def __init__(self, ref, flags, note='', old_commit=None): + def __init__(self, ref, flags, note='', old_commit=None, remote_ref_path=None): """ Initialize a new instance """ @@ -201,6 +203,7 @@ def __init__(self, ref, flags, note='', old_commit=None): self.flags = flags self.note = note self.old_commit = old_commit + self.remote_ref_path = remote_ref_path def __str__(self): return self.name @@ -243,7 +246,7 @@ def _from_line(cls, repo, line, fetch_line): new_hex_sha, fetch_operation, fetch_note = fetch_line.split("\t") ref_type_name, fetch_note = fetch_note.split(' ', 1) except ValueError: # unpack error - raise ValueError("Failed to parse FETCH__HEAD line: %r" % fetch_line) + raise ValueError("Failed to parse FETCH_HEAD line: %r" % fetch_line) # parse flags from control_character flags = 0 @@ -288,6 +291,11 @@ def _from_line(cls, repo, line, fetch_line): # note: remote-tracking is just the first part of the 'remote-tracking branch' token. # We don't parse it correctly, but its enough to know what to do, and its new in git 1.7something ref_type = RemoteReference + elif '/' in ref_type_name: + # If the fetch spec look something like this '+refs/pull/*:refs/heads/pull/*', and is thus pretty + # much anything the user wants, we will have trouble to determine what's going on + # For now, we assume the local ref is a Head + ref_type = Head else: raise TypeError("Cannot handle reference type: %r" % ref_type_name) # END handle ref type @@ -325,7 +333,7 @@ def _from_line(cls, repo, line, fetch_line): note = (note and note.strip()) or '' - return cls(remote_local_ref, flags, note, old_commit) + return cls(remote_local_ref, flags, note, old_commit, local_remote_ref) class Remote(LazyMixin, Iterable): diff --git a/git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD b/git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD new file mode 100644 index 000000000..7df36f246 --- /dev/null +++ b/git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD @@ -0,0 +1,6 @@ +c2e3c20affa3e2b61a05fdc9ee3061dd416d915e 'refs/pull/1/head' of http://github.com/loic-bot/testrepo +fd8695d980e2c6df62b7785f93fd6292d1e283fb 'refs/pull/1/merge' of http://github.com/loic-bot/testrepo +bb46faf089720d1a3f9e4dc3b11ed5ff77d7e764 'refs/pull/2/head' of http://github.com/loic-bot/testrepo +5faa366d58454eceea811e0e34c502bdd7b37e4b 'refs/pull/2/merge' of http://github.com/loic-bot/testrepo +b3ad3c4f1864b50d4d3e09320947a1a3c34c9ea2 'refs/pull/3/head' of http://github.com/loic-bot/testrepo +71fe57e511776042b009ed4bb281b62b0522b434 'refs/pull/3/merge' of http://github.com/loic-bot/testrepo diff --git a/git/test/fixtures/uncommon_branch_prefix_stderr b/git/test/fixtures/uncommon_branch_prefix_stderr new file mode 100644 index 000000000..5a6aca653 --- /dev/null +++ b/git/test/fixtures/uncommon_branch_prefix_stderr @@ -0,0 +1,6 @@ + = [up to date] refs/pull/1/head -> pull/1/head + = [up to date] refs/pull/1/merge -> pull/1/merge + = [up to date] refs/pull/2/head -> pull/2/head + = [up to date] refs/pull/2/merge -> pull/2/merge + = [up to date] refs/pull/3/head -> pull/3/head + = [up to date] refs/pull/3/merge -> pull/3/merge diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 255662437..397641e0c 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -181,7 +181,7 @@ def update(self, op_code, cur_count, max_count=None, message=''): def test_references_and_objects(self, rw_dir): # [1-test_references_and_objects] import git - repo = git.Repo.clone_from(self._small_repo_url(), os.path.join(rw_dir, 'repo')) + repo = git.Repo.clone_from(self._small_repo_url(), os.path.join(rw_dir, 'repo'), branch='master') heads = repo.heads master = heads.master # lists can be accessed by name for convenience diff --git a/git/test/test_remote.py b/git/test/test_remote.py index d4a92ed4d..4fd782301 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -7,7 +7,8 @@ from git.test.lib import ( TestBase, with_rw_repo, - with_rw_and_rw_remote_repo + with_rw_and_rw_remote_repo, + fixture ) from git import ( RemoteProgress, @@ -520,3 +521,16 @@ def test_fetch_info(self): assert type(fi.ref) is Reference assert fi.ref.path == "refs/something/branch" + + def test_uncommon_branch_names(self): + stderr_lines = fixture('uncommon_branch_prefix_stderr').decode('ascii').splitlines() + fetch_lines = fixture('uncommon_branch_prefix_FETCH_HEAD').decode('ascii').splitlines() + + # The contents of the files above must be fetched with a custom refspec: + # +refs/pull/*:refs/heads/pull/* + res = [FetchInfo._from_line('ShouldntMatterRepo', stderr, fetch_line) + for stderr, fetch_line in zip(stderr_lines, fetch_lines)] + assert len(res) + assert res[0].remote_ref_path == 'refs/pull/1/head' + assert res[0].ref.path == 'refs/heads/pull/1/head' + assert isinstance(res[0].ref, Head) From 1410bcc76725b50be794b385006dedd96bebf0fb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 15:45:34 +0100 Subject: [PATCH 0146/2790] This should finally fix travis ci --- git/test/test_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 397641e0c..586f0ce4a 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -431,7 +431,7 @@ def test_references_and_objects(self, rw_dir): # [31-test_references_and_objects] git = repo.git - git.checkout('head', b="my_new_branch") # create a new branch + git.checkout('HEAD', b="my_new_branch") # create a new branch git.branch('another-new-one') git.branch('-D', 'another-new-one') # pass strings for full control over argument order git.for_each_ref() # '-' becomes '_' when calling it From 2ce3fe7cef8910aadc2a2b39a3dab4242a751380 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 16:22:15 +0100 Subject: [PATCH 0147/2790] Intermediate commit on my way to get this finalized. Renamed context manager 'with_environment' to 'custom_environment'. On my way to implement sshkey test. --- doc/source/tutorial.rst | 2 +- git/cmd.py | 25 +++++++++++++----------- git/scripts/ssh_wrapper.sh | 2 ++ git/test/test_git.py | 40 ++++++++++++++++++++++++++------------ scripts/ssh_wrapper.py | 9 --------- 5 files changed, 45 insertions(+), 33 deletions(-) create mode 100755 git/scripts/ssh_wrapper.sh delete mode 100755 scripts/ssh_wrapper.py diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 6ca0fd877..33a0a8841 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -384,7 +384,7 @@ Change configuration for a specific remote only:: o.config_writer.set("pushurl", "other_url") -You can also specify an SSH key to use for any operations on the remotes: +You can also specify an SSH key to use for any operations on the remotes:: private_key_file = project_dir+'id_rsa_deployment_key' with repo.git.sshkey(private_key_file): diff --git a/git/cmd.py b/git/cmd.py index 914424706..a03190730 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -439,6 +439,10 @@ def _set_cache_(self, attr): super(Git, self)._set_cache_(attr) # END handle version info + def _sshkey_script_path(self): + this_dir = os.path.dirname(__file__) + return os.path.join(this_dir, 'scripts', 'ssh_wrapper.sh') + @property def working_dir(self): """:return: Git directory we are working on""" @@ -541,6 +545,7 @@ def execute(self, command, # Start the process env = os.environ.copy() env["LC_MESSAGES"] = "C" + print(self._environment) env.update(self._environment) proc = Popen(command, @@ -633,7 +638,7 @@ def update_environment(self, **kwargs): :return: dict that maps environment variables to their old values """ old_env = {} - for key, value in kwargs.iteritems(): + for key, value in kwargs.items(): # set value if it is None if value is not None: if key in self._environment: @@ -648,14 +653,14 @@ def update_environment(self, **kwargs): return old_env @contextmanager - def with_environment(self, **kwargs): + def custom_environment(self, **kwargs): """ - A context manager around the above update_environment to restore the + A context manager around the above ``update_environment`` method to restore the environment back to its previous state after operation. ``Examples``:: - with self.with_environment(GIT_SSH='/bin/ssh_wrapper'): + with self.custom_environment(GIT_SSH='/bin/ssh_wrapper'): repo.remotes.origin.fetch() :param kwargs: see update_environment @@ -667,22 +672,20 @@ def with_environment(self, **kwargs): self.update_environment(**old_env) @contextmanager - def sshkey(self, sshkey_file): + def sshkey(self, sshkey_file_path): """ A context manager to temporarily set an SSH key for all operations that run inside it. ``Examples``:: - with self.environment(GIT_SSH=project_dir+'deployment_key'): + with self.sshkey('deployment_key'): repo.remotes.origin.fetch() - :param sshkey_file: Path to a private SSH key file + :param sshkey_file_path: Path to a private SSH key file """ - this_dir = os.path.dirname(__file__) - ssh_wrapper = os.path.join(this_dir, '..', 'scripts', 'ssh_wrapper.py') - - with self.with_environment(GIT_SSH_KEY_FILE=sshkey_file, GIT_SSH=ssh_wrapper): + ssh_wrapper = self._sshkey_script_path() + with self.custom_environment(GIT_SSH_KEY_FILE=sshkey_file_path, GIT_SSH=ssh_wrapper): yield def transform_kwargs(self, split_single_char_options=False, **kwargs): diff --git a/git/scripts/ssh_wrapper.sh b/git/scripts/ssh_wrapper.sh new file mode 100755 index 000000000..bc0ab0246 --- /dev/null +++ b/git/scripts/ssh_wrapper.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +ssh -i "$GIT_SSH_KEY_FILE" $@ diff --git a/git/test/test_git.py b/git/test/test_git.py index 85ee56c6b..990f4cd01 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -4,18 +4,24 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php - import os import mock -from git.test.lib import (TestBase, - patch, - raises, - assert_equal, - assert_true, - assert_match, - fixture_path) -from git import (Git, - GitCommandError) + +from git.test.lib import ( + TestBase, + patch, + raises, + assert_equal, + assert_true, + assert_match, + fixture_path +) +from git import ( + Git, + GitCommandError, + Repo +) +from gitdb.test.lib import with_rw_directory from git.compat import PY3 @@ -154,12 +160,13 @@ def test_env_vars_passed_to_git(self): with mock.patch.dict('os.environ', {'GIT_EDITOR': editor}): assert self.git.var("GIT_EDITOR") == editor - def test_environment(self): + @with_rw_directory + def test_environment(self, rw_dir): # sanity check assert self.git.environment() == {} # make sure the context manager works and cleans up after itself - with self.git.with_environment(PWD='/tmp'): + with self.git.custom_environment(PWD='/tmp'): assert self.git.environment() == {'PWD': '/tmp'} assert self.git.environment() == {} @@ -173,3 +180,12 @@ def test_environment(self): new_env = self.git.update_environment(**old_env) assert new_env == {'VARKEY': 'VARVALUE'} assert self.git.environment() == {} + + rw_repo = Repo.init(os.path.join(rw_dir, 'repo')) + remote = rw_repo.create_remote('ssh-origin', "ssh://git@server/foo") + + with rw_repo.git.sshkey('doesntexist.key'): + remote.fetch() + # end + + diff --git a/scripts/ssh_wrapper.py b/scripts/ssh_wrapper.py deleted file mode 100755 index af657f606..000000000 --- a/scripts/ssh_wrapper.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python - -import os -import subprocess -import sys - -ssh_options = ['-i', os.environ['GIT_SSH_KEY_FILE']] -ret_code = subprocess.call(['ssh'] + ssh_options + sys.argv[1:]) -sys.exit(ret_code) From 0ddbe4bc24e634e6496abd3bc6ce3c4377cdf2fb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 16:45:12 +0100 Subject: [PATCH 0148/2790] Added test for `sshkey` context manager. It verifies that the script is actually called. Interestingly, the shell script version works within an msysgit environment on windows. Fixes #234 --- git/repo/base.py | 3 +-- git/test/test_docs.py | 2 +- git/test/test_git.py | 23 +++++++++++++++++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index 61352a9ac..b7a9e29dc 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -75,7 +75,6 @@ def _expand_path(p): class Repo(object): - """Represents a git repository and allows you to query references, gather commit information, generate diffs, create and clone repositories query the log. @@ -758,7 +757,7 @@ def init(cls, path=None, mkdir=True, **kwargs): # git command automatically chdir into the directory git = Git(path) git.init(**kwargs) - return Repo(path) + return cls(path) @classmethod def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 965d10fb8..175e728a4 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -440,7 +440,7 @@ def test_references_and_objects(self, rw_dir): # [32-test_references_and_objects] private_key_file = os.path.join(rw_dir, 'id_rsa_deployment_key') with repo.git.sshkey(private_key_file): - # Note that we don't actually make the call here, as our test-setup doesn't permit it to + # Note that we don't actually make the call here, as our test-setup doesn't permit it to # succeed. # It will in your case :) repo.remotes.origin.fetch diff --git a/git/test/test_git.py b/git/test/test_git.py index 990f4cd01..18acd77e4 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -181,11 +181,26 @@ def test_environment(self, rw_dir): assert new_env == {'VARKEY': 'VARVALUE'} assert self.git.environment() == {} - rw_repo = Repo.init(os.path.join(rw_dir, 'repo')) + class TestRepo(Repo): + class GitCommandWrapperType(Git): + def _sshkey_script_path(self): + path = os.path.join(rw_dir, 'failing-script.sh') + stream = open(path, 'wt') + stream.write("#!/usr/bin/env sh\n" + + "echo FOO\n") + stream.close() + os.chmod(path, 0o555) + return path + # end Git + # end Repo + + rw_repo = TestRepo.init(os.path.join(rw_dir, 'repo')) remote = rw_repo.create_remote('ssh-origin', "ssh://git@server/foo") with rw_repo.git.sshkey('doesntexist.key'): - remote.fetch() + try: + remote.fetch() + except GitCommandError as err: + assert 'FOO' in str(err) + # end # end - - From 66c5b33fb5405fe12756f07048e3bcc3a958b2c1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 17:34:11 +0100 Subject: [PATCH 0149/2790] Minor improvements to submodule test for windows portability However, most tests fail for reasons unknown - SHA cannot be found. For now, I will wait until someone complains, as I doubt too many people will use it on windows. Related to #244 --- git/test/test_submodule.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 459e20303..cbf38c182 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -689,7 +689,7 @@ def test_git_submodules(self, rwdir): @with_rw_directory def test_git_submodule_compatibility(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) - sm_path = 'submodules/intermediate/one' + sm_path = join_path_native('submodules', 'intermediate', 'one') sm = parent.create_submodule('mymodules/myname', sm_path, url=self._small_repo_url()) parent.index.commit("added submodule") @@ -714,12 +714,12 @@ def assert_exists(sm, value=True): # end verify submodule 'style' # test move - new_sm_path = 'submodules/one' + new_sm_path = join_path_native('submodules', 'one') sm.move(new_sm_path) assert_exists(sm) # Add additional submodule level - csm = sm.module().create_submodule('nested-submodule', 'nested-submodule/working-tree', + csm = sm.module().create_submodule('nested-submodule', join_path_native('nested-submodule', 'working-tree'), url=self._small_repo_url()) sm.module().index.commit("added nested submodule") sm_head_commit = sm.module().commit() @@ -781,7 +781,7 @@ def test_rename(self, rwdir): sm_mod = sm.module() if os.path.isfile(os.path.join(sm_mod.working_tree_dir, '.git')) == sm._need_gitfile_submodules(parent.git): - assert sm_mod.git_dir.endswith(".git/modules/" + new_sm_name) + assert sm_mod.git_dir.endswith(join_path_native('.git', 'modules', new_sm_name)) # end @with_rw_directory From ffefb154982c6cc47c9be6b3eae6fb1170bb0791 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 18:10:43 +0100 Subject: [PATCH 0150/2790] Improved performance of rev-parse test. Hoping to make this significantly faster on travis. Related to #245 --- git/test/test_repo.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index c32dbdbff..ea4918245 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -34,7 +34,10 @@ from git.util import join_path_native from git.exc import BadObject from gitdb.util import bin_to_hex -from git.compat import string_types +from git.compat import ( + string_types, + # PY3 +) from gitdb.test.lib import with_rw_directory import os @@ -555,7 +558,7 @@ def test_rev_parse(self): # start from reference num_resolved = 0 - for ref in Reference.iter_items(self.rorepo): + for ref_no, ref in enumerate(Reference.iter_items(self.rorepo)): path_tokens = ref.path.split("/") for pt in range(len(path_tokens)): path_section = '/'.join(path_tokens[-(pt + 1):]) @@ -569,6 +572,8 @@ def test_rev_parse(self): pass # END exception handling # END for each token + if ref_no == 3 - 1: + break # END for each reference assert num_resolved @@ -610,6 +615,7 @@ def test_rev_parse(self): # END handle multiple tokens # try partial parsing + # if not (PY3 and 'TRAVIS' in os.environ): max_items = 40 for i, binsha in enumerate(self.rorepo.odb.sha_iter()): assert rev_parse(bin_to_hex(binsha)[:8 - (i % 2)].decode('ascii')).binsha == binsha @@ -618,6 +624,7 @@ def test_rev_parse(self): # which requires accessing packs, it has some additional overhead break # END for each binsha in repo + # end travis special handling # missing closing brace commit^{tree self.failUnlessRaises(ValueError, rev_parse, '0.1.4^{tree') From f3d91ca75500285d19c6ae2d4bf018452ad822a6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 18:56:28 +0100 Subject: [PATCH 0151/2790] Bumped version to 0.3.6 Unfortunately, installation of a executable script has proven to be so difficult thanks setuptools gloriousness, which will force me to remove that feature --- MANIFEST.in | 2 +- VERSION | 2 +- git/test/test_repo.py | 7 +------ setup.py | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 4c02e39a3..028d36193 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,7 +4,7 @@ include CHANGES include AUTHORS include README include requirements.txt -include scripts/ssh_wrapper.py +include git/scripts/ssh_wrapper.sh graft git/test/fixtures graft git/test/performance diff --git a/VERSION b/VERSION index c2c0004f0..449d7e73a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.5 +0.3.6 diff --git a/git/test/test_repo.py b/git/test/test_repo.py index ea4918245..667ede74d 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -34,10 +34,7 @@ from git.util import join_path_native from git.exc import BadObject from gitdb.util import bin_to_hex -from git.compat import ( - string_types, - # PY3 -) +from git.compat import string_types from gitdb.test.lib import with_rw_directory import os @@ -615,7 +612,6 @@ def test_rev_parse(self): # END handle multiple tokens # try partial parsing - # if not (PY3 and 'TRAVIS' in os.environ): max_items = 40 for i, binsha in enumerate(self.rorepo.odb.sha_iter()): assert rev_parse(bin_to_hex(binsha)[:8 - (i % 2)].decode('ascii')).binsha == binsha @@ -624,7 +620,6 @@ def test_rev_parse(self): # which requires accessing packs, it has some additional overhead break # END for each binsha in repo - # end travis special handling # missing closing brace commit^{tree self.failUnlessRaises(ValueError, rev_parse, '0.1.4^{tree') diff --git a/setup.py b/setup.py index d35301ae8..d2d8f2fa4 100755 --- a/setup.py +++ b/setup.py @@ -82,7 +82,7 @@ def _stamp_version(filename): url="https://github.com/gitpython-developers/GitPython", packages=find_packages('.'), py_modules=['git.' + f[:-3] for f in os.listdir('./git') if f.endswith('.py')], - package_data={'git.test': ['fixtures/*']}, + package_data={'git.test': ['fixtures/*'], 'git' : ['scripts/*']}, package_dir={'git': 'git'}, license="BSD License", requires=['gitdb (>=0.6.4)'], From 4df4159413a4bf30a891f21cd69202e8746c8fea Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 22 Jan 2015 19:04:57 +0100 Subject: [PATCH 0152/2790] Removed Git.sshkey() as it couldn't be distributed properly. However, I kept information on how to achieve the same thing with `custom_environment()` in the test. Related to #234 --- MANIFEST.in | 1 - doc/source/tutorial.rst | 2 +- git/cmd.py | 21 --------------------- git/ext/gitdb | 2 +- git/scripts/ssh_wrapper.sh | 2 -- git/test/test_docs.py | 4 ++-- git/test/test_git.py | 24 +++++++++--------------- setup.py | 2 +- 8 files changed, 14 insertions(+), 44 deletions(-) delete mode 100755 git/scripts/ssh_wrapper.sh diff --git a/MANIFEST.in b/MANIFEST.in index 028d36193..c84a9dd32 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,7 +4,6 @@ include CHANGES include AUTHORS include README include requirements.txt -include git/scripts/ssh_wrapper.sh graft git/test/fixtures graft git/test/performance diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 7f57ec947..0d60f0aae 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -331,7 +331,7 @@ You can easily access configuration information for a remote by accessing option :start-after: # [26-test_references_and_objects] :end-before: # ![26-test_references_and_objects] -You can also specify an SSH key to use for any operations on the remotes +You can also specify per-call custom environments using a new context manager on the Git command .. literalinclude:: ../../git/test/test_docs.py :language: python diff --git a/git/cmd.py b/git/cmd.py index 960b2a216..7e15d4eaa 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -439,10 +439,6 @@ def _set_cache_(self, attr): super(Git, self)._set_cache_(attr) # END handle version info - def _sshkey_script_path(self): - this_dir = os.path.dirname(__file__) - return os.path.join(this_dir, 'scripts', 'ssh_wrapper.sh') - @property def working_dir(self): """:return: Git directory we are working on""" @@ -670,23 +666,6 @@ def custom_environment(self, **kwargs): finally: self.update_environment(**old_env) - @contextmanager - def sshkey(self, sshkey_file_path): - """ - A context manager to temporarily set an SSH key for all operations that - run inside it. - - ``Examples``:: - - with self.sshkey('deployment_key'): - repo.remotes.origin.fetch() - - :param sshkey_file_path: Path to a private SSH key file - """ - ssh_wrapper = self._sshkey_script_path() - with self.custom_environment(GIT_SSH_KEY_FILE=sshkey_file_path, GIT_SSH=ssh_wrapper): - yield - def transform_kwargs(self, split_single_char_options=False, **kwargs): """Transforms Python style kwargs into git command line options.""" args = list() diff --git a/git/ext/gitdb b/git/ext/gitdb index b3237e804..9aae93ea5 160000 --- a/git/ext/gitdb +++ b/git/ext/gitdb @@ -1 +1 @@ -Subproject commit b3237e804ae313503f5479349f90066c356b1548 +Subproject commit 9aae93ea584c8cf9d1539a60e41c5c37119401d6 diff --git a/git/scripts/ssh_wrapper.sh b/git/scripts/ssh_wrapper.sh deleted file mode 100755 index bc0ab0246..000000000 --- a/git/scripts/ssh_wrapper.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env sh -ssh -i "$GIT_SSH_KEY_FILE" $@ diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 175e728a4..8dfef1c6d 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -438,8 +438,8 @@ def test_references_and_objects(self, rw_dir): # ![31-test_references_and_objects] # [32-test_references_and_objects] - private_key_file = os.path.join(rw_dir, 'id_rsa_deployment_key') - with repo.git.sshkey(private_key_file): + ssh_executable = os.path.join(rw_dir, 'my_ssh_executable.sh') + with repo.git.custom_environment(GIT_SSH=ssh_executable): # Note that we don't actually make the call here, as our test-setup doesn't permit it to # succeed. # It will in your case :) diff --git a/git/test/test_git.py b/git/test/test_git.py index 18acd77e4..8087bc454 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -181,23 +181,17 @@ def test_environment(self, rw_dir): assert new_env == {'VARKEY': 'VARVALUE'} assert self.git.environment() == {} - class TestRepo(Repo): - class GitCommandWrapperType(Git): - def _sshkey_script_path(self): - path = os.path.join(rw_dir, 'failing-script.sh') - stream = open(path, 'wt') - stream.write("#!/usr/bin/env sh\n" + - "echo FOO\n") - stream.close() - os.chmod(path, 0o555) - return path - # end Git - # end Repo - - rw_repo = TestRepo.init(os.path.join(rw_dir, 'repo')) + path = os.path.join(rw_dir, 'failing-script.sh') + stream = open(path, 'wt') + stream.write("#!/usr/bin/env sh\n" + + "echo FOO\n") + stream.close() + os.chmod(path, 0o555) + + rw_repo = Repo.init(os.path.join(rw_dir, 'repo')) remote = rw_repo.create_remote('ssh-origin', "ssh://git@server/foo") - with rw_repo.git.sshkey('doesntexist.key'): + with rw_repo.git.custom_environment(GIT_SSH=path): try: remote.fetch() except GitCommandError as err: diff --git a/setup.py b/setup.py index d2d8f2fa4..d35301ae8 100755 --- a/setup.py +++ b/setup.py @@ -82,7 +82,7 @@ def _stamp_version(filename): url="https://github.com/gitpython-developers/GitPython", packages=find_packages('.'), py_modules=['git.' + f[:-3] for f in os.listdir('./git') if f.endswith('.py')], - package_data={'git.test': ['fixtures/*'], 'git' : ['scripts/*']}, + package_data={'git.test': ['fixtures/*']}, package_dir={'git': 'git'}, license="BSD License", requires=['gitdb (>=0.6.4)'], From f498de9bfd67bcbb42d36dfb8ff9e59ec788825b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 30 Jan 2015 05:49:18 +0100 Subject: [PATCH 0153/2790] Remote.update() didn't pass kwargs along to git command. Fixes #250 --- git/remote.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/remote.py b/git/remote.py index d048f87bc..2267c2035 100644 --- a/git/remote.py +++ b/git/remote.py @@ -517,7 +517,7 @@ def update(self, **kwargs): Additional arguments passed to git-remote update :return: self """ - self.repo.git.remote("update", self.name) + self.repo.git.remote("update", self.name, **kwargs) return self def _get_fetch_info_from_stderr(self, proc, progress): From 47d9f1321c3a6da68a7909fcb1a66a209066d4c9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 30 Jan 2015 06:34:48 +0100 Subject: [PATCH 0154/2790] Added test to verify we can handle fetch prunes. They are just skipped. Fixes #249 --- git/test/test_remote.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 98d74d8be..b7bf98018 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -445,6 +445,19 @@ def test_base(self, rw_repo, remote_repo): origin = rw_repo.remote('origin') assert origin == rw_repo.remotes.origin + # Verify we can handle prunes when fetching + # stderr lines look like this: x [deleted] (none) -> origin/experiment-2012 + # These should just be skipped + num_deleted = False + for branch in remote_repo.heads: + if branch.name != 'master': + branch.delete(remote_repo, branch, force=True) + num_deleted += 1 + # end + # end for each branch + assert num_deleted > 0 + assert len(rw_repo.remotes.origin.fetch(prune=True)) == 1, "deleted everything but master" + @with_rw_repo('HEAD', bare=True) def test_creation_and_removal(self, bare_rw_repo): new_name = "test_new_one" From 91645aa87e79e54a56efb8686eb4ab6c8ba67087 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 30 Jan 2015 06:54:49 +0100 Subject: [PATCH 0155/2790] This should fix the test failure on travis --- git/test/test_remote.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/git/test/test_remote.py b/git/test/test_remote.py index b7bf98018..2540e49b0 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -448,6 +448,11 @@ def test_base(self, rw_repo, remote_repo): # Verify we can handle prunes when fetching # stderr lines look like this: x [deleted] (none) -> origin/experiment-2012 # These should just be skipped + # If we don't have a manual checkout, we can't actually assume there are any non-master branches + remote_repo.create_head("myone_for_deletion") + # Get the branch - to be pruned later + origin.fetch() + num_deleted = False for branch in remote_repo.heads: if branch.name != 'master': From 91562247e0d11d28b4bc6d85ba50b7af2bd7224b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 2 Feb 2015 08:06:13 +0100 Subject: [PATCH 0156/2790] An attempt to better steer questions and answers. Currently, people put it onto the mailing list and on stack overflow [ci skip] --- README.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0019dc179..1895635fd 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,11 @@ The object database implementation is optimized for handling large quantities of ### REQUIREMENTS -* Git ( tested with 1.8.3.4 ) -* Python Nose - used for running the tests - - Tested with nose 1.3.0 -* Mock by Michael Foord used for tests - - Tested with 1.0.1 -* Coverage - used for tests coverage +GitPython needs the `git` executable to be installed on the system and available in your `PATH` for most operations. If it is not in your `PATH`, you can help GitPython find it by setting the `GIT_PYTHON_GIT_EXECUTABLE=` environment variable. -The list of dependencies are listed in /requirements.txt and /test-requirements.txt. The installer takes care of installing them for you though. +* Git (1.7.x or newer) + +The list of dependencies are listed in `./requirements.txt` and `./test-requirements.txt`. The installer takes care of installing them for you. ### INSTALL @@ -62,8 +59,16 @@ You can watch me fix issues or implement new features [live on Twitch][twitch-ch ### INFRASTRUCTURE * [User Documentation](http://gitpython.readthedocs.org) +* [Questions and Answers](http://stackexchange.com/filters/167317/gitpython) + * Please post on stackoverflow and use the `gitpython` tag * [Mailing List](http://groups.google.com/group/git-python) + * Please use it for everything that doesn't fit Stackoverflow. * [Issue Tracker](https://github.com/gitpython-developers/GitPython/issues) + * Post reproducible bugs and feature requests as a new issue. Please be sure to provide the following information if posting bugs: + * GitPython version (e.g. `import git; git.__version__`) + * Python version (e.g. `python --version`) + * The encountered stack-trace, if applicable + * Enough information to allow reproducing the issue ### LICENSE From d8bbfea4cdcb36ce0e9ee7d7cad4c41096d4d54f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 5 Feb 2015 06:10:42 +0100 Subject: [PATCH 0157/2790] Updated copyright information. Fixes #246 --- doc/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 942996b0b..f86f08ac8 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -43,7 +43,7 @@ # General information about the project. project = u'GitPython' -copyright = u'Copyright (C) 2008, 2009 Michael Trier and contributors, 2010 Sebastian Thiel' +copyright = u'Copyright (C) 2008, 2009 Michael Trier and contributors, 2010-2015 Sebastian Thiel' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From d7729245060f9aecfef4544f91e2656aa8d483ec Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sat, 7 Feb 2015 11:14:03 -0500 Subject: [PATCH 0158/2790] ENH: respect GIT_PYTHON_TEST_GIT_REPO_BASE env var in tests --- git/test/lib/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 8300f2722..5efb7d9d9 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -15,7 +15,7 @@ from git import Repo, Remote, GitCommandError, Git from git.compat import string_types -GIT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) +GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))) __all__ = ( 'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter', From 756b7ad43d0ad18858075f90ce5eaec2896d439c Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sat, 7 Feb 2015 11:14:42 -0500 Subject: [PATCH 0159/2790] BF: skip unicode filename test in env not supporting unicode encodings --- git/test/test_base.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/git/test/test_base.py b/git/test/test_base.py index 91b9d0053..72f2d5542 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -5,6 +5,7 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os +import sys import tempfile import git.objects.base as base @@ -116,6 +117,14 @@ def test_add_unicode(self, rw_repo): filename = u"שלום.txt" file_path = os.path.join(rw_repo.working_dir, filename) + + # verify first that we could encode file name in this environment + try: + _ = file_path.encode(sys.getfilesystemencoding()) + except UnicodeEncodeError: + from nose import SkipTest + raise SkipTest("Environment doesn't support unicode filenames") + open(file_path, "wb").write(b'something') if os.name == 'nt': From 873823f39275ceb8d65ebfae74206c7347e07123 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 8 Feb 2015 21:47:55 -0500 Subject: [PATCH 0160/2790] BF: run commit hook with repo.working_dir as cwd Otherwise commit hook might rightfully fail, as happens if repository is e.g. git-annex repository. See e.g. now failing https://travis-ci.org/datalad/datalad/builds/49802394\#L1590 which seems to pass tests nicely with patch as this --- git/index/fun.py | 1 + 1 file changed, 1 insertion(+) diff --git a/git/index/fun.py b/git/index/fun.py index f07cf7dc3..c2fe912e6 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -72,6 +72,7 @@ def run_commit_hook(name, index): env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + cwd=index.repo.working_dir, close_fds=(os.name == 'posix')) stdout, stderr = cmd.communicate() cmd.stdout.close() From fe426d404b727d0567f21871f61cc6dc881e8bf0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 9 Feb 2015 19:22:18 +0100 Subject: [PATCH 0161/2790] Minor Flake8 fixes. Latest version of it is required to show the issues travis shows as well --- git/index/fun.py | 6 +++--- git/test/lib/helper.py | 10 ++++++---- git/test/test_base.py | 2 +- tox.ini | 4 +++- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/git/index/fun.py b/git/index/fun.py index f07cf7dc3..f8bd9d894 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -10,8 +10,6 @@ S_IFREG, ) -S_IFGITLINK = S_IFLNK | S_IFDIR # a submodule - from io import BytesIO import os import subprocess @@ -33,7 +31,6 @@ CE_NAMEMASK, CE_STAGESHIFT ) -CE_NAMEMASK_INV = ~CE_NAMEMASK from .util import ( pack, @@ -47,6 +44,9 @@ force_text ) +S_IFGITLINK = S_IFLNK | S_IFDIR # a submodule +CE_NAMEMASK_INV = ~CE_NAMEMASK + __all__ = ('write_cache', 'read_cache', 'write_tree_from_cache', 'entry_key', 'stat_mode_to_index_mode', 'S_IFGITLINK', 'run_commit_hook', 'hook_path') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 5efb7d9d9..31bee78f6 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -15,7 +15,9 @@ from git import Repo, Remote, GitCommandError, Git from git.compat import string_types -GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))) +osp = os.path.dirname + +GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", osp(osp(osp(osp(__file__))))) __all__ = ( 'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter', @@ -26,7 +28,7 @@ def fixture_path(name): - test_dir = os.path.dirname(os.path.dirname(__file__)) + test_dir = osp(osp(__file__)) return os.path.join(test_dir, "fixtures", name) @@ -35,7 +37,7 @@ def fixture(name): def absolute_project_path(): - return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + return os.path.abspath(os.path.join(osp(__file__), "..", "..")) #} END routines @@ -195,7 +197,7 @@ def remote_repo_creator(self): d_remote.config_writer.set('url', remote_repo_url) - temp_dir = os.path.dirname(_mktemp()) + temp_dir = osp(_mktemp()) # On windows, this will fail ... we deal with failures anyway and default to telling the user to do it try: gd = Git().daemon(temp_dir, enable='receive-pack', as_process=True) diff --git a/git/test/test_base.py b/git/test/test_base.py index 72f2d5542..94379ca34 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -120,7 +120,7 @@ def test_add_unicode(self, rw_repo): # verify first that we could encode file name in this environment try: - _ = file_path.encode(sys.getfilesystemencoding()) + file_path.encode(sys.getfilesystemencoding()) except UnicodeEncodeError: from nose import SkipTest raise SkipTest("Environment doesn't support unicode filenames") diff --git a/tox.ini b/tox.ini index bb1e9a85b..da624b5ee 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,9 @@ commands = {posargs} [flake8] #show-source = True # E265 = comment blocks like @{ section, which it can't handle +# E266 = too many leading '#' for block comment +# E731 = do not assign a lambda expression, use a def # W293 = Blank line contains whitespace -ignore = E265,W293 +ignore = E265,W293,E266,E731 max-line-length = 120 exclude = .tox,.venv,build,dist,doc,git/ext/ From f51fe3e66d358e997f4af4e91a894a635f7cb601 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 9 Feb 2015 21:05:41 +0100 Subject: [PATCH 0162/2790] Added previously missing parameter documentation for Repo.__init__ . Related to #255 --- git/repo/base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/git/repo/base.py b/git/repo/base.py index b7a9e29dc..e59cb0c7d 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -121,6 +121,11 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will be used to access all object data + :param search_parent_directories: + if True, all parent directories will be searched for a valid repo as well. + + Please note that this was the default behaviour in older versions of GitPython, + which is considered a bug though. :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ From 158bc981130bfbe214190cac19da228d1f321fe1 Mon Sep 17 00:00:00 2001 From: Jonas Trappenberg Date: Mon, 9 Feb 2015 15:15:15 -0800 Subject: [PATCH 0163/2790] Replace GIT_SSH with GIT_SSH_COMMAND for SSH key management. Also move untestable documentation out of test. Related: #234, #242 --- doc/source/tutorial.rst | 9 ++++----- git/test/test_docs.py | 9 --------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 0d60f0aae..e86fd8d57 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -331,12 +331,11 @@ You can easily access configuration information for a remote by accessing option :start-after: # [26-test_references_and_objects] :end-before: # ![26-test_references_and_objects] -You can also specify per-call custom environments using a new context manager on the Git command +You can also specify per-call custom environments using a new context manager on the Git command, e.g. for using a specific SSH key. -.. literalinclude:: ../../git/test/test_docs.py - :language: python - :start-after: # [32-test_references_and_objects] - :end-before: # ![32-test_references_and_objects] + ssh_cmd = 'ssh -i id_deployment_key' + with repo.git.custom_environment(GIT_SSH_COMMAND=ssh_cmd): + repo.remotes.origin.fetch() Submodule Handling ****************** diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 8dfef1c6d..586f0ce4a 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -437,15 +437,6 @@ def test_references_and_objects(self, rw_dir): git.for_each_ref() # '-' becomes '_' when calling it # ![31-test_references_and_objects] - # [32-test_references_and_objects] - ssh_executable = os.path.join(rw_dir, 'my_ssh_executable.sh') - with repo.git.custom_environment(GIT_SSH=ssh_executable): - # Note that we don't actually make the call here, as our test-setup doesn't permit it to - # succeed. - # It will in your case :) - repo.remotes.origin.fetch - # ![32-test_references_and_objects] - def test_submodules(self): # [1-test_submodules] repo = self.rorepo From 5ac93b1d7e0694ceb303ee72c312921a9b1588f4 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 19 Feb 2015 16:56:13 +0100 Subject: [PATCH 0164/2790] Use uuid instead of tempfile.mkdtmp, which created an actual directory. That, over time, could have caused slow downs due to file-system hassle. Fixes #258 --- git/objects/submodule/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index be243acc5..82c465acb 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -37,7 +37,7 @@ import os import logging -import tempfile +import uuid __all__ = ["Submodule", "UpdateProgress"] @@ -992,7 +992,7 @@ def rename(self, new_name): source_dir = mod.git_dir # Let's be sure the submodule name is not so obviously tied to a directory if destination_module_abspath.startswith(mod.git_dir): - tmp_dir = self._module_abspath(self.repo, self.path, os.path.basename(tempfile.mkdtemp())) + tmp_dir = self._module_abspath(self.repo, self.path, str(uuid.uuid4())) os.renames(source_dir, tmp_dir) source_dir = tmp_dir # end handle self-containment From 0f5320e8171324a002d3769824152cf5166a21a2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 19 Feb 2015 17:12:15 +0100 Subject: [PATCH 0165/2790] Fix flake8 issue. It's new in the latest version of flake - thanks travis for letting me know. --- git/objects/submodule/base.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 82c465acb..9c1dc6471 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -578,11 +578,13 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= base_commit = mrepo.merge_base(mrepo.head.commit, hexsha) if len(base_commit) == 0 or base_commit[0].hexsha == hexsha: if force: - log.debug("Will force checkout or reset on local branch that is possibly in the future of" - + "the commit it will be checked out to, effectively 'forgetting' new commits") + msg = "Will force checkout or reset on local branch that is possibly in the future of" + msg += "the commit it will be checked out to, effectively 'forgetting' new commits" + log.debug(msg) else: - log.info("Skipping %s on branch '%s' of submodule repo '%s' as it contains " - + "un-pushed commits", is_detached and "checkout" or "reset", mrepo.head, mrepo) + msg = "Skipping %s on branch '%s' of submodule repo '%s' as it contains un-pushed commits" + msg %= (is_detached and "checkout" or "reset", mrepo.head, mrepo) + log.info(msg) may_reset = False # end handle force # end handle if we are in the future From 346424daaaf2bb3936b5f4c2891101763dc2bdc0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 19 Feb 2015 18:02:35 +0100 Subject: [PATCH 0166/2790] Assure to not iterate packed-refs file, ever. Related to #252 --- git/refs/symbolic.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index fed7006e6..d884250f7 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -140,6 +140,7 @@ def _get_ref_info(cls, repo, ref_path): # Don't only split on spaces, but on whitespace, which allows to parse lines like # 60b64ef992065e2600bfef6187a97f92398a9144 branch 'master' of git-server:/path/to/repo tokens = value.split() + assert(len(tokens) != 0) except (OSError, IOError): # Probably we are just packed, find our entry in the packed refs file # NOTE: We are not a symbolic ref if we are in a packed file, as these @@ -582,6 +583,8 @@ def _iter_items(cls, repo, common_path=None): # END prune non-refs folders for f in files: + if f == 'packed-refs': + continue abs_path = to_native_path_linux(join_path(root, f)) rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_dir) + '/', "")) # END for each file in root directory From 3d74543a545a9468cabec5d20519db025952efed Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 19 Feb 2015 18:29:10 +0100 Subject: [PATCH 0167/2790] Adjust minimum git version with git-file support. As I am pretty sure to have tested it with 1.7.0, I assume they added the git file feature somewhere between .0 .10. Fixes #252 --- git/objects/submodule/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 9c1dc6471..4347df55d 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -136,7 +136,8 @@ def _get_intermediate_items(self, item): @classmethod def _need_gitfile_submodules(cls, git): - return git.version_info[:3] >= (1, 8, 0) + # on debian wheezy, it seems to already support git files at this version. Maybe even earler, who knows + return git.version_info[:3] >= (1, 7, 10) def __eq__(self, other): """Compare with another submodule""" From 38fc944390d57399d393dc34b4d1c5c81241fb87 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 20 Feb 2015 07:09:18 +0100 Subject: [PATCH 0168/2790] It seems something within our environment changed ... ... as we are now running out of file handles. Previously, it worked ... and gitpython didn't change --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1fda20189..069527ebf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ install: - git config --global user.name "Travis Runner" script: # Make sure we limit open handles to see if we are leaking them - - ulimit -n 64 + - ulimit -n 96 - ulimit -n - nosetests -v --with-coverage - flake8 From e2feb62c17acd1dddb6cd125d8b90933c32f89e1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 20 Feb 2015 18:11:13 +0100 Subject: [PATCH 0169/2790] Apparently, git 1.7.9 supports git-files too, lets assume it's starting at 1.7.0 --- git/objects/submodule/base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 4347df55d..7e8dd053e 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -136,8 +136,7 @@ def _get_intermediate_items(self, item): @classmethod def _need_gitfile_submodules(cls, git): - # on debian wheezy, it seems to already support git files at this version. Maybe even earler, who knows - return git.version_info[:3] >= (1, 7, 10) + return git.version_info[:3] >= (1, 7, 0) def __eq__(self, other): """Compare with another submodule""" From c00567d3025016550d55a7abaf94cbb82a5c44fb Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 20 Feb 2015 15:06:30 -0500 Subject: [PATCH 0170/2790] BF: do not checkout master -- that ruins testing of PRs. "reset" master to original HEAD --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 069527ebf..b53228ca1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,11 +15,12 @@ install: - pip install coveralls flake8 sphinx # generate some reflog as git-python tests need it (in master) + - git tag __testing_point__ - git checkout master - git reset --hard HEAD~1 - git reset --hard HEAD~1 - git reset --hard HEAD~1 - - git reset --hard origin/master + - git reset --hard __testing_point__ # as commits are performed with the default user, it needs to be set for travis too - git config --global user.email "travis@ci.com" From e0acb8371bb2b68c2bda04db7cb2746ba3f9da86 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 21 Feb 2015 10:12:11 +0100 Subject: [PATCH 0171/2790] Added 'insert_kwargs_after' flag for consumption by _call_process. While at it, all other invocations of .git in remote.py were reviewed Fixes #262 --- git/cmd.py | 14 +++++++++++++- git/remote.py | 8 ++++++-- git/test/test_git.py | 4 ++++ git/test/test_remote.py | 3 +++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 7e15d4eaa..911bb9f36 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -753,11 +753,23 @@ def _call_process(self, method, *args, **kwargs): except KeyError: pass + insert_after_this_arg = kwargs.pop('insert_kwargs_after', None) + # Prepare the argument list opt_args = self.transform_kwargs(**kwargs) ext_args = self.__unpack_args([a for a in args if a is not None]) - args = opt_args + ext_args + if insert_after_this_arg is None: + args = opt_args + ext_args + else: + try: + index = ext_args.index(insert_after_this_arg) + except ValueError: + raise ValueError("Couldn't find argument '%s' in args %s to insert kwargs after" + % (insert_after_this_arg, str(ext_args))) + # end handle error + args = ext_args[:index + 1] + opt_args + ext_args[index + 1:] + # end handle kwargs def make_call(): call = [self.GIT_PYTHON_GIT_EXECUTABLE] diff --git a/git/remote.py b/git/remote.py index 2267c2035..8911aaa43 100644 --- a/git/remote.py +++ b/git/remote.py @@ -477,7 +477,9 @@ def create(cls, repo, name, url, **kwargs): :param kwargs: Additional arguments to be passed to the git-remote add command :return: New Remote instance :raise GitCommandError: in case an origin with that name already exists""" - repo.git.remote("add", name, url, **kwargs) + scmd = 'add' + kwargs['insert_kwargs_after'] = scmd + repo.git.remote(scmd, name, url, **kwargs) return cls(repo, name) # add is an alias @@ -517,7 +519,9 @@ def update(self, **kwargs): Additional arguments passed to git-remote update :return: self """ - self.repo.git.remote("update", self.name, **kwargs) + scmd = 'update' + kwargs['insert_kwargs_after'] = scmd + self.repo.git.remote(scmd, self.name, **kwargs) return self def _get_fetch_info_from_stderr(self, proc, progress): diff --git a/git/test/test_git.py b/git/test/test_git.py index 8087bc454..ef6947552 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -155,6 +155,10 @@ def test_single_char_git_options_are_passed_to_git(self): def test_change_to_transform_kwargs_does_not_break_command_options(self): self.git.log(n=1) + def test_insert_after_kwarg_raises(self): + # This isn't a complete add command, which doesn't matter here + self.failUnlessRaises(ValueError, self.git.remote, 'add', insert_kwargs_after='foo') + def test_env_vars_passed_to_git(self): editor = 'non_existant_editor' with mock.patch.dict('os.environ', {'GIT_EDITOR': editor}): diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 2540e49b0..8500a295a 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -486,6 +486,9 @@ def test_creation_and_removal(self, bare_rw_repo): # END if deleted remote matches existing remote's name # END for each remote + # Issue #262 - the next call would fail if bug wasn't fixed + bare_rw_repo.create_remote('bogus', '/bogus/path', mirror='push') + def test_fetch_info(self): # assure we can handle remote-tracking branches fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of " From 3236f8b966061b23ba063f3f7e1652764fee968f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 21 Feb 2015 11:14:53 +0100 Subject: [PATCH 0172/2790] `stale_refs()` may now also handle other kinds of references, like tags. Fixes #260 --- git/remote.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/git/remote.py b/git/remote.py index 8911aaa43..bb2165f22 100644 --- a/git/remote.py +++ b/git/remote.py @@ -455,7 +455,13 @@ def stale_refs(self): remote side, but are still available locally. The IterableList is prefixed, hence the 'origin' must be omitted. See - 'refs' property for an example.""" + 'refs' property for an example. + + To make things more complicated, it can be possble for the list to include + other kinds of references, for example, tag references, if these are stale + as well. This is a fix for the issue described here: + https://github.com/gitpython-developers/GitPython/issues/260 + """ out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name) for line in self.repo.git.remote("prune", "--dry-run", self).splitlines()[2:]: # expecting @@ -463,8 +469,14 @@ def stale_refs(self): token = " * [would prune] " if not line.startswith(token): raise ValueError("Could not parse git-remote prune result: %r" % line) - fqhn = "%s/%s" % (RemoteReference._common_path_default, line.replace(token, "")) - out_refs.append(RemoteReference(self.repo, fqhn)) + ref_name = line.replace(token, "") + # sometimes, paths start with a full ref name, like refs/tags/foo, see #260 + if ref_name.startswith(Reference._common_path_default + '/'): + out_refs.append(SymbolicReference.from_path(self.repo, ref_name)) + else: + fqhn = "%s/%s" % (RemoteReference._common_path_default, ref_name) + out_refs.append(RemoteReference(self.repo, fqhn)) + # end special case handlin # END for each line return out_refs From 9d1a489931ecbdd652111669c0bd86bcd6f5abbe Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 21 Feb 2015 11:21:55 +0100 Subject: [PATCH 0173/2790] Fixed trailing white space! Think about how expensive this single invisible character was, with all the time and energy spent on it ! --- git/remote.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/remote.py b/git/remote.py index bb2165f22..6a15c9c4f 100644 --- a/git/remote.py +++ b/git/remote.py @@ -458,7 +458,7 @@ def stale_refs(self): 'refs' property for an example. To make things more complicated, it can be possble for the list to include - other kinds of references, for example, tag references, if these are stale + other kinds of references, for example, tag references, if these are stale as well. This is a fix for the issue described here: https://github.com/gitpython-developers/GitPython/issues/260 """ From 630d030058c234e50d87196b624adc2049834472 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 23 Feb 2015 08:33:54 +0100 Subject: [PATCH 0174/2790] Improved documentation on IndexFile.add(...) Related to #224 [ci skip] --- git/index/base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/git/index/base.py b/git/index/base.py index b73edd6f3..733d4a63b 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -625,6 +625,10 @@ def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=Non strings denote a relative or absolute path into the repository pointing to an existing file, i.e. CHANGES, lib/myfile.ext, '/home/gitrepo/lib/myfile.ext'. + Absolute paths must start with working tree directory of this index's repository + to be considered valid. For example, if it was initialized with a non-normalized path, like + `/root/repo/../repo`, absolute paths to be added must start with `/root/repo/../repo`. + Paths provided like this must exist. When added, they will be written into the object database. From a5e607e8aa62ca3778f1026c27a927ee5c79749b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 2 Mar 2015 14:19:05 +0100 Subject: [PATCH 0175/2790] fix(iter-commit): ambiguous argument error In repositories like > git branch -a * test > ls test `repo.iter_commits` failed due to an ambigous argument (`'git rev-list test`). Now this cannot happen anymore. fixes #264 --- git/objects/commit.py | 7 +++++-- git/test/test_commit.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/git/objects/commit.py b/git/objects/commit.py index b9718694f..f13760fdb 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -189,9 +189,12 @@ def iter_items(cls, repo, rev, paths='', **kwargs): if 'pretty' in kwargs: raise ValueError("--pretty cannot be used as parsing expects single sha's only") # END handle pretty - args = list() + + # use -- in any case, to prevent possibility of ambiguous arguments + # see https://github.com/gitpython-developers/GitPython/issues/264 + args = ['--'] if paths: - args.extend(('--', paths)) + args.extend((paths, )) # END if paths proc = repo.git.rev_list(rev, args, as_process=True, **kwargs) diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 1f0f8c561..3e958edf2 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -19,15 +19,19 @@ Actor, ) from gitdb import IStream +from gitdb.test.lib import with_rw_directory from git.compat import ( string_types, text_type ) +from git import Repo +from git.repo.fun import touch from io import BytesIO import time import sys import re +import os def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False): @@ -219,6 +223,15 @@ def test_rev_list_bisect_all(self): for sha1, commit in zip(expected_ids, commits): assert_equal(sha1, commit.hexsha) + @with_rw_directory + def test_ambiguous_arg_iteration(self, rw_dir): + rw_repo = Repo.init(os.path.join(rw_dir, 'test_ambiguous_arg')) + path = os.path.join(rw_repo.working_tree_dir, 'master') + touch(path) + rw_repo.index.add([path]) + rw_repo.index.commit('initial commit') + list(rw_repo.iter_commits(rw_repo.head.ref)) # should fail unless bug is fixed + def test_count(self): assert self.rorepo.tag('refs/tags/0.1.5').commit.count() == 143 From 50f763cfe38a1d69a3a04e41a36741545885f1d8 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Mon, 2 Mar 2015 09:25:27 -0800 Subject: [PATCH 0176/2790] Store path attribute on Diff object If a file in a commit contains no changes (for example, if only the file mode is changed) there will be no blob attached. This is usually where the filename is stored, so without it, the calling context can not tell what file was changed. Instead, always store a_path and b_path on the Diff object so that information is available. --- git/diff.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/git/diff.py b/git/diff.py index 378823696..dc53f3f71 100644 --- a/git/diff.py +++ b/git/diff.py @@ -168,11 +168,13 @@ class Diff(object): a_mode is None a_blob is None + a_path is None ``Deleted File``:: b_mode is None b_blob is None + b_path is None ``Working Tree Blobs`` @@ -200,8 +202,8 @@ class Diff(object): NULL_HEX_SHA = "0" * 40 NULL_BIN_SHA = b"\0" * 20 - __slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "new_file", "deleted_file", - "rename_from", "rename_to", "diff") + __slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "a_path", "b_path", + "new_file", "deleted_file", "rename_from", "rename_to", "diff") def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode, b_mode, new_file, deleted_file, rename_from, @@ -210,6 +212,9 @@ def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode, self.a_mode = a_mode self.b_mode = b_mode + self.a_path = a_path + self.b_path = b_path + if self.a_mode: self.a_mode = mode_str_to_int(self.a_mode) if self.b_mode: From 21a6cb7336b61f904198f1d48526dcbe9cba6eec Mon Sep 17 00:00:00 2001 From: "Kyle P. Johnson" Date: Fri, 27 Mar 2015 10:04:58 -0400 Subject: [PATCH 0177/2790] Fix typo --- git/objects/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/objects/util.py b/git/objects/util.py index cefef862d..567b1d5b2 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -216,7 +216,7 @@ def __getattr__(self, attr): class Traversable(object): - """Simple interface to perforam depth-first or breadth-first traversals + """Simple interface to perform depth-first or breadth-first traversals into one direction. Subclasses only need to implement one function. Instances of the Subclass must be hashable""" From 1c2502ee83927437442b13b83f3a7976e4146a01 Mon Sep 17 00:00:00 2001 From: Markus Siemens Date: Tue, 7 Apr 2015 14:33:39 +0200 Subject: [PATCH 0178/2790] Fix problem with submodules on Windows On Windows, `repo.create_submodule(...)` failed because git didn't recognize the worktree path set in `.git/modules/sub/config` (`fatal: bad config file line 6 in ./config`). This commit makes `_write_git_file_and_module_config` convert the worktree path to the linux format (forward slashes) which git recognizes. --- git/objects/submodule/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 7e8dd053e..f9b0b6ad6 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -293,7 +293,8 @@ def _write_git_file_and_module_config(cls, working_tree_dir, module_abspath): fp.close() writer = GitConfigParser(os.path.join(module_abspath, 'config'), read_only=False, merge_includes=False) - writer.set_value('core', 'worktree', os.path.relpath(working_tree_dir, start=module_abspath)) + writer.set_value('core', 'worktree', + to_native_path_linux(os.path.relpath(working_tree_dir, start=module_abspath))) writer.release() #{ Edit Interface From 54e27f7bbb412408bbf0d2735b07d57193869ea6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 7 Apr 2015 17:19:22 +0200 Subject: [PATCH 0179/2790] fix(docs): sphinx docs build in latest version --- doc/source/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index f86f08ac8..add686d3f 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -94,7 +94,6 @@ # ----------------------- html_theme_options = { - "stickysidebar": "true" } # The style sheet to use for HTML and HTML Help pages. A file of that name From 1fd07a0a7a6300db1db8b300a3f567b31b335570 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 7 Apr 2015 18:27:16 +0200 Subject: [PATCH 0180/2790] test(index): test for #265 However, it doesn't reproduce on the latest version of GitPython. Maybe it's on an older one. --- git/test/test_index.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/git/test/test_index.py b/git/test/test_index.py index 63f99f109..8124ec164 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -44,8 +44,11 @@ BaseIndexEntry, IndexEntry ) +from gitdb.test.lib import with_rw_directory from git.index.fun import hook_path +import git + class TestIndex(TestBase): @@ -765,3 +768,15 @@ def test_index_bare_add(self, rw_bare_repo): except InvalidGitRepositoryError: asserted = True assert asserted, "Adding using a filename is not correctly asserted." + + @with_rw_directory + def test_index_add_corruption(self, rw_dir): + # Test for https://github.com/gitpython-developers/GitPython/issues/265 + repo = git.Repo.clone_from("git://pkgs.fedoraproject.org/GitPython", rw_dir) + assert not repo.is_dirty() + file_path = os.path.join(rw_dir, "GitPython.spec") + open(file_path, 'wb').close() + assert repo.is_dirty() + repo.index.add(['0001-GPG-signature-support-on-commit-object.patch', 'GitPython.spec', '.gitignore', 'sources']) + repo.git.commit(m="committing file") + assert not repo.is_dirty() From ab7c3223076306ca71f692ed5979199863cf45a7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 7 Apr 2015 18:38:42 +0200 Subject: [PATCH 0181/2790] fix(externals): init external in dev mode only Previously it would always adjust your system path, which is bad behaviour. --- git/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git/__init__.py b/git/__init__.py index 5630b91d0..e8dae2723 100644 --- a/git/__init__.py +++ b/git/__init__.py @@ -15,7 +15,8 @@ #{ Initialization def _init_externals(): """Initialize external projects by putting them into the path""" - sys.path.append(os.path.join(os.path.dirname(__file__), 'ext', 'gitdb')) + if __version__ == 'git': + sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'ext', 'gitdb')) try: import gitdb From 8f043d8a1d7f4076350ff0c778bfa60f7aa2f7aa Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 09:50:26 +0200 Subject: [PATCH 0182/2790] fix(index): don't write extension data by default It turned out that the index is not actually corrupted, which is good news. What happens is that `git` writes `TREE` extension data into the index, which causes it to write out the given tree *as is* next time a `git commit` is executed. When using `git add`, this extension data is maintained automatically. However, GitPython doesn't do that ... . Usually this is no problem at all, as you are supposed to use `IndexFile.commit(...)` along with `IndexFile.add(...)`. Thanks to a shortcoming in the GitPython API, the index was automatically written out whenever files have been added, without providing control over whether or not *extension data* will be written along with it. My fix consists of an additional flag in `IndexFile.add(...)`, which causes extension data not to be written by default, so commits can be safely done via `git commit` or `IndexFile.commit(...)`. However, this might introduce new subtle bugs in case someone is relying on extension data to be written. As this can be controlled through the said flag though, a fix is easily done in that case. Fixes #265 --- doc/source/changes.rst | 6 ++++++ git/index/base.py | 37 +++++++++++++++++++++++++------------ git/test/test_index.py | 15 --------------- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 5b85e56ab..52d70c0f1 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,12 @@ Changelog ========= +0.3.7 - Fixes +============= +* `IndexFile.add()` will now write the index without any extension data by default. However, you may override this behaviour with the new `write_extension_data` keyword argument. + + - Renamed `ignore_tree_extension_data` keyword argument in `IndexFile.write(...)` to `ignore_extension_data` + 0.3.6 - Features ================ * **DOCS** diff --git a/git/index/base.py b/git/index/base.py index 733d4a63b..0553f418a 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -172,16 +172,17 @@ def _entries_sorted(self): """:return: list of entries, in a sorted fashion, first by path, then by stage""" return sorted(self.entries.values(), key=lambda e: (e.path, e.stage)) - def _serialize(self, stream, ignore_tree_extension_data=False): + def _serialize(self, stream, ignore_extension_data=False): entries = self._entries_sorted() - write_cache(entries, - stream, - (ignore_tree_extension_data and None) or self._extension_data) + extension_data = self._extension_data + if ignore_extension_data: + extension_data = None + write_cache(entries, stream, extension_data) return self #} END serializable interface - def write(self, file_path=None, ignore_tree_extension_data=False): + def write(self, file_path=None, ignore_extension_data=False): """Write the current state to our file path or to the given one :param file_path: @@ -190,9 +191,10 @@ def write(self, file_path=None, ignore_tree_extension_data=False): Please note that this will change the file_path of this index to the one you gave. - :param ignore_tree_extension_data: + :param ignore_extension_data: If True, the TREE type extension data read in the index will not - be written to disk. Use this if you have altered the index and + be written to disk. NOTE that no extension data is actually written. + Use this if you have altered the index and would like to use git-write-tree afterwards to create a tree representing your written changes. If this data is present in the written index, git-write-tree @@ -208,7 +210,7 @@ def write(self, file_path=None, ignore_tree_extension_data=False): lfd = LockedFD(file_path or self._file_path) stream = lfd.open(write=True, stream=True) - self._serialize(stream, ignore_tree_extension_data) + self._serialize(stream, ignore_extension_data) lfd.commit() @@ -612,7 +614,7 @@ def _entries_for_paths(self, paths, path_rewriter, fprogress, entries): return entries_added def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=None, - write=True): + write=True, write_extension_data=False): """Add files from the working tree, specific blobs or BaseIndexEntries to the index. @@ -689,8 +691,19 @@ def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=Non Please note that entry.path is relative to the git repository. :param write: - If True, the index will be written once it was altered. Otherwise - the changes only exist in memory and are not available to git commands. + If True, the index will be written once it was altered. Otherwise + the changes only exist in memory and are not available to git commands. + + :param write_extension_data: + If True, extension data will be written back to the index. This can lead to issues in case + it is containing the 'TREE' extension, which will cause the `git commit` command to write an + old tree, instead of a new one representing the now changed index. + This doesn't matter if you use `IndexFile.commit()`, which ignores the `TREE` extension altogether. + You should set it to True if you intend to use `IndexFile.commit()` exclusively while maintaining + support for third-party extensions. Besides that, you can usually safely ignore the built-in + extensions when using GitPython on repositories that are not handled manually at all. + All current built-in extensions are listed here: + http://opensource.apple.com/source/Git/Git-26/src/git-htmldocs/technical/index-format.txt :return: List(BaseIndexEntries) representing the entries just actually added. @@ -763,7 +776,7 @@ def handle_null_entries(self): self.entries[(entry.path, 0)] = IndexEntry.from_base(entry) if write: - self.write() + self.write(ignore_extension_data=not write_extension_data) # END handle write return entries_added diff --git a/git/test/test_index.py b/git/test/test_index.py index 8124ec164..63f99f109 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -44,11 +44,8 @@ BaseIndexEntry, IndexEntry ) -from gitdb.test.lib import with_rw_directory from git.index.fun import hook_path -import git - class TestIndex(TestBase): @@ -768,15 +765,3 @@ def test_index_bare_add(self, rw_bare_repo): except InvalidGitRepositoryError: asserted = True assert asserted, "Adding using a filename is not correctly asserted." - - @with_rw_directory - def test_index_add_corruption(self, rw_dir): - # Test for https://github.com/gitpython-developers/GitPython/issues/265 - repo = git.Repo.clone_from("git://pkgs.fedoraproject.org/GitPython", rw_dir) - assert not repo.is_dirty() - file_path = os.path.join(rw_dir, "GitPython.spec") - open(file_path, 'wb').close() - assert repo.is_dirty() - repo.index.add(['0001-GPG-signature-support-on-commit-object.patch', 'GitPython.spec', '.gitignore', 'sources']) - repo.git.commit(m="committing file") - assert not repo.is_dirty() From 98f6995bdcbd10ea0387d0c55cb6351b81a857fd Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 10:13:50 +0200 Subject: [PATCH 0183/2790] fix(index): _store_path() now closes it's stream This should prevent a resource warning given in py3 Fixes #263 --- git/index/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/git/index/base.py b/git/index/base.py index 0553f418a..10de3358a 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -579,6 +579,7 @@ def _store_path(self, filepath, fprogress): fprogress(filepath, False, filepath) istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream)) fprogress(filepath, True, filepath) + stream.close() return BaseIndexEntry((stat_mode_to_index_mode(st.st_mode), istream.binsha, 0, to_native_path_linux(filepath))) From 723f100a422577235e06dc024a73285710770fca Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 10:41:18 +0200 Subject: [PATCH 0184/2790] fix(docs): be clear about exit code handling When pushing/pulling, we ignore errors unless it's exit code 128. The reason for this is now made explicit to make clear that issues are handled by PushInfo flags accordingly. Related #271 --- git/test/lib/helper.py | 14 +++++++++++--- git/util.py | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 31bee78f6..541b972de 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -232,7 +232,13 @@ def remote_repo_creator(self): prev_cwd = os.getcwd() os.chdir(rw_repo.working_dir) try: - return func(self, rw_repo, rw_remote_repo) + try: + return func(self, rw_repo, rw_remote_repo) + except: + print("Keeping repos after failure: repo_dir = %s, remote_repo_dir = %s" + % (repo_dir, remote_repo_dir), file=sys.stderr) + repo_dir = remote_repo_dir = None + raise finally: # gd.proc.kill() ... no idea why that doesn't work if gd is not None: @@ -241,8 +247,10 @@ def remote_repo_creator(self): os.chdir(prev_cwd) rw_repo.git.clear_cache() rw_remote_repo.git.clear_cache() - shutil.rmtree(repo_dir, onerror=_rmtree_onerror) - shutil.rmtree(remote_repo_dir, onerror=_rmtree_onerror) + if repo_dir: + shutil.rmtree(repo_dir, onerror=_rmtree_onerror) + if remote_repo_dir: + shutil.rmtree(remote_repo_dir, onerror=_rmtree_onerror) if gd is not None: gd.proc.wait() diff --git a/git/util.py b/git/util.py index 02c54bc3e..f41f20fb4 100644 --- a/git/util.py +++ b/git/util.py @@ -159,6 +159,23 @@ def finalize_process(proc): except GitCommandError: # if a push has rejected items, the command has non-zero return status # a return status of 128 indicates a connection error - reraise the previous one + # Everything else will still be parsed and made available through PushInfo flags + # Estimated error results look like this: + # ```bash + # To /var/folders/xp/m48gs2tx2vg95tmtzw7tprs40000gn/T/tmpk5jeBeremote_repo_test_base + # ! refs/heads/master:refs/heads/master [rejected] (non-fast-forward) + # Done + # error: failed to push some refs to + # '/var/folders/xp/m48gs2tx2vg95tmtzw7tprs40000gn/T/tmpk5jeBeremote_repo_test_base' + # hint: Updates were rejected because the tip of your current branch is behind + # hint: its remote counterpart. Integrate the remote changes (e.g. + # hint: 'git pull ...') before pushing again. + # hint: See the 'Note about fast-forwards' in 'git push --help' for details. + # ``` + # See https://github.com/gitpython-developers/GitPython/blob/master/git/test/test_remote.py#L305 + # on how to check for these kinds of errors. + # Also see this issue for a reason for this verbosity: + # https://github.com/gitpython-developers/GitPython/issues/271 if proc.poll() == 128: raise pass From e9f8f159ebad405b2c08aa75f735146bb8e216ef Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 11:00:32 +0200 Subject: [PATCH 0185/2790] fix(remote): allow to raise during push/fetch Do not swallow non-zero exit status during push and fetch unless we managed to parse head information. This behaviour will effetively handle cases were no work was done due to invalid refspecs or insufficient permissions. Fixes #271 --- doc/source/changes.rst | 4 ++++ git/remote.py | 13 +++++++++++-- git/test/test_remote.py | 3 +-- git/util.py | 32 ++------------------------------ 4 files changed, 18 insertions(+), 34 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 52d70c0f1..35c2f15c3 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -7,6 +7,10 @@ Changelog * `IndexFile.add()` will now write the index without any extension data by default. However, you may override this behaviour with the new `write_extension_data` keyword argument. - Renamed `ignore_tree_extension_data` keyword argument in `IndexFile.write(...)` to `ignore_extension_data` +* If the git command executed during `Remote.push(...)|fetch(...)` returns with an non-zero exit code and GitPython didn't + obtain any head-information, the corresponding `GitCommandError` will be raised. This may break previous code which expected + these operations to never raise. However, that behavious is undesirable as it would effectively hide the fact that there + was an error. See `this issue `_ for more information. 0.3.6 - Features ================ diff --git a/git/remote.py b/git/remote.py index 6a15c9c4f..4baa2838c 100644 --- a/git/remote.py +++ b/git/remote.py @@ -568,7 +568,12 @@ def _get_fetch_info_from_stderr(self, proc, progress): # end # We are only interested in stderr here ... - finalize_process(proc) + try: + finalize_process(proc) + except Exception: + if len(fetch_info_lines) == 0: + raise + # end exception handler # read head information fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') @@ -601,7 +606,11 @@ def stdout_handler(line): # END exception handling # END for each line - handle_process_output(proc, stdout_handler, progress_handler, finalize_process) + try: + handle_process_output(proc, stdout_handler, progress_handler, finalize_process) + except Exception: + if len(output) == 0: + raise return output def fetch(self, refspec=None, progress=None, **kwargs): diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 8500a295a..c419ecee9 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -313,8 +313,7 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo): self._do_test_push_result(res, remote) # invalid refspec - res = remote.push("hellothere") - assert len(res) == 0 + self.failUnlessRaises(GitCommandError, remote.push, "hellothere") # push new tags progress = TestRemoteProgress() diff --git a/git/util.py b/git/util.py index f41f20fb4..1147cb535 100644 --- a/git/util.py +++ b/git/util.py @@ -16,10 +16,7 @@ # NOTE: Some of the unused imports might be used/imported by others. # Handle once test-cases are back up and running. -from .exc import ( - GitCommandError, - InvalidGitRepositoryError -) +from .exc import InvalidGitRepositoryError from .compat import ( MAXSIZE, @@ -154,32 +151,7 @@ def get_user_id(): def finalize_process(proc): """Wait for the process (clone, fetch, pull or push) and handle its errors accordingly""" - try: - proc.wait() - except GitCommandError: - # if a push has rejected items, the command has non-zero return status - # a return status of 128 indicates a connection error - reraise the previous one - # Everything else will still be parsed and made available through PushInfo flags - # Estimated error results look like this: - # ```bash - # To /var/folders/xp/m48gs2tx2vg95tmtzw7tprs40000gn/T/tmpk5jeBeremote_repo_test_base - # ! refs/heads/master:refs/heads/master [rejected] (non-fast-forward) - # Done - # error: failed to push some refs to - # '/var/folders/xp/m48gs2tx2vg95tmtzw7tprs40000gn/T/tmpk5jeBeremote_repo_test_base' - # hint: Updates were rejected because the tip of your current branch is behind - # hint: its remote counterpart. Integrate the remote changes (e.g. - # hint: 'git pull ...') before pushing again. - # hint: See the 'Note about fast-forwards' in 'git push --help' for details. - # ``` - # See https://github.com/gitpython-developers/GitPython/blob/master/git/test/test_remote.py#L305 - # on how to check for these kinds of errors. - # Also see this issue for a reason for this verbosity: - # https://github.com/gitpython-developers/GitPython/issues/271 - if proc.poll() == 128: - raise - pass - # END exception handling + proc.wait() #} END utilities From 1c2dd54358dd526d1d08a8e4a977f041aff74174 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 11:43:10 +0200 Subject: [PATCH 0186/2790] fix(cmd): throw GitCommandNotFoundError ... ... if it is not found. Previously, especially on windows, this wasn't explicit. Fixes #248, affects #126 --- doc/source/changes.rst | 5 +++++ git/cmd.py | 46 ++++++++++++++++++++++++++++++------------ git/exc.py | 6 ++++++ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 35c2f15c3..99b578bd8 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -12,6 +12,11 @@ Changelog these operations to never raise. However, that behavious is undesirable as it would effectively hide the fact that there was an error. See `this issue `_ for more information. +* If the git executable can't be found in the PATH or at the path provided by `GIT_PYTHON_GIT_EXECUTABLE`, this is made + obvious by throwing `GitCommandNotFound`, both on unix and on windows. + + - Those who support **GUI on windows** will now have to set `git.Git.USE_SHELL = True` to get the previous behaviour. + 0.3.6 - Features ================ * **DOCS** diff --git a/git/cmd.py b/git/cmd.py index 911bb9f36..429046be1 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -26,7 +26,10 @@ stream_copy, WaitGroup ) -from .exc import GitCommandError +from .exc import ( + GitCommandError, + GitCommandNotFound +) from git.compat import ( string_types, defenc, @@ -241,6 +244,12 @@ class Git(LazyMixin): _git_exec_env_var = "GIT_PYTHON_GIT_EXECUTABLE" GIT_PYTHON_GIT_EXECUTABLE = os.environ.get(_git_exec_env_var, git_exec_name) + # If True, a shell will be used when executing git commands. + # This should only be desirable on windows, see https://github.com/gitpython-developers/GitPython/pull/126 + # for more information + # Override this value using `Git.USE_SHELL = True` + USE_SHELL = False + class AutoInterrupt(object): """Kill/Interrupt the stored process instance once this instance goes out of scope. It is @@ -543,18 +552,29 @@ def execute(self, command, env["LC_MESSAGES"] = "C" env.update(self._environment) - proc = Popen(command, - env=env, - cwd=cwd, - stdin=istream, - stderr=PIPE, - stdout=PIPE, - # Prevent cmd prompt popups on windows by using a shell ... . - # See https://github.com/gitpython-developers/GitPython/pull/126 - shell=sys.platform == 'win32', - close_fds=(os.name == 'posix'), # unsupported on windows - **subprocess_kwargs - ) + if sys.platform == 'win32': + cmd_not_found_exception = WindowsError + else: + if sys.version_info[0] > 2: + cmd_not_found_exception = FileNotFoundError # NOQA # this is defined, but flake8 doesn't know + else: + cmd_not_found_exception = OSError + # end handle + + try: + proc = Popen(command, + env=env, + cwd=cwd, + stdin=istream, + stderr=PIPE, + stdout=PIPE, + shell=self.USE_SHELL, + close_fds=(os.name == 'posix'), # unsupported on windows + **subprocess_kwargs + ) + except cmd_not_found_exception as err: + raise GitCommandNotFound(str(err)) + if as_process: return self.AutoInterrupt(proc, command) diff --git a/git/exc.py b/git/exc.py index 7ee6726e8..f5b52374b 100644 --- a/git/exc.py +++ b/git/exc.py @@ -18,6 +18,12 @@ class NoSuchPathError(OSError): """ Thrown if a path could not be access by the system. """ +class GitCommandNotFound(Exception): + """Thrown if we cannot find the `git` executable in the PATH or at the path given by + the GIT_PYTHON_GIT_EXECUTABLE environment variable""" + pass + + class GitCommandError(Exception): """ Thrown if execution of the git command fails with non-zero status code. """ From a08733d76a8254a20a28f4c3875a173dcf0ad129 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 12:08:54 +0200 Subject: [PATCH 0187/2790] fix(test_cmd): handle GitCommandNotFound in test Related to #248 --- git/test/test_git.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index ef6947552..742c842db 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -19,6 +19,7 @@ from git import ( Git, GitCommandError, + GitCommandNotFound, Repo ) from gitdb.test.lib import with_rw_directory @@ -127,11 +128,7 @@ def test_version(self): def test_cmd_override(self): prev_cmd = self.git.GIT_PYTHON_GIT_EXECUTABLE - if os.name == 'nt': - exc = GitCommandError - else: - exc = OSError - # end handle windows case + exc = GitCommandNotFound try: # set it to something that doens't exist, assure it raises type(self.git).GIT_PYTHON_GIT_EXECUTABLE = os.path.join( From 6cc1e7e08094494916db1aadda17e03ce695d049 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 14:58:33 +0200 Subject: [PATCH 0188/2790] docs(tutorial): add pre-v2.3 GIT_SSH example It goes along with the new one advertising the GIT_SSH_COMMAND environment variable. Related to #256 --- doc/source/tutorial.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index e86fd8d57..84b3b5f50 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -331,11 +331,17 @@ You can easily access configuration information for a remote by accessing option :start-after: # [26-test_references_and_objects] :end-before: # ![26-test_references_and_objects] -You can also specify per-call custom environments using a new context manager on the Git command, e.g. for using a specific SSH key. +You can also specify per-call custom environments using a new context manager on the Git command, e.g. for using a specific SSH key. The following example works with `git` starting at *v2.3*. ssh_cmd = 'ssh -i id_deployment_key' with repo.git.custom_environment(GIT_SSH_COMMAND=ssh_cmd): repo.remotes.origin.fetch() + +This one sets a custom script to be executed in place of `ssh`, and can be used in `git` prior to *v2.3*. + + ssh_executable = os.path.join(rw_dir, 'my_ssh_executable.sh') + with repo.git.custom_environment(GIT_SSH=ssh_executable): + repo.remotes.origin.fetch() Submodule Handling ****************** From 545ac2574cfb75b02e407e814e10f76bc485926d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 15:05:23 +0200 Subject: [PATCH 0189/2790] docs(tutorial): fix GIT_SSH examples They didn't show up as code-block Related to #256 --- doc/source/tutorial.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 84b3b5f50..632d2d0cc 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -331,17 +331,19 @@ You can easily access configuration information for a remote by accessing option :start-after: # [26-test_references_and_objects] :end-before: # ![26-test_references_and_objects] -You can also specify per-call custom environments using a new context manager on the Git command, e.g. for using a specific SSH key. The following example works with `git` starting at *v2.3*. +You can also specify per-call custom environments using a new context manager on the Git command, e.g. for using a specific SSH key. The following example works with `git` starting at *v2.3*:: ssh_cmd = 'ssh -i id_deployment_key' with repo.git.custom_environment(GIT_SSH_COMMAND=ssh_cmd): repo.remotes.origin.fetch() -This one sets a custom script to be executed in place of `ssh`, and can be used in `git` prior to *v2.3*. +This one sets a custom script to be executed in place of `ssh`, and can be used in `git` prior to *v2.3*:: ssh_executable = os.path.join(rw_dir, 'my_ssh_executable.sh') with repo.git.custom_environment(GIT_SSH=ssh_executable): repo.remotes.origin.fetch() + +You might also have a look at `Git.update_environment(...)` in case you want to setup a changed environment more permanently. Submodule Handling ****************** From 3470e269bcdc9091d0c5e25e7c09ce175c7cee77 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 15:14:37 +0200 Subject: [PATCH 0190/2790] fix(version-up): v0.3.7 * milestone URL: http://goo.gl/HFaeZ4 --- VERSION | 2 +- doc/source/changes.rst | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 449d7e73a..0f8268533 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.6 +0.3.7 diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 99b578bd8..d9f44a86c 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -16,6 +16,9 @@ Changelog obvious by throwing `GitCommandNotFound`, both on unix and on windows. - Those who support **GUI on windows** will now have to set `git.Git.USE_SHELL = True` to get the previous behaviour. + +* A list of all issues can be found `on github `_ + 0.3.6 - Features ================ From 7f662857381a0384bd03d72d6132e0b23f52deef Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 15:41:26 +0200 Subject: [PATCH 0191/2790] fix(version-up): v1.0.0 This is just me being honest to myself, after all, GitPython is already version 3.0, considering that for me the leading zero was just historical baggage. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0f8268533..3eefcb9dd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.7 +1.0.0 From 21b0448b65317b2830270ff4156a25aca7941472 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 15:48:28 +0200 Subject: [PATCH 0192/2790] docs(changes): add 1.0.0 notes Just to declare the motivation behind this version jump, and state it is similar to v0.3.7. --- doc/source/changes.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index d9f44a86c..480f2c09f 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,13 @@ Changelog ========= +1.0.0 - Notes +============= + +This version is equivalent to v0.3.7, but finally acknowledges that GitPython is stable and production ready. + +It follows the `semantic version scheme `_, and thus will not break its existing API unless it goes 2.0. + 0.3.7 - Fixes ============= * `IndexFile.add()` will now write the index without any extension data by default. However, you may override this behaviour with the new `write_extension_data` keyword argument. From ae334e4d145f6787fd08e346a925bbc09e870341 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Apr 2015 15:50:53 +0200 Subject: [PATCH 0193/2790] docs(README): remove future goals Because there are none. --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index 1895635fd..6d21b45c7 100644 --- a/README.md +++ b/README.md @@ -87,14 +87,5 @@ Now that there seems to be a massive user base, this should be motivation enough * no open pull requests * no open issues describing bugs -#### FUTURE GOALS - -There has been a lot of work in the master branch, which is the direction I want git-python to go. Namely, it should be able to freely mix and match the back-end used, depending on your requirements and environment. - -* make new master work similarly to 0.3, but with the option to swap for at least one additional backend -* make a 1.0 release -* add backends as required - - [twitch-channel]: http://www.twitch.tv/byronimo/profile [youtube-playlist]: https://www.youtube.com/playlist?list=PLMHbQxe1e9MnoEcLhn6Yhv5KAvpWkJbL0 \ No newline at end of file From e129846a1a5344c8d7c0abe5ec52136c3a581cce Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 10 Apr 2015 19:33:52 +0200 Subject: [PATCH 0194/2790] docs(README): added code-climate badge We are not too good, but nothing to shy away from. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6d21b45c7..3bd6508eb 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ New BSD License. See the LICENSE file. ### DEVELOPMENT STATUS [![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg?branch=0.3)](https://travis-ci.org/gitpython-developers/GitPython) +[![Code Climate](https://codeclimate.com/github/gitpython-developers/GitPython/badges/gpa.svg)](https://codeclimate.com/github/gitpython-developers/GitPython) [![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=master)](https://coveralls.io/r/gitpython-developers/GitPython?branch=master) [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) [![Issue Stats](http://www.issuestats.com/github/gitpython-developers/GitPython/badge/pr)](http://www.issuestats.com/github/gitpython-developers/GitPython) From f9e7a3d93da741f81a5af2e84422376c54f1f337 Mon Sep 17 00:00:00 2001 From: Matt Jordan Date: Wed, 15 Apr 2015 12:42:41 -0500 Subject: [PATCH 0195/2790] fix(util): Handle 'Finding sources' messages in RemoteProgress When running a long running operation (such as a clone on a large repo), Git may return a message indicating that it is 'Finding sources'. Since there is no bit field value for this message, this causes a large amount of error messages to be emitted to stderr. This patch fixes this by adding another bit field value for this message, FINDING_SOURCES. Derived classes can look for this op_code and handle it appropriately. --- git/util.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/git/util.py b/git/util.py index 1147cb535..547da093f 100644 --- a/git/util.py +++ b/git/util.py @@ -165,7 +165,7 @@ class RemoteProgress(object): and git-fetch and to dispatch callbacks allowing subclasses to react to the progress. """ _num_op_codes = 7 - BEGIN, END, COUNTING, COMPRESSING, WRITING, RECEIVING, RESOLVING = [1 << x for x in range(_num_op_codes)] + BEGIN, END, COUNTING, COMPRESSING, WRITING, RECEIVING, RESOLVING, FINDING_SOURCES = [1 << x for x in range(_num_op_codes)] STAGE_MASK = BEGIN | END OP_MASK = ~STAGE_MASK @@ -227,6 +227,8 @@ def _parse_progress_line(self, line): op_code |= self.RECEIVING elif op_name == 'Resolving deltas': op_code |= self.RESOLVING + elif op_name == 'Finding sources': + op_code |= self.FINDING_SOURCES else: # Note: On windows it can happen that partial lines are sent # Hence we get something like "CompreReceiving objects", which is From 6d83f44007c5c581eae7ddc6c5de33311b7c1895 Mon Sep 17 00:00:00 2001 From: Matt Jordan Date: Wed, 15 Apr 2015 16:15:10 -0500 Subject: [PATCH 0196/2790] fix(util): Correct number of op codes The previous patch failed to update the expected number of op_codes, which would result in an exception when creating an instance of RemoteProgress. This patch corrects the value to the new expected number of op_codes (8) --- git/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/util.py b/git/util.py index 547da093f..ec605b0b4 100644 --- a/git/util.py +++ b/git/util.py @@ -164,7 +164,7 @@ class RemoteProgress(object): Handler providing an interface to parse progress information emitted by git-push and git-fetch and to dispatch callbacks allowing subclasses to react to the progress. """ - _num_op_codes = 7 + _num_op_codes = 8 BEGIN, END, COUNTING, COMPRESSING, WRITING, RECEIVING, RESOLVING, FINDING_SOURCES = [1 << x for x in range(_num_op_codes)] STAGE_MASK = BEGIN | END OP_MASK = ~STAGE_MASK From b89b089972b5bac824ac3de67b8a02097e7e95d7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 16 Apr 2015 09:09:26 +0200 Subject: [PATCH 0197/2790] fix(indent): flake-8 happyness --- git/util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git/util.py b/git/util.py index ec605b0b4..fb459da10 100644 --- a/git/util.py +++ b/git/util.py @@ -165,7 +165,8 @@ class RemoteProgress(object): and git-fetch and to dispatch callbacks allowing subclasses to react to the progress. """ _num_op_codes = 8 - BEGIN, END, COUNTING, COMPRESSING, WRITING, RECEIVING, RESOLVING, FINDING_SOURCES = [1 << x for x in range(_num_op_codes)] + BEGIN, END, COUNTING, COMPRESSING, WRITING, RECEIVING, RESOLVING, FINDING_SOURCES = \ + [1 << x for x in range(_num_op_codes)] STAGE_MASK = BEGIN | END OP_MASK = ~STAGE_MASK From abd23a37d8b93721c0e58e8c133cef26ed5ba1f0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 16 Apr 2015 09:12:13 +0200 Subject: [PATCH 0198/2790] fix(test_docs): we are at major version 1 now It expected to see major version 0 though. --- git/test/test_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 586f0ce4a..5b8aa8179 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -94,7 +94,7 @@ def test_init_repo_object(self, rw_dir): # [11-test_init_repo_object] assert now.commit.message != past.commit.message # You can read objects directly through binary streams, no working tree required - assert (now.commit.tree / 'VERSION').data_stream.read().decode('ascii').startswith('0') + assert (now.commit.tree / 'VERSION').data_stream.read().decode('ascii').startswith('1') # You can traverse trees as well to handle all contained files of a particular commit file_count = 0 From 2f233e2405c16e2b185aa90cc8e7ad257307b991 Mon Sep 17 00:00:00 2001 From: bradley Date: Fri, 17 Apr 2015 13:59:43 -0400 Subject: [PATCH 0199/2790] Changelog typo very small typo in changelog. Reop -> Repo --- doc/source/changes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 480f2c09f..d1b6cfd2e 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -360,7 +360,7 @@ General a treeish git cowardly refuses to pick one and asks for the command to use the unambiguous syntax where '--' seperates the treeish from the paths. -* ``Repo.commits``, ``Repo.commits_between``, ``Reop.commits_since``, +* ``Repo.commits``, ``Repo.commits_between``, ``Repo.commits_since``, ``Repo.commit_count``, ``Repo.commit``, ``Commit.count`` and ``Commit.find_all`` all now optionally take a path argument which constrains the lookup by path. This changes the order of the positional From bccdb483aaa7235b85a49f2c208ee1befd2706dd Mon Sep 17 00:00:00 2001 From: Benedikt Morbach Date: Tue, 21 Apr 2015 13:28:13 +0200 Subject: [PATCH 0200/2790] test: Make git-daemon only listen on localhost No reason to expose a daemon to all interfaces when it is only used for tests, which connect to localhost anyway. I'd love to use localhost here instead, but the git-daemon man page points out: If IPv6 is not supported, then --listen=hostname is also not supported and --listen must be given an IPv4 address. I don't know of a way to check if git has ipv6 support, but 127.0.0.1 should be around for the foreseeable future --- git/test/lib/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 541b972de..77ab82ff0 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -200,7 +200,7 @@ def remote_repo_creator(self): temp_dir = osp(_mktemp()) # On windows, this will fail ... we deal with failures anyway and default to telling the user to do it try: - gd = Git().daemon(temp_dir, enable='receive-pack', as_process=True) + gd = Git().daemon(temp_dir, enable='receive-pack', listen='127.0.0.1', as_process=True) # yes, I know ... fortunately, this is always going to work if sleep time is just large enough time.sleep(0.5) except Exception: From c1cedc5c417ddf3c2a955514dcca6fe74913259b Mon Sep 17 00:00:00 2001 From: Benedikt Morbach Date: Tue, 21 Apr 2015 13:45:02 +0200 Subject: [PATCH 0201/2790] test: make git-daemon port configurable via env add a GIT_PYTHON_TEST_GIT_DAEMON_PORT to set a port other than 9418, for example for when you already have a daemon running on that port. --- git/test/lib/helper.py | 10 +++++++--- git/test/test_remote.py | 5 +++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 77ab82ff0..8be2881c3 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -18,10 +18,11 @@ osp = os.path.dirname GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", osp(osp(osp(osp(__file__))))) +GIT_DAEMON_PORT = os.environ.get("GIT_PYTHON_TEST_GIT_DAEMON_PORT", "9418") __all__ = ( 'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter', - 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', 'GIT_REPO' + 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', 'GIT_REPO', 'GIT_DAEMON_PORT' ) #{ Routines @@ -193,14 +194,15 @@ def remote_repo_creator(self): # by the user, not by us d_remote = Remote.create(rw_repo, "daemon_origin", remote_repo_dir) d_remote.fetch() - remote_repo_url = "git://localhost%s" % remote_repo_dir + remote_repo_url = "git://localhost:%s%s" % (GIT_DAEMON_PORT, remote_repo_dir) d_remote.config_writer.set('url', remote_repo_url) temp_dir = osp(_mktemp()) # On windows, this will fail ... we deal with failures anyway and default to telling the user to do it try: - gd = Git().daemon(temp_dir, enable='receive-pack', listen='127.0.0.1', as_process=True) + gd = Git().daemon(temp_dir, enable='receive-pack', listen='127.0.0.1', port=GIT_DAEMON_PORT, + as_process=True) # yes, I know ... fortunately, this is always going to work if sleep time is just large enough time.sleep(0.5) except Exception: @@ -223,6 +225,8 @@ def remote_repo_creator(self): raise AssertionError(msg) else: msg = 'Please start a git-daemon to run this test, execute: git daemon --enable=receive-pack "%s"' + msg += 'You can also run the daemon on a different port by passing --port=' + msg += 'and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to ' msg %= temp_dir raise AssertionError(msg) # END make assertion diff --git a/git/test/test_remote.py b/git/test/test_remote.py index c419ecee9..af854988f 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -8,7 +8,8 @@ TestBase, with_rw_repo, with_rw_and_rw_remote_repo, - fixture + fixture, + GIT_DAEMON_PORT ) from git import ( RemoteProgress, @@ -250,7 +251,7 @@ def get_info(res, remote, name): # must clone with a local path for the repo implementation not to freak out # as it wants local paths only ( which I can understand ) other_repo = remote_repo.clone(other_repo_dir, shared=False) - remote_repo_url = "git://localhost%s" % remote_repo.git_dir + remote_repo_url = "git://localhost:%s%s" % (GIT_DAEMON_PORT, remote_repo.git_dir) # put origin to git-url other_origin = other_repo.remotes.origin From b9a2ea80aa9970bbd625da4c986d29a36c405629 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 22 Apr 2015 08:51:29 +0200 Subject: [PATCH 0202/2790] fix(config): selective cfg write;fix cfg parser * config parser now handles quoted values correctly. This doesn't hamper multi-line support. * added regression test to travis to assure we will be warned if we rewrite and break the user's .gitconfig file * only rewrite configuration files if we actually called a mutating method on the writer. Previously it would always rewrite it. Fixes #285 --- .travis.yml | 3 +++ git/config.py | 6 +++++- git/test/fixtures/.gitconfig | 3 +++ git/test/test_config.py | 15 +++++++++------ 4 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 git/test/fixtures/.gitconfig diff --git a/.travis.yml b/.travis.yml index b53228ca1..389780c7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,9 @@ install: # as commits are performed with the default user, it needs to be set for travis too - git config --global user.email "travis@ci.com" - git config --global user.name "Travis Runner" + # If we rewrite the user's config by accident, we will mess it up + # and cause subsequent tests to fail + - cp git/test/fixtures/.gitconfig ~/ script: # Make sure we limit open handles to see if we are leaking them - ulimit -n 96 diff --git a/git/config.py b/git/config.py index 38dd1b444..a6a25c7bb 100644 --- a/git/config.py +++ b/git/config.py @@ -81,6 +81,7 @@ def set_dirty_and_flush_changes(non_const_func): def flush_changes(self, *args, **kwargs): rval = non_const_func(self, *args, **kwargs) + self._dirty = True self.write() return rval # END wrapper method @@ -190,6 +191,7 @@ def __init__(self, file_or_files, read_only=True, merge_includes=True): self._file_or_files = file_or_files self._read_only = read_only + self._dirty = False self._is_initialized = False self._merge_includes = merge_includes self._lock = None @@ -304,7 +306,7 @@ def string_decode(v): if mo: # We might just have handled the last line, which could contain a quotation we want to remove optname, vi, optval = mo.group('option', 'vi', 'value') - if vi in ('=', ':') and ';' in optval: + if vi in ('=', ':') and ';' in optval and not optval.strip().startswith('"'): pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] @@ -433,6 +435,8 @@ def write(self): :raise IOError: if this is a read-only writer instance or if we could not obtain a file lock""" self._assure_writable("write") + if not self._dirty: + return if isinstance(self._file_or_files, (list, tuple)): raise AssertionError("Cannot write back if there is not exactly a single file to write to, have %i files" diff --git a/git/test/fixtures/.gitconfig b/git/test/fixtures/.gitconfig new file mode 100644 index 000000000..6a0459f6b --- /dev/null +++ b/git/test/fixtures/.gitconfig @@ -0,0 +1,3 @@ +[alias] + rbi = "!g() { git rebase -i origin/${1:-master} ; } ; g" + expush = "!f() { git branch -f tmp ; { git rbi $1 && git push ; } ; git reset --hard tmp ; git rebase origin/${1:-master}; } ; f" \ No newline at end of file diff --git a/git/test/test_config.py b/git/test/test_config.py index fc2b87b68..7758a094f 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -18,7 +18,6 @@ ) import io import os -from copy import copy from git.config import cp @@ -30,21 +29,18 @@ def _to_memcache(self, file_path): sio.name = file_path return sio - def _parsers_equal_or_raise(self, lhs, rhs): - pass - def test_read_write(self): # writer must create the exact same file as the one read before for filename in ("git_config", "git_config_global"): file_obj = self._to_memcache(fixture_path(filename)) - file_obj_orig = copy(file_obj) w_config = GitConfigParser(file_obj, read_only=False) w_config.read() # enforce reading assert w_config._sections w_config.write() # enforce writing # we stripped lines when reading, so the results differ - assert file_obj.getvalue() and file_obj.getvalue() != file_obj_orig.getvalue() + assert file_obj.getvalue() + self.assertEqual(file_obj.getvalue(), self._to_memcache(fixture_path(filename)).getvalue()) # creating an additional config writer must fail due to exclusive access self.failUnlessRaises(IOError, GitConfigParser, file_obj, read_only=False) @@ -207,3 +203,10 @@ def test_rename(self): assert not cw.has_section('core') assert len(cw.items(nn)) == 4 cw.release() + + def test_complex_aliases(self): + file_obj = self._to_memcache(fixture_path('.gitconfig')) + w_config = GitConfigParser(file_obj, read_only=False) + self.assertEqual(w_config.get('alias', 'rbi'), '"!g() { git rebase -i origin/${1:-master} ; } ; g"') + w_config.release() + self.assertEqual(file_obj.getvalue(), self._to_memcache(fixture_path('.gitconfig')).getvalue()) From 96928d2eb3d98c475fd0737240c06bf8e5f96ad6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 22 Apr 2015 09:05:24 +0200 Subject: [PATCH 0203/2790] fix(travis): can't overrwrite travis .gitconfig As it seems to contain custom inforamtion that we want to keep. Now we are appending to it ... --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 389780c7d..7aaf9f949 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ install: - git config --global user.name "Travis Runner" # If we rewrite the user's config by accident, we will mess it up # and cause subsequent tests to fail - - cp git/test/fixtures/.gitconfig ~/ + - cat git/test/fixtures/.gitconfig >> ~/.gitconfig script: # Make sure we limit open handles to see if we are leaking them - ulimit -n 96 From 2c594195eb614a200e1abb85706ec7b8b7c91268 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 22 Apr 2015 09:24:15 +0200 Subject: [PATCH 0204/2790] fix(versionup): release 1.0.1 --- VERSION | 2 +- doc/source/changes.rst | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3eefcb9dd..7dea76edb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 +1.0.1 diff --git a/doc/source/changes.rst b/doc/source/changes.rst index d1b6cfd2e..e6d7b09be 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,11 @@ Changelog ========= +1.0.1 - Fixes +============= + +* A list of all issues can be found `on github `_ + 1.0.0 - Notes ============= From 9563d27fbde02b8b2a8b0d808759cb235b4e083b Mon Sep 17 00:00:00 2001 From: "John L. Walker" Date: Wed, 13 May 2015 17:28:14 -0400 Subject: [PATCH 0205/2790] Fix type error (startswith expects bytes) --- git/objects/commit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/objects/commit.py b/git/objects/commit.py index f13760fdb..ac381cd93 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -445,7 +445,7 @@ def _deserialize(self, stream): next_line = readline() while next_line.startswith(b'mergetag '): next_line = readline() - while next_line.startswith(' '): + while next_line.startswith(b' '): next_line = readline() # end skip mergetags From 1199f90c523f170c377bf7a5ca04c2ccaab67e08 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 26 May 2015 13:25:25 +0200 Subject: [PATCH 0206/2790] docs(intro):swap mailinglist with stackoverflow --- doc/source/intro.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/source/intro.rst b/doc/source/intro.rst index b767ccd79..78d40344e 100644 --- a/doc/source/intro.rst +++ b/doc/source/intro.rst @@ -90,9 +90,11 @@ Finally verify the installation by running the `nose powered Date: Sun, 31 May 2015 14:48:47 +0200 Subject: [PATCH 0207/2790] fix(git-cmd): use LC_ALL instead of LC_MESSAGES Previously, only program messages where forced to the C-locale, now we force the entire program. That way, we should assure a remote will not provide us with branch information in any other language but english. Related to #290 --- git/cmd.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 429046be1..ee35bbcfe 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -530,7 +530,7 @@ def execute(self, command, * output_stream if extended_output = False * tuple(int(status), output_stream, str(stderr)) if extended_output = True - Note git is executed with LC_MESSAGES="C" to ensure consitent + Note git is executed with LC_MESSAGES="C" to ensure consistent output regardless of system language. :raise GitCommandError: @@ -549,7 +549,9 @@ def execute(self, command, # Start the process env = os.environ.copy() - env["LC_MESSAGES"] = "C" + # Attempt to force all output to plain ascii english, which is what some parsing code + # may expect. + env["LC_ALL"] = "C" env.update(self._environment) if sys.platform == 'win32': From 14851034ab5204ddb7329eb34bb0964d3f206f2b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 31 May 2015 15:02:10 +0200 Subject: [PATCH 0208/2790] fix(git-cmd): set LANGUAGE as well This is a pre-emptive measure based on http://goo.gl/l74GC8 . Related to #290 --- git/cmd.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git/cmd.py b/git/cmd.py index ee35bbcfe..87e482d82 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -551,6 +551,9 @@ def execute(self, command, env = os.environ.copy() # Attempt to force all output to plain ascii english, which is what some parsing code # may expect. + # According to stackoverflow (http://goo.gl/l74GC8), we are setting LANGUAGE as well + # just to be sure. + env["LANGUAGE"] = "C" env["LC_ALL"] = "C" env.update(self._environment) From c1d5c614c38db015485190d65db05b0b75d171d4 Mon Sep 17 00:00:00 2001 From: Hung Nguyen Viet Date: Mon, 1 Jun 2015 11:02:41 +0700 Subject: [PATCH 0209/2790] support passing odbt for using with Repo --- git/repo/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index e59cb0c7d..45550826c 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -737,7 +737,7 @@ def blame(self, rev, file): return blames @classmethod - def init(cls, path=None, mkdir=True, **kwargs): + def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs): """Initialize a git repository at the given path if specified :param path: @@ -762,7 +762,7 @@ def init(cls, path=None, mkdir=True, **kwargs): # git command automatically chdir into the directory git = Git(path) git.init(**kwargs) - return cls(path) + return cls(path, odbt=odbt) @classmethod def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): From 643e6369553759407ca433ed51a5a06b47e763d4 Mon Sep 17 00:00:00 2001 From: Hung Nguyen Viet Date: Mon, 1 Jun 2015 14:34:14 +0700 Subject: [PATCH 0210/2790] add docstring for new arg --- git/repo/base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/git/repo/base.py b/git/repo/base.py index 45550826c..c8915bbc4 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -750,6 +750,11 @@ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs): already exists. Creates the directory with a mode=0755. Only effective if a path is explicitly given + :param odbt: + Object DataBase type - a type which is constructed by providing + the directory containing the database objects, i.e. .git/objects. + It will be used to access all object data + :parm kwargs: keyword arguments serving as additional options to the git-init command From 1143e1c66b8b054a2fefca2a23b1f499522ddb76 Mon Sep 17 00:00:00 2001 From: Tomas Dabasinskas Date: Fri, 5 Jun 2015 12:59:45 +1000 Subject: [PATCH 0211/2790] Add example ssh script --- doc/source/tutorial.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 632d2d0cc..5110a2528 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -343,6 +343,14 @@ This one sets a custom script to be executed in place of `ssh`, and can be used with repo.git.custom_environment(GIT_SSH=ssh_executable): repo.remotes.origin.fetch() +Here's an executable used as GIT_SSH:: + + #!/bin/sh + ID_RSA=/var/lib/openshift/5562b947ecdd5ce939000038/app-deployments/id_rsa + exec /usr/bin/ssh -o StrictHostKeyChecking=no -i $ID_RSA "$@" + +Please note script must have executable permissions. StrictHostKeyChecking=no is used to avoid prompts asking to save hots key to ~/.ssh/known_hosts (this is in case you run this in some service) + You might also have a look at `Git.update_environment(...)` in case you want to setup a changed environment more permanently. Submodule Handling From 5385cbd969cc8727777d503a513ccee8372cd506 Mon Sep 17 00:00:00 2001 From: javex Date: Fri, 5 Jun 2015 11:25:23 +0200 Subject: [PATCH 0212/2790] Allow submodules to be ignored in is_dirty There are cases when might not consider a directory dirty when a submodule has changes. Particular case was git-up stashing changes where submodules are irrelevant. --- git/repo/base.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index e59cb0c7d..bb9fb72c1 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -563,7 +563,8 @@ def _set_alternates(self, alts): alternates = property(_get_alternates, _set_alternates, doc="Retrieve a list of alternates paths or set a list paths to be used as alternates") - def is_dirty(self, index=True, working_tree=True, untracked_files=False): + def is_dirty(self, index=True, working_tree=True, untracked_files=False, + consider_submodules=True): """ :return: ``True``, the repository is considered dirty. By default it will react @@ -575,7 +576,9 @@ def is_dirty(self, index=True, working_tree=True, untracked_files=False): return False # start from the one which is fastest to evaluate - default_args = ('--abbrev=40', '--full-index', '--raw') + default_args = ['--abbrev=40', '--full-index', '--raw'] + if not consider_submodules: + default_args.append('--ignore-submodules') if index: # diff index against HEAD if isfile(self.index.path) and \ @@ -588,7 +591,10 @@ def is_dirty(self, index=True, working_tree=True, untracked_files=False): return True # END working tree handling if untracked_files: - if len(self.untracked_files): + kwargs = {} + if not consider_submodules: + kwargs['ignore_submodules'] = True + if len(self._get_untracked_files(**kwargs)): return True # END untracked files return False @@ -604,10 +610,14 @@ def untracked_files(self): :note: ignored files will not appear here, i.e. files mentioned in .gitignore""" + return self._get_untracked_files() + + def _get_untracked_files(self, **kwargs): # make sure we get all files, no only untracked directores proc = self.git.status(porcelain=True, untracked_files=True, - as_process=True) + as_process=True, + **kwargs) # Untracked files preffix in porcelain mode prefix = "?? " untracked_files = list() From 3e79604c8bdfc367f10a4a522c9bf548bdb3ab9a Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Mon, 8 Jun 2015 18:19:34 -0700 Subject: [PATCH 0213/2790] While parsing errors, also detecting lines starting with error: --- git/remote.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/remote.py b/git/remote.py index 4baa2838c..485e1445d 100644 --- a/git/remote.py +++ b/git/remote.py @@ -555,7 +555,7 @@ def _get_fetch_info_from_stderr(self, proc, progress): line = line.decode(defenc) line = line.rstrip() for pline in progress_handler(line): - if line.startswith('fatal:'): + if line.startswith('fatal:') or line.startswith('error:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) # END handle special messages for cmd in cmds: From bafb4cc0a95428cbedaaa225abdceecee7533fac Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 10 Jun 2015 13:46:11 +0200 Subject: [PATCH 0214/2790] docs(tutorial): fix typo, minor improvements --- doc/source/tutorial.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 5110a2528..7cc296d83 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -343,13 +343,13 @@ This one sets a custom script to be executed in place of `ssh`, and can be used with repo.git.custom_environment(GIT_SSH=ssh_executable): repo.remotes.origin.fetch() -Here's an executable used as GIT_SSH:: +Here's an example executable that can be used in place of the `ssh_executable` above:: #!/bin/sh ID_RSA=/var/lib/openshift/5562b947ecdd5ce939000038/app-deployments/id_rsa exec /usr/bin/ssh -o StrictHostKeyChecking=no -i $ID_RSA "$@" -Please note script must have executable permissions. StrictHostKeyChecking=no is used to avoid prompts asking to save hots key to ~/.ssh/known_hosts (this is in case you run this in some service) +Please note that the script must be executable (i.e. `chomd +x script.sh`). `StrictHostKeyChecking=no` is used to avoid prompts asking to save the hosts key to `~/.ssh/known_hosts`, which happens in case you run this as daemon. You might also have a look at `Git.update_environment(...)` in case you want to setup a changed environment more permanently. From a771e102ec2238a60277e2dce68283833060fd37 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 10 Jun 2015 14:01:56 +0200 Subject: [PATCH 0215/2790] refactor(repo): parameter renaming and cleanup * renamed `consider_submodules` to `submodules` to be in line with the existing parameters. Nowadays I would prefer the `consider_` prefix, but can't change the existing API and thus stick to the current naming scheme. * reduced amount of code in one portion to make it more maintainable. Related to #294 --- git/repo/base.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index bb9fb72c1..f9d4ad6d3 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -564,7 +564,7 @@ def _set_alternates(self, alts): doc="Retrieve a list of alternates paths or set a list paths to be used as alternates") def is_dirty(self, index=True, working_tree=True, untracked_files=False, - consider_submodules=True): + submodules=True): """ :return: ``True``, the repository is considered dirty. By default it will react @@ -577,7 +577,7 @@ def is_dirty(self, index=True, working_tree=True, untracked_files=False, # start from the one which is fastest to evaluate default_args = ['--abbrev=40', '--full-index', '--raw'] - if not consider_submodules: + if not submodules: default_args.append('--ignore-submodules') if index: # diff index against HEAD @@ -591,10 +591,7 @@ def is_dirty(self, index=True, working_tree=True, untracked_files=False, return True # END working tree handling if untracked_files: - kwargs = {} - if not consider_submodules: - kwargs['ignore_submodules'] = True - if len(self._get_untracked_files(**kwargs)): + if len(self._get_untracked_files(ignore_submodules=not submodules)): return True # END untracked files return False From c8c696b3cf0c2441aefaef3592e2b815472f162a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 10 Jun 2015 14:18:33 +0200 Subject: [PATCH 0216/2790] fix(remote): don't close stdout on fetch/pull Reverted changes of `fe2fbc5~2`. This caused `git-pull` to error, which now actually results in a fatal error while fetching or pulling. Previously we simply didn't check for this issue. Now we are back to a `poll` based or threaded concurrent reading from stdout and stderr to prevent a git process deadlock, and the aforementioned error. Related to #297 --- git/remote.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/git/remote.py b/git/remote.py index 485e1445d..6126e3ccb 100644 --- a/git/remote.py +++ b/git/remote.py @@ -538,7 +538,6 @@ def update(self, **kwargs): def _get_fetch_info_from_stderr(self, proc, progress): # skip first line as it is some remote info we are not interested in - # TODO: Use poll() to process stdout and stderr at same time output = IterableList('name') # lines which are no progress are fetch info lines @@ -551,9 +550,7 @@ def _get_fetch_info_from_stderr(self, proc, progress): progress_handler = progress.new_message_handler() - for line in proc.stderr: - line = line.decode(defenc) - line = line.rstrip() + def my_progress_handler(line): for pline in progress_handler(line): if line.startswith('fatal:') or line.startswith('error:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) @@ -568,12 +565,7 @@ def _get_fetch_info_from_stderr(self, proc, progress): # end # We are only interested in stderr here ... - try: - finalize_process(proc) - except Exception: - if len(fetch_info_lines) == 0: - raise - # end exception handler + handle_process_output(proc, None, my_progress_handler, finalize_process) # read head information fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') @@ -593,7 +585,6 @@ def _get_push_info(self, proc, progress): # we hope stdout can hold all the data, it should ... # read the lines manually as it will use carriage returns between the messages # to override the previous one. This is why we read the bytes manually - # TODO: poll() on file descriptors to know what to read next, process streams concurrently progress_handler = progress.new_message_handler() output = IterableList('name') @@ -647,7 +638,6 @@ def fetch(self, refspec=None, progress=None, **kwargs): args = [refspec] proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, v=True, **kwargs) - proc.stdout.close() res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() @@ -663,7 +653,6 @@ def pull(self, refspec=None, progress=None, **kwargs): :return: Please see 'fetch' method """ kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) - proc.stdout.close() res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() From 982eefb2008826604d54c1a6622c12240efb0961 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 10 Jun 2015 15:10:27 +0200 Subject: [PATCH 0217/2790] fix(test_git): handle `select.poll()` missing In that case, the handler for processing stdout and stderr of the git process is offloaded to threads. These currently don't return any exception they raise. We could easily fix this using an approach as shown [here](http://goo.gl/hnVax6). --- git/test/test_git.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index 742c842db..a4172f7ac 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -192,10 +192,14 @@ def test_environment(self, rw_dir): rw_repo = Repo.init(os.path.join(rw_dir, 'repo')) remote = rw_repo.create_remote('ssh-origin', "ssh://git@server/foo") - with rw_repo.git.custom_environment(GIT_SSH=path): - try: - remote.fetch() - except GitCommandError as err: - assert 'FOO' in str(err) + # This only works if we are not evaluating git-push/pull output in a thread ! + import select + if hasattr(select, 'poll'): + with rw_repo.git.custom_environment(GIT_SSH=path): + try: + remote.fetch() + except GitCommandError as err: + assert 'FOO' in str(err) + # end # end - # end + # end if select.poll exists From 4a771adc5352dd3876dd2ef3d0c52c8e803fc084 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 10 Jun 2015 16:59:00 +0200 Subject: [PATCH 0218/2790] fix(remote): assert fetch respec is set It turns out we can't deal do fetches if no refspec is set as git will change the format of the fetch return values, providing less information than usual. A test was added to show that such a case will fail, and an assertion will assure we don't attempt to fetch/pull if there is no refspec for 'fetch'. Closes #296 --- git/remote.py | 14 ++++++++++++++ git/test/test_remote.py | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/git/remote.py b/git/remote.py index 6126e3ccb..c9da19791 100644 --- a/git/remote.py +++ b/git/remote.py @@ -604,6 +604,18 @@ def stdout_handler(line): raise return output + def _assert_refspec(self): + """Turns out we can't deal with remotes if the refspec is missing""" + config = self.config_reader + try: + if config.get_value('fetch', default=type) is type: + msg = "Remote '%s' has no refspec set.\n" + msg += "You can set it as follows:" + msg += " 'git config --add \"remote.%s.fetch +refs/heads/*:refs/heads/*\"'." % self.name + raise AssertionError(msg) + finally: + config.release() + def fetch(self, refspec=None, progress=None, **kwargs): """Fetch the latest changes for this remote @@ -631,6 +643,7 @@ def fetch(self, refspec=None, progress=None, **kwargs): :note: As fetch does not provide progress information to non-ttys, we cannot make it available here unfortunately as in the 'push' method.""" + self._assert_refspec() kwargs = add_progress(kwargs, self.repo.git, progress) if isinstance(refspec, list): args = refspec @@ -651,6 +664,7 @@ def pull(self, refspec=None, progress=None, **kwargs): :param progress: see 'push' method :param kwargs: Additional arguments to be passed to git-pull :return: Please see 'fetch' method """ + self._assert_refspec() kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) diff --git a/git/test/test_remote.py b/git/test/test_remote.py index af854988f..6c37614dd 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -494,6 +494,11 @@ def test_fetch_info(self): fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of " fetch_info_line_fmt += "git://github.com/gitpython-developers/GitPython" remote_info_line_fmt = "* [new branch] nomatter -> %s" + + self.failUnlessRaises(ValueError, FetchInfo._from_line, self.rorepo, + remote_info_line_fmt % "refs/something/branch", + "269c498e56feb93e408ed4558c8138d750de8893\t\t/Users/ben/test/foo\n") + fi = FetchInfo._from_line(self.rorepo, remote_info_line_fmt % "local/master", fetch_info_line_fmt % 'remote-tracking branch') From aa0ccead680443b07fd675f8b906758907bdb415 Mon Sep 17 00:00:00 2001 From: James Nowell Date: Thu, 25 Jun 2015 09:24:40 -0400 Subject: [PATCH 0219/2790] Added NullHandlers to all loggers to preven "No handler" messages When the code is run without setting up loggers, the loggers have no handlers for the emitted messages. The logging module displays: `No handlers could be found for logger "git.cmd"` on the console. By adding a NullHandler (a no-op) the message disappears, and doesn't affect logging when other handlers are configured. --- git/cmd.py | 1 + git/config.py | 1 + git/objects/commit.py | 1 + git/objects/submodule/base.py | 1 + git/objects/submodule/root.py | 1 + 5 files changed, 5 insertions(+) diff --git a/git/cmd.py b/git/cmd.py index 87e482d82..c0eeec0a5 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -44,6 +44,7 @@ 'output_stream') log = logging.getLogger('git.cmd') +log.addHandler(logging.NullHandler()) __all__ = ('Git', ) diff --git a/git/config.py b/git/config.py index a6a25c7bb..2d9adbdd9 100644 --- a/git/config.py +++ b/git/config.py @@ -32,6 +32,7 @@ log = logging.getLogger('git.config') +log.addHandler(logging.NullHandler()) class MetaParserBuilder(abc.ABCMeta): diff --git a/git/objects/commit.py b/git/objects/commit.py index ac381cd93..d301e3014 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -34,6 +34,7 @@ import logging log = logging.getLogger('git.objects.commit') +log.addHandler(logging.NullHandler()) __all__ = ('Commit', ) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index f9b0b6ad6..30201e090 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -43,6 +43,7 @@ log = logging.getLogger('git.objects.submodule.base') +log.addHandler(logging.NullHandler()) class UpdateProgress(RemoteProgress): diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index 1c863f6fb..4fe856c2c 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -13,6 +13,7 @@ __all__ = ["RootModule", "RootUpdateProgress"] log = logging.getLogger('git.objects.submodule.root') +log.addHandler(logging.NullHandler()) class RootUpdateProgress(UpdateProgress): From d1a9a232fbde88a347935804721ec7cd08de6f65 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 26 Jun 2015 09:17:19 +0200 Subject: [PATCH 0220/2790] fix(logging): monkeypatch logging with NullHandler This will make usage of the `NullHandler` possible in python 2.6 and below. --- git/util.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/git/util.py b/git/util.py index fb459da10..f0a08e799 100644 --- a/git/util.py +++ b/git/util.py @@ -13,6 +13,7 @@ import platform import getpass import threading +import logging # NOTE: Some of the unused imports might be used/imported by others. # Handle once test-cases are back up and running. @@ -753,3 +754,12 @@ def wait(self): while self.count > 0: self.cv.wait() self.cv.release() + + +class NullHandler(logging.Handler): + def emit(self, record): + pass + +# In Python 2.6, there is no NullHandler yet. Let's monkey-patch it for a workaround. +if not hasattr(logging, 'NullHandler'): + logging.NullHandler = NullHandler From cfc70fe92d42a853d4171943bde90d86061e3f3a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 26 Jun 2015 09:58:47 +0200 Subject: [PATCH 0221/2790] fix(index): handle adding symlinks to dirs When expanding directories, check if it is a symlink and don't expand them at all. Previously, we followed symlinks and expanded their contents, which could lead to weird index files. Fixes #302 --- git/index/base.py | 11 +++++++++++ git/test/test_index.py | 28 ++++++++++++++++------------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/git/index/base.py b/git/index/base.py index 10de3358a..f86968007 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -367,6 +367,17 @@ def raise_exc(e): abs_path = os.path.join(r, path) # END make absolute path + try: + st = os.lstat(abs_path) # handles non-symlinks as well + except OSError: + # the lstat call may fail as the path may contain globs as well + pass + else: + if S_ISLNK(st.st_mode): + yield abs_path.replace(rs, '') + continue + # end check symlink + # resolve globs if possible if '?' in path or '*' in path or '[' in path: for f in self._iter_expand_paths(glob.glob(abs_path)): diff --git a/git/test/test_index.py b/git/test/test_index.py index 63f99f109..8c3775d2b 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -542,18 +542,22 @@ def mixed_iterator(): # add symlink if sys.platform != "win32": - basename = "my_real_symlink" - target = "/etc/that" - link_file = os.path.join(rw_repo.working_tree_dir, basename) - os.symlink(target, link_file) - entries = index.reset(new_commit).add([link_file], fprogress=self._fprogress_add) - self._assert_entries(entries) - self._assert_fprogress(entries) - assert len(entries) == 1 and S_ISLNK(entries[0].mode) - assert S_ISLNK(index.entries[index.entry_key("my_real_symlink", 0)].mode) - - # we expect only the target to be written - assert index.repo.odb.stream(entries[0].binsha).read().decode('ascii') == target + for target in ('/etc/nonexisting', '/etc/passwd', '/etc'): + basename = "my_real_symlink" + + link_file = os.path.join(rw_repo.working_tree_dir, basename) + os.symlink(target, link_file) + entries = index.reset(new_commit).add([link_file], fprogress=self._fprogress_add) + self._assert_entries(entries) + self._assert_fprogress(entries) + assert len(entries) == 1 and S_ISLNK(entries[0].mode) + assert S_ISLNK(index.entries[index.entry_key("my_real_symlink", 0)].mode) + + # we expect only the target to be written + assert index.repo.odb.stream(entries[0].binsha).read().decode('ascii') == target + + os.remove(link_file) + # end for each target # END real symlink test # add fake symlink and assure it checks-our as symlink From f2efb814d0c3720f018f01329e43d9afa11ddf54 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 26 Jun 2015 10:45:35 +0200 Subject: [PATCH 0222/2790] docs(README): travis badge for master, not 0.3 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bd6508eb..f87cb0efe 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ New BSD License. See the LICENSE file. ### DEVELOPMENT STATUS -[![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg?branch=0.3)](https://travis-ci.org/gitpython-developers/GitPython) +[![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg)](https://travis-ci.org/gitpython-developers/GitPython) [![Code Climate](https://codeclimate.com/github/gitpython-developers/GitPython/badges/gpa.svg)](https://codeclimate.com/github/gitpython-developers/GitPython) [![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=master)](https://coveralls.io/r/gitpython-developers/GitPython?branch=master) [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) From 195ecc3da4a851734a853af6d739c21b44e0d7f0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 26 Jun 2015 10:46:39 +0200 Subject: [PATCH 0223/2790] fix(git-test): assure test does works on linux It shows that the previous implementation was never really working on linux, and thus failed on travis as well for good reason. Closes #303 --- git/test/test_git.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index a4172f7ac..51da5f975 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -199,7 +199,8 @@ def test_environment(self, rw_dir): try: remote.fetch() except GitCommandError as err: - assert 'FOO' in str(err) + assert 'ssh-origin' in str(err) + assert err.status == 128 # end # end # end if select.poll exists From 85a45a691ad068a4a25566cc1ed26db09d46daa4 Mon Sep 17 00:00:00 2001 From: Jon Lund Steffensen Date: Mon, 29 Jun 2015 18:57:27 -0400 Subject: [PATCH 0224/2790] Fix docstring of Repo.clone_from() --- git/repo/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/git/repo/base.py b/git/repo/base.py index 88e213797..03ef5a97e 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -853,6 +853,7 @@ def clone(self, path, progress=None, **kwargs): @classmethod def clone_from(cls, url, to_path, progress=None, **kwargs): """Create a clone from the given URL + :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS :param to_path: Path to which the repository should be cloned to :param progress: See 'git.remote.Remote.push'. From 2c0f47b3076a84c5c32cccc95748f18c50e3d948 Mon Sep 17 00:00:00 2001 From: Jon Lund Steffensen Date: Tue, 30 Jun 2015 17:04:18 -0400 Subject: [PATCH 0225/2790] Add env parameter to Repo.clone_from() for setting environment variables Adds the optional keyword parameter env to Repo.clone_from(). The parameter is a dictionary containing the desired environment variables for the git clone invocation. The environment is applied to the temporary Git instance before calling Repo._clone(). --- git/repo/base.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index 03ef5a97e..2783e2a4e 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -851,15 +851,19 @@ def clone(self, path, progress=None, **kwargs): return self._clone(self.git, self.git_dir, path, type(self.odb), progress, **kwargs) @classmethod - def clone_from(cls, url, to_path, progress=None, **kwargs): + def clone_from(cls, url, to_path, progress=None, env=None, **kwargs): """Create a clone from the given URL :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS :param to_path: Path to which the repository should be cloned to :param progress: See 'git.remote.Remote.push'. + :param env: Optional dictionary containing the desired environment variables. :param kwargs: see the ``clone`` method :return: Repo instance pointing to the cloned directory""" - return cls._clone(Git(os.getcwd()), url, to_path, GitCmdObjectDB, progress, **kwargs) + git = Git(os.getcwd()) + if env is not None: + git.update_environment(**env) + return cls._clone(git, url, to_path, GitCmdObjectDB, progress, **kwargs) def archive(self, ostream, treeish=None, prefix=None, **kwargs): """Archive the tree at the given revision. From 040108747e2f868c61f870799a78850b792ddd0a Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 11:43:40 +0200 Subject: [PATCH 0226/2790] fix(cmd): line parsing * Previously we could fail to parse the last line within a read buffer, which is now fixed. * Added a test to verify our *slow* line parsing works as expected. --- git/cmd.py | 149 +- git/test/fixtures/issue-301_FETCH_HEAD | 5001 +++++++++++++++++++++++ git/test/fixtures/issue-301_stderr | 5002 ++++++++++++++++++++++++ git/test/test_git.py | 17 + 4 files changed, 10101 insertions(+), 68 deletions(-) create mode 100644 git/test/fixtures/issue-301_FETCH_HEAD create mode 100644 git/test/fixtures/issue-301_stderr diff --git a/git/cmd.py b/git/cmd.py index c0eeec0a5..ec916d8aa 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -65,6 +65,84 @@ def _bchr(c): # Documentation ## @{ +def _parse_lines_from_buffer(buf): + line = b'' + bi = 0 + lb = len(buf) + while bi < lb: + char = _bchr(buf[bi]) + bi += 1 + + if char in (b'\r', b'\n') and line: + yield bi, line + line = b'' + else: + line += char + # END process parsed line + # END while file is not done reading +# end + +def _read_lines_from_fno(fno, last_buf_list): + buf = os.read(fno, mmap.PAGESIZE) + buf = last_buf_list[0] + buf + + bi = 0 + for bi, line in _parse_lines_from_buffer(buf): + yield line + # for each line to parse from the buffer + + # keep remainder + last_buf_list[0] = buf[bi:] + +def _dispatch_single_line(line, handler): + line = line.decode(defenc) + if line and handler: + try: + handler(line) + except Exception: + # Keep reading, have to pump the lines empty nontheless + log.error("Line handler exception on line: %s", line, exc_info=True) + # end + # end dispatch helper +# end single line helper + +def _dispatch_lines(fno, handler, buf_list): + lc = 0 + last_buf = buf_list[0] + while True: + for line in _read_lines_from_fno(fno, buf_list): + _dispatch_single_line(line, handler) + lc += 1 + # for each line + + if last_buf == buf_list[0]: + break + + last_buf = buf_list[0] + # end endless loop + return lc +# end + +def _deplete_buffer(fno, handler, buf_list, wg=None): + lc = 0 + while True: + line_count = _dispatch_lines(fno, handler, buf_list) + lc += line_count + if line_count == 0: + break + # end deplete buffer + + if buf_list[0]: + _dispatch_single_line(buf_list[0], handler) + lc += 1 + # end + + if wg: + wg.done() + + return lc +# end + def handle_process_output(process, stdout_handler, stderr_handler, finalizer): """Registers for notifications to lean that process output is ready to read, and dispatches lines to the respective line handlers. We are able to handle carriage returns in case progress is sent by that @@ -75,71 +153,6 @@ def handle_process_output(process, stdout_handler, stderr_handler, finalizer): :param stdout_handler: f(stdout_line_string), or None :param stderr_hanlder: f(stderr_line_string), or None :param finalizer: f(proc) - wait for proc to finish""" - def parse_lines_from_buffer(fno, buf): - line = b'' - bi = 0 - lb = len(buf) - while bi < lb: - char = _bchr(buf[bi]) - bi += 1 - - if char in (b'\r', b'\n') and line: - yield bi, line - line = b'' - else: - line += char - # END process parsed line - # END while file is not done reading - # end - - def read_lines_from_fno(fno, last_buf_list): - buf = os.read(fno, mmap.PAGESIZE) - buf = last_buf_list[0] + buf - - bi = 0 - for bi, line in parse_lines_from_buffer(fno, buf): - yield line - # for each line to parse from the buffer - - # keep remainder - last_buf_list[0] = buf[bi:] - - def dispatch_single_line(line, handler): - line = line.decode(defenc) - if line and handler: - try: - handler(line) - except Exception: - # Keep reading, have to pump the lines empty nontheless - log.error("Line handler exception on line: %s", line, exc_info=True) - # end - # end dispatch helper - # end single line helper - - def dispatch_lines(fno, handler, buf_list): - lc = 0 - for line in read_lines_from_fno(fno, buf_list): - dispatch_single_line(line, handler) - lc += 1 - # for each line - return lc - # end - - def deplete_buffer(fno, handler, buf_list, wg=None): - while True: - line_count = dispatch_lines(fno, handler, buf_list) - if line_count == 0: - break - # end deplete buffer - - if buf_list[0]: - dispatch_single_line(buf_list[0], handler) - # end - - if wg: - wg.done() - # end - fdmap = {process.stdout.fileno(): (stdout_handler, [b'']), process.stderr.fileno(): (stderr_handler, [b''])} @@ -169,7 +182,7 @@ def deplete_buffer(fno, handler, buf_list, wg=None): if result & CLOSED: closed_streams.add(fd) else: - dispatch_lines(fd, *fdmap[fd]) + _dispatch_lines(fd, *fdmap[fd]) # end handle closed stream # end for each poll-result tuple @@ -180,7 +193,7 @@ def deplete_buffer(fno, handler, buf_list, wg=None): # Depelete all remaining buffers for fno, (handler, buf_list) in fdmap.items(): - deplete_buffer(fno, handler, buf_list) + _deplete_buffer(fno, handler, buf_list) # end for each file handle for fno in fdmap.keys(): @@ -194,7 +207,7 @@ def deplete_buffer(fno, handler, buf_list, wg=None): wg = WaitGroup() for fno, (handler, buf_list) in fdmap.items(): wg.add(1) - t = threading.Thread(target=lambda: deplete_buffer(fno, handler, buf_list, wg)) + t = threading.Thread(target=lambda: _deplete_buffer(fno, handler, buf_list, wg)) t.start() # end # NOTE: Just joining threads can possibly fail as there is a gap between .start() and when it's diff --git a/git/test/fixtures/issue-301_FETCH_HEAD b/git/test/fixtures/issue-301_FETCH_HEAD new file mode 100644 index 000000000..17a81664d --- /dev/null +++ b/git/test/fixtures/issue-301_FETCH_HEAD @@ -0,0 +1,5001 @@ +f78f35d9dab6228d31f5767733ad7a35abb66eb5 branch 'master' of github.com:jantman/gitpython_issue_301 +813bb61a2f1fb04814b7f15145881ea73cd133cc not-for-merge branch 'testcommit1' of github.com:jantman/gitpython_issue_301 +74b231851fb084c47066e7e7648a14136c7c299d not-for-merge branch 'testcommit10' of github.com:jantman/gitpython_issue_301 +1cb5483706293ea69fafb91c786234e6e65ad689 not-for-merge branch 'testcommit100' of github.com:jantman/gitpython_issue_301 +0d82e65448bcc2c6682b21cf85f7c96ed040df70 not-for-merge branch 'testcommit1000' of github.com:jantman/gitpython_issue_301 +057f1fdad7209439aa9114f0262fb9c4d33200d0 not-for-merge branch 'testcommit1001' of github.com:jantman/gitpython_issue_301 +15d69d4aee5526eb411e54dc397134dee26b2283 not-for-merge branch 'testcommit1002' of github.com:jantman/gitpython_issue_301 +b0e2c328992b65ec1fd6208caa4a3dd4cc37f9d7 not-for-merge branch 'testcommit1003' of github.com:jantman/gitpython_issue_301 +87060a7536049854ef45968da61f5770abdaedc4 not-for-merge branch 'testcommit1004' of github.com:jantman/gitpython_issue_301 +d8d3f321891ca92ee293d06ed87a064a1fe62677 not-for-merge branch 'testcommit1005' of github.com:jantman/gitpython_issue_301 +7115c362226c07137043eed46b2e5a98a69cc43f not-for-merge branch 'testcommit1006' of github.com:jantman/gitpython_issue_301 +ba5f552c10b5c8508d83ed32ac5bf67001629b20 not-for-merge branch 'testcommit1007' of github.com:jantman/gitpython_issue_301 +03fde1b9f89ecf6a785517163f16005119fc680e not-for-merge branch 'testcommit1008' of github.com:jantman/gitpython_issue_301 +b6ae330511eaac90bb3c845e955c886a777568e7 not-for-merge branch 'testcommit1009' of github.com:jantman/gitpython_issue_301 +fae4350e6e080b5a02b37acd8b82b4c5b6562549 not-for-merge branch 'testcommit101' of github.com:jantman/gitpython_issue_301 +a291c06e6ab3aa92ecc4016038f2d917522cbe57 not-for-merge branch 'testcommit1010' of github.com:jantman/gitpython_issue_301 +dd5bbd0857ed5b6065c241f55319f7390e3db09c not-for-merge branch 'testcommit1011' of github.com:jantman/gitpython_issue_301 +d64ea9fbb015aa75e8b0baabc0a139c65a473526 not-for-merge branch 'testcommit1012' of github.com:jantman/gitpython_issue_301 +5b82157edda8f2a2ef46b15e386d4c616eab3226 not-for-merge branch 'testcommit1013' of github.com:jantman/gitpython_issue_301 +1e54cf4e8bbc10acab0a376276ae54076c68200f not-for-merge branch 'testcommit1014' of github.com:jantman/gitpython_issue_301 +c132323053db7a8ee9f20476b3b40277fe1005b7 not-for-merge branch 'testcommit1015' of github.com:jantman/gitpython_issue_301 +68f5e4e2e2901044a58443b72c55acd15a30cb5d not-for-merge branch 'testcommit1016' of github.com:jantman/gitpython_issue_301 +a49783e1fb03a15e9d57888821a41d49ee5d9753 not-for-merge branch 'testcommit1017' of github.com:jantman/gitpython_issue_301 +c7d0e081d606dea226968d51277dc2c9a02583eb not-for-merge branch 'testcommit1018' of github.com:jantman/gitpython_issue_301 +33de4b6e4e3fe03893686549e855751e65fe0d3e not-for-merge branch 'testcommit1019' of github.com:jantman/gitpython_issue_301 +2a58c9b7e1b797cc978f9dbcfd896ac4520725aa not-for-merge branch 'testcommit102' of github.com:jantman/gitpython_issue_301 +c66ae862a6acd990e11ec0d2fdf99449930c61a4 not-for-merge branch 'testcommit1020' of github.com:jantman/gitpython_issue_301 +a306c22db519841f9457c13bf63ac1d4d2c436ac not-for-merge branch 'testcommit1021' of github.com:jantman/gitpython_issue_301 +7e4f0c9300a171e3d3dea6120d5826ac2a750f58 not-for-merge branch 'testcommit1022' of github.com:jantman/gitpython_issue_301 +1a30379b859495d9ff8c1ed612c1d9fc17000541 not-for-merge branch 'testcommit1023' of github.com:jantman/gitpython_issue_301 +f35d38a1c6e4ba013f3fbcd9b833152038bf4b2b not-for-merge branch 'testcommit1024' of github.com:jantman/gitpython_issue_301 +a23ec8ef4e5591c19a1160826cd1707edcc323ff not-for-merge branch 'testcommit1025' of github.com:jantman/gitpython_issue_301 +086c8dc0652cf0872decec7ec15f568b692f2b79 not-for-merge branch 'testcommit1026' of github.com:jantman/gitpython_issue_301 +fbec4b838cff070bfa44262d92bd3348aa0c49df not-for-merge branch 'testcommit1027' of github.com:jantman/gitpython_issue_301 +e1db0463d7d4b9b879193e287cfb3e57afad8545 not-for-merge branch 'testcommit1028' of github.com:jantman/gitpython_issue_301 +daf9d90c758f46d1eaeedbdd9777765eeeb41b16 not-for-merge branch 'testcommit1029' of github.com:jantman/gitpython_issue_301 +e4a78df9c577229cb8e4e19c5fd68f861e6bcd54 not-for-merge branch 'testcommit103' of github.com:jantman/gitpython_issue_301 +ca2bd8768ddf3353366ded2cb0c45a2378415728 not-for-merge branch 'testcommit1030' of github.com:jantman/gitpython_issue_301 +3bd79462e516e4b6042edde2247db47dc6998cee not-for-merge branch 'testcommit1031' of github.com:jantman/gitpython_issue_301 +0b5c7a6c18d0dad345f9c862c34a053ba3ff03dd not-for-merge branch 'testcommit1032' of github.com:jantman/gitpython_issue_301 +133a759b81ec33386d55e1abdc6b175512ebd7be not-for-merge branch 'testcommit1033' of github.com:jantman/gitpython_issue_301 +ff11d39a567ca85619fecd22665ce0111d9f5bf3 not-for-merge branch 'testcommit1034' of github.com:jantman/gitpython_issue_301 +b474a98c90debc1aa1c78e53fdafd2fa46b5c507 not-for-merge branch 'testcommit1035' of github.com:jantman/gitpython_issue_301 +51a6e4eaedee9cd13c5df6fbb32dfce7c57d5126 not-for-merge branch 'testcommit1036' of github.com:jantman/gitpython_issue_301 +dfe09cab749db84038eee918e71706030ab5b1be not-for-merge branch 'testcommit1037' of github.com:jantman/gitpython_issue_301 +0867b340c832c30f63196bc69fb88fd14ff3b6c2 not-for-merge branch 'testcommit1038' of github.com:jantman/gitpython_issue_301 +9485d0cc1dee71fc8c9faac84eb9d29768d03b2b not-for-merge branch 'testcommit1039' of github.com:jantman/gitpython_issue_301 +e88c09f111fd3922e7ccf44660afbe169f3f1eeb not-for-merge branch 'testcommit104' of github.com:jantman/gitpython_issue_301 +36c52368b69c03153dab376f915cbf8e7630dc7e not-for-merge branch 'testcommit1040' of github.com:jantman/gitpython_issue_301 +cd82e0f6ee3c171011228cb2e8f363a9da925fb8 not-for-merge branch 'testcommit1041' of github.com:jantman/gitpython_issue_301 +4f49ea944a6c0c398220b90378370c105170046f not-for-merge branch 'testcommit1042' of github.com:jantman/gitpython_issue_301 +1917539f10f2b4838ef2f994eb10a1d460a0f650 not-for-merge branch 'testcommit1043' of github.com:jantman/gitpython_issue_301 +82e70e8e03b24a24a0373f4192d8aecc9f1cd172 not-for-merge branch 'testcommit1044' of github.com:jantman/gitpython_issue_301 +92b53b8ae31d0629dc47b8f1c26404c7746d02f2 not-for-merge branch 'testcommit1045' of github.com:jantman/gitpython_issue_301 +1708c4ea98cece372c63d3351a036e6a7f2cd888 not-for-merge branch 'testcommit1046' of github.com:jantman/gitpython_issue_301 +775a094cad4abd26b46f3bd76983720f0f7555a7 not-for-merge branch 'testcommit1047' of github.com:jantman/gitpython_issue_301 +62f14aec2a95e69f2f6cefae5a169a2213f0979a not-for-merge branch 'testcommit1048' of github.com:jantman/gitpython_issue_301 +a89a06c658550fbf08f7febeb879a18e8cd0d0ea not-for-merge branch 'testcommit1049' of github.com:jantman/gitpython_issue_301 +e6dc222522a5bd977c1ac0c7fe6da6d2266c63e4 not-for-merge branch 'testcommit105' of github.com:jantman/gitpython_issue_301 +081d87eac78da472a5ffc0fe0f2dc291ebb149e9 not-for-merge branch 'testcommit1050' of github.com:jantman/gitpython_issue_301 +cbc215ca6c83abdc61551a836d7a28904a62d085 not-for-merge branch 'testcommit1051' of github.com:jantman/gitpython_issue_301 +c217b655f666dcef95f2c7d94a347142f64dc8e7 not-for-merge branch 'testcommit1052' of github.com:jantman/gitpython_issue_301 +1a2639fe5bb81d58fc1e440cd0de13542f30ede0 not-for-merge branch 'testcommit1053' of github.com:jantman/gitpython_issue_301 +e26f97c6030a35eecf7529db67891b2a5e62fc65 not-for-merge branch 'testcommit1054' of github.com:jantman/gitpython_issue_301 +21ef95611a661a26982384eca4d6de1deec05019 not-for-merge branch 'testcommit1055' of github.com:jantman/gitpython_issue_301 +45cddb9b4249654b010ec2eb1bf8e0335f790a71 not-for-merge branch 'testcommit1056' of github.com:jantman/gitpython_issue_301 +7be0d0f80bdef478e0b7c807385eecdee966cd36 not-for-merge branch 'testcommit1057' of github.com:jantman/gitpython_issue_301 +657248968c110f9fb1176fc6a7885edf65cd15d8 not-for-merge branch 'testcommit1058' of github.com:jantman/gitpython_issue_301 +47b6e1ce23a3825ae5562028f627da4fc16b0e6a not-for-merge branch 'testcommit1059' of github.com:jantman/gitpython_issue_301 +30b94663b5f4cbef4851cb4f6e8cee8c773fc1f6 not-for-merge branch 'testcommit106' of github.com:jantman/gitpython_issue_301 +360052485cbc5662afa083468e54b6d510076a06 not-for-merge branch 'testcommit1060' of github.com:jantman/gitpython_issue_301 +058a069963bc1140c31d0f29c39d635b0470a075 not-for-merge branch 'testcommit1061' of github.com:jantman/gitpython_issue_301 +be9d2205c3435645fbeb619825650bf3e608528a not-for-merge branch 'testcommit1062' of github.com:jantman/gitpython_issue_301 +cb1d7c4180bbfe8048b16081b49cce7d459f76a5 not-for-merge branch 'testcommit1063' of github.com:jantman/gitpython_issue_301 +a18d81ab79bfd95a0db0186ec98bfa69e2110fd5 not-for-merge branch 'testcommit1064' of github.com:jantman/gitpython_issue_301 +d77a1368f70c8bcb861646b3671d00979f3eb9b3 not-for-merge branch 'testcommit1065' of github.com:jantman/gitpython_issue_301 +7f37ec5d5dd7c8ae9ddc384b01bb96e10dc1aec7 not-for-merge branch 'testcommit1066' of github.com:jantman/gitpython_issue_301 +405505546f113b75d9b802cb8141595275a2efcb not-for-merge branch 'testcommit1067' of github.com:jantman/gitpython_issue_301 +27c56c91701905fa665f1fced077332e46e873df not-for-merge branch 'testcommit1068' of github.com:jantman/gitpython_issue_301 +afbb0a989463065043e6a4b2346e380c80294221 not-for-merge branch 'testcommit1069' of github.com:jantman/gitpython_issue_301 +6b30eeeb7b070b6c27edebc96973249f8225ed91 not-for-merge branch 'testcommit107' of github.com:jantman/gitpython_issue_301 +b11e6d299ea7e12939ced678695dee2050dc9edb not-for-merge branch 'testcommit1070' of github.com:jantman/gitpython_issue_301 +4c3de2f4ada98d216fc053a0187159f8bcffbb07 not-for-merge branch 'testcommit1071' of github.com:jantman/gitpython_issue_301 +e4b1931a7d5746c3b1d1a8f0c0275c501cda16bd not-for-merge branch 'testcommit1072' of github.com:jantman/gitpython_issue_301 +2bf742d78ade4aeffd07c6f18fc834f5e2885d8d not-for-merge branch 'testcommit1073' of github.com:jantman/gitpython_issue_301 +3da6bf729de2650f17c0cd68350549d51c4ce5d5 not-for-merge branch 'testcommit1074' of github.com:jantman/gitpython_issue_301 +b98266702d45a342e9717b4051bf40aa00376767 not-for-merge branch 'testcommit1075' of github.com:jantman/gitpython_issue_301 +032f33390c64f58e6d7c7f30d130c2254fd2daac not-for-merge branch 'testcommit1076' of github.com:jantman/gitpython_issue_301 +665c4528e45a6cbb6bb77dc0abf25a396459f3f0 not-for-merge branch 'testcommit1077' of github.com:jantman/gitpython_issue_301 +c2521839c44c1c2f9b2cb421927c09637ad86a09 not-for-merge branch 'testcommit1078' of github.com:jantman/gitpython_issue_301 +c6baebe98130dfa62a85d34237711af6fc751b66 not-for-merge branch 'testcommit1079' of github.com:jantman/gitpython_issue_301 +711f48c1dc1bf9a0fe7d7dfdd4bbeb8d90756a24 not-for-merge branch 'testcommit108' of github.com:jantman/gitpython_issue_301 +d01f1a495c951de18dc9c63072ad1452a474a37f not-for-merge branch 'testcommit1080' of github.com:jantman/gitpython_issue_301 +ce21f34ce9171e7671213e70594301a96c28eef7 not-for-merge branch 'testcommit1081' of github.com:jantman/gitpython_issue_301 +5f0e3ca0aa91eb6cf87a8a1522e7b349e9786651 not-for-merge branch 'testcommit1082' of github.com:jantman/gitpython_issue_301 +31482a712ef4f499376c09e6e6db34e28d25a2bd not-for-merge branch 'testcommit1083' of github.com:jantman/gitpython_issue_301 +4cb0da37944358fa42bcee36dac42f2999d1d96c not-for-merge branch 'testcommit1084' of github.com:jantman/gitpython_issue_301 +17df70989870fea0d0f8a64b55ed8b62bf430541 not-for-merge branch 'testcommit1085' of github.com:jantman/gitpython_issue_301 +7cac5985ca2795958bfa9ff8489f055d768d5c2b not-for-merge branch 'testcommit1086' of github.com:jantman/gitpython_issue_301 +606bffc22073d5d42042ea3d33be235458bbbef6 not-for-merge branch 'testcommit1087' of github.com:jantman/gitpython_issue_301 +30b0e5295a1d82e3401a88097784f0d1939c1666 not-for-merge branch 'testcommit1088' of github.com:jantman/gitpython_issue_301 +3d0e8effe1aae0591459621b5fdcd5fdb7f7ad53 not-for-merge branch 'testcommit1089' of github.com:jantman/gitpython_issue_301 +4289c5f725b6c51b64399bf43d4bd55969225146 not-for-merge branch 'testcommit109' of github.com:jantman/gitpython_issue_301 +1caa617f02115fe9ae372d4f13bb885d78e94dff not-for-merge branch 'testcommit1090' of github.com:jantman/gitpython_issue_301 +ac3be29d3e1e82548e54093630c3a69231dd735f not-for-merge branch 'testcommit1091' of github.com:jantman/gitpython_issue_301 +ed7c2973e590c4a938c3985b08f91558b68cb37d not-for-merge branch 'testcommit1092' of github.com:jantman/gitpython_issue_301 +bdefdd16ab5d5e95cc1b32b8fdff47a125151949 not-for-merge branch 'testcommit1093' of github.com:jantman/gitpython_issue_301 +38cff866165cddda64c291565c158ee3c780fb66 not-for-merge branch 'testcommit1094' of github.com:jantman/gitpython_issue_301 +12cfe834195d2c50bc774fdcf8811a4d1e5876bd not-for-merge branch 'testcommit1095' of github.com:jantman/gitpython_issue_301 +4ae27f31ee4cb5c4faa79ad9193ae2f963eb9b06 not-for-merge branch 'testcommit1096' of github.com:jantman/gitpython_issue_301 +b7ab182d4840ed5ae95f11b173649c9beb79912e not-for-merge branch 'testcommit1097' of github.com:jantman/gitpython_issue_301 +672ffcd369a825f73d284a74059f5f19f736ff6d not-for-merge branch 'testcommit1098' of github.com:jantman/gitpython_issue_301 +c93a97da2e71a559ff7e03782979bf355b3e1136 not-for-merge branch 'testcommit1099' of github.com:jantman/gitpython_issue_301 +55cb6f9568e7a100d09d00164f5dd7b0535e4310 not-for-merge branch 'testcommit11' of github.com:jantman/gitpython_issue_301 +9dcffbb783f71c611bef7141399c10dda819d468 not-for-merge branch 'testcommit110' of github.com:jantman/gitpython_issue_301 +e53af6e7a2f361864dda512199cb6a38292755ae not-for-merge branch 'testcommit1100' of github.com:jantman/gitpython_issue_301 +e7a5c09b0b88deaf241fe6514b5cc0bb6bb6cb45 not-for-merge branch 'testcommit1101' of github.com:jantman/gitpython_issue_301 +2218dafaef4f8d31712a6cdc7fbeac770c3ae896 not-for-merge branch 'testcommit1102' of github.com:jantman/gitpython_issue_301 +ef5a88d0daeb8861ca59fbdd261b09641fc30575 not-for-merge branch 'testcommit1103' of github.com:jantman/gitpython_issue_301 +7a1dac58789c9bc72da312fead7e8925e9ff3b3b not-for-merge branch 'testcommit1104' of github.com:jantman/gitpython_issue_301 +fd182a64f6fefd07e80df51cab24e2e3ff997404 not-for-merge branch 'testcommit1105' of github.com:jantman/gitpython_issue_301 +2870deb98332e9bf702926a27d219068df2a5734 not-for-merge branch 'testcommit1106' of github.com:jantman/gitpython_issue_301 +e1e3f1228c9aae832efb3ce813eacd18e799af1c not-for-merge branch 'testcommit1107' of github.com:jantman/gitpython_issue_301 +b83df5064e6ca92bf23f4e8893d0d895794491c2 not-for-merge branch 'testcommit1108' of github.com:jantman/gitpython_issue_301 +ba699e788131115d827e013b8b536db517c08b9e not-for-merge branch 'testcommit1109' of github.com:jantman/gitpython_issue_301 +20e0be248c4ef3ec27fe5c1c470a6914cb459395 not-for-merge branch 'testcommit111' of github.com:jantman/gitpython_issue_301 +09e22ef75bd95b357570f7a4ce1eaf5c78518926 not-for-merge branch 'testcommit1110' of github.com:jantman/gitpython_issue_301 +cbfa17e2e435273f83cfc4c86b7665445b627ec7 not-for-merge branch 'testcommit1111' of github.com:jantman/gitpython_issue_301 +69e2c4783070ca246c2911cd78477a1f5cae442a not-for-merge branch 'testcommit1112' of github.com:jantman/gitpython_issue_301 +122ac4d63172d44674c5fc339d0393f4b60f1b1f not-for-merge branch 'testcommit1113' of github.com:jantman/gitpython_issue_301 +07e3b6dc5419875073c52fb3f8401a6d4644a891 not-for-merge branch 'testcommit1114' of github.com:jantman/gitpython_issue_301 +c601acd83e899ee23af369fc73ffbe3134d48de2 not-for-merge branch 'testcommit1115' of github.com:jantman/gitpython_issue_301 +e50cfc4d294fdf07524142815662cc33b87b705b not-for-merge branch 'testcommit1116' of github.com:jantman/gitpython_issue_301 +d7acf565b440e6b00f8edfb3d540fa839cd273ab not-for-merge branch 'testcommit1117' of github.com:jantman/gitpython_issue_301 +1eac6a459b15b563b5f43bdc6f97df4711a600df not-for-merge branch 'testcommit1118' of github.com:jantman/gitpython_issue_301 +1fd3fe8021b31637516f531be4848fe83b59b1cf not-for-merge branch 'testcommit1119' of github.com:jantman/gitpython_issue_301 +a62a45f2d78c4ca178fcef92d5f6de1ddbfb4746 not-for-merge branch 'testcommit112' of github.com:jantman/gitpython_issue_301 +199af89fec1154e4d40bd6507365b4cba4c29a94 not-for-merge branch 'testcommit1120' of github.com:jantman/gitpython_issue_301 +0f3e33d551325fe2fdd88659fb4b6331b90521a3 not-for-merge branch 'testcommit1121' of github.com:jantman/gitpython_issue_301 +a0e70e450c770c3b916cf5dad60619fd95956dfc not-for-merge branch 'testcommit1122' of github.com:jantman/gitpython_issue_301 +547dbcd351e72f99181118fec4778fd0648f6ff0 not-for-merge branch 'testcommit1123' of github.com:jantman/gitpython_issue_301 +2b3446f6c54478603f594a1f7fa2dc4729101106 not-for-merge branch 'testcommit1124' of github.com:jantman/gitpython_issue_301 +3f415e48bd54b0eb8db4f3c5899ab376d0e3aeb7 not-for-merge branch 'testcommit1125' of github.com:jantman/gitpython_issue_301 +c27e72d137dcd985138d438e3e3a16e08d1355b6 not-for-merge branch 'testcommit1126' of github.com:jantman/gitpython_issue_301 +633b426e10f2fd0e16ff3a0da736349058722815 not-for-merge branch 'testcommit1127' of github.com:jantman/gitpython_issue_301 +d2a581ad637e7e8060288c6d43d8226c021a3f42 not-for-merge branch 'testcommit1128' of github.com:jantman/gitpython_issue_301 +efac764b787df54fe2dabea8f32e02ecbd6a2ddb not-for-merge branch 'testcommit1129' of github.com:jantman/gitpython_issue_301 +1333282639ec695f5a595ac2f56248337c5b1838 not-for-merge branch 'testcommit113' of github.com:jantman/gitpython_issue_301 +a5969e439375214fc465fd1f09b31fae1bdf7ee7 not-for-merge branch 'testcommit1130' of github.com:jantman/gitpython_issue_301 +3e67a1c7a8103e1d6fb91b1a83f7fef821a7dbac not-for-merge branch 'testcommit1131' of github.com:jantman/gitpython_issue_301 +8ae97d7a41c1c09e23252a9b546f895492a7ec4b not-for-merge branch 'testcommit1132' of github.com:jantman/gitpython_issue_301 +7cbd6c26fd6402de4375c87a7b0e1fddef7a0632 not-for-merge branch 'testcommit1133' of github.com:jantman/gitpython_issue_301 +a93a37fc6632a843ba746eb4090f0d3cc31dd876 not-for-merge branch 'testcommit1134' of github.com:jantman/gitpython_issue_301 +ecc257ed5ee7dc26110a3cfa75cf1251e04c4ca1 not-for-merge branch 'testcommit1135' of github.com:jantman/gitpython_issue_301 +b4c3c3f6e0f6867b25e926f72ab4c7840a1f23bd not-for-merge branch 'testcommit1136' of github.com:jantman/gitpython_issue_301 +fba79db2fff2531d982a3ee0bf86a904a315adcd not-for-merge branch 'testcommit1137' of github.com:jantman/gitpython_issue_301 +97ec8bf454187944227f639b2348f9089f8a2a23 not-for-merge branch 'testcommit1138' of github.com:jantman/gitpython_issue_301 +09632791d06f73ea50f628e1e720ad8a874f58e7 not-for-merge branch 'testcommit1139' of github.com:jantman/gitpython_issue_301 +1d82fe9bb1c761912fc5c8598af055c26f380aca not-for-merge branch 'testcommit114' of github.com:jantman/gitpython_issue_301 +c9e9b0c05e64778a55ccf0ee26ef199fc57a5d7b not-for-merge branch 'testcommit1140' of github.com:jantman/gitpython_issue_301 +11bc154798db96737fd5fea7f35c7f164db165e1 not-for-merge branch 'testcommit1141' of github.com:jantman/gitpython_issue_301 +4c9e4e24f790fd1512e5908aaf77e86b46e5339a not-for-merge branch 'testcommit1142' of github.com:jantman/gitpython_issue_301 +8a804d4bb492e080bad2b2190b65bfe711b71f40 not-for-merge branch 'testcommit1143' of github.com:jantman/gitpython_issue_301 +0951f67dd9b8563482047b7b74176df3f1c9a429 not-for-merge branch 'testcommit1144' of github.com:jantman/gitpython_issue_301 +1c363695812110631a945a84489b6997c9136018 not-for-merge branch 'testcommit1145' of github.com:jantman/gitpython_issue_301 +b004ea4ffd2f9905e0e6cebb08cac5fc40918015 not-for-merge branch 'testcommit1146' of github.com:jantman/gitpython_issue_301 +b33c28ba069959c30370195a6010e9c91075788a not-for-merge branch 'testcommit1147' of github.com:jantman/gitpython_issue_301 +b09105acb2591685646e1c69bbfce9a24569ed75 not-for-merge branch 'testcommit1148' of github.com:jantman/gitpython_issue_301 +07f1efa2dff41cf6c562c90cf57a85d15791d4fc not-for-merge branch 'testcommit1149' of github.com:jantman/gitpython_issue_301 +873878b0a7e3d057124fbeef30099162e4dcf1a0 not-for-merge branch 'testcommit115' of github.com:jantman/gitpython_issue_301 +025d348dce7f01d0fc1a4acb9bb24309002a4749 not-for-merge branch 'testcommit1150' of github.com:jantman/gitpython_issue_301 +7ebd68d136bcac39d9b9a7178328b650a1c839a7 not-for-merge branch 'testcommit1151' of github.com:jantman/gitpython_issue_301 +7203b4ddf827bc0e312d942177831147eb5b6841 not-for-merge branch 'testcommit1152' of github.com:jantman/gitpython_issue_301 +cfc0cda3154ed7494f172801a99ddcbc11b12996 not-for-merge branch 'testcommit1153' of github.com:jantman/gitpython_issue_301 +45549e31b199ac0e5c16f53b3e2b6712650d715a not-for-merge branch 'testcommit1154' of github.com:jantman/gitpython_issue_301 +cbaa071137433d5314acf6e85b8174e4994c276a not-for-merge branch 'testcommit1155' of github.com:jantman/gitpython_issue_301 +a46da4d72bb8497b803191b1d3b13730ab49f766 not-for-merge branch 'testcommit1156' of github.com:jantman/gitpython_issue_301 +17aec3730c7682b9057803a3d990c85961a6ce44 not-for-merge branch 'testcommit1157' of github.com:jantman/gitpython_issue_301 +e7558b39811d49f3c4b386a38419e960fbd95382 not-for-merge branch 'testcommit1158' of github.com:jantman/gitpython_issue_301 +ddff4bf440241ec9a5c03b16ca7be2df8a46eb1e not-for-merge branch 'testcommit1159' of github.com:jantman/gitpython_issue_301 +eddc98b14ac57fdf5260183110265682f8906cee not-for-merge branch 'testcommit116' of github.com:jantman/gitpython_issue_301 +96568821f122d5610878a7797dc353a396150360 not-for-merge branch 'testcommit1160' of github.com:jantman/gitpython_issue_301 +4b7ffafad4febcad43b5f4902c2229c303b16696 not-for-merge branch 'testcommit1161' of github.com:jantman/gitpython_issue_301 +03f487eceaa0b9e7b2800c6078cf852249af82c9 not-for-merge branch 'testcommit1162' of github.com:jantman/gitpython_issue_301 +92f4da7b29f0b9b007265e7254d1acfd0c12725f not-for-merge branch 'testcommit1163' of github.com:jantman/gitpython_issue_301 +d513e6a13759a435426ae2ded67f1ec066ca0a13 not-for-merge branch 'testcommit1164' of github.com:jantman/gitpython_issue_301 +7dc838ff52ec8c791573160e2d9fd5513ba13365 not-for-merge branch 'testcommit1165' of github.com:jantman/gitpython_issue_301 +31ff5fa84b887aec02c9f1031be27e6c76d68e00 not-for-merge branch 'testcommit1166' of github.com:jantman/gitpython_issue_301 +ac987b3df23e22c9c4bc7504c3efc44605db7f07 not-for-merge branch 'testcommit1167' of github.com:jantman/gitpython_issue_301 +d2c26f2766e8d62685df28ca8b854c01df6cc1b4 not-for-merge branch 'testcommit1168' of github.com:jantman/gitpython_issue_301 +53ca1a605398e207c601d87613a4bb23c27e03e1 not-for-merge branch 'testcommit1169' of github.com:jantman/gitpython_issue_301 +ce925e45d8fcfe942f1e0b4d9e08601ebb580919 not-for-merge branch 'testcommit117' of github.com:jantman/gitpython_issue_301 +1a3b00146f94811d76fcd676de68b78e4e78ea61 not-for-merge branch 'testcommit1170' of github.com:jantman/gitpython_issue_301 +e224395b2fc68666892914e730ef12c4d69c88e3 not-for-merge branch 'testcommit1171' of github.com:jantman/gitpython_issue_301 +d6d72aada4c36698dd3fe6c7773c8ba643b9703a not-for-merge branch 'testcommit1172' of github.com:jantman/gitpython_issue_301 +9124e4622f87f3ec4250d8ed3113482c07b2d68b not-for-merge branch 'testcommit1173' of github.com:jantman/gitpython_issue_301 +15928c4d9a627836dc5eb88e559f320dd1ee2283 not-for-merge branch 'testcommit1174' of github.com:jantman/gitpython_issue_301 +18567d26548b12ffc09ede23f16b57b18cb43310 not-for-merge branch 'testcommit1175' of github.com:jantman/gitpython_issue_301 +5547f331d7c55ff1973bd536d40a92841e7ce035 not-for-merge branch 'testcommit1176' of github.com:jantman/gitpython_issue_301 +2ca1c5ca13be4c28c0e73b1961cb7682bcb3ea1a not-for-merge branch 'testcommit1177' of github.com:jantman/gitpython_issue_301 +208509ce8e39a3be1c9b6e2d99eafa89fd1cf684 not-for-merge branch 'testcommit1178' of github.com:jantman/gitpython_issue_301 +644d579fada2ada76b4d51be94fa8393654be214 not-for-merge branch 'testcommit1179' of github.com:jantman/gitpython_issue_301 +fee627a495ce3c9780c5b2bd740f6d9e437b9d6e not-for-merge branch 'testcommit118' of github.com:jantman/gitpython_issue_301 +ff311ba7e3b485bbe9d1c3705df5d605b2476a89 not-for-merge branch 'testcommit1180' of github.com:jantman/gitpython_issue_301 +a78eac859cdda172a5c9721c5c36e44907c192f7 not-for-merge branch 'testcommit1181' of github.com:jantman/gitpython_issue_301 +a897b2f084a65c47ccc0331c565a9a20c04ebcbc not-for-merge branch 'testcommit1182' of github.com:jantman/gitpython_issue_301 +d262fbce249a1832e461a26357897580df1f2932 not-for-merge branch 'testcommit1183' of github.com:jantman/gitpython_issue_301 +7ffc89d7b9a94632bb8ff5f0a3e7d35de3eccf13 not-for-merge branch 'testcommit1184' of github.com:jantman/gitpython_issue_301 +1a0e0df0e8c291d108baa981e65d0722786efe27 not-for-merge branch 'testcommit1185' of github.com:jantman/gitpython_issue_301 +95e905cad2c6d6a4ff010cceac8d4a60d9505fa6 not-for-merge branch 'testcommit1186' of github.com:jantman/gitpython_issue_301 +ea03310563b0d64d0eb7001ff78b1e22f38a0bf1 not-for-merge branch 'testcommit1187' of github.com:jantman/gitpython_issue_301 +223c152e55c2d986b6974f8b3423a2fb5a253b48 not-for-merge branch 'testcommit1188' of github.com:jantman/gitpython_issue_301 +8565160a8ded00222fd9d8dcd603a7524e4ee17f not-for-merge branch 'testcommit1189' of github.com:jantman/gitpython_issue_301 +dd7eabc192578056bf93932039a6cca81cc6fb31 not-for-merge branch 'testcommit119' of github.com:jantman/gitpython_issue_301 +5068432d1d3b7ac57fdeb67e0dac55bd3cc0888d not-for-merge branch 'testcommit1190' of github.com:jantman/gitpython_issue_301 +e56dea1cc059761ae0cf5099f2fee179efa1010a not-for-merge branch 'testcommit1191' of github.com:jantman/gitpython_issue_301 +a0673e3b53f347ca3aa658be042271528bb61880 not-for-merge branch 'testcommit1192' of github.com:jantman/gitpython_issue_301 +6aaefc469bc1ccc7099038a5a4e4ef2e4817e40a not-for-merge branch 'testcommit1193' of github.com:jantman/gitpython_issue_301 +201d665fe94dab10938153a637728e7b2ca3e17a not-for-merge branch 'testcommit1194' of github.com:jantman/gitpython_issue_301 +eedc465ddb5fc8d47e7bd4823e607db3dd93a190 not-for-merge branch 'testcommit1195' of github.com:jantman/gitpython_issue_301 +f0fa95cd65fe1dec9dfb0beb82fefc2c5a17e7b5 not-for-merge branch 'testcommit1196' of github.com:jantman/gitpython_issue_301 +97804411c5bab39edae1238a98a99ff55124e4d7 not-for-merge branch 'testcommit1197' of github.com:jantman/gitpython_issue_301 +daf886b0396d37ddf5be47f23d862246ce01bc26 not-for-merge branch 'testcommit1198' of github.com:jantman/gitpython_issue_301 +9326044f3cae96bb56555630c3f9d1280fc76858 not-for-merge branch 'testcommit1199' of github.com:jantman/gitpython_issue_301 +f7346357820a98dd830ab33f714aa7d0c7eddbcb not-for-merge branch 'testcommit12' of github.com:jantman/gitpython_issue_301 +c8ae02d70be5592704e42ac1fcb0d13cf8a7b4fe not-for-merge branch 'testcommit120' of github.com:jantman/gitpython_issue_301 +1a7cece8c70eb73485b5144cd9b0d460b2f49c83 not-for-merge branch 'testcommit1200' of github.com:jantman/gitpython_issue_301 +c273dc35f9668fd0d76bfd1e740cd1867c5b4db7 not-for-merge branch 'testcommit1201' of github.com:jantman/gitpython_issue_301 +19d27a3d8c1f8791cf93053a025e0b8d5ea0f415 not-for-merge branch 'testcommit1202' of github.com:jantman/gitpython_issue_301 +c0c3d079a5ad9cb5804b4887384e1d36d22267c0 not-for-merge branch 'testcommit1203' of github.com:jantman/gitpython_issue_301 +b3734aaca05fa0a678efcc3b9c1fef6ab8dbc18e not-for-merge branch 'testcommit1204' of github.com:jantman/gitpython_issue_301 +f6436a629721d356a980ab75a216db5a82306d81 not-for-merge branch 'testcommit1205' of github.com:jantman/gitpython_issue_301 +7fe5dcbf48e5c46a8c765cb9ff7d4d79f4aed662 not-for-merge branch 'testcommit1206' of github.com:jantman/gitpython_issue_301 +4733001f193d7adaa2373497c0dde4df63ddf9c2 not-for-merge branch 'testcommit1207' of github.com:jantman/gitpython_issue_301 +f3236bfa507baa2ad0a3b9364b7333d25ffbe465 not-for-merge branch 'testcommit1208' of github.com:jantman/gitpython_issue_301 +5bd9c0bf26bb7b13c46d11370442d2df58f86414 not-for-merge branch 'testcommit1209' of github.com:jantman/gitpython_issue_301 +37afc3365b9dc38f5060539b8a607679a66105ec not-for-merge branch 'testcommit121' of github.com:jantman/gitpython_issue_301 +6c2898e7d320b52ad15ac99dc1b182e0282f5ce6 not-for-merge branch 'testcommit1210' of github.com:jantman/gitpython_issue_301 +10d235e4ba482d7d8e130e8e4caee72d210851d0 not-for-merge branch 'testcommit1211' of github.com:jantman/gitpython_issue_301 +d32b703e1f5d1202a84fe8b7a5802004f3d0c4b7 not-for-merge branch 'testcommit1212' of github.com:jantman/gitpython_issue_301 +33359c5b379e60f699eabc9f4f5dd9a996eb6d52 not-for-merge branch 'testcommit1213' of github.com:jantman/gitpython_issue_301 +224fc55c881e41d3021ecb1c2d4bde6e24625964 not-for-merge branch 'testcommit1214' of github.com:jantman/gitpython_issue_301 +9bc61997f25937d8c432ec03e6c9a6fc0dcec3e0 not-for-merge branch 'testcommit1215' of github.com:jantman/gitpython_issue_301 +a26f66075c9be07dec5fa0080fe77d8b40f00e9a not-for-merge branch 'testcommit1216' of github.com:jantman/gitpython_issue_301 +e1f7848720c2c482da0f0aae2960e039e293ba02 not-for-merge branch 'testcommit1217' of github.com:jantman/gitpython_issue_301 +8023fd647a1b9084210842cccc33328e9b34c488 not-for-merge branch 'testcommit1218' of github.com:jantman/gitpython_issue_301 +3089eb6f9b4bc6d21d8cabf6efed5ef19ddf147e not-for-merge branch 'testcommit1219' of github.com:jantman/gitpython_issue_301 +3f8921965ebe3783d820ab4c86ee792abe2119f5 not-for-merge branch 'testcommit122' of github.com:jantman/gitpython_issue_301 +ddbe2c92c86118f1845bcb0838816df97aa87076 not-for-merge branch 'testcommit1220' of github.com:jantman/gitpython_issue_301 +99c87e055d0b50065bd41268e854b9e620b4bc28 not-for-merge branch 'testcommit1221' of github.com:jantman/gitpython_issue_301 +d67a6d82d83bffa3094f581208e1b42f0dea48fd not-for-merge branch 'testcommit1222' of github.com:jantman/gitpython_issue_301 +ed82e93f0a65931744846b0339173cb4467e542a not-for-merge branch 'testcommit1223' of github.com:jantman/gitpython_issue_301 +4b937668a267d2834b5d3cb04e71e5ccacdbf5f9 not-for-merge branch 'testcommit1224' of github.com:jantman/gitpython_issue_301 +6d4f87d580c4c7d03aa1197aaeac1a090d77a94e not-for-merge branch 'testcommit1225' of github.com:jantman/gitpython_issue_301 +7a2d34f9652aafa466dc2e7468bc2c242c5aa9ec not-for-merge branch 'testcommit1226' of github.com:jantman/gitpython_issue_301 +6649172a7854ed8210c75680a3bfb3d65d8d8c1f not-for-merge branch 'testcommit1227' of github.com:jantman/gitpython_issue_301 +c6ec1586a8104013066ee5821d42db649460b27c not-for-merge branch 'testcommit1228' of github.com:jantman/gitpython_issue_301 +1531579d34a1f19ec0d7a78dc83a3c9ae05aa721 not-for-merge branch 'testcommit1229' of github.com:jantman/gitpython_issue_301 +fa3fa7d446c26c2f015c2f6dd61f1e2138a8d6c9 not-for-merge branch 'testcommit123' of github.com:jantman/gitpython_issue_301 +7fb6c9a6731548024169343733bab02b751724a6 not-for-merge branch 'testcommit1230' of github.com:jantman/gitpython_issue_301 +a684a7296369c1fd0b54857ac8e8678f54d3e011 not-for-merge branch 'testcommit1231' of github.com:jantman/gitpython_issue_301 +3908d0dc256277b9ab5099b947701c269fe81d42 not-for-merge branch 'testcommit1232' of github.com:jantman/gitpython_issue_301 +a3445f55ec1c9dc41ce44a9051d3c83b44043349 not-for-merge branch 'testcommit1233' of github.com:jantman/gitpython_issue_301 +f9a5f80ad16ade559d1d53ac8d01c661aae45b19 not-for-merge branch 'testcommit1234' of github.com:jantman/gitpython_issue_301 +4dfd70925886f4f7c0e384d505e0d9367a774ca0 not-for-merge branch 'testcommit1235' of github.com:jantman/gitpython_issue_301 +bbdd8d4d857523a14f0ab7632fd82414cbca2a8e not-for-merge branch 'testcommit1236' of github.com:jantman/gitpython_issue_301 +1c526ea4948f0dd6a4843f5e139cdbde8cde684a not-for-merge branch 'testcommit1237' of github.com:jantman/gitpython_issue_301 +7c8354a6bad3b80bfdcc897ba4bdbab3dfdb065d not-for-merge branch 'testcommit1238' of github.com:jantman/gitpython_issue_301 +5550055865f962179c1435f2c407e15985c1f05f not-for-merge branch 'testcommit1239' of github.com:jantman/gitpython_issue_301 +e2b6345c9afe44a57698169b9fed2b7d404dbfb8 not-for-merge branch 'testcommit124' of github.com:jantman/gitpython_issue_301 +200330e705ca4b61acbc9bb299240a4c5513e74b not-for-merge branch 'testcommit1240' of github.com:jantman/gitpython_issue_301 +7f0bb6240776c6ee7b469adfa63cfd9d8dfecb59 not-for-merge branch 'testcommit1241' of github.com:jantman/gitpython_issue_301 +59674d33dade0dca533159833f16a54e7eb5fba7 not-for-merge branch 'testcommit1242' of github.com:jantman/gitpython_issue_301 +b49f392bd60038daa7addae08e03b4e8966f3bf8 not-for-merge branch 'testcommit1243' of github.com:jantman/gitpython_issue_301 +12daf7cd0173681aa72241fa101fd55ccd0ad014 not-for-merge branch 'testcommit1244' of github.com:jantman/gitpython_issue_301 +b2de7b56d619c18c341df03cdd9d390b6a84550d not-for-merge branch 'testcommit1245' of github.com:jantman/gitpython_issue_301 +0e24d5f1bd3c6ce0df6ac1028c2b136880d64b4b not-for-merge branch 'testcommit1246' of github.com:jantman/gitpython_issue_301 +8edb0a11c2cb2bd670e65680ac6b2dfa247a5fa2 not-for-merge branch 'testcommit1247' of github.com:jantman/gitpython_issue_301 +13a2a7044617fde9da4ca68c7706ef5f3142c700 not-for-merge branch 'testcommit1248' of github.com:jantman/gitpython_issue_301 +c6b92b8f948d7eec32c08d48f74b18e5aab36364 not-for-merge branch 'testcommit1249' of github.com:jantman/gitpython_issue_301 +3dcfa77f3c552a95208f9cefdc1cacd9dd32c810 not-for-merge branch 'testcommit125' of github.com:jantman/gitpython_issue_301 +c5aeba94b0db763d7e967b9c2e5c57aca3a5da3c not-for-merge branch 'testcommit1250' of github.com:jantman/gitpython_issue_301 +1c8f5177549888d810047dcabfb5422a0864b84c not-for-merge branch 'testcommit1251' of github.com:jantman/gitpython_issue_301 +65c8c35ca7151800b8eb1fe3d4c9fbb79d6229f4 not-for-merge branch 'testcommit1252' of github.com:jantman/gitpython_issue_301 +9435f03a3164fc4bd5b0662df3de534e1a31deb4 not-for-merge branch 'testcommit1253' of github.com:jantman/gitpython_issue_301 +a6a7752eb5528afc49ac57bdcbce8086e8405f15 not-for-merge branch 'testcommit1254' of github.com:jantman/gitpython_issue_301 +ba85742d3ecf45b4cd2f10ae8415cad77b205dad not-for-merge branch 'testcommit1255' of github.com:jantman/gitpython_issue_301 +3862f60a0578ab367c9101d71a1e57e79a69d437 not-for-merge branch 'testcommit1256' of github.com:jantman/gitpython_issue_301 +aaa3e1f7b4ae8a33f3b8ab7ff3cfd1581669bd8d not-for-merge branch 'testcommit1257' of github.com:jantman/gitpython_issue_301 +602f3b372e63e48b5a6a9045b79822eed47d7bcd not-for-merge branch 'testcommit1258' of github.com:jantman/gitpython_issue_301 +48d61a52461a222cfae9dddebd0f9d8d5569bc30 not-for-merge branch 'testcommit1259' of github.com:jantman/gitpython_issue_301 +c0345930edb1c6b64819db1a74c995e9d33d9dc3 not-for-merge branch 'testcommit126' of github.com:jantman/gitpython_issue_301 +b2d7b7f9d81b01701c93500df462aa3db9cbe02f not-for-merge branch 'testcommit1260' of github.com:jantman/gitpython_issue_301 +d4055c32978c932959b6a27682696e74e695777b not-for-merge branch 'testcommit1261' of github.com:jantman/gitpython_issue_301 +d8226cd372fcba01784c60085dd4700089612f0c not-for-merge branch 'testcommit1262' of github.com:jantman/gitpython_issue_301 +f0a2bfd3d906267dfeb4e476b63bc155405b15bf not-for-merge branch 'testcommit1263' of github.com:jantman/gitpython_issue_301 +8d29fdc6f8fafe5449920b3195428aa66cae8868 not-for-merge branch 'testcommit1264' of github.com:jantman/gitpython_issue_301 +fe487724ba78a69b6ffef1b0c5c2758e9eb4fa34 not-for-merge branch 'testcommit1265' of github.com:jantman/gitpython_issue_301 +0a61a6f00479d0e40929132d20d2d6bd989fc7c6 not-for-merge branch 'testcommit1266' of github.com:jantman/gitpython_issue_301 +e217bbc3907220e09f37554e45759d8d7845ceed not-for-merge branch 'testcommit1267' of github.com:jantman/gitpython_issue_301 +c0f97a4fdb47d6610d0f597597e7b440a2830c96 not-for-merge branch 'testcommit1268' of github.com:jantman/gitpython_issue_301 +5616c697e5f3641b3b89d7571c34cd68d8173cf7 not-for-merge branch 'testcommit1269' of github.com:jantman/gitpython_issue_301 +a8627944a005270fb5c89f8b5aea3b550738057d not-for-merge branch 'testcommit127' of github.com:jantman/gitpython_issue_301 +4a5029178f86a2d8d0f75499abb010f1c8d88598 not-for-merge branch 'testcommit1270' of github.com:jantman/gitpython_issue_301 +b6a75d09b3f33e2469812e0b94460168201867ca not-for-merge branch 'testcommit1271' of github.com:jantman/gitpython_issue_301 +0263e0e2c7a269ba254f3c5d6cbda9c50a8a11bf not-for-merge branch 'testcommit1272' of github.com:jantman/gitpython_issue_301 +0cf0b2c48109cf906c4f799b2fb115b9d65cb1cb not-for-merge branch 'testcommit1273' of github.com:jantman/gitpython_issue_301 +1f98a2f26b55d95ced1ffa639a6b56780ded9b4d not-for-merge branch 'testcommit1274' of github.com:jantman/gitpython_issue_301 +c922c196018e49890a391c8071ed3ed682b16133 not-for-merge branch 'testcommit1275' of github.com:jantman/gitpython_issue_301 +801a6946cfabbe8a45b61ff102e406f7c9f6c341 not-for-merge branch 'testcommit1276' of github.com:jantman/gitpython_issue_301 +b7b814b9562a2466a881354efaef1e9e64612fc1 not-for-merge branch 'testcommit1277' of github.com:jantman/gitpython_issue_301 +b16acccce3d80a1cb2f6d594e7197c89eeb5dd9d not-for-merge branch 'testcommit1278' of github.com:jantman/gitpython_issue_301 +a66150c4c5548ddaaef5054c671660e4e6ba894f not-for-merge branch 'testcommit1279' of github.com:jantman/gitpython_issue_301 +fdbcb6fb2b480e5f46a0fab92f42b3eb80db1bc3 not-for-merge branch 'testcommit128' of github.com:jantman/gitpython_issue_301 +40958f670c56537c3b028a8b67fd878e5724ecd3 not-for-merge branch 'testcommit1280' of github.com:jantman/gitpython_issue_301 +16e640590f1b4007d81da333c17d3bbd08cba561 not-for-merge branch 'testcommit1281' of github.com:jantman/gitpython_issue_301 +6b23eabf5f3da092cbae17b0e1e0e180e5785725 not-for-merge branch 'testcommit1282' of github.com:jantman/gitpython_issue_301 +18345f72e075b8952a0bfa4de2425857c428a348 not-for-merge branch 'testcommit1283' of github.com:jantman/gitpython_issue_301 +2740274ec39b89e3e7655ffd297b0c9d54c56b12 not-for-merge branch 'testcommit1284' of github.com:jantman/gitpython_issue_301 +328c0fd03b055a15fc77ff46bc29bcab39a7d896 not-for-merge branch 'testcommit1285' of github.com:jantman/gitpython_issue_301 +97fa973768e0779f0ebe4cca9a1f4d657ff89563 not-for-merge branch 'testcommit1286' of github.com:jantman/gitpython_issue_301 +472466ea520e1178faec9e6da3f45ed6e08c8a57 not-for-merge branch 'testcommit1287' of github.com:jantman/gitpython_issue_301 +55487cbe72c4d0452f21df644af6872090ccaf95 not-for-merge branch 'testcommit1288' of github.com:jantman/gitpython_issue_301 +ddcb315e54934cbc96c4651fd263cfdab6b0d157 not-for-merge branch 'testcommit1289' of github.com:jantman/gitpython_issue_301 +35111dc8446354ce2c61b885b5d81d00d0067f87 not-for-merge branch 'testcommit129' of github.com:jantman/gitpython_issue_301 +389a12bf807abdb68cf9258da631df6e17f4983c not-for-merge branch 'testcommit1290' of github.com:jantman/gitpython_issue_301 +1da47c0973bf8d9c2d15712b317d27d778623965 not-for-merge branch 'testcommit1291' of github.com:jantman/gitpython_issue_301 +e1544f6ad6c2236c67702a98dc44faa5470f4ca8 not-for-merge branch 'testcommit1292' of github.com:jantman/gitpython_issue_301 +f09ca7832ca5c7348dadac88d0e2020b3b90deff not-for-merge branch 'testcommit1293' of github.com:jantman/gitpython_issue_301 +41a7a3b448dd4f48e47527c043ba7381174a7181 not-for-merge branch 'testcommit1294' of github.com:jantman/gitpython_issue_301 +45f152403fab6fcb74cb5f696295bce7c35ae262 not-for-merge branch 'testcommit1295' of github.com:jantman/gitpython_issue_301 +331f9f77d469e268d86ba0e00ddfb9744a88740e not-for-merge branch 'testcommit1296' of github.com:jantman/gitpython_issue_301 +3ae655a0237dc2600c4691fad6da754771a9d733 not-for-merge branch 'testcommit1297' of github.com:jantman/gitpython_issue_301 +629b87c5252c2d75612340623e6919fb34eb68f5 not-for-merge branch 'testcommit1298' of github.com:jantman/gitpython_issue_301 +4a439a3f5a92c2264e0aed1a9cd92bb99a71ff91 not-for-merge branch 'testcommit1299' of github.com:jantman/gitpython_issue_301 +f21a2ed894533cfd439abef2d015716aa870bc2b not-for-merge branch 'testcommit13' of github.com:jantman/gitpython_issue_301 +494bc67a7e8562f6e55602b633c218129871e516 not-for-merge branch 'testcommit130' of github.com:jantman/gitpython_issue_301 +4448225334875001fc4e7ef1dd38ff2a1e82ca8f not-for-merge branch 'testcommit1300' of github.com:jantman/gitpython_issue_301 +c903bd75677a46688a118d35a900e902b7420024 not-for-merge branch 'testcommit1301' of github.com:jantman/gitpython_issue_301 +17e21c3221fc62b3c66507fe8c0f253c52e939d9 not-for-merge branch 'testcommit1302' of github.com:jantman/gitpython_issue_301 +8c63e973b927c3ed557e07e0241201a655f45621 not-for-merge branch 'testcommit1303' of github.com:jantman/gitpython_issue_301 +ce6b131c441b000cb16ee58e4bd12753ac06a6f8 not-for-merge branch 'testcommit1304' of github.com:jantman/gitpython_issue_301 +b807eab7a0da60ed68f3411cce38a8d912fd6b56 not-for-merge branch 'testcommit1305' of github.com:jantman/gitpython_issue_301 +6d1f426b09d1bd2ed433d2b67d33b4edf5a65b1b not-for-merge branch 'testcommit1306' of github.com:jantman/gitpython_issue_301 +9db3aa543d64aff701190a4b5b2adc44020c2b0a not-for-merge branch 'testcommit1307' of github.com:jantman/gitpython_issue_301 +59b34e0112c83e58640c1d7af3d5823d006620b0 not-for-merge branch 'testcommit1308' of github.com:jantman/gitpython_issue_301 +9429570db3230fcc3bb64eaf80f07c0b4d77c1d4 not-for-merge branch 'testcommit1309' of github.com:jantman/gitpython_issue_301 +035173ba6f0408792a81d823fa8447fa128218de not-for-merge branch 'testcommit131' of github.com:jantman/gitpython_issue_301 +0cd395fe7cee54ba3a192ab3bed45ccf5e3680e5 not-for-merge branch 'testcommit1310' of github.com:jantman/gitpython_issue_301 +305c17ab30d4adfbb7c7ec2e6747323f8bfe109b not-for-merge branch 'testcommit1311' of github.com:jantman/gitpython_issue_301 +20da0bac5c179f36f753cb8fa7a7d8317276e181 not-for-merge branch 'testcommit1312' of github.com:jantman/gitpython_issue_301 +100847fa1b521ad5eab501b5cd0ab43b6b8c7340 not-for-merge branch 'testcommit1313' of github.com:jantman/gitpython_issue_301 +6fd07bf74d0593922bde9d00fd1394314011c292 not-for-merge branch 'testcommit1314' of github.com:jantman/gitpython_issue_301 +a7c8ffff394a98335df5d1e432dcaccb200ba468 not-for-merge branch 'testcommit1315' of github.com:jantman/gitpython_issue_301 +1a045affcd539c4649a1618a640a69dc197bf6de not-for-merge branch 'testcommit1316' of github.com:jantman/gitpython_issue_301 +0a3d476403e1b9ead6b9c498e8a12912d0341762 not-for-merge branch 'testcommit1317' of github.com:jantman/gitpython_issue_301 +6f784c0c418669b5c4941b54666fa85b0ed9faac not-for-merge branch 'testcommit1318' of github.com:jantman/gitpython_issue_301 +aec10eaee00908d2ebe35f67d9e9b1aa0d9ac1bc not-for-merge branch 'testcommit1319' of github.com:jantman/gitpython_issue_301 +66f2619ed5a9b5ab1da9c171730a95cff1f69d7e not-for-merge branch 'testcommit132' of github.com:jantman/gitpython_issue_301 +7ec982ab4b6a521d508fb4f8b025adefb7db1fd7 not-for-merge branch 'testcommit1320' of github.com:jantman/gitpython_issue_301 +fcc0270a252d3a4a61185399d2c2e308845e1b59 not-for-merge branch 'testcommit1321' of github.com:jantman/gitpython_issue_301 +ad2b5ea7137907042e6bb070cddbf9e251551482 not-for-merge branch 'testcommit1322' of github.com:jantman/gitpython_issue_301 +74a5045d67df103d53b42c9b1fd698fda85b1689 not-for-merge branch 'testcommit1323' of github.com:jantman/gitpython_issue_301 +cebebbc2b2323e0b5f7f9b72740ea25b7771e65e not-for-merge branch 'testcommit1324' of github.com:jantman/gitpython_issue_301 +f4aad42eea9ec42ac97c865901601520544debed not-for-merge branch 'testcommit1325' of github.com:jantman/gitpython_issue_301 +a1921397f68b1b79f842219905991996f5e35129 not-for-merge branch 'testcommit1326' of github.com:jantman/gitpython_issue_301 +391075a8fb1835406ca75d93aa9dba2346e0f23f not-for-merge branch 'testcommit1327' of github.com:jantman/gitpython_issue_301 +800c2370259a213f3bb5a56d6ebbb83e2be36afe not-for-merge branch 'testcommit1328' of github.com:jantman/gitpython_issue_301 +8b794b4e7293049294b1f79813b9380537071f1f not-for-merge branch 'testcommit1329' of github.com:jantman/gitpython_issue_301 +1b30ed2886d442d33b15674ca4da71e94520061b not-for-merge branch 'testcommit133' of github.com:jantman/gitpython_issue_301 +108d1f0269b5a8c2c04b478466bd54b6d107bbdb not-for-merge branch 'testcommit1330' of github.com:jantman/gitpython_issue_301 +c6b5cc45062bbae816b9604330dc43bbe4421a89 not-for-merge branch 'testcommit1331' of github.com:jantman/gitpython_issue_301 +2a560b8afc0c624895d0655a8f07f6c3c035d5b0 not-for-merge branch 'testcommit1332' of github.com:jantman/gitpython_issue_301 +090943c2ca312cb140270ebe5572054962749115 not-for-merge branch 'testcommit1333' of github.com:jantman/gitpython_issue_301 +ec3f55826f769fe2f9d54de75a2664abd8cd2ce3 not-for-merge branch 'testcommit1334' of github.com:jantman/gitpython_issue_301 +a37598f237ff29c6e3a95954e05ec3ca28847d67 not-for-merge branch 'testcommit1335' of github.com:jantman/gitpython_issue_301 +37e28e8550c13b53916cbaaa652cf133055ae972 not-for-merge branch 'testcommit1336' of github.com:jantman/gitpython_issue_301 +7ffa0ba56766f3fc6030cae79ca21322a41ac44b not-for-merge branch 'testcommit1337' of github.com:jantman/gitpython_issue_301 +630444aaea5b26a478e40785a78d329cc26f9fb5 not-for-merge branch 'testcommit1338' of github.com:jantman/gitpython_issue_301 +2f85dba18ba1d4e185f182ca537ac2770dd27f80 not-for-merge branch 'testcommit1339' of github.com:jantman/gitpython_issue_301 +1c8da6c47058e4a8b887e2efdbd73c88fc9ad563 not-for-merge branch 'testcommit134' of github.com:jantman/gitpython_issue_301 +c3e0b7890c84fc6ec99e755c93bd67df21994f1f not-for-merge branch 'testcommit1340' of github.com:jantman/gitpython_issue_301 +5f72be5cb0bccd8d40e059cd967fb18002e2d7cc not-for-merge branch 'testcommit1341' of github.com:jantman/gitpython_issue_301 +f3fd85d022e8a1f56d4a71437d1d60ed5f89e50d not-for-merge branch 'testcommit1342' of github.com:jantman/gitpython_issue_301 +e2800a5f6819a486ab157fc4b1a57b767c5d86e0 not-for-merge branch 'testcommit1343' of github.com:jantman/gitpython_issue_301 +968488acb290d9a17f6ef2fb6b37ff2589b5b296 not-for-merge branch 'testcommit1344' of github.com:jantman/gitpython_issue_301 +ac63d0b8c2ef2861d1100c892651c8bbff068a01 not-for-merge branch 'testcommit1345' of github.com:jantman/gitpython_issue_301 +c1ea47152d583858ca9fd0ce2b4e2ee826df68c9 not-for-merge branch 'testcommit1346' of github.com:jantman/gitpython_issue_301 +536706a293a82565722193bd5ced953ddc81ef71 not-for-merge branch 'testcommit1347' of github.com:jantman/gitpython_issue_301 +49c194bca48052418474b9a5a358dc0fa60dbf34 not-for-merge branch 'testcommit1348' of github.com:jantman/gitpython_issue_301 +50a77638cd0e9bcfebb6c95794f72a42006c93a1 not-for-merge branch 'testcommit1349' of github.com:jantman/gitpython_issue_301 +599aaccca44ac72d0e136a4370c85cf32bdf8841 not-for-merge branch 'testcommit135' of github.com:jantman/gitpython_issue_301 +21a51222a4510ca00bc049c49252616a67238e6c not-for-merge branch 'testcommit1350' of github.com:jantman/gitpython_issue_301 +b4581d67c4ee0019b16fbbc90914aa83b5bbed10 not-for-merge branch 'testcommit1351' of github.com:jantman/gitpython_issue_301 +68c48f52ae3cb2d7425df2d7520eaa724279e659 not-for-merge branch 'testcommit1352' of github.com:jantman/gitpython_issue_301 +a6acaba93617fd99a423b43ced738d0d2698452a not-for-merge branch 'testcommit1353' of github.com:jantman/gitpython_issue_301 +29bbd78089ab9826112c93139b35d6236fca24bd not-for-merge branch 'testcommit1354' of github.com:jantman/gitpython_issue_301 +dd1538461b459bb703a9d4cc22e9b83f22e09b38 not-for-merge branch 'testcommit1355' of github.com:jantman/gitpython_issue_301 +69fc8d428059f97980c2e49c94f44ece0d22841e not-for-merge branch 'testcommit1356' of github.com:jantman/gitpython_issue_301 +068a4d5712d78c18f9bff5d11ce01dc5ece6e776 not-for-merge branch 'testcommit1357' of github.com:jantman/gitpython_issue_301 +6c7b12bb8050f90f5f4a5c259c54100ef6f214d8 not-for-merge branch 'testcommit1358' of github.com:jantman/gitpython_issue_301 +1695fdad1aa06c3ce280b6a370d107b5a81ea14b not-for-merge branch 'testcommit1359' of github.com:jantman/gitpython_issue_301 +7171ec0e3d018afd0466ff16eb17645f2f42fa88 not-for-merge branch 'testcommit136' of github.com:jantman/gitpython_issue_301 +1451ea5b2992026f12c835f6e4d13147723c86c1 not-for-merge branch 'testcommit1360' of github.com:jantman/gitpython_issue_301 +2665d1b8e9d3d10916795e851569dd28f1315d26 not-for-merge branch 'testcommit1361' of github.com:jantman/gitpython_issue_301 +7b93cf6b45cc2057bec223725a06e604ce698060 not-for-merge branch 'testcommit1362' of github.com:jantman/gitpython_issue_301 +3de5760230ae6eec8d4790b06ff2355f2090f3e6 not-for-merge branch 'testcommit1363' of github.com:jantman/gitpython_issue_301 +5d1b0c128f0760f4a3731b91cbe897f014ce59ce not-for-merge branch 'testcommit1364' of github.com:jantman/gitpython_issue_301 +415f762fbd9150a2334afa18590403f1e07da971 not-for-merge branch 'testcommit1365' of github.com:jantman/gitpython_issue_301 +c26f250b54270b02b3ee88687d9ce0f985c48527 not-for-merge branch 'testcommit1366' of github.com:jantman/gitpython_issue_301 +f924dc2cf152a31271062b101ac56ca47f898cca not-for-merge branch 'testcommit1367' of github.com:jantman/gitpython_issue_301 +fce412e5d24537fcfca38dab83e97ec5636fe409 not-for-merge branch 'testcommit1368' of github.com:jantman/gitpython_issue_301 +fa1d82fcf27b513d7e6a5850310fb336a7267c2c not-for-merge branch 'testcommit1369' of github.com:jantman/gitpython_issue_301 +fa577d62d9ea9a59d3fa79454458d2b1ad9ab0e9 not-for-merge branch 'testcommit137' of github.com:jantman/gitpython_issue_301 +8453631771aed0740ed55400beea87fb5fd35305 not-for-merge branch 'testcommit1370' of github.com:jantman/gitpython_issue_301 +327b3a70cbd49d5f5795bd1d94352f8caa124de9 not-for-merge branch 'testcommit1371' of github.com:jantman/gitpython_issue_301 +9f6a9bde6a17ca688011f67105168e59f704a9c7 not-for-merge branch 'testcommit1372' of github.com:jantman/gitpython_issue_301 +6ae0eed5fb0412a6197e86f41152de503a3d2a66 not-for-merge branch 'testcommit1373' of github.com:jantman/gitpython_issue_301 +0bd81c3ac896c39fae5b1890219a30bc5b533942 not-for-merge branch 'testcommit1374' of github.com:jantman/gitpython_issue_301 +d2b9b79b6c03742e9f0460ba33f7f9cf3972b6c3 not-for-merge branch 'testcommit1375' of github.com:jantman/gitpython_issue_301 +93d38c570071fb1c2d432c8c89c83aac4cc55148 not-for-merge branch 'testcommit1376' of github.com:jantman/gitpython_issue_301 +88fbc6ed6740a8f323e077afcab4fe67a589f677 not-for-merge branch 'testcommit1377' of github.com:jantman/gitpython_issue_301 +120dad271ccec5028a8d1f2e0102714cea8a6161 not-for-merge branch 'testcommit1378' of github.com:jantman/gitpython_issue_301 +c43da9ffa4dec5920ea7ca265194783e21d56180 not-for-merge branch 'testcommit1379' of github.com:jantman/gitpython_issue_301 +656d4a02e083b6b7159b9a54722cd2e4154769b4 not-for-merge branch 'testcommit138' of github.com:jantman/gitpython_issue_301 +7ff2c1c9392f66a3a1aadb3c1afe8263c81834db not-for-merge branch 'testcommit1380' of github.com:jantman/gitpython_issue_301 +334e3481ed565733cc4cd83da48cc608d6b18c5b not-for-merge branch 'testcommit1381' of github.com:jantman/gitpython_issue_301 +547ba0ed34920aedf2b2dcdf4c29db0c828b7d89 not-for-merge branch 'testcommit1382' of github.com:jantman/gitpython_issue_301 +5365ba7bc3048827f64774d2239838ad09f8704f not-for-merge branch 'testcommit1383' of github.com:jantman/gitpython_issue_301 +17f62d19a61711130f8b56461c0b2bd264bf4db2 not-for-merge branch 'testcommit1384' of github.com:jantman/gitpython_issue_301 +40ee983bdcc9875bb347c39feabbf0546c72414a not-for-merge branch 'testcommit1385' of github.com:jantman/gitpython_issue_301 +607feaef441b4b705755e1ba2c2b59df4a496a27 not-for-merge branch 'testcommit1386' of github.com:jantman/gitpython_issue_301 +d0fffc2c3e679b3adba6b53b7d1a39218160fada not-for-merge branch 'testcommit1387' of github.com:jantman/gitpython_issue_301 +884583a7cee5bd6aeabc4309ddc1417db97a41a7 not-for-merge branch 'testcommit1388' of github.com:jantman/gitpython_issue_301 +05801c213bdaecf8d63188e9334269b46ea2c3c8 not-for-merge branch 'testcommit1389' of github.com:jantman/gitpython_issue_301 +8fb690c72fd4f3dfd8e2dec723ee559ff3fe4f4e not-for-merge branch 'testcommit139' of github.com:jantman/gitpython_issue_301 +3c91d8ae1a388fe9d0072c2e10958e0a8805a134 not-for-merge branch 'testcommit1390' of github.com:jantman/gitpython_issue_301 +0bbf7f583b0e161b36cdbbee09735fa5f97d63ff not-for-merge branch 'testcommit1391' of github.com:jantman/gitpython_issue_301 +8c05f87af535a7241b5cfa7d17fce9a6b9803794 not-for-merge branch 'testcommit1392' of github.com:jantman/gitpython_issue_301 +2d77ca8dc95cc6db4e65d318ee63d1bb55a1249c not-for-merge branch 'testcommit1393' of github.com:jantman/gitpython_issue_301 +8267efe64d7c56dc618d6131aeaba2f0d2510af3 not-for-merge branch 'testcommit1394' of github.com:jantman/gitpython_issue_301 +54587c6d2ac8dd8a4cadf73fdeeecfe14fed1188 not-for-merge branch 'testcommit1395' of github.com:jantman/gitpython_issue_301 +d04061c0732cb32b6c16a9f44135fc3d1ef06528 not-for-merge branch 'testcommit1396' of github.com:jantman/gitpython_issue_301 +d56fae58887fabed6fce908f3499bcf6a5e6a629 not-for-merge branch 'testcommit1397' of github.com:jantman/gitpython_issue_301 +2655f52f7f3c0cd68bcafdd6d3e27a88d91e80af not-for-merge branch 'testcommit1398' of github.com:jantman/gitpython_issue_301 +5c5e35d52cae040ab351d289586075d3411b8309 not-for-merge branch 'testcommit1399' of github.com:jantman/gitpython_issue_301 +4726511baada4463aad73f8383e53e896693ba0c not-for-merge branch 'testcommit14' of github.com:jantman/gitpython_issue_301 +75f6dd4cc0c0da3f0d4da04505ada25aa48fad8c not-for-merge branch 'testcommit140' of github.com:jantman/gitpython_issue_301 +5c3b8654292c21ce23e52655efeb6d2c9d48b8a7 not-for-merge branch 'testcommit1400' of github.com:jantman/gitpython_issue_301 +ece449a362ab9bd156a16f692806900d01d4e6e3 not-for-merge branch 'testcommit1401' of github.com:jantman/gitpython_issue_301 +e229a0b1c01a350974a8fb6d7090e99ac72ea24b not-for-merge branch 'testcommit1402' of github.com:jantman/gitpython_issue_301 +983ea6b69afc11d039fff2d90a8ab0aa9f57a264 not-for-merge branch 'testcommit1403' of github.com:jantman/gitpython_issue_301 +6a670d0d8eb05924afdf12c5b40bd71cc90e74d8 not-for-merge branch 'testcommit1404' of github.com:jantman/gitpython_issue_301 +a7a58e9a3f1c91fdb621f9d3f2a9ac366e3a92c8 not-for-merge branch 'testcommit1405' of github.com:jantman/gitpython_issue_301 +599cf8662e948ef4016bb1ed3ebdfb8b13aed572 not-for-merge branch 'testcommit1406' of github.com:jantman/gitpython_issue_301 +16e46ea6714b6dfb32f232a8985a422b67ac983f not-for-merge branch 'testcommit1407' of github.com:jantman/gitpython_issue_301 +957d130f85b71849427335084963502aa05ccaa6 not-for-merge branch 'testcommit1408' of github.com:jantman/gitpython_issue_301 +785e285d11fdbada098e46b9a86d58a3bdb08b6f not-for-merge branch 'testcommit1409' of github.com:jantman/gitpython_issue_301 +b5e3dbf786c02e87d06201d389c31013a7b8aa93 not-for-merge branch 'testcommit141' of github.com:jantman/gitpython_issue_301 +77d0537a8dad05ae596c076528c5408313a0e2c9 not-for-merge branch 'testcommit1410' of github.com:jantman/gitpython_issue_301 +adc84570b78ec2b9a2c4f0d053b66e8d2f2582fe not-for-merge branch 'testcommit1411' of github.com:jantman/gitpython_issue_301 +c2c9b46234369d9b873d0dd955d6a79bf1a05091 not-for-merge branch 'testcommit1412' of github.com:jantman/gitpython_issue_301 +c64ff88a370ef5391212a0240ef770999feaf2a2 not-for-merge branch 'testcommit1413' of github.com:jantman/gitpython_issue_301 +e5daeddc97d52195369fcfc06ffa95887b7d8570 not-for-merge branch 'testcommit1414' of github.com:jantman/gitpython_issue_301 +b46da404b60c03445b95ef496230b98572996c23 not-for-merge branch 'testcommit1415' of github.com:jantman/gitpython_issue_301 +ac747c9e6b8aa80d5a364eac1dd20893e0c9452e not-for-merge branch 'testcommit1416' of github.com:jantman/gitpython_issue_301 +6e24e93eb0c36e7385d3645963ad2291ea07d8e6 not-for-merge branch 'testcommit1417' of github.com:jantman/gitpython_issue_301 +9bff17506fdba526f5d6f37d07ff0010612b913f not-for-merge branch 'testcommit1418' of github.com:jantman/gitpython_issue_301 +eed0494f7a94755da24df44d76fc9561a93e9231 not-for-merge branch 'testcommit1419' of github.com:jantman/gitpython_issue_301 +d59c8cfd0e2632214d992acc8a2ada48fb99c1a7 not-for-merge branch 'testcommit142' of github.com:jantman/gitpython_issue_301 +66382cbf8bf06fdd3d7a73021bbc9173f7f1c891 not-for-merge branch 'testcommit1420' of github.com:jantman/gitpython_issue_301 +6d566d47d2bc4cdff93aec5173e3590d760ff0b6 not-for-merge branch 'testcommit1421' of github.com:jantman/gitpython_issue_301 +5a2f1ed4caaf1214368dbc6d3ea59c96e7e4cada not-for-merge branch 'testcommit1422' of github.com:jantman/gitpython_issue_301 +5636e4ae3be13ad559c5178585d4314eb6c6fc76 not-for-merge branch 'testcommit1423' of github.com:jantman/gitpython_issue_301 +2893e152d7bb86e5cf5696a7cc67c0337f839cae not-for-merge branch 'testcommit1424' of github.com:jantman/gitpython_issue_301 +109b55abbf02eb019d62bd7d0f83d6c5a3f91e4d not-for-merge branch 'testcommit1425' of github.com:jantman/gitpython_issue_301 +f7ffe7889b02e77ba06cac4da445026274d9bbcc not-for-merge branch 'testcommit1426' of github.com:jantman/gitpython_issue_301 +b591ec82f57675e4d15b7383e3e7298439155515 not-for-merge branch 'testcommit1427' of github.com:jantman/gitpython_issue_301 +7814e65fbb105c16809b64bc160b29ecbd71a737 not-for-merge branch 'testcommit1428' of github.com:jantman/gitpython_issue_301 +e9613fd04c5f790f6ecfd471273e3135f9c8fc3b not-for-merge branch 'testcommit1429' of github.com:jantman/gitpython_issue_301 +751c556322c3b253f202bab845ae75c7e0050ce0 not-for-merge branch 'testcommit143' of github.com:jantman/gitpython_issue_301 +878beda79cdb770a7ac8b7a38b7bf64093fc1e9e not-for-merge branch 'testcommit1430' of github.com:jantman/gitpython_issue_301 +e09a0534302467f45dc40f681093da0400c4e16b not-for-merge branch 'testcommit1431' of github.com:jantman/gitpython_issue_301 +03920d2537bb0af033f2781470dfad9e4f928045 not-for-merge branch 'testcommit1432' of github.com:jantman/gitpython_issue_301 +a026589497c2339a4681945c3d44e6ff1f114ea5 not-for-merge branch 'testcommit1433' of github.com:jantman/gitpython_issue_301 +a60aa6a46260f5cc944d1883093a9dca42812efc not-for-merge branch 'testcommit1434' of github.com:jantman/gitpython_issue_301 +60c68b580842211bc7b52f2d3d732831192f2751 not-for-merge branch 'testcommit1435' of github.com:jantman/gitpython_issue_301 +8c27e485dcde72e394cacda328e2c6a1c911e690 not-for-merge branch 'testcommit1436' of github.com:jantman/gitpython_issue_301 +f92a2a3fd520f09279d55118929f8f0a60923212 not-for-merge branch 'testcommit1437' of github.com:jantman/gitpython_issue_301 +e08e75b4a0c5c312863815e0d2995791cbeb79bf not-for-merge branch 'testcommit1438' of github.com:jantman/gitpython_issue_301 +0826414258dc8f2aa7e53682de5a030b1abd1334 not-for-merge branch 'testcommit1439' of github.com:jantman/gitpython_issue_301 +1c8762cd27d2d9933f276fc9473cda2d1105260f not-for-merge branch 'testcommit144' of github.com:jantman/gitpython_issue_301 +0ce5cd7a105e6e49eb917a42e649f5a09ef2077b not-for-merge branch 'testcommit1440' of github.com:jantman/gitpython_issue_301 +c54682d73f0c05e27492efadc663aa0e3405d57a not-for-merge branch 'testcommit1441' of github.com:jantman/gitpython_issue_301 +f5fd49d1c115855c6d0b54827474721b94378244 not-for-merge branch 'testcommit1442' of github.com:jantman/gitpython_issue_301 +76644651115238b697c6194208657dcbf4143e27 not-for-merge branch 'testcommit1443' of github.com:jantman/gitpython_issue_301 +75461c2c2c6285824cdda80b457cda002f9086e4 not-for-merge branch 'testcommit1444' of github.com:jantman/gitpython_issue_301 +7378bc3ff8998f46c63768e8393800a59b7fc35e not-for-merge branch 'testcommit1445' of github.com:jantman/gitpython_issue_301 +b16795522622b92968da9e1928b7b80ee6546077 not-for-merge branch 'testcommit1446' of github.com:jantman/gitpython_issue_301 +0eca19cb4c6145b23862b99022a2aff2402dce60 not-for-merge branch 'testcommit1447' of github.com:jantman/gitpython_issue_301 +3ef5fffe847b4f25d99b4d5612148fa3ee898df9 not-for-merge branch 'testcommit1448' of github.com:jantman/gitpython_issue_301 +8a5ba8271985ebcdb570b83f962d7eb415a6d2a6 not-for-merge branch 'testcommit1449' of github.com:jantman/gitpython_issue_301 +e1cf0b981cd04172dd15bf52225670bf72fbad1c not-for-merge branch 'testcommit145' of github.com:jantman/gitpython_issue_301 +3e8f4489ab3d5346cb4a56f0d9adb31219b00ce4 not-for-merge branch 'testcommit1450' of github.com:jantman/gitpython_issue_301 +a1c3a54c9945bab499bcb358ce39667020b7c24e not-for-merge branch 'testcommit1451' of github.com:jantman/gitpython_issue_301 +cccae833e676a4e191e57d0cf3b242002980487f not-for-merge branch 'testcommit1452' of github.com:jantman/gitpython_issue_301 +e00c41829cb079ca75920b5b0a5aeaa468c9c4d1 not-for-merge branch 'testcommit1453' of github.com:jantman/gitpython_issue_301 +01cbf8b4aa117d517b27aca0ae6055fa8f7fc8c4 not-for-merge branch 'testcommit1454' of github.com:jantman/gitpython_issue_301 +bb625c024577d05ed5b80f7589b6fa0762a2ce9a not-for-merge branch 'testcommit1455' of github.com:jantman/gitpython_issue_301 +542b3f67aec5fda47d549ea4fac06f6dc2d81266 not-for-merge branch 'testcommit1456' of github.com:jantman/gitpython_issue_301 +1df81514238f60420352aeb0b8b1e8ef8940be20 not-for-merge branch 'testcommit1457' of github.com:jantman/gitpython_issue_301 +2c9b131ce00fd209511183e91226aecbe23871fc not-for-merge branch 'testcommit1458' of github.com:jantman/gitpython_issue_301 +9dea49e925f3d983d81187a11d6e43107e4e07f9 not-for-merge branch 'testcommit1459' of github.com:jantman/gitpython_issue_301 +76cc1ea240b1afd1b5b14ea6b17dd17b9ad26a8d not-for-merge branch 'testcommit146' of github.com:jantman/gitpython_issue_301 +17f0a8b1ef58bf1ed5a3597f9f630dc9cf96a535 not-for-merge branch 'testcommit1460' of github.com:jantman/gitpython_issue_301 +95cbd4446e3625a99fc3eb58dee75a16b7a125e8 not-for-merge branch 'testcommit1461' of github.com:jantman/gitpython_issue_301 +be47e3c01c730f1bab9e0f647bdcc410d51d7f72 not-for-merge branch 'testcommit1462' of github.com:jantman/gitpython_issue_301 +dcd84e12282b940ca5758dae08e145a77889840d not-for-merge branch 'testcommit1463' of github.com:jantman/gitpython_issue_301 +de0e91e8deff615cb9edbf86ab623f447122bd0a not-for-merge branch 'testcommit1464' of github.com:jantman/gitpython_issue_301 +f85d1552408cbc977595ce55538635a3d77ffbb7 not-for-merge branch 'testcommit1465' of github.com:jantman/gitpython_issue_301 +0914c4772336f58ab8d5d4f0400f791a2838ed73 not-for-merge branch 'testcommit1466' of github.com:jantman/gitpython_issue_301 +d76095c2b62a7fd7e145527caf25b9bdbf3be7e0 not-for-merge branch 'testcommit1467' of github.com:jantman/gitpython_issue_301 +b8fb4dd09d2a14318f13d6343b00d375da7ad7bf not-for-merge branch 'testcommit1468' of github.com:jantman/gitpython_issue_301 +24f1251b6024f4fa0e986f2b621d309d6d98a274 not-for-merge branch 'testcommit1469' of github.com:jantman/gitpython_issue_301 +eebb725b455af404490ae91868cd59dacad68dc0 not-for-merge branch 'testcommit147' of github.com:jantman/gitpython_issue_301 +5a25e5ad11bdf333d42c86ce2783e7dc6ef4e728 not-for-merge branch 'testcommit1470' of github.com:jantman/gitpython_issue_301 +14791de397b91f889fb65744134de2551a92ca9b not-for-merge branch 'testcommit1471' of github.com:jantman/gitpython_issue_301 +d460635551e17cdb12a33d4cf60e2aada303f3e3 not-for-merge branch 'testcommit1472' of github.com:jantman/gitpython_issue_301 +63d962f8b1e90cfca325781c3021b43c833c84a1 not-for-merge branch 'testcommit1473' of github.com:jantman/gitpython_issue_301 +613acc762aea65a529cc1048a5876e63f2ae3926 not-for-merge branch 'testcommit1474' of github.com:jantman/gitpython_issue_301 +3f9c5796d2cb4d87eded6a8b61e2c35de4a699e3 not-for-merge branch 'testcommit1475' of github.com:jantman/gitpython_issue_301 +d0ab75bb005fd791dcac9840bf77b6f76f6f2163 not-for-merge branch 'testcommit1476' of github.com:jantman/gitpython_issue_301 +732592f3672e860640097bc84f8dcfe4c70efeac not-for-merge branch 'testcommit1477' of github.com:jantman/gitpython_issue_301 +eb01539e9c6f912568c1f6ff53716482fcd3a0b6 not-for-merge branch 'testcommit1478' of github.com:jantman/gitpython_issue_301 +0ab8f6378bd855ee8ba37e6c71002dbeffbd0021 not-for-merge branch 'testcommit1479' of github.com:jantman/gitpython_issue_301 +f925cc2654717f3caa5b5c9bc73f599d1589aecd not-for-merge branch 'testcommit148' of github.com:jantman/gitpython_issue_301 +5c800024acbf87def2003412d8ebe1d3c02382a0 not-for-merge branch 'testcommit1480' of github.com:jantman/gitpython_issue_301 +1bc1af20805f0168b9d010cb831e6c1afcc33f1a not-for-merge branch 'testcommit1481' of github.com:jantman/gitpython_issue_301 +40671840a08d7d5c6d5ec7bfe34b918f70dae670 not-for-merge branch 'testcommit1482' of github.com:jantman/gitpython_issue_301 +b70d127503bea543a79fdf5f7b0ea79e7528a3ac not-for-merge branch 'testcommit1483' of github.com:jantman/gitpython_issue_301 +7d1d90e2d40119a9f28ddbedcf3bbffd240ca01d not-for-merge branch 'testcommit1484' of github.com:jantman/gitpython_issue_301 +87634e0107f8271c19bd007d92fed603cd4ce147 not-for-merge branch 'testcommit1485' of github.com:jantman/gitpython_issue_301 +65e5dfe7f018ec5fb86cee88dab50ab4e7cb577e not-for-merge branch 'testcommit1486' of github.com:jantman/gitpython_issue_301 +ce45cf98b6bc8ebabccf859dd0dba03038dd7771 not-for-merge branch 'testcommit1487' of github.com:jantman/gitpython_issue_301 +461d648f16935721c60f526a825e4f039e37cec5 not-for-merge branch 'testcommit1488' of github.com:jantman/gitpython_issue_301 +5da3162b12f51e37758c1540b968cd90a09760db not-for-merge branch 'testcommit1489' of github.com:jantman/gitpython_issue_301 +9f323a17eab0f79fb7fb9e8ddf914fa6dde29d55 not-for-merge branch 'testcommit149' of github.com:jantman/gitpython_issue_301 +1d6e759dbf5e131bff0d55dd5a22bc47511217a8 not-for-merge branch 'testcommit1490' of github.com:jantman/gitpython_issue_301 +f55393eec66f03f2afa40c66e9918be9126eab87 not-for-merge branch 'testcommit1491' of github.com:jantman/gitpython_issue_301 +fc79d0c7e33f23339ffd5407830f869037c9f27b not-for-merge branch 'testcommit1492' of github.com:jantman/gitpython_issue_301 +2545311dc5c38526ec76d748c02bdde229abf531 not-for-merge branch 'testcommit1493' of github.com:jantman/gitpython_issue_301 +b4b7d62982a0923a44bf7c516dd672916c8820cf not-for-merge branch 'testcommit1494' of github.com:jantman/gitpython_issue_301 +ebc603a2a72f48be3d837f7514fac0cfef7d2969 not-for-merge branch 'testcommit1495' of github.com:jantman/gitpython_issue_301 +103db9bb1f5141b0d7a244433db5717900fd3ae5 not-for-merge branch 'testcommit1496' of github.com:jantman/gitpython_issue_301 +9f30b022b6820651e5f3201abe7aeaf3822adb4a not-for-merge branch 'testcommit1497' of github.com:jantman/gitpython_issue_301 +8e9f16ac3b2e5fcfc4f7737bb6fe8b24e534c15b not-for-merge branch 'testcommit1498' of github.com:jantman/gitpython_issue_301 +9db4b13f9276608e091a62c0eab4521904a88264 not-for-merge branch 'testcommit1499' of github.com:jantman/gitpython_issue_301 +49bddd3914d645360e84e6498071af1afea3c5e0 not-for-merge branch 'testcommit15' of github.com:jantman/gitpython_issue_301 +bb5cc8f03023e98e11bd9c5cd49532f08e2c2765 not-for-merge branch 'testcommit150' of github.com:jantman/gitpython_issue_301 +916b544185250bf5ed8eb0c6aa4e394fdf221f4c not-for-merge branch 'testcommit1500' of github.com:jantman/gitpython_issue_301 +6427dd73a3d5c93590cf7228b61137b9fee087e3 not-for-merge branch 'testcommit1501' of github.com:jantman/gitpython_issue_301 +935f5ed8b757dab968cbbbf42a0f77bfcc0c63ac not-for-merge branch 'testcommit1502' of github.com:jantman/gitpython_issue_301 +68454496677a256483e43f56bc34904b9e8523bb not-for-merge branch 'testcommit1503' of github.com:jantman/gitpython_issue_301 +dca9cb4d53936a01cbe15a064090c9255335f1f6 not-for-merge branch 'testcommit1504' of github.com:jantman/gitpython_issue_301 +c28e4ad5ced66cff068583f322befdeca36e36ca not-for-merge branch 'testcommit1505' of github.com:jantman/gitpython_issue_301 +1939fa5c6c0f3655a1c9c20f470e3f5d7efd2abc not-for-merge branch 'testcommit1506' of github.com:jantman/gitpython_issue_301 +acb9956bb17e66cfced8560fb10e687d115ce2a9 not-for-merge branch 'testcommit1507' of github.com:jantman/gitpython_issue_301 +d5f12d9ec9f4abe2a53e6d9c915920f1ddb65d26 not-for-merge branch 'testcommit1508' of github.com:jantman/gitpython_issue_301 +68597980198108b9f3b1fd69d86cfec928c44a57 not-for-merge branch 'testcommit1509' of github.com:jantman/gitpython_issue_301 +19a11c92eaa8b14c29b40ab4652c88917e0d82ba not-for-merge branch 'testcommit151' of github.com:jantman/gitpython_issue_301 +2f62659eeab67d3cf6af26aab007cf4e98018243 not-for-merge branch 'testcommit1510' of github.com:jantman/gitpython_issue_301 +cea5714dcd1ed7b7ea509c468c7e6411dc90f97a not-for-merge branch 'testcommit1511' of github.com:jantman/gitpython_issue_301 +6b881fde50652360b80c40f9781aaf1cecc2540b not-for-merge branch 'testcommit1512' of github.com:jantman/gitpython_issue_301 +56c54736f9db449ec4328225936a09fe10dbd77b not-for-merge branch 'testcommit1513' of github.com:jantman/gitpython_issue_301 +4285825003148e431c42615256c60e3cc79718d6 not-for-merge branch 'testcommit1514' of github.com:jantman/gitpython_issue_301 +b1a1ddb347f091dd95a226cdbd1016d985f1a4c4 not-for-merge branch 'testcommit1515' of github.com:jantman/gitpython_issue_301 +6915361469eb8b12e37529baece150c9bdd5209e not-for-merge branch 'testcommit1516' of github.com:jantman/gitpython_issue_301 +bf47373aa74331906ca2061cd4dff3c849620012 not-for-merge branch 'testcommit1517' of github.com:jantman/gitpython_issue_301 +790e951a9cccef0efdb071b5908856c7234ccb70 not-for-merge branch 'testcommit1518' of github.com:jantman/gitpython_issue_301 +b344455d22cce84e1980c85ca10a252123a2afbf not-for-merge branch 'testcommit1519' of github.com:jantman/gitpython_issue_301 +d73de06aa85e2a038474180a916dc28078e58e7a not-for-merge branch 'testcommit152' of github.com:jantman/gitpython_issue_301 +0663488b790dff422b9e55d05c0582a37c261dcb not-for-merge branch 'testcommit1520' of github.com:jantman/gitpython_issue_301 +18310f9b218d3109be53c1d1207b4425e3750a7e not-for-merge branch 'testcommit1521' of github.com:jantman/gitpython_issue_301 +021ff01fc39c4004a71f541c74419bf34e13946b not-for-merge branch 'testcommit1522' of github.com:jantman/gitpython_issue_301 +fd3192409fa51d64bbdf763fa28d0312f991bd00 not-for-merge branch 'testcommit1523' of github.com:jantman/gitpython_issue_301 +ca72ddade4d6a425a3a1c7e23621efbe1e683fdd not-for-merge branch 'testcommit1524' of github.com:jantman/gitpython_issue_301 +d8f5efa762fac4bcc1a609771ad631994d47075d not-for-merge branch 'testcommit1525' of github.com:jantman/gitpython_issue_301 +014109d57ebc82db386efd991c3f0306c9e0c9fc not-for-merge branch 'testcommit1526' of github.com:jantman/gitpython_issue_301 +d2f88294086b349aee47e1c2583b793a7217c12a not-for-merge branch 'testcommit1527' of github.com:jantman/gitpython_issue_301 +1bdcf41766b58f948ac1234d7cada8cd84ea8353 not-for-merge branch 'testcommit1528' of github.com:jantman/gitpython_issue_301 +4a82d9c1726fd8d295caa79b0c11a7081930efc4 not-for-merge branch 'testcommit1529' of github.com:jantman/gitpython_issue_301 +88acb3a048bc7462245aee92ff416a7d1326c7e6 not-for-merge branch 'testcommit153' of github.com:jantman/gitpython_issue_301 +53740bd0f71e4437108692bbb5eab13e7080b9c0 not-for-merge branch 'testcommit1530' of github.com:jantman/gitpython_issue_301 +cc170ddeb8795b03437d8b6b66c8eb120681c6e9 not-for-merge branch 'testcommit1531' of github.com:jantman/gitpython_issue_301 +ca270b9cdd8dd830b7a1aefb11d497844c177fc5 not-for-merge branch 'testcommit1532' of github.com:jantman/gitpython_issue_301 +a9508a2bed561e9d42daab3fa8f9bdaef24f7c98 not-for-merge branch 'testcommit1533' of github.com:jantman/gitpython_issue_301 +7d983b395be594b4c176f8e1b877563d8d8b8a32 not-for-merge branch 'testcommit1534' of github.com:jantman/gitpython_issue_301 +2d99f61b35871a26a7757cd06b24cc346a7fbc08 not-for-merge branch 'testcommit1535' of github.com:jantman/gitpython_issue_301 +98c70845bf6ea06fffdfc8cb1e04421da56d32d2 not-for-merge branch 'testcommit1536' of github.com:jantman/gitpython_issue_301 +6b685cef946864ca4537597235b9cd7922339ccd not-for-merge branch 'testcommit1537' of github.com:jantman/gitpython_issue_301 +596f92d56373889516018d2a0d62d1e0be44f7ff not-for-merge branch 'testcommit1538' of github.com:jantman/gitpython_issue_301 +48f9b75503b05dca164438382b1dd39031765cf2 not-for-merge branch 'testcommit1539' of github.com:jantman/gitpython_issue_301 +cf37b7dfbfe7b9e622667d3e22673495e137e6cc not-for-merge branch 'testcommit154' of github.com:jantman/gitpython_issue_301 +a1c3c9ffac555af44a0228d5e18863910fc2d58c not-for-merge branch 'testcommit1540' of github.com:jantman/gitpython_issue_301 +36564e147643020d4f4ba11dfba9582d0f73924e not-for-merge branch 'testcommit1541' of github.com:jantman/gitpython_issue_301 +02d84edcda5eb865375a57ed72acc86856ecff7b not-for-merge branch 'testcommit1542' of github.com:jantman/gitpython_issue_301 +eb5afb4f57bb40f9f6ffeda49ced67a3637d8460 not-for-merge branch 'testcommit1543' of github.com:jantman/gitpython_issue_301 +d63b1c3408777ed3b450526e46cfd65e9bbd9885 not-for-merge branch 'testcommit1544' of github.com:jantman/gitpython_issue_301 +bdf59cb5b718020fb4d8f0643c02e49dd485cd83 not-for-merge branch 'testcommit1545' of github.com:jantman/gitpython_issue_301 +e1789dbb967e6a718127d6da3eedff1ead7ef2d4 not-for-merge branch 'testcommit1546' of github.com:jantman/gitpython_issue_301 +7567f6baa5c50b2be4f9153e545cb3ab9183b460 not-for-merge branch 'testcommit1547' of github.com:jantman/gitpython_issue_301 +214a180a48a370995aaf9b909400b193d0129d8e not-for-merge branch 'testcommit1548' of github.com:jantman/gitpython_issue_301 +62f291223bb9e119e744a02785fe98ef77024621 not-for-merge branch 'testcommit1549' of github.com:jantman/gitpython_issue_301 +9ab28926076e91c723d0fb83a776a1239bc3341b not-for-merge branch 'testcommit155' of github.com:jantman/gitpython_issue_301 +34a4f7c246333916355fbf1cc35946191514a709 not-for-merge branch 'testcommit1550' of github.com:jantman/gitpython_issue_301 +cc1d2ec0a2235a4269dd2181d7148c7718522f82 not-for-merge branch 'testcommit1551' of github.com:jantman/gitpython_issue_301 +879078ec94b13cf1463bdb166fabd4baf0cff50c not-for-merge branch 'testcommit1552' of github.com:jantman/gitpython_issue_301 +0e3c1c98de99f105f63eafa38b09d76d7382d866 not-for-merge branch 'testcommit1553' of github.com:jantman/gitpython_issue_301 +7a0c46baa01c7c4648da428e8b58c291443ad54f not-for-merge branch 'testcommit1554' of github.com:jantman/gitpython_issue_301 +ff574a86c2e347789d9694a47d60d2d8e169e2f3 not-for-merge branch 'testcommit1555' of github.com:jantman/gitpython_issue_301 +76f590259454f06b930627f23269c6c3d5ee2ce2 not-for-merge branch 'testcommit1556' of github.com:jantman/gitpython_issue_301 +da2157f6811e634235763006c5959802b461f894 not-for-merge branch 'testcommit1557' of github.com:jantman/gitpython_issue_301 +0dd252eefa8704c306b781f3455989dd1cedfba5 not-for-merge branch 'testcommit1558' of github.com:jantman/gitpython_issue_301 +7433facdfc8ab33451edd3ed0bf3f5e5edf3cf1d not-for-merge branch 'testcommit1559' of github.com:jantman/gitpython_issue_301 +2594991d8757a52b527e815ce778c2572980e45f not-for-merge branch 'testcommit156' of github.com:jantman/gitpython_issue_301 +e81bd7448a3719d1740bbbb3d1f544572bcad5d3 not-for-merge branch 'testcommit1560' of github.com:jantman/gitpython_issue_301 +5cec4c4c14601ade981b1cc60c448af28970d0f1 not-for-merge branch 'testcommit1561' of github.com:jantman/gitpython_issue_301 +80ab8d39387d8e6694d2ce9684d80588950f79b6 not-for-merge branch 'testcommit1562' of github.com:jantman/gitpython_issue_301 +cc137c2e47112206a8d6e750d46c24b3b637f697 not-for-merge branch 'testcommit1563' of github.com:jantman/gitpython_issue_301 +ac61d2bf6673b8e110f10cc9c42e90066fbcb72b not-for-merge branch 'testcommit1564' of github.com:jantman/gitpython_issue_301 +838dd9daaa19a4726b0a001815275f285a580729 not-for-merge branch 'testcommit1565' of github.com:jantman/gitpython_issue_301 +bf4c5329605a2fb6f4a539002bd3e3c2087eb9bd not-for-merge branch 'testcommit1566' of github.com:jantman/gitpython_issue_301 +cebf60864006a20775f97f5074fb66c1f1cb5f03 not-for-merge branch 'testcommit1567' of github.com:jantman/gitpython_issue_301 +e22f9e6d72f4f2661304f2a8c87278e6edf4653d not-for-merge branch 'testcommit1568' of github.com:jantman/gitpython_issue_301 +5005f1f512e4ae12bd37d8dae63d506f053fd324 not-for-merge branch 'testcommit1569' of github.com:jantman/gitpython_issue_301 +b680c1de7df5195d1ccadd4dd04c66b9c9819351 not-for-merge branch 'testcommit157' of github.com:jantman/gitpython_issue_301 +d4bbaaf733f9c1b00eacf3cff3edb1f48ed5eba7 not-for-merge branch 'testcommit1570' of github.com:jantman/gitpython_issue_301 +b349e6a719aaab13a9899ca5f42e1008833528b9 not-for-merge branch 'testcommit1571' of github.com:jantman/gitpython_issue_301 +c1c0e29d1c07babd468f2b83c9a613c1bad5ed9a not-for-merge branch 'testcommit1572' of github.com:jantman/gitpython_issue_301 +6438939856cf16434ac6e555e90d3d1d42736753 not-for-merge branch 'testcommit1573' of github.com:jantman/gitpython_issue_301 +2e3ee0fc3091fdc76d5a9d877320f5ff74ab8110 not-for-merge branch 'testcommit1574' of github.com:jantman/gitpython_issue_301 +095fc82fb187815ba6db7b4a6197c45d317d7a58 not-for-merge branch 'testcommit1575' of github.com:jantman/gitpython_issue_301 +c980eeb039f50261d13575f1d336dc2f8509a9d3 not-for-merge branch 'testcommit1576' of github.com:jantman/gitpython_issue_301 +4f5bb947cfa79513359adc2435dba82580ca8944 not-for-merge branch 'testcommit1577' of github.com:jantman/gitpython_issue_301 +3c6945e4b2bf816f851bd5bd2cf5b3b3cb4afc2d not-for-merge branch 'testcommit1578' of github.com:jantman/gitpython_issue_301 +9dcd46de494dce8bf9a2f8dbadc17ddd31c73fdb not-for-merge branch 'testcommit1579' of github.com:jantman/gitpython_issue_301 +e3bfbd933582135ae2a20a4a4fe0ec87437567b8 not-for-merge branch 'testcommit158' of github.com:jantman/gitpython_issue_301 +c40237fb172d3fadbc0404bcadade4cdb2ee0ade not-for-merge branch 'testcommit1580' of github.com:jantman/gitpython_issue_301 +2a76d75520c5bdc8cad08a08018b5cd233cce742 not-for-merge branch 'testcommit1581' of github.com:jantman/gitpython_issue_301 +2a61132e79a7c4239bd122f8fc0f32b4a7773485 not-for-merge branch 'testcommit1582' of github.com:jantman/gitpython_issue_301 +e77b2a82f89b603ba2ddc38a55ccd87b2e63ab9b not-for-merge branch 'testcommit1583' of github.com:jantman/gitpython_issue_301 +e01bf50eb6d5bc0c10227ea98f740a4b8e7c523c not-for-merge branch 'testcommit1584' of github.com:jantman/gitpython_issue_301 +cabeb6276d4bac20eb08bafe185dbd671573ea28 not-for-merge branch 'testcommit1585' of github.com:jantman/gitpython_issue_301 +b755f13ffae142ba63aa5de560380868b63c6bb7 not-for-merge branch 'testcommit1586' of github.com:jantman/gitpython_issue_301 +8e155be59b4fb4f05fa1fa32f810fc215e066854 not-for-merge branch 'testcommit1587' of github.com:jantman/gitpython_issue_301 +841d44b5a414b2748c146715d1b0fed83b7bc529 not-for-merge branch 'testcommit1588' of github.com:jantman/gitpython_issue_301 +d619cd2fd5550600f84bd3beabe0005f3374fb0f not-for-merge branch 'testcommit1589' of github.com:jantman/gitpython_issue_301 +20b3fe06318887494ffb740efcf61941543af21f not-for-merge branch 'testcommit159' of github.com:jantman/gitpython_issue_301 +3650c820a2041e335b85f2c95ed09c6f23675558 not-for-merge branch 'testcommit1590' of github.com:jantman/gitpython_issue_301 +bfca0510b8a065b30c99fec11a0627a2526c9fcb not-for-merge branch 'testcommit1591' of github.com:jantman/gitpython_issue_301 +3f7076e6b9abd042e32760c56a0c0fcc78900df7 not-for-merge branch 'testcommit1592' of github.com:jantman/gitpython_issue_301 +04e31557480f11ba3b36af5d94e4eecdb226fcf9 not-for-merge branch 'testcommit1593' of github.com:jantman/gitpython_issue_301 +5152dd72d4f4e591612efae7bd6d6d69b8bfcf3f not-for-merge branch 'testcommit1594' of github.com:jantman/gitpython_issue_301 +b043f271d52e6aeb8e8d8327f76577857d270463 not-for-merge branch 'testcommit1595' of github.com:jantman/gitpython_issue_301 +97091b0cc3afeda6f4ea5d2169a9248a84aa89f5 not-for-merge branch 'testcommit1596' of github.com:jantman/gitpython_issue_301 +20501c93afb9daaba1e8f722c6df9a7227b5699c not-for-merge branch 'testcommit1597' of github.com:jantman/gitpython_issue_301 +f1e3a584c4b5165500e45fd8b9d90dab1f88bc34 not-for-merge branch 'testcommit1598' of github.com:jantman/gitpython_issue_301 +8d6060504de76dae957f34a4f6062dbdfc1a0c9a not-for-merge branch 'testcommit1599' of github.com:jantman/gitpython_issue_301 +51715f00ed3bd74a9cabda3a5764f441bf7d7747 not-for-merge branch 'testcommit16' of github.com:jantman/gitpython_issue_301 +ee26d3bcca07a687ea24910a75e331e50fe425b2 not-for-merge branch 'testcommit160' of github.com:jantman/gitpython_issue_301 +88fcfc140a29254703197053ffd8ce8b97f18dd4 not-for-merge branch 'testcommit1600' of github.com:jantman/gitpython_issue_301 +54b7a9212fb4fac1501580b8a82fd082c16a48e1 not-for-merge branch 'testcommit1601' of github.com:jantman/gitpython_issue_301 +01a43d8556e4ec0ec721ecbca5bfb994202a7164 not-for-merge branch 'testcommit1602' of github.com:jantman/gitpython_issue_301 +e0ea60b45972cf017b3eb1f34dd5da22c58e25bd not-for-merge branch 'testcommit1603' of github.com:jantman/gitpython_issue_301 +5b97a3ad71633476b6777f2c15bf93b59bbee12e not-for-merge branch 'testcommit1604' of github.com:jantman/gitpython_issue_301 +03ae858875b823a13643111fe47767d28b38eb0d not-for-merge branch 'testcommit1605' of github.com:jantman/gitpython_issue_301 +dad5564bb110cbd7e71775ad60ec149d40428596 not-for-merge branch 'testcommit1606' of github.com:jantman/gitpython_issue_301 +fa6f7c64020cbe02820473275ec940574323438e not-for-merge branch 'testcommit1607' of github.com:jantman/gitpython_issue_301 +91445c284841653c355ab47751945fbd864cab0a not-for-merge branch 'testcommit1608' of github.com:jantman/gitpython_issue_301 +5eb23347b6ad4c69c29571597e7b59bcce10e57e not-for-merge branch 'testcommit1609' of github.com:jantman/gitpython_issue_301 +316a5ebc6bfc76183c96ab5b65203a220d7007b8 not-for-merge branch 'testcommit161' of github.com:jantman/gitpython_issue_301 +2eb84493ea0abdcb68bf0a3188fc4697c9518878 not-for-merge branch 'testcommit1610' of github.com:jantman/gitpython_issue_301 +e01be3719b69e9b6ef4b4a035b902a523ca61621 not-for-merge branch 'testcommit1611' of github.com:jantman/gitpython_issue_301 +4b78b1973832dbe7edb12f2cd385a675d6ea3b8a not-for-merge branch 'testcommit1612' of github.com:jantman/gitpython_issue_301 +80f56954b1a413e1f82bb8405f1c4284815b3349 not-for-merge branch 'testcommit1613' of github.com:jantman/gitpython_issue_301 +da59a486ef8b85065d78bc250beae98f6f69dc23 not-for-merge branch 'testcommit1614' of github.com:jantman/gitpython_issue_301 +4b647cf43a587444a0c8058eeb1c3e3ecfffaa55 not-for-merge branch 'testcommit1615' of github.com:jantman/gitpython_issue_301 +5351ff4f6a502843e7a46ef040ab34a066fb3e85 not-for-merge branch 'testcommit1616' of github.com:jantman/gitpython_issue_301 +124798481a921f72d9f7a068e677db141c152f8f not-for-merge branch 'testcommit1617' of github.com:jantman/gitpython_issue_301 +649069bdfed25075ded515c03b0780445f19163a not-for-merge branch 'testcommit1618' of github.com:jantman/gitpython_issue_301 +887d29af466e4ce5004544a27dabe1b2b381e9f2 not-for-merge branch 'testcommit1619' of github.com:jantman/gitpython_issue_301 +23da4ee4613d6622330659d38203a9d15d9b5c06 not-for-merge branch 'testcommit162' of github.com:jantman/gitpython_issue_301 +55f4439bb8d0cd5c2ce8281da842901fc130759e not-for-merge branch 'testcommit1620' of github.com:jantman/gitpython_issue_301 +425d1a75400476479592a4a35dbca5b5ee58dca3 not-for-merge branch 'testcommit1621' of github.com:jantman/gitpython_issue_301 +b46188fbab438f824fd5c2e2b7eb332169c61700 not-for-merge branch 'testcommit1622' of github.com:jantman/gitpython_issue_301 +450d8af7ca93c67e3945ded1fe376f9ba647c3d1 not-for-merge branch 'testcommit1623' of github.com:jantman/gitpython_issue_301 +7203ba2871ecb7ab98229eca11d893b12eda208c not-for-merge branch 'testcommit1624' of github.com:jantman/gitpython_issue_301 +04b0fce3774f057370451809f620df3300836c8b not-for-merge branch 'testcommit1625' of github.com:jantman/gitpython_issue_301 +995a81f7fa9bb7452433874d3c0bb612716fe29c not-for-merge branch 'testcommit1626' of github.com:jantman/gitpython_issue_301 +13c3b70455fae4f04bdddab4b01e6429de266a1e not-for-merge branch 'testcommit1627' of github.com:jantman/gitpython_issue_301 +c8062aacf300b5a5748833d2b0515ec53084fd36 not-for-merge branch 'testcommit1628' of github.com:jantman/gitpython_issue_301 +2d184ec6eeeb533346eb8ce95143b7d0f41540a8 not-for-merge branch 'testcommit1629' of github.com:jantman/gitpython_issue_301 +6c4c8d47c73597ec5f456ede3378266f73c21a41 not-for-merge branch 'testcommit163' of github.com:jantman/gitpython_issue_301 +7e7e5b0dd00ad3e8c700d0afd31764e70493e024 not-for-merge branch 'testcommit1630' of github.com:jantman/gitpython_issue_301 +7bced094d8258c88c3fcc2f84f29758d46de2532 not-for-merge branch 'testcommit1631' of github.com:jantman/gitpython_issue_301 +9aeb36d25cfacc04a2eb368d630c9c4dfd8dccef not-for-merge branch 'testcommit1632' of github.com:jantman/gitpython_issue_301 +21eea88981978b579c2cd4c0bcc7a094573fe566 not-for-merge branch 'testcommit1633' of github.com:jantman/gitpython_issue_301 +920c716ed0a9ec5fd710a81b7d095954a25738d0 not-for-merge branch 'testcommit1634' of github.com:jantman/gitpython_issue_301 +7be9490bc59a2ebbfe7b6748d8c83844b309230b not-for-merge branch 'testcommit1635' of github.com:jantman/gitpython_issue_301 +cc158b64449fed6974a27fca95dd0283185659ea not-for-merge branch 'testcommit1636' of github.com:jantman/gitpython_issue_301 +0e543cdec8f166a09567e53380902d1fd8a9f289 not-for-merge branch 'testcommit1637' of github.com:jantman/gitpython_issue_301 +a927e6e98f184025c53599c378a81c0068c474c5 not-for-merge branch 'testcommit1638' of github.com:jantman/gitpython_issue_301 +0c02e31c28f55f2947e62db6b6f611f0255b7f86 not-for-merge branch 'testcommit1639' of github.com:jantman/gitpython_issue_301 +8c2edc1a4054b99abffac89fb9cb42035e7d7f05 not-for-merge branch 'testcommit164' of github.com:jantman/gitpython_issue_301 +8257baeb721b1f5da232aaf1561d464b36318dab not-for-merge branch 'testcommit1640' of github.com:jantman/gitpython_issue_301 +dc930c97929121548cf376ba686245f9de115856 not-for-merge branch 'testcommit1641' of github.com:jantman/gitpython_issue_301 +0eef8aa1b6b51f6b570318d3e10030014b6c8f57 not-for-merge branch 'testcommit1642' of github.com:jantman/gitpython_issue_301 +91f581110fa9b277e558636a8d1c0b97dc021a5c not-for-merge branch 'testcommit1643' of github.com:jantman/gitpython_issue_301 +d31e836536e19f411f1d937764ef73d7d4248d8c not-for-merge branch 'testcommit1644' of github.com:jantman/gitpython_issue_301 +acd68ef6c0081ac7e87f59d39d44b3c31226f2be not-for-merge branch 'testcommit1645' of github.com:jantman/gitpython_issue_301 +e31707befd405a946a09a7f590c9d3c0ece10102 not-for-merge branch 'testcommit1646' of github.com:jantman/gitpython_issue_301 +b5552e4a07fbacb942d7701003e69328ccfda217 not-for-merge branch 'testcommit1647' of github.com:jantman/gitpython_issue_301 +8657ec4ec4a69cfa30bca004deeebe8a0763d519 not-for-merge branch 'testcommit1648' of github.com:jantman/gitpython_issue_301 +9f4b001ca5caeaba4d20bec146b860a03c963c59 not-for-merge branch 'testcommit1649' of github.com:jantman/gitpython_issue_301 +5df73ebf4ac671de1b2e312254d0724930e6ecf1 not-for-merge branch 'testcommit165' of github.com:jantman/gitpython_issue_301 +5dee05455b33cf1948a86026ac02cbf147fcd407 not-for-merge branch 'testcommit1650' of github.com:jantman/gitpython_issue_301 +4296f7bbb45fad1127b3f94ee404cd41de46efd8 not-for-merge branch 'testcommit1651' of github.com:jantman/gitpython_issue_301 +e53d9ebcc826e483cdd64d33d343dd392aa2477b not-for-merge branch 'testcommit1652' of github.com:jantman/gitpython_issue_301 +b4e4d76cb8775c8991f049d27d31d2f9ae08b3a2 not-for-merge branch 'testcommit1653' of github.com:jantman/gitpython_issue_301 +4916bc4ea8391f074f6f40c8ad454c320333c8ba not-for-merge branch 'testcommit1654' of github.com:jantman/gitpython_issue_301 +20dda5d66dfc5b3b4c9482c85f6999c5c94a5a96 not-for-merge branch 'testcommit1655' of github.com:jantman/gitpython_issue_301 +d305d8a81f8f97f038b2350224a09e14aa0f1269 not-for-merge branch 'testcommit1656' of github.com:jantman/gitpython_issue_301 +d1ad1a4be6e04374e70000586039451e12e8760e not-for-merge branch 'testcommit1657' of github.com:jantman/gitpython_issue_301 +8599221f04d327bd2e8fe75c8a5978478e5160eb not-for-merge branch 'testcommit1658' of github.com:jantman/gitpython_issue_301 +77e8af461dffc49a65ffafa2069d0637a03b6e2f not-for-merge branch 'testcommit1659' of github.com:jantman/gitpython_issue_301 +e674692376d94e4045297c6605528db48b3f5a65 not-for-merge branch 'testcommit166' of github.com:jantman/gitpython_issue_301 +4a05c50a5fd7964cd344c2bdcfae8b3f7e6c24d6 not-for-merge branch 'testcommit1660' of github.com:jantman/gitpython_issue_301 +db34830bba0949420349112b6576784f90c87d12 not-for-merge branch 'testcommit1661' of github.com:jantman/gitpython_issue_301 +fd3ca37cc312ac5264d527ea5b426ec741422875 not-for-merge branch 'testcommit1662' of github.com:jantman/gitpython_issue_301 +d7a21eac10911c6be058dfde1bdf2a22a3a1ffaf not-for-merge branch 'testcommit1663' of github.com:jantman/gitpython_issue_301 +9838f351ecb571d225a405936be39bf693777970 not-for-merge branch 'testcommit1664' of github.com:jantman/gitpython_issue_301 +67dbdb5df8bcdc1a2797e4d1d18a0cdcef4a87bd not-for-merge branch 'testcommit1665' of github.com:jantman/gitpython_issue_301 +71a0f3be409ab0ecdadb502c7b87f1e488512b2d not-for-merge branch 'testcommit1666' of github.com:jantman/gitpython_issue_301 +e5f3f4f29174b4309d98d3ae1e5b0bf42c86d015 not-for-merge branch 'testcommit1667' of github.com:jantman/gitpython_issue_301 +87b8199de60dc046068d6de09fbd4c5c3159c101 not-for-merge branch 'testcommit1668' of github.com:jantman/gitpython_issue_301 +e483d78d2b9a30d3924ec813578b998ff83daf4b not-for-merge branch 'testcommit1669' of github.com:jantman/gitpython_issue_301 +7b530a2823c61aafffaf33080815aa62d5f03597 not-for-merge branch 'testcommit167' of github.com:jantman/gitpython_issue_301 +cc5109681fceeddd2d238f984ef4b4313a3a5b82 not-for-merge branch 'testcommit1670' of github.com:jantman/gitpython_issue_301 +fafe083a4fffaf64d64f770aaf63b3afe8982f3a not-for-merge branch 'testcommit1671' of github.com:jantman/gitpython_issue_301 +78e289bd27b332f91850dac36c459a1acff62148 not-for-merge branch 'testcommit1672' of github.com:jantman/gitpython_issue_301 +43da7df955813959570889f303c90f40a3f8d1ad not-for-merge branch 'testcommit1673' of github.com:jantman/gitpython_issue_301 +2efda24923ed03c29d1783fd4bb1a28f097ec7cd not-for-merge branch 'testcommit1674' of github.com:jantman/gitpython_issue_301 +2928898d6acf23e430fa0b4690a0d1d8a49054cd not-for-merge branch 'testcommit1675' of github.com:jantman/gitpython_issue_301 +86a620b3e5e169505edf19729d24be503ba3aeda not-for-merge branch 'testcommit1676' of github.com:jantman/gitpython_issue_301 +a8f5fd4ab564d94a5e3d1b6546fdffebec20cbd3 not-for-merge branch 'testcommit1677' of github.com:jantman/gitpython_issue_301 +167ec7cfa902ed4f5398edd20b1eaea6f136d46c not-for-merge branch 'testcommit1678' of github.com:jantman/gitpython_issue_301 +f96260b7d51729e4183185721ae3630ea3dc9afa not-for-merge branch 'testcommit1679' of github.com:jantman/gitpython_issue_301 +9563d15f939b1355c75aa5df204688fbd9b02076 not-for-merge branch 'testcommit168' of github.com:jantman/gitpython_issue_301 +e3edd5b16f3a21d6273def1befe6a1564e1d92e9 not-for-merge branch 'testcommit1680' of github.com:jantman/gitpython_issue_301 +199d30ef89eacc69e4aa0b648f2186679db90201 not-for-merge branch 'testcommit1681' of github.com:jantman/gitpython_issue_301 +7b1b81bef1871fe78825ddb3fa5c3b738485b70b not-for-merge branch 'testcommit1682' of github.com:jantman/gitpython_issue_301 +9732e5be5208ffd53bb520bd023e026ada0d6f9b not-for-merge branch 'testcommit1683' of github.com:jantman/gitpython_issue_301 +64e37147f52bfda924a82fb6c49db7e29d635e5c not-for-merge branch 'testcommit1684' of github.com:jantman/gitpython_issue_301 +83408bc5fc9e795c3f9af1346a236117f58f6017 not-for-merge branch 'testcommit1685' of github.com:jantman/gitpython_issue_301 +d6585114ff811dfbf84777fc450cef310c1f2115 not-for-merge branch 'testcommit1686' of github.com:jantman/gitpython_issue_301 +2c25e972cdd7ffb23a8e8f2035cf3064b451f428 not-for-merge branch 'testcommit1687' of github.com:jantman/gitpython_issue_301 +6be3986e954f06904e42b4112e50c5c94129341c not-for-merge branch 'testcommit1688' of github.com:jantman/gitpython_issue_301 +19cafa3a9a32a15ce962258c20a5aa2f54073421 not-for-merge branch 'testcommit1689' of github.com:jantman/gitpython_issue_301 +abc5208751255a5438a70622e997cd8d8dc8ab8d not-for-merge branch 'testcommit169' of github.com:jantman/gitpython_issue_301 +d2bd80b0b245b5811ea0023b49eb313aa623cc73 not-for-merge branch 'testcommit1690' of github.com:jantman/gitpython_issue_301 +ba5af95bc0bb17dda9153fe3260851f1ba32eef6 not-for-merge branch 'testcommit1691' of github.com:jantman/gitpython_issue_301 +8a5d13ade36d3d13b88ce5a002759eb93d15a530 not-for-merge branch 'testcommit1692' of github.com:jantman/gitpython_issue_301 +3d25478ffe9e5405c55fd3cbfc50f95828416b40 not-for-merge branch 'testcommit1693' of github.com:jantman/gitpython_issue_301 +4f98d634c8ce258af6621b592f8e919714f58591 not-for-merge branch 'testcommit1694' of github.com:jantman/gitpython_issue_301 +80f0c5bbaf098a5a3216eaa5ea3dfa5b0975c67e not-for-merge branch 'testcommit1695' of github.com:jantman/gitpython_issue_301 +497abd3a219636dcce25f7bba1c326f8a5f2a817 not-for-merge branch 'testcommit1696' of github.com:jantman/gitpython_issue_301 +35f0c66a0aa7d66ed49b41a61e587865f377207a not-for-merge branch 'testcommit1697' of github.com:jantman/gitpython_issue_301 +0593838a1e001f484289284579dbb583dc1f629b not-for-merge branch 'testcommit1698' of github.com:jantman/gitpython_issue_301 +75a249673929f0a7b0ef701c2fb78eb22a62f6b7 not-for-merge branch 'testcommit1699' of github.com:jantman/gitpython_issue_301 +f1858aa74ffd6304a8a9d5ce313b203ef6b567c7 not-for-merge branch 'testcommit17' of github.com:jantman/gitpython_issue_301 +eed67e47ef9689d322749c252619e701a8ef6aef not-for-merge branch 'testcommit170' of github.com:jantman/gitpython_issue_301 +13a042f4ec30842a7ad03adb088a90d1ee11a707 not-for-merge branch 'testcommit1700' of github.com:jantman/gitpython_issue_301 +785e72b36b79599f87d1d53e96a1b395c863591d not-for-merge branch 'testcommit1701' of github.com:jantman/gitpython_issue_301 +36e095b5c2d0c8c7b26ed6b3bec5310c09e80038 not-for-merge branch 'testcommit1702' of github.com:jantman/gitpython_issue_301 +39624f00997409b930c3f9b7263ace28a24ec46b not-for-merge branch 'testcommit1703' of github.com:jantman/gitpython_issue_301 +018ffcd8350ab2fd09ad76b754e751153cb0e779 not-for-merge branch 'testcommit1704' of github.com:jantman/gitpython_issue_301 +0c44b134b6ae525bdc43357db545dc2aefd3e829 not-for-merge branch 'testcommit1705' of github.com:jantman/gitpython_issue_301 +3af2130b75088d66af06d7f10fbde7923b4f8c72 not-for-merge branch 'testcommit1706' of github.com:jantman/gitpython_issue_301 +84aa63d7e6565dcbd8056be5c2e7a0ac02660c39 not-for-merge branch 'testcommit1707' of github.com:jantman/gitpython_issue_301 +cf8229f1e6615a6287d35b89f22630150f4ed4ea not-for-merge branch 'testcommit1708' of github.com:jantman/gitpython_issue_301 +435aa1496b33fe020ee2c5ad0e1c82e2c001884c not-for-merge branch 'testcommit1709' of github.com:jantman/gitpython_issue_301 +4bfe3f5cdafe04f558cc75f5c9417b5cd204d664 not-for-merge branch 'testcommit171' of github.com:jantman/gitpython_issue_301 +3cec3aceb6d0d0d071f37c3323a0ea66bc251692 not-for-merge branch 'testcommit1710' of github.com:jantman/gitpython_issue_301 +c419267e954d5b5a8e78366c1f9464d10f9ef42a not-for-merge branch 'testcommit1711' of github.com:jantman/gitpython_issue_301 +2e50eaca740459a048a4e0d03b8068a14a4fd8c9 not-for-merge branch 'testcommit1712' of github.com:jantman/gitpython_issue_301 +05a6360631b25f87169b130488b400046d7e8b72 not-for-merge branch 'testcommit1713' of github.com:jantman/gitpython_issue_301 +d2bef685fd8557ed0c4b6da09be20ab8e5f7c506 not-for-merge branch 'testcommit1714' of github.com:jantman/gitpython_issue_301 +42fc3b6baf3c5359dd3d83cf3b7522756b84f9f2 not-for-merge branch 'testcommit1715' of github.com:jantman/gitpython_issue_301 +977b3f428bc87e3858d32ef0530a9d108fa8ee58 not-for-merge branch 'testcommit1716' of github.com:jantman/gitpython_issue_301 +0c74b5fcef818fc4bc2d79dfbc7a77ff010c669d not-for-merge branch 'testcommit1717' of github.com:jantman/gitpython_issue_301 +81eba4c0c063b9eeeba37019ad99c288d18a1a6e not-for-merge branch 'testcommit1718' of github.com:jantman/gitpython_issue_301 +e115ae2d8cf613bc2f7cdd65849573b9ef655fe7 not-for-merge branch 'testcommit1719' of github.com:jantman/gitpython_issue_301 +feebfa9c558a72f0e6fbf07a410649459394c945 not-for-merge branch 'testcommit172' of github.com:jantman/gitpython_issue_301 +b798a31ddf914cf4e8dce58ea81424085bc828cf not-for-merge branch 'testcommit1720' of github.com:jantman/gitpython_issue_301 +a2f21ad95388b9bdc83f5b036e49ad3a59faf662 not-for-merge branch 'testcommit1721' of github.com:jantman/gitpython_issue_301 +ee3593539a074f157377029ebd457f5ce79c7787 not-for-merge branch 'testcommit1722' of github.com:jantman/gitpython_issue_301 +77c8db37ec1fe95371da2d28b2136ae1e056068d not-for-merge branch 'testcommit1723' of github.com:jantman/gitpython_issue_301 +2a17f54ea840907e3c989964c0d1b25d46700129 not-for-merge branch 'testcommit1724' of github.com:jantman/gitpython_issue_301 +145a72f2ad67e860ab709ac1f0089fcfebd10d7f not-for-merge branch 'testcommit1725' of github.com:jantman/gitpython_issue_301 +1758871b844f23a516b8fd6b7963af1b54c59c7c not-for-merge branch 'testcommit1726' of github.com:jantman/gitpython_issue_301 +249884bba6ffea38e15d79655c078c91edcebbc5 not-for-merge branch 'testcommit1727' of github.com:jantman/gitpython_issue_301 +0c071d79997485324fe04bd53122cc30e5040854 not-for-merge branch 'testcommit1728' of github.com:jantman/gitpython_issue_301 +19ac8fe2266de524d7ae713351589683fc8fce87 not-for-merge branch 'testcommit1729' of github.com:jantman/gitpython_issue_301 +6d25e5ebdf0caea6ffa519101a290681050c9321 not-for-merge branch 'testcommit173' of github.com:jantman/gitpython_issue_301 +a1bc2f8dcefa485f577dcd8ffe8dbf6a364b34aa not-for-merge branch 'testcommit1730' of github.com:jantman/gitpython_issue_301 +5d23f3d3df92019b97ddf9417a993aef2b1d6e6c not-for-merge branch 'testcommit1731' of github.com:jantman/gitpython_issue_301 +d4d4141efc28302ce75b75c624a6e9cadb645735 not-for-merge branch 'testcommit1732' of github.com:jantman/gitpython_issue_301 +e4c216314c7d06fb77eec4653c6083358cb80b42 not-for-merge branch 'testcommit1733' of github.com:jantman/gitpython_issue_301 +56f2f7abe4be1fa5400bd64324f9aa1a4a1356fc not-for-merge branch 'testcommit1734' of github.com:jantman/gitpython_issue_301 +8a133817b56f84bca0cb5b08e2e7f18d5fae2dea not-for-merge branch 'testcommit1735' of github.com:jantman/gitpython_issue_301 +cbd17f293f7737d27471de54073d774462ba0315 not-for-merge branch 'testcommit1736' of github.com:jantman/gitpython_issue_301 +da693e68d6a432f0278f86cdcea9e183a0aa6c9a not-for-merge branch 'testcommit1737' of github.com:jantman/gitpython_issue_301 +3b853c103bb5c93f694101404809a1110e777e76 not-for-merge branch 'testcommit1738' of github.com:jantman/gitpython_issue_301 +afa244ffaf28e8c1dfd0d9429057ba1179a9d87a not-for-merge branch 'testcommit1739' of github.com:jantman/gitpython_issue_301 +b8db4b8a962025e7928600519fee10d8f31ca989 not-for-merge branch 'testcommit174' of github.com:jantman/gitpython_issue_301 +94ab1e714c30005895b1f5071d087036f9438fbf not-for-merge branch 'testcommit1740' of github.com:jantman/gitpython_issue_301 +7584b60ce88fceff1934fe33d56d99b4e707b6eb not-for-merge branch 'testcommit1741' of github.com:jantman/gitpython_issue_301 +3c04882b298516750a420e3b86b8cead611de556 not-for-merge branch 'testcommit1742' of github.com:jantman/gitpython_issue_301 +ff0ff2b4f3fc4a56e2039f5bcc1d4b48fa4694d4 not-for-merge branch 'testcommit1743' of github.com:jantman/gitpython_issue_301 +c944606356fa772421d63a3831872fa80759e1ea not-for-merge branch 'testcommit1744' of github.com:jantman/gitpython_issue_301 +c037dfc37769bf098ccc35ea17f13da4b091d467 not-for-merge branch 'testcommit1745' of github.com:jantman/gitpython_issue_301 +f8243d6265cb83171b849430b08e6b9e0aaca2a1 not-for-merge branch 'testcommit1746' of github.com:jantman/gitpython_issue_301 +4b8de2e6244f8e075fe9835cb0691620c2f55e40 not-for-merge branch 'testcommit1747' of github.com:jantman/gitpython_issue_301 +c44f79a7389a42f179b1ca35e67ec73b66793c85 not-for-merge branch 'testcommit1748' of github.com:jantman/gitpython_issue_301 +ca07212a570425fb258d6c48e11c406f41e9768f not-for-merge branch 'testcommit1749' of github.com:jantman/gitpython_issue_301 +a389ebf629081e793e11aa2badbbcd4c9e4c9b6b not-for-merge branch 'testcommit175' of github.com:jantman/gitpython_issue_301 +7036826e32b137bf3f8c03c4869094e4fc8cacdf not-for-merge branch 'testcommit1750' of github.com:jantman/gitpython_issue_301 +b79ee8f3977272c3e7fa65a885c2869ea698c6be not-for-merge branch 'testcommit1751' of github.com:jantman/gitpython_issue_301 +656cfcd61b9176741c238d42d0ff67b736213eab not-for-merge branch 'testcommit1752' of github.com:jantman/gitpython_issue_301 +09ab47f528fdafd11674e6feccfea970759e95d1 not-for-merge branch 'testcommit1753' of github.com:jantman/gitpython_issue_301 +12791a995ca7bbec5894bc4587218a5574375bcd not-for-merge branch 'testcommit1754' of github.com:jantman/gitpython_issue_301 +505dfb948521eb672d89964910099355ac05f352 not-for-merge branch 'testcommit1755' of github.com:jantman/gitpython_issue_301 +18d988ce7f21409100bf908af9a65ceec88fbbbc not-for-merge branch 'testcommit1756' of github.com:jantman/gitpython_issue_301 +464f7eb01a67f0f4b1a5527c2f6cb9fb0b902850 not-for-merge branch 'testcommit1757' of github.com:jantman/gitpython_issue_301 +7777f0b27b5b4b616af3a25800ca039ce5f64735 not-for-merge branch 'testcommit1758' of github.com:jantman/gitpython_issue_301 +2cf2e156711c8447d38135ab891ef7ab99f8909f not-for-merge branch 'testcommit1759' of github.com:jantman/gitpython_issue_301 +680f52a755dd762cbfb8ce63690325f1018dd2eb not-for-merge branch 'testcommit176' of github.com:jantman/gitpython_issue_301 +a2d8e82487ee3c81d162b62c86077d783b5f2f0a not-for-merge branch 'testcommit1760' of github.com:jantman/gitpython_issue_301 +e4d2ab7181728e5cd3ebbec114aeac3c75cc1fc5 not-for-merge branch 'testcommit1761' of github.com:jantman/gitpython_issue_301 +d70382a7fe3fa38c3b601dba1b5739d56e8dd3ee not-for-merge branch 'testcommit1762' of github.com:jantman/gitpython_issue_301 +5457883dcff74f97364ac2d24473153c7b54ef4f not-for-merge branch 'testcommit1763' of github.com:jantman/gitpython_issue_301 +c05964492e4f7123a57e8311c7785ba1612c916c not-for-merge branch 'testcommit1764' of github.com:jantman/gitpython_issue_301 +8bdc0ddcf11ffde4de2b07c8d8e37b7a38832f4e not-for-merge branch 'testcommit1765' of github.com:jantman/gitpython_issue_301 +16ba021ab2b9b12d3f50f3c84be0cd64e7a3493b not-for-merge branch 'testcommit1766' of github.com:jantman/gitpython_issue_301 +4c7982e81a053dd4fd4a6eef04ea254cafa4d1cc not-for-merge branch 'testcommit1767' of github.com:jantman/gitpython_issue_301 +c1e49bf2a2cca4c225672e9f1312fb2dca985eac not-for-merge branch 'testcommit1768' of github.com:jantman/gitpython_issue_301 +ed8ce226415a90a7b5b26471a2a60abd3c2a777c not-for-merge branch 'testcommit1769' of github.com:jantman/gitpython_issue_301 +7e1689d99dcd2dcf9b61167ca76eed38efb97727 not-for-merge branch 'testcommit177' of github.com:jantman/gitpython_issue_301 +7c51dacd4c870dbf7d01a6a6ccfc38f99a021648 not-for-merge branch 'testcommit1770' of github.com:jantman/gitpython_issue_301 +038b7879a64314c75c926714f582c64701a720a7 not-for-merge branch 'testcommit1771' of github.com:jantman/gitpython_issue_301 +8e1c3c9a0c6324043e1df49bb6fafcaefaa250c3 not-for-merge branch 'testcommit1772' of github.com:jantman/gitpython_issue_301 +e4682c8a580ae53f7205e37c9a7c61ef56e6e343 not-for-merge branch 'testcommit1773' of github.com:jantman/gitpython_issue_301 +1ef48c413c83915ef69df200749fee774589f37b not-for-merge branch 'testcommit1774' of github.com:jantman/gitpython_issue_301 +c85c2b03553a893b79c43dc8ce02b517274b7641 not-for-merge branch 'testcommit1775' of github.com:jantman/gitpython_issue_301 +1ebf97ca05f0786164baf5df37da6092e25bec7c not-for-merge branch 'testcommit1776' of github.com:jantman/gitpython_issue_301 +1b73e428e2d807f7aab05ade12b578363ac95f54 not-for-merge branch 'testcommit1777' of github.com:jantman/gitpython_issue_301 +8094124c88dc71694e345cd4bcdab17ea77685b0 not-for-merge branch 'testcommit1778' of github.com:jantman/gitpython_issue_301 +5aac80e94f8f6d7d3dcbfafdf53684ba780a472a not-for-merge branch 'testcommit1779' of github.com:jantman/gitpython_issue_301 +337a2c620365d535a8806cb8a97611498f546393 not-for-merge branch 'testcommit178' of github.com:jantman/gitpython_issue_301 +88bb4d19ac7c33ec8cf790afe1969adb2fa8fa20 not-for-merge branch 'testcommit1780' of github.com:jantman/gitpython_issue_301 +4fa805cb667c45017a2793a1dbfc42c0da826f38 not-for-merge branch 'testcommit1781' of github.com:jantman/gitpython_issue_301 +b0eea3a2bf5fb9b2255dc2573bc5566900081b83 not-for-merge branch 'testcommit1782' of github.com:jantman/gitpython_issue_301 +e7184bdd13fec2dbe1da840df93afa9763187816 not-for-merge branch 'testcommit1783' of github.com:jantman/gitpython_issue_301 +915764496d5848526ad6f5e7f3ef927475fe28b0 not-for-merge branch 'testcommit1784' of github.com:jantman/gitpython_issue_301 +f896d8c33441a1330fadd8cd6b0976e51f7eeb92 not-for-merge branch 'testcommit1785' of github.com:jantman/gitpython_issue_301 +7d0265049fda8818295ed80306966f813f718adf not-for-merge branch 'testcommit1786' of github.com:jantman/gitpython_issue_301 +b36a62c3c7ab58bc5f1477053811fc0eff603334 not-for-merge branch 'testcommit1787' of github.com:jantman/gitpython_issue_301 +383dc5e6dbfb51e0f2496c7459ef6008c1224800 not-for-merge branch 'testcommit1788' of github.com:jantman/gitpython_issue_301 +2dcb853f11cb77c1e92693e79196a18cbb967427 not-for-merge branch 'testcommit1789' of github.com:jantman/gitpython_issue_301 +34bfa9918224ab28801b902dc941aeb19a6b6a6e not-for-merge branch 'testcommit179' of github.com:jantman/gitpython_issue_301 +ee89f56a65bc2359f9f19811e82ad65a5bbcc5a6 not-for-merge branch 'testcommit1790' of github.com:jantman/gitpython_issue_301 +59211de8b846411a4189ac423edb8c3111428581 not-for-merge branch 'testcommit1791' of github.com:jantman/gitpython_issue_301 +86eb74e96cc9024c42801b656bd9dbb97ba396e2 not-for-merge branch 'testcommit1792' of github.com:jantman/gitpython_issue_301 +9f4ce593ecf8e2c8715121e608fd0f6e3ac720e3 not-for-merge branch 'testcommit1793' of github.com:jantman/gitpython_issue_301 +d85543e5da4962a757ffb05d1e8c272f36610fa6 not-for-merge branch 'testcommit1794' of github.com:jantman/gitpython_issue_301 +858c367cac3a2f802b7d43ef8ed1d39ed7c92bac not-for-merge branch 'testcommit1795' of github.com:jantman/gitpython_issue_301 +48b880232a584b1638f9b4f387253cefac5e0b19 not-for-merge branch 'testcommit1796' of github.com:jantman/gitpython_issue_301 +c19ddaaa777f015917700db5e4a0b473ffa23228 not-for-merge branch 'testcommit1797' of github.com:jantman/gitpython_issue_301 +183c27cea9542f9eaf00652690f714118b82e497 not-for-merge branch 'testcommit1798' of github.com:jantman/gitpython_issue_301 +d43c27e4a2f796107cc820ec64e88bc548a4908c not-for-merge branch 'testcommit1799' of github.com:jantman/gitpython_issue_301 +266da296b8352ac64d930db071b4708fa16a8e61 not-for-merge branch 'testcommit18' of github.com:jantman/gitpython_issue_301 +a39f025c550653974adc776389cfe2872902f2d8 not-for-merge branch 'testcommit180' of github.com:jantman/gitpython_issue_301 +7ea3d120db4efdf3d9f1a90187596b7382dbe44a not-for-merge branch 'testcommit1800' of github.com:jantman/gitpython_issue_301 +a6e9f6ee8b3b861e78d798fd021295107942ec00 not-for-merge branch 'testcommit1801' of github.com:jantman/gitpython_issue_301 +804061be93cabcb9e16e146e5c5272e548647ab9 not-for-merge branch 'testcommit1802' of github.com:jantman/gitpython_issue_301 +57c3909407e1de7cddeec1831d3fc524ce2dbca0 not-for-merge branch 'testcommit1803' of github.com:jantman/gitpython_issue_301 +e4a9777ec6ea2c932781d8000b6be72873602eb9 not-for-merge branch 'testcommit1804' of github.com:jantman/gitpython_issue_301 +85c2a6c6077cc988838634ca47de8f2e30ee09a4 not-for-merge branch 'testcommit1805' of github.com:jantman/gitpython_issue_301 +8213cefa3cc56a1471c9458598e1330ac54a0491 not-for-merge branch 'testcommit1806' of github.com:jantman/gitpython_issue_301 +42969669be9bb1793a5d5bff0dbe7ba950975032 not-for-merge branch 'testcommit1807' of github.com:jantman/gitpython_issue_301 +3a97c3b910d8fc187e4ebee831eedbeeadd48cf7 not-for-merge branch 'testcommit1808' of github.com:jantman/gitpython_issue_301 +485ae429b26eccae13376af0c437f3b82b85bc1d not-for-merge branch 'testcommit1809' of github.com:jantman/gitpython_issue_301 +b218cd50685d0d340099d6b2421ce68afed3668e not-for-merge branch 'testcommit181' of github.com:jantman/gitpython_issue_301 +f1de28491a8fdcc1d8a623f848d7544c17832d28 not-for-merge branch 'testcommit1810' of github.com:jantman/gitpython_issue_301 +3e335a23bf3b183a42e48f68f27499e8f89d483f not-for-merge branch 'testcommit1811' of github.com:jantman/gitpython_issue_301 +1aef53acb7aada8cd66a7e2bd5470af3be70848b not-for-merge branch 'testcommit1812' of github.com:jantman/gitpython_issue_301 +f6ef449a7fd6585f1ff7102e9efd2cd0eb8fa444 not-for-merge branch 'testcommit1813' of github.com:jantman/gitpython_issue_301 +4664a12e68eebb4b989e18bd8fb3f9311ad31fdd not-for-merge branch 'testcommit1814' of github.com:jantman/gitpython_issue_301 +e866a69b8f1b41f714e2bce9960f0b928ffd1ed7 not-for-merge branch 'testcommit1815' of github.com:jantman/gitpython_issue_301 +b616d4e319ffc189378adb8df71262fb1cfc38f2 not-for-merge branch 'testcommit1816' of github.com:jantman/gitpython_issue_301 +f2d6c738bf0496e8b7cd716281af360dbe8cd0cc not-for-merge branch 'testcommit1817' of github.com:jantman/gitpython_issue_301 +c620aa5797ea5a95193caa66081835b9e0cc863d not-for-merge branch 'testcommit1818' of github.com:jantman/gitpython_issue_301 +b9c8b579e7a65d8121e76680174cfe49332d6cc1 not-for-merge branch 'testcommit1819' of github.com:jantman/gitpython_issue_301 +3fc529676fbe17fe0ee98d61ea51e458fd2f4981 not-for-merge branch 'testcommit182' of github.com:jantman/gitpython_issue_301 +35f3f4ee8532e4102de68601447dbed817ec1146 not-for-merge branch 'testcommit1820' of github.com:jantman/gitpython_issue_301 +569528e9b8ea723b17f47a38eb9a7a7fdfda8ca0 not-for-merge branch 'testcommit1821' of github.com:jantman/gitpython_issue_301 +b18ddc6f8b13e69a0b494332a7b39f5a185f11b3 not-for-merge branch 'testcommit1822' of github.com:jantman/gitpython_issue_301 +d8447475015455a3c4354d319172b671775805fc not-for-merge branch 'testcommit1823' of github.com:jantman/gitpython_issue_301 +7444b7324d6db09eabbb55f427d1cfe93139fe10 not-for-merge branch 'testcommit1824' of github.com:jantman/gitpython_issue_301 +f20141cf3ed002349e1370a7afd46ca897f403ac not-for-merge branch 'testcommit1825' of github.com:jantman/gitpython_issue_301 +978999a7dbf7df440674145fca017b4831e0699a not-for-merge branch 'testcommit1826' of github.com:jantman/gitpython_issue_301 +2cae161128dce81a9e32af949c280feae2d246b0 not-for-merge branch 'testcommit1827' of github.com:jantman/gitpython_issue_301 +ee7d8c2c04378b50a4aeca245190a2844982aa68 not-for-merge branch 'testcommit1828' of github.com:jantman/gitpython_issue_301 +8867ff6c7957ca8ebd7288165e2fb3862b642360 not-for-merge branch 'testcommit1829' of github.com:jantman/gitpython_issue_301 +780c632a91974acff1834312edcfd1bda1c536d2 not-for-merge branch 'testcommit183' of github.com:jantman/gitpython_issue_301 +a1cc2f742303af886466dd7dab4a099a99fc32a1 not-for-merge branch 'testcommit1830' of github.com:jantman/gitpython_issue_301 +2c56bd79ff43c088498ec3d5fb8fc3db30bde07f not-for-merge branch 'testcommit1831' of github.com:jantman/gitpython_issue_301 +5da9f9bd17a36c89ad4c3f94cdc8e884e1a03ded not-for-merge branch 'testcommit1832' of github.com:jantman/gitpython_issue_301 +ae4093938cbbf54b7e74d0e6055f53cc864e7536 not-for-merge branch 'testcommit1833' of github.com:jantman/gitpython_issue_301 +84808c336d3a13c0ff29df712e84ed49fca3bce4 not-for-merge branch 'testcommit1834' of github.com:jantman/gitpython_issue_301 +ce6e47d20bac6d1a2a2715fa9d648dc3a3f2506c not-for-merge branch 'testcommit1835' of github.com:jantman/gitpython_issue_301 +ad31adcf5dc691286ec0c20c002cea7ecc12d4b2 not-for-merge branch 'testcommit1836' of github.com:jantman/gitpython_issue_301 +41f8aac0b083e61972565bd2bbf7891fb73abe7e not-for-merge branch 'testcommit1837' of github.com:jantman/gitpython_issue_301 +870e0b08349ef131d8d264da5fff15eb83e914e4 not-for-merge branch 'testcommit1838' of github.com:jantman/gitpython_issue_301 +a5fd1d028453c37372b322d1d608c28e81f5c420 not-for-merge branch 'testcommit1839' of github.com:jantman/gitpython_issue_301 +20658778ac5ed481db9ea80e95f1d8752c188ac6 not-for-merge branch 'testcommit184' of github.com:jantman/gitpython_issue_301 +2e3026f5b46660df7b73227fb92a5adfb1817810 not-for-merge branch 'testcommit1840' of github.com:jantman/gitpython_issue_301 +5578d0f801419114409867b90ed19226949ea205 not-for-merge branch 'testcommit1841' of github.com:jantman/gitpython_issue_301 +6d43300cf93c03325a7bb4a2a461a50e02f9df6e not-for-merge branch 'testcommit1842' of github.com:jantman/gitpython_issue_301 +1f4a10a6d9cca6d103dc73bb2526a167ba74623f not-for-merge branch 'testcommit1843' of github.com:jantman/gitpython_issue_301 +b1e489f194ed7e33631c50599397f5f98ca905fb not-for-merge branch 'testcommit1844' of github.com:jantman/gitpython_issue_301 +74b22f3fa9499603b35265bd769d11e145202a2c not-for-merge branch 'testcommit1845' of github.com:jantman/gitpython_issue_301 +73a7a34b2e4a325f66f90e30a962e119b84bb016 not-for-merge branch 'testcommit1846' of github.com:jantman/gitpython_issue_301 +953e9ecead0933d084edc3cbb94a398658a96a86 not-for-merge branch 'testcommit1847' of github.com:jantman/gitpython_issue_301 +f9d67de25b470ea080e9e0d755bf5b761c3b41dc not-for-merge branch 'testcommit1848' of github.com:jantman/gitpython_issue_301 +5bcc71603f97f457e270eaa7c00d693055b3494c not-for-merge branch 'testcommit1849' of github.com:jantman/gitpython_issue_301 +b5d08f76dca1410680a9d8720f429d780d192ae2 not-for-merge branch 'testcommit185' of github.com:jantman/gitpython_issue_301 +05faabf11011feabe8874a39ac3adc1aa0a82f6c not-for-merge branch 'testcommit1850' of github.com:jantman/gitpython_issue_301 +a4a2375e3d4200e86c2c0971708a757c43a10f3b not-for-merge branch 'testcommit1851' of github.com:jantman/gitpython_issue_301 +9e4d1e8aa308c65fcaeb0865de2c3e7c13ae0f25 not-for-merge branch 'testcommit1852' of github.com:jantman/gitpython_issue_301 +83dc080d2d8c303f8635c2b539a7325ccc4e1d41 not-for-merge branch 'testcommit1853' of github.com:jantman/gitpython_issue_301 +41fcbbc29b8d5cf072d73850d36c7aacaef7ace7 not-for-merge branch 'testcommit1854' of github.com:jantman/gitpython_issue_301 +867bd112b5b3e04883ff78593f9a69f2132157cc not-for-merge branch 'testcommit1855' of github.com:jantman/gitpython_issue_301 +6fe4083b87ebfb975179b6254fe183efa6becdd6 not-for-merge branch 'testcommit1856' of github.com:jantman/gitpython_issue_301 +2892280e7769749260729581c525bcdf1501e040 not-for-merge branch 'testcommit1857' of github.com:jantman/gitpython_issue_301 +8f66c277db601e992c1bf9527a7c075aa4b9298c not-for-merge branch 'testcommit1858' of github.com:jantman/gitpython_issue_301 +3a9b11e5f46efe9cfdf5583d57b7b1d7158aabbc not-for-merge branch 'testcommit1859' of github.com:jantman/gitpython_issue_301 +df67e67a8177edc60ccb88748e8fdc13c6e892b3 not-for-merge branch 'testcommit186' of github.com:jantman/gitpython_issue_301 +4237e91283d333ae37f1d3c631e938e0346d638c not-for-merge branch 'testcommit1860' of github.com:jantman/gitpython_issue_301 +2f679ff04fd269e77154d64fce7217f1a9a4cd17 not-for-merge branch 'testcommit1861' of github.com:jantman/gitpython_issue_301 +600b88357afb29e0daa124ac0e4506a7e3aecdba not-for-merge branch 'testcommit1862' of github.com:jantman/gitpython_issue_301 +72016792bd5142a9c334a4a0e9aebc794d2ee64f not-for-merge branch 'testcommit1863' of github.com:jantman/gitpython_issue_301 +a9530a54d7ab0354039f37c274d3647151769e73 not-for-merge branch 'testcommit1864' of github.com:jantman/gitpython_issue_301 +604fbdda57b3380c01923bbd0308ac232d57ea2c not-for-merge branch 'testcommit1865' of github.com:jantman/gitpython_issue_301 +3e09ac8fae95622e48c2efca65fcfdd25be8f546 not-for-merge branch 'testcommit1866' of github.com:jantman/gitpython_issue_301 +ed47de3fd958bab5ebd4ab9c1793e38938a08f2d not-for-merge branch 'testcommit1867' of github.com:jantman/gitpython_issue_301 +d00e57ab856270aac66ea834b2548318d64683f5 not-for-merge branch 'testcommit1868' of github.com:jantman/gitpython_issue_301 +5f2cdfa6e75b414b9c96c55828a33b4f764a4045 not-for-merge branch 'testcommit1869' of github.com:jantman/gitpython_issue_301 +db7ad70804c3ccfb62289030984d092d3e65ba55 not-for-merge branch 'testcommit187' of github.com:jantman/gitpython_issue_301 +fb8fcf39db46332b5fc18ddbb859722a8a100425 not-for-merge branch 'testcommit1870' of github.com:jantman/gitpython_issue_301 +c6669a89c2c72fa9c27eb6f9209da561f9f7e16a not-for-merge branch 'testcommit1871' of github.com:jantman/gitpython_issue_301 +d85ada1987bec8d624269c6533104405b7a57b4f not-for-merge branch 'testcommit1872' of github.com:jantman/gitpython_issue_301 +2f26942eed17b5411afffa3bba43508dc8e0a4ea not-for-merge branch 'testcommit1873' of github.com:jantman/gitpython_issue_301 +3ec3023cc52d12796c687782ff4bfa44311a47b6 not-for-merge branch 'testcommit1874' of github.com:jantman/gitpython_issue_301 +1de9b4ea31ba7b943cf894184c0a1dee2c588591 not-for-merge branch 'testcommit1875' of github.com:jantman/gitpython_issue_301 +036d33e27bb548bb00361672726bc58eaafb8fac not-for-merge branch 'testcommit1876' of github.com:jantman/gitpython_issue_301 +d77378ba3adfe4757f10177cd5c0820d39895a76 not-for-merge branch 'testcommit1877' of github.com:jantman/gitpython_issue_301 +d2fa4853ab409e3de448388a61acc9229cfd2e25 not-for-merge branch 'testcommit1878' of github.com:jantman/gitpython_issue_301 +3a37ac453453a13acd6129281444a66410eee34a not-for-merge branch 'testcommit1879' of github.com:jantman/gitpython_issue_301 +213750fda1ca114664ecaae18907db9acebf365f not-for-merge branch 'testcommit188' of github.com:jantman/gitpython_issue_301 +fa5023261ea9bedc302cbb767ece2fdb0707dd94 not-for-merge branch 'testcommit1880' of github.com:jantman/gitpython_issue_301 +ee3848220ae1dc40a55397f145718e030e157250 not-for-merge branch 'testcommit1881' of github.com:jantman/gitpython_issue_301 +9879f03bdb8ccaf2a3bd1e578dfbcfd75f3fd0d4 not-for-merge branch 'testcommit1882' of github.com:jantman/gitpython_issue_301 +6fc002dc221dbd2e4f87e3e5ef7fc4e31d49c05d not-for-merge branch 'testcommit1883' of github.com:jantman/gitpython_issue_301 +1be1b0042d5548ce9a8e0b478a84969dfb3b761f not-for-merge branch 'testcommit1884' of github.com:jantman/gitpython_issue_301 +f7edee3809ecbcfc40ae8cff9a749df059716c8b not-for-merge branch 'testcommit1885' of github.com:jantman/gitpython_issue_301 +989b0dfe78b9203a6b6c748f2496eabdcd0ff332 not-for-merge branch 'testcommit1886' of github.com:jantman/gitpython_issue_301 +64627515852dc163a3e994d686254ef79a9d3e73 not-for-merge branch 'testcommit1887' of github.com:jantman/gitpython_issue_301 +218bf90069181de27a07341e16382fc770ebe103 not-for-merge branch 'testcommit1888' of github.com:jantman/gitpython_issue_301 +4467172bc7f066f1ec71182d682e183cfaad3640 not-for-merge branch 'testcommit1889' of github.com:jantman/gitpython_issue_301 +9ee056b8b66566801c1ad03408992000225890f0 not-for-merge branch 'testcommit189' of github.com:jantman/gitpython_issue_301 +6e9107a5c3f636eba3e8b6384883091124112bf5 not-for-merge branch 'testcommit1890' of github.com:jantman/gitpython_issue_301 +90417ade803f6fc49f189971e3dc248f86dc0717 not-for-merge branch 'testcommit1891' of github.com:jantman/gitpython_issue_301 +b421ed8dae75691ef86e8b39121abd2d6c0c1cec not-for-merge branch 'testcommit1892' of github.com:jantman/gitpython_issue_301 +7189f28c476083dc9cfd4ed46679b3555130f61c not-for-merge branch 'testcommit1893' of github.com:jantman/gitpython_issue_301 +8af7998de46c2a951d19243a67f2e4480c30da48 not-for-merge branch 'testcommit1894' of github.com:jantman/gitpython_issue_301 +6e1be6146a3fab7dc49435db2f3074c1a14a64d1 not-for-merge branch 'testcommit1895' of github.com:jantman/gitpython_issue_301 +25c44412f5cd70c96a1f10f04fbf69d2b6bdacb5 not-for-merge branch 'testcommit1896' of github.com:jantman/gitpython_issue_301 +dc88de9f5c26c37a1ad38be1826bffd8f0a01baf not-for-merge branch 'testcommit1897' of github.com:jantman/gitpython_issue_301 +3b6cb9a9224dc96917e180eb6e504618b8a1891b not-for-merge branch 'testcommit1898' of github.com:jantman/gitpython_issue_301 +5dc35df7933809e15c5f0ba1c780ee7b63b1564d not-for-merge branch 'testcommit1899' of github.com:jantman/gitpython_issue_301 +220aaf1a08f0ac3d63f4eb5e2b30567d7853943b not-for-merge branch 'testcommit19' of github.com:jantman/gitpython_issue_301 +f53cd8b70e08bd30b27355af50f4ed2c8dffa59c not-for-merge branch 'testcommit190' of github.com:jantman/gitpython_issue_301 +c511c9b48f5ed3f912060780cdb488ca17c712a1 not-for-merge branch 'testcommit1900' of github.com:jantman/gitpython_issue_301 +923bbdac8a194c569d4e9bb18e57f00114fecb97 not-for-merge branch 'testcommit1901' of github.com:jantman/gitpython_issue_301 +93f3861e25d152b0d0ed10f1d712f213b3b10509 not-for-merge branch 'testcommit1902' of github.com:jantman/gitpython_issue_301 +88fb82bdf8c750c3676e27bfccaa6e18c0138f51 not-for-merge branch 'testcommit1903' of github.com:jantman/gitpython_issue_301 +adafd95ca199b546ff57ba93483394bfec3708ed not-for-merge branch 'testcommit1904' of github.com:jantman/gitpython_issue_301 +1686018fcac0aa8b054d38ba29a5459655886f12 not-for-merge branch 'testcommit1905' of github.com:jantman/gitpython_issue_301 +0d6a17df7f7e162e5d35939eaf73e2b0d8fd12f2 not-for-merge branch 'testcommit1906' of github.com:jantman/gitpython_issue_301 +291d931b731bc7499c5baa31d8e2edbb5693270e not-for-merge branch 'testcommit1907' of github.com:jantman/gitpython_issue_301 +83d5c871907a96c1e175097534e0063f328d3b5e not-for-merge branch 'testcommit1908' of github.com:jantman/gitpython_issue_301 +6fbe2161e2a1bf892d1a12f94460b1dc61f66300 not-for-merge branch 'testcommit1909' of github.com:jantman/gitpython_issue_301 +d473b288492a2a19b5690bcc031c48d66fb54634 not-for-merge branch 'testcommit191' of github.com:jantman/gitpython_issue_301 +5ae9cf3b1ffc833b6478da483c33ef8f689687cc not-for-merge branch 'testcommit1910' of github.com:jantman/gitpython_issue_301 +f5b58a81dc338df3dbc6e3e91276c39a40220591 not-for-merge branch 'testcommit1911' of github.com:jantman/gitpython_issue_301 +ddd81ed64b1ee518057547b746a6397da5354f9e not-for-merge branch 'testcommit1912' of github.com:jantman/gitpython_issue_301 +8496fd9edac6b1884a67b83ec325680079fdd988 not-for-merge branch 'testcommit1913' of github.com:jantman/gitpython_issue_301 +1cecb1472a8bef0642319a1075b933e8370dbd73 not-for-merge branch 'testcommit1914' of github.com:jantman/gitpython_issue_301 +18789d62daf6a555d7a9114c302cf70431fb0a26 not-for-merge branch 'testcommit1915' of github.com:jantman/gitpython_issue_301 +680e5f74e22c22b424b57a1a7bec05fcd65f75fc not-for-merge branch 'testcommit1916' of github.com:jantman/gitpython_issue_301 +52982dd3c3b301aa492dc7d071e5bea6f02eb394 not-for-merge branch 'testcommit1917' of github.com:jantman/gitpython_issue_301 +7dabf5246dbd92d700f18c8f654ff8514f74bfe2 not-for-merge branch 'testcommit1918' of github.com:jantman/gitpython_issue_301 +32b3929c977aa6669df40942889662d1e4a0bb53 not-for-merge branch 'testcommit1919' of github.com:jantman/gitpython_issue_301 +0d2e9dccf2db1a5ebccc446d45bb92560e0671d6 not-for-merge branch 'testcommit192' of github.com:jantman/gitpython_issue_301 +693abc79496c543c6ecfcfd34f03b18aa8d20714 not-for-merge branch 'testcommit1920' of github.com:jantman/gitpython_issue_301 +de6586a141c3ba21015d382d09485271bca82e6a not-for-merge branch 'testcommit1921' of github.com:jantman/gitpython_issue_301 +98325a18d3d783b687bfd5a79425d772b014b8ae not-for-merge branch 'testcommit1922' of github.com:jantman/gitpython_issue_301 +f81c14aa29872bb0bf0e4e75d5aa5965f497d19c not-for-merge branch 'testcommit1923' of github.com:jantman/gitpython_issue_301 +99eac10f66303a3380ef70b80a5e39c5b52c0d4d not-for-merge branch 'testcommit1924' of github.com:jantman/gitpython_issue_301 +fae3b74591bacd155c3ef0ea977f44bcf5dad2f0 not-for-merge branch 'testcommit1925' of github.com:jantman/gitpython_issue_301 +89b9c61f8d0e5378c70e52b1d73e57d4c091f1a6 not-for-merge branch 'testcommit1926' of github.com:jantman/gitpython_issue_301 +3197ac4831d5bfb8691454608d3cafc9c7e3c93b not-for-merge branch 'testcommit1927' of github.com:jantman/gitpython_issue_301 +891b92af0a2aea94bbe606774db75387e45b3e95 not-for-merge branch 'testcommit1928' of github.com:jantman/gitpython_issue_301 +cc20c764b80e997f8170da4626a2f79b83fcf93e not-for-merge branch 'testcommit1929' of github.com:jantman/gitpython_issue_301 +5508cd0f6b52a7f6a0685b4d0e380462b0443fcb not-for-merge branch 'testcommit193' of github.com:jantman/gitpython_issue_301 +328fd7c99087f84cf66f9f9bd66b2ccee60c1a3a not-for-merge branch 'testcommit1930' of github.com:jantman/gitpython_issue_301 +5919f2872aa4523a2cc24e9f0cfeb36c0bb9f7c5 not-for-merge branch 'testcommit1931' of github.com:jantman/gitpython_issue_301 +6c98df3f6e1928f3d5c2e760aec27781e15e3350 not-for-merge branch 'testcommit1932' of github.com:jantman/gitpython_issue_301 +b0da6afecaa7a46dddae3faefe45b531a2ffdbaf not-for-merge branch 'testcommit1933' of github.com:jantman/gitpython_issue_301 +3b488f746b8103b0538258026c98a3b1888dcbbb not-for-merge branch 'testcommit1934' of github.com:jantman/gitpython_issue_301 +a47fc611318333eebdd408ae00302605018b09de not-for-merge branch 'testcommit1935' of github.com:jantman/gitpython_issue_301 +c26d1c29b49a47c7931ba74c0aa432e662e70cec not-for-merge branch 'testcommit1936' of github.com:jantman/gitpython_issue_301 +85defd47144200dc9e46952f919ba238ce43669b not-for-merge branch 'testcommit1937' of github.com:jantman/gitpython_issue_301 +b6ca1685ff3f478a3b1b586b5a33be9bafa792f2 not-for-merge branch 'testcommit1938' of github.com:jantman/gitpython_issue_301 +b3be66c05a8a441c5f12f2efff179cb540562b48 not-for-merge branch 'testcommit1939' of github.com:jantman/gitpython_issue_301 +543b87fc78bdcc49d5671c0a62c1d5105ec77d38 not-for-merge branch 'testcommit194' of github.com:jantman/gitpython_issue_301 +0b959dd020661964c8218ea5de5599ab984220c2 not-for-merge branch 'testcommit1940' of github.com:jantman/gitpython_issue_301 +1faf86aa17e7ad5ff7b23eb4c16e38ef8f2d0690 not-for-merge branch 'testcommit1941' of github.com:jantman/gitpython_issue_301 +0b939dff38392cb14848fb290eee9c95edcde0b9 not-for-merge branch 'testcommit1942' of github.com:jantman/gitpython_issue_301 +a47e40fdd6dc56d7425b06ecea583c165c9c13b7 not-for-merge branch 'testcommit1943' of github.com:jantman/gitpython_issue_301 +4144729c03059784bb0343ac92979430bcae6f4b not-for-merge branch 'testcommit1944' of github.com:jantman/gitpython_issue_301 +ec9b84d239228b0ef8c0782939be5848305b81b0 not-for-merge branch 'testcommit1945' of github.com:jantman/gitpython_issue_301 +cfd09461d0cb2383e3ea5139abcf28048f25adde not-for-merge branch 'testcommit1946' of github.com:jantman/gitpython_issue_301 +dfcb171ff0a332a4953e0caf9cabd7250fe0947d not-for-merge branch 'testcommit1947' of github.com:jantman/gitpython_issue_301 +775652f64cd08ecfb952f9b6b4604203680cd317 not-for-merge branch 'testcommit1948' of github.com:jantman/gitpython_issue_301 +0893b760f7b0f2e922d5de7b877dec077dd36640 not-for-merge branch 'testcommit1949' of github.com:jantman/gitpython_issue_301 +e449f2f4177140c119824f37a309295dab59ac87 not-for-merge branch 'testcommit195' of github.com:jantman/gitpython_issue_301 +7c0431100e7acf7c5b285588047ef4a50bc6659b not-for-merge branch 'testcommit1950' of github.com:jantman/gitpython_issue_301 +a52aca2a831b48e1e2472a14c84020a9724c9c96 not-for-merge branch 'testcommit1951' of github.com:jantman/gitpython_issue_301 +de608cb3dc7f2aa87fec7e153a906f9f17c80837 not-for-merge branch 'testcommit1952' of github.com:jantman/gitpython_issue_301 +39d39098213b01a587269f07e84d72d569580ed4 not-for-merge branch 'testcommit1953' of github.com:jantman/gitpython_issue_301 +f33606a986117e407a83a3f2388bc2995318479c not-for-merge branch 'testcommit1954' of github.com:jantman/gitpython_issue_301 +31acc304ea0b1bbe70ab271e8b42f98fbd6f789f not-for-merge branch 'testcommit1955' of github.com:jantman/gitpython_issue_301 +b16345a7c541e725ad419fdd34477df2e4b241a8 not-for-merge branch 'testcommit1956' of github.com:jantman/gitpython_issue_301 +d48ea5bec69ae2589b9253e18006faa12be873c5 not-for-merge branch 'testcommit1957' of github.com:jantman/gitpython_issue_301 +129904abc54b8d0da7c01159554374110361e4e8 not-for-merge branch 'testcommit1958' of github.com:jantman/gitpython_issue_301 +10550b108d3ab4dab11cd2e51f4230fa84e5698d not-for-merge branch 'testcommit1959' of github.com:jantman/gitpython_issue_301 +5475601c8cb6dd661aa8d254fd0a22ccd5edb40f not-for-merge branch 'testcommit196' of github.com:jantman/gitpython_issue_301 +c1a58ace9e56f85b446dceeecaeb29bee9d30d29 not-for-merge branch 'testcommit1960' of github.com:jantman/gitpython_issue_301 +66f80513f5896feb64665beade166ed2b3281ebc not-for-merge branch 'testcommit1961' of github.com:jantman/gitpython_issue_301 +83847018e335a2eda1ef51ab4949ede9af7a7886 not-for-merge branch 'testcommit1962' of github.com:jantman/gitpython_issue_301 +4dfe5c4510811ba700c0b724cbd53908b53a2985 not-for-merge branch 'testcommit1963' of github.com:jantman/gitpython_issue_301 +40679050e70f119f74ac830bac5f01b4340ca85a not-for-merge branch 'testcommit1964' of github.com:jantman/gitpython_issue_301 +1e84d496c6cf7df2397be13dc5e38cd0bd3bedcf not-for-merge branch 'testcommit1965' of github.com:jantman/gitpython_issue_301 +1acee900bad3858c67ee0eda6626a391686f6ea6 not-for-merge branch 'testcommit1966' of github.com:jantman/gitpython_issue_301 +6691c51726a3d2487363058b9057160cf40af444 not-for-merge branch 'testcommit1967' of github.com:jantman/gitpython_issue_301 +c5238c7ed8bedb15b0ced4b23f230f9ad818c268 not-for-merge branch 'testcommit1968' of github.com:jantman/gitpython_issue_301 +1652913e59f1d6f423ac39b819d3abffb5d37249 not-for-merge branch 'testcommit1969' of github.com:jantman/gitpython_issue_301 +a9e49032e626534ac14460069a6b58abaaf25293 not-for-merge branch 'testcommit197' of github.com:jantman/gitpython_issue_301 +9867d8239fd528bd43e315b5970fdafcb98750ca not-for-merge branch 'testcommit1970' of github.com:jantman/gitpython_issue_301 +15eda2a4ba455c371dc1c51157063103e2373dc0 not-for-merge branch 'testcommit1971' of github.com:jantman/gitpython_issue_301 +f8a8bbe11fe5df102ac2e93630dffffd31940013 not-for-merge branch 'testcommit1972' of github.com:jantman/gitpython_issue_301 +2a924bb97e1b63527547c140004db7605f644968 not-for-merge branch 'testcommit1973' of github.com:jantman/gitpython_issue_301 +c705750c3d09dc94205febf54d182745cd783013 not-for-merge branch 'testcommit1974' of github.com:jantman/gitpython_issue_301 +555f0827b9b57ad9adc209a83b86e31e86034a17 not-for-merge branch 'testcommit1975' of github.com:jantman/gitpython_issue_301 +10c92be4fae1e1253912123067a777642a90c1ae not-for-merge branch 'testcommit1976' of github.com:jantman/gitpython_issue_301 +b1763448fb927bb34a0572c4a5c31a57d5a05f48 not-for-merge branch 'testcommit1977' of github.com:jantman/gitpython_issue_301 +660eec3d26c484156395d01a823e13690d738687 not-for-merge branch 'testcommit1978' of github.com:jantman/gitpython_issue_301 +6cfc5683435ceb67f5b80009b3bc2f1efada8ad1 not-for-merge branch 'testcommit1979' of github.com:jantman/gitpython_issue_301 +f2e92247fa80eebb41458c1729568729c8246684 not-for-merge branch 'testcommit198' of github.com:jantman/gitpython_issue_301 +d81047445092cb18629b46ebd6f0d11e4c2a810a not-for-merge branch 'testcommit1980' of github.com:jantman/gitpython_issue_301 +81428dbdac46c41db9153552d0fdca2a72daf506 not-for-merge branch 'testcommit1981' of github.com:jantman/gitpython_issue_301 +00633b02e703aeabc17f826e3b0a139301b16f49 not-for-merge branch 'testcommit1982' of github.com:jantman/gitpython_issue_301 +1a8b203a5fbdee45b0532385db534bf382ff5287 not-for-merge branch 'testcommit1983' of github.com:jantman/gitpython_issue_301 +c2f91552a53fef9dcee85ae4c144b55ee09d3e30 not-for-merge branch 'testcommit1984' of github.com:jantman/gitpython_issue_301 +26e54f7b2f3e319803b167fe5b2ff1f06212570a not-for-merge branch 'testcommit1985' of github.com:jantman/gitpython_issue_301 +dca7165ba32510d1755a13f959b0c80a9e6156fd not-for-merge branch 'testcommit1986' of github.com:jantman/gitpython_issue_301 +04636ea5e77bb0f9e0502270de92db4ef1b2644d not-for-merge branch 'testcommit1987' of github.com:jantman/gitpython_issue_301 +8a1bca9afe0daccf0c8d9ae4ecde4de7728ecacb not-for-merge branch 'testcommit1988' of github.com:jantman/gitpython_issue_301 +b397da7b0e20364f935187d25d03edd6cd91fb95 not-for-merge branch 'testcommit1989' of github.com:jantman/gitpython_issue_301 +537940b94f85ede631a4b275d8ae06e4b60f1f66 not-for-merge branch 'testcommit199' of github.com:jantman/gitpython_issue_301 +287c8fcc4e113a5097a0875f9a666ee84601c714 not-for-merge branch 'testcommit1990' of github.com:jantman/gitpython_issue_301 +4c98df3ad54ced7973008202e2a206ae135613e4 not-for-merge branch 'testcommit1991' of github.com:jantman/gitpython_issue_301 +994b9d6324942b9f1be8489b000ef98a2bb1dc85 not-for-merge branch 'testcommit1992' of github.com:jantman/gitpython_issue_301 +851e9b1db49ada6869d26168807743d79de03cc7 not-for-merge branch 'testcommit1993' of github.com:jantman/gitpython_issue_301 +43d9b77aead53682556b27c548db7c71218e6a10 not-for-merge branch 'testcommit1994' of github.com:jantman/gitpython_issue_301 +eac06dcf8daba6afd1f1b6ee158eb90ff4f4c762 not-for-merge branch 'testcommit1995' of github.com:jantman/gitpython_issue_301 +7245b63f5fde58669fa7b4bc02461a1f7be3feed not-for-merge branch 'testcommit1996' of github.com:jantman/gitpython_issue_301 +29cffc2d30ea896637d0306eaccc56e8b303f526 not-for-merge branch 'testcommit1997' of github.com:jantman/gitpython_issue_301 +b0ed236be933d51a608c4c487eed68d5f8df4756 not-for-merge branch 'testcommit1998' of github.com:jantman/gitpython_issue_301 +bfcb133bfdbc820feabdd8c9a493242bc8934e3f not-for-merge branch 'testcommit1999' of github.com:jantman/gitpython_issue_301 +53108067022b48267310024c8afa284e2bed535f not-for-merge branch 'testcommit2' of github.com:jantman/gitpython_issue_301 +4b64c0b181f4c8c29e3a5f869edfd181f9d5b27a not-for-merge branch 'testcommit20' of github.com:jantman/gitpython_issue_301 +aa2986db9b2c7d9625556b2b0647a76d34c0a82e not-for-merge branch 'testcommit200' of github.com:jantman/gitpython_issue_301 +1c55ca130bb9555c157feb4d0836092d6cffebee not-for-merge branch 'testcommit2000' of github.com:jantman/gitpython_issue_301 +08438c7b848733d61f6b4c76ffaa4e4e0d4e4872 not-for-merge branch 'testcommit2001' of github.com:jantman/gitpython_issue_301 +bc5263a39707949786feae2a8ed5434ba7b68146 not-for-merge branch 'testcommit2002' of github.com:jantman/gitpython_issue_301 +492a5a913e1cae4c4f5269168460476ee26a193c not-for-merge branch 'testcommit2003' of github.com:jantman/gitpython_issue_301 +b7632ca9c40075621ce033d7798272a43574d416 not-for-merge branch 'testcommit2004' of github.com:jantman/gitpython_issue_301 +1aae06b0501be9cc4ac2c541f4724a7c94179861 not-for-merge branch 'testcommit2005' of github.com:jantman/gitpython_issue_301 +d0b97833e908f3c828e65ab4bf4a3fa7c4446247 not-for-merge branch 'testcommit2006' of github.com:jantman/gitpython_issue_301 +3ff125ac7cbc2b5b3e853b35d4a2db36cfbc66e5 not-for-merge branch 'testcommit2007' of github.com:jantman/gitpython_issue_301 +661468dfda27473b56b5dc1b299a36b6c9ccf671 not-for-merge branch 'testcommit2008' of github.com:jantman/gitpython_issue_301 +2f999211bb3ee8d9294f0bafa3b02f0c67ba0502 not-for-merge branch 'testcommit2009' of github.com:jantman/gitpython_issue_301 +5d21180545220579d8cbc58b9c2f11fa8d147b04 not-for-merge branch 'testcommit201' of github.com:jantman/gitpython_issue_301 +90a098eea5f7c746b1d93aa4dc36152a929b09e4 not-for-merge branch 'testcommit2010' of github.com:jantman/gitpython_issue_301 +7eedc4b237f8d0c7fd32fc3c01faf2bc748ce9f7 not-for-merge branch 'testcommit2011' of github.com:jantman/gitpython_issue_301 +801b225c1ad95f33a0156bc6faf0505fbd319075 not-for-merge branch 'testcommit2012' of github.com:jantman/gitpython_issue_301 +4a53b3bdaa88e2409b4673d6f03670e761136f72 not-for-merge branch 'testcommit2013' of github.com:jantman/gitpython_issue_301 +78539a2aae2b6426c49200b9a8cd6c20c72a69b8 not-for-merge branch 'testcommit2014' of github.com:jantman/gitpython_issue_301 +91dcb65eaa98e1ea77dc7377cb864c2daad1ac23 not-for-merge branch 'testcommit2015' of github.com:jantman/gitpython_issue_301 +73283187d1581ff23cd25946f004125a33e5d194 not-for-merge branch 'testcommit2016' of github.com:jantman/gitpython_issue_301 +ae460348819e2861b619955521abf7c9f7d52352 not-for-merge branch 'testcommit2017' of github.com:jantman/gitpython_issue_301 +e398a9f792345d8f9cda643732bc1f795cf9580c not-for-merge branch 'testcommit2018' of github.com:jantman/gitpython_issue_301 +4ac63bd46912976f467293034404b13b465d0956 not-for-merge branch 'testcommit2019' of github.com:jantman/gitpython_issue_301 +70c0fd8e14566df1adecd0d24f39e3c1990c7a54 not-for-merge branch 'testcommit202' of github.com:jantman/gitpython_issue_301 +fb06ed3204f39f85c7bb97cc2ac2478409c33612 not-for-merge branch 'testcommit2020' of github.com:jantman/gitpython_issue_301 +3c55bc13f5f1b5133d687f5b8ece9e3acaef2dcd not-for-merge branch 'testcommit2021' of github.com:jantman/gitpython_issue_301 +010812300617f659cb5201c5ba9bd1cb0afdd44d not-for-merge branch 'testcommit2022' of github.com:jantman/gitpython_issue_301 +21f4591f7b9b8264f002b74f0b14d5c3319b0b8d not-for-merge branch 'testcommit2023' of github.com:jantman/gitpython_issue_301 +1e1852e92df494ca4d0fa39f4ac7fddf2fe78c12 not-for-merge branch 'testcommit2024' of github.com:jantman/gitpython_issue_301 +807ed61e5141fe53d2f07759b3d6d22c0b9fb4f5 not-for-merge branch 'testcommit2025' of github.com:jantman/gitpython_issue_301 +e476905b6793bc7bf56e8ce604d5ec2517e6a33a not-for-merge branch 'testcommit2026' of github.com:jantman/gitpython_issue_301 +84154d33f06e118b6979c1d08d75715a5831faba not-for-merge branch 'testcommit2027' of github.com:jantman/gitpython_issue_301 +db95b369a94947a6bf5686e20cdc1f2906237c43 not-for-merge branch 'testcommit2028' of github.com:jantman/gitpython_issue_301 +a4d33325424942acaed2b6e85842752df032e119 not-for-merge branch 'testcommit2029' of github.com:jantman/gitpython_issue_301 +88b01984ebc75d8920c4b18397b4945b19ae4a27 not-for-merge branch 'testcommit203' of github.com:jantman/gitpython_issue_301 +7a9bb1725ed15b664a7b911af91f5c99cf11543f not-for-merge branch 'testcommit2030' of github.com:jantman/gitpython_issue_301 +907ab997798f7176699eceb72cd6f8c186be0a49 not-for-merge branch 'testcommit2031' of github.com:jantman/gitpython_issue_301 +b272b675225f8bbc7f0e7f8b1a84841858299de9 not-for-merge branch 'testcommit2032' of github.com:jantman/gitpython_issue_301 +0389aabd3e43e3b8968cebd456149b0629a05812 not-for-merge branch 'testcommit2033' of github.com:jantman/gitpython_issue_301 +eed7a4b3a15618700b0693c13168dc69ffe19800 not-for-merge branch 'testcommit2034' of github.com:jantman/gitpython_issue_301 +a76d126953b261b2d8b99b09cc2bafb049c61fe6 not-for-merge branch 'testcommit2035' of github.com:jantman/gitpython_issue_301 +2722685e618d6287e1e14881567dd045640bd63e not-for-merge branch 'testcommit2036' of github.com:jantman/gitpython_issue_301 +54b0a794a4af0eb4e3f858f36395df97b7aa04ef not-for-merge branch 'testcommit2037' of github.com:jantman/gitpython_issue_301 +d0ba849a60c09b63a69c42dd1e1c5dbf68d85a7e not-for-merge branch 'testcommit2038' of github.com:jantman/gitpython_issue_301 +e1aaf841d54292077d97854924069d6ea5374042 not-for-merge branch 'testcommit2039' of github.com:jantman/gitpython_issue_301 +d1715181a14d1d642f64c819fcfc6e7298a5028f not-for-merge branch 'testcommit204' of github.com:jantman/gitpython_issue_301 +3fc496ce4811acf970b3041c671f49a2383394eb not-for-merge branch 'testcommit2040' of github.com:jantman/gitpython_issue_301 +3303cdf9a4269e9b3570f301724ee500793b823b not-for-merge branch 'testcommit2041' of github.com:jantman/gitpython_issue_301 +e6bb5b9baf5d3984dfebd8fe54f8067f4857d118 not-for-merge branch 'testcommit2042' of github.com:jantman/gitpython_issue_301 +b2657a0eb93212e363e6658fae13ef78fe9672e4 not-for-merge branch 'testcommit2043' of github.com:jantman/gitpython_issue_301 +c86cd67936ff170ef7ae8807b77d7c24be15b28b not-for-merge branch 'testcommit2044' of github.com:jantman/gitpython_issue_301 +cd4d269a740d25f686dc53b0c73d6514824df535 not-for-merge branch 'testcommit2045' of github.com:jantman/gitpython_issue_301 +e409b35b829dcde2f5629a296650a60514d3a75a not-for-merge branch 'testcommit2046' of github.com:jantman/gitpython_issue_301 +1ad2ab1062c46205b983ca4722c85422303e9588 not-for-merge branch 'testcommit2047' of github.com:jantman/gitpython_issue_301 +224d3aaefc27aa276d4aa057a985f3e3a17a8e1d not-for-merge branch 'testcommit2048' of github.com:jantman/gitpython_issue_301 +72ab2ebcbfac4963792727ab548fec7e4594be9c not-for-merge branch 'testcommit2049' of github.com:jantman/gitpython_issue_301 +8c42ec38f6a1bf1d34a667c339892b2bee559b59 not-for-merge branch 'testcommit205' of github.com:jantman/gitpython_issue_301 +7bf331d6e6da551bbb624af73e9fafcbcb58e3bf not-for-merge branch 'testcommit2050' of github.com:jantman/gitpython_issue_301 +0c646cd25088aea8d7ae6280ed8cecc34b971caf not-for-merge branch 'testcommit2051' of github.com:jantman/gitpython_issue_301 +bc2baa505331ba40ae76f6d7d8d919aacd0b0bb5 not-for-merge branch 'testcommit2052' of github.com:jantman/gitpython_issue_301 +9b404ed714296ffff1821a499a94341daaf4ba3d not-for-merge branch 'testcommit2053' of github.com:jantman/gitpython_issue_301 +8c04d004c2a1c6cfdb86a71a1a1d3eac7aa972f1 not-for-merge branch 'testcommit2054' of github.com:jantman/gitpython_issue_301 +d9f5760f3a2280736d396ceee12eadc306c76fcb not-for-merge branch 'testcommit2055' of github.com:jantman/gitpython_issue_301 +78a169a3413761baf83babce753fee67b9ce8e91 not-for-merge branch 'testcommit2056' of github.com:jantman/gitpython_issue_301 +6e079667ea52cd68b5d239fb070d518a16991e23 not-for-merge branch 'testcommit2057' of github.com:jantman/gitpython_issue_301 +701f24f67ba4e8d576a1f52bc66f5343d1e2880c not-for-merge branch 'testcommit2058' of github.com:jantman/gitpython_issue_301 +2a0a5ddfaf07f8b96e6140de33df2b02822d0a2f not-for-merge branch 'testcommit2059' of github.com:jantman/gitpython_issue_301 +8bf20777ff988f203003605ca6ceda8d5f0d05d2 not-for-merge branch 'testcommit206' of github.com:jantman/gitpython_issue_301 +e30a8f96cf55dc0e60e14666784d526de9565756 not-for-merge branch 'testcommit2060' of github.com:jantman/gitpython_issue_301 +803ca5ee2e46064005325d016a8aab5ced89611c not-for-merge branch 'testcommit2061' of github.com:jantman/gitpython_issue_301 +dd530c9af40d3410a3e7ec026330e6be23b6290c not-for-merge branch 'testcommit2062' of github.com:jantman/gitpython_issue_301 +0d9edbe99ff2fb52b42a3e1f30f3ab5fdf5631e2 not-for-merge branch 'testcommit2063' of github.com:jantman/gitpython_issue_301 +54b1dd961799815a5d91c3bb268e5b7b3a27b3d5 not-for-merge branch 'testcommit2064' of github.com:jantman/gitpython_issue_301 +6d52395ffe8dec0aedd12ec0b222a0a81fdb6981 not-for-merge branch 'testcommit2065' of github.com:jantman/gitpython_issue_301 +b8e59384de712d7f234a0af92678f8052de3be1d not-for-merge branch 'testcommit2066' of github.com:jantman/gitpython_issue_301 +ea3cc26dae85a099fe01b5c7f88bbdb1444fd555 not-for-merge branch 'testcommit2067' of github.com:jantman/gitpython_issue_301 +50045950ef26dc8b6ac4cba026fbaec492722424 not-for-merge branch 'testcommit2068' of github.com:jantman/gitpython_issue_301 +e32629d2babc6b5e825fbc479bc2cf79cf579334 not-for-merge branch 'testcommit2069' of github.com:jantman/gitpython_issue_301 +adbe7127f57aa32b9b8dff66ab733db2b011a765 not-for-merge branch 'testcommit207' of github.com:jantman/gitpython_issue_301 +9de7498541220de007901d3f47a32797d2e4ed08 not-for-merge branch 'testcommit2070' of github.com:jantman/gitpython_issue_301 +52c3b7720459e3148bd2eca5827c1ed402e95f9d not-for-merge branch 'testcommit2071' of github.com:jantman/gitpython_issue_301 +098d4312dfa3a593fa8070c82a10dfc149f0ede1 not-for-merge branch 'testcommit2072' of github.com:jantman/gitpython_issue_301 +4e41f29d48f976d6f7bf711ed7e285cfd1740edb not-for-merge branch 'testcommit2073' of github.com:jantman/gitpython_issue_301 +e8fa1aa09a15c02ad7616b8ea8d67a963a505f39 not-for-merge branch 'testcommit2074' of github.com:jantman/gitpython_issue_301 +61141cf55e6e91128f993702259a0dab3c37ff45 not-for-merge branch 'testcommit2075' of github.com:jantman/gitpython_issue_301 +c88f97ae7d8da34099435b62a4c7c3420f9b7e47 not-for-merge branch 'testcommit2076' of github.com:jantman/gitpython_issue_301 +2a653191fecbb83f36f44a47441c388db7e3fd16 not-for-merge branch 'testcommit2077' of github.com:jantman/gitpython_issue_301 +ab06b6e29095d7a616aaa85a8730c3e1072452b8 not-for-merge branch 'testcommit2078' of github.com:jantman/gitpython_issue_301 +c3da56ed9085783ab99c68e94a2fba7696043466 not-for-merge branch 'testcommit2079' of github.com:jantman/gitpython_issue_301 +c9fc27b383454fd4f36d0f0af3b2ddae4f3af644 not-for-merge branch 'testcommit208' of github.com:jantman/gitpython_issue_301 +b3c4763847f74b876d48e4de25cebf00c368b050 not-for-merge branch 'testcommit2080' of github.com:jantman/gitpython_issue_301 +933e7b7a8a4a4205ff9068ff0e8ea3b4fa1f9c69 not-for-merge branch 'testcommit2081' of github.com:jantman/gitpython_issue_301 +4ff71c9a1b4c692255abe9efabf8ab204fef3444 not-for-merge branch 'testcommit2082' of github.com:jantman/gitpython_issue_301 +3bc8c2ceb63c924d6bb1796ca05b49b16e022aad not-for-merge branch 'testcommit2083' of github.com:jantman/gitpython_issue_301 +b3b4dffba229e8e750b6e1f0cdeac9724d6fede2 not-for-merge branch 'testcommit2084' of github.com:jantman/gitpython_issue_301 +589095c3dc28656bec1eeb98d3186f6e6e4eb93c not-for-merge branch 'testcommit2085' of github.com:jantman/gitpython_issue_301 +43521cd647b00ce0f048441b30c5201392f60b94 not-for-merge branch 'testcommit2086' of github.com:jantman/gitpython_issue_301 +dc654d85720c762ea947f643fdf9c8c0cef3f2db not-for-merge branch 'testcommit2087' of github.com:jantman/gitpython_issue_301 +737fecdfc813ddb296e5947f0ac1923ef94016d4 not-for-merge branch 'testcommit2088' of github.com:jantman/gitpython_issue_301 +c0f5b5bf065a4ea637666982e9c96ed430c223c2 not-for-merge branch 'testcommit2089' of github.com:jantman/gitpython_issue_301 +87e62dc1b4ae5b6589081196a6e4a2a38148f257 not-for-merge branch 'testcommit209' of github.com:jantman/gitpython_issue_301 +d58d1a2c81afa35b114a5a5c7f6b8ee8c0874493 not-for-merge branch 'testcommit2090' of github.com:jantman/gitpython_issue_301 +bca85b054c28412c7bbd14db967d117c70ed3fcb not-for-merge branch 'testcommit2091' of github.com:jantman/gitpython_issue_301 +944f5f403c7889f63e057693a7fcbe592596e8e2 not-for-merge branch 'testcommit2092' of github.com:jantman/gitpython_issue_301 +10fb545a1689d9dcebf153252cd712eadda54ec1 not-for-merge branch 'testcommit2093' of github.com:jantman/gitpython_issue_301 +348b09a885a1f14a229f48442538521652e7000f not-for-merge branch 'testcommit2094' of github.com:jantman/gitpython_issue_301 +b53e195a0ed4f6158016ce0053adf2c87747bea0 not-for-merge branch 'testcommit2095' of github.com:jantman/gitpython_issue_301 +2d0e43431c0c303fa86419d4d68f1144ec9c9401 not-for-merge branch 'testcommit2096' of github.com:jantman/gitpython_issue_301 +088e536627e3ac850a45a23a11dc537ed99d6a3d not-for-merge branch 'testcommit2097' of github.com:jantman/gitpython_issue_301 +56128f0e64da26840a077fe9d9d2475d5f72b53a not-for-merge branch 'testcommit2098' of github.com:jantman/gitpython_issue_301 +1199f6633c5175ea6dae75b41cd5704f5a82fe5e not-for-merge branch 'testcommit2099' of github.com:jantman/gitpython_issue_301 +88f9bc8d5cfa2f7d8f44a7932ad5eb0589f83d49 not-for-merge branch 'testcommit21' of github.com:jantman/gitpython_issue_301 +b55ac7114cf44c418884a89e1bc025e31296bc34 not-for-merge branch 'testcommit210' of github.com:jantman/gitpython_issue_301 +a6ddad73109311f67107d8d2a6f7c8b4f9e0bb4b not-for-merge branch 'testcommit2100' of github.com:jantman/gitpython_issue_301 +22eaa580d0a12f5dc0e44df158bce76dee7f72ab not-for-merge branch 'testcommit2101' of github.com:jantman/gitpython_issue_301 +70838db5282ab7c85022b50dfd6c49d3baf2a93f not-for-merge branch 'testcommit2102' of github.com:jantman/gitpython_issue_301 +25683acb50bbf967a7df021a8487c8d349a4ca86 not-for-merge branch 'testcommit2103' of github.com:jantman/gitpython_issue_301 +31219498719b7e77586e5d8f6db4ded15f723040 not-for-merge branch 'testcommit2104' of github.com:jantman/gitpython_issue_301 +e0bffd68bfdb96ed3716dd58ce07d6c729b11785 not-for-merge branch 'testcommit2105' of github.com:jantman/gitpython_issue_301 +cd82858a17c7363b6fd3515144fefe5a56dc7e74 not-for-merge branch 'testcommit2106' of github.com:jantman/gitpython_issue_301 +580c999f64e205938fd6e98922812b805600540a not-for-merge branch 'testcommit2107' of github.com:jantman/gitpython_issue_301 +2467f3034fc4ece410caae23e20ba3fc7eba2331 not-for-merge branch 'testcommit2108' of github.com:jantman/gitpython_issue_301 +02587028064459c611958fa48a35f32ae6abca4a not-for-merge branch 'testcommit2109' of github.com:jantman/gitpython_issue_301 +014ea8627f0e04308cc694e18072be2000c63061 not-for-merge branch 'testcommit211' of github.com:jantman/gitpython_issue_301 +a4c91c49b02771b9d3ffc1664b30a000da25bdd5 not-for-merge branch 'testcommit2110' of github.com:jantman/gitpython_issue_301 +1a0e42d20b0e165bccc11ee3ce04fd266efa069b not-for-merge branch 'testcommit2111' of github.com:jantman/gitpython_issue_301 +671c756e9c1f12ce614661283107c2141b6aa467 not-for-merge branch 'testcommit2112' of github.com:jantman/gitpython_issue_301 +50859356e8e6a6deede992700d04e4e0994ac21b not-for-merge branch 'testcommit2113' of github.com:jantman/gitpython_issue_301 +03e80098a0b5694a94630b60559d4b3cf706d4bb not-for-merge branch 'testcommit2114' of github.com:jantman/gitpython_issue_301 +5d774047f702ffebecdd1c240ca5e22568c40d67 not-for-merge branch 'testcommit2115' of github.com:jantman/gitpython_issue_301 +38cd37aa27cf8778cd03c25d3844bee28be0e4e2 not-for-merge branch 'testcommit2116' of github.com:jantman/gitpython_issue_301 +3ebdf1d0f7bbc7c3281243e04cdb0a37953615a1 not-for-merge branch 'testcommit2117' of github.com:jantman/gitpython_issue_301 +faf8149f2fb0310b4cef8a5c8bd08fcb19871650 not-for-merge branch 'testcommit2118' of github.com:jantman/gitpython_issue_301 +d9c7dbfc5760deae5430ba277f520c11b0234934 not-for-merge branch 'testcommit2119' of github.com:jantman/gitpython_issue_301 +0ca47ebfee475a1b7d08d93214e04640ab8b0f26 not-for-merge branch 'testcommit212' of github.com:jantman/gitpython_issue_301 +20cd08766e458f11e3025e89597eca1cdc9ead14 not-for-merge branch 'testcommit2120' of github.com:jantman/gitpython_issue_301 +d47bb030fa4ca7cf4d444cf81af39ff12c0f859d not-for-merge branch 'testcommit2121' of github.com:jantman/gitpython_issue_301 +3c412e7a8f80ee3f8757c04813a604140bb75d2b not-for-merge branch 'testcommit2122' of github.com:jantman/gitpython_issue_301 +3d2098eea85e2b9dd24d2a0e8d1b466601ba7377 not-for-merge branch 'testcommit2123' of github.com:jantman/gitpython_issue_301 +5cc560e6755209edf3366b1a06f2844f03dff412 not-for-merge branch 'testcommit2124' of github.com:jantman/gitpython_issue_301 +658b867abb60dc9b0e7e06cd69372dfe9757e45c not-for-merge branch 'testcommit2125' of github.com:jantman/gitpython_issue_301 +601e61b34142833d466157d5867f05d30c0f0389 not-for-merge branch 'testcommit2126' of github.com:jantman/gitpython_issue_301 +9afa45ced9ec9418210025570ef092ae1df010dc not-for-merge branch 'testcommit2127' of github.com:jantman/gitpython_issue_301 +28701add626c8e2abff1265f6cd9b9dca0f69acc not-for-merge branch 'testcommit2128' of github.com:jantman/gitpython_issue_301 +b92b4a2b2670e8ec1988d7839cbd269478d45cff not-for-merge branch 'testcommit2129' of github.com:jantman/gitpython_issue_301 +be19aeac45e4e9fa17bb776a197518e8c1d69358 not-for-merge branch 'testcommit213' of github.com:jantman/gitpython_issue_301 +bbc571c4239049af443ef8810d0c89b70b9c222a not-for-merge branch 'testcommit2130' of github.com:jantman/gitpython_issue_301 +c8b58cea73a075a3525e7cd6dc2cb397fbf8c3b5 not-for-merge branch 'testcommit2131' of github.com:jantman/gitpython_issue_301 +1406c93e99ab85e82fd8012b73d6202cf5fc90cb not-for-merge branch 'testcommit2132' of github.com:jantman/gitpython_issue_301 +c1c5fe54d4e8eff4bd25a8f3f0c2ae6190e65426 not-for-merge branch 'testcommit2133' of github.com:jantman/gitpython_issue_301 +d84c1477131eee9aa40aa03f8baf768e6b38e749 not-for-merge branch 'testcommit2134' of github.com:jantman/gitpython_issue_301 +d6508030909b293c9e1aa0b98202b601b0d53aa6 not-for-merge branch 'testcommit2135' of github.com:jantman/gitpython_issue_301 +b796b9d671c42eecb344cb8c1701bed5f4eb97c1 not-for-merge branch 'testcommit2136' of github.com:jantman/gitpython_issue_301 +54e7f971551131ee9f4543880ccea06306a66884 not-for-merge branch 'testcommit2137' of github.com:jantman/gitpython_issue_301 +e6f998469a976859308de5cdd3ed9c06725e5ed0 not-for-merge branch 'testcommit2138' of github.com:jantman/gitpython_issue_301 +5bb90ca9f7d05d4aed65aba2e132e4705904bc61 not-for-merge branch 'testcommit2139' of github.com:jantman/gitpython_issue_301 +099b1dfb55e9cd5318833187123b8d8dadb913d4 not-for-merge branch 'testcommit214' of github.com:jantman/gitpython_issue_301 +80af9a8e0846db3905031cf6e4f281ffc91b4018 not-for-merge branch 'testcommit2140' of github.com:jantman/gitpython_issue_301 +ab8ad878a222331e67eb14ea8cb9588565fbec10 not-for-merge branch 'testcommit2141' of github.com:jantman/gitpython_issue_301 +12bf019dc1ac208168314a4f60282ce8343ccfa2 not-for-merge branch 'testcommit2142' of github.com:jantman/gitpython_issue_301 +989310e594bbba654b1870338920e8b9eee9954b not-for-merge branch 'testcommit2143' of github.com:jantman/gitpython_issue_301 +6de94835a3983402c20b80a2ffe3247e0714f8ad not-for-merge branch 'testcommit2144' of github.com:jantman/gitpython_issue_301 +07724a8c81eb949d15b6e56ab9e0cfa2f22dc4f6 not-for-merge branch 'testcommit2145' of github.com:jantman/gitpython_issue_301 +c5684b5152e118041e91c64c3c580f112b8118cf not-for-merge branch 'testcommit2146' of github.com:jantman/gitpython_issue_301 +94437beaa3b270502b8f7c5681bc2e52beaf528a not-for-merge branch 'testcommit2147' of github.com:jantman/gitpython_issue_301 +b0c543c034cc346ab3a89081522891cad11551b4 not-for-merge branch 'testcommit2148' of github.com:jantman/gitpython_issue_301 +96dd00d9b572c95b7885083b32e46b0d515ec2af not-for-merge branch 'testcommit2149' of github.com:jantman/gitpython_issue_301 +84a85406d770cfdebf99e1fe20f97b55458ab346 not-for-merge branch 'testcommit215' of github.com:jantman/gitpython_issue_301 +815d1aff1b28e14b51141dc2b2a7574c0ff40794 not-for-merge branch 'testcommit2150' of github.com:jantman/gitpython_issue_301 +d6e5a366f59f2023931338f4e6221f46d41880c6 not-for-merge branch 'testcommit2151' of github.com:jantman/gitpython_issue_301 +dee0470cf06c3f587a3f925e4321874f134da86b not-for-merge branch 'testcommit2152' of github.com:jantman/gitpython_issue_301 +6cb062ec7e01a7487ecabfc63bd9c8af1013ce2b not-for-merge branch 'testcommit2153' of github.com:jantman/gitpython_issue_301 +6e582d855acfdcd85d83367f7ffa807f491aa807 not-for-merge branch 'testcommit2154' of github.com:jantman/gitpython_issue_301 +a2a58d171ad6ad7d312bc3c9f5148f37fde23ae2 not-for-merge branch 'testcommit2155' of github.com:jantman/gitpython_issue_301 +e495280d78e5f1a38930dea6dff5d9080f4e5e67 not-for-merge branch 'testcommit2156' of github.com:jantman/gitpython_issue_301 +96192b844473a876ec3e02c82611b40366af69dd not-for-merge branch 'testcommit2157' of github.com:jantman/gitpython_issue_301 +2b223d114595bfebd290a1bb0d2d7c02fcfb204c not-for-merge branch 'testcommit2158' of github.com:jantman/gitpython_issue_301 +f19c6439a77a9beb97e8b1fd3d5ae611547d7449 not-for-merge branch 'testcommit2159' of github.com:jantman/gitpython_issue_301 +62aaf0b54d50fec4fa24d615e5e66a81e824c0a5 not-for-merge branch 'testcommit216' of github.com:jantman/gitpython_issue_301 +15109ae1345629dd3b5bc547db85cb4a20ceed5f not-for-merge branch 'testcommit2160' of github.com:jantman/gitpython_issue_301 +1b0c8c90c0be0b75712e1b0c69ca683a77437268 not-for-merge branch 'testcommit2161' of github.com:jantman/gitpython_issue_301 +db194db01d621130f5424260bfe228d35662e05c not-for-merge branch 'testcommit2162' of github.com:jantman/gitpython_issue_301 +4d567e6e6c50381650d029ff778c15a772ed1ffb not-for-merge branch 'testcommit2163' of github.com:jantman/gitpython_issue_301 +d802cfdc0230a4ebc983928273d7f18d30030a5a not-for-merge branch 'testcommit2164' of github.com:jantman/gitpython_issue_301 +b91d47eeebfa9e64060ad6c1bd1ed14bca69a887 not-for-merge branch 'testcommit2165' of github.com:jantman/gitpython_issue_301 +68cceff05ef4206e1dc540ab5be16c7085d7c6f8 not-for-merge branch 'testcommit2166' of github.com:jantman/gitpython_issue_301 +83fdf5863fb96490392daba6c57eec7d4b30dd58 not-for-merge branch 'testcommit2167' of github.com:jantman/gitpython_issue_301 +90ec826120d8feede3d564a85c32aca75cccd6d7 not-for-merge branch 'testcommit2168' of github.com:jantman/gitpython_issue_301 +6a30e525a10cd75b4e6ec600991ddd7fd2052fb8 not-for-merge branch 'testcommit2169' of github.com:jantman/gitpython_issue_301 +99c95c829774ebdcb48f6e27af58837cde96939e not-for-merge branch 'testcommit217' of github.com:jantman/gitpython_issue_301 +b458fd4c4a571b5cb2cdc9ccf3638255bcbb5fc1 not-for-merge branch 'testcommit2170' of github.com:jantman/gitpython_issue_301 +dd0deb69576b8520a3a51f4dd0a218260496b13f not-for-merge branch 'testcommit2171' of github.com:jantman/gitpython_issue_301 +3f6418e04623eccf154be3fded97a9f0b33ae88c not-for-merge branch 'testcommit2172' of github.com:jantman/gitpython_issue_301 +93f0b47e848861b028b2071ae910662c97fafd04 not-for-merge branch 'testcommit2173' of github.com:jantman/gitpython_issue_301 +8c04c54ab4588a63b7b016cbe6f2a69d739926e4 not-for-merge branch 'testcommit2174' of github.com:jantman/gitpython_issue_301 +c16b529fcb1cd24d230d2b6268d3b6401844677e not-for-merge branch 'testcommit2175' of github.com:jantman/gitpython_issue_301 +7ba1a06a7c9dd33e960014ba8a5a08e4947a1624 not-for-merge branch 'testcommit2176' of github.com:jantman/gitpython_issue_301 +bbd24f0217a786a7e1f55ecc2536955a5cbf355d not-for-merge branch 'testcommit2177' of github.com:jantman/gitpython_issue_301 +8e509137fefdb0788e39f02c0a840df53263d30a not-for-merge branch 'testcommit2178' of github.com:jantman/gitpython_issue_301 +af3575172fba80cb2aed38c1485efe2891cb7626 not-for-merge branch 'testcommit2179' of github.com:jantman/gitpython_issue_301 +2235a270c90cd854ef92ad2475445f2ec92ec2c5 not-for-merge branch 'testcommit218' of github.com:jantman/gitpython_issue_301 +83dfde9ece745dd9d764c759997c5faf81de67f7 not-for-merge branch 'testcommit2180' of github.com:jantman/gitpython_issue_301 +be9b53554346ce75a6ae2dba7deebd609da7a3b7 not-for-merge branch 'testcommit2181' of github.com:jantman/gitpython_issue_301 +7fc754802abf63d562a0337e4a44765a47ab3dc8 not-for-merge branch 'testcommit2182' of github.com:jantman/gitpython_issue_301 +ea889a4a83cdda578eea2ebce139a3d092e189c9 not-for-merge branch 'testcommit2183' of github.com:jantman/gitpython_issue_301 +915b898207e6c10ad85ce537cde77d5b720b985e not-for-merge branch 'testcommit2184' of github.com:jantman/gitpython_issue_301 +44f1b53565fde09489c3d619bf35897c3117d0ce not-for-merge branch 'testcommit2185' of github.com:jantman/gitpython_issue_301 +76387025b53342e79e7d47eb16c00ac54155dc5e not-for-merge branch 'testcommit2186' of github.com:jantman/gitpython_issue_301 +af5d9bf568c1102d0abe2132352b2971251a6055 not-for-merge branch 'testcommit2187' of github.com:jantman/gitpython_issue_301 +bf2a3633354d4bc90b4a0be8115fb957548cb643 not-for-merge branch 'testcommit2188' of github.com:jantman/gitpython_issue_301 +52e82c94094a1701224752b84e79718744da9734 not-for-merge branch 'testcommit2189' of github.com:jantman/gitpython_issue_301 +c957abe469cd839a3851f07a8070fdc69772657d not-for-merge branch 'testcommit219' of github.com:jantman/gitpython_issue_301 +015c1b53220efeb4ee276050e127a289460854bf not-for-merge branch 'testcommit2190' of github.com:jantman/gitpython_issue_301 +dba9b11095f9419d06f1545c8c4d141aaeb13da3 not-for-merge branch 'testcommit2191' of github.com:jantman/gitpython_issue_301 +01102fef4005e1026031be817511b6bb32f2a018 not-for-merge branch 'testcommit2192' of github.com:jantman/gitpython_issue_301 +a94a93d22077ca581df98581602b5f63de83265a not-for-merge branch 'testcommit2193' of github.com:jantman/gitpython_issue_301 +c57aed6475c29fb4c1068e836dc090dfc51ed5cb not-for-merge branch 'testcommit2194' of github.com:jantman/gitpython_issue_301 +934841c9b2532b1507011ad2d606b5ab6b0533e6 not-for-merge branch 'testcommit2195' of github.com:jantman/gitpython_issue_301 +4bacde797a79799883ec8c869d4686ef0ebce11b not-for-merge branch 'testcommit2196' of github.com:jantman/gitpython_issue_301 +447285526d7a77cf1910e1d8d1f385c9548c4eef not-for-merge branch 'testcommit2197' of github.com:jantman/gitpython_issue_301 +e9f77c5809bae5b67d47a695675449e25b13d998 not-for-merge branch 'testcommit2198' of github.com:jantman/gitpython_issue_301 +083778ea18fd74381bca65ce1cb86f320fc46f28 not-for-merge branch 'testcommit2199' of github.com:jantman/gitpython_issue_301 +c7704a628b53301110fd7da48f42b794427ac316 not-for-merge branch 'testcommit22' of github.com:jantman/gitpython_issue_301 +10f1551521884cb5d79ee1b4d5d74a750ae943ba not-for-merge branch 'testcommit220' of github.com:jantman/gitpython_issue_301 +995795626bf16660dd51eb2f695012a752b26976 not-for-merge branch 'testcommit2200' of github.com:jantman/gitpython_issue_301 +ec76fbd61a869ef7775056e5e43f41e39f08db15 not-for-merge branch 'testcommit2201' of github.com:jantman/gitpython_issue_301 +267bf309f8276e3b74640feee30e562cc7b3db50 not-for-merge branch 'testcommit2202' of github.com:jantman/gitpython_issue_301 +c31dc28876b3bbd15f101dfa05f270d25cedb504 not-for-merge branch 'testcommit2203' of github.com:jantman/gitpython_issue_301 +11ff8cfaf747ccb68ca97e0322209e499a6d0402 not-for-merge branch 'testcommit2204' of github.com:jantman/gitpython_issue_301 +e68e051efecd3e4dc921a3aa289e3a94771b0ccc not-for-merge branch 'testcommit2205' of github.com:jantman/gitpython_issue_301 +167c827d6a9bc8e28b368956e551df122d936d2d not-for-merge branch 'testcommit2206' of github.com:jantman/gitpython_issue_301 +c2455da917302cbef53c1a2e0ca0d5a5ff637e47 not-for-merge branch 'testcommit2207' of github.com:jantman/gitpython_issue_301 +a3fb8def5bc8f4669b2dc52a7e7cd9c26580837b not-for-merge branch 'testcommit2208' of github.com:jantman/gitpython_issue_301 +84de96a6471f51d5e4e977344032cd5e7cd6da27 not-for-merge branch 'testcommit2209' of github.com:jantman/gitpython_issue_301 +338f38041c79db054a016228ca740de19899d8cd not-for-merge branch 'testcommit221' of github.com:jantman/gitpython_issue_301 +52aed0bb2abd2e3ac73a1c8c965af25370f5cc83 not-for-merge branch 'testcommit2210' of github.com:jantman/gitpython_issue_301 +3a63ba30e6830a01315285eccb7ad7cc67c43a29 not-for-merge branch 'testcommit2211' of github.com:jantman/gitpython_issue_301 +e4b2801298a0e730b4b4461cabaccd0ba6dd8228 not-for-merge branch 'testcommit2212' of github.com:jantman/gitpython_issue_301 +6da91216f1c578cfb3916dc63fb596d09391b0a0 not-for-merge branch 'testcommit2213' of github.com:jantman/gitpython_issue_301 +22734a486668182247fe702a5750c54487309bdb not-for-merge branch 'testcommit2214' of github.com:jantman/gitpython_issue_301 +a9344b1d40d2dc4265faf138ad70b9552c7fa975 not-for-merge branch 'testcommit2215' of github.com:jantman/gitpython_issue_301 +d05544496e51dd325c7109d6b0a873d9f02347bc not-for-merge branch 'testcommit2216' of github.com:jantman/gitpython_issue_301 +e214275877955a49f368cfbb809c0f3f79b42073 not-for-merge branch 'testcommit2217' of github.com:jantman/gitpython_issue_301 +a0740f193ba7f32a5d085ae3410b3b364cb8f9ea not-for-merge branch 'testcommit2218' of github.com:jantman/gitpython_issue_301 +468fd485a0a57bf3f41b58725faafff55d6e0993 not-for-merge branch 'testcommit2219' of github.com:jantman/gitpython_issue_301 +c589bd88e349769b934576f505096e3b94994fa4 not-for-merge branch 'testcommit222' of github.com:jantman/gitpython_issue_301 +fbc413c164739a7e248442a8231b2e1b1af9c6eb not-for-merge branch 'testcommit2220' of github.com:jantman/gitpython_issue_301 +82cd20db1a352223bfa1543bf2305e6eaa7eaaaa not-for-merge branch 'testcommit2221' of github.com:jantman/gitpython_issue_301 +48a3ffcc99825ec9412d7b43eeca255b9981b092 not-for-merge branch 'testcommit2222' of github.com:jantman/gitpython_issue_301 +0fdb6cea083ce96d14dad8b8eaea7d5dcea6aa7a not-for-merge branch 'testcommit2223' of github.com:jantman/gitpython_issue_301 +623d6d7e38f40a36d094ffc44e0df2fd616aa69e not-for-merge branch 'testcommit2224' of github.com:jantman/gitpython_issue_301 +598c30e45fa2c332f1306ff3733c589de384f305 not-for-merge branch 'testcommit2225' of github.com:jantman/gitpython_issue_301 +ec697727cbe4c75aa0fe70fa71656d29024b1c3b not-for-merge branch 'testcommit2226' of github.com:jantman/gitpython_issue_301 +36f409ed8d4a5cff2ff7a4bbde2798c908a0c70d not-for-merge branch 'testcommit2227' of github.com:jantman/gitpython_issue_301 +3d05e0efdee0de23c0136c1eb321053960f746a6 not-for-merge branch 'testcommit2228' of github.com:jantman/gitpython_issue_301 +8aa4de111709b2a93058afea30d036bd67d0a8f0 not-for-merge branch 'testcommit2229' of github.com:jantman/gitpython_issue_301 +525f1379468b47a79ac422de820b1f8bafc5e87d not-for-merge branch 'testcommit223' of github.com:jantman/gitpython_issue_301 +63d5af6d702fd76c649c885231d6de0edba888be not-for-merge branch 'testcommit2230' of github.com:jantman/gitpython_issue_301 +91a61b345f72529f9a025b5335e301a7163a9981 not-for-merge branch 'testcommit2231' of github.com:jantman/gitpython_issue_301 +a2ed4d2b6ada7067316d3442657afae89233d8cb not-for-merge branch 'testcommit2232' of github.com:jantman/gitpython_issue_301 +1d371185c7e1acbca2ae14fc606d5290bca28303 not-for-merge branch 'testcommit2233' of github.com:jantman/gitpython_issue_301 +f5aca6b9721384e83da90850626cae2d261f8167 not-for-merge branch 'testcommit2234' of github.com:jantman/gitpython_issue_301 +693b3298b86605af185df590bd34ba7b385644b5 not-for-merge branch 'testcommit2235' of github.com:jantman/gitpython_issue_301 +536c53e19e6c3fb6f64efe06bfdf26ea3cdfba07 not-for-merge branch 'testcommit2236' of github.com:jantman/gitpython_issue_301 +13a0d94c55a8c294a2f5495b7637587ec733d086 not-for-merge branch 'testcommit2237' of github.com:jantman/gitpython_issue_301 +7afb771fb8baf679650653c30953c4f05d2be33e not-for-merge branch 'testcommit2238' of github.com:jantman/gitpython_issue_301 +67e8f4a64cf0f9942161a919b2c9787f30430320 not-for-merge branch 'testcommit2239' of github.com:jantman/gitpython_issue_301 +16961ce037d729e645a5601f436b584ebe86d1a4 not-for-merge branch 'testcommit224' of github.com:jantman/gitpython_issue_301 +203e6d95e7cc7c2874a31a2d037a54250280211c not-for-merge branch 'testcommit2240' of github.com:jantman/gitpython_issue_301 +b83fd6f0f127fb83809531de58ffe04f4a94d7a5 not-for-merge branch 'testcommit2241' of github.com:jantman/gitpython_issue_301 +8a1f91ed08cd3c1f8627618c294c7db61b4f7718 not-for-merge branch 'testcommit2242' of github.com:jantman/gitpython_issue_301 +46968390713fba3ce6242dbdc90ab6ac1f60462b not-for-merge branch 'testcommit2243' of github.com:jantman/gitpython_issue_301 +b5afe9f9f9aeeda73b59990763cad367d36f900d not-for-merge branch 'testcommit2244' of github.com:jantman/gitpython_issue_301 +6dd7d9cda19a06ded0dd98b8fb46b51aa39fb239 not-for-merge branch 'testcommit2245' of github.com:jantman/gitpython_issue_301 +cc6fbb5dc9e69a2a0e743ab6b3db9fb7762e8a6d not-for-merge branch 'testcommit2246' of github.com:jantman/gitpython_issue_301 +d32bcfb824c91286118136f4ce26ec5c458516fa not-for-merge branch 'testcommit2247' of github.com:jantman/gitpython_issue_301 +7d43a4b562c16c060c42ed95fbf0c3caedaad0d5 not-for-merge branch 'testcommit2248' of github.com:jantman/gitpython_issue_301 +0d038b495c0a95015dc799fdc7f8283454dbc4b2 not-for-merge branch 'testcommit2249' of github.com:jantman/gitpython_issue_301 +19aeadbbf556fff248f135b727f8c3c48f051c79 not-for-merge branch 'testcommit225' of github.com:jantman/gitpython_issue_301 +d8143d2c7f8849ec8c1618ad447a5b2f1a9cceff not-for-merge branch 'testcommit2250' of github.com:jantman/gitpython_issue_301 +b23db930b57b8207589aa3c955a7c2776c8714a5 not-for-merge branch 'testcommit2251' of github.com:jantman/gitpython_issue_301 +2e407d03f3993fbe1bf97ba9e4d63329e8c24c66 not-for-merge branch 'testcommit2252' of github.com:jantman/gitpython_issue_301 +e00457cd73115cdb6fb7ee8370a546c64b47cfc8 not-for-merge branch 'testcommit2253' of github.com:jantman/gitpython_issue_301 +2f4abe92aa35150fed35f0b35f7a5a4f27baecd8 not-for-merge branch 'testcommit2254' of github.com:jantman/gitpython_issue_301 +3b2c1efcd3927f6b432a4675c2529deece0c7471 not-for-merge branch 'testcommit2255' of github.com:jantman/gitpython_issue_301 +070959c65deb79a2183bb44da621332d6dde2a15 not-for-merge branch 'testcommit2256' of github.com:jantman/gitpython_issue_301 +5ac1afbfa03d8c167eac46ed47fbf02ae613f299 not-for-merge branch 'testcommit2257' of github.com:jantman/gitpython_issue_301 +91d638383ebff94f84486bd5630092c3c043e7b7 not-for-merge branch 'testcommit2258' of github.com:jantman/gitpython_issue_301 +14377e4c619735b378cb4a84fc1f5ad55957b740 not-for-merge branch 'testcommit2259' of github.com:jantman/gitpython_issue_301 +3fd150078f346fc14188ef1fd6e305097a27bef4 not-for-merge branch 'testcommit226' of github.com:jantman/gitpython_issue_301 +8986391f2c89c2f8e6de4eabac675648b4ee371a not-for-merge branch 'testcommit2260' of github.com:jantman/gitpython_issue_301 +ea5f554317f5bdf1122592a0bc463ca7bdc38037 not-for-merge branch 'testcommit2261' of github.com:jantman/gitpython_issue_301 +31ed0e04c72dd8faf0b3f7bc72ca5e4d9a41aaa5 not-for-merge branch 'testcommit2262' of github.com:jantman/gitpython_issue_301 +f1321d8d0d1d3a61e90f6e2a6babc96bacd7d665 not-for-merge branch 'testcommit2263' of github.com:jantman/gitpython_issue_301 +69506f13e7bfcc5e16adbd93283b35c63d68d6d1 not-for-merge branch 'testcommit2264' of github.com:jantman/gitpython_issue_301 +dd1233e7e67f68b96eb7d5de8cf8c0d9a16ca271 not-for-merge branch 'testcommit2265' of github.com:jantman/gitpython_issue_301 +02516d71a9b7047b875815b1173d499b3f42d18c not-for-merge branch 'testcommit2266' of github.com:jantman/gitpython_issue_301 +7ddc1871919fccc70ce08276d5bd20e2367ec845 not-for-merge branch 'testcommit2267' of github.com:jantman/gitpython_issue_301 +38d028cc6ad46d9d23960e33d94751347cf9323c not-for-merge branch 'testcommit2268' of github.com:jantman/gitpython_issue_301 +ba115859631eec2a68ad328f3659cc00605a0507 not-for-merge branch 'testcommit2269' of github.com:jantman/gitpython_issue_301 +a9e8089c3fb84af1e4b5d60aaeed338bb2a0cda1 not-for-merge branch 'testcommit227' of github.com:jantman/gitpython_issue_301 +eee2631a02043693b18187139d21a6f546d9f1b9 not-for-merge branch 'testcommit2270' of github.com:jantman/gitpython_issue_301 +e2b2b640d0ffe0b7aff3e83c668027a1fcd056d8 not-for-merge branch 'testcommit2271' of github.com:jantman/gitpython_issue_301 +582dfba4b8ca45d476dbd459afe95b87cab21999 not-for-merge branch 'testcommit2272' of github.com:jantman/gitpython_issue_301 +259d28354683c5ee95264e32152e5f70a138e56a not-for-merge branch 'testcommit2273' of github.com:jantman/gitpython_issue_301 +cd8e6ef35b97732cba92d146b35856a578c36bfc not-for-merge branch 'testcommit2274' of github.com:jantman/gitpython_issue_301 +0f8ef7609911a4d80a9b0baac3930ff30c923a2e not-for-merge branch 'testcommit2275' of github.com:jantman/gitpython_issue_301 +fd032ddfc3607a1c1cf474b73d50631d6da4b3a8 not-for-merge branch 'testcommit2276' of github.com:jantman/gitpython_issue_301 +52469f16a3b159b0a95c3530feff98a88d8c9ad5 not-for-merge branch 'testcommit2277' of github.com:jantman/gitpython_issue_301 +b6a56b4ccd3702935e59b631ae16cec50a66debf not-for-merge branch 'testcommit2278' of github.com:jantman/gitpython_issue_301 +f67640bc3fa2d30ee0c52900f20709d01139fbee not-for-merge branch 'testcommit2279' of github.com:jantman/gitpython_issue_301 +87b81d1c54d4341afe2a51e59c34ceb3137c4e6d not-for-merge branch 'testcommit228' of github.com:jantman/gitpython_issue_301 +02441c114f74b36b63ce278cb98f13f57713e546 not-for-merge branch 'testcommit2280' of github.com:jantman/gitpython_issue_301 +e5fcb7de2f3c7b31cec4b82dba086d86770f24b0 not-for-merge branch 'testcommit2281' of github.com:jantman/gitpython_issue_301 +26cfa99ca037033ff00791e54ac626f8ac129fb8 not-for-merge branch 'testcommit2282' of github.com:jantman/gitpython_issue_301 +c6f391c0b6ef699826a0837bd95e05d258f019ab not-for-merge branch 'testcommit2283' of github.com:jantman/gitpython_issue_301 +7b62226e6afb48fef801c24f3a945299a4732733 not-for-merge branch 'testcommit2284' of github.com:jantman/gitpython_issue_301 +6481951a29e494e6b3aedd6002a30b557a978803 not-for-merge branch 'testcommit2285' of github.com:jantman/gitpython_issue_301 +a83807061d53a51b54ba9d72925b85f89935d915 not-for-merge branch 'testcommit2286' of github.com:jantman/gitpython_issue_301 +762dac7005bf7c022bddf31efed439f4d0151d1d not-for-merge branch 'testcommit2287' of github.com:jantman/gitpython_issue_301 +664899277df979d3fe2465972ad830eeef6f5280 not-for-merge branch 'testcommit2288' of github.com:jantman/gitpython_issue_301 +98d3c60127ec7eaca903799739e079f3e48c5b4d not-for-merge branch 'testcommit2289' of github.com:jantman/gitpython_issue_301 +27e0b7bd5d316f5908b9faadf2dbc2f0a9379e8d not-for-merge branch 'testcommit229' of github.com:jantman/gitpython_issue_301 +65a2d58c4d22620bd54070abdb4eb050cb3f2d40 not-for-merge branch 'testcommit2290' of github.com:jantman/gitpython_issue_301 +cab8d562021768c1a3f4930487a8282a78483dc1 not-for-merge branch 'testcommit2291' of github.com:jantman/gitpython_issue_301 +8bcf51cc08da5543ed33d9d3b786421c1289f618 not-for-merge branch 'testcommit2292' of github.com:jantman/gitpython_issue_301 +81879f95b4ab593d9a6a53a4650c38394c903fc1 not-for-merge branch 'testcommit2293' of github.com:jantman/gitpython_issue_301 +9f4ffa8852c33d89c7a057b0e734b0dc245f0345 not-for-merge branch 'testcommit2294' of github.com:jantman/gitpython_issue_301 +37849d2e00ece080dbcc338f93cfa1821266f8d9 not-for-merge branch 'testcommit2295' of github.com:jantman/gitpython_issue_301 +2e1830f2b0d743b94501874f7b73a09460694d00 not-for-merge branch 'testcommit2296' of github.com:jantman/gitpython_issue_301 +20174f17f11225c03819bd8db3132f7bdd226171 not-for-merge branch 'testcommit2297' of github.com:jantman/gitpython_issue_301 +2bbdea142765dad2081a0d208758395ee20a322c not-for-merge branch 'testcommit2298' of github.com:jantman/gitpython_issue_301 +6abf0b05e61decf3777ea6da620ca17e0e7592ec not-for-merge branch 'testcommit2299' of github.com:jantman/gitpython_issue_301 +0fe57e4da5f19feef9f841b2a16771d636af8038 not-for-merge branch 'testcommit23' of github.com:jantman/gitpython_issue_301 +f2bd30b9371cb80e7149350df5e43d5740de3be1 not-for-merge branch 'testcommit230' of github.com:jantman/gitpython_issue_301 +d1426db02ecbc28d6e4c1488649be5e2e0dfc23d not-for-merge branch 'testcommit2300' of github.com:jantman/gitpython_issue_301 +33e22ba8f61501357f22ada1863cc5965c1e52db not-for-merge branch 'testcommit2301' of github.com:jantman/gitpython_issue_301 +4dbe4d5597aebc99f731713df7046b3106c04d28 not-for-merge branch 'testcommit2302' of github.com:jantman/gitpython_issue_301 +5be4523391053b13f1b77eef0a1d20c2423be876 not-for-merge branch 'testcommit2303' of github.com:jantman/gitpython_issue_301 +f10ae0b4b2049ddd8dda2b6b140096a8be8b4c6f not-for-merge branch 'testcommit2304' of github.com:jantman/gitpython_issue_301 +aea1d74f0b532826d1dc549f53aa77e281a65d23 not-for-merge branch 'testcommit2305' of github.com:jantman/gitpython_issue_301 +1b2696c3c4cdb8ab0c8a3b5961140b16e7fe7189 not-for-merge branch 'testcommit2306' of github.com:jantman/gitpython_issue_301 +6e77716d257be115c5756acbda12fa848b35f7a4 not-for-merge branch 'testcommit2307' of github.com:jantman/gitpython_issue_301 +f429a080d99621b2fa65b9c2babc66fb80cb88c1 not-for-merge branch 'testcommit2308' of github.com:jantman/gitpython_issue_301 +924c1496b39f8d7794efb09fc8a231f801a2e716 not-for-merge branch 'testcommit2309' of github.com:jantman/gitpython_issue_301 +da9244bde255bb4ee6e3ba3bac53a8bd4987ed45 not-for-merge branch 'testcommit231' of github.com:jantman/gitpython_issue_301 +2292f7c848cf882dd59e37da952df03dba959976 not-for-merge branch 'testcommit2310' of github.com:jantman/gitpython_issue_301 +627e7be35594175911614667d76691018f0b7384 not-for-merge branch 'testcommit2311' of github.com:jantman/gitpython_issue_301 +1eaf28bc61ea826b1ad9d149edefdefbd9ee7fca not-for-merge branch 'testcommit2312' of github.com:jantman/gitpython_issue_301 +561c2626ca54af77ef2ad9bf5dae5fa9e249f814 not-for-merge branch 'testcommit2313' of github.com:jantman/gitpython_issue_301 +80ebfba4250317fe524a9ba77e0277ee310b5266 not-for-merge branch 'testcommit2314' of github.com:jantman/gitpython_issue_301 +adf7dea28e7d9175394ef64817aee56c288e56f4 not-for-merge branch 'testcommit2315' of github.com:jantman/gitpython_issue_301 +8711ee8bab3029466c6ab4f917b40efac7dfd3e8 not-for-merge branch 'testcommit2316' of github.com:jantman/gitpython_issue_301 +36e299fbc300ff0b70940961cba7a506345e2c4c not-for-merge branch 'testcommit2317' of github.com:jantman/gitpython_issue_301 +fb45e86af26cce21408494fc30c40575e924e89a not-for-merge branch 'testcommit2318' of github.com:jantman/gitpython_issue_301 +ff4a3dc6b40ad04a5f8da4ad6815fdb97f16e9e9 not-for-merge branch 'testcommit2319' of github.com:jantman/gitpython_issue_301 +5e6084d1393da07d80d7fdacd0259ff884edaa7f not-for-merge branch 'testcommit232' of github.com:jantman/gitpython_issue_301 +e0bc54c8b33a8ed7fe39189f073f506f30b95c4e not-for-merge branch 'testcommit2320' of github.com:jantman/gitpython_issue_301 +e831cac5838d33993e2dd7233b1d955e96f46c90 not-for-merge branch 'testcommit2321' of github.com:jantman/gitpython_issue_301 +376f8bc59102e5e5c3b8d74e250d43010b21bfbe not-for-merge branch 'testcommit2322' of github.com:jantman/gitpython_issue_301 +059ab4297af3991d2cf215f455589eaeb458ce84 not-for-merge branch 'testcommit2323' of github.com:jantman/gitpython_issue_301 +baf8ac74e559a718281e2062f215fb60043de83c not-for-merge branch 'testcommit2324' of github.com:jantman/gitpython_issue_301 +78cc716c9e1ee4fdb8f33b0bac574275bfb46876 not-for-merge branch 'testcommit2325' of github.com:jantman/gitpython_issue_301 +ffb60495241c1f28537758e60bb02ac87686886e not-for-merge branch 'testcommit2326' of github.com:jantman/gitpython_issue_301 +6923f9cc0e4508a2d8be28f62be04b0bce795e9c not-for-merge branch 'testcommit2327' of github.com:jantman/gitpython_issue_301 +72d361c6a437be7b86844fbdec19133993b2ca7c not-for-merge branch 'testcommit2328' of github.com:jantman/gitpython_issue_301 +226dd68bc54c953f64b1944964897eeab5e36747 not-for-merge branch 'testcommit2329' of github.com:jantman/gitpython_issue_301 +8779414ab495735092104a4f2bbc02e4b0101cdc not-for-merge branch 'testcommit233' of github.com:jantman/gitpython_issue_301 +1f0f268263b9eb3b80713758421d88e9b92e3f4e not-for-merge branch 'testcommit2330' of github.com:jantman/gitpython_issue_301 +e46db99708fc5decd05db56ceedf845c3efa94e7 not-for-merge branch 'testcommit2331' of github.com:jantman/gitpython_issue_301 +778ce4cc6cd730e39438427520de285ffa207f1b not-for-merge branch 'testcommit2332' of github.com:jantman/gitpython_issue_301 +f152342389ad4eef1bf91121af1129309c1e014d not-for-merge branch 'testcommit2333' of github.com:jantman/gitpython_issue_301 +23ecd57f178bf24c18743b827729d752fd24a977 not-for-merge branch 'testcommit2334' of github.com:jantman/gitpython_issue_301 +048c88c1d8475e420775b3228772c5e38dff3c5f not-for-merge branch 'testcommit2335' of github.com:jantman/gitpython_issue_301 +f6a96d81f5c9ceeaaae98328cb6e9ee6f6778389 not-for-merge branch 'testcommit2336' of github.com:jantman/gitpython_issue_301 +42a41d352322b56b283d221202be1029f9a0fd77 not-for-merge branch 'testcommit2337' of github.com:jantman/gitpython_issue_301 +5a3cc6499728ba879a77b84ead9091479f4334dd not-for-merge branch 'testcommit2338' of github.com:jantman/gitpython_issue_301 +721718838d5cc8e4d76f383f3b61bea5cb4c752b not-for-merge branch 'testcommit2339' of github.com:jantman/gitpython_issue_301 +a259452c051820c3faf31eb311eabcf23adac7b5 not-for-merge branch 'testcommit234' of github.com:jantman/gitpython_issue_301 +53c4da3cfe6ce02dc93f4205a8d2072a1e7e91f2 not-for-merge branch 'testcommit2340' of github.com:jantman/gitpython_issue_301 +32d05aec002cba39b6b39e6ff331ccb614b77417 not-for-merge branch 'testcommit2341' of github.com:jantman/gitpython_issue_301 +4fa83d07775a0ab5ff2eacef7c529729a217c588 not-for-merge branch 'testcommit2342' of github.com:jantman/gitpython_issue_301 +52150e498c4f207e160a2ca7707c5533e9add502 not-for-merge branch 'testcommit2343' of github.com:jantman/gitpython_issue_301 +617c1868be2219e99444905ed0a9273d7d7beaeb not-for-merge branch 'testcommit2344' of github.com:jantman/gitpython_issue_301 +7c4b00fe848b6b61bb59b6d4606d80a1a445df58 not-for-merge branch 'testcommit2345' of github.com:jantman/gitpython_issue_301 +09f4f1765dd99c92053cb362cfced686a1ccf40b not-for-merge branch 'testcommit2346' of github.com:jantman/gitpython_issue_301 +0dc1cbc52512a3887aec94a7587321772cfc32d0 not-for-merge branch 'testcommit2347' of github.com:jantman/gitpython_issue_301 +57654560c0f2efe10cc6d1b7135d8d5286edbe5f not-for-merge branch 'testcommit2348' of github.com:jantman/gitpython_issue_301 +95b1fc51566c08fe619592f96df778abb4bb5a30 not-for-merge branch 'testcommit2349' of github.com:jantman/gitpython_issue_301 +28e2e39d8469c8052ed658af7b48ae62e67a97fb not-for-merge branch 'testcommit235' of github.com:jantman/gitpython_issue_301 +2024e4d5f6a22d7c278cd23dd2a5e3f826b71206 not-for-merge branch 'testcommit2350' of github.com:jantman/gitpython_issue_301 +64f918c87e1dcf23c11dc643748391c991a83f4e not-for-merge branch 'testcommit2351' of github.com:jantman/gitpython_issue_301 +ad6864f9d42d1de5f442dc5c1c532265f23594eb not-for-merge branch 'testcommit2352' of github.com:jantman/gitpython_issue_301 +66a248b9a261bbd2d28bebc239e8c5a208ffddab not-for-merge branch 'testcommit2353' of github.com:jantman/gitpython_issue_301 +ed2fb5de7500a3497e5108ff09261ef1168aec29 not-for-merge branch 'testcommit2354' of github.com:jantman/gitpython_issue_301 +e10160318492d3f1c74cf95e601edd6f9addf02a not-for-merge branch 'testcommit2355' of github.com:jantman/gitpython_issue_301 +35422657a2f4939e66bca2f78e827f1a20c0e6ca not-for-merge branch 'testcommit2356' of github.com:jantman/gitpython_issue_301 +4ec6bc3b224265a670b825bc766503d1e875dda5 not-for-merge branch 'testcommit2357' of github.com:jantman/gitpython_issue_301 +988ab730ca6f0f30fd87976b3c2f4800cc695c34 not-for-merge branch 'testcommit2358' of github.com:jantman/gitpython_issue_301 +f11991e5f3825647fccf5a0a1995056a61e2ad91 not-for-merge branch 'testcommit2359' of github.com:jantman/gitpython_issue_301 +6ae4a6f60f4cd116d821578d3ff194710e67e475 not-for-merge branch 'testcommit236' of github.com:jantman/gitpython_issue_301 +407a35181363d4d8274ac62766c0eabc81549825 not-for-merge branch 'testcommit2360' of github.com:jantman/gitpython_issue_301 +b6b7c0f11864d87a164a7c20984691796aaf1be9 not-for-merge branch 'testcommit2361' of github.com:jantman/gitpython_issue_301 +29ae536227f7318c1e2592fb6dcbf2726c0de5e8 not-for-merge branch 'testcommit2362' of github.com:jantman/gitpython_issue_301 +4ee0c17b2a64c3f9dc39dded191fe80f429be935 not-for-merge branch 'testcommit2363' of github.com:jantman/gitpython_issue_301 +7efe265e8fd283d9b38eed2207c1835f5bbf092b not-for-merge branch 'testcommit2364' of github.com:jantman/gitpython_issue_301 +09163df544adf906da100b7af19b6900b442ff60 not-for-merge branch 'testcommit2365' of github.com:jantman/gitpython_issue_301 +7c0d70c8ed5f3bd96c0dfd7efabf49d89a4d4845 not-for-merge branch 'testcommit2366' of github.com:jantman/gitpython_issue_301 +fc11ea6fc4f551aeb0340eeab93b32ca471aacc9 not-for-merge branch 'testcommit2367' of github.com:jantman/gitpython_issue_301 +1ca123892afa748526569f07881ff490843a7a65 not-for-merge branch 'testcommit2368' of github.com:jantman/gitpython_issue_301 +75a798cbea6a95b5ab85df638f09f538ffb4fb89 not-for-merge branch 'testcommit2369' of github.com:jantman/gitpython_issue_301 +7239ebcf436f0599f72269668dbe47d95c9a8b59 not-for-merge branch 'testcommit237' of github.com:jantman/gitpython_issue_301 +910115a40a24864fad19a9519e24dd34cb3fbeb5 not-for-merge branch 'testcommit2370' of github.com:jantman/gitpython_issue_301 +9a5de3e3be0efa89309d48b6ba4ff2612a97c15f not-for-merge branch 'testcommit2371' of github.com:jantman/gitpython_issue_301 +45dd7b9cee58faa19179a3ff29702d65c5663660 not-for-merge branch 'testcommit2372' of github.com:jantman/gitpython_issue_301 +4b8c55c0f9fc8447a98b17723d007a7f0582bcf8 not-for-merge branch 'testcommit2373' of github.com:jantman/gitpython_issue_301 +f0fc0c611cef7d3e02df897e9d64c76180a8d780 not-for-merge branch 'testcommit2374' of github.com:jantman/gitpython_issue_301 +55cc258eea8e1b8cc655349b088a6f77d0a39d35 not-for-merge branch 'testcommit2375' of github.com:jantman/gitpython_issue_301 +4575d57bd7f40d2c6d95a5c132013334fb1e0e24 not-for-merge branch 'testcommit2376' of github.com:jantman/gitpython_issue_301 +c6d3d91320352fa45920f37c4d818a29d291f580 not-for-merge branch 'testcommit2377' of github.com:jantman/gitpython_issue_301 +78f893af9737cbaf8684432e2fb765c893f3bb5a not-for-merge branch 'testcommit2378' of github.com:jantman/gitpython_issue_301 +cb7b64cbdfa4e9c151d9d4fb0e6d66a48b4f215a not-for-merge branch 'testcommit2379' of github.com:jantman/gitpython_issue_301 +8bb584df2d90ab6a6ba528f87da785f976aff951 not-for-merge branch 'testcommit238' of github.com:jantman/gitpython_issue_301 +47911636da6831da595483bbdff207f0c538ae7d not-for-merge branch 'testcommit2380' of github.com:jantman/gitpython_issue_301 +71cb4ac1d7528ffed3b5f0ff0d44060b8b582c13 not-for-merge branch 'testcommit2381' of github.com:jantman/gitpython_issue_301 +327bc749c4d7230594ecd1503310ee35b93c9eb4 not-for-merge branch 'testcommit2382' of github.com:jantman/gitpython_issue_301 +2735a2c7ed6cda41b21c790221513f879338448a not-for-merge branch 'testcommit2383' of github.com:jantman/gitpython_issue_301 +1fae50a37e65e010de5c10ecdb6c68b15489016a not-for-merge branch 'testcommit2384' of github.com:jantman/gitpython_issue_301 +3caf3663260c7043df279bde9366cbe4759d5522 not-for-merge branch 'testcommit2385' of github.com:jantman/gitpython_issue_301 +479ebb2583aca3e52c1970b62b8e6288fbcfe91e not-for-merge branch 'testcommit2386' of github.com:jantman/gitpython_issue_301 +cec1951f472ffd9978700feb8ec9898b86b29e86 not-for-merge branch 'testcommit2387' of github.com:jantman/gitpython_issue_301 +d4eefd5da01f3b7ee3d4089021b21e263da35abc not-for-merge branch 'testcommit2388' of github.com:jantman/gitpython_issue_301 +d739805a3b0add73aa9eae5f0a7426f9a152e6a5 not-for-merge branch 'testcommit2389' of github.com:jantman/gitpython_issue_301 +f4c87added742d3317bc1d02258a6c21838b737f not-for-merge branch 'testcommit239' of github.com:jantman/gitpython_issue_301 +f70e1f7cf9b83baed530e211464e369253a63a41 not-for-merge branch 'testcommit2390' of github.com:jantman/gitpython_issue_301 +e2adaa45776273cca5c930fd709bb1c895eb671c not-for-merge branch 'testcommit2391' of github.com:jantman/gitpython_issue_301 +364045967b74f9157ef9e06bd082befaa2f44cb5 not-for-merge branch 'testcommit2392' of github.com:jantman/gitpython_issue_301 +ca394b781920b959ace80098bc5c93efa765b361 not-for-merge branch 'testcommit2393' of github.com:jantman/gitpython_issue_301 +bd299622ce49ab2dd15c584de706984c2b61c21c not-for-merge branch 'testcommit2394' of github.com:jantman/gitpython_issue_301 +218a9ec3edb64488ec380fe4cda5951635b82d40 not-for-merge branch 'testcommit2395' of github.com:jantman/gitpython_issue_301 +0264f83198904a32f22604e8719b31b0cafe4556 not-for-merge branch 'testcommit2396' of github.com:jantman/gitpython_issue_301 +14aa73f6dfba1325fce39d2187f4c5c8dd35d2e6 not-for-merge branch 'testcommit2397' of github.com:jantman/gitpython_issue_301 +6a529f95b491069e09969118a0498e5de8c3acef not-for-merge branch 'testcommit2398' of github.com:jantman/gitpython_issue_301 +8ac0f4139f265c149c90b82952d9c4dae063c378 not-for-merge branch 'testcommit2399' of github.com:jantman/gitpython_issue_301 +b4d14118c8216eaf0206c1e92a82d21638ac3289 not-for-merge branch 'testcommit24' of github.com:jantman/gitpython_issue_301 +965715bd555173f06e3e880d675f05ff96042d69 not-for-merge branch 'testcommit240' of github.com:jantman/gitpython_issue_301 +b9c20db245f2b7a0f8191e2e22b48846e10001a7 not-for-merge branch 'testcommit2400' of github.com:jantman/gitpython_issue_301 +24c61898b4d67ecc700d41ab4e65564559bf022e not-for-merge branch 'testcommit2401' of github.com:jantman/gitpython_issue_301 +44eecabed6eb2d32a2acce0f4ea73a2a5e9200f1 not-for-merge branch 'testcommit2402' of github.com:jantman/gitpython_issue_301 +a137725293bc9725151ddc8aedb732c55a284961 not-for-merge branch 'testcommit2403' of github.com:jantman/gitpython_issue_301 +286b2678fca2d36525c6c8360ada172605196c24 not-for-merge branch 'testcommit2404' of github.com:jantman/gitpython_issue_301 +bddfe3e3ff6ed510a38ee0db41e9dca436a08108 not-for-merge branch 'testcommit2405' of github.com:jantman/gitpython_issue_301 +4cd9b9e436e1b13c6e28d89ecc8c67da48b21497 not-for-merge branch 'testcommit2406' of github.com:jantman/gitpython_issue_301 +2215efb01737dc8ab47161a9e0eb305fd376f107 not-for-merge branch 'testcommit2407' of github.com:jantman/gitpython_issue_301 +29e970c5ca417af9dc3aca63aefb0aef2de07e7f not-for-merge branch 'testcommit2408' of github.com:jantman/gitpython_issue_301 +3bc21777a3b3bf0cf8b5431adfcb6740e8d23ac6 not-for-merge branch 'testcommit2409' of github.com:jantman/gitpython_issue_301 +9c2a9c05314edce9b3d124c0d6c165ee8e5a13ec not-for-merge branch 'testcommit241' of github.com:jantman/gitpython_issue_301 +b2b874a22460571b6ec9840d7b7014aa3e982570 not-for-merge branch 'testcommit2410' of github.com:jantman/gitpython_issue_301 +b7744beff988a44a685003a75304dc42c814d344 not-for-merge branch 'testcommit2411' of github.com:jantman/gitpython_issue_301 +cb943af9d0a52c7fa6dbedab55d1f363c6d2b413 not-for-merge branch 'testcommit2412' of github.com:jantman/gitpython_issue_301 +5307367bba8f69d6684e9a4ffb41f243a9ebebb2 not-for-merge branch 'testcommit2413' of github.com:jantman/gitpython_issue_301 +f8a2457bf625b53d5ba7647a5d79fec26ae6b3c0 not-for-merge branch 'testcommit2414' of github.com:jantman/gitpython_issue_301 +9ff7efd18383834bf3d1246344b3965d5ad42d6c not-for-merge branch 'testcommit2415' of github.com:jantman/gitpython_issue_301 +f766d03deaa52e516e46f4826baffaeb88ae964f not-for-merge branch 'testcommit2416' of github.com:jantman/gitpython_issue_301 +8e5d51e85abbb9ea15589e0c678771d965bc2905 not-for-merge branch 'testcommit2417' of github.com:jantman/gitpython_issue_301 +0aec4ee825bfe3c4093d8db393576788cf612a4e not-for-merge branch 'testcommit2418' of github.com:jantman/gitpython_issue_301 +b21e3a187d872804f1cae76fae015322ee2aae2a not-for-merge branch 'testcommit2419' of github.com:jantman/gitpython_issue_301 +b1e5015368b731dc9595ce09f026c47da27e2a38 not-for-merge branch 'testcommit242' of github.com:jantman/gitpython_issue_301 +7160977fc9bce9543b2df45b7113ebf95d38c77b not-for-merge branch 'testcommit2420' of github.com:jantman/gitpython_issue_301 +eb54221f4ae7c3c19057d3d48b22115b0039f414 not-for-merge branch 'testcommit2421' of github.com:jantman/gitpython_issue_301 +9aac3c05842419cf32be269da09c08fce25dcbb5 not-for-merge branch 'testcommit2422' of github.com:jantman/gitpython_issue_301 +e5fc7ca540e12718ba84f7357953e13c38c45c60 not-for-merge branch 'testcommit2423' of github.com:jantman/gitpython_issue_301 +23e05f9aea9f4defba3123c7b654e7c6b78198be not-for-merge branch 'testcommit2424' of github.com:jantman/gitpython_issue_301 +56305aab985d88e99714e5aab841a25b4a5c119c not-for-merge branch 'testcommit2425' of github.com:jantman/gitpython_issue_301 +5c617aeb3435f322b191c172df5cb4750efa7b23 not-for-merge branch 'testcommit2426' of github.com:jantman/gitpython_issue_301 +27601a41b8cd732bc64977889cf224b51083a730 not-for-merge branch 'testcommit2427' of github.com:jantman/gitpython_issue_301 +42cdf67527c5e82388954dc2e4f5470eb6a043ac not-for-merge branch 'testcommit2428' of github.com:jantman/gitpython_issue_301 +3dccf168418e1a0dcddbfb8bb56a21a5f4abf0f7 not-for-merge branch 'testcommit2429' of github.com:jantman/gitpython_issue_301 +662ef4ad9f101cf742eff68a9a7af8701fe39034 not-for-merge branch 'testcommit243' of github.com:jantman/gitpython_issue_301 +cd733cdf51224e3cb163839b34c13c1ba14ff01c not-for-merge branch 'testcommit2430' of github.com:jantman/gitpython_issue_301 +756e873f8f0091f3396bc7ca79d595cb60114f76 not-for-merge branch 'testcommit2431' of github.com:jantman/gitpython_issue_301 +7a8dded69bac5eb00440b2ff9c96ecdbe809f67d not-for-merge branch 'testcommit2432' of github.com:jantman/gitpython_issue_301 +38de30b4cecb5d52937e6b18d69f4bcad3e8e25c not-for-merge branch 'testcommit2433' of github.com:jantman/gitpython_issue_301 +8299dc56d1fe1299c050786489b76592f643ec83 not-for-merge branch 'testcommit2434' of github.com:jantman/gitpython_issue_301 +7a0a1ca0f38def3782956c10bb49b4ceab85d157 not-for-merge branch 'testcommit2435' of github.com:jantman/gitpython_issue_301 +6416b4fcc302ba8c2f94310acbf3693adf86df1c not-for-merge branch 'testcommit2436' of github.com:jantman/gitpython_issue_301 +4e8e603caac7e6ddd4e703a6025727d224b5f41f not-for-merge branch 'testcommit2437' of github.com:jantman/gitpython_issue_301 +f09f9909ec5349346a05248f32c70b7654b6e590 not-for-merge branch 'testcommit2438' of github.com:jantman/gitpython_issue_301 +64611e2c7af7e83b01738ba7cebc4ffa0d2017bc not-for-merge branch 'testcommit2439' of github.com:jantman/gitpython_issue_301 +883337c976df16fd6cdb5229921b0f6f84dbfb4c not-for-merge branch 'testcommit244' of github.com:jantman/gitpython_issue_301 +27d18962404b8aa222c9d3c4357d134161bbcaa2 not-for-merge branch 'testcommit2440' of github.com:jantman/gitpython_issue_301 +ea288d352db1d7eaa1c8d00289c6a0bdda1bcc76 not-for-merge branch 'testcommit2441' of github.com:jantman/gitpython_issue_301 +73986aa79af74fc72ede132010397ff819f62c1c not-for-merge branch 'testcommit2442' of github.com:jantman/gitpython_issue_301 +d67afc83b0608854804f7a49da2ddcfc4efbc941 not-for-merge branch 'testcommit2443' of github.com:jantman/gitpython_issue_301 +1fa31c4205aa139ae8b3e751dee734b13f84f301 not-for-merge branch 'testcommit2444' of github.com:jantman/gitpython_issue_301 +972c33b3f51db5849143a4e5ccc4b2e1393e2c27 not-for-merge branch 'testcommit2445' of github.com:jantman/gitpython_issue_301 +23b88e677b51d57ca4a886508570f208d86e9dae not-for-merge branch 'testcommit2446' of github.com:jantman/gitpython_issue_301 +22daf2e983ba9ba119a996b4d9b30e72986c866d not-for-merge branch 'testcommit2447' of github.com:jantman/gitpython_issue_301 +98b2e4e6fe211f51f4b874b6e0ab3c166dcf8409 not-for-merge branch 'testcommit2448' of github.com:jantman/gitpython_issue_301 +48a440515d5b05120fd7ff5a8229b69883c31c55 not-for-merge branch 'testcommit2449' of github.com:jantman/gitpython_issue_301 +e5d8cfe4b41d26fcf4140d1c7492f5d82c56e78e not-for-merge branch 'testcommit245' of github.com:jantman/gitpython_issue_301 +ba2281218b20f708d7ad19c4bd5af24620b8dec8 not-for-merge branch 'testcommit2450' of github.com:jantman/gitpython_issue_301 +63156b30b41c8431b6af2ebfe221f1a301d64433 not-for-merge branch 'testcommit2451' of github.com:jantman/gitpython_issue_301 +1f6a4f8fca81cf72c08f749a753147487582c24f not-for-merge branch 'testcommit2452' of github.com:jantman/gitpython_issue_301 +2cebb78eaeb9b91832c0512063e74f0bb13c6470 not-for-merge branch 'testcommit2453' of github.com:jantman/gitpython_issue_301 +a35cf782cd3c1b2133f9603d41d3f5d838490720 not-for-merge branch 'testcommit2454' of github.com:jantman/gitpython_issue_301 +2a628386f39d921671b662335bcdce1564dcfbb2 not-for-merge branch 'testcommit2455' of github.com:jantman/gitpython_issue_301 +6477371c396b500b13c5faec7c870b82158fad3b not-for-merge branch 'testcommit2456' of github.com:jantman/gitpython_issue_301 +6cd874e1ab26af23779ef185d850ee8af9fdce4e not-for-merge branch 'testcommit2457' of github.com:jantman/gitpython_issue_301 +6cb426bd96fa4806a684713cafe3d687829203b4 not-for-merge branch 'testcommit2458' of github.com:jantman/gitpython_issue_301 +1efc72c0298cabe19de93600ffda106e3bf13a4e not-for-merge branch 'testcommit2459' of github.com:jantman/gitpython_issue_301 +1d4b1ef1c940bb3bab1b02eedbb92da3604808e4 not-for-merge branch 'testcommit246' of github.com:jantman/gitpython_issue_301 +fab1e8f9ec9de577a7287c77803df1218b41ab78 not-for-merge branch 'testcommit2460' of github.com:jantman/gitpython_issue_301 +1c4a67cbfd46701c3f9c0003f77f16e2ad509987 not-for-merge branch 'testcommit2461' of github.com:jantman/gitpython_issue_301 +03a4c137c42cf631221067a2d06e1614047d5b2d not-for-merge branch 'testcommit2462' of github.com:jantman/gitpython_issue_301 +760bee2374f630049ba0e2be91f7d30bdc35def2 not-for-merge branch 'testcommit2463' of github.com:jantman/gitpython_issue_301 +411130ce4abafdde62e65d13a9b73040ce5f6992 not-for-merge branch 'testcommit2464' of github.com:jantman/gitpython_issue_301 +9809dda92b35c05ce19745dcf50909786e79d446 not-for-merge branch 'testcommit2465' of github.com:jantman/gitpython_issue_301 +07e38d233ca974dcefd941072367759ace0c56d2 not-for-merge branch 'testcommit2466' of github.com:jantman/gitpython_issue_301 +b302017f225a5e47328d5e70a18fd4974a3af5ae not-for-merge branch 'testcommit2467' of github.com:jantman/gitpython_issue_301 +02549af281231180983872841b31f9f49d2c68b5 not-for-merge branch 'testcommit2468' of github.com:jantman/gitpython_issue_301 +991e168ded96390212d294f217fdcc4d0a6e6083 not-for-merge branch 'testcommit2469' of github.com:jantman/gitpython_issue_301 +b88fb990f009c56eef157ae5cdc477a0683f482d not-for-merge branch 'testcommit247' of github.com:jantman/gitpython_issue_301 +f2448ce092ec2ad3855b94facdeea9dfa52a53c7 not-for-merge branch 'testcommit2470' of github.com:jantman/gitpython_issue_301 +c249f489360bfac4fb81bdb78bdd356ec67f32a3 not-for-merge branch 'testcommit2471' of github.com:jantman/gitpython_issue_301 +db55205a7cfc73e6d74724b7fefd6eed44a3cd2b not-for-merge branch 'testcommit2472' of github.com:jantman/gitpython_issue_301 +40c4197fd8ed2ac4de16b5cec4d3a47786e6f7a3 not-for-merge branch 'testcommit2473' of github.com:jantman/gitpython_issue_301 +6201845ec1a44978d048d80c73852c93ad336bc6 not-for-merge branch 'testcommit2474' of github.com:jantman/gitpython_issue_301 +3d0566940de40dde5190ec3b61adb16ea9bf288c not-for-merge branch 'testcommit2475' of github.com:jantman/gitpython_issue_301 +551eea23140f5d0ce217d9b4f9cecb7e3a2cca14 not-for-merge branch 'testcommit2476' of github.com:jantman/gitpython_issue_301 +5a289451475676fa60a7bae5615a438a8b6fee1d not-for-merge branch 'testcommit2477' of github.com:jantman/gitpython_issue_301 +483522410fa62ab90a9c9565f6c5ee53951debf4 not-for-merge branch 'testcommit2478' of github.com:jantman/gitpython_issue_301 +b551623a6bc97b819ba00457b6c9e58ec53bfe2d not-for-merge branch 'testcommit2479' of github.com:jantman/gitpython_issue_301 +a3bab4cca99cd3f70cf4d8f26a7f31a604a73790 not-for-merge branch 'testcommit248' of github.com:jantman/gitpython_issue_301 +2d85780aaab6111fd914527f10cc2b21b79b10fe not-for-merge branch 'testcommit2480' of github.com:jantman/gitpython_issue_301 +d9bad33d717697f384ac845568bc4660c0fa17f2 not-for-merge branch 'testcommit2481' of github.com:jantman/gitpython_issue_301 +8e3c245be7c2f0ebfc25007d55d1084efa831457 not-for-merge branch 'testcommit2482' of github.com:jantman/gitpython_issue_301 +fa0a870b42a806fd15a6a22a1d19250bede168f6 not-for-merge branch 'testcommit2483' of github.com:jantman/gitpython_issue_301 +495904b9d5e6c534526ff2943e938a962d519098 not-for-merge branch 'testcommit2484' of github.com:jantman/gitpython_issue_301 +7bf6fc5692c576d918131a59e5b21c3ba761c4b1 not-for-merge branch 'testcommit2485' of github.com:jantman/gitpython_issue_301 +73a58778157d8f5bf547e15ed37bf6ef04d6b3d4 not-for-merge branch 'testcommit2486' of github.com:jantman/gitpython_issue_301 +5f5cda3d2d41f3dffd518e709844dd32a8c9ebaa not-for-merge branch 'testcommit2487' of github.com:jantman/gitpython_issue_301 +1bcbd2ee03bdd4ed3dee14801cfd7d447ab5893f not-for-merge branch 'testcommit2488' of github.com:jantman/gitpython_issue_301 +71bbb9703780bc1168efd6ad80792b72e29368d0 not-for-merge branch 'testcommit2489' of github.com:jantman/gitpython_issue_301 +1a82f3c2f9b29614cf62762a8f34ea71533b5024 not-for-merge branch 'testcommit249' of github.com:jantman/gitpython_issue_301 +65c7e457923624025c8ec8db959eb1d6bf574227 not-for-merge branch 'testcommit2490' of github.com:jantman/gitpython_issue_301 +554fff3a56baed029d9e5c700ab04694cf0d903f not-for-merge branch 'testcommit2491' of github.com:jantman/gitpython_issue_301 +1f8e7643e8eaaeac85402ffcbdba04d7ac87e9fc not-for-merge branch 'testcommit2492' of github.com:jantman/gitpython_issue_301 +c595c602818bfe85bf7f0bbf8b7642d6c46ca107 not-for-merge branch 'testcommit2493' of github.com:jantman/gitpython_issue_301 +fd5ca5d1b23476b7d4b19787117981ef50981971 not-for-merge branch 'testcommit2494' of github.com:jantman/gitpython_issue_301 +94ffe7293aba50d644cf7e4ce291c02065530f24 not-for-merge branch 'testcommit2495' of github.com:jantman/gitpython_issue_301 +204d77290958e8a63f51b4b712c4e096de875ede not-for-merge branch 'testcommit2496' of github.com:jantman/gitpython_issue_301 +0ced74e2d818799241d509437481d326cb2e6a29 not-for-merge branch 'testcommit2497' of github.com:jantman/gitpython_issue_301 +becb9b183a16b28f9635f9010c9e4f6ca6d1f40d not-for-merge branch 'testcommit2498' of github.com:jantman/gitpython_issue_301 +10c6365d8c5aaf192f7b74fa64052a95425dd5b8 not-for-merge branch 'testcommit2499' of github.com:jantman/gitpython_issue_301 +36ecc67ce3ad378c357403dccc885e564fd1fb6c not-for-merge branch 'testcommit25' of github.com:jantman/gitpython_issue_301 +7f65c6e89bb4d25127a11b13ab01a26d7b5917d0 not-for-merge branch 'testcommit250' of github.com:jantman/gitpython_issue_301 +9f8207cea9f14613b0da78aad6315ab7366729e9 not-for-merge branch 'testcommit2500' of github.com:jantman/gitpython_issue_301 +6fb9649faa6bdbb71e77f1f82937c3c1a26a1e0f not-for-merge branch 'testcommit2501' of github.com:jantman/gitpython_issue_301 +9af73df381eab5ef131300ce0ae4dffe2209eef5 not-for-merge branch 'testcommit2502' of github.com:jantman/gitpython_issue_301 +88433e2dcbe32d379b0282e9629170b384a27ef6 not-for-merge branch 'testcommit2503' of github.com:jantman/gitpython_issue_301 +b3d3457f4d86a74d100baace5e2a1fd21a93a8af not-for-merge branch 'testcommit2504' of github.com:jantman/gitpython_issue_301 +e50d10b6a87ae30d15b0507e950de03d0f9c089b not-for-merge branch 'testcommit2505' of github.com:jantman/gitpython_issue_301 +7b22683150ba8f8ff4c4da2f07c8b1a36d51f582 not-for-merge branch 'testcommit2506' of github.com:jantman/gitpython_issue_301 +634341785be8c1cd80aea9ea546925586163f9ff not-for-merge branch 'testcommit2507' of github.com:jantman/gitpython_issue_301 +2f921695dd1023b845fa53a8fea7862c6ffa3ab0 not-for-merge branch 'testcommit2508' of github.com:jantman/gitpython_issue_301 +3ecbb8310c8ac3d44f4e6db90fe6feff89ce32e8 not-for-merge branch 'testcommit2509' of github.com:jantman/gitpython_issue_301 +8fe658a85456807f4d679e187feb6e19a34177fb not-for-merge branch 'testcommit251' of github.com:jantman/gitpython_issue_301 +4a81015742b8e6cfd0c1688a5149d6dbf1ad8fab not-for-merge branch 'testcommit2510' of github.com:jantman/gitpython_issue_301 +b49afa22e3445c286d393a648c7008899e357f16 not-for-merge branch 'testcommit2511' of github.com:jantman/gitpython_issue_301 +9ab15838a207fcce6794a5732e1a41225695f3e4 not-for-merge branch 'testcommit2512' of github.com:jantman/gitpython_issue_301 +a8d28cd2dd6b43071d789c2086ea44c9d509f839 not-for-merge branch 'testcommit2513' of github.com:jantman/gitpython_issue_301 +65a8f327d1d0f21180e0a06a7b97ce5e92e11187 not-for-merge branch 'testcommit2514' of github.com:jantman/gitpython_issue_301 +eb1ce859412acd84ed8fd095b949e9a52148fe26 not-for-merge branch 'testcommit2515' of github.com:jantman/gitpython_issue_301 +32cb05cd13b01cb7f3e28e3aab6d0ea37152ccc9 not-for-merge branch 'testcommit2516' of github.com:jantman/gitpython_issue_301 +65a7462c7fb6c0efb3ae55dd60c2a75d24b17699 not-for-merge branch 'testcommit2517' of github.com:jantman/gitpython_issue_301 +346cbbcedec7f318aeb73c2f7680d2fb9b873256 not-for-merge branch 'testcommit2518' of github.com:jantman/gitpython_issue_301 +84695003efbf10ce8633329c02e1e27f2bae8ed3 not-for-merge branch 'testcommit2519' of github.com:jantman/gitpython_issue_301 +4ebf7167852e460bac157425ddfc6050eedcb6e8 not-for-merge branch 'testcommit252' of github.com:jantman/gitpython_issue_301 +57671b1f416f664424d890035879304bdbe93db5 not-for-merge branch 'testcommit2520' of github.com:jantman/gitpython_issue_301 +9116784214dd975a277b77edccfb00a155b9a2de not-for-merge branch 'testcommit2521' of github.com:jantman/gitpython_issue_301 +9227a8820d142544c889039090535c91f3a5f619 not-for-merge branch 'testcommit2522' of github.com:jantman/gitpython_issue_301 +a84e4d38fda2edc1210c725d45c2f4f332fb53b9 not-for-merge branch 'testcommit2523' of github.com:jantman/gitpython_issue_301 +fd731b4deccfdadf58337edcc5b5a351335fbdab not-for-merge branch 'testcommit2524' of github.com:jantman/gitpython_issue_301 +a5cef96aa401362360a7f05b416ad5fc1292dce6 not-for-merge branch 'testcommit2525' of github.com:jantman/gitpython_issue_301 +744f1b1eddc435bf75d0a69db682ff77982979b0 not-for-merge branch 'testcommit2526' of github.com:jantman/gitpython_issue_301 +4fd6e2ce11f7a8da63a8103e8f4b63ba904a41fd not-for-merge branch 'testcommit2527' of github.com:jantman/gitpython_issue_301 +ef5dc38b06a23882b4f2f1234fa68ec009327147 not-for-merge branch 'testcommit2528' of github.com:jantman/gitpython_issue_301 +1e5f1adf9c665e8fc2b4e89a0c2f343632e32c87 not-for-merge branch 'testcommit2529' of github.com:jantman/gitpython_issue_301 +81b0668d40dd32901d0dce29b6238d43b0a4b248 not-for-merge branch 'testcommit253' of github.com:jantman/gitpython_issue_301 +63bc745cb3bcda41533aafc82fd10c478258fa82 not-for-merge branch 'testcommit2530' of github.com:jantman/gitpython_issue_301 +06d3fcced50ad8c923549df83f92981cfe868b55 not-for-merge branch 'testcommit2531' of github.com:jantman/gitpython_issue_301 +ca1102f5a01c64685f5d6da535859371f7cd6b2b not-for-merge branch 'testcommit2532' of github.com:jantman/gitpython_issue_301 +5dc38224517b22506ac2a92fda2a47261067de32 not-for-merge branch 'testcommit2533' of github.com:jantman/gitpython_issue_301 +2ca31df99804169b9bcd9ce7faad3a080082124c not-for-merge branch 'testcommit2534' of github.com:jantman/gitpython_issue_301 +ca0a03d079cbba77894fe3e1768e5aec075614ce not-for-merge branch 'testcommit2535' of github.com:jantman/gitpython_issue_301 +6371392995425b3c03379c914d80352996313a1a not-for-merge branch 'testcommit2536' of github.com:jantman/gitpython_issue_301 +275d584bd35615078958d6a5f1e53835fa455519 not-for-merge branch 'testcommit2537' of github.com:jantman/gitpython_issue_301 +3abb1cb869f1159a113d1f4de5751fcefdab5cda not-for-merge branch 'testcommit2538' of github.com:jantman/gitpython_issue_301 +a6209f5516a12ba99c2da26ca4b89ef9c2a4919b not-for-merge branch 'testcommit2539' of github.com:jantman/gitpython_issue_301 +e6539bbf318dda8404b4d68000867952d9ba91db not-for-merge branch 'testcommit254' of github.com:jantman/gitpython_issue_301 +890c959e619477790cf915387ed47cd400bcf22d not-for-merge branch 'testcommit2540' of github.com:jantman/gitpython_issue_301 +ce992bd6b6ed109059771cea2f4975b5ef2d4a26 not-for-merge branch 'testcommit2541' of github.com:jantman/gitpython_issue_301 +14b13f5d38a4dc198cf4f364d8bc359e6806b384 not-for-merge branch 'testcommit2542' of github.com:jantman/gitpython_issue_301 +fd96be8a9ceca346fb83ea263fabe11a10eca49b not-for-merge branch 'testcommit2543' of github.com:jantman/gitpython_issue_301 +f6627807b966d3054ed81f2d5b4849083a962b58 not-for-merge branch 'testcommit2544' of github.com:jantman/gitpython_issue_301 +fcc60eba4d5802993c0de4112483afc19f3b4d30 not-for-merge branch 'testcommit2545' of github.com:jantman/gitpython_issue_301 +11968e5fb02505919beba80ea0d012f03a6867f2 not-for-merge branch 'testcommit2546' of github.com:jantman/gitpython_issue_301 +d0f6adfd67f5dbfd920fb8e0edbb13b7934b2dac not-for-merge branch 'testcommit2547' of github.com:jantman/gitpython_issue_301 +ad814aba0f84b171ce3f9abd080ffe9d81345dd5 not-for-merge branch 'testcommit2548' of github.com:jantman/gitpython_issue_301 +3afcfbd695e9427b3decbe7f77a9a33762defa7a not-for-merge branch 'testcommit2549' of github.com:jantman/gitpython_issue_301 +ee500b47ce450e00868565eb8dbcf1980c66a9c0 not-for-merge branch 'testcommit255' of github.com:jantman/gitpython_issue_301 +035cfd14aef1277f96468207c7199c48ec4edf35 not-for-merge branch 'testcommit2550' of github.com:jantman/gitpython_issue_301 +a422e114c5183308d221922ca6b4bc47d2d1c819 not-for-merge branch 'testcommit2551' of github.com:jantman/gitpython_issue_301 +d0a2e77af2ae0dbf87e5f91efdb85b3ae53c1904 not-for-merge branch 'testcommit2552' of github.com:jantman/gitpython_issue_301 +ae5b919b143b7cfb9013b6fe4d114a92ac31f531 not-for-merge branch 'testcommit2553' of github.com:jantman/gitpython_issue_301 +627dbe84369e211b103e64a475a052f8bedcb395 not-for-merge branch 'testcommit2554' of github.com:jantman/gitpython_issue_301 +ece723468f0eb8bf8be44d3af49412c0706ee264 not-for-merge branch 'testcommit2555' of github.com:jantman/gitpython_issue_301 +490cdf3db2c73dae209b22bae9fa6a2d650a07b3 not-for-merge branch 'testcommit2556' of github.com:jantman/gitpython_issue_301 +c5bdf8ce253384786be95c2b506433dde480eef1 not-for-merge branch 'testcommit2557' of github.com:jantman/gitpython_issue_301 +70b62327f2da14897232140a0414ff790ccd383f not-for-merge branch 'testcommit2558' of github.com:jantman/gitpython_issue_301 +690c04d4f72e3ed2c88c3739bdc726aff369755e not-for-merge branch 'testcommit2559' of github.com:jantman/gitpython_issue_301 +ac347911c82ee30b6b683e2dcc34ffdb3d83970b not-for-merge branch 'testcommit256' of github.com:jantman/gitpython_issue_301 +833751778abacd85f0ca20526e2ac6680ffce9ef not-for-merge branch 'testcommit2560' of github.com:jantman/gitpython_issue_301 +dbcfb87e2703c587a7e6b42ca61dbc1915123e9d not-for-merge branch 'testcommit2561' of github.com:jantman/gitpython_issue_301 +2b49b68cd46e14a58523ff8fcfebca4bd358744f not-for-merge branch 'testcommit2562' of github.com:jantman/gitpython_issue_301 +63e773e12bdb20f2d7f8f9ade7184cda6d583891 not-for-merge branch 'testcommit2563' of github.com:jantman/gitpython_issue_301 +9665011c0245b109d61b1643e5849cf98f10ac64 not-for-merge branch 'testcommit2564' of github.com:jantman/gitpython_issue_301 +3e790f24528c7cdee0faa872563dfebefb9bb7a1 not-for-merge branch 'testcommit2565' of github.com:jantman/gitpython_issue_301 +5dc843d1defb4c016b8d75e26ed131651a73494c not-for-merge branch 'testcommit2566' of github.com:jantman/gitpython_issue_301 +7cba31d62d15a7887aefa476c196b7f6ebda0993 not-for-merge branch 'testcommit2567' of github.com:jantman/gitpython_issue_301 +d94d0a851cfa7383c894b99ab1c59caffa4fceec not-for-merge branch 'testcommit2568' of github.com:jantman/gitpython_issue_301 +2274abbfe6f3ac9827f76ede449eca0f41fa5b8f not-for-merge branch 'testcommit2569' of github.com:jantman/gitpython_issue_301 +8b6264a409bd63a17ce91cfbd096ce69c584358e not-for-merge branch 'testcommit257' of github.com:jantman/gitpython_issue_301 +cdff398579d9fc1042de9d5705b8b141bb7fc240 not-for-merge branch 'testcommit2570' of github.com:jantman/gitpython_issue_301 +524f03f602dd78249faf1257a3bbf2da0898f903 not-for-merge branch 'testcommit2571' of github.com:jantman/gitpython_issue_301 +b47f5cdc1c7fb1a55e5a1df96d69966e2594b59b not-for-merge branch 'testcommit2572' of github.com:jantman/gitpython_issue_301 +2bf626dbb6f1c2c4f42c9ca07851387a9138ea91 not-for-merge branch 'testcommit2573' of github.com:jantman/gitpython_issue_301 +a3b0350cea18e9d2a977822cd58b5c459d22955b not-for-merge branch 'testcommit2574' of github.com:jantman/gitpython_issue_301 +5a6f7df368e95cd5bd4b5d2729dfd90f304237d1 not-for-merge branch 'testcommit2575' of github.com:jantman/gitpython_issue_301 +b26e88546d6c8642e34067507aaab9e55db21043 not-for-merge branch 'testcommit2576' of github.com:jantman/gitpython_issue_301 +f24360465b4dac88c2c94760fb6477f3dc705420 not-for-merge branch 'testcommit2577' of github.com:jantman/gitpython_issue_301 +fce23dc01e8a71d968d2602b83c879c9125f51bb not-for-merge branch 'testcommit2578' of github.com:jantman/gitpython_issue_301 +b9c72e74d9a02685735cdf5527ee7b08179bb945 not-for-merge branch 'testcommit2579' of github.com:jantman/gitpython_issue_301 +56100e094ea6e31e21ce89d6cf3be7ae9b2cb0e9 not-for-merge branch 'testcommit258' of github.com:jantman/gitpython_issue_301 +d3db6f82904a0d2ed6698437d8d046a31169de7f not-for-merge branch 'testcommit2580' of github.com:jantman/gitpython_issue_301 +22827d5ed6e9c8da94125360feb1231d238d2755 not-for-merge branch 'testcommit2581' of github.com:jantman/gitpython_issue_301 +a140a5fa20249fd9e76b493c559dbfe78336b792 not-for-merge branch 'testcommit2582' of github.com:jantman/gitpython_issue_301 +6ae718b96b85a5f7b48048d3d3d856c4a17023e8 not-for-merge branch 'testcommit2583' of github.com:jantman/gitpython_issue_301 +e01fade251ff4ad844f0c8ddaf31e0ae3df5ee16 not-for-merge branch 'testcommit2584' of github.com:jantman/gitpython_issue_301 +cbfdd98197022fe04f72004edeabe1c6b2fa2ce4 not-for-merge branch 'testcommit2585' of github.com:jantman/gitpython_issue_301 +f361df761b4117d09ded74f93dbd944adaa1f5a6 not-for-merge branch 'testcommit2586' of github.com:jantman/gitpython_issue_301 +68abb9be9ec33357b8ccc941332367eb1d22a552 not-for-merge branch 'testcommit2587' of github.com:jantman/gitpython_issue_301 +0f84dca8d20f18ed7fff1914f51e59d2ad1c77bc not-for-merge branch 'testcommit2588' of github.com:jantman/gitpython_issue_301 +ed14e4a52da8d77c12eb2c86feae1c8f96cc2071 not-for-merge branch 'testcommit2589' of github.com:jantman/gitpython_issue_301 +3faa66220ebbcc659a61b2cfebbc05a355a172d3 not-for-merge branch 'testcommit259' of github.com:jantman/gitpython_issue_301 +e26cdd365bc52a6c608a0ef75044691c7031fe90 not-for-merge branch 'testcommit2590' of github.com:jantman/gitpython_issue_301 +31c2122189840c61bb68fdb24b4623110901bc7f not-for-merge branch 'testcommit2591' of github.com:jantman/gitpython_issue_301 +85a9243cd378c0b543354675f5d91c78931eb82b not-for-merge branch 'testcommit2592' of github.com:jantman/gitpython_issue_301 +8a4936ca60a231aeeef8d4c976d2de6753e0cb50 not-for-merge branch 'testcommit2593' of github.com:jantman/gitpython_issue_301 +4697d87c3c3a72d74014284e0313afdac8896df1 not-for-merge branch 'testcommit2594' of github.com:jantman/gitpython_issue_301 +77727bc9e2ebe482df031b55dd4b5947e711f94e not-for-merge branch 'testcommit2595' of github.com:jantman/gitpython_issue_301 +47abd91b828c63b5af658dbec82defe3de7c2e4b not-for-merge branch 'testcommit2596' of github.com:jantman/gitpython_issue_301 +8fb879a957412f521cff23a96d1156703d7977b4 not-for-merge branch 'testcommit2597' of github.com:jantman/gitpython_issue_301 +2506f3999ed65736cc421bc323e5d73d91fa8910 not-for-merge branch 'testcommit2598' of github.com:jantman/gitpython_issue_301 +10b242460292fc9e7d6c8faac9f3b151ac0d63b9 not-for-merge branch 'testcommit2599' of github.com:jantman/gitpython_issue_301 +e070e1850fc3fcc175d5757b384c286274788d42 not-for-merge branch 'testcommit26' of github.com:jantman/gitpython_issue_301 +9e48be2702026120c6c15f27c450955dfc55b786 not-for-merge branch 'testcommit260' of github.com:jantman/gitpython_issue_301 +bfdef405841687d9dec80839993589af8bbb56f1 not-for-merge branch 'testcommit2600' of github.com:jantman/gitpython_issue_301 +51454689316a7913c18899369e353940e9c51da3 not-for-merge branch 'testcommit2601' of github.com:jantman/gitpython_issue_301 +ce0b8bb4aefd1c372d1b51e7da42021e7c4d12a0 not-for-merge branch 'testcommit2602' of github.com:jantman/gitpython_issue_301 +77445f7154035c094c16c6c448a35a33e7d221d6 not-for-merge branch 'testcommit2603' of github.com:jantman/gitpython_issue_301 +53fa5db3d131949deeb2471032913e123500442e not-for-merge branch 'testcommit2604' of github.com:jantman/gitpython_issue_301 +57f9ab589cbc23d753909287fb1a6c0546e3fdc9 not-for-merge branch 'testcommit2605' of github.com:jantman/gitpython_issue_301 +8305ade3aa6c3c7b400140d876a704b58da497ad not-for-merge branch 'testcommit2606' of github.com:jantman/gitpython_issue_301 +95f11943781299259b7185d46ad30df29f476648 not-for-merge branch 'testcommit2607' of github.com:jantman/gitpython_issue_301 +d340663049f70d3ea9dd225a3c535db8998c2a82 not-for-merge branch 'testcommit2608' of github.com:jantman/gitpython_issue_301 +d8bb27acda39727d74160e787a2333d803339761 not-for-merge branch 'testcommit2609' of github.com:jantman/gitpython_issue_301 +b244352a169e7d3e6eb4d6cf84511adf8e0d1d24 not-for-merge branch 'testcommit261' of github.com:jantman/gitpython_issue_301 +ce096555cdeb7f1e49e5f2855d5895e1ab379ab8 not-for-merge branch 'testcommit2610' of github.com:jantman/gitpython_issue_301 +2b5f64057c3c43bcf86dc506e49465e3eaf02dfc not-for-merge branch 'testcommit2611' of github.com:jantman/gitpython_issue_301 +884d6baa8267feb83e6b53c08b9cfe39287ddce4 not-for-merge branch 'testcommit2612' of github.com:jantman/gitpython_issue_301 +a4cb1c752e962c7c01719350c5ed53279225e6af not-for-merge branch 'testcommit2613' of github.com:jantman/gitpython_issue_301 +2275030b6492cee03472aac3576d58c67e943b3c not-for-merge branch 'testcommit2614' of github.com:jantman/gitpython_issue_301 +f039e98fd25f6d94fd97af1ea7c84f08adfbb992 not-for-merge branch 'testcommit2615' of github.com:jantman/gitpython_issue_301 +b359040761bad8dfe3a8fb65c56929215e75e1fa not-for-merge branch 'testcommit2616' of github.com:jantman/gitpython_issue_301 +ae0a8ccc7c3c32aabf7ebc1e20d8e14009cc66b1 not-for-merge branch 'testcommit2617' of github.com:jantman/gitpython_issue_301 +28c50ab0ddbc598d909955a89e44a73b675d191a not-for-merge branch 'testcommit2618' of github.com:jantman/gitpython_issue_301 +4e2c29f54f4b2265021926db02d8adef3c998aeb not-for-merge branch 'testcommit2619' of github.com:jantman/gitpython_issue_301 +1853984c561cde1995de6a13fda117647b0df0ad not-for-merge branch 'testcommit262' of github.com:jantman/gitpython_issue_301 +054826341269f6d9acac7d6045b99ffe37d7f352 not-for-merge branch 'testcommit2620' of github.com:jantman/gitpython_issue_301 +5d9b8bca889841339b564958d3f321f7c0162ba8 not-for-merge branch 'testcommit2621' of github.com:jantman/gitpython_issue_301 +037c615dbbf2c91e46beb62807434d8c32e01085 not-for-merge branch 'testcommit2622' of github.com:jantman/gitpython_issue_301 +c9d0e2884f1f9e557906486abb03a9ec5827a60a not-for-merge branch 'testcommit2623' of github.com:jantman/gitpython_issue_301 +56cdce8414532a9b304cc115da989a1984fef217 not-for-merge branch 'testcommit2624' of github.com:jantman/gitpython_issue_301 +b2b9f37f721ac3f955fca0b8e02a18a978ec73ad not-for-merge branch 'testcommit2625' of github.com:jantman/gitpython_issue_301 +17fe9ebac333c4c0b8c5eb609d65eba6d09459fb not-for-merge branch 'testcommit2626' of github.com:jantman/gitpython_issue_301 +ed516f1be4d0315920f670363b4dc0bb686a876d not-for-merge branch 'testcommit2627' of github.com:jantman/gitpython_issue_301 +00ef43b34ff69c9372888302bf1d27fcf74f9e04 not-for-merge branch 'testcommit2628' of github.com:jantman/gitpython_issue_301 +d6a29e39a1a33ea0a9f635ec4a482f66e3422e17 not-for-merge branch 'testcommit2629' of github.com:jantman/gitpython_issue_301 +b5568616d8e8b8e5e98b58fbeffde260a0b971f0 not-for-merge branch 'testcommit263' of github.com:jantman/gitpython_issue_301 +568304a0a1afa31b1d62ceef7c78873dd0e27d65 not-for-merge branch 'testcommit2630' of github.com:jantman/gitpython_issue_301 +88b9bf3db6efa520697ce71d47b493aa6da2149e not-for-merge branch 'testcommit2631' of github.com:jantman/gitpython_issue_301 +fef9167ecc90bea079adbc2875adc2ad25c8acb4 not-for-merge branch 'testcommit2632' of github.com:jantman/gitpython_issue_301 +638062826e001daf99077de32979f5447bdbd058 not-for-merge branch 'testcommit2633' of github.com:jantman/gitpython_issue_301 +dee4e1340478abd383bc231d6142ca7608d72ee6 not-for-merge branch 'testcommit2634' of github.com:jantman/gitpython_issue_301 +de1acf1124466fefc0420169697022d98b513eee not-for-merge branch 'testcommit2635' of github.com:jantman/gitpython_issue_301 +17f41e91d74673490151cee7c2618d7a53527412 not-for-merge branch 'testcommit2636' of github.com:jantman/gitpython_issue_301 +2be39a4a4673f529f9df0bd61ee64ac0d016e1ef not-for-merge branch 'testcommit2637' of github.com:jantman/gitpython_issue_301 +15a59660970c5efab7e456ae85bbbe914621581b not-for-merge branch 'testcommit2638' of github.com:jantman/gitpython_issue_301 +24b3100e41a4aa2a84a13991a2d44c9e81656465 not-for-merge branch 'testcommit2639' of github.com:jantman/gitpython_issue_301 +87fa504cb4b61e84902a80507ae9a32668fbc508 not-for-merge branch 'testcommit264' of github.com:jantman/gitpython_issue_301 +a4d891608c6cbb5b540c8f6114c144767a580262 not-for-merge branch 'testcommit2640' of github.com:jantman/gitpython_issue_301 +8280d94ac09e0670ca42b6ebcc2ba0dc868a6ea3 not-for-merge branch 'testcommit2641' of github.com:jantman/gitpython_issue_301 +0ad0d09aa10569f3f386c8253aedde617cd38a88 not-for-merge branch 'testcommit2642' of github.com:jantman/gitpython_issue_301 +3351157e7b78404a88462a171f3f6d9e7c07f927 not-for-merge branch 'testcommit2643' of github.com:jantman/gitpython_issue_301 +79a10805c3d42c900f45d462680e5f7682802cf6 not-for-merge branch 'testcommit2644' of github.com:jantman/gitpython_issue_301 +2c82599eab154662f64759486591fdb5d165fc4e not-for-merge branch 'testcommit2645' of github.com:jantman/gitpython_issue_301 +6e664103fc185bced7e715653c218463746f7bc9 not-for-merge branch 'testcommit2646' of github.com:jantman/gitpython_issue_301 +2a4d144dcb3d6f7215b3b53fdd7c6607499e22d8 not-for-merge branch 'testcommit2647' of github.com:jantman/gitpython_issue_301 +7ed08181cf870cc1f37414083a3b94c04181db51 not-for-merge branch 'testcommit2648' of github.com:jantman/gitpython_issue_301 +23e910e2918a2dbbb8bba55803b5c323b800718e not-for-merge branch 'testcommit2649' of github.com:jantman/gitpython_issue_301 +6bc9791debf3ac39b8c2805379364740041510ec not-for-merge branch 'testcommit265' of github.com:jantman/gitpython_issue_301 +c048ab1a6a2b4d2b6e95f54d7b3a4ea3092a3ff1 not-for-merge branch 'testcommit2650' of github.com:jantman/gitpython_issue_301 +ed1a1c89a6ff45dcdf837667404d1aabcb9ce9ae not-for-merge branch 'testcommit2651' of github.com:jantman/gitpython_issue_301 +4ea1acf690fb01309e729dccf00be42203961b7e not-for-merge branch 'testcommit2652' of github.com:jantman/gitpython_issue_301 +ce5ced01e8796e263e0a7a6f3f95ddf10fdcbd2e not-for-merge branch 'testcommit2653' of github.com:jantman/gitpython_issue_301 +dca4ad36be287199fa292b43cd7256fa39bacf25 not-for-merge branch 'testcommit2654' of github.com:jantman/gitpython_issue_301 +024ee6ddf8ae0d22a29afa13c8d5d8944668fb62 not-for-merge branch 'testcommit2655' of github.com:jantman/gitpython_issue_301 +6e441f6bc1200309dcdb0f7bbe25ce61d78dffc7 not-for-merge branch 'testcommit2656' of github.com:jantman/gitpython_issue_301 +ccbbe854f51c484e36177e5c33160212eb6d95b0 not-for-merge branch 'testcommit2657' of github.com:jantman/gitpython_issue_301 +9a99077e28b8f0d0a33f5165223c992d347d4127 not-for-merge branch 'testcommit2658' of github.com:jantman/gitpython_issue_301 +1518873b7a5f4fd5c79fa47d1d7d8163292ba00d not-for-merge branch 'testcommit2659' of github.com:jantman/gitpython_issue_301 +70f6cb5d1d6ddadac08c3202a322ca934584cf12 not-for-merge branch 'testcommit266' of github.com:jantman/gitpython_issue_301 +74a61ef4d19710e7fcd3dd658cd04436c2ac54bf not-for-merge branch 'testcommit2660' of github.com:jantman/gitpython_issue_301 +3e6a49c01c5edb83fd17ee4247fab66febf1f465 not-for-merge branch 'testcommit2661' of github.com:jantman/gitpython_issue_301 +0db04deeb40ac6bb776406deef343e458c28382c not-for-merge branch 'testcommit2662' of github.com:jantman/gitpython_issue_301 +ba1a8a085e5357b8913c1ee8814ef73217bd2001 not-for-merge branch 'testcommit2663' of github.com:jantman/gitpython_issue_301 +76c72bd5f4d143a694b89c338be792508edca632 not-for-merge branch 'testcommit2664' of github.com:jantman/gitpython_issue_301 +206339f0b44eff1df783ab459c72358341051d04 not-for-merge branch 'testcommit2665' of github.com:jantman/gitpython_issue_301 +9e8915b78f3215edf061b4642baded0ee26ab6b4 not-for-merge branch 'testcommit2666' of github.com:jantman/gitpython_issue_301 +c38daa95e16a2581f499d8ef38146283c42778b1 not-for-merge branch 'testcommit2667' of github.com:jantman/gitpython_issue_301 +66262cc757d815fa93cdc4c85060c690b4aadb8d not-for-merge branch 'testcommit2668' of github.com:jantman/gitpython_issue_301 +b309f8a6a67c0732c81efe23108112b89bad438f not-for-merge branch 'testcommit2669' of github.com:jantman/gitpython_issue_301 +ef005bc403b9317cfef380ea66ee4375e17040e8 not-for-merge branch 'testcommit267' of github.com:jantman/gitpython_issue_301 +86288859c62d1573f4fcf01d1f86bec40a7027cd not-for-merge branch 'testcommit2670' of github.com:jantman/gitpython_issue_301 +129570286e1629420e82015fc327520499755b3c not-for-merge branch 'testcommit2671' of github.com:jantman/gitpython_issue_301 +93a888381f65fa720388683e78ac0d1af7d5a117 not-for-merge branch 'testcommit2672' of github.com:jantman/gitpython_issue_301 +2215fe716627591511e34372d13b4c13c675a24a not-for-merge branch 'testcommit2673' of github.com:jantman/gitpython_issue_301 +5c03fe6ca8062972977d72ab7ebbd62e544f4271 not-for-merge branch 'testcommit2674' of github.com:jantman/gitpython_issue_301 +2eee715e5b304db3dd7b49213e57f4477f340c18 not-for-merge branch 'testcommit2675' of github.com:jantman/gitpython_issue_301 +f426a68d464edbbb0fcd098e69c1c8c2a52fafef not-for-merge branch 'testcommit2676' of github.com:jantman/gitpython_issue_301 +5ff37210ae00cbfb8aeaa3384ac1fce563e11498 not-for-merge branch 'testcommit2677' of github.com:jantman/gitpython_issue_301 +6fd5b2cbeae2f59fbcaf05dc93b0448924062e9b not-for-merge branch 'testcommit2678' of github.com:jantman/gitpython_issue_301 +e348ac03144c8d6943783235734e4302ece8cc6b not-for-merge branch 'testcommit2679' of github.com:jantman/gitpython_issue_301 +300c7978ef457b7fccb43d14ab1c93a3e4ccd881 not-for-merge branch 'testcommit268' of github.com:jantman/gitpython_issue_301 +cdc29b2d2c8a4dc193bc7d9975988d8527d41cdc not-for-merge branch 'testcommit2680' of github.com:jantman/gitpython_issue_301 +be3b63eca38e70fe48f36489aab93264ceb80c1b not-for-merge branch 'testcommit2681' of github.com:jantman/gitpython_issue_301 +51c7867a1771079e47424d9cc17611bae322584c not-for-merge branch 'testcommit2682' of github.com:jantman/gitpython_issue_301 +7b12453557681ade6898dd507d4e727afa618d77 not-for-merge branch 'testcommit2683' of github.com:jantman/gitpython_issue_301 +84a48e91705171ac379aca84c346da76f326d6cf not-for-merge branch 'testcommit2684' of github.com:jantman/gitpython_issue_301 +bdcf7a3e1acd3e33f3fcc08227907f2cb7359b3f not-for-merge branch 'testcommit2685' of github.com:jantman/gitpython_issue_301 +9538298ca2365a3f9736de6a93ea6a4bdab8defe not-for-merge branch 'testcommit2686' of github.com:jantman/gitpython_issue_301 +63560c686703299cf694bc673a941730c2bf40bd not-for-merge branch 'testcommit2687' of github.com:jantman/gitpython_issue_301 +e24c4ef040ed699e342156091719feb8a33dfed0 not-for-merge branch 'testcommit2688' of github.com:jantman/gitpython_issue_301 +fa7b2a71864006f9e8c64d53759e16bbfbca88a8 not-for-merge branch 'testcommit2689' of github.com:jantman/gitpython_issue_301 +9af1fab67eaa3b9a9ea108e1d4786cff78befb8a not-for-merge branch 'testcommit269' of github.com:jantman/gitpython_issue_301 +74e96964a8e3d2f5a3f9524d1167ce487a02796b not-for-merge branch 'testcommit2690' of github.com:jantman/gitpython_issue_301 +92f47c6638ee730d064c8cb409eca606b1ca5929 not-for-merge branch 'testcommit2691' of github.com:jantman/gitpython_issue_301 +bb8afeefbbf9294955d21fd08f862141cef0b656 not-for-merge branch 'testcommit2692' of github.com:jantman/gitpython_issue_301 +c7159e9c424273b30873f629524eae5bb8ce6301 not-for-merge branch 'testcommit2693' of github.com:jantman/gitpython_issue_301 +d0fccb4e8662379c41109af466e2404e7fb39b7d not-for-merge branch 'testcommit2694' of github.com:jantman/gitpython_issue_301 +c24d1498e8077e75a26999e3af6156bdb04b724b not-for-merge branch 'testcommit2695' of github.com:jantman/gitpython_issue_301 +a75d80e85917af7b88218c368eb202ba9400d918 not-for-merge branch 'testcommit2696' of github.com:jantman/gitpython_issue_301 +abdf2a7afe654bcac049fa46a4f74eca98fade56 not-for-merge branch 'testcommit2697' of github.com:jantman/gitpython_issue_301 +bbccfc7270f0f3431a3297bc304afd8cbfcb2d97 not-for-merge branch 'testcommit2698' of github.com:jantman/gitpython_issue_301 +fb6428efd505078c6e7b926d570a80f6f3a47113 not-for-merge branch 'testcommit2699' of github.com:jantman/gitpython_issue_301 +86444c4cebc67617880a05d97e464db7ca38c546 not-for-merge branch 'testcommit27' of github.com:jantman/gitpython_issue_301 +bdc60eee03be3b64f7cacaecc4ddf610d90f9dd9 not-for-merge branch 'testcommit270' of github.com:jantman/gitpython_issue_301 +de26f83c4efd759d47a4ad1e346720886f5ddc16 not-for-merge branch 'testcommit2700' of github.com:jantman/gitpython_issue_301 +016235c16e3b2fef12b060a0bac6162230b5443b not-for-merge branch 'testcommit2701' of github.com:jantman/gitpython_issue_301 +a8bc665e709be9ded447734fbc1fcdbf58973b36 not-for-merge branch 'testcommit2702' of github.com:jantman/gitpython_issue_301 +58664702dcb2ec5b154b4bcb866df6e880300526 not-for-merge branch 'testcommit2703' of github.com:jantman/gitpython_issue_301 +a443eb109afd8f3bfe759f1df120a364768c10e5 not-for-merge branch 'testcommit2704' of github.com:jantman/gitpython_issue_301 +dd1de412d01042f2890882b232a66fcf8f90ad2f not-for-merge branch 'testcommit2705' of github.com:jantman/gitpython_issue_301 +d931a521881b9ad881f7772d1747d3a04568cb3b not-for-merge branch 'testcommit2706' of github.com:jantman/gitpython_issue_301 +86e7796fd585d1c5b147f9c67d72495c7b267ebc not-for-merge branch 'testcommit2707' of github.com:jantman/gitpython_issue_301 +db7e7eb3277462bba1a8207279b59668e05607f8 not-for-merge branch 'testcommit2708' of github.com:jantman/gitpython_issue_301 +4cb3443760ee6a81e567e1bd9a0f76f798fbbb1c not-for-merge branch 'testcommit2709' of github.com:jantman/gitpython_issue_301 +7742b508e1d883a747d9ee94105cac74ea79e4ec not-for-merge branch 'testcommit271' of github.com:jantman/gitpython_issue_301 +0de6121a63f96569022c290424382bb3e5cc2b4a not-for-merge branch 'testcommit2710' of github.com:jantman/gitpython_issue_301 +d7a9df3fef684f3ce429bdd6c995a1785dca8982 not-for-merge branch 'testcommit2711' of github.com:jantman/gitpython_issue_301 +ec57dda0858c96bdea0bab3921492cf534c1fc36 not-for-merge branch 'testcommit2712' of github.com:jantman/gitpython_issue_301 +5bacc377869bb9ef27ab75d504627bc40a8aeab6 not-for-merge branch 'testcommit2713' of github.com:jantman/gitpython_issue_301 +f5818ec3c7fe1ea6df085b70aa65e7573a2b88f4 not-for-merge branch 'testcommit2714' of github.com:jantman/gitpython_issue_301 +a478f10013a5f41e0e34407091f78cce8f1b3cc5 not-for-merge branch 'testcommit2715' of github.com:jantman/gitpython_issue_301 +07803d7fa36152de3581a51a5f83693226075561 not-for-merge branch 'testcommit2716' of github.com:jantman/gitpython_issue_301 +283f5f7f8f5665a2b7de5d1031ee79cd3d11ff4c not-for-merge branch 'testcommit2717' of github.com:jantman/gitpython_issue_301 +e8f2143a073a38d778098dd1a1daf01df9c0ead5 not-for-merge branch 'testcommit2718' of github.com:jantman/gitpython_issue_301 +0f112673877298bd3bd605114ad8c1b2cf43dc7a not-for-merge branch 'testcommit2719' of github.com:jantman/gitpython_issue_301 +035812528689be89881b8ec09e21737c7955995d not-for-merge branch 'testcommit272' of github.com:jantman/gitpython_issue_301 +e3149e6672d27980097dea1245199656b6176faa not-for-merge branch 'testcommit2720' of github.com:jantman/gitpython_issue_301 +2fb5c6d8aebe7fe6328163f40bae46a9854d85c1 not-for-merge branch 'testcommit2721' of github.com:jantman/gitpython_issue_301 +b7456b3ae93086407e552cadc415eda203c24358 not-for-merge branch 'testcommit2722' of github.com:jantman/gitpython_issue_301 +4e42c57ee519d14f7ec027dffe2be48bdbc7daac not-for-merge branch 'testcommit2723' of github.com:jantman/gitpython_issue_301 +927845166fc8e31757cfa1c9c4249ebb31a522a4 not-for-merge branch 'testcommit2724' of github.com:jantman/gitpython_issue_301 +e68a346325aa25becc92f9b9a10db604a48d8881 not-for-merge branch 'testcommit2725' of github.com:jantman/gitpython_issue_301 +609b151484bd05209fb1ef8c946b729c12d4f56c not-for-merge branch 'testcommit2726' of github.com:jantman/gitpython_issue_301 +c534af6312aed0f6d8cb5285824aa2eda4caf09a not-for-merge branch 'testcommit2727' of github.com:jantman/gitpython_issue_301 +c661785bbbc1c7eaed3d4e11a659fb8b20910423 not-for-merge branch 'testcommit2728' of github.com:jantman/gitpython_issue_301 +1e1ffafff1120407cafa9d4cdef0bd2ee0961f9a not-for-merge branch 'testcommit2729' of github.com:jantman/gitpython_issue_301 +ec5db5ba7bf31c8fed3e077fc4e4428e55bd937b not-for-merge branch 'testcommit273' of github.com:jantman/gitpython_issue_301 +a516a24619e590a89e54a0866050d1443490b447 not-for-merge branch 'testcommit2730' of github.com:jantman/gitpython_issue_301 +6219988603450d46d50fd59a6ed21500212f312d not-for-merge branch 'testcommit2731' of github.com:jantman/gitpython_issue_301 +89a06adc73c37228f217c238e70898df46ce27b9 not-for-merge branch 'testcommit2732' of github.com:jantman/gitpython_issue_301 +155e19bdecedc58f2ca66ac38a8631b225a1e68d not-for-merge branch 'testcommit2733' of github.com:jantman/gitpython_issue_301 +3a8b1a870e538c0317f03df5ed818f79b47a262f not-for-merge branch 'testcommit2734' of github.com:jantman/gitpython_issue_301 +c0dab4e6717c07af103823d7646b0e1f3b263ec5 not-for-merge branch 'testcommit2735' of github.com:jantman/gitpython_issue_301 +b0f635202391d9fec2ad7136e7d098329c67c68d not-for-merge branch 'testcommit2736' of github.com:jantman/gitpython_issue_301 +1373da2e4254b55791746c2159c5e6da5753a793 not-for-merge branch 'testcommit2737' of github.com:jantman/gitpython_issue_301 +909d20a90a555d603e4f1cfb752adc47a6278cf7 not-for-merge branch 'testcommit2738' of github.com:jantman/gitpython_issue_301 +4d49e4a988b4aef58e6d3a822829ed1083866941 not-for-merge branch 'testcommit2739' of github.com:jantman/gitpython_issue_301 +8b8788798939ef345f6ad148732befd1de9ab2d2 not-for-merge branch 'testcommit274' of github.com:jantman/gitpython_issue_301 +a547eb02b189c22c391b88a640e91fda0a2087bb not-for-merge branch 'testcommit2740' of github.com:jantman/gitpython_issue_301 +ac280a16a4670388dd00014cfdabcf54e6fabaf3 not-for-merge branch 'testcommit2741' of github.com:jantman/gitpython_issue_301 +27992a11520a0fdef876683a22092b32d4251421 not-for-merge branch 'testcommit2742' of github.com:jantman/gitpython_issue_301 +6cefc7759c71a19a82d39b9cf472ce96a7481c3a not-for-merge branch 'testcommit2743' of github.com:jantman/gitpython_issue_301 +b7f30ab3c5d43499d50b2ee584ddec438cdf09c0 not-for-merge branch 'testcommit2744' of github.com:jantman/gitpython_issue_301 +023f9a33118b8a0a8f463519aa206641f0ad2ec1 not-for-merge branch 'testcommit2745' of github.com:jantman/gitpython_issue_301 +2db9231127b08684799009d64d329e675f599e66 not-for-merge branch 'testcommit2746' of github.com:jantman/gitpython_issue_301 +3dd1ecc41233793f087029fc3357d461b86e7ceb not-for-merge branch 'testcommit2747' of github.com:jantman/gitpython_issue_301 +873dd50bab8c3f3cba8e84b8110544f01c7d6902 not-for-merge branch 'testcommit2748' of github.com:jantman/gitpython_issue_301 +956d1e251cec402289af0bf7e180741298c923ab not-for-merge branch 'testcommit2749' of github.com:jantman/gitpython_issue_301 +477d03bc58fa8c59b03462f44fc10fd987a74054 not-for-merge branch 'testcommit275' of github.com:jantman/gitpython_issue_301 +f2b70c7e86776cfa22a58b244273504a11efd5b0 not-for-merge branch 'testcommit2750' of github.com:jantman/gitpython_issue_301 +925b538be48bd1edaa56bcf19f05956f0f6316ea not-for-merge branch 'testcommit2751' of github.com:jantman/gitpython_issue_301 +f412bad2aaee04a094c36b85ebeb7b5ab3eb991d not-for-merge branch 'testcommit2752' of github.com:jantman/gitpython_issue_301 +c7587fcc8f1eb94cab32acd40de77547369d704b not-for-merge branch 'testcommit2753' of github.com:jantman/gitpython_issue_301 +c89b3d790ce8c437607087567662fa763fcc311c not-for-merge branch 'testcommit2754' of github.com:jantman/gitpython_issue_301 +c83ae4b35822e78fe1be4631cee0608b664a292f not-for-merge branch 'testcommit2755' of github.com:jantman/gitpython_issue_301 +f00e1c7858ec32818e89f2d38657bf6c0a516eb7 not-for-merge branch 'testcommit2756' of github.com:jantman/gitpython_issue_301 +087ed30400590e1daad14505a1404c96de62f961 not-for-merge branch 'testcommit2757' of github.com:jantman/gitpython_issue_301 +06cb5d1b0ae16206b1003ded7db4e72e2fed95b2 not-for-merge branch 'testcommit2758' of github.com:jantman/gitpython_issue_301 +66a79aa83488a1cd179bdc2e0fc5371074e6a0fe not-for-merge branch 'testcommit2759' of github.com:jantman/gitpython_issue_301 +8df0be89ec1439e3a516d2ca645d33e97caa2689 not-for-merge branch 'testcommit276' of github.com:jantman/gitpython_issue_301 +5b90ea29f31d9bc5b270e05058bdbaa5b6ba9150 not-for-merge branch 'testcommit2760' of github.com:jantman/gitpython_issue_301 +ad9984635ee7e17c1b1c4d9de3e7e367a8a3e861 not-for-merge branch 'testcommit2761' of github.com:jantman/gitpython_issue_301 +f010a2da6865e00079778b3cfe805e46ba60861b not-for-merge branch 'testcommit2762' of github.com:jantman/gitpython_issue_301 +421b6b8dbfb7839eecae249860138ab71c95a850 not-for-merge branch 'testcommit2763' of github.com:jantman/gitpython_issue_301 +6cf0b6323bc07b85884a65d1d57ca05d3d9ba9e2 not-for-merge branch 'testcommit2764' of github.com:jantman/gitpython_issue_301 +583dbe12667f76f42af7bea0b5b20d3111a9f954 not-for-merge branch 'testcommit2765' of github.com:jantman/gitpython_issue_301 +5400094de2a040f58add91b4a95f35130d411dfe not-for-merge branch 'testcommit2766' of github.com:jantman/gitpython_issue_301 +10881284f090720529dedff6fffb2734c54b4c90 not-for-merge branch 'testcommit2767' of github.com:jantman/gitpython_issue_301 +0964c71aaaf0a65258d0f3933fbe570e6b4fb7de not-for-merge branch 'testcommit2768' of github.com:jantman/gitpython_issue_301 +a6889b94b9e1119824ac1956907487a5136ea430 not-for-merge branch 'testcommit2769' of github.com:jantman/gitpython_issue_301 +0e258afeb12f7fa6b5cd57cd94e27bdc1b51845d not-for-merge branch 'testcommit277' of github.com:jantman/gitpython_issue_301 +897d82cfccd7da726b95dffc511fc0d2a77248d6 not-for-merge branch 'testcommit2770' of github.com:jantman/gitpython_issue_301 +204658991b5b32471a98c984150160f0180b66d0 not-for-merge branch 'testcommit2771' of github.com:jantman/gitpython_issue_301 +e65bf4f95303bf1f47b0e62a8fca0d0fcda832b0 not-for-merge branch 'testcommit2772' of github.com:jantman/gitpython_issue_301 +1b9d8323fe0358b796fa1f3561617123111672ff not-for-merge branch 'testcommit2773' of github.com:jantman/gitpython_issue_301 +e50473a5f64b865ab34a693bb5e257bd1592d26a not-for-merge branch 'testcommit2774' of github.com:jantman/gitpython_issue_301 +e2579b9a36080c8e292f1034ec74b6aec5e46aa5 not-for-merge branch 'testcommit2775' of github.com:jantman/gitpython_issue_301 +16fe622481f729172e1cb7704e561727e480654c not-for-merge branch 'testcommit2776' of github.com:jantman/gitpython_issue_301 +9c280129dbbf0b7e5f4019caa555d6cf3a4007ef not-for-merge branch 'testcommit2777' of github.com:jantman/gitpython_issue_301 +1795991e54abd633ca64594400f330eea2e2a27c not-for-merge branch 'testcommit2778' of github.com:jantman/gitpython_issue_301 +72a215758e23ab980c89b97011cc5b5e6b10a19c not-for-merge branch 'testcommit2779' of github.com:jantman/gitpython_issue_301 +67fd7727b4369f200f2eeeb50450c11221582537 not-for-merge branch 'testcommit278' of github.com:jantman/gitpython_issue_301 +02716c9cfec93f1f08a4c0bfeaf1aff58083212b not-for-merge branch 'testcommit2780' of github.com:jantman/gitpython_issue_301 +70676f8847aeb07923edfb21b2dfb5eade2e2b6f not-for-merge branch 'testcommit2781' of github.com:jantman/gitpython_issue_301 +803364d253a90b4a8170fce874608e82e8385910 not-for-merge branch 'testcommit2782' of github.com:jantman/gitpython_issue_301 +b1ca2933b2138feb9b61d5d75b339831570b30f2 not-for-merge branch 'testcommit2783' of github.com:jantman/gitpython_issue_301 +af05f0faa36baaac6dd47b3072c58400cde5f224 not-for-merge branch 'testcommit2784' of github.com:jantman/gitpython_issue_301 +ac0a7f21f0b23fef9660e75aa999b82637e18b84 not-for-merge branch 'testcommit2785' of github.com:jantman/gitpython_issue_301 +02393139cb60d1704928338e3100e8c13d2328a4 not-for-merge branch 'testcommit2786' of github.com:jantman/gitpython_issue_301 +7316fd058fe6eb44fc327d3789d7099424bf25dd not-for-merge branch 'testcommit2787' of github.com:jantman/gitpython_issue_301 +469632325ebf3d08d7446a0e66883f84988686c8 not-for-merge branch 'testcommit2788' of github.com:jantman/gitpython_issue_301 +9fa2adc9160008673283c5434cc1d741de1e94e2 not-for-merge branch 'testcommit2789' of github.com:jantman/gitpython_issue_301 +cc60365a311424117593f615fd3aeb22d8205c5c not-for-merge branch 'testcommit279' of github.com:jantman/gitpython_issue_301 +214513b925a30204902d04169b821fe9a180534e not-for-merge branch 'testcommit2790' of github.com:jantman/gitpython_issue_301 +c8db2a432d55148404dad501de4748d0dce02959 not-for-merge branch 'testcommit2791' of github.com:jantman/gitpython_issue_301 +d0bd4211a76785bee781b9dd01529fac1f6301cb not-for-merge branch 'testcommit2792' of github.com:jantman/gitpython_issue_301 +54fdf6337efc7fd52c991691950f6e031afdb6c7 not-for-merge branch 'testcommit2793' of github.com:jantman/gitpython_issue_301 +9165edda237827b716ad1ecf6d346939b1104d80 not-for-merge branch 'testcommit2794' of github.com:jantman/gitpython_issue_301 +757377d84877e476f0637ab7a08f3862923d335a not-for-merge branch 'testcommit2795' of github.com:jantman/gitpython_issue_301 +0da9eb322ffefb66e35eb0af4dddaa7d43133666 not-for-merge branch 'testcommit2796' of github.com:jantman/gitpython_issue_301 +0581b81f81a4b9f6c7eee9011b7841d666131b27 not-for-merge branch 'testcommit2797' of github.com:jantman/gitpython_issue_301 +4c77cd3af6303d4e2d0ec6fc18958cbbd40beb2f not-for-merge branch 'testcommit2798' of github.com:jantman/gitpython_issue_301 +ff8de229133309d6afafc3d06bfa1ab2d2568168 not-for-merge branch 'testcommit2799' of github.com:jantman/gitpython_issue_301 +ac487289a5508d904dda5de4b2340469e866627c not-for-merge branch 'testcommit28' of github.com:jantman/gitpython_issue_301 +5bbe390a67502cc508b405490ca3007c8a3bab96 not-for-merge branch 'testcommit280' of github.com:jantman/gitpython_issue_301 +fd8e9a39a438f7a06475fe4adc801781db0b20d5 not-for-merge branch 'testcommit2800' of github.com:jantman/gitpython_issue_301 +a1c2e86465d6faac7b9544c588ff8f8f6f081758 not-for-merge branch 'testcommit2801' of github.com:jantman/gitpython_issue_301 +a38f94d87d261dfe6ec5411a3cc25e99e144a147 not-for-merge branch 'testcommit2802' of github.com:jantman/gitpython_issue_301 +2659c6ae1147254044797821d4a53e8d5b869a01 not-for-merge branch 'testcommit2803' of github.com:jantman/gitpython_issue_301 +bed4d7147ffaf84aeb0e302b0f2319756838f5fd not-for-merge branch 'testcommit2804' of github.com:jantman/gitpython_issue_301 +084c13f0d1a6d1d5dfdb7bb51807b6fe030772ca not-for-merge branch 'testcommit2805' of github.com:jantman/gitpython_issue_301 +c552623708d02901c5179e0a175c5f7be1586ed7 not-for-merge branch 'testcommit2806' of github.com:jantman/gitpython_issue_301 +9f738d021a38717a4d5e4ca979231fcea5c04c0d not-for-merge branch 'testcommit2807' of github.com:jantman/gitpython_issue_301 +47dd034e5ce727d7a167e405b52f1bb8212a693f not-for-merge branch 'testcommit2808' of github.com:jantman/gitpython_issue_301 +57f633c9b4ad4aeb0dbb54a18ec664499359af88 not-for-merge branch 'testcommit2809' of github.com:jantman/gitpython_issue_301 +ceea04a47f441c8c6d5d8e7f7cee1c8e082994cf not-for-merge branch 'testcommit281' of github.com:jantman/gitpython_issue_301 +dfcd67c70f5aee8ba896a49ee834974b4374e07e not-for-merge branch 'testcommit2810' of github.com:jantman/gitpython_issue_301 +f8a27a4b63fc44101789f6191c38d71f3a9a8402 not-for-merge branch 'testcommit2811' of github.com:jantman/gitpython_issue_301 +a947df6f494ac57c03410ac4f227a947a918951c not-for-merge branch 'testcommit2812' of github.com:jantman/gitpython_issue_301 +98c97d1cdb1e759be79579e48c2a277f37dad5a2 not-for-merge branch 'testcommit2813' of github.com:jantman/gitpython_issue_301 +88e7b9ca6b698d8ee3473bd4990349cdae5a0028 not-for-merge branch 'testcommit2814' of github.com:jantman/gitpython_issue_301 +3a3f5ed3cd30319ce9bb067674c40bd713e6280f not-for-merge branch 'testcommit2815' of github.com:jantman/gitpython_issue_301 +f27cd7d4386f4b75df4972b86ce81e767a4061a6 not-for-merge branch 'testcommit2816' of github.com:jantman/gitpython_issue_301 +9b4d0352f135fdceda3ff49dfcdd82795c0eb6e6 not-for-merge branch 'testcommit2817' of github.com:jantman/gitpython_issue_301 +e168108728ca92d06e4d05b56e371ee4f5683463 not-for-merge branch 'testcommit2818' of github.com:jantman/gitpython_issue_301 +ea4903e182d7915f8ed7276169608de7810b0c50 not-for-merge branch 'testcommit2819' of github.com:jantman/gitpython_issue_301 +dafa72ad2f875a258f7af83c42f8140bad0f7d74 not-for-merge branch 'testcommit282' of github.com:jantman/gitpython_issue_301 +3bb0edf31d30a47aa8eed04a86ca7b3cb7cc41ee not-for-merge branch 'testcommit2820' of github.com:jantman/gitpython_issue_301 +fda67e2fe38848b5de5c8d455ffea646a3d2a39a not-for-merge branch 'testcommit2821' of github.com:jantman/gitpython_issue_301 +628d25311a7bd83f152b59899a07f73ad7dca2c3 not-for-merge branch 'testcommit2822' of github.com:jantman/gitpython_issue_301 +68983f508954e0239e8b2f90ae5709bdb9d188fb not-for-merge branch 'testcommit2823' of github.com:jantman/gitpython_issue_301 +3a2a9c0bae785899637ff4f348e45e13b658e1a5 not-for-merge branch 'testcommit2824' of github.com:jantman/gitpython_issue_301 +269723ed7f27d60891f63ec518597577022ae377 not-for-merge branch 'testcommit2825' of github.com:jantman/gitpython_issue_301 +c298f7918dbab068e7cbd3b1330e1134c02306da not-for-merge branch 'testcommit2826' of github.com:jantman/gitpython_issue_301 +b3c60a0f0132b77ba51f637e6abe199a702d0447 not-for-merge branch 'testcommit2827' of github.com:jantman/gitpython_issue_301 +ca3963f474bcd248106d47c7d3b78233466c85a9 not-for-merge branch 'testcommit2828' of github.com:jantman/gitpython_issue_301 +ad6f8527271c6e96f48e28a9009adced69c01a4b not-for-merge branch 'testcommit2829' of github.com:jantman/gitpython_issue_301 +622b626d0714a2a94d8e2e119bcc052976887e8b not-for-merge branch 'testcommit283' of github.com:jantman/gitpython_issue_301 +8a12df8988d15378c586cc4577af90bebcefd06f not-for-merge branch 'testcommit2830' of github.com:jantman/gitpython_issue_301 +3ede9bb472dd3732b0ed3b081782986da0130964 not-for-merge branch 'testcommit2831' of github.com:jantman/gitpython_issue_301 +33672258d1dd731513d08cccc0e0ee7cf19f2346 not-for-merge branch 'testcommit2832' of github.com:jantman/gitpython_issue_301 +482f30671610f776f2180f59583ae638abf6f401 not-for-merge branch 'testcommit2833' of github.com:jantman/gitpython_issue_301 +40f02ac1c274ca7976338a935baee735cdf29620 not-for-merge branch 'testcommit2834' of github.com:jantman/gitpython_issue_301 +ae7f18a9fb2d2b0f6f882c890838ca8f30fb61ad not-for-merge branch 'testcommit2835' of github.com:jantman/gitpython_issue_301 +27d41a004c6c9498a8968055c63e1d5bdf2de2b5 not-for-merge branch 'testcommit2836' of github.com:jantman/gitpython_issue_301 +68b6410688f18411c29a4098dddd4eed6c738ddd not-for-merge branch 'testcommit2837' of github.com:jantman/gitpython_issue_301 +7f410b0f4b96c8a01f2ca8cf08ba18333d53a9ba not-for-merge branch 'testcommit2838' of github.com:jantman/gitpython_issue_301 +917d3e52e9989da8f8744355497df273add0895b not-for-merge branch 'testcommit2839' of github.com:jantman/gitpython_issue_301 +b484f30f09c92a1e320a008c535206724baaed48 not-for-merge branch 'testcommit284' of github.com:jantman/gitpython_issue_301 +6e06949a3d9a9aab247abb210dc307a8d2d6f40a not-for-merge branch 'testcommit2840' of github.com:jantman/gitpython_issue_301 +ab0b8f65183595171e23b3e38a0d8e67584938f3 not-for-merge branch 'testcommit2841' of github.com:jantman/gitpython_issue_301 +37af590319369a8bd9f95d1401fa0ee7fcdab202 not-for-merge branch 'testcommit2842' of github.com:jantman/gitpython_issue_301 +b74bd0f49f33e968f04070b3f61c6548c783f923 not-for-merge branch 'testcommit2843' of github.com:jantman/gitpython_issue_301 +e0a2e0b9767393cd14225d5bfa15eaac2273a032 not-for-merge branch 'testcommit2844' of github.com:jantman/gitpython_issue_301 +bed0c832d9bb1844e120054954f58735d3c50276 not-for-merge branch 'testcommit2845' of github.com:jantman/gitpython_issue_301 +e15b6ee7c80701a89a9cb8fc185c54c974f4505a not-for-merge branch 'testcommit2846' of github.com:jantman/gitpython_issue_301 +32828f07ce2dbea52d79829e055084a9b9611168 not-for-merge branch 'testcommit2847' of github.com:jantman/gitpython_issue_301 +3a995e58c1912783f9aaece7239d62e32c0f1c19 not-for-merge branch 'testcommit2848' of github.com:jantman/gitpython_issue_301 +a345b752f0cc947574402db6dc3e8884f605a210 not-for-merge branch 'testcommit2849' of github.com:jantman/gitpython_issue_301 +3c103af086db7fb74afaec94552fabbf21804524 not-for-merge branch 'testcommit285' of github.com:jantman/gitpython_issue_301 +7d0b1886f53e9d24b21bee6c8a38503f2a2d3ea9 not-for-merge branch 'testcommit2850' of github.com:jantman/gitpython_issue_301 +6ad5c1e2adae6f4a3890820f5b2ad3888b3e058e not-for-merge branch 'testcommit2851' of github.com:jantman/gitpython_issue_301 +900146a079d65fde506e5e3b7a66263098122f93 not-for-merge branch 'testcommit2852' of github.com:jantman/gitpython_issue_301 +ef629c25fd85612ea2c76f753aeb86a79b333a88 not-for-merge branch 'testcommit2853' of github.com:jantman/gitpython_issue_301 +0df22f4a33372214ef7963be483e85584bcc6ded not-for-merge branch 'testcommit2854' of github.com:jantman/gitpython_issue_301 +4db5d31321e5ba6d2dfb86908315f99c345c00cb not-for-merge branch 'testcommit2855' of github.com:jantman/gitpython_issue_301 +343cfe3f3882a7549e9899e0ec454feec29a9d4e not-for-merge branch 'testcommit2856' of github.com:jantman/gitpython_issue_301 +2e944c2af6041eb9e9b33a2d0969a32db95a334e not-for-merge branch 'testcommit2857' of github.com:jantman/gitpython_issue_301 +60a1ec72b04d0b60043af211d93c91ed48d09b8d not-for-merge branch 'testcommit2858' of github.com:jantman/gitpython_issue_301 +7304503cef189fecffbb02dde90338d5f6ad93da not-for-merge branch 'testcommit2859' of github.com:jantman/gitpython_issue_301 +c9384375bb2d2871f74744c4977163816b6450d5 not-for-merge branch 'testcommit286' of github.com:jantman/gitpython_issue_301 +3fa7ef58ead134e17834c7f1b3562f2a0a0fe878 not-for-merge branch 'testcommit2860' of github.com:jantman/gitpython_issue_301 +b30345cb9027b2c40f4e65d3ca47a16293800947 not-for-merge branch 'testcommit2861' of github.com:jantman/gitpython_issue_301 +6011bae92ec840e6ab5a29f1d8c48552d9ce2d6e not-for-merge branch 'testcommit2862' of github.com:jantman/gitpython_issue_301 +15b34d89d00c600df73691eee3b8d4cd816bd12b not-for-merge branch 'testcommit2863' of github.com:jantman/gitpython_issue_301 +674034cf8ab7faeca34f80b1fec36ef720792f97 not-for-merge branch 'testcommit2864' of github.com:jantman/gitpython_issue_301 +8d42442fd5c9d642cebcd998d0807c6382478c81 not-for-merge branch 'testcommit2865' of github.com:jantman/gitpython_issue_301 +9a0c0d5a4eea720cd5b61ad7462ed8b0d83eb1b2 not-for-merge branch 'testcommit2866' of github.com:jantman/gitpython_issue_301 +4a533b4cf48340c5c710c71cdda1e93dc2a8c10f not-for-merge branch 'testcommit2867' of github.com:jantman/gitpython_issue_301 +09cb947106e850ad6c3b7eb031748cc189f17ce3 not-for-merge branch 'testcommit2868' of github.com:jantman/gitpython_issue_301 +b15752e5e49ff9d89ad656b4da5dd41ea3af00a9 not-for-merge branch 'testcommit2869' of github.com:jantman/gitpython_issue_301 +3747ad166e7dac24d174af1de9118a98d17601f3 not-for-merge branch 'testcommit287' of github.com:jantman/gitpython_issue_301 +ed29d7f32123a398242d38c1eed148e66db431c8 not-for-merge branch 'testcommit2870' of github.com:jantman/gitpython_issue_301 +87b084adfb447371deab02c91edebdf79054874e not-for-merge branch 'testcommit2871' of github.com:jantman/gitpython_issue_301 +7f05fa54821e0a57da951400df41125d448ff037 not-for-merge branch 'testcommit2872' of github.com:jantman/gitpython_issue_301 +466af9206d347fe2dfc5a1fa9105a52a07987a5a not-for-merge branch 'testcommit2873' of github.com:jantman/gitpython_issue_301 +4692bb889b2ba3cda3ad679e579ca2cb75a735da not-for-merge branch 'testcommit2874' of github.com:jantman/gitpython_issue_301 +5331c826921a162831b5d9ca31cdbeb9f39dba8a not-for-merge branch 'testcommit2875' of github.com:jantman/gitpython_issue_301 +0c8a45501a40a4c8093f8eaeb99d94ce86148f3e not-for-merge branch 'testcommit2876' of github.com:jantman/gitpython_issue_301 +297971f48158e36843075e079316e5ed09d9a7a6 not-for-merge branch 'testcommit2877' of github.com:jantman/gitpython_issue_301 +aaa6ce4320523cbc43a956223c3a155433e4b4fa not-for-merge branch 'testcommit2878' of github.com:jantman/gitpython_issue_301 +6bba2b29b8e68d3000d92629cd9d9b96269c8dde not-for-merge branch 'testcommit2879' of github.com:jantman/gitpython_issue_301 +ca6a252bfed0319fe92e8e975a0223b1dd5bcf99 not-for-merge branch 'testcommit288' of github.com:jantman/gitpython_issue_301 +02c8ea7be9206ae07da5456114c947275b6660c4 not-for-merge branch 'testcommit2880' of github.com:jantman/gitpython_issue_301 +0ba86126d3c78f7d0fb60bdf848a3bf9cada6120 not-for-merge branch 'testcommit2881' of github.com:jantman/gitpython_issue_301 +48c11f09d3fd249e73b08865137ed7324fec8466 not-for-merge branch 'testcommit2882' of github.com:jantman/gitpython_issue_301 +18568b8bd04369d9521ca53a0383a9012362b5d1 not-for-merge branch 'testcommit2883' of github.com:jantman/gitpython_issue_301 +e041337dd1dd87005a0d37ab1b1872daece98a62 not-for-merge branch 'testcommit2884' of github.com:jantman/gitpython_issue_301 +83b39cbd328f77066289c0c36d89853f49e8425d not-for-merge branch 'testcommit2885' of github.com:jantman/gitpython_issue_301 +7e90eb75ac079c885c0abac5c7d75fcc47cff6d3 not-for-merge branch 'testcommit2886' of github.com:jantman/gitpython_issue_301 +a1a7ecd2be754616ef84d593302f0fd09ee55b69 not-for-merge branch 'testcommit2887' of github.com:jantman/gitpython_issue_301 +5abdcbef7aeb73a88ad11b599f3008634246d556 not-for-merge branch 'testcommit2888' of github.com:jantman/gitpython_issue_301 +0bbae08c46ee0f15d1155306f6cfd61b2174f171 not-for-merge branch 'testcommit2889' of github.com:jantman/gitpython_issue_301 +21ef1f0cb44604673582d5e0663a988ee7468a00 not-for-merge branch 'testcommit289' of github.com:jantman/gitpython_issue_301 +f15cc9c806b362a2c21bb837007fd94be1e3584c not-for-merge branch 'testcommit2890' of github.com:jantman/gitpython_issue_301 +d3cdeec77dbd1eb4d0a5b1373e98b7419a1e8259 not-for-merge branch 'testcommit2891' of github.com:jantman/gitpython_issue_301 +4e02181459903e9e6d8e22eb51b80df1fc2ae783 not-for-merge branch 'testcommit2892' of github.com:jantman/gitpython_issue_301 +e13f8ae70937c4da439fe77835de7aa944aed172 not-for-merge branch 'testcommit2893' of github.com:jantman/gitpython_issue_301 +cb0681da02959190104499bba48da7f11ec5b38a not-for-merge branch 'testcommit2894' of github.com:jantman/gitpython_issue_301 +b4bbebaf8af5dfc9871e205bcdbe73a6f0253319 not-for-merge branch 'testcommit2895' of github.com:jantman/gitpython_issue_301 +afa1646cdef2004aa8d555ddba9020c67d5c3628 not-for-merge branch 'testcommit2896' of github.com:jantman/gitpython_issue_301 +ce0a95687ad9bb048a4e235ffa87325341fd9576 not-for-merge branch 'testcommit2897' of github.com:jantman/gitpython_issue_301 +c0703465282cecf9c7c9ec88de9897a46096c783 not-for-merge branch 'testcommit2898' of github.com:jantman/gitpython_issue_301 +62934bbbe1a7df6965e7d788a0cc302b386338f0 not-for-merge branch 'testcommit2899' of github.com:jantman/gitpython_issue_301 +ccc0c35ea5f4542d987bcb6674851c7d5e65f305 not-for-merge branch 'testcommit29' of github.com:jantman/gitpython_issue_301 +1382bfdc94bc2f4997bd3a6b7b88ec7d27f8687f not-for-merge branch 'testcommit290' of github.com:jantman/gitpython_issue_301 +c08dc997a702a5422d3e7cd9f908c65a6cfda2ed not-for-merge branch 'testcommit2900' of github.com:jantman/gitpython_issue_301 +0ff54628f7d5edf593b2e953d50122ce1ed9308c not-for-merge branch 'testcommit2901' of github.com:jantman/gitpython_issue_301 +520d3e5f6e2591939eac5ee49f3ee73325eb52e6 not-for-merge branch 'testcommit2902' of github.com:jantman/gitpython_issue_301 +8d78f0bd1b133424c0fdbe70b6f858cc652f3436 not-for-merge branch 'testcommit2903' of github.com:jantman/gitpython_issue_301 +0715c2ed051b27907a9f6a46717ad69740d7b1b4 not-for-merge branch 'testcommit2904' of github.com:jantman/gitpython_issue_301 +580733c810691a4ed33bd32cca33c37c055e2397 not-for-merge branch 'testcommit2905' of github.com:jantman/gitpython_issue_301 +daa1c9acce05bfdda83ac18f921f105fd351df09 not-for-merge branch 'testcommit2906' of github.com:jantman/gitpython_issue_301 +2d4e6d0eea0bd497d83ab9e097c998445490d5f5 not-for-merge branch 'testcommit2907' of github.com:jantman/gitpython_issue_301 +3c6291c874d509f7cd43f60282f86a8914237acb not-for-merge branch 'testcommit2908' of github.com:jantman/gitpython_issue_301 +fc26c1bca0bc8c19289e3271ad39b73357396132 not-for-merge branch 'testcommit2909' of github.com:jantman/gitpython_issue_301 +d835f7de8ff055a9728eea14f9c375b44a86dbaf not-for-merge branch 'testcommit291' of github.com:jantman/gitpython_issue_301 +77c48739fb3b67370f9aec52d59eb29a72d1d3b3 not-for-merge branch 'testcommit2910' of github.com:jantman/gitpython_issue_301 +a0055e5cb2462980dd510811c7776a4a292ef02d not-for-merge branch 'testcommit2911' of github.com:jantman/gitpython_issue_301 +8673a8e73c3e566b8f3151e68e268d9f94ba6d3d not-for-merge branch 'testcommit2912' of github.com:jantman/gitpython_issue_301 +1ed8f63a00d8fc2444d403e58fff649b78b96ce5 not-for-merge branch 'testcommit2913' of github.com:jantman/gitpython_issue_301 +b81c15f3b300abe7ca6405ed322a7f01b462b2b4 not-for-merge branch 'testcommit2914' of github.com:jantman/gitpython_issue_301 +f5cf70a1d7a7992167a14d5014c1bd92878704cc not-for-merge branch 'testcommit2915' of github.com:jantman/gitpython_issue_301 +fc45bb13086a345f707f9eb30b5cd6ae8f90f7e4 not-for-merge branch 'testcommit2916' of github.com:jantman/gitpython_issue_301 +ea2f299ad6c61dfcaa833275bcfd002364981d1d not-for-merge branch 'testcommit2917' of github.com:jantman/gitpython_issue_301 +ac1b8138ecc96ae5019e7a6c3fd1b7aa974d9f9d not-for-merge branch 'testcommit2918' of github.com:jantman/gitpython_issue_301 +65dc2912a9285c0d91dc465ff71181639816204d not-for-merge branch 'testcommit2919' of github.com:jantman/gitpython_issue_301 +6cc730bcd56a4e847085e8cd83f3ff639836aadd not-for-merge branch 'testcommit292' of github.com:jantman/gitpython_issue_301 +3e07cfea837a25e73901febc2ed9841a32969a39 not-for-merge branch 'testcommit2920' of github.com:jantman/gitpython_issue_301 +9326f9b6dfce0f159893d3779b6c0c704f9dd4bb not-for-merge branch 'testcommit2921' of github.com:jantman/gitpython_issue_301 +d36bf8189245a5feb948550df1d8598202620209 not-for-merge branch 'testcommit2922' of github.com:jantman/gitpython_issue_301 +d86d7c1b97684340363882706a1fd08bd6fbeca5 not-for-merge branch 'testcommit2923' of github.com:jantman/gitpython_issue_301 +7b47063e07380a5834ead0970c5ffca5f6156613 not-for-merge branch 'testcommit2924' of github.com:jantman/gitpython_issue_301 +67a6f03902b9b936143a0255244b6f72ea966c29 not-for-merge branch 'testcommit2925' of github.com:jantman/gitpython_issue_301 +667c739b09f3ff099462bbad74c1bc9d20686be1 not-for-merge branch 'testcommit2926' of github.com:jantman/gitpython_issue_301 +15c18b4e7d91fbb22a52e0166b6bbbd8fe253dc2 not-for-merge branch 'testcommit2927' of github.com:jantman/gitpython_issue_301 +32ded4ff465798576b5d1f5bc8b1a55b7fd36a60 not-for-merge branch 'testcommit2928' of github.com:jantman/gitpython_issue_301 +89feb483c3a9c5fc485c00bdcdf006d5c4bb2675 not-for-merge branch 'testcommit2929' of github.com:jantman/gitpython_issue_301 +f814acd6f91c60bd72e481f8f501533a1c4cbbf3 not-for-merge branch 'testcommit293' of github.com:jantman/gitpython_issue_301 +aa201cb305498658bea583a4136ab402cbae788e not-for-merge branch 'testcommit2930' of github.com:jantman/gitpython_issue_301 +955a556baa34a4a29169c594d044726f5d4621f3 not-for-merge branch 'testcommit2931' of github.com:jantman/gitpython_issue_301 +839b7ef257046f3cf6c450e116b37f57e9b8aa2b not-for-merge branch 'testcommit2932' of github.com:jantman/gitpython_issue_301 +1cf7e05544e7ba2d4c2e1634bf2fa1c75bcedd08 not-for-merge branch 'testcommit2933' of github.com:jantman/gitpython_issue_301 +08300d00c28fed43aa12a143c682388fe98e1005 not-for-merge branch 'testcommit2934' of github.com:jantman/gitpython_issue_301 +69073155283d786f3b3bc04c6387bbaf09be8998 not-for-merge branch 'testcommit2935' of github.com:jantman/gitpython_issue_301 +d124d0be158563f7af88ce853df0d8536a8e3fda not-for-merge branch 'testcommit2936' of github.com:jantman/gitpython_issue_301 +3dfe5dae560fe84429b016e9dd8caf92161d09d9 not-for-merge branch 'testcommit2937' of github.com:jantman/gitpython_issue_301 +c454cfef0849c05665e2a563acc661717a4f512f not-for-merge branch 'testcommit2938' of github.com:jantman/gitpython_issue_301 +088064dfd953e953a52825743bf28614bc9d99f4 not-for-merge branch 'testcommit2939' of github.com:jantman/gitpython_issue_301 +90d5b105d0627e338bbab6928f6c9239ebdd6b85 not-for-merge branch 'testcommit294' of github.com:jantman/gitpython_issue_301 +336e66de13b7885006e5b1f9ad7defeaf894c425 not-for-merge branch 'testcommit2940' of github.com:jantman/gitpython_issue_301 +2b14903dc1b925e2daa419d1dbbca7e9da4adc01 not-for-merge branch 'testcommit2941' of github.com:jantman/gitpython_issue_301 +ac30937dfa64b4cb66170031e82a5d3ee4f4c56a not-for-merge branch 'testcommit2942' of github.com:jantman/gitpython_issue_301 +65ba353eb4b2c7d7de1eafaf9bc49903b4b4ddb2 not-for-merge branch 'testcommit2943' of github.com:jantman/gitpython_issue_301 +9d575797fb4fe7688bfa5e6f29697a1f71db63f3 not-for-merge branch 'testcommit2944' of github.com:jantman/gitpython_issue_301 +74115216c6a03e51300579237ace8918dc490861 not-for-merge branch 'testcommit2945' of github.com:jantman/gitpython_issue_301 +4ed279f01c6e13c9937cded9bc45712bd36240a3 not-for-merge branch 'testcommit2946' of github.com:jantman/gitpython_issue_301 +c6ae9e758a63143e556ef99c3bb5be4afb532eea not-for-merge branch 'testcommit2947' of github.com:jantman/gitpython_issue_301 +5bc54714ac5d5da2982589c0facf9e4d7ce8c7ce not-for-merge branch 'testcommit2948' of github.com:jantman/gitpython_issue_301 +c732544420f82ad3166d576674d879db94abbc72 not-for-merge branch 'testcommit2949' of github.com:jantman/gitpython_issue_301 +146ecdd033d0658898cdeb8e3534964c607cea6a not-for-merge branch 'testcommit295' of github.com:jantman/gitpython_issue_301 +6997de62aa74fc36a75109f32d7a7e530bcb4031 not-for-merge branch 'testcommit2950' of github.com:jantman/gitpython_issue_301 +723edd683bc522c2b80bb93f4587e9e600594fcf not-for-merge branch 'testcommit2951' of github.com:jantman/gitpython_issue_301 +c6ea77395baa2fd79eea946bcb9066f5ff7b7de3 not-for-merge branch 'testcommit2952' of github.com:jantman/gitpython_issue_301 +3183ac0352181dc5c276730c1a416d14404dd0d6 not-for-merge branch 'testcommit2953' of github.com:jantman/gitpython_issue_301 +c80f19a8bd071723f73c56ea1c644a55ef81adc8 not-for-merge branch 'testcommit2954' of github.com:jantman/gitpython_issue_301 +7d67399cdcf0874614398847519b944242b44520 not-for-merge branch 'testcommit2955' of github.com:jantman/gitpython_issue_301 +023891c1089f948e777fffc0b0cad5260bdccd6a not-for-merge branch 'testcommit2956' of github.com:jantman/gitpython_issue_301 +5f9b08545b63f4dc369a296a8cba74e49b3323cc not-for-merge branch 'testcommit2957' of github.com:jantman/gitpython_issue_301 +c847e290b84fb5607198bc5c209e6491a59a8063 not-for-merge branch 'testcommit2958' of github.com:jantman/gitpython_issue_301 +a1e959cd27581f548d0dc3825162737fe665e7e0 not-for-merge branch 'testcommit2959' of github.com:jantman/gitpython_issue_301 +91b4f81d958d90a2aac3ea03acddae55a1baa142 not-for-merge branch 'testcommit296' of github.com:jantman/gitpython_issue_301 +ceccf2a4c9e8f399a01be3a2a2c3ba9f87a41757 not-for-merge branch 'testcommit2960' of github.com:jantman/gitpython_issue_301 +b7d5b802e0fcef66fad34a35d1ddc41761124e61 not-for-merge branch 'testcommit2961' of github.com:jantman/gitpython_issue_301 +c99ab8a6a8067a2d8629aed0907f23035fbdc0ac not-for-merge branch 'testcommit2962' of github.com:jantman/gitpython_issue_301 +0dc3dc141867bed7fc08d077ce2dfdef9055b3fe not-for-merge branch 'testcommit2963' of github.com:jantman/gitpython_issue_301 +b0dc1ec5d589aeb408c709c22b865226a9b350d4 not-for-merge branch 'testcommit2964' of github.com:jantman/gitpython_issue_301 +77d4c860027af2dfd3b9724b01fc5bf0cf7dbbdd not-for-merge branch 'testcommit2965' of github.com:jantman/gitpython_issue_301 +51f38c55b58c5b87faa314fa9aa63a6c5112fd41 not-for-merge branch 'testcommit2966' of github.com:jantman/gitpython_issue_301 +b77d8ed4748e62e6bff33b30a8411fd7c936daa9 not-for-merge branch 'testcommit2967' of github.com:jantman/gitpython_issue_301 +793fcc60c4f1422ad8a7121bb99a50de29c37516 not-for-merge branch 'testcommit2968' of github.com:jantman/gitpython_issue_301 +acd242bd3f6258853dfb3b487a8f2146b769ece1 not-for-merge branch 'testcommit2969' of github.com:jantman/gitpython_issue_301 +68b253d1f623bd00e2cd2aa2dcff105b517a7b2f not-for-merge branch 'testcommit297' of github.com:jantman/gitpython_issue_301 +92c71e5f43348db1e58f645f9e9d1d47c2cebcaf not-for-merge branch 'testcommit2970' of github.com:jantman/gitpython_issue_301 +61d376aa1e72e701afa1fa7365f843a14dc603f9 not-for-merge branch 'testcommit2971' of github.com:jantman/gitpython_issue_301 +4fb1c613910ab248888cee907efd6f239195f48a not-for-merge branch 'testcommit2972' of github.com:jantman/gitpython_issue_301 +407614a023967b69891aae180b9224b853374f9d not-for-merge branch 'testcommit2973' of github.com:jantman/gitpython_issue_301 +86275582a81f35e52c9c9008b722ed2db0a5a729 not-for-merge branch 'testcommit2974' of github.com:jantman/gitpython_issue_301 +8251064b4d9219fbecb77c4f5397756f54cf7640 not-for-merge branch 'testcommit2975' of github.com:jantman/gitpython_issue_301 +af892e741565266001392b4b59028fd373c0a657 not-for-merge branch 'testcommit2976' of github.com:jantman/gitpython_issue_301 +b0c70367426caf88f78c1d9d734e8a56c23b4b44 not-for-merge branch 'testcommit2977' of github.com:jantman/gitpython_issue_301 +ae9465a5ae6643151c024768158fd573b3cbaf0c not-for-merge branch 'testcommit2978' of github.com:jantman/gitpython_issue_301 +d1f02dd102cea976cab9d76f53dd5c955b7bfebf not-for-merge branch 'testcommit2979' of github.com:jantman/gitpython_issue_301 +fc38290e57a95c75510bfddf2ae354c5640d7b53 not-for-merge branch 'testcommit298' of github.com:jantman/gitpython_issue_301 +9b2bc9ca92235483509186a709f1e34b20a4d2e7 not-for-merge branch 'testcommit2980' of github.com:jantman/gitpython_issue_301 +5cfea9ec5535e612c30c50697defdee666928892 not-for-merge branch 'testcommit2981' of github.com:jantman/gitpython_issue_301 +b4adf20285dc78ee2a03c2e8afa00f9d45751487 not-for-merge branch 'testcommit2982' of github.com:jantman/gitpython_issue_301 +188f99fcdc5d9fe8f31114e7ffab5bf3739da8d2 not-for-merge branch 'testcommit2983' of github.com:jantman/gitpython_issue_301 +b00880e63c61fbe617d7129d46ce809cc36d525b not-for-merge branch 'testcommit2984' of github.com:jantman/gitpython_issue_301 +4f60b9d57734ca5491f9d9109af2e47f1e3aa2f3 not-for-merge branch 'testcommit2985' of github.com:jantman/gitpython_issue_301 +f76f3c51641c72f5e5597fa29ce2ebefac99efe7 not-for-merge branch 'testcommit2986' of github.com:jantman/gitpython_issue_301 +f758ad50fd438409a0f0a07ff4d2ce552dc3b826 not-for-merge branch 'testcommit2987' of github.com:jantman/gitpython_issue_301 +44f68aa84a4c85b65559bce6fab3f2926c28b205 not-for-merge branch 'testcommit2988' of github.com:jantman/gitpython_issue_301 +68f59ad059603046e9ec5336d774fda2b73916aa not-for-merge branch 'testcommit2989' of github.com:jantman/gitpython_issue_301 +c7c20305653769c48f003197c38775bc6b372f0d not-for-merge branch 'testcommit299' of github.com:jantman/gitpython_issue_301 +2b0743a4ea1153ba67f76ffe541f557c9e04afa7 not-for-merge branch 'testcommit2990' of github.com:jantman/gitpython_issue_301 +e349dba503b710f462fc2d9af6adb844b0f78e8d not-for-merge branch 'testcommit2991' of github.com:jantman/gitpython_issue_301 +6b1f3c1c53716762d2fe9c8f5f17dd1da64b0c47 not-for-merge branch 'testcommit2992' of github.com:jantman/gitpython_issue_301 +fee6432ba53aba731a5537dee264ba02a7cd6236 not-for-merge branch 'testcommit2993' of github.com:jantman/gitpython_issue_301 +3c3a87f5c24affa518b77c835db6b50d7b78707f not-for-merge branch 'testcommit2994' of github.com:jantman/gitpython_issue_301 +72b847946939fe54c70e307944f1d3131596e07b not-for-merge branch 'testcommit2995' of github.com:jantman/gitpython_issue_301 +83c985631b203c4cab4eb86eb02144f43f3ddca4 not-for-merge branch 'testcommit2996' of github.com:jantman/gitpython_issue_301 +066dc4b1c8478848a2519cc664f1e24efc99eecd not-for-merge branch 'testcommit2997' of github.com:jantman/gitpython_issue_301 +2d76b3c07bc5bfd10068806fdfcc3a0c688bbb9a not-for-merge branch 'testcommit2998' of github.com:jantman/gitpython_issue_301 +9cada7bc8e294a78956b9ce3d13b720a2bb2d681 not-for-merge branch 'testcommit2999' of github.com:jantman/gitpython_issue_301 +e4cee9486bf22b4859e667511db86e00c711f139 not-for-merge branch 'testcommit3' of github.com:jantman/gitpython_issue_301 +dbcbcf7b94817f83d5aa24759f5366ea9bf280e9 not-for-merge branch 'testcommit30' of github.com:jantman/gitpython_issue_301 +0b14f6d87462c7f7762f7dcee17f828b07d6450b not-for-merge branch 'testcommit300' of github.com:jantman/gitpython_issue_301 +469992971ccae0d0e3d25abcdba39f62b932922e not-for-merge branch 'testcommit3000' of github.com:jantman/gitpython_issue_301 +3c6301e69de26c23307eaf76deaaf768d8f3467c not-for-merge branch 'testcommit3001' of github.com:jantman/gitpython_issue_301 +dcbc6013dfe8c3620095f082c911f1a712046b95 not-for-merge branch 'testcommit3002' of github.com:jantman/gitpython_issue_301 +daa81eb841f8ac34b5de5ef1122b4b9958efc32c not-for-merge branch 'testcommit3003' of github.com:jantman/gitpython_issue_301 +18a62ffe2d69d5b9620ce02d1cd46dd442f91dc3 not-for-merge branch 'testcommit3004' of github.com:jantman/gitpython_issue_301 +25d42d3ec5a4cc6f6bf9d59c0efba007cd6d234b not-for-merge branch 'testcommit3005' of github.com:jantman/gitpython_issue_301 +67bcaa13423e7ada3af23c2eaad0eeac4aff243b not-for-merge branch 'testcommit3006' of github.com:jantman/gitpython_issue_301 +8bb5acfa51c384bd6da05654c10ef0c1629daa3f not-for-merge branch 'testcommit3007' of github.com:jantman/gitpython_issue_301 +79d3394c66f51e7a36f02e40d31e80f11d405a39 not-for-merge branch 'testcommit3008' of github.com:jantman/gitpython_issue_301 +5e4c4da1e0523bccd8ce50a42bca025befc60035 not-for-merge branch 'testcommit3009' of github.com:jantman/gitpython_issue_301 +e956ec20cf565ffe133e203fc0fe28e2dabc2b81 not-for-merge branch 'testcommit301' of github.com:jantman/gitpython_issue_301 +4c674bf124dc14c4082c5a85ba2fde84632ecc21 not-for-merge branch 'testcommit3010' of github.com:jantman/gitpython_issue_301 +be03731a1d63f7328abc0c8c44e4b6bd07dd358c not-for-merge branch 'testcommit3011' of github.com:jantman/gitpython_issue_301 +ca30de394fbeb0e7531c75e12f374f30336e959c not-for-merge branch 'testcommit3012' of github.com:jantman/gitpython_issue_301 +2adbe4020d60644d11ac2c287f63f595653c7ce1 not-for-merge branch 'testcommit3013' of github.com:jantman/gitpython_issue_301 +563494f581e2734926119dabb05bd02d7b0fc488 not-for-merge branch 'testcommit3014' of github.com:jantman/gitpython_issue_301 +4561515162910827429e26dff72bf31d789cc056 not-for-merge branch 'testcommit3015' of github.com:jantman/gitpython_issue_301 +6299ce3c3e16d00b78c12ae51003f5575da3a587 not-for-merge branch 'testcommit3016' of github.com:jantman/gitpython_issue_301 +fa49c090caa610d6818d17bb2b691f6bdf7e6191 not-for-merge branch 'testcommit3017' of github.com:jantman/gitpython_issue_301 +7395b02ad92ca3fe30991ca949c73fd3ff5324b8 not-for-merge branch 'testcommit3018' of github.com:jantman/gitpython_issue_301 +9cae3ee8ac8a452f0d034b761de85ae275c94342 not-for-merge branch 'testcommit3019' of github.com:jantman/gitpython_issue_301 +a5bac65752d2ea09b4aec4a53916031e0df02a5f not-for-merge branch 'testcommit302' of github.com:jantman/gitpython_issue_301 +477c757618750aca3bb78de6209ec9c2f10dd977 not-for-merge branch 'testcommit3020' of github.com:jantman/gitpython_issue_301 +1f04bdd3d4934549219abcb74c5ae16321c2e379 not-for-merge branch 'testcommit3021' of github.com:jantman/gitpython_issue_301 +fb842b05b791a00fbbf1c2a1c810ab7504e81393 not-for-merge branch 'testcommit3022' of github.com:jantman/gitpython_issue_301 +4cd11d72bb3037e84df29408b33e42b5c2fee957 not-for-merge branch 'testcommit3023' of github.com:jantman/gitpython_issue_301 +58293fa3e700bb70eefc9363aac970264b469d91 not-for-merge branch 'testcommit3024' of github.com:jantman/gitpython_issue_301 +6f428c26432e64f96e2477efc8011083c4364229 not-for-merge branch 'testcommit3025' of github.com:jantman/gitpython_issue_301 +9b4aa01cefbe909cfa5342fd79f0cb395fdc3732 not-for-merge branch 'testcommit3026' of github.com:jantman/gitpython_issue_301 +7005fa1a3fa4dfa782553ab14bc3bcffff9c56df not-for-merge branch 'testcommit3027' of github.com:jantman/gitpython_issue_301 +bf9e4d85ee2f56dd7ef27e6143e845b785b6618b not-for-merge branch 'testcommit3028' of github.com:jantman/gitpython_issue_301 +45d168af42f0ed636050ee8f692e868961de6826 not-for-merge branch 'testcommit3029' of github.com:jantman/gitpython_issue_301 +1f3e973d3a67b4447e88bdaa226a9d86efd2843b not-for-merge branch 'testcommit303' of github.com:jantman/gitpython_issue_301 +186860071e3470cf69460d6402a218088a8093c0 not-for-merge branch 'testcommit3030' of github.com:jantman/gitpython_issue_301 +62b7698ae336cb97d6cb0738ee5b0a709a4ad07b not-for-merge branch 'testcommit3031' of github.com:jantman/gitpython_issue_301 +01d430de1d69d12e931134baf5bb9548f32d6cd5 not-for-merge branch 'testcommit3032' of github.com:jantman/gitpython_issue_301 +41233661f67acbfe2f148536ea1125d103fc208a not-for-merge branch 'testcommit3033' of github.com:jantman/gitpython_issue_301 +5669e6dc8e1ab17442ebc7b2186dd859996a2e31 not-for-merge branch 'testcommit3034' of github.com:jantman/gitpython_issue_301 +d9f2d60beba5fba8a9310bbb67522e92c37b468d not-for-merge branch 'testcommit3035' of github.com:jantman/gitpython_issue_301 +99c303d2e56375382b13a93b961af664a3b820a9 not-for-merge branch 'testcommit3036' of github.com:jantman/gitpython_issue_301 +800e70fc7a677c61b57fd802a361cad08afc12fd not-for-merge branch 'testcommit3037' of github.com:jantman/gitpython_issue_301 +f75c16aeddc5073657490c13e61f6faf5f581f25 not-for-merge branch 'testcommit3038' of github.com:jantman/gitpython_issue_301 +ad943dd467147d40bf1df47e38c088806950a659 not-for-merge branch 'testcommit3039' of github.com:jantman/gitpython_issue_301 +45b4862bd4febaba654cf50c8a230b83f542c0f3 not-for-merge branch 'testcommit304' of github.com:jantman/gitpython_issue_301 +3a8608b91d032305abd134bb21d612c3d8aaa4be not-for-merge branch 'testcommit3040' of github.com:jantman/gitpython_issue_301 +9f16520155c87bef70e97768b1923e78d419472a not-for-merge branch 'testcommit3041' of github.com:jantman/gitpython_issue_301 +13b232c36eb2f99b8cf33ae8051cfe6e895f4e3f not-for-merge branch 'testcommit3042' of github.com:jantman/gitpython_issue_301 +030fbaa9a0a8cadacb2f0f5ea4f175d46325bf61 not-for-merge branch 'testcommit3043' of github.com:jantman/gitpython_issue_301 +65a11e2928b23964215c1bd9536471f4390daf62 not-for-merge branch 'testcommit3044' of github.com:jantman/gitpython_issue_301 +87918a3c9d4c47544a85ec9f68223c34b3586e19 not-for-merge branch 'testcommit3045' of github.com:jantman/gitpython_issue_301 +afca50e8307f3289c1cb796bae5307f8ddf08d06 not-for-merge branch 'testcommit3046' of github.com:jantman/gitpython_issue_301 +5228c57194a6eb2be9d4d84ba3f39636d1184101 not-for-merge branch 'testcommit3047' of github.com:jantman/gitpython_issue_301 +508fd41879344e12ef8e143097a73d5678b1a278 not-for-merge branch 'testcommit3048' of github.com:jantman/gitpython_issue_301 +376a347f87572bfaf7dd673a4189612bacaa9494 not-for-merge branch 'testcommit3049' of github.com:jantman/gitpython_issue_301 +5f203ab3a2323d6a465c73248bfe5b908f5c056f not-for-merge branch 'testcommit305' of github.com:jantman/gitpython_issue_301 +5bf3e183c4b4b6167a7b104a6a6fb31605ef0cb7 not-for-merge branch 'testcommit3050' of github.com:jantman/gitpython_issue_301 +962825f7c91cc25ebd27394653e48fa855921256 not-for-merge branch 'testcommit3051' of github.com:jantman/gitpython_issue_301 +b27c09d7a09676c25d5f5cae0dd171c2ccf7622c not-for-merge branch 'testcommit3052' of github.com:jantman/gitpython_issue_301 +aab6a2a4377864550855bdd639dae8a5c52fa717 not-for-merge branch 'testcommit3053' of github.com:jantman/gitpython_issue_301 +44d6c16157e42f293b0a69b8a5941c81fb267082 not-for-merge branch 'testcommit3054' of github.com:jantman/gitpython_issue_301 +9e8bb2ae67064c95ea37dd63e2bd9be8a8150e27 not-for-merge branch 'testcommit3055' of github.com:jantman/gitpython_issue_301 +18997866b093f734233a38049635402298847d7d not-for-merge branch 'testcommit3056' of github.com:jantman/gitpython_issue_301 +8474ef14f9a88cce7b1c2a0866ba2fe10e83404c not-for-merge branch 'testcommit3057' of github.com:jantman/gitpython_issue_301 +c4507863a62a4b708bf1fd535fc50011f3de8a4f not-for-merge branch 'testcommit3058' of github.com:jantman/gitpython_issue_301 +e5ba02eae339b890d37c7323c7ac1c2f9801726a not-for-merge branch 'testcommit3059' of github.com:jantman/gitpython_issue_301 +f1c04f6206adcc49ac80406cf581fd5b49fbcd76 not-for-merge branch 'testcommit306' of github.com:jantman/gitpython_issue_301 +659f32739f88ff65bda3bac5b296c743d08ed140 not-for-merge branch 'testcommit3060' of github.com:jantman/gitpython_issue_301 +86e677e2db9fbe0bcaa83931892cac0e2dc51472 not-for-merge branch 'testcommit3061' of github.com:jantman/gitpython_issue_301 +643f424501c37369cb0ee2360e1a03096ebe5e0d not-for-merge branch 'testcommit3062' of github.com:jantman/gitpython_issue_301 +6ceed51db69910f0e380d94bba7d9cf2591c4b85 not-for-merge branch 'testcommit3063' of github.com:jantman/gitpython_issue_301 +1e72a2238daf237404b33697f6543f7cd062fcc1 not-for-merge branch 'testcommit3064' of github.com:jantman/gitpython_issue_301 +bd70a284a16bd4c53e34aa4c8f90d75c76fb564f not-for-merge branch 'testcommit3065' of github.com:jantman/gitpython_issue_301 +4722e54013e65377a28cf9919a3356c38bb96c3a not-for-merge branch 'testcommit3066' of github.com:jantman/gitpython_issue_301 +397e46f7d27f3e9944440d81cb6c883f597ef95b not-for-merge branch 'testcommit3067' of github.com:jantman/gitpython_issue_301 +27548fe41e35df65e77e7e6faa318e20d823fd7f not-for-merge branch 'testcommit3068' of github.com:jantman/gitpython_issue_301 +eca823d28ad93642c720acdd8c5f7bed96164c89 not-for-merge branch 'testcommit3069' of github.com:jantman/gitpython_issue_301 +b5ec269973a2bffd96ef3937d60e7b1a983c3dc8 not-for-merge branch 'testcommit307' of github.com:jantman/gitpython_issue_301 +edee647a005f99eeff6c2105c2a784074094a41d not-for-merge branch 'testcommit3070' of github.com:jantman/gitpython_issue_301 +7ca5bec9c741b01114936f5deb4ad7aa9bb432a0 not-for-merge branch 'testcommit3071' of github.com:jantman/gitpython_issue_301 +cfcf8ba80f40b32e2d8ba720653b2d9aa0b79588 not-for-merge branch 'testcommit3072' of github.com:jantman/gitpython_issue_301 +d4077ae770847e80ac9a7c4bd6afccabaeb5189a not-for-merge branch 'testcommit3073' of github.com:jantman/gitpython_issue_301 +ecd1ff3fa0160f88ef4abc899e8de0301b565a52 not-for-merge branch 'testcommit3074' of github.com:jantman/gitpython_issue_301 +5b9e6e36823188fee3dfcff8d73ae763ea50689d not-for-merge branch 'testcommit3075' of github.com:jantman/gitpython_issue_301 +bfb8a68ffd302b1c6850520386356e9b87407ce1 not-for-merge branch 'testcommit3076' of github.com:jantman/gitpython_issue_301 +26bcd09fad349b226d226ea45bd679791990869d not-for-merge branch 'testcommit3077' of github.com:jantman/gitpython_issue_301 +e7b17d85d57ef952230e08ed10b3f31153d528e6 not-for-merge branch 'testcommit3078' of github.com:jantman/gitpython_issue_301 +6956a52f6a1518e158fc73bbc04d6554cc7e6c7a not-for-merge branch 'testcommit3079' of github.com:jantman/gitpython_issue_301 +82220f2bac391b9c25c8fe21d1f584f328d6a601 not-for-merge branch 'testcommit308' of github.com:jantman/gitpython_issue_301 +10989c2734f5843318cbb8b29a5949a51492ba39 not-for-merge branch 'testcommit3080' of github.com:jantman/gitpython_issue_301 +ec56c090752aa98b9fd9f4b5802729ec3ffd0626 not-for-merge branch 'testcommit3081' of github.com:jantman/gitpython_issue_301 +0549c1cd5b8ba7c28d3a3d6dac81a84ed5085fbd not-for-merge branch 'testcommit3082' of github.com:jantman/gitpython_issue_301 +13b3fb97fdfa15ac745676d1fe4cd343c88f6b86 not-for-merge branch 'testcommit3083' of github.com:jantman/gitpython_issue_301 +20a9cd5de43270a3f47d7f67a3b9617a70f7525a not-for-merge branch 'testcommit3084' of github.com:jantman/gitpython_issue_301 +567e3422b2a50faa132e6c55c7d60087120e69b8 not-for-merge branch 'testcommit3085' of github.com:jantman/gitpython_issue_301 +01d7e7c3460894d4a306defc77a18c2a9a7eee18 not-for-merge branch 'testcommit3086' of github.com:jantman/gitpython_issue_301 +9b5c78deafb0062bd83b33852ec0956453b061f9 not-for-merge branch 'testcommit3087' of github.com:jantman/gitpython_issue_301 +b43a9fb97a4f5c7664a6e370c683ce4ed1f89c7f not-for-merge branch 'testcommit3088' of github.com:jantman/gitpython_issue_301 +e3286a24f44cc00fccaae801ba311879e587a9a5 not-for-merge branch 'testcommit3089' of github.com:jantman/gitpython_issue_301 +0c5f76c8757a4a782765aa7aff6ce3851e16422b not-for-merge branch 'testcommit309' of github.com:jantman/gitpython_issue_301 +97696d289ed6a78cab23e3add293e595114124e0 not-for-merge branch 'testcommit3090' of github.com:jantman/gitpython_issue_301 +48f1524918bd8a901a3abf04a636f4033a8a3469 not-for-merge branch 'testcommit3091' of github.com:jantman/gitpython_issue_301 +f55ea4dcc471ee1951e6b26ec6638748daedd3d8 not-for-merge branch 'testcommit3092' of github.com:jantman/gitpython_issue_301 +731662a23a16ee155733f46a61b64db824abed9d not-for-merge branch 'testcommit3093' of github.com:jantman/gitpython_issue_301 +50655deed02283d0e3d680009087eb042ce03f4e not-for-merge branch 'testcommit3094' of github.com:jantman/gitpython_issue_301 +135ffcd74b6c3deada8cb724947447fc65d190db not-for-merge branch 'testcommit3095' of github.com:jantman/gitpython_issue_301 +0a8e15bec4f24dcdfddb2b91c9ec3310098f61db not-for-merge branch 'testcommit3096' of github.com:jantman/gitpython_issue_301 +b8d8ed3883ef8243496b4e534105687536643a65 not-for-merge branch 'testcommit3097' of github.com:jantman/gitpython_issue_301 +f69ca845b226c693f39f43404591470b60c0ae86 not-for-merge branch 'testcommit3098' of github.com:jantman/gitpython_issue_301 +0bb52b22b9502e69f6715e4755a041bfe71e6351 not-for-merge branch 'testcommit3099' of github.com:jantman/gitpython_issue_301 +b7aa295ca3d57ab6864f78dc25cac503139edb77 not-for-merge branch 'testcommit31' of github.com:jantman/gitpython_issue_301 +31760b9035fc3098b80f29a30c18832e34bb8470 not-for-merge branch 'testcommit310' of github.com:jantman/gitpython_issue_301 +66aefe6da4c091f820dc285ffb7c55270c9f70e6 not-for-merge branch 'testcommit3100' of github.com:jantman/gitpython_issue_301 +bb298ceb6a2f6d2e94c52443cebcc4aecaa0d1e7 not-for-merge branch 'testcommit3101' of github.com:jantman/gitpython_issue_301 +f24570edf796111e761a7cf220536c583fbdcc4d not-for-merge branch 'testcommit3102' of github.com:jantman/gitpython_issue_301 +d43c0b36a3fd9d3100d534bf3f15686f3060cda2 not-for-merge branch 'testcommit3103' of github.com:jantman/gitpython_issue_301 +c0c0b599f72e88a7e43e8df0635e62787087b844 not-for-merge branch 'testcommit3104' of github.com:jantman/gitpython_issue_301 +193e92aca2d12f4b6dd7509675a40d80449129e1 not-for-merge branch 'testcommit3105' of github.com:jantman/gitpython_issue_301 +5a5dba60d054162e9f697093fc0827885f7321ee not-for-merge branch 'testcommit3106' of github.com:jantman/gitpython_issue_301 +6ab09c475ea7de06d312a38a0cadc18febe1f25a not-for-merge branch 'testcommit3107' of github.com:jantman/gitpython_issue_301 +61d0a13af1dadf6dcb93e7a32fc2f754c82b9c6f not-for-merge branch 'testcommit3108' of github.com:jantman/gitpython_issue_301 +9e591bd78c6e4a82122fc44026eeba03d545a76c not-for-merge branch 'testcommit3109' of github.com:jantman/gitpython_issue_301 +4cb4e1853561f8d6d4933eb2e19c17aa6890f00f not-for-merge branch 'testcommit311' of github.com:jantman/gitpython_issue_301 +d9f920210bd04f677cbfc9360fb80cf74efc027b not-for-merge branch 'testcommit3110' of github.com:jantman/gitpython_issue_301 +f68bbbfef1733cd862b0f6223a62e7b4c71c6176 not-for-merge branch 'testcommit3111' of github.com:jantman/gitpython_issue_301 +3f6d77bf52d5f748d82c956726be68eab00dcdcc not-for-merge branch 'testcommit3112' of github.com:jantman/gitpython_issue_301 +36f6bcd97dbab81f6d9f6efc00d152252969bc0a not-for-merge branch 'testcommit3113' of github.com:jantman/gitpython_issue_301 +6238d3310878473e8660a035e2e44290867f527f not-for-merge branch 'testcommit3114' of github.com:jantman/gitpython_issue_301 +6ab1d7107225030b2402d0d7b9b8262a559dc156 not-for-merge branch 'testcommit3115' of github.com:jantman/gitpython_issue_301 +32d03c829e431bed049795054126b4fa63aa3180 not-for-merge branch 'testcommit3116' of github.com:jantman/gitpython_issue_301 +eed4c18ab3e6b156a261d3eb4e4333b4e051c1e9 not-for-merge branch 'testcommit3117' of github.com:jantman/gitpython_issue_301 +6bc87b3d39d8861dfa107f350e49d583ef921ea1 not-for-merge branch 'testcommit3118' of github.com:jantman/gitpython_issue_301 +c9ff6c217bc48a406287b8e6f8c089d1a353bf06 not-for-merge branch 'testcommit3119' of github.com:jantman/gitpython_issue_301 +f8fbdb568acb8726a97a581635b8b4437a5a8496 not-for-merge branch 'testcommit312' of github.com:jantman/gitpython_issue_301 +1ad3edae963d8d7b5829da0de75db85a34f93b71 not-for-merge branch 'testcommit3120' of github.com:jantman/gitpython_issue_301 +d68b71d2768b40f4037b2a0ec66d7b909bd0d83b not-for-merge branch 'testcommit3121' of github.com:jantman/gitpython_issue_301 +507b5bbe23a8db25e34d6f2453963453e76fc039 not-for-merge branch 'testcommit3122' of github.com:jantman/gitpython_issue_301 +073d01c464da61c8e79848ef3bdfb0820619cf56 not-for-merge branch 'testcommit3123' of github.com:jantman/gitpython_issue_301 +e938095d843eb2e6b9148398576e04774cc1b4ca not-for-merge branch 'testcommit3124' of github.com:jantman/gitpython_issue_301 +9349027b9cc4754541adf5af7ac2faac522a6e19 not-for-merge branch 'testcommit3125' of github.com:jantman/gitpython_issue_301 +fef764ed1fe695e4bce3f3c280ba6485778cb6ec not-for-merge branch 'testcommit3126' of github.com:jantman/gitpython_issue_301 +45d29b5f1183a27db430e4a2cfafa8503156e5e1 not-for-merge branch 'testcommit3127' of github.com:jantman/gitpython_issue_301 +693e55c8db4eb6e3a24359f98091cb921594c7f3 not-for-merge branch 'testcommit3128' of github.com:jantman/gitpython_issue_301 +eaf04ef00009d7fe60eff92afa6cf8768ab56e05 not-for-merge branch 'testcommit3129' of github.com:jantman/gitpython_issue_301 +8fe4b5dd9c4ad052e0e4cae1cfbc9252c31497ae not-for-merge branch 'testcommit313' of github.com:jantman/gitpython_issue_301 +c515794201b46a0d49548fb5b4d767d4d7c941e2 not-for-merge branch 'testcommit3130' of github.com:jantman/gitpython_issue_301 +0365650552245dc6d125f9fcb1c0280220625708 not-for-merge branch 'testcommit3131' of github.com:jantman/gitpython_issue_301 +9adec0acca004907c68b8ed2bc00ab3bbe116f69 not-for-merge branch 'testcommit3132' of github.com:jantman/gitpython_issue_301 +9f55d8029e573dc95854498bb9a77c12c470404b not-for-merge branch 'testcommit3133' of github.com:jantman/gitpython_issue_301 +2ab9eb7e11f2d64bbd933e291e39b3da4b968626 not-for-merge branch 'testcommit3134' of github.com:jantman/gitpython_issue_301 +c9997da50a421af4ed993eb98fbef14f46ac215c not-for-merge branch 'testcommit3135' of github.com:jantman/gitpython_issue_301 +c6e12495e260997dde3492d67519e2bb5f0e6b40 not-for-merge branch 'testcommit3136' of github.com:jantman/gitpython_issue_301 +d2aca33e23e72a24bd5d0cdcdf04071a42df6382 not-for-merge branch 'testcommit3137' of github.com:jantman/gitpython_issue_301 +a3659d50c92b28f84b1bc4779e2d2ec5b02d2543 not-for-merge branch 'testcommit3138' of github.com:jantman/gitpython_issue_301 +bc1a34b079b6b2b77c8875953e4a70cfe5954812 not-for-merge branch 'testcommit3139' of github.com:jantman/gitpython_issue_301 +396282103d037fdad4e519be5aa489137ee9d8d1 not-for-merge branch 'testcommit314' of github.com:jantman/gitpython_issue_301 +5dceca8a4821e705646a20782ff98f7addc24410 not-for-merge branch 'testcommit3140' of github.com:jantman/gitpython_issue_301 +791a558362b7f59ba004c646f3a3957eb5e7e412 not-for-merge branch 'testcommit3141' of github.com:jantman/gitpython_issue_301 +c574de3f70655ca22f49230b8a5bcd2d34760422 not-for-merge branch 'testcommit3142' of github.com:jantman/gitpython_issue_301 +f377d2e0cf12cba5aa62d7e81713a9660e1d5ad1 not-for-merge branch 'testcommit3143' of github.com:jantman/gitpython_issue_301 +ee2588bdf5c00ada17186cfdec3965282895ebee not-for-merge branch 'testcommit3144' of github.com:jantman/gitpython_issue_301 +ce9c2f87beb5b9c321c5cbcf2d2d25924e776c36 not-for-merge branch 'testcommit3145' of github.com:jantman/gitpython_issue_301 +8af8af863fae0fe56f2dbc9f734bc5dcb0b43612 not-for-merge branch 'testcommit3146' of github.com:jantman/gitpython_issue_301 +8a818027cd88e75ee4dfc37be13c3a3d42a26adf not-for-merge branch 'testcommit3147' of github.com:jantman/gitpython_issue_301 +f883c8b50d31b66e79d504077a4ccdbf503b9c1d not-for-merge branch 'testcommit3148' of github.com:jantman/gitpython_issue_301 +119f296794e4761d32747c35eebb80a4fbe08db5 not-for-merge branch 'testcommit3149' of github.com:jantman/gitpython_issue_301 +ed9d9e76b68a020db3d32d8663660c940b679d12 not-for-merge branch 'testcommit315' of github.com:jantman/gitpython_issue_301 +0f9599a2ec0dcb5477f4f72a5791af17c4dc0121 not-for-merge branch 'testcommit3150' of github.com:jantman/gitpython_issue_301 +592604690d6819e4e12d198a910400106f12215e not-for-merge branch 'testcommit3151' of github.com:jantman/gitpython_issue_301 +d8ef81e2596b04436a907995c463c31a78bd59f5 not-for-merge branch 'testcommit3152' of github.com:jantman/gitpython_issue_301 +b0704862da0fa6dd25afcdc59677f6d63ab00d80 not-for-merge branch 'testcommit3153' of github.com:jantman/gitpython_issue_301 +f67dcaad0dc437ddbce1e7eac846529a77662f67 not-for-merge branch 'testcommit3154' of github.com:jantman/gitpython_issue_301 +e79517ef3e1304eaeb7a2b141bf80ee012861ac8 not-for-merge branch 'testcommit3155' of github.com:jantman/gitpython_issue_301 +364df92f30f457a3c021c20c183b3ec8fb473340 not-for-merge branch 'testcommit3156' of github.com:jantman/gitpython_issue_301 +9d9050ccb96b1f256232a08a0ed7dc734cf4c86a not-for-merge branch 'testcommit3157' of github.com:jantman/gitpython_issue_301 +f305c2ff672311d658a10c66a08a7e3d659262ea not-for-merge branch 'testcommit3158' of github.com:jantman/gitpython_issue_301 +bbfbb0e4ed7493cbe8b672a64d9f29061e57e1d7 not-for-merge branch 'testcommit3159' of github.com:jantman/gitpython_issue_301 +ae925c1a638331ffe711a2c9b99b0ae7d4ba52e8 not-for-merge branch 'testcommit316' of github.com:jantman/gitpython_issue_301 +72dfafa2178f51220b4103b2159ee767b6f650e3 not-for-merge branch 'testcommit3160' of github.com:jantman/gitpython_issue_301 +75bf5eb2f1797a89ebd4345115815b0016a56cc9 not-for-merge branch 'testcommit3161' of github.com:jantman/gitpython_issue_301 +eff2bf51e40a626e4b3881b2f0f8ae96b4cfe5c3 not-for-merge branch 'testcommit3162' of github.com:jantman/gitpython_issue_301 +a91cda3decbbd1bf34a7cc379ee1f009182c893e not-for-merge branch 'testcommit3163' of github.com:jantman/gitpython_issue_301 +ab74957e1a2c8cc3ed3d1a715bba51b64af6cde2 not-for-merge branch 'testcommit3164' of github.com:jantman/gitpython_issue_301 +e93ecae2182ee8f54245fad37b0f45b631839dc8 not-for-merge branch 'testcommit3165' of github.com:jantman/gitpython_issue_301 +c52b71c4ca77d3ec8b65fc916d3d1d993d8c6153 not-for-merge branch 'testcommit3166' of github.com:jantman/gitpython_issue_301 +ecaee1b6a4bc3dbee318d7c03687af4a618989fa not-for-merge branch 'testcommit3167' of github.com:jantman/gitpython_issue_301 +5b5d9107a19487bf7c06c0295e9e6ae6ada92c0a not-for-merge branch 'testcommit3168' of github.com:jantman/gitpython_issue_301 +d116bdc5260977ba8f66a5e01c428929f6decc19 not-for-merge branch 'testcommit3169' of github.com:jantman/gitpython_issue_301 +1f523bcc78615916a35514cc72664112021c7a24 not-for-merge branch 'testcommit317' of github.com:jantman/gitpython_issue_301 +3e501978a09f12f49d928e89e91166f2e2f2d07e not-for-merge branch 'testcommit3170' of github.com:jantman/gitpython_issue_301 +e766b2a2b82eadf2f29091b4d1869e1dd8b73d31 not-for-merge branch 'testcommit3171' of github.com:jantman/gitpython_issue_301 +4487811ac3c0b1f104776bf0ac07d57a7b87d64a not-for-merge branch 'testcommit3172' of github.com:jantman/gitpython_issue_301 +9c3a7c9feff96d9ac3e46456212275d6669c39b5 not-for-merge branch 'testcommit3173' of github.com:jantman/gitpython_issue_301 +e3741fbdc9e01f6b15bd7eafc4a2bcb47b3c837a not-for-merge branch 'testcommit3174' of github.com:jantman/gitpython_issue_301 +c6a31ef52181e736a07551e3107b9f65a2666c1a not-for-merge branch 'testcommit3175' of github.com:jantman/gitpython_issue_301 +90f57889a1719cd82a31e4588fc3980b3b70f9ad not-for-merge branch 'testcommit3176' of github.com:jantman/gitpython_issue_301 +d39d7349b1e3304a1c554cd147a3889e71ea3e35 not-for-merge branch 'testcommit3177' of github.com:jantman/gitpython_issue_301 +03a94c74ecdb30c6b1576f364bd7697c4e30b5fe not-for-merge branch 'testcommit3178' of github.com:jantman/gitpython_issue_301 +5e1300d415aa96c38211ccf18aae61085e352397 not-for-merge branch 'testcommit3179' of github.com:jantman/gitpython_issue_301 +3e0b17c8c0032dd65fac1e08a505fc0d467a038c not-for-merge branch 'testcommit318' of github.com:jantman/gitpython_issue_301 +4df76718d03595c9844f3102b494758af5f7a27a not-for-merge branch 'testcommit3180' of github.com:jantman/gitpython_issue_301 +e02232903046e11bd5bd92340efc34c10615213e not-for-merge branch 'testcommit3181' of github.com:jantman/gitpython_issue_301 +77e189ce96553dd632d446bb6a4eafa55a12aa5a not-for-merge branch 'testcommit3182' of github.com:jantman/gitpython_issue_301 +275a7c634aa350b529fc9b8b3461ac12453d2736 not-for-merge branch 'testcommit3183' of github.com:jantman/gitpython_issue_301 +a608c2d391bb0f7711e02e55d2241a30189dc776 not-for-merge branch 'testcommit3184' of github.com:jantman/gitpython_issue_301 +425c9f6f3fe484e3a6c5caebccb45ed3fc7afdee not-for-merge branch 'testcommit3185' of github.com:jantman/gitpython_issue_301 +90f22686bd14991ecf39bab75a3e912727d0142a not-for-merge branch 'testcommit3186' of github.com:jantman/gitpython_issue_301 +c2eb084a83f31d8fd0984887d5a796388774f55e not-for-merge branch 'testcommit3187' of github.com:jantman/gitpython_issue_301 +f60533eabaa834f2ef454a8e934c3bbe93869c00 not-for-merge branch 'testcommit3188' of github.com:jantman/gitpython_issue_301 +f579ad8e4e7e03aedb1d957cf4708fcb276a1ae2 not-for-merge branch 'testcommit3189' of github.com:jantman/gitpython_issue_301 +039e08e2b20a0d7a6a3d240e0cf9c8c6d18d90f8 not-for-merge branch 'testcommit319' of github.com:jantman/gitpython_issue_301 +47807ed0686b186bc74c53dfe823e832c5b1fe34 not-for-merge branch 'testcommit3190' of github.com:jantman/gitpython_issue_301 +1eed719913efec3150f1f32e7850a13015148e4c not-for-merge branch 'testcommit3191' of github.com:jantman/gitpython_issue_301 +7f7b013b8e454b59410ad7c18a2328be1a9b2843 not-for-merge branch 'testcommit3192' of github.com:jantman/gitpython_issue_301 +e2fdcbb3f5ad6891533accaa4910d6b386775dbb not-for-merge branch 'testcommit3193' of github.com:jantman/gitpython_issue_301 +4d9d2b00c964c502caa4a74b0f03333b0029e9b9 not-for-merge branch 'testcommit3194' of github.com:jantman/gitpython_issue_301 +9f803dd6ab9a26e5d9860cdb7b9b9e5abe03aa4e not-for-merge branch 'testcommit3195' of github.com:jantman/gitpython_issue_301 +f0c2555e8bfbde1e9c5ec45445e2ac852b291f24 not-for-merge branch 'testcommit3196' of github.com:jantman/gitpython_issue_301 +5dd7bbbeeed131026cfcd047001f41beba45f6e7 not-for-merge branch 'testcommit3197' of github.com:jantman/gitpython_issue_301 +84cbb686bcdb10ba3e0d3601159edbb80529aa2e not-for-merge branch 'testcommit3198' of github.com:jantman/gitpython_issue_301 +b40843d189469403d90b7c13729b704028451c9d not-for-merge branch 'testcommit3199' of github.com:jantman/gitpython_issue_301 +67a7e80511933e91d1c7e605d148d430329995c0 not-for-merge branch 'testcommit32' of github.com:jantman/gitpython_issue_301 +3ecfd3773cc5c0fbdcf5051435fd9034aa9aac83 not-for-merge branch 'testcommit320' of github.com:jantman/gitpython_issue_301 +b3caef26176b848c3e9d09136fe8d87a2a8c439d not-for-merge branch 'testcommit3200' of github.com:jantman/gitpython_issue_301 +f6560af1bc09356b6cb62e93ddb54e0e19f91027 not-for-merge branch 'testcommit3201' of github.com:jantman/gitpython_issue_301 +cda9efa2da61f3fb0342c2fc40504c770bb9e1cc not-for-merge branch 'testcommit3202' of github.com:jantman/gitpython_issue_301 +31f9c26f9dbc6d9430c997a5f34547b0f1f4b039 not-for-merge branch 'testcommit3203' of github.com:jantman/gitpython_issue_301 +b6e9ea946d1d8c2ce7963ff253db91305d94c605 not-for-merge branch 'testcommit3204' of github.com:jantman/gitpython_issue_301 +59b918068cb34e8764a3c8b9c0037944722c804d not-for-merge branch 'testcommit3205' of github.com:jantman/gitpython_issue_301 +1f2f13e0077551439af604313186e8d22c0df588 not-for-merge branch 'testcommit3206' of github.com:jantman/gitpython_issue_301 +e109f58006d3e5523dd5cf71e8d86505db3274ea not-for-merge branch 'testcommit3207' of github.com:jantman/gitpython_issue_301 +28294a5c69078bdccf0fad8ca6b7fd3c39a04773 not-for-merge branch 'testcommit3208' of github.com:jantman/gitpython_issue_301 +867f36a18c5629577866b1bc2a8244a5e23fc108 not-for-merge branch 'testcommit3209' of github.com:jantman/gitpython_issue_301 +1f1c7bb1f6c6916c90caa8f7a9fd33db7ce808bb not-for-merge branch 'testcommit321' of github.com:jantman/gitpython_issue_301 +7eeb65d0af5f62b2efc3bb089cdb79dddf228342 not-for-merge branch 'testcommit3210' of github.com:jantman/gitpython_issue_301 +03df7945451de60bd595ebfc4eda912882a0caae not-for-merge branch 'testcommit3211' of github.com:jantman/gitpython_issue_301 +5bdaac2e8209ac19ab48a4273fe6b95993478d9f not-for-merge branch 'testcommit3212' of github.com:jantman/gitpython_issue_301 +612e677ac0cc872b6f514179e563bb7f0080a131 not-for-merge branch 'testcommit3213' of github.com:jantman/gitpython_issue_301 +a0b944ab0feca1498712c7b450adb8d7b4c8c859 not-for-merge branch 'testcommit3214' of github.com:jantman/gitpython_issue_301 +c183c3aebcbfc6672045c942bdedd7665c6841dd not-for-merge branch 'testcommit3215' of github.com:jantman/gitpython_issue_301 +dc0ea2ad6e6754e54facc6ce7f07a3f765d9fbd8 not-for-merge branch 'testcommit3216' of github.com:jantman/gitpython_issue_301 +b9494ad40695fc3e0b5ee853042e4699fcd3cd23 not-for-merge branch 'testcommit3217' of github.com:jantman/gitpython_issue_301 +0b1fd4da2f4793a3e28fd345d472d67947c70f43 not-for-merge branch 'testcommit3218' of github.com:jantman/gitpython_issue_301 +8927f99a3d0ca4fb88f2e875436119ad5413c3e7 not-for-merge branch 'testcommit3219' of github.com:jantman/gitpython_issue_301 +d10e132919280fcdf48c62593460861031ab8c99 not-for-merge branch 'testcommit322' of github.com:jantman/gitpython_issue_301 +dc9c808aeb634c1ea885b451b202a5711e892f3f not-for-merge branch 'testcommit3220' of github.com:jantman/gitpython_issue_301 +e5778e4d9d0fdcc6a41c8c601e82e76b68211ee3 not-for-merge branch 'testcommit3221' of github.com:jantman/gitpython_issue_301 +e2021abf719fe651d2fecaf96c4bf801c6d55ad5 not-for-merge branch 'testcommit3222' of github.com:jantman/gitpython_issue_301 +7f7a4daee49d0baf077bec63ef2e9fcb1fd48425 not-for-merge branch 'testcommit3223' of github.com:jantman/gitpython_issue_301 +d4516d40be38b2326860edc9cbeaad609947b0e8 not-for-merge branch 'testcommit3224' of github.com:jantman/gitpython_issue_301 +effa895baa2f8b9641b9a0e904f407dd47678261 not-for-merge branch 'testcommit3225' of github.com:jantman/gitpython_issue_301 +b1998f7115b771156dede32cc6497de5a03204b3 not-for-merge branch 'testcommit3226' of github.com:jantman/gitpython_issue_301 +1537cc72ea1d301a0adbb9d87776c71ab05b6459 not-for-merge branch 'testcommit3227' of github.com:jantman/gitpython_issue_301 +0ee2e347e262675e86eb79a06cad82d72eee5bfa not-for-merge branch 'testcommit3228' of github.com:jantman/gitpython_issue_301 +76ef9520bffae40bd7c71d60dd215f260de9173e not-for-merge branch 'testcommit3229' of github.com:jantman/gitpython_issue_301 +776dee42ff792a033f0dba962df1f0cdce6985ca not-for-merge branch 'testcommit323' of github.com:jantman/gitpython_issue_301 +4afe8e11f2d35c6529ce3158faf1c14fe01ea968 not-for-merge branch 'testcommit3230' of github.com:jantman/gitpython_issue_301 +41c6c1dac91e84fce84b48f521b1f7a1ef24fdd4 not-for-merge branch 'testcommit3231' of github.com:jantman/gitpython_issue_301 +06337339fdef80c49fd96e2a4597c039d478264f not-for-merge branch 'testcommit3232' of github.com:jantman/gitpython_issue_301 +8450e5988e2b9c8fbee512db64d10dde38a03f6a not-for-merge branch 'testcommit3233' of github.com:jantman/gitpython_issue_301 +10b0cd35b2f954eb865d06007e3458f2d57b0bec not-for-merge branch 'testcommit3234' of github.com:jantman/gitpython_issue_301 +42dadf787d9691ccbb76651abaca92682ad8a546 not-for-merge branch 'testcommit3235' of github.com:jantman/gitpython_issue_301 +4b8f3cbae967245614d062c4fbac1c752bc36cdb not-for-merge branch 'testcommit3236' of github.com:jantman/gitpython_issue_301 +5cf5bf0af30129883220af107a9c317024f6d0fc not-for-merge branch 'testcommit3237' of github.com:jantman/gitpython_issue_301 +d612a01b30ca0d49d0a23787132fd5ebb0ac9d66 not-for-merge branch 'testcommit3238' of github.com:jantman/gitpython_issue_301 +7b1099ec96f7f77ee0ead7263c3bdaf6329ced04 not-for-merge branch 'testcommit3239' of github.com:jantman/gitpython_issue_301 +0608d22ef75fec628ab594a7f2528dfaeb8fa200 not-for-merge branch 'testcommit324' of github.com:jantman/gitpython_issue_301 +1ca12453387594d89cbf93568198e4ad83b2bb25 not-for-merge branch 'testcommit3240' of github.com:jantman/gitpython_issue_301 +455e5af5394a1c5a994dd088f847c61c9e85a8a3 not-for-merge branch 'testcommit3241' of github.com:jantman/gitpython_issue_301 +c96e9d25665e4d82773117e2ec73416704a2b172 not-for-merge branch 'testcommit3242' of github.com:jantman/gitpython_issue_301 +71b8def7858375e9784b5058b06cdee2a5afd3a5 not-for-merge branch 'testcommit3243' of github.com:jantman/gitpython_issue_301 +a1616b3c277737b4221d42b6f0eebaaba3a413b2 not-for-merge branch 'testcommit3244' of github.com:jantman/gitpython_issue_301 +ab8d732bef012568e6ba88765b9b7c5d9bfd044d not-for-merge branch 'testcommit3245' of github.com:jantman/gitpython_issue_301 +c4531d927d3f8ff1c93cbef43edb12144f5319e1 not-for-merge branch 'testcommit3246' of github.com:jantman/gitpython_issue_301 +5dcbf05dbed71edb03fc88504a9a389acc167628 not-for-merge branch 'testcommit3247' of github.com:jantman/gitpython_issue_301 +1e1e8fa7e12d4a65778917fa776bf31d6c172a32 not-for-merge branch 'testcommit3248' of github.com:jantman/gitpython_issue_301 +d44cf24d2c8f8d6df5e86dcaa08294223f665fc3 not-for-merge branch 'testcommit3249' of github.com:jantman/gitpython_issue_301 +67727507c300ff9fd434801b92952637bc2ae0c2 not-for-merge branch 'testcommit325' of github.com:jantman/gitpython_issue_301 +6950fdedcbf67ae771c923fac264b0032ccbb39d not-for-merge branch 'testcommit3250' of github.com:jantman/gitpython_issue_301 +797dc97294bc132e9a7700228e2afb60721f2927 not-for-merge branch 'testcommit3251' of github.com:jantman/gitpython_issue_301 +e59d2fa4aaf74c69946894eca02299a794427d9e not-for-merge branch 'testcommit3252' of github.com:jantman/gitpython_issue_301 +6767cd851cb484c779e2491bbdb7d4f9f71f4a93 not-for-merge branch 'testcommit3253' of github.com:jantman/gitpython_issue_301 +7e2607136a5e177716c835bc2093e7673ce12e80 not-for-merge branch 'testcommit3254' of github.com:jantman/gitpython_issue_301 +fc79de06daf5b1f760f50b61d186b3a7ec1f7aaf not-for-merge branch 'testcommit3255' of github.com:jantman/gitpython_issue_301 +d6dfb47b0cd2028de1c7287fabbce1161d03c1d2 not-for-merge branch 'testcommit3256' of github.com:jantman/gitpython_issue_301 +929350753647c43000cf87bb4d2d74ca60b02e38 not-for-merge branch 'testcommit3257' of github.com:jantman/gitpython_issue_301 +4ad7285a2dca21e136a2261775d54acc55ade8af not-for-merge branch 'testcommit3258' of github.com:jantman/gitpython_issue_301 +9efe673fb4c6470ce354b412819f988ba6bc371d not-for-merge branch 'testcommit3259' of github.com:jantman/gitpython_issue_301 +5ae0e294868d63bd32009b4682b72f8ef4a4b132 not-for-merge branch 'testcommit326' of github.com:jantman/gitpython_issue_301 +56a870e0b039d681b91e19a5c89095efa5272eb6 not-for-merge branch 'testcommit3260' of github.com:jantman/gitpython_issue_301 +c69b67208e8a288fa49298aa78cd296027d43e7b not-for-merge branch 'testcommit3261' of github.com:jantman/gitpython_issue_301 +33a20d5c51c15384d99ab714ef3fe2eaaa277134 not-for-merge branch 'testcommit3262' of github.com:jantman/gitpython_issue_301 +df70f74a288839df1e7a8f38c40e03965c759962 not-for-merge branch 'testcommit3263' of github.com:jantman/gitpython_issue_301 +4b3be6cf273358a9d4e18924fce986fa749d360e not-for-merge branch 'testcommit3264' of github.com:jantman/gitpython_issue_301 +b0853536a3dd5e604485cfd5f0d5dc13f553d215 not-for-merge branch 'testcommit3265' of github.com:jantman/gitpython_issue_301 +f71e87e4e39e0a7a35b7df661040ef2fff301d9c not-for-merge branch 'testcommit3266' of github.com:jantman/gitpython_issue_301 +da30095199650da647f47bb0b24c03de9e750850 not-for-merge branch 'testcommit3267' of github.com:jantman/gitpython_issue_301 +f4d0ed569cb9a042bbcb545bb4b3b6b9a28c5407 not-for-merge branch 'testcommit3268' of github.com:jantman/gitpython_issue_301 +1048c0d69eb5e7e7d0bdd966853b59146cd20de2 not-for-merge branch 'testcommit3269' of github.com:jantman/gitpython_issue_301 +96888d9d793609ff180a131fb12a027f97d97701 not-for-merge branch 'testcommit327' of github.com:jantman/gitpython_issue_301 +f641995b2a08f1e8955b15c77f3be76c077d4041 not-for-merge branch 'testcommit3270' of github.com:jantman/gitpython_issue_301 +04359ca5ecb19f950e9cc12f74deb43d7b6ead9e not-for-merge branch 'testcommit3271' of github.com:jantman/gitpython_issue_301 +72a5ab0d4d62fa20a04f3344d8df80ea33f13299 not-for-merge branch 'testcommit3272' of github.com:jantman/gitpython_issue_301 +46d0adc2499a7f3f567876fff74bbb2c7dbc5542 not-for-merge branch 'testcommit3273' of github.com:jantman/gitpython_issue_301 +e22d06931baff749c13514ff7227083fd735274e not-for-merge branch 'testcommit3274' of github.com:jantman/gitpython_issue_301 +6ea93b0544b800c8229de9d2daf3283c47163293 not-for-merge branch 'testcommit3275' of github.com:jantman/gitpython_issue_301 +626fc1422b478741a8204bca342c85bc0e4e404c not-for-merge branch 'testcommit3276' of github.com:jantman/gitpython_issue_301 +51713e7dab526f02f9b905f53c2fda95e195a868 not-for-merge branch 'testcommit3277' of github.com:jantman/gitpython_issue_301 +a020cbf33508798d865e7fa0855b54dd0dc57940 not-for-merge branch 'testcommit3278' of github.com:jantman/gitpython_issue_301 +145723d2a48d66b00620acc2c72434ab15f6d809 not-for-merge branch 'testcommit3279' of github.com:jantman/gitpython_issue_301 +7f57c39071554b60cf9da8615fb5079e49fce6d7 not-for-merge branch 'testcommit328' of github.com:jantman/gitpython_issue_301 +a9d16bad28d046382a5ea95019cd7d835be7c0eb not-for-merge branch 'testcommit3280' of github.com:jantman/gitpython_issue_301 +af1c3373c22aa937c7216e976324a16510374979 not-for-merge branch 'testcommit3281' of github.com:jantman/gitpython_issue_301 +d2c96c3c043e288ba0a5d9b40b684b5af4dcc069 not-for-merge branch 'testcommit3282' of github.com:jantman/gitpython_issue_301 +3fba0839769023c841d10f8a0ebb256ceccfa4ce not-for-merge branch 'testcommit3283' of github.com:jantman/gitpython_issue_301 +4aa99df62af5075bfdefa9b21df4a7b31cadf549 not-for-merge branch 'testcommit3284' of github.com:jantman/gitpython_issue_301 +593b926ce669858687305890e5705f55ded91030 not-for-merge branch 'testcommit3285' of github.com:jantman/gitpython_issue_301 +8eda75c3e84572a28be4f2f929549e2a9b469dbb not-for-merge branch 'testcommit3286' of github.com:jantman/gitpython_issue_301 +8aae2f41cd68feebfb72cd74da8ac0f085521396 not-for-merge branch 'testcommit3287' of github.com:jantman/gitpython_issue_301 +8be8e798c7b5ca4faa898a22540302f4e72536d7 not-for-merge branch 'testcommit3288' of github.com:jantman/gitpython_issue_301 +a49ed9c232fa00ec0807b0ac6c3f5bcc7b7a4b23 not-for-merge branch 'testcommit3289' of github.com:jantman/gitpython_issue_301 +77c4bb3ba7e76502898a9b3ab1ed88196edfd94e not-for-merge branch 'testcommit329' of github.com:jantman/gitpython_issue_301 +844a08808c86fbe2e81e90eb5cb54b6c82ffe25c not-for-merge branch 'testcommit3290' of github.com:jantman/gitpython_issue_301 +952b8d889474770b8b455a8044e56e873c144308 not-for-merge branch 'testcommit3291' of github.com:jantman/gitpython_issue_301 +2ffce0ad6bf485081cce51671db0339d55102bf7 not-for-merge branch 'testcommit3292' of github.com:jantman/gitpython_issue_301 +2419b315faf28f85be09193098560e8e5230dbcf not-for-merge branch 'testcommit3293' of github.com:jantman/gitpython_issue_301 +0e48ce79788ea5a6e00e7ed416b7c635c041d931 not-for-merge branch 'testcommit3294' of github.com:jantman/gitpython_issue_301 +df947b14bff373b4a30e5d6df97f8e7535d1776e not-for-merge branch 'testcommit3295' of github.com:jantman/gitpython_issue_301 +f3999c1c55dd1c5ecf33ba19e91d9a3b8e537973 not-for-merge branch 'testcommit3296' of github.com:jantman/gitpython_issue_301 +867929b2f6a5684399dacc471160f12d5d0ad4e6 not-for-merge branch 'testcommit3297' of github.com:jantman/gitpython_issue_301 +2e6e1b52810e6d10d0d4544ff64cf6fc65527d67 not-for-merge branch 'testcommit3298' of github.com:jantman/gitpython_issue_301 +ceaed6fcda89a11de67dc199afc922e2123d91b4 not-for-merge branch 'testcommit3299' of github.com:jantman/gitpython_issue_301 +b606e6388257425e1b2cdbb9564b4bbf482509c5 not-for-merge branch 'testcommit33' of github.com:jantman/gitpython_issue_301 +19580969d7d584783a74fa88c5c676c0cecba99a not-for-merge branch 'testcommit330' of github.com:jantman/gitpython_issue_301 +8c9b8c05bb5c0211c73c7bb8ca0fe1a5ade80169 not-for-merge branch 'testcommit3300' of github.com:jantman/gitpython_issue_301 +a242d715bce62cdb145895c9d5eae56512da2f80 not-for-merge branch 'testcommit3301' of github.com:jantman/gitpython_issue_301 +3509074311ceffc1f956713c6c9ee9a27949a1b0 not-for-merge branch 'testcommit3302' of github.com:jantman/gitpython_issue_301 +ba11ac5b0368e44a3e7e55b9c33598b28b5f7f7f not-for-merge branch 'testcommit3303' of github.com:jantman/gitpython_issue_301 +20458319a9b87474d66a31f667bf76e089917060 not-for-merge branch 'testcommit3304' of github.com:jantman/gitpython_issue_301 +70ea655b94dd1c6d39fc90a81ddcdc76485fc3b4 not-for-merge branch 'testcommit3305' of github.com:jantman/gitpython_issue_301 +55d8b2f782c1a10f314c2af5ccaf975f7eecde76 not-for-merge branch 'testcommit3306' of github.com:jantman/gitpython_issue_301 +a4dd253f67f3f9a36370da094c775e19ff784e92 not-for-merge branch 'testcommit3307' of github.com:jantman/gitpython_issue_301 +31a5e48d89b42597522c0fe27200b9a99275b640 not-for-merge branch 'testcommit3308' of github.com:jantman/gitpython_issue_301 +5e0ac7942db0d0d09cd2591d9ced7ac5044a3919 not-for-merge branch 'testcommit3309' of github.com:jantman/gitpython_issue_301 +a9d4134d9f50a1f7a7d7be925b819b6a2c8971ec not-for-merge branch 'testcommit331' of github.com:jantman/gitpython_issue_301 +5c8a9b4e0fa3dedb28a291f60f7b38dcd7ed66b6 not-for-merge branch 'testcommit3310' of github.com:jantman/gitpython_issue_301 +36bb1cb9046c6b76b890093c2244f6a91e8d23c3 not-for-merge branch 'testcommit3311' of github.com:jantman/gitpython_issue_301 +91810190fa163aa1b21b63dc2396ea55cf69b7a0 not-for-merge branch 'testcommit3312' of github.com:jantman/gitpython_issue_301 +986f6a24a837d98e84701429fd5a4d83956575cb not-for-merge branch 'testcommit3313' of github.com:jantman/gitpython_issue_301 +e52637b386dcee608b076fca97573d918183b3fd not-for-merge branch 'testcommit3314' of github.com:jantman/gitpython_issue_301 +f138b7809521cf9d64c7c0542adf3797f1cc8054 not-for-merge branch 'testcommit3315' of github.com:jantman/gitpython_issue_301 +ac7d8631567db9ca16b4aeca4bc345f610d45a2b not-for-merge branch 'testcommit3316' of github.com:jantman/gitpython_issue_301 +e2980145baed2200ddc1b599fc872995c59cbb05 not-for-merge branch 'testcommit3317' of github.com:jantman/gitpython_issue_301 +62f39a280ec4833cdc2e5cae8d24568cc4093eb1 not-for-merge branch 'testcommit3318' of github.com:jantman/gitpython_issue_301 +7c6f8d06b83bb1ffc80bb2508fd666dfd66ee2c5 not-for-merge branch 'testcommit3319' of github.com:jantman/gitpython_issue_301 +3d8648ce5f49b70a9c12e6be2e4c60cfcb75b057 not-for-merge branch 'testcommit332' of github.com:jantman/gitpython_issue_301 +946482e320278b065520711f8eeb940b069de44f not-for-merge branch 'testcommit3320' of github.com:jantman/gitpython_issue_301 +9294586a50aeedde770548653893972f7c805876 not-for-merge branch 'testcommit3321' of github.com:jantman/gitpython_issue_301 +1aba242a003088dd227afb74b82aed226bf9d26e not-for-merge branch 'testcommit3322' of github.com:jantman/gitpython_issue_301 +94aacd8ef48fcef25b90996937e46789a3dad2ce not-for-merge branch 'testcommit3323' of github.com:jantman/gitpython_issue_301 +825ab29c69a261a9c489478a396d387f9e8c3710 not-for-merge branch 'testcommit3324' of github.com:jantman/gitpython_issue_301 +9a6412c075cb48eef05a91f986ba8d51badbe42e not-for-merge branch 'testcommit3325' of github.com:jantman/gitpython_issue_301 +55762348856e4a4a66a633c08741603efc0dde3d not-for-merge branch 'testcommit3326' of github.com:jantman/gitpython_issue_301 +2be3069f58f6a5226baac4e5c9a091531ede8eac not-for-merge branch 'testcommit3327' of github.com:jantman/gitpython_issue_301 +1cc0930dceccc43dc51f5aac86d77369c6b62282 not-for-merge branch 'testcommit3328' of github.com:jantman/gitpython_issue_301 +039c7dbdda87bffdcad46ddbcde46e3908897f28 not-for-merge branch 'testcommit3329' of github.com:jantman/gitpython_issue_301 +6ceed68e94402cbe03e44a64e23b5b1f7acc4dc7 not-for-merge branch 'testcommit333' of github.com:jantman/gitpython_issue_301 +4213278301388bc0936bb72acdd433b17a4df60a not-for-merge branch 'testcommit3330' of github.com:jantman/gitpython_issue_301 +bb73dce2283d75d232f5882018d4fc0f90022f0f not-for-merge branch 'testcommit3331' of github.com:jantman/gitpython_issue_301 +9b725dd358f75df945b80a42474907fc19722024 not-for-merge branch 'testcommit3332' of github.com:jantman/gitpython_issue_301 +15e14bf1ffae08b1ffe64f36e2d46631f4690eb7 not-for-merge branch 'testcommit3333' of github.com:jantman/gitpython_issue_301 +8b5a12689adaeb5f2dd6b00fb70a3bfe5f8c0844 not-for-merge branch 'testcommit3334' of github.com:jantman/gitpython_issue_301 +ce611933cdf5ec62f00ce4baad38fc09961e8b9f not-for-merge branch 'testcommit3335' of github.com:jantman/gitpython_issue_301 +81d8dc8b548705cc0f3606a84fdf14a0dac63128 not-for-merge branch 'testcommit3336' of github.com:jantman/gitpython_issue_301 +b20684df50c703290c75a21b324d2efac1558814 not-for-merge branch 'testcommit3337' of github.com:jantman/gitpython_issue_301 +70ea09fb20c0fd6c6d6941285a5c156b159c0824 not-for-merge branch 'testcommit3338' of github.com:jantman/gitpython_issue_301 +154333cadcfe91e20d000ef8b4bd1c97ac8bcfe2 not-for-merge branch 'testcommit3339' of github.com:jantman/gitpython_issue_301 +ab6bfc48b9ed488da6461b5cd8b04b997da74b95 not-for-merge branch 'testcommit334' of github.com:jantman/gitpython_issue_301 +28d7870c610f6c2c2145497709522bc654393fe6 not-for-merge branch 'testcommit3340' of github.com:jantman/gitpython_issue_301 +d3841bee6760ed1696b236b47191caf3b4e8b344 not-for-merge branch 'testcommit3341' of github.com:jantman/gitpython_issue_301 +3cc9d0288790905f41b57139c2bbfffa64d97e44 not-for-merge branch 'testcommit3342' of github.com:jantman/gitpython_issue_301 +8fbccb2d7ecd7e11ccf342fea8e27de777b0a903 not-for-merge branch 'testcommit3343' of github.com:jantman/gitpython_issue_301 +4a5f0672ec9648b98833e91cdc8725a275ac6661 not-for-merge branch 'testcommit3344' of github.com:jantman/gitpython_issue_301 +ffb3634f7fa1e1e2e9c562b18be8865ab7f03139 not-for-merge branch 'testcommit3345' of github.com:jantman/gitpython_issue_301 +d91132b0ae947f7fae525a7e637054bef0024cd0 not-for-merge branch 'testcommit3346' of github.com:jantman/gitpython_issue_301 +6e7eba060ee5ab899d193f04889623cc0eff30cf not-for-merge branch 'testcommit3347' of github.com:jantman/gitpython_issue_301 +8e1992ca02f4f68968d2c4947fb4917ee721652c not-for-merge branch 'testcommit3348' of github.com:jantman/gitpython_issue_301 +925b5d68c0ec38ad65baaf90bbff53f0582b4e80 not-for-merge branch 'testcommit3349' of github.com:jantman/gitpython_issue_301 +434abe11e0936987ce440355dc6324a08cf4d104 not-for-merge branch 'testcommit335' of github.com:jantman/gitpython_issue_301 +cb31cf3528f4c946cb7977779fc06d2a6a3629c8 not-for-merge branch 'testcommit3350' of github.com:jantman/gitpython_issue_301 +7a51cd000169534975d03d5c49e2a487a98dde0b not-for-merge branch 'testcommit3351' of github.com:jantman/gitpython_issue_301 +dfa6520df0f4d15150d6f9ffa1dca38e7a6aeba7 not-for-merge branch 'testcommit3352' of github.com:jantman/gitpython_issue_301 +e04d102dcbee3526a603df8ab95906e554ab522f not-for-merge branch 'testcommit3353' of github.com:jantman/gitpython_issue_301 +c76a4c228b3c178dc270e945cde1ae89809f8c55 not-for-merge branch 'testcommit3354' of github.com:jantman/gitpython_issue_301 +2af949d68c0738594a438c037b84b1c2035142fd not-for-merge branch 'testcommit3355' of github.com:jantman/gitpython_issue_301 +2c10394e344dd4e48e1d600775725a6346253363 not-for-merge branch 'testcommit3356' of github.com:jantman/gitpython_issue_301 +a974dd0d10b67f978f0857ae4b328769c099754e not-for-merge branch 'testcommit3357' of github.com:jantman/gitpython_issue_301 +bcecf7ff289e1800db0dc3c332a64010b6978881 not-for-merge branch 'testcommit3358' of github.com:jantman/gitpython_issue_301 +0bce5bef637a161e93af097fe2703f494a6f813f not-for-merge branch 'testcommit3359' of github.com:jantman/gitpython_issue_301 +f1d5468a0e1d643ba6be89c72b13227e991d9e10 not-for-merge branch 'testcommit336' of github.com:jantman/gitpython_issue_301 +0b5074d1e238d6aff8ccbbbaee36bf2046885a29 not-for-merge branch 'testcommit3360' of github.com:jantman/gitpython_issue_301 +9cef3996c623f5454dc7fb9c5593766d681184bd not-for-merge branch 'testcommit3361' of github.com:jantman/gitpython_issue_301 +c0b9561d6025f6600b2fdb20e970a03fd8b0d7cb not-for-merge branch 'testcommit3362' of github.com:jantman/gitpython_issue_301 +b48c5f0157d9c11cc6b6683d7330029737036749 not-for-merge branch 'testcommit3363' of github.com:jantman/gitpython_issue_301 +0be69ca5f50d1986c8d182feef4f79b705ede481 not-for-merge branch 'testcommit3364' of github.com:jantman/gitpython_issue_301 +c6c20ec3c7bfca20d52aab382d7e7b177b7b93c5 not-for-merge branch 'testcommit3365' of github.com:jantman/gitpython_issue_301 +de77e6ca89c05e2ab0bdb3d2492d55c20cd3f2b7 not-for-merge branch 'testcommit3366' of github.com:jantman/gitpython_issue_301 +05d83fb014b7299a0ba2f0447d885f1129aa022b not-for-merge branch 'testcommit3367' of github.com:jantman/gitpython_issue_301 +8e22cffe3cb99b7c63afa9d1a60e785f85be634b not-for-merge branch 'testcommit3368' of github.com:jantman/gitpython_issue_301 +ba4d02428db5811112907a82a4eebca65be2fb17 not-for-merge branch 'testcommit3369' of github.com:jantman/gitpython_issue_301 +2d439c55c4c22d826686181fcbd938baf70092e4 not-for-merge branch 'testcommit337' of github.com:jantman/gitpython_issue_301 +747039611c0041bf04248e8dc8f3ec23137026fb not-for-merge branch 'testcommit3370' of github.com:jantman/gitpython_issue_301 +5f5e4eb055c477e3ba5c0c5da9c0fa1f46f5a016 not-for-merge branch 'testcommit3371' of github.com:jantman/gitpython_issue_301 +b826cf9dd50dd4bbadf895d64aecaa49aecfa8e7 not-for-merge branch 'testcommit3372' of github.com:jantman/gitpython_issue_301 +9488b06d0640e71332b5dadd5a237362a59d7e39 not-for-merge branch 'testcommit3373' of github.com:jantman/gitpython_issue_301 +2d2d1d6a467f0ac53296575f0f2243db1308ab43 not-for-merge branch 'testcommit3374' of github.com:jantman/gitpython_issue_301 +8580b605fdf472e80686491ade9213e7b6a625de not-for-merge branch 'testcommit3375' of github.com:jantman/gitpython_issue_301 +dcea3b0069f0e242db0b578628cdadd2629e5876 not-for-merge branch 'testcommit3376' of github.com:jantman/gitpython_issue_301 +6537e6bc8a1436a1a71ff7a4ddf8968a921eadde not-for-merge branch 'testcommit3377' of github.com:jantman/gitpython_issue_301 +83cfb0d38b3ab7cca1c22bd583267015647fe135 not-for-merge branch 'testcommit3378' of github.com:jantman/gitpython_issue_301 +d8d0ac9c4a1e65c15a263fb39dcfdc983f36dab2 not-for-merge branch 'testcommit3379' of github.com:jantman/gitpython_issue_301 +57005aea40208410c66df59fe9306dae0f6eb8e5 not-for-merge branch 'testcommit338' of github.com:jantman/gitpython_issue_301 +7fbe6ebab09acbda2d91cf80be657c7b11640c20 not-for-merge branch 'testcommit3380' of github.com:jantman/gitpython_issue_301 +853fdb2adfa55da166965c42f006c007c776a618 not-for-merge branch 'testcommit3381' of github.com:jantman/gitpython_issue_301 +77214fc5e42b2619decde7a47a9861c15964865b not-for-merge branch 'testcommit3382' of github.com:jantman/gitpython_issue_301 +59b7efdd7923aab63b2643531416ba9d241ca174 not-for-merge branch 'testcommit3383' of github.com:jantman/gitpython_issue_301 +011a81621798696da93d7a940567db67ff1131a4 not-for-merge branch 'testcommit3384' of github.com:jantman/gitpython_issue_301 +d5f8ab0bcca99ce74444fb7f5d0dd0a6cc77f3df not-for-merge branch 'testcommit3385' of github.com:jantman/gitpython_issue_301 +72bccd4eaa5a43665edca88ff7c275e27b49cfd5 not-for-merge branch 'testcommit3386' of github.com:jantman/gitpython_issue_301 +67ea152da6a589f5e1c508162825a24fe06f07a5 not-for-merge branch 'testcommit3387' of github.com:jantman/gitpython_issue_301 +c2f2b9a19ec3b6cac5441aa5e26524bb0afb4b24 not-for-merge branch 'testcommit3388' of github.com:jantman/gitpython_issue_301 +c945f8bb77b727ef2fd8d79c4932c9f7c1fe64c5 not-for-merge branch 'testcommit3389' of github.com:jantman/gitpython_issue_301 +b0f2cd0f6012d9b14eeb4a3b4959ac8e9d9e433e not-for-merge branch 'testcommit339' of github.com:jantman/gitpython_issue_301 +06c11f8dbfb7668b406eddba432587ec58bf4c89 not-for-merge branch 'testcommit3390' of github.com:jantman/gitpython_issue_301 +4de93bf7ca8a0fa7009403dfc5e861e1ed172f99 not-for-merge branch 'testcommit3391' of github.com:jantman/gitpython_issue_301 +cc22bbe59708d87597ca6013ec74348937352225 not-for-merge branch 'testcommit3392' of github.com:jantman/gitpython_issue_301 +b7dfd3d3eb9f9d73528cfb0bfc9581f6637d609b not-for-merge branch 'testcommit3393' of github.com:jantman/gitpython_issue_301 +4d41e0c56c4432e5bfd55219e6fbee5a6097507b not-for-merge branch 'testcommit3394' of github.com:jantman/gitpython_issue_301 +79b2c50ad9b99d1ccc36a5f25c68f8ffd5294514 not-for-merge branch 'testcommit3395' of github.com:jantman/gitpython_issue_301 +ef6d2d6cbbb5cb4f684a770fe5346f67d16c7484 not-for-merge branch 'testcommit3396' of github.com:jantman/gitpython_issue_301 +34edadf4847c1d0a41f32baad2b01f9d25f3c6d7 not-for-merge branch 'testcommit3397' of github.com:jantman/gitpython_issue_301 +0462689329222656c97e15a87dd92708d1157765 not-for-merge branch 'testcommit3398' of github.com:jantman/gitpython_issue_301 +998cbec7f04fbc33e2dcd7b0ebbed1c632fa1af9 not-for-merge branch 'testcommit3399' of github.com:jantman/gitpython_issue_301 +fa391b6aea1cd11d71a77c0e30b6fa52b74fcbba not-for-merge branch 'testcommit34' of github.com:jantman/gitpython_issue_301 +97f003d39df2ee02070fed09b02977cea61f3886 not-for-merge branch 'testcommit340' of github.com:jantman/gitpython_issue_301 +2791a05cb53972c73aa0f9e22aa19c5ecbf2850b not-for-merge branch 'testcommit3400' of github.com:jantman/gitpython_issue_301 +843a0d0c2289481780ebc1c46f55d0458e1f1ed4 not-for-merge branch 'testcommit3401' of github.com:jantman/gitpython_issue_301 +b3a8f90be64d7fad685469f6105b8514f400f965 not-for-merge branch 'testcommit3402' of github.com:jantman/gitpython_issue_301 +e9461779adc6d842192f523be3fd448ff8658ef0 not-for-merge branch 'testcommit3403' of github.com:jantman/gitpython_issue_301 +6b35a64d5faaabbeb6ad4e777bff13086347bc75 not-for-merge branch 'testcommit3404' of github.com:jantman/gitpython_issue_301 +fac007c21a114c0edf50d3b07155c69ebc7dc8ac not-for-merge branch 'testcommit3405' of github.com:jantman/gitpython_issue_301 +5ae82dbc5460838f9963a0560f11e503d409c156 not-for-merge branch 'testcommit3406' of github.com:jantman/gitpython_issue_301 +a451d1a379978f0099b114002dabe2df9d2cd238 not-for-merge branch 'testcommit3407' of github.com:jantman/gitpython_issue_301 +c28feb1e0742c0e1d5057a7de5fa294cad0f3315 not-for-merge branch 'testcommit3408' of github.com:jantman/gitpython_issue_301 +3be92caf3be3ea94695b71d44b62352b1b71fb22 not-for-merge branch 'testcommit3409' of github.com:jantman/gitpython_issue_301 +b8bca81fbbb92e13d9229f7203721ccf1cf6a3e5 not-for-merge branch 'testcommit341' of github.com:jantman/gitpython_issue_301 +0bee4cb69df1b686192fb5679b25d8eff2ae5f7f not-for-merge branch 'testcommit3410' of github.com:jantman/gitpython_issue_301 +b5beb53b21c008d5ab0018dd0e794337190e706a not-for-merge branch 'testcommit3411' of github.com:jantman/gitpython_issue_301 +9ef57a524c00fa4967a55a99c77240607968fb2d not-for-merge branch 'testcommit3412' of github.com:jantman/gitpython_issue_301 +e347c421e5f9ab7cf7a623eec2f8d18e456f7a62 not-for-merge branch 'testcommit3413' of github.com:jantman/gitpython_issue_301 +3b3d71282323712ef2f154bc6e0d05b83ce6923f not-for-merge branch 'testcommit3414' of github.com:jantman/gitpython_issue_301 +746cbc7753a923f31657817ac3789228bf872418 not-for-merge branch 'testcommit3415' of github.com:jantman/gitpython_issue_301 +3b9dd7a3965310d1cbc4d264223880b6a3191f6c not-for-merge branch 'testcommit3416' of github.com:jantman/gitpython_issue_301 +a74afd35f1263f4afe05e5fbdc85fe98fc7a79a8 not-for-merge branch 'testcommit3417' of github.com:jantman/gitpython_issue_301 +3df24b48b31fa187114dd70b5bfccc5daee8c1d4 not-for-merge branch 'testcommit3418' of github.com:jantman/gitpython_issue_301 +6438dbd340bd8fb38bfb366b37d42edf7968dfe0 not-for-merge branch 'testcommit3419' of github.com:jantman/gitpython_issue_301 +d64fec53cb5ecf98922655d99951dc66bdad16dc not-for-merge branch 'testcommit342' of github.com:jantman/gitpython_issue_301 +d0461058eaadaa3b78009589af4b6d1fde9e47fc not-for-merge branch 'testcommit3420' of github.com:jantman/gitpython_issue_301 +b68955077a0da44f25f8278a7265f980f53d05aa not-for-merge branch 'testcommit3421' of github.com:jantman/gitpython_issue_301 +5d0504ea9db4406b698ff8dbb9501b8c528ca503 not-for-merge branch 'testcommit3422' of github.com:jantman/gitpython_issue_301 +158aca170ed308f13597b201585a929bbe941050 not-for-merge branch 'testcommit3423' of github.com:jantman/gitpython_issue_301 +9f25164eae86e2fd6503f170dbe565f2aa10faa8 not-for-merge branch 'testcommit3424' of github.com:jantman/gitpython_issue_301 +8076cac738e8ee62a5b91aa3167681872b8567f5 not-for-merge branch 'testcommit3425' of github.com:jantman/gitpython_issue_301 +f853aa650a5b892b937adb40ecec4af510e4dbd9 not-for-merge branch 'testcommit3426' of github.com:jantman/gitpython_issue_301 +5ef91b23926bab823fb8e7a03434d67f950f1ded not-for-merge branch 'testcommit3427' of github.com:jantman/gitpython_issue_301 +55c2866bbf9c7f931bf7759f260800bf51bd56ca not-for-merge branch 'testcommit3428' of github.com:jantman/gitpython_issue_301 +688a109516e9f5cd91baea1bfea953900865185b not-for-merge branch 'testcommit3429' of github.com:jantman/gitpython_issue_301 +4ed449ee5d10398fe17f1bd3d3f85defbed38d59 not-for-merge branch 'testcommit343' of github.com:jantman/gitpython_issue_301 +7cf4ae4fb14a8405de93e8242e6c0dcabde99d44 not-for-merge branch 'testcommit3430' of github.com:jantman/gitpython_issue_301 +0f894f8294c2da571c163ce99db83f5b7304b6ff not-for-merge branch 'testcommit3431' of github.com:jantman/gitpython_issue_301 +0f502eab9ebc54b81426e7dd64e6ecec7ee3e7cd not-for-merge branch 'testcommit3432' of github.com:jantman/gitpython_issue_301 +b1c60aad57f85c182c97d0b0eb4fda1c4aa248aa not-for-merge branch 'testcommit3433' of github.com:jantman/gitpython_issue_301 +0c93b5b502add319e3c95b29cd9f3bd1f794d1ce not-for-merge branch 'testcommit3434' of github.com:jantman/gitpython_issue_301 +fbf492146d79c8ce03ba2bc383ea00c538f2c0d5 not-for-merge branch 'testcommit3435' of github.com:jantman/gitpython_issue_301 +703ab63cdd9f3e7c49a1128b5455b470a78994ce not-for-merge branch 'testcommit3436' of github.com:jantman/gitpython_issue_301 +ab52f85abbb192f7f9769491693f6d9c45a3b9f6 not-for-merge branch 'testcommit3437' of github.com:jantman/gitpython_issue_301 +5237e2e4673b1acb6ed703202f31582d22412a11 not-for-merge branch 'testcommit3438' of github.com:jantman/gitpython_issue_301 +f7b823ff6b581462f1b344a73069359bbd8b25e5 not-for-merge branch 'testcommit3439' of github.com:jantman/gitpython_issue_301 +1f03c0694248b34d12e5e6d69bfcfbd4845fdfd6 not-for-merge branch 'testcommit344' of github.com:jantman/gitpython_issue_301 +a8f6141dd239d02d4beae605a202398f1cd70492 not-for-merge branch 'testcommit3440' of github.com:jantman/gitpython_issue_301 +385c325a6d704def0585018013f13c8f650e95ad not-for-merge branch 'testcommit3441' of github.com:jantman/gitpython_issue_301 +c6726342266cdf7b380e13892c3e1bd7655ddb0d not-for-merge branch 'testcommit3442' of github.com:jantman/gitpython_issue_301 +6cb1e00a6053c6c8c17d4fcbf2fc1c1693fe6d30 not-for-merge branch 'testcommit3443' of github.com:jantman/gitpython_issue_301 +484a0b2b2d6dce16747a05ceb859a4fca7b521ce not-for-merge branch 'testcommit3444' of github.com:jantman/gitpython_issue_301 +d5dc0f235d3ad6a88b751f0da86017806ee255a5 not-for-merge branch 'testcommit3445' of github.com:jantman/gitpython_issue_301 +5dbf63d32c6beb7b38b32b925201ab8527b03418 not-for-merge branch 'testcommit3446' of github.com:jantman/gitpython_issue_301 +6b28def3de118e15d14d0943f617a84a026a137b not-for-merge branch 'testcommit3447' of github.com:jantman/gitpython_issue_301 +6489ad5b9a9c681ecc8c62c46cd0b8a331d47027 not-for-merge branch 'testcommit3448' of github.com:jantman/gitpython_issue_301 +67640817a7b89e35579b08a179e401db33452f6a not-for-merge branch 'testcommit3449' of github.com:jantman/gitpython_issue_301 +d3a0b3d489f6c1ff7a94c53d1715c184d8996a8b not-for-merge branch 'testcommit345' of github.com:jantman/gitpython_issue_301 +fcb2b5541b19891ba474c8c6f5e935a9b62a9002 not-for-merge branch 'testcommit3450' of github.com:jantman/gitpython_issue_301 +f62907a580fb0ac7c7cd9828f0c7e941999a29e7 not-for-merge branch 'testcommit3451' of github.com:jantman/gitpython_issue_301 +b2f69e2c9ea5ec8324442760eda25a7266ed97e7 not-for-merge branch 'testcommit3452' of github.com:jantman/gitpython_issue_301 +6034f14e4687c46bc9b1a30ded493d7bacc7dadd not-for-merge branch 'testcommit3453' of github.com:jantman/gitpython_issue_301 +2db35b6fafda5ef30b548eb7d289d58f86cae0bd not-for-merge branch 'testcommit3454' of github.com:jantman/gitpython_issue_301 +cdf8078bd5330b387400db4e6d1fd6107cbe5dac not-for-merge branch 'testcommit3455' of github.com:jantman/gitpython_issue_301 +08fbd0f723c850b32e7b223ac0443c2b6e8be2bc not-for-merge branch 'testcommit3456' of github.com:jantman/gitpython_issue_301 +7ad45d4d2d2b285024cff6401d04d98da1fcb8d2 not-for-merge branch 'testcommit3457' of github.com:jantman/gitpython_issue_301 +56557fde01a928159b9770f90b926d013943d4eb not-for-merge branch 'testcommit3458' of github.com:jantman/gitpython_issue_301 +ddffb641c0b9658f724c441ac0df513b0169ba13 not-for-merge branch 'testcommit3459' of github.com:jantman/gitpython_issue_301 +631da8acae5866f6e3b89fe93e8b76b6c08604c2 not-for-merge branch 'testcommit346' of github.com:jantman/gitpython_issue_301 +c823a563b8d6c416cf0afb3ef42b944c8d6273c3 not-for-merge branch 'testcommit3460' of github.com:jantman/gitpython_issue_301 +6f091766af383c9605f526497b330dfca3e05913 not-for-merge branch 'testcommit3461' of github.com:jantman/gitpython_issue_301 +d26efed758a860cf54d36b61542d2722c23c3b8f not-for-merge branch 'testcommit3462' of github.com:jantman/gitpython_issue_301 +1ec65a1e7fed2d9ab7573416ab103f0ae3c6b919 not-for-merge branch 'testcommit3463' of github.com:jantman/gitpython_issue_301 +70b73e9cdb060d0bed9e454b42edba816f7271c0 not-for-merge branch 'testcommit3464' of github.com:jantman/gitpython_issue_301 +25ab7e388a6e5719a13382fab11f211932c53848 not-for-merge branch 'testcommit3465' of github.com:jantman/gitpython_issue_301 +bf26f1783b8cde40110729def5c9a4d31dc0932c not-for-merge branch 'testcommit3466' of github.com:jantman/gitpython_issue_301 +6bad86cb8dc119d801957cad71289cdd7462f7a6 not-for-merge branch 'testcommit3467' of github.com:jantman/gitpython_issue_301 +95df4264212b46e3d987e7ea043ce4aea453a0cc not-for-merge branch 'testcommit3468' of github.com:jantman/gitpython_issue_301 +da501c449073fea4f196839d9c38f93dd96439b1 not-for-merge branch 'testcommit3469' of github.com:jantman/gitpython_issue_301 +3fc1e2d1419ee7137f0a909f728e3c8b89045fbb not-for-merge branch 'testcommit347' of github.com:jantman/gitpython_issue_301 +57b844d9637cecf7adc14cfce93fc792cab14216 not-for-merge branch 'testcommit3470' of github.com:jantman/gitpython_issue_301 +9c375dc219edecda376f30b01158783a5739d65b not-for-merge branch 'testcommit3471' of github.com:jantman/gitpython_issue_301 +57e22e6e408f74b3ae1a14a16b411821bebb8de7 not-for-merge branch 'testcommit3472' of github.com:jantman/gitpython_issue_301 +e6c0495e2c0956fa5c8f57793bfa0b69f1622352 not-for-merge branch 'testcommit3473' of github.com:jantman/gitpython_issue_301 +1863058c4529b1f84f8ee806a1ddcbd234be0040 not-for-merge branch 'testcommit3474' of github.com:jantman/gitpython_issue_301 +f2583decabf7848abc622306062baad1e7179c78 not-for-merge branch 'testcommit3475' of github.com:jantman/gitpython_issue_301 +00454eb51b614bcb7afe2408aee22a73c2f3e749 not-for-merge branch 'testcommit3476' of github.com:jantman/gitpython_issue_301 +be00589e21fe7ff8249faf65a313141d40f33893 not-for-merge branch 'testcommit3477' of github.com:jantman/gitpython_issue_301 +fa79d444fa173109f14c2fe25e731491768eed6b not-for-merge branch 'testcommit3478' of github.com:jantman/gitpython_issue_301 +b88a29ec867a166d4976d0b3705e5c1ca4399ca0 not-for-merge branch 'testcommit3479' of github.com:jantman/gitpython_issue_301 +3ba2f4b9d05c69fca7c387032ca63fb054fd1bd6 not-for-merge branch 'testcommit348' of github.com:jantman/gitpython_issue_301 +ee0ed69085d7b10ea4ad9fc7e7f5b583dc5f2e4c not-for-merge branch 'testcommit3480' of github.com:jantman/gitpython_issue_301 +3fcefa715674bc64fb36bd46675e8121fb135db3 not-for-merge branch 'testcommit3481' of github.com:jantman/gitpython_issue_301 +614cb228b296231bf60d58c519019765530d0271 not-for-merge branch 'testcommit3482' of github.com:jantman/gitpython_issue_301 +9cf4c7aeb3f83d1202294967208c55f9ea6af044 not-for-merge branch 'testcommit3483' of github.com:jantman/gitpython_issue_301 +fa65c6bba6c8a05e84ac3951e1aac4e72e5fa016 not-for-merge branch 'testcommit3484' of github.com:jantman/gitpython_issue_301 +e745e02b111d49f74471fce73f243bbbf52dd1c6 not-for-merge branch 'testcommit3485' of github.com:jantman/gitpython_issue_301 +ea7cd5a3cf4334c2289196795890a14398e0477e not-for-merge branch 'testcommit3486' of github.com:jantman/gitpython_issue_301 +2d1f242553e19906dff767220122e8e9e5941763 not-for-merge branch 'testcommit3487' of github.com:jantman/gitpython_issue_301 +b53e599df2dc5cda61f8d4e1af351db3cb75d811 not-for-merge branch 'testcommit3488' of github.com:jantman/gitpython_issue_301 +f0c42010514060dbe25194ddbc1c0a3644d76cc4 not-for-merge branch 'testcommit3489' of github.com:jantman/gitpython_issue_301 +88735d17b4989726ef49e90cbed6f22977dcadcc not-for-merge branch 'testcommit349' of github.com:jantman/gitpython_issue_301 +3cf6b5612b4f1dc5ccafa09082c20168695bc3a2 not-for-merge branch 'testcommit3490' of github.com:jantman/gitpython_issue_301 +42616fd47140bd61d6246cd1debfc24b679a321c not-for-merge branch 'testcommit3491' of github.com:jantman/gitpython_issue_301 +a30568dd9c59ec0545997b7625ccd868bab07e66 not-for-merge branch 'testcommit3492' of github.com:jantman/gitpython_issue_301 +f0f1f6456c400daf2d475b6d813562b88ffe3ff1 not-for-merge branch 'testcommit3493' of github.com:jantman/gitpython_issue_301 +3b0af110283f73fe1448768351d3267c05bf76cb not-for-merge branch 'testcommit3494' of github.com:jantman/gitpython_issue_301 +7eeb7e5cbbe0615c5971328f03330bf9738bb1d0 not-for-merge branch 'testcommit3495' of github.com:jantman/gitpython_issue_301 +edd4dd54930378ea6c37ff503dc7efad30086168 not-for-merge branch 'testcommit3496' of github.com:jantman/gitpython_issue_301 +eeffe1007d813ce84269647a2a8ca367f8068a6f not-for-merge branch 'testcommit3497' of github.com:jantman/gitpython_issue_301 +3f7e1c6313b132f272409974fca1f7ef111e5446 not-for-merge branch 'testcommit3498' of github.com:jantman/gitpython_issue_301 +c1a3da32691b85021afc85d9cd69cde91fbcf82d not-for-merge branch 'testcommit3499' of github.com:jantman/gitpython_issue_301 +2681351a6497e85d8f2faadc826f9c358c3e633e not-for-merge branch 'testcommit35' of github.com:jantman/gitpython_issue_301 +45faf96948c2f556bd8fae5df9115cb630dd1515 not-for-merge branch 'testcommit350' of github.com:jantman/gitpython_issue_301 +079c9a08bafbc4822f2b1561bb06d194529b936f not-for-merge branch 'testcommit3500' of github.com:jantman/gitpython_issue_301 +d746f5b0e2a7f18b1e192759c879450c984a5092 not-for-merge branch 'testcommit3501' of github.com:jantman/gitpython_issue_301 +b3e4de99100c120fead11d5b33a6b9ba301c85ab not-for-merge branch 'testcommit3502' of github.com:jantman/gitpython_issue_301 +47532933369d97709fb3c2e1ba18dcd56e3c62bc not-for-merge branch 'testcommit3503' of github.com:jantman/gitpython_issue_301 +1a6570f4b197f9869a96a18eeba066b7ef8a6654 not-for-merge branch 'testcommit3504' of github.com:jantman/gitpython_issue_301 +35bffeef6f9aa1f40d5c1faf88351758bd512cef not-for-merge branch 'testcommit3505' of github.com:jantman/gitpython_issue_301 +7980882c0c609ef038aa58be3b99ba4eb2d2c58c not-for-merge branch 'testcommit3506' of github.com:jantman/gitpython_issue_301 +7ac26c5ebd47326a347d5d01d9362747d00d5043 not-for-merge branch 'testcommit3507' of github.com:jantman/gitpython_issue_301 +0c9456cd2b773aa005e6119aff2947144c0781c5 not-for-merge branch 'testcommit3508' of github.com:jantman/gitpython_issue_301 +92424f64313cafa5e9e62bb04ba76c53dec756ff not-for-merge branch 'testcommit3509' of github.com:jantman/gitpython_issue_301 +51048d8afebb5d3508845596972ff9eee4999598 not-for-merge branch 'testcommit351' of github.com:jantman/gitpython_issue_301 +8b6b28ed471800a9f32c009cd4cfb9bc7f75073b not-for-merge branch 'testcommit3510' of github.com:jantman/gitpython_issue_301 +b9b7739fb90dbbfa00aa8a55c3846c3e2dfd069c not-for-merge branch 'testcommit3511' of github.com:jantman/gitpython_issue_301 +49e0b1f8408dcc2597f63cbb37b87d51b4db208d not-for-merge branch 'testcommit3512' of github.com:jantman/gitpython_issue_301 +5d479a69e5efcb9656745a5fa63e0feb194dc15d not-for-merge branch 'testcommit3513' of github.com:jantman/gitpython_issue_301 +df00298ae610a7b7efc82490b272ba3732cf157d not-for-merge branch 'testcommit3514' of github.com:jantman/gitpython_issue_301 +c6c509fba53095de43d48a5693c63b7390f44fb8 not-for-merge branch 'testcommit3515' of github.com:jantman/gitpython_issue_301 +73cfb7086291fa3be981aefd35ea67ddbe54d992 not-for-merge branch 'testcommit3516' of github.com:jantman/gitpython_issue_301 +479587c484bbcbbdf9833ef4ce4ec67d6dc65196 not-for-merge branch 'testcommit3517' of github.com:jantman/gitpython_issue_301 +4d65b2edd3841bbde7a455e76e60a1c85be48f77 not-for-merge branch 'testcommit3518' of github.com:jantman/gitpython_issue_301 +6526cde0de53de4cc5bc7df1f0e2e2ff2768b2c5 not-for-merge branch 'testcommit3519' of github.com:jantman/gitpython_issue_301 +e7b2ccfa40700cf4983a7d77d3a3cc447b431e8c not-for-merge branch 'testcommit352' of github.com:jantman/gitpython_issue_301 +b8bc685dd7cb2d5665f936043e3b7dd8f4d44ebb not-for-merge branch 'testcommit3520' of github.com:jantman/gitpython_issue_301 +23645cd4ce9f5a03a5ce733bf051e068e0c38eb4 not-for-merge branch 'testcommit3521' of github.com:jantman/gitpython_issue_301 +05b1fcc8e4d4a2f0a3d3ed2abef9edbd53796aa3 not-for-merge branch 'testcommit3522' of github.com:jantman/gitpython_issue_301 +df021eae381fa907e27aefb45257810496759ffc not-for-merge branch 'testcommit3523' of github.com:jantman/gitpython_issue_301 +54c8232e239919db025ee6b0d550055c9a2fe80d not-for-merge branch 'testcommit3524' of github.com:jantman/gitpython_issue_301 +275afaee7ce6a1645c2ca932c7bfd625b6fa4898 not-for-merge branch 'testcommit3525' of github.com:jantman/gitpython_issue_301 +61139fcd9b64ae9324188543824c7ec215b87f46 not-for-merge branch 'testcommit3526' of github.com:jantman/gitpython_issue_301 +95c1acf27cb92da36c8075ae099ad553b9cbf86d not-for-merge branch 'testcommit3527' of github.com:jantman/gitpython_issue_301 +2d8d625ae3a4c5a10c99fde1a49d6e2964f91009 not-for-merge branch 'testcommit3528' of github.com:jantman/gitpython_issue_301 +82e31be5f491bbc74e3b3825bbbc89cfd124d495 not-for-merge branch 'testcommit3529' of github.com:jantman/gitpython_issue_301 +725966a241e87f8328c2fa925eaf957a68dfc0e0 not-for-merge branch 'testcommit353' of github.com:jantman/gitpython_issue_301 +5d498b3d2ee20dd3a3ed342a30062f9aa0997055 not-for-merge branch 'testcommit3530' of github.com:jantman/gitpython_issue_301 +19b747c9be38c337fee1ee2585760434e624122a not-for-merge branch 'testcommit3531' of github.com:jantman/gitpython_issue_301 +eb013b79ff2a1569d8930f567b8e1377693ec65d not-for-merge branch 'testcommit3532' of github.com:jantman/gitpython_issue_301 +7f8b935d4978c052c910323cf2547781d8648e86 not-for-merge branch 'testcommit3533' of github.com:jantman/gitpython_issue_301 +ffeb2ec90095a218c19e7def99f4b78dcd116855 not-for-merge branch 'testcommit3534' of github.com:jantman/gitpython_issue_301 +f10048ce7b8afba418ee6ef9a93a02978d04d74c not-for-merge branch 'testcommit3535' of github.com:jantman/gitpython_issue_301 +baf270f4d916c6621b46021b2339b252fbdc96fb not-for-merge branch 'testcommit3536' of github.com:jantman/gitpython_issue_301 +0243d417c97a09636502eecda822bc931594af0d not-for-merge branch 'testcommit3537' of github.com:jantman/gitpython_issue_301 +31f133e50801705780dcbe0f8a863cf3029dbc1d not-for-merge branch 'testcommit3538' of github.com:jantman/gitpython_issue_301 +7d964cf9ab0412f51e866ca0f651da8f4618bb76 not-for-merge branch 'testcommit3539' of github.com:jantman/gitpython_issue_301 +1f56b7629b97f3da517bb1e5c75b74575da6992c not-for-merge branch 'testcommit354' of github.com:jantman/gitpython_issue_301 +64edeefeb1e61f9cea681aa4b183bb668deddc91 not-for-merge branch 'testcommit3540' of github.com:jantman/gitpython_issue_301 +82b26f277093bfbee3ecf77a0172741e65d1222c not-for-merge branch 'testcommit3541' of github.com:jantman/gitpython_issue_301 +04b9fc14688b04a63e71973b162eee495ee3e00a not-for-merge branch 'testcommit3542' of github.com:jantman/gitpython_issue_301 +1d1c0e284c4edeb6aa56bc385133bba660997899 not-for-merge branch 'testcommit3543' of github.com:jantman/gitpython_issue_301 +5f049e0207d0044a009dd4deb5720288edb8ab1d not-for-merge branch 'testcommit3544' of github.com:jantman/gitpython_issue_301 +40d72345b53b52e29af2901b7c3d37fb4a3a590e not-for-merge branch 'testcommit3545' of github.com:jantman/gitpython_issue_301 +0a6333776e18cce42fb15ea3780c9a1695905b8d not-for-merge branch 'testcommit3546' of github.com:jantman/gitpython_issue_301 +c38cbf54637540047cd8c9f1446fe68a76e8c6b5 not-for-merge branch 'testcommit3547' of github.com:jantman/gitpython_issue_301 +8bdd62c3f2a7cd12af7ef4c61d90eaf5109c415e not-for-merge branch 'testcommit3548' of github.com:jantman/gitpython_issue_301 +532b7053c7efe8c24e3cbb136d58a4eea7f5a25c not-for-merge branch 'testcommit3549' of github.com:jantman/gitpython_issue_301 +0a84bb17a563a2c507b14ccd3f243e4ff5bc5d13 not-for-merge branch 'testcommit355' of github.com:jantman/gitpython_issue_301 +7a11ec6604f61432aa55d1d885d7b08928277892 not-for-merge branch 'testcommit3550' of github.com:jantman/gitpython_issue_301 +9cf349c5488ac038205cb13fbf4bb2f4e3f474d6 not-for-merge branch 'testcommit3551' of github.com:jantman/gitpython_issue_301 +8858fd89e1e935cd894ab04f3e444e3ac27fa032 not-for-merge branch 'testcommit3552' of github.com:jantman/gitpython_issue_301 +05e5000a9eb7a7d0bc7584c6139f44eb5ada763b not-for-merge branch 'testcommit3553' of github.com:jantman/gitpython_issue_301 +ced3669c88984a8bf739f92dc2256654504be5ae not-for-merge branch 'testcommit3554' of github.com:jantman/gitpython_issue_301 +352c2c98b551f4bc11237b0bf46bf69f4514741f not-for-merge branch 'testcommit3555' of github.com:jantman/gitpython_issue_301 +aec581b02c582f40009891fa3e9df8a9b0de0d40 not-for-merge branch 'testcommit3556' of github.com:jantman/gitpython_issue_301 +7ad82f13ae3bad1d72a15246bcc3f576f142d8c1 not-for-merge branch 'testcommit3557' of github.com:jantman/gitpython_issue_301 +676b2ed5d545fb1e808ff86de32b20db4ce4a603 not-for-merge branch 'testcommit3558' of github.com:jantman/gitpython_issue_301 +d83d8b930677a2135f8a4e7ccd2106d9dd3149c4 not-for-merge branch 'testcommit3559' of github.com:jantman/gitpython_issue_301 +86c324fa6465a5e313a749859ff644f44701eec5 not-for-merge branch 'testcommit356' of github.com:jantman/gitpython_issue_301 +cfb89d42cf00b55d061d8037009591cb9fba7a26 not-for-merge branch 'testcommit3560' of github.com:jantman/gitpython_issue_301 +9cfadfee26e98c17a05a27817ae387698133a9f7 not-for-merge branch 'testcommit3561' of github.com:jantman/gitpython_issue_301 +cea8d3b7b23aaa4a311ddbc0a364cd314874332d not-for-merge branch 'testcommit3562' of github.com:jantman/gitpython_issue_301 +2a813ae608c43d32fb252ea6158c5d9e497811a2 not-for-merge branch 'testcommit3563' of github.com:jantman/gitpython_issue_301 +d3818e94bd6f27bf56c9397627d3c0a02654eb22 not-for-merge branch 'testcommit3564' of github.com:jantman/gitpython_issue_301 +643916b72d27d6be35e603147453bb4a5d0b0b01 not-for-merge branch 'testcommit3565' of github.com:jantman/gitpython_issue_301 +2e5a2da210d8abce34a5434b8c91debe9a6747db not-for-merge branch 'testcommit3566' of github.com:jantman/gitpython_issue_301 +e1e433a3de58cefd9c224ff7087180114c76529d not-for-merge branch 'testcommit3567' of github.com:jantman/gitpython_issue_301 +656b4ec04e932aba08bf02e39228b036bb9c44f5 not-for-merge branch 'testcommit3568' of github.com:jantman/gitpython_issue_301 +21156cc5345ef750c887373ccd3e11ba7c6bd7e2 not-for-merge branch 'testcommit3569' of github.com:jantman/gitpython_issue_301 +edfe6f21906e94f6aff3724e591367a150547e20 not-for-merge branch 'testcommit357' of github.com:jantman/gitpython_issue_301 +ccad2b0b944476f6361aa64f0087472b19ff1e91 not-for-merge branch 'testcommit3570' of github.com:jantman/gitpython_issue_301 +2625f1f5e7abe957ac8aaa4204b08d1c7a7a74c1 not-for-merge branch 'testcommit3571' of github.com:jantman/gitpython_issue_301 +1edebb9f39f2669a287aa2eae14d114cb0c507ac not-for-merge branch 'testcommit3572' of github.com:jantman/gitpython_issue_301 +9f1dfe442887ed1a390cad1797603d4a20f9a0f6 not-for-merge branch 'testcommit3573' of github.com:jantman/gitpython_issue_301 +0e673a904a1e4023cad5db412863538914c60b9a not-for-merge branch 'testcommit3574' of github.com:jantman/gitpython_issue_301 +b87bf111a69c54b3ce3a2bcb7f6e451cdabedd7f not-for-merge branch 'testcommit3575' of github.com:jantman/gitpython_issue_301 +48b627a3b6d1a6f8bb5a0f3cfaec7f2c887b8cf5 not-for-merge branch 'testcommit3576' of github.com:jantman/gitpython_issue_301 +7510719110d335b6902fbf5bdc80faf1a590cadb not-for-merge branch 'testcommit3577' of github.com:jantman/gitpython_issue_301 +9b629e8744d9dcdaef93b8c6747033e2526cb281 not-for-merge branch 'testcommit3578' of github.com:jantman/gitpython_issue_301 +6157835f6626affb326916331d0eb7f8adc1daca not-for-merge branch 'testcommit3579' of github.com:jantman/gitpython_issue_301 +0933e24600b075433d01e1dd081c05016700a3fd not-for-merge branch 'testcommit358' of github.com:jantman/gitpython_issue_301 +cc3ce4fccc43fb969b469a8551281dfcd781c47f not-for-merge branch 'testcommit3580' of github.com:jantman/gitpython_issue_301 +cd1e5538a28cdda20e163c2a5cea60b2c250d88e not-for-merge branch 'testcommit3581' of github.com:jantman/gitpython_issue_301 +deda6832e0afe4e09d2c310978e0325d6b3f8656 not-for-merge branch 'testcommit3582' of github.com:jantman/gitpython_issue_301 +37460240a1b5dc8867b54e5d5ace138a81b3bcee not-for-merge branch 'testcommit3583' of github.com:jantman/gitpython_issue_301 +de18d5071881b6fcf48409bf40874db34b226932 not-for-merge branch 'testcommit3584' of github.com:jantman/gitpython_issue_301 +b71e1079226649d17665471357f574a99283aaf1 not-for-merge branch 'testcommit3585' of github.com:jantman/gitpython_issue_301 +88b43c7193907134990d04c2f1b204b7d1535ea0 not-for-merge branch 'testcommit3586' of github.com:jantman/gitpython_issue_301 +4261a25302e6cc9bc0a9ab479e75d188a3339e37 not-for-merge branch 'testcommit3587' of github.com:jantman/gitpython_issue_301 +0979268db531c72d1ac298866cf0c72077057f50 not-for-merge branch 'testcommit3588' of github.com:jantman/gitpython_issue_301 +a63ffac9a2fe4d182189e92f555a95a7e5458371 not-for-merge branch 'testcommit3589' of github.com:jantman/gitpython_issue_301 +44b6a28984b033683982e631de358e0a857de306 not-for-merge branch 'testcommit359' of github.com:jantman/gitpython_issue_301 +060825cb161860aeedd0dcefa54f900ed8eb7996 not-for-merge branch 'testcommit3590' of github.com:jantman/gitpython_issue_301 +1b900ef2eb82608ba5fed81ee0ed7e6ba3ef60f9 not-for-merge branch 'testcommit3591' of github.com:jantman/gitpython_issue_301 +c33f58930f18e7936f77192ccb19806a9abed48f not-for-merge branch 'testcommit3592' of github.com:jantman/gitpython_issue_301 +e952a5e62390527d184eb20b72302b4a36c39695 not-for-merge branch 'testcommit3593' of github.com:jantman/gitpython_issue_301 +fa1af6faac05be6754d2631a029ae465f4a7052d not-for-merge branch 'testcommit3594' of github.com:jantman/gitpython_issue_301 +3a16a16863d9e70eb851ad5174ec59508e12c2ae not-for-merge branch 'testcommit3595' of github.com:jantman/gitpython_issue_301 +8a7a46dcb515bd7295567b12f23258d09e0483dc not-for-merge branch 'testcommit3596' of github.com:jantman/gitpython_issue_301 +030fa5c2bbf2c636372363939570e5a357c87904 not-for-merge branch 'testcommit3597' of github.com:jantman/gitpython_issue_301 +eb257c4ccd519ad40eca759a75da75c6ca547e7f not-for-merge branch 'testcommit3598' of github.com:jantman/gitpython_issue_301 +67725828ee516d2944803ea883cfb737389abb41 not-for-merge branch 'testcommit3599' of github.com:jantman/gitpython_issue_301 +b1828c2292198fbacf5ee9696d8fcbeba2efbdef not-for-merge branch 'testcommit36' of github.com:jantman/gitpython_issue_301 +35f9d975487700f9044543783c1613341d295705 not-for-merge branch 'testcommit360' of github.com:jantman/gitpython_issue_301 +f06ff26b5e98e9e3ee9240fd246f1006c4b494e1 not-for-merge branch 'testcommit3600' of github.com:jantman/gitpython_issue_301 +6fe748cbf0863ee5734e78bd39b395bbd6684d55 not-for-merge branch 'testcommit3601' of github.com:jantman/gitpython_issue_301 +7e72c200fec5344e540e90d082b1aa0badcdef55 not-for-merge branch 'testcommit3602' of github.com:jantman/gitpython_issue_301 +b4e23ea2e6774bc06f7eda9fa8addfcbfa014a9d not-for-merge branch 'testcommit3603' of github.com:jantman/gitpython_issue_301 +21ee6d0fb39d53a00288693206f64c025019293b not-for-merge branch 'testcommit3604' of github.com:jantman/gitpython_issue_301 +de04f3c17d79eebe8f10f711afe8913893c57c94 not-for-merge branch 'testcommit3605' of github.com:jantman/gitpython_issue_301 +15ae0183d12a59a3da9f897b96483a868c9d9646 not-for-merge branch 'testcommit3606' of github.com:jantman/gitpython_issue_301 +c6d740b5dd09b65c9d3add0f05c46d9a049c9608 not-for-merge branch 'testcommit3607' of github.com:jantman/gitpython_issue_301 +bdf3466ef48c80844a50a550c028a5eca6b7b50f not-for-merge branch 'testcommit3608' of github.com:jantman/gitpython_issue_301 +fdd1856b6e4767b11933f95998db798607314937 not-for-merge branch 'testcommit3609' of github.com:jantman/gitpython_issue_301 +a49c446d598eea3e6e3d687cbb94c3721ef7cc27 not-for-merge branch 'testcommit361' of github.com:jantman/gitpython_issue_301 +8b839f329ec77e577445cbac5f5a600d18056260 not-for-merge branch 'testcommit3610' of github.com:jantman/gitpython_issue_301 +877e53012e1f3ab5d989ced3f4a68128f68d141c not-for-merge branch 'testcommit3611' of github.com:jantman/gitpython_issue_301 +f12981e71c9289ad54db65f3d6d57caa314801d6 not-for-merge branch 'testcommit3612' of github.com:jantman/gitpython_issue_301 +601638053961894c3ab000b8ad376e6e745d3ff8 not-for-merge branch 'testcommit3613' of github.com:jantman/gitpython_issue_301 +a890b051cf08e348dbd673e317d11d9ab7adc6fc not-for-merge branch 'testcommit3614' of github.com:jantman/gitpython_issue_301 +4cefc95fc69b4a1e99161bf8b4e194deb7c0a85d not-for-merge branch 'testcommit3615' of github.com:jantman/gitpython_issue_301 +1c11c9eea081e4da2ee78e531923a8adc9dbed41 not-for-merge branch 'testcommit3616' of github.com:jantman/gitpython_issue_301 +40904c2867dbc6f0ca9656000e3abb3b4a3136ae not-for-merge branch 'testcommit3617' of github.com:jantman/gitpython_issue_301 +e557668bd3749b20a14987480751bf3d21bc7072 not-for-merge branch 'testcommit3618' of github.com:jantman/gitpython_issue_301 +ff19c0af73b1ee3089d41ff32443de76c6e00263 not-for-merge branch 'testcommit3619' of github.com:jantman/gitpython_issue_301 +c12fd60dad9a1153aee6090b528063aa56043d8e not-for-merge branch 'testcommit362' of github.com:jantman/gitpython_issue_301 +9adb97a071edb1757d3de32687b0aca72f5bb824 not-for-merge branch 'testcommit3620' of github.com:jantman/gitpython_issue_301 +c6df58af2413e0a56d85d8f5d990e2239e517bea not-for-merge branch 'testcommit3621' of github.com:jantman/gitpython_issue_301 +0563586588ddc02c1afb5b56777479fe9a7ef737 not-for-merge branch 'testcommit3622' of github.com:jantman/gitpython_issue_301 +9b1344f872ccdf24704263b9e5f984c39cd582be not-for-merge branch 'testcommit3623' of github.com:jantman/gitpython_issue_301 +be2c66a1c154c790057a25df6cd049208a68e1c1 not-for-merge branch 'testcommit3624' of github.com:jantman/gitpython_issue_301 +ac916630785af8e3cdbf0216b3f48d0a0e3c3e86 not-for-merge branch 'testcommit3625' of github.com:jantman/gitpython_issue_301 +ecb8f6f3074f4ab830d6924cd9baa715c36d2b77 not-for-merge branch 'testcommit3626' of github.com:jantman/gitpython_issue_301 +7965b02dd3e03e0b05863623c64a33a7f6afccb1 not-for-merge branch 'testcommit3627' of github.com:jantman/gitpython_issue_301 +7b12d1340a6408f93d1516c3912f96ceb86d4dff not-for-merge branch 'testcommit3628' of github.com:jantman/gitpython_issue_301 +d180592b5efa4a13e6e24f535249f07d53938821 not-for-merge branch 'testcommit3629' of github.com:jantman/gitpython_issue_301 +d0220065a28f1aebfb0b4aa24164cd16d81c06bb not-for-merge branch 'testcommit363' of github.com:jantman/gitpython_issue_301 +08cc273bf9b6033319eb1fb849a9dc7708477318 not-for-merge branch 'testcommit3630' of github.com:jantman/gitpython_issue_301 +10dcd7614c7f7d9f35e06761c69ef7a1eaa4b2a1 not-for-merge branch 'testcommit3631' of github.com:jantman/gitpython_issue_301 +a381f55491d07973302bc48407fa8af085759a4b not-for-merge branch 'testcommit3632' of github.com:jantman/gitpython_issue_301 +0d5da25cd7c507b9657bdc06699e50dce4467823 not-for-merge branch 'testcommit3633' of github.com:jantman/gitpython_issue_301 +8c67f5648625b0add9b3bd817293735a20afeb0c not-for-merge branch 'testcommit3634' of github.com:jantman/gitpython_issue_301 +b689c9e9274f711c2c8c07eac12f2627423dcd8f not-for-merge branch 'testcommit3635' of github.com:jantman/gitpython_issue_301 +d6e6be2cf115ecbbb6a0f48b0a9161f6a1d91840 not-for-merge branch 'testcommit3636' of github.com:jantman/gitpython_issue_301 +bb0c955e03343c0517e750f057d7f52611f12930 not-for-merge branch 'testcommit3637' of github.com:jantman/gitpython_issue_301 +8f52a5d40d89038eb1d3ed3381ad5324781e33db not-for-merge branch 'testcommit3638' of github.com:jantman/gitpython_issue_301 +81bffc1f4c39002bdcc1640a03c8f65a055937cf not-for-merge branch 'testcommit3639' of github.com:jantman/gitpython_issue_301 +538f3455fd516a96775c4728857808c6b8f835d0 not-for-merge branch 'testcommit364' of github.com:jantman/gitpython_issue_301 +2949a2678ddb7591f74a207a725a68a5b7564f11 not-for-merge branch 'testcommit3640' of github.com:jantman/gitpython_issue_301 +4438047f49d4de722513ba455ffb4032e5acd3a7 not-for-merge branch 'testcommit3641' of github.com:jantman/gitpython_issue_301 +16ffc53d5dc7c416a46bbbfb9616f514e39e1a24 not-for-merge branch 'testcommit3642' of github.com:jantman/gitpython_issue_301 +7a160ce5c0bd99b2f3f2a5703311e628a3f76bef not-for-merge branch 'testcommit3643' of github.com:jantman/gitpython_issue_301 +f5bfdae62d92a9a5385f518684648bd4e70575b1 not-for-merge branch 'testcommit3644' of github.com:jantman/gitpython_issue_301 +5d04a56a5e29b6421a38388a6e212530e29f62c5 not-for-merge branch 'testcommit3645' of github.com:jantman/gitpython_issue_301 +00aaf03a9add10dd8e105a5ae9bc54b5a82da71c not-for-merge branch 'testcommit3646' of github.com:jantman/gitpython_issue_301 +e93b80a98261625a3352241575f9bc09801e3b1c not-for-merge branch 'testcommit3647' of github.com:jantman/gitpython_issue_301 +356c0833f31e5e187bbae4ee80955f0a12e07af9 not-for-merge branch 'testcommit3648' of github.com:jantman/gitpython_issue_301 +db2cd37c006abb6bed58373dfd362dfc8c10c49b not-for-merge branch 'testcommit3649' of github.com:jantman/gitpython_issue_301 +a486982ff8fe37a3afc543a6a7c5fd1c1b239901 not-for-merge branch 'testcommit365' of github.com:jantman/gitpython_issue_301 +680681a4e8e7300cb351b1ef773c132b6d0bbe9c not-for-merge branch 'testcommit3650' of github.com:jantman/gitpython_issue_301 +b3fcccdd5b31c85ffd74b57f8207ea519bba19df not-for-merge branch 'testcommit3651' of github.com:jantman/gitpython_issue_301 +bbd705a1c914c799275c52f3409c41e3e47b9300 not-for-merge branch 'testcommit3652' of github.com:jantman/gitpython_issue_301 +f850343db43892eaeec7ddc2c94fa8cfa949919b not-for-merge branch 'testcommit3653' of github.com:jantman/gitpython_issue_301 +51078c2fd0dd38cabc7ee0b5be47a22bf8305ea9 not-for-merge branch 'testcommit3654' of github.com:jantman/gitpython_issue_301 +117754fe706ae3f9ab794fc599991578eb8d8223 not-for-merge branch 'testcommit3655' of github.com:jantman/gitpython_issue_301 +644e0ae7d99c92895d180c01a29749785b4d7bab not-for-merge branch 'testcommit3656' of github.com:jantman/gitpython_issue_301 +99c9d566f913c4f55326aa4e9289bb5c22218281 not-for-merge branch 'testcommit3657' of github.com:jantman/gitpython_issue_301 +59a0ba06dd0018bfcd14f8d5a4d21d7b7c418f6c not-for-merge branch 'testcommit3658' of github.com:jantman/gitpython_issue_301 +33277dd1b2558fcdc37479e3d34dc8963c7cb1ab not-for-merge branch 'testcommit3659' of github.com:jantman/gitpython_issue_301 +7432f9d61979014ec2e09fd0ab8eb8dd023d9f8a not-for-merge branch 'testcommit366' of github.com:jantman/gitpython_issue_301 +328b450df81b0b9a7fb6a364e80c536fe200bcfe not-for-merge branch 'testcommit3660' of github.com:jantman/gitpython_issue_301 +d104cd59a095c7a6b123836d3ed0cde7cfa47637 not-for-merge branch 'testcommit3661' of github.com:jantman/gitpython_issue_301 +40cb8853ce37f6c1cffc7a3cc20a8003987725aa not-for-merge branch 'testcommit3662' of github.com:jantman/gitpython_issue_301 +c3a2d09d4dc320dcfff3e32e9bcff5aafc03a26b not-for-merge branch 'testcommit3663' of github.com:jantman/gitpython_issue_301 +dd7c9b098599ff3e6bcccbf7641d1379bc4dc4db not-for-merge branch 'testcommit3664' of github.com:jantman/gitpython_issue_301 +5b8cfddcf528e8f3586a1adf71eb39f5e8d29788 not-for-merge branch 'testcommit3665' of github.com:jantman/gitpython_issue_301 +ba2c13ac2613dab9619b305756329d1db82a1047 not-for-merge branch 'testcommit3666' of github.com:jantman/gitpython_issue_301 +d508086d9736fe478ba2b5b1650ff83de046cb91 not-for-merge branch 'testcommit3667' of github.com:jantman/gitpython_issue_301 +1f361cf4089609e649a884dfd8dadd60575257c3 not-for-merge branch 'testcommit3668' of github.com:jantman/gitpython_issue_301 +a95b32942c5b0d039bda4d9453815a7ec7b1c99e not-for-merge branch 'testcommit3669' of github.com:jantman/gitpython_issue_301 +7d0eed69ff9e3b572f52adafbc5efed5b0bd275f not-for-merge branch 'testcommit367' of github.com:jantman/gitpython_issue_301 +57c54de45db2d2b6b0c9683671c482b5912796b4 not-for-merge branch 'testcommit3670' of github.com:jantman/gitpython_issue_301 +b40e3740c74fde7ffb3b36faa8eef712ac8856b3 not-for-merge branch 'testcommit3671' of github.com:jantman/gitpython_issue_301 +d90791526672f62a0fb7fc6c24529986fdc9b8de not-for-merge branch 'testcommit3672' of github.com:jantman/gitpython_issue_301 +5428fd7f5de26b061b0d4dcf408790e92f05cbe4 not-for-merge branch 'testcommit3673' of github.com:jantman/gitpython_issue_301 +8513463044740b1b424891fe48926a515d46ceae not-for-merge branch 'testcommit3674' of github.com:jantman/gitpython_issue_301 +42354bdcfa1c85a94bf9533e18434abc4e7cebb4 not-for-merge branch 'testcommit3675' of github.com:jantman/gitpython_issue_301 +da9a5e479f5e070e98a4a6845d55d6266b11c966 not-for-merge branch 'testcommit3676' of github.com:jantman/gitpython_issue_301 +195b3acfded78e655e56d5c50d3278f130fc688b not-for-merge branch 'testcommit3677' of github.com:jantman/gitpython_issue_301 +6733d0b31dce892525b732cbcb4ea77d25fa5d8d not-for-merge branch 'testcommit3678' of github.com:jantman/gitpython_issue_301 +58bd0b8e83706d3eea82646a8d23e3464a0377b9 not-for-merge branch 'testcommit3679' of github.com:jantman/gitpython_issue_301 +b5a5f552c24c3f6f5483cbd5c02fc27fa7fc8ffe not-for-merge branch 'testcommit368' of github.com:jantman/gitpython_issue_301 +722d93bed2c837ca80e2385feff8fbd302812bd0 not-for-merge branch 'testcommit3680' of github.com:jantman/gitpython_issue_301 +1e9df8d40ea44e727126f2870ecfaef569ffd593 not-for-merge branch 'testcommit3681' of github.com:jantman/gitpython_issue_301 +dfe6c3b0740c39721aaca89fe59b9b9458378728 not-for-merge branch 'testcommit3682' of github.com:jantman/gitpython_issue_301 +c8f26df5001f4015d5c107fcb4be0eb114168dd3 not-for-merge branch 'testcommit3683' of github.com:jantman/gitpython_issue_301 +2e4a10543be540cdd94eef7bac2195b21e93e00e not-for-merge branch 'testcommit3684' of github.com:jantman/gitpython_issue_301 +a79a9b273d08ef13212006af56e613783bbe2fa9 not-for-merge branch 'testcommit3685' of github.com:jantman/gitpython_issue_301 +9fc1847ca374405230f3b3de5cd7eeeca4389994 not-for-merge branch 'testcommit3686' of github.com:jantman/gitpython_issue_301 +83d283bba596b5d5708d3391d13710546e690d0a not-for-merge branch 'testcommit3687' of github.com:jantman/gitpython_issue_301 +d2e574f213cc3a79ecded38b749af3bf9e4ec443 not-for-merge branch 'testcommit3688' of github.com:jantman/gitpython_issue_301 +2504731901e264e47e7b8676f9c50fc33040a199 not-for-merge branch 'testcommit3689' of github.com:jantman/gitpython_issue_301 +b6d59342e61a9561471f7a517522d844a5c33fb9 not-for-merge branch 'testcommit369' of github.com:jantman/gitpython_issue_301 +33ffc5ca77c217b70f69940c2b9d86381a56679e not-for-merge branch 'testcommit3690' of github.com:jantman/gitpython_issue_301 +f453cd51d13276356ec9f36ed671b26a527b10a0 not-for-merge branch 'testcommit3691' of github.com:jantman/gitpython_issue_301 +40e04ec976c8b72860a524be8af5a8c71fd39005 not-for-merge branch 'testcommit3692' of github.com:jantman/gitpython_issue_301 +5eaa603fca328eb84e60367e32098450037c12ec not-for-merge branch 'testcommit3693' of github.com:jantman/gitpython_issue_301 +19f4ddce06d0254890b779ade9683592924f4481 not-for-merge branch 'testcommit3694' of github.com:jantman/gitpython_issue_301 +18cf34ccbd56a9d23240854a45e632dc3209ddce not-for-merge branch 'testcommit3695' of github.com:jantman/gitpython_issue_301 +f85bbdf9674ca9d03a5143ba2e6c1a53d4063828 not-for-merge branch 'testcommit3696' of github.com:jantman/gitpython_issue_301 +94a55dce4d1c751fff0c8473bad25f16ddb5c401 not-for-merge branch 'testcommit3697' of github.com:jantman/gitpython_issue_301 +961fea91a1c087a7672679587fb88fc62f70839d not-for-merge branch 'testcommit3698' of github.com:jantman/gitpython_issue_301 +4a371b8a4beb44be2d624f7657624369dec9a564 not-for-merge branch 'testcommit3699' of github.com:jantman/gitpython_issue_301 +84cf693df85140b9995a7ef4dcd0025b6a0966eb not-for-merge branch 'testcommit37' of github.com:jantman/gitpython_issue_301 +5634b6241568604d07e69d3f9819aada1871d1c0 not-for-merge branch 'testcommit370' of github.com:jantman/gitpython_issue_301 +0df99eb7a5c466923431bef2e9a85b6789c26267 not-for-merge branch 'testcommit3700' of github.com:jantman/gitpython_issue_301 +385ec758edf80ca1672e7c1b9a7b5454708d6014 not-for-merge branch 'testcommit3701' of github.com:jantman/gitpython_issue_301 +fee29312572d8c65feffd38df2867a30e31af021 not-for-merge branch 'testcommit3702' of github.com:jantman/gitpython_issue_301 +a5ef9d38ad173d1d387614a394a4e4612aa0100a not-for-merge branch 'testcommit3703' of github.com:jantman/gitpython_issue_301 +c343f44a1bca5edefadd3a4a5bf732c73a7e9dad not-for-merge branch 'testcommit3704' of github.com:jantman/gitpython_issue_301 +89ac1d8ac6678d93df7b11037c5449c32951a148 not-for-merge branch 'testcommit3705' of github.com:jantman/gitpython_issue_301 +55f47fccc0139a556fb62d4752e6b8dedabe5d8d not-for-merge branch 'testcommit3706' of github.com:jantman/gitpython_issue_301 +166726730f21f50d667c79563438f33497400c16 not-for-merge branch 'testcommit3707' of github.com:jantman/gitpython_issue_301 +4dabcd5c2e9562ca8821484f9fe7c31a3bedc9ed not-for-merge branch 'testcommit3708' of github.com:jantman/gitpython_issue_301 +d357d86dbbae30896091b9e39239e149b38807f6 not-for-merge branch 'testcommit3709' of github.com:jantman/gitpython_issue_301 +48332b59eb97e6a9ab7a0599fb0815b5f4379424 not-for-merge branch 'testcommit371' of github.com:jantman/gitpython_issue_301 +2d7dcdd1cff833ab78e73a975095b0de30845909 not-for-merge branch 'testcommit3710' of github.com:jantman/gitpython_issue_301 +59597cbc75cb1ebf4718a1dbfb79d61586e2bb63 not-for-merge branch 'testcommit3711' of github.com:jantman/gitpython_issue_301 +79c06c896f151e6096ec7a6839e224ca7be030c7 not-for-merge branch 'testcommit3712' of github.com:jantman/gitpython_issue_301 +7a5b1c78e30c131dc900044226164598eb35658c not-for-merge branch 'testcommit3713' of github.com:jantman/gitpython_issue_301 +529837f7014af8d1f1a7574e046a4a0c08426ad7 not-for-merge branch 'testcommit3714' of github.com:jantman/gitpython_issue_301 +40bd5ae509535405bb2670738c61f30dbd056703 not-for-merge branch 'testcommit3715' of github.com:jantman/gitpython_issue_301 +150327841b948e62c35002df78053db10ae3b279 not-for-merge branch 'testcommit3716' of github.com:jantman/gitpython_issue_301 +e8298f955fc49e46d093b44bcb3f4c0fb588f900 not-for-merge branch 'testcommit3717' of github.com:jantman/gitpython_issue_301 +37cf15d4ea7d5e4b0bde1945c1e94856015b691d not-for-merge branch 'testcommit3718' of github.com:jantman/gitpython_issue_301 +e3e5c3a5be73688cebf0d6ddbe7e63088778af69 not-for-merge branch 'testcommit3719' of github.com:jantman/gitpython_issue_301 +460b740007fda9e79b4c8ee6f467bb3a90aadd44 not-for-merge branch 'testcommit372' of github.com:jantman/gitpython_issue_301 +7169f7c499ace2edf0424e6d4e30e0be260676ce not-for-merge branch 'testcommit3720' of github.com:jantman/gitpython_issue_301 +301b7995fce02eb3419f0b8478db775aab6ca2bb not-for-merge branch 'testcommit3721' of github.com:jantman/gitpython_issue_301 +e3d17fc2e9315b2ecbe69bcc79721441f8c05a09 not-for-merge branch 'testcommit3722' of github.com:jantman/gitpython_issue_301 +2d64cadbaae3428574b0dc5d7a17c32a3743ef90 not-for-merge branch 'testcommit3723' of github.com:jantman/gitpython_issue_301 +c5e09e4e23473a1810d97230ddcf79c883e9a5ec not-for-merge branch 'testcommit3724' of github.com:jantman/gitpython_issue_301 +1f3fcf22bee04fdc46f0470710400e2816e8da40 not-for-merge branch 'testcommit3725' of github.com:jantman/gitpython_issue_301 +74f61e5a338c927b7937cfd11d73cf6ef535ef82 not-for-merge branch 'testcommit3726' of github.com:jantman/gitpython_issue_301 +ce1911ea14de453523afaf16426e093d9f0f1012 not-for-merge branch 'testcommit3727' of github.com:jantman/gitpython_issue_301 +efd0b1b90b5fbee34d7a12847840ed1615981c87 not-for-merge branch 'testcommit3728' of github.com:jantman/gitpython_issue_301 +14308a11e50b3c4b531ea95bba870ecc1a9207a3 not-for-merge branch 'testcommit3729' of github.com:jantman/gitpython_issue_301 +105925a695c4c46a16c972eb9542d287bb4d0edf not-for-merge branch 'testcommit373' of github.com:jantman/gitpython_issue_301 +36a052a201cdc598b0f104d5ab5185d021f55ba4 not-for-merge branch 'testcommit3730' of github.com:jantman/gitpython_issue_301 +28bcdf1a995ed6f3af4c535755cc533b23da2848 not-for-merge branch 'testcommit3731' of github.com:jantman/gitpython_issue_301 +1c19589ae7b55045ee1a485eabb25596a7348201 not-for-merge branch 'testcommit3732' of github.com:jantman/gitpython_issue_301 +9d602178d91e81e0765d108e2eaf608eafa47fd7 not-for-merge branch 'testcommit3733' of github.com:jantman/gitpython_issue_301 +3337218caf58e44ff79b59cbb2b10fd888fea85f not-for-merge branch 'testcommit3734' of github.com:jantman/gitpython_issue_301 +bf75b85382bb3f616e51b37692cb63fc17660e42 not-for-merge branch 'testcommit3735' of github.com:jantman/gitpython_issue_301 +cbdcf7ae23ca0443c93476dd11d68f9a25419078 not-for-merge branch 'testcommit3736' of github.com:jantman/gitpython_issue_301 +3c1f16e2d3c41ca949c469a12d63a15d8021f21c not-for-merge branch 'testcommit3737' of github.com:jantman/gitpython_issue_301 +5243bf2c85bf90c04c7bb0f3563c2f4ddf48d372 not-for-merge branch 'testcommit3738' of github.com:jantman/gitpython_issue_301 +fdbe09ddddb8ff7459bcd1bd3c9fe6de2b89cd3d not-for-merge branch 'testcommit3739' of github.com:jantman/gitpython_issue_301 +6cd9164dac28e9d91a35de6596059646a256a1d2 not-for-merge branch 'testcommit374' of github.com:jantman/gitpython_issue_301 +1c8ade731eb3b1af3f9b5e52ceba07f9b28c4f77 not-for-merge branch 'testcommit3740' of github.com:jantman/gitpython_issue_301 +fa9b03711f3dae738ad57cf7e483a7759ec543d3 not-for-merge branch 'testcommit3741' of github.com:jantman/gitpython_issue_301 +258ef452453aba216529436260b3b5041a8a40e7 not-for-merge branch 'testcommit3742' of github.com:jantman/gitpython_issue_301 +ff4411e29c48fe458660e13452c71192d6308be5 not-for-merge branch 'testcommit3743' of github.com:jantman/gitpython_issue_301 +8d4e91b49f86eec66be8ed8f9f767fcf8605af6a not-for-merge branch 'testcommit3744' of github.com:jantman/gitpython_issue_301 +d0c99291e24413b39144857f08b53f9d2babb22b not-for-merge branch 'testcommit3745' of github.com:jantman/gitpython_issue_301 +9d87c3b91e005b00d9879d218e5a278d4a5a664b not-for-merge branch 'testcommit3746' of github.com:jantman/gitpython_issue_301 +b77a80fa8b238553dcabc68c37441be2a06b0892 not-for-merge branch 'testcommit3747' of github.com:jantman/gitpython_issue_301 +3e3adf97fd586889bf699c276f4bc69939920fab not-for-merge branch 'testcommit3748' of github.com:jantman/gitpython_issue_301 +7e8a1f0d13f6592b665089bdccba57a23968b473 not-for-merge branch 'testcommit3749' of github.com:jantman/gitpython_issue_301 +32c28c9307d461f306a5bc347e9f6007a313cbda not-for-merge branch 'testcommit375' of github.com:jantman/gitpython_issue_301 +189876b73171469da69ae384c3fab8e9a9e213fd not-for-merge branch 'testcommit3750' of github.com:jantman/gitpython_issue_301 +ea926e25f58cfbd9aac57faf67b8b0697ab5b4d8 not-for-merge branch 'testcommit3751' of github.com:jantman/gitpython_issue_301 +eec23601cd00390bb0bdb373193997419d3b8a20 not-for-merge branch 'testcommit3752' of github.com:jantman/gitpython_issue_301 +5c2fabd4c8fee812868423576f9b4107d6f72667 not-for-merge branch 'testcommit3753' of github.com:jantman/gitpython_issue_301 +fff1328e8f94712d7f83eea38a11d1988549075e not-for-merge branch 'testcommit3754' of github.com:jantman/gitpython_issue_301 +b46c499f4f3d836e0a1076d9be1524a8ad42197d not-for-merge branch 'testcommit3755' of github.com:jantman/gitpython_issue_301 +16900b99e91c583a38281bd8b591c6a110083dde not-for-merge branch 'testcommit3756' of github.com:jantman/gitpython_issue_301 +3c1be1fa184cec4d279a7944f3f0e43dc7ab2cd3 not-for-merge branch 'testcommit3757' of github.com:jantman/gitpython_issue_301 +6627362097795d139f35e1a18c9c81415ee45708 not-for-merge branch 'testcommit3758' of github.com:jantman/gitpython_issue_301 +9ed80bd571844c7769d35e0d03d76d10c27afb91 not-for-merge branch 'testcommit3759' of github.com:jantman/gitpython_issue_301 +0e96a2e347c8000bebe359e2d899e6d65c22eaf2 not-for-merge branch 'testcommit376' of github.com:jantman/gitpython_issue_301 +bf3a5527eaf501be8d22823c962ab8488096f5c9 not-for-merge branch 'testcommit3760' of github.com:jantman/gitpython_issue_301 +a2dd7e507ceee863a17650dba14e81591f241256 not-for-merge branch 'testcommit3761' of github.com:jantman/gitpython_issue_301 +401c96d4f88c3c3d313a83b83812a075dae4e6ed not-for-merge branch 'testcommit3762' of github.com:jantman/gitpython_issue_301 +cb16192c01799867f4b5722792ea9b550c333e78 not-for-merge branch 'testcommit3763' of github.com:jantman/gitpython_issue_301 +7779cd8745fb65001e3451a92fa0e3f995e08c4e not-for-merge branch 'testcommit3764' of github.com:jantman/gitpython_issue_301 +18ec9e744441ba2ef95d26827bbc48e4075f895f not-for-merge branch 'testcommit3765' of github.com:jantman/gitpython_issue_301 +43b44d1526e107baf6991bd4c5df659955497b95 not-for-merge branch 'testcommit3766' of github.com:jantman/gitpython_issue_301 +82d8019954f52fe140f0df1c0d7650e5351afe82 not-for-merge branch 'testcommit3767' of github.com:jantman/gitpython_issue_301 +80f3713a6bf62e49396dd01d3dc718e14e3c8c8f not-for-merge branch 'testcommit3768' of github.com:jantman/gitpython_issue_301 +b91d66cd8bcb857f0d2b535058ec1c38ed0c5f99 not-for-merge branch 'testcommit3769' of github.com:jantman/gitpython_issue_301 +7c53eacbf1fe3e8f71125298c4fe0d51e29cc117 not-for-merge branch 'testcommit377' of github.com:jantman/gitpython_issue_301 +71ee5c946db99170a6eb47d61502e5445db48dc0 not-for-merge branch 'testcommit3770' of github.com:jantman/gitpython_issue_301 +5ccdd83fea8e4d9626e1e9792bfb45426294f572 not-for-merge branch 'testcommit3771' of github.com:jantman/gitpython_issue_301 +38fe9679a780f8c888086f4a0419b0438ab8134e not-for-merge branch 'testcommit3772' of github.com:jantman/gitpython_issue_301 +ffdefd911ecdb5bd98144dcb91823f3f054f7f89 not-for-merge branch 'testcommit3773' of github.com:jantman/gitpython_issue_301 +a37276edba09027af6be007e4309b7f3a29dd4bc not-for-merge branch 'testcommit3774' of github.com:jantman/gitpython_issue_301 +5e03148f270ae958aa6c0aee8b02d863de8dc54d not-for-merge branch 'testcommit3775' of github.com:jantman/gitpython_issue_301 +05bebbc4cdb70a9ef6c2cca69e2b5b4412ef74f6 not-for-merge branch 'testcommit3776' of github.com:jantman/gitpython_issue_301 +3433f81a6733c1ac5ac8c4fd29efa6d128dceafa not-for-merge branch 'testcommit3777' of github.com:jantman/gitpython_issue_301 +63a6b07c84748be55502c5c63df44a9f01521d6d not-for-merge branch 'testcommit3778' of github.com:jantman/gitpython_issue_301 +6e73296b7a7bbdfb5cf1e606ed10e90d265ad944 not-for-merge branch 'testcommit3779' of github.com:jantman/gitpython_issue_301 +9d3dcf23a80d7cb3cdcd2450e9e1a702c3617010 not-for-merge branch 'testcommit378' of github.com:jantman/gitpython_issue_301 +bb9fc5f291d692687e489e7b3eb7920073a6f1e8 not-for-merge branch 'testcommit3780' of github.com:jantman/gitpython_issue_301 +924b7057b2ee1b94dd1aee8fcc9bca52a925452e not-for-merge branch 'testcommit3781' of github.com:jantman/gitpython_issue_301 +0cc3f3f78e95f629f8dbc47dd01eb6939fef9ba4 not-for-merge branch 'testcommit3782' of github.com:jantman/gitpython_issue_301 +ca20f6bf09bded40228dd1f0ad173584e077d06e not-for-merge branch 'testcommit3783' of github.com:jantman/gitpython_issue_301 +8b7623cf94c54e0917a3e57e255a5cb0de83c27b not-for-merge branch 'testcommit3784' of github.com:jantman/gitpython_issue_301 +c18a530563a3386fd08b718c625ae976a694efe5 not-for-merge branch 'testcommit3785' of github.com:jantman/gitpython_issue_301 +575f0b7580df270c83f2c88931d4a8386f22842c not-for-merge branch 'testcommit3786' of github.com:jantman/gitpython_issue_301 +3e0308aa5e9d4c6d3b1108af37417740fac79edc not-for-merge branch 'testcommit3787' of github.com:jantman/gitpython_issue_301 +34c2caf8dd84bde1e7ae809d0e9460d9245fcb66 not-for-merge branch 'testcommit3788' of github.com:jantman/gitpython_issue_301 +40e0d4fce0790920e12a297aa075933727756731 not-for-merge branch 'testcommit3789' of github.com:jantman/gitpython_issue_301 +706b80f418435f084e8f584437362ec23ea572a8 not-for-merge branch 'testcommit379' of github.com:jantman/gitpython_issue_301 +706b0891e82263af37f5ca15efaa2d616bcc4042 not-for-merge branch 'testcommit3790' of github.com:jantman/gitpython_issue_301 +3f1a699ba616c8a2ff9eba0cdeb472b754252378 not-for-merge branch 'testcommit3791' of github.com:jantman/gitpython_issue_301 +3ec24b18bd8b2c815981dec74661df7b9c630dae not-for-merge branch 'testcommit3792' of github.com:jantman/gitpython_issue_301 +d2a8812d7f4cf3e096c9ac6e5ac5b0d6873517f5 not-for-merge branch 'testcommit3793' of github.com:jantman/gitpython_issue_301 +7fd364daa7daa312f4895dd4c813dc53c542720f not-for-merge branch 'testcommit3794' of github.com:jantman/gitpython_issue_301 +3805a7d3b2be42f7b560497aa163c130fd87111a not-for-merge branch 'testcommit3795' of github.com:jantman/gitpython_issue_301 +607d13348c4a6de0800c9f42ce17597409b95f5d not-for-merge branch 'testcommit3796' of github.com:jantman/gitpython_issue_301 +f1a1a01f3171c91d7bc4f08d16b23e31b068f30a not-for-merge branch 'testcommit3797' of github.com:jantman/gitpython_issue_301 +88f66c8acd7b7375ad5a94e22b5432f3a3a5700d not-for-merge branch 'testcommit3798' of github.com:jantman/gitpython_issue_301 +30763f806977f180d177583bfa915601b3844ad7 not-for-merge branch 'testcommit3799' of github.com:jantman/gitpython_issue_301 +3ca64d0af1860daf6521e4979152c421b0aa07f0 not-for-merge branch 'testcommit38' of github.com:jantman/gitpython_issue_301 +2cf4f3e7ff08e1a3b278964bced79674fe975c6c not-for-merge branch 'testcommit380' of github.com:jantman/gitpython_issue_301 +6f739e78b80b89d1c821a23642dfb1b384dfa28f not-for-merge branch 'testcommit3800' of github.com:jantman/gitpython_issue_301 +2993811abcfb2b8a6a4d788b8cbafb6dcb1ba6b8 not-for-merge branch 'testcommit3801' of github.com:jantman/gitpython_issue_301 +63eba19d3cff22913eb2e13be082177adf7c76e8 not-for-merge branch 'testcommit3802' of github.com:jantman/gitpython_issue_301 +6c5ad825fbdf8d425d499b8b6c0638e2e3033241 not-for-merge branch 'testcommit3803' of github.com:jantman/gitpython_issue_301 +13f313def805f5056c1c2896f4a31774524efcf8 not-for-merge branch 'testcommit3804' of github.com:jantman/gitpython_issue_301 +cb1dec33eddfd87857f3521af42e76f2adb21ce7 not-for-merge branch 'testcommit3805' of github.com:jantman/gitpython_issue_301 +21708fb301b7b56de000e70d16312bc50875868f not-for-merge branch 'testcommit3806' of github.com:jantman/gitpython_issue_301 +0c30e5fdee7d056c5bf2fe34eb99c16ad05aee43 not-for-merge branch 'testcommit3807' of github.com:jantman/gitpython_issue_301 +8ce19621f43a3ca2035ccea7da08e6f145aed48f not-for-merge branch 'testcommit3808' of github.com:jantman/gitpython_issue_301 +b19bc2253aac320d26abe4f069498ede1677851a not-for-merge branch 'testcommit3809' of github.com:jantman/gitpython_issue_301 +9958996cc7bc188182537832207753191dc55b35 not-for-merge branch 'testcommit381' of github.com:jantman/gitpython_issue_301 +e1961cb76986ad2d66ddeee4ccafcbd5744dacdd not-for-merge branch 'testcommit3810' of github.com:jantman/gitpython_issue_301 +6b20f72db42faf481c2ec72611818b3a3ccd397f not-for-merge branch 'testcommit3811' of github.com:jantman/gitpython_issue_301 +054d0994a246596bc02eae642894d959acfc4ae0 not-for-merge branch 'testcommit3812' of github.com:jantman/gitpython_issue_301 +32e8e41d6a4bb1f13b21ce4778be8bc005b20d45 not-for-merge branch 'testcommit3813' of github.com:jantman/gitpython_issue_301 +93540b157eac325a80caca54a5b6917ffee2ef92 not-for-merge branch 'testcommit3814' of github.com:jantman/gitpython_issue_301 +23223cab4ca7f72b6ccf871f8c50e90aa9bd1ab4 not-for-merge branch 'testcommit3815' of github.com:jantman/gitpython_issue_301 +45c6a3c1a9a9b7b74e496006fc42dcdf1bb80a1a not-for-merge branch 'testcommit3816' of github.com:jantman/gitpython_issue_301 +39aab84f8fa9e40bf5c8e1194461276e7bdef74a not-for-merge branch 'testcommit3817' of github.com:jantman/gitpython_issue_301 +a3eb9624fa7ea387fa8f768580280ec4db49542a not-for-merge branch 'testcommit3818' of github.com:jantman/gitpython_issue_301 +f19b3d1628cb0bf60efc4bd09b582f8edb073c31 not-for-merge branch 'testcommit3819' of github.com:jantman/gitpython_issue_301 +14ebe187a39457cc6dfc28fd95eaa7192a1cf128 not-for-merge branch 'testcommit382' of github.com:jantman/gitpython_issue_301 +52d6739a9c48f357feaf67b142f285dfdb1dd7cf not-for-merge branch 'testcommit3820' of github.com:jantman/gitpython_issue_301 +7fed48fde489385c02d16536533dcf177c0667a6 not-for-merge branch 'testcommit3821' of github.com:jantman/gitpython_issue_301 +ca7cc5e525682d8119bf12613072532bf8c51dae not-for-merge branch 'testcommit3822' of github.com:jantman/gitpython_issue_301 +2d51e42cdbd61bedc18f198939fe2e61d51b4c29 not-for-merge branch 'testcommit3823' of github.com:jantman/gitpython_issue_301 +7a6ddd2c192ca92540fac56f75f422af94ca489d not-for-merge branch 'testcommit3824' of github.com:jantman/gitpython_issue_301 +6713c2f4f80cee18686e2f46e1509664f10816ca not-for-merge branch 'testcommit3825' of github.com:jantman/gitpython_issue_301 +928b589b6bf7d47eb8b6c7d028980c21506e09ac not-for-merge branch 'testcommit3826' of github.com:jantman/gitpython_issue_301 +95bcb0bb8e3d93b52eb6e711b845021c8bae6ac0 not-for-merge branch 'testcommit3827' of github.com:jantman/gitpython_issue_301 +b957f8c6e4bf6f4cb93bedac7e924a503da3f8a0 not-for-merge branch 'testcommit3828' of github.com:jantman/gitpython_issue_301 +2a454eca03556db8b00cae971340b4185309ac31 not-for-merge branch 'testcommit3829' of github.com:jantman/gitpython_issue_301 +032474cd9eeffd8ed82d2465f0286669a3d6f872 not-for-merge branch 'testcommit383' of github.com:jantman/gitpython_issue_301 +c68ef9aafd5c5445745dca8b5d815758cd22cf72 not-for-merge branch 'testcommit3830' of github.com:jantman/gitpython_issue_301 +ca8c33f3abf4cace0d923e7d9b0d4f8bd24ed29f not-for-merge branch 'testcommit3831' of github.com:jantman/gitpython_issue_301 +ee11eaf0e11ce364dd78d1720ed12ef0c684fb55 not-for-merge branch 'testcommit3832' of github.com:jantman/gitpython_issue_301 +12a7538464b0ad95fc7aa939e1cdaff64fb653be not-for-merge branch 'testcommit3833' of github.com:jantman/gitpython_issue_301 +9e6556d29d11c3639e1c10c36bfba7a6a3a1f332 not-for-merge branch 'testcommit3834' of github.com:jantman/gitpython_issue_301 +a8f079c17a39f54752fb0978bf8e8cd563bf868d not-for-merge branch 'testcommit3835' of github.com:jantman/gitpython_issue_301 +87cfbbc949d9eab05967fd0f287fb71b0b2bd173 not-for-merge branch 'testcommit3836' of github.com:jantman/gitpython_issue_301 +c6931a691804ce8ca2580ef1d7f9d3c39b770656 not-for-merge branch 'testcommit3837' of github.com:jantman/gitpython_issue_301 +c864971c1f961db1d8d3e96d7ecde6b56281029e not-for-merge branch 'testcommit3838' of github.com:jantman/gitpython_issue_301 +010095debd48ce111734c952edfa1ac895ec0a05 not-for-merge branch 'testcommit3839' of github.com:jantman/gitpython_issue_301 +8f4c19558c08996bf71396ba5d193116e43c0638 not-for-merge branch 'testcommit384' of github.com:jantman/gitpython_issue_301 +24e33eff4e399ba2b465537d81b898ed54be6ef8 not-for-merge branch 'testcommit3840' of github.com:jantman/gitpython_issue_301 +40f54390ab75777f8c8576c43c7b2e5faca9323f not-for-merge branch 'testcommit3841' of github.com:jantman/gitpython_issue_301 +f93b097537c69a977ce3a920822e8e8a2a38f928 not-for-merge branch 'testcommit3842' of github.com:jantman/gitpython_issue_301 +f57e54bd7f06796bc3346d58833cb0efae3c9444 not-for-merge branch 'testcommit3843' of github.com:jantman/gitpython_issue_301 +355a85fa99c12c19d4895ae52af07a2e0b6109de not-for-merge branch 'testcommit3844' of github.com:jantman/gitpython_issue_301 +aaa405a1d071331782ed75a07bb7dc7d98e9377d not-for-merge branch 'testcommit3845' of github.com:jantman/gitpython_issue_301 +a48f96458c7030f8c2ecc2075243f3d9f86bcad0 not-for-merge branch 'testcommit3846' of github.com:jantman/gitpython_issue_301 +b4360b92fcd9965c89ac2efdf7d6ab446f3f28b6 not-for-merge branch 'testcommit3847' of github.com:jantman/gitpython_issue_301 +40f1014dc73f5a42f1173f8a7bc3b255ccf21e6c not-for-merge branch 'testcommit3848' of github.com:jantman/gitpython_issue_301 +0f501f3ee090db5ecb64c1200724e726c9b75c5b not-for-merge branch 'testcommit3849' of github.com:jantman/gitpython_issue_301 +1f50d6e82b30bfa67a8d87675d384c201fe8f41c not-for-merge branch 'testcommit385' of github.com:jantman/gitpython_issue_301 +4b85db2b2ff2b98bf204b572edf9b2c1b59adac6 not-for-merge branch 'testcommit3850' of github.com:jantman/gitpython_issue_301 +67089fceb4db61f48aeffe837f8792c0d3320e44 not-for-merge branch 'testcommit3851' of github.com:jantman/gitpython_issue_301 +9212eb1201bf77bf87cd2a657b1bab32f3f517ee not-for-merge branch 'testcommit3852' of github.com:jantman/gitpython_issue_301 +bacfb9a04cfe0b04144b70c54645cad3dc2f07ef not-for-merge branch 'testcommit3853' of github.com:jantman/gitpython_issue_301 +476b34fef7432a4d12748ad2d411a8fac100b10c not-for-merge branch 'testcommit3854' of github.com:jantman/gitpython_issue_301 +de68fc5e2a9fa6d80995342a13188fce84e28566 not-for-merge branch 'testcommit3855' of github.com:jantman/gitpython_issue_301 +0a726b742da9a7ec004ca9ed891206d996864b14 not-for-merge branch 'testcommit3856' of github.com:jantman/gitpython_issue_301 +c4b78fb4ebed19e6d5cccc21a00fad32e00271dc not-for-merge branch 'testcommit3857' of github.com:jantman/gitpython_issue_301 +73b6f8af40b0a25c3fbe9830c7a8261bbfcebc6b not-for-merge branch 'testcommit3858' of github.com:jantman/gitpython_issue_301 +3dbfc94194f9df4af4674f8fe7b452c42daeca39 not-for-merge branch 'testcommit3859' of github.com:jantman/gitpython_issue_301 +5f8c59f98c5e541ffe46c839142c66074187f14c not-for-merge branch 'testcommit386' of github.com:jantman/gitpython_issue_301 +c99f86547a5839ae556026c543ed53697ee41b72 not-for-merge branch 'testcommit3860' of github.com:jantman/gitpython_issue_301 +874c6591a4d68cfaca6e71f4731cdab6cc354239 not-for-merge branch 'testcommit3861' of github.com:jantman/gitpython_issue_301 +fc4ae29205cddcd51482abf808bc92983a033015 not-for-merge branch 'testcommit3862' of github.com:jantman/gitpython_issue_301 +a4417d61b3242550549569f2b5addad5dea912e0 not-for-merge branch 'testcommit3863' of github.com:jantman/gitpython_issue_301 +52d8629d93dff8d2527487e47ca876b278e6c3bf not-for-merge branch 'testcommit3864' of github.com:jantman/gitpython_issue_301 +795d582fb85c12f143135f61294501012381bae6 not-for-merge branch 'testcommit3865' of github.com:jantman/gitpython_issue_301 +801f849b5d8f5bd1178563f45dcfd7829ca4c659 not-for-merge branch 'testcommit3866' of github.com:jantman/gitpython_issue_301 +eaf24aa62ffcaa1b09041f3cfb52b860d6f381e9 not-for-merge branch 'testcommit3867' of github.com:jantman/gitpython_issue_301 +56be15fdaa7672ddb89776c5e41a57c69a6ac750 not-for-merge branch 'testcommit3868' of github.com:jantman/gitpython_issue_301 +f9bc4f70ead35cca010561da2042f5e71ba593d3 not-for-merge branch 'testcommit3869' of github.com:jantman/gitpython_issue_301 +61978735cc5a13a085295e7d61255a98d2ad4f80 not-for-merge branch 'testcommit387' of github.com:jantman/gitpython_issue_301 +17e69ca51366140da637dac4dd4dc11bc2055a43 not-for-merge branch 'testcommit3870' of github.com:jantman/gitpython_issue_301 +66c85ae6413c1e4442cee3f92c10571ba25d8cfb not-for-merge branch 'testcommit3871' of github.com:jantman/gitpython_issue_301 +bde44bfcfe6cf769e3c1aed53af272c814e32602 not-for-merge branch 'testcommit3872' of github.com:jantman/gitpython_issue_301 +47d5eab7ca2637b6ef751ab8c6e346279497edb8 not-for-merge branch 'testcommit3873' of github.com:jantman/gitpython_issue_301 +ec3109f76df91b18e14c5d8f35dc98997dc3f9b4 not-for-merge branch 'testcommit3874' of github.com:jantman/gitpython_issue_301 +8597c1bd8404f10d3208606ed6959e14facfcbfa not-for-merge branch 'testcommit3875' of github.com:jantman/gitpython_issue_301 +0bc83cb4d547b8ec5a53f4df7731f3bfb7c842cd not-for-merge branch 'testcommit3876' of github.com:jantman/gitpython_issue_301 +0fabfca9fda0ea0d386e77febfc1dc8afcd6b073 not-for-merge branch 'testcommit3877' of github.com:jantman/gitpython_issue_301 +e0fe27e86f331163c013653e6713ea5773f11ce7 not-for-merge branch 'testcommit3878' of github.com:jantman/gitpython_issue_301 +c86d6ae3d37f05c0b12decafc8d78124b80329af not-for-merge branch 'testcommit3879' of github.com:jantman/gitpython_issue_301 +59a48ae14b7e116c8080b0da2477616595ec7ff9 not-for-merge branch 'testcommit388' of github.com:jantman/gitpython_issue_301 +973ac3d2feb69f093a0b0fc2c46cd0bfdebcb27d not-for-merge branch 'testcommit3880' of github.com:jantman/gitpython_issue_301 +6c85300334780cda8433fc05029bd42829d9565a not-for-merge branch 'testcommit3881' of github.com:jantman/gitpython_issue_301 +bd8ac18a8a8dd192dfd79b69d091fd8d0baccbe1 not-for-merge branch 'testcommit3882' of github.com:jantman/gitpython_issue_301 +1db52912dbb8969b2d683973572c8fe889a09ae4 not-for-merge branch 'testcommit3883' of github.com:jantman/gitpython_issue_301 +2488fcd98f60e137a517b17c158febc2b218b6d9 not-for-merge branch 'testcommit3884' of github.com:jantman/gitpython_issue_301 +6a008841b2663989f88462f4cd380b937ecf9c3d not-for-merge branch 'testcommit3885' of github.com:jantman/gitpython_issue_301 +c3df063f6aca1ce970d214a119dd43032240dbdc not-for-merge branch 'testcommit3886' of github.com:jantman/gitpython_issue_301 +f0c5a30075365ccf2c8d8cea3154b6eec20d312e not-for-merge branch 'testcommit3887' of github.com:jantman/gitpython_issue_301 +481dbe650d118f39ee12851d869b1d4267e18acd not-for-merge branch 'testcommit3888' of github.com:jantman/gitpython_issue_301 +c75899d799a89aa8c2e57198a11eb403e99e8723 not-for-merge branch 'testcommit3889' of github.com:jantman/gitpython_issue_301 +47236e7d14ae6d44c4fbc4ef9db53d1f425e3e00 not-for-merge branch 'testcommit389' of github.com:jantman/gitpython_issue_301 +c1de52ce86c058411bee6c935c29617c2c1ea85f not-for-merge branch 'testcommit3890' of github.com:jantman/gitpython_issue_301 +e052a0acd5f69553e11b412c09a86c1b1417fa53 not-for-merge branch 'testcommit3891' of github.com:jantman/gitpython_issue_301 +10efe2e6093685f272e15d10f888a3168c41bb8c not-for-merge branch 'testcommit3892' of github.com:jantman/gitpython_issue_301 +e247f10d9d5991ab02e451395de8f7211fdcad7a not-for-merge branch 'testcommit3893' of github.com:jantman/gitpython_issue_301 +39b78b0a16a5c0ae4cac55fe66d1c15d31d393b4 not-for-merge branch 'testcommit3894' of github.com:jantman/gitpython_issue_301 +7634768feb1804de498c41fc3488438a40a45d8f not-for-merge branch 'testcommit3895' of github.com:jantman/gitpython_issue_301 +577e26732d73a0f49785e133aed5df9f97d2c9dd not-for-merge branch 'testcommit3896' of github.com:jantman/gitpython_issue_301 +c9b3d530435bd772b4c9b50348da4dae52e48fb9 not-for-merge branch 'testcommit3897' of github.com:jantman/gitpython_issue_301 +8f62c5c8b6802f1baace842ddb6eb7051f2bc98e not-for-merge branch 'testcommit3898' of github.com:jantman/gitpython_issue_301 +85e2bd9253c1b770590e12de6348efeac83a3d00 not-for-merge branch 'testcommit3899' of github.com:jantman/gitpython_issue_301 +ae4e5dbc32debf78df0206db8f52d15464c8f745 not-for-merge branch 'testcommit39' of github.com:jantman/gitpython_issue_301 +c20b5618f3138a65d792ede4ebe5fd0d936b8efe not-for-merge branch 'testcommit390' of github.com:jantman/gitpython_issue_301 +9de05fca620f1448b84ed7a460255c89787ebecc not-for-merge branch 'testcommit3900' of github.com:jantman/gitpython_issue_301 +31830de5122d1f5dab0b4217e907ad2538bea8a7 not-for-merge branch 'testcommit3901' of github.com:jantman/gitpython_issue_301 +58aa1aca5b6ee2af76f67368eda51ed8ef99a622 not-for-merge branch 'testcommit3902' of github.com:jantman/gitpython_issue_301 +caae2c1add527091145bd98da94f35a795fd005f not-for-merge branch 'testcommit3903' of github.com:jantman/gitpython_issue_301 +6b9ee22c20949f83dc0ce57b2c7f8006f86cd0bb not-for-merge branch 'testcommit3904' of github.com:jantman/gitpython_issue_301 +e5c309035697ba9f26646e0ff86964a82b51cb00 not-for-merge branch 'testcommit3905' of github.com:jantman/gitpython_issue_301 +ee468a566795e437314400664e373bd4a257d302 not-for-merge branch 'testcommit3906' of github.com:jantman/gitpython_issue_301 +432f5cc64166b3e08ca6447e177f6917ffd31248 not-for-merge branch 'testcommit3907' of github.com:jantman/gitpython_issue_301 +8fd89909b8e9cc76085588627e418e6cf14a2d2a not-for-merge branch 'testcommit3908' of github.com:jantman/gitpython_issue_301 +19f82031991f16c78d88d40eaf95eaf1a24d203d not-for-merge branch 'testcommit3909' of github.com:jantman/gitpython_issue_301 +a52f3d75f0db5fbb0b8ccd0a2cfed4912fef924a not-for-merge branch 'testcommit391' of github.com:jantman/gitpython_issue_301 +19c191e54a0a61c4a36c7c72aaada2d59c5130bd not-for-merge branch 'testcommit3910' of github.com:jantman/gitpython_issue_301 +af944c5630a1ae99ce2249a161104943fa7fb99b not-for-merge branch 'testcommit3911' of github.com:jantman/gitpython_issue_301 +8f4aee6f0f9e7b993a11dabe2c65790a59d366d2 not-for-merge branch 'testcommit3912' of github.com:jantman/gitpython_issue_301 +b5f0492ef7cb877d123b962f85eed4597e67db8e not-for-merge branch 'testcommit3913' of github.com:jantman/gitpython_issue_301 +d05ed14b900312dc83c7e045af8497361184ff7a not-for-merge branch 'testcommit3914' of github.com:jantman/gitpython_issue_301 +b43a96f581dbeacb9d96128939253ed88c450984 not-for-merge branch 'testcommit3915' of github.com:jantman/gitpython_issue_301 +af4a4fc6f65c8a6f5b6eb333591143bd78f163e0 not-for-merge branch 'testcommit3916' of github.com:jantman/gitpython_issue_301 +81ba33a17651da3c661d809324d586e094a8b9b1 not-for-merge branch 'testcommit3917' of github.com:jantman/gitpython_issue_301 +b85a4a23bc4c28303cd5682cc112d75f3d87f607 not-for-merge branch 'testcommit3918' of github.com:jantman/gitpython_issue_301 +9c95076aef310382ff41827f1464c0636b5a1ba9 not-for-merge branch 'testcommit3919' of github.com:jantman/gitpython_issue_301 +575852e533be5fcb9d28a3a1fb5e358ba7fa0176 not-for-merge branch 'testcommit392' of github.com:jantman/gitpython_issue_301 +490047e6885fce07ef7c821a1b57d78b5b0c3c62 not-for-merge branch 'testcommit3920' of github.com:jantman/gitpython_issue_301 +c269dceb110a63552de99cd1c8e54fe4ce3a018b not-for-merge branch 'testcommit3921' of github.com:jantman/gitpython_issue_301 +97e83fbb4b2a28317bc399b6ac812883d80c7aef not-for-merge branch 'testcommit3922' of github.com:jantman/gitpython_issue_301 +a5b660dc2029dd716f865a055659ad97353294b4 not-for-merge branch 'testcommit3923' of github.com:jantman/gitpython_issue_301 +a4d3b8e3164d3da3f3fa997cc7d421230ead8392 not-for-merge branch 'testcommit3924' of github.com:jantman/gitpython_issue_301 +ca2e5c8f02a95ef9cf52ef0a9769421d6b332435 not-for-merge branch 'testcommit3925' of github.com:jantman/gitpython_issue_301 +3a6b7b9bdc8706963e6991f83aac55e0d1b36aea not-for-merge branch 'testcommit3926' of github.com:jantman/gitpython_issue_301 +c03543c9ceddbfda1c6df4085c9b9ce1fd2ac784 not-for-merge branch 'testcommit3927' of github.com:jantman/gitpython_issue_301 +3ae95906f301e06d57a4335f294acabc46473436 not-for-merge branch 'testcommit3928' of github.com:jantman/gitpython_issue_301 +cf26748ecb963deaf0b216860db4099547484723 not-for-merge branch 'testcommit3929' of github.com:jantman/gitpython_issue_301 +c1ed414955bb0fcb0756c63e986aa1b49477f9ed not-for-merge branch 'testcommit393' of github.com:jantman/gitpython_issue_301 +82fff8d60219b4853b316c84232a50ad381deffe not-for-merge branch 'testcommit3930' of github.com:jantman/gitpython_issue_301 +25d6987a8a4da6b5deabe297123c8fa7fa610572 not-for-merge branch 'testcommit3931' of github.com:jantman/gitpython_issue_301 +0089ee8a1067b293456f5e35aa8e47097e290376 not-for-merge branch 'testcommit3932' of github.com:jantman/gitpython_issue_301 +dedc65439ca2cb52898d3c14afc666171a1a03af not-for-merge branch 'testcommit3933' of github.com:jantman/gitpython_issue_301 +a6db19fc66b736370a7d61f236435255af22c82e not-for-merge branch 'testcommit3934' of github.com:jantman/gitpython_issue_301 +3fb6ae79fbe4e642818f80b27004c838036ad1ed not-for-merge branch 'testcommit3935' of github.com:jantman/gitpython_issue_301 +2a1bc1f05f220461c1f6153ecfdf352978978569 not-for-merge branch 'testcommit3936' of github.com:jantman/gitpython_issue_301 +812f1c62b4e623ea073bd89c9cdcafd9385b6c3b not-for-merge branch 'testcommit3937' of github.com:jantman/gitpython_issue_301 +ae762f6f3a6e0b05005b4c3567dfd88cab81eb0e not-for-merge branch 'testcommit3938' of github.com:jantman/gitpython_issue_301 +2f38a3ce46a3e19e05c2b7950bace89ebe03298d not-for-merge branch 'testcommit3939' of github.com:jantman/gitpython_issue_301 +43eb9dcda46bfafa70501c69c9e7b0fbd368fda7 not-for-merge branch 'testcommit394' of github.com:jantman/gitpython_issue_301 +5bc21149b222627f2fa05a871e325a9f5b3cd9fd not-for-merge branch 'testcommit3940' of github.com:jantman/gitpython_issue_301 +217f80b9511a361bf07f0d108d745bf6b725475c not-for-merge branch 'testcommit3941' of github.com:jantman/gitpython_issue_301 +fbdbd51e2c00acd28271b1546063436c6d2b1249 not-for-merge branch 'testcommit3942' of github.com:jantman/gitpython_issue_301 +88492ddd36cdc0ac1bfe9ef7b63e3caf4b29fe5a not-for-merge branch 'testcommit3943' of github.com:jantman/gitpython_issue_301 +178747bc40e5e432ca98c3edb2e20bb15b7f043b not-for-merge branch 'testcommit3944' of github.com:jantman/gitpython_issue_301 +6f3c5b26a051220d90e10a7b58f030213d2bb2dd not-for-merge branch 'testcommit3945' of github.com:jantman/gitpython_issue_301 +e2bffffff64411c2529c8397da8e593ff6bf834b not-for-merge branch 'testcommit3946' of github.com:jantman/gitpython_issue_301 +f29b87f309dc471a3438d8c011f54473d2f45edb not-for-merge branch 'testcommit3947' of github.com:jantman/gitpython_issue_301 +32d072fb2d85814484a1e223e71876debc111178 not-for-merge branch 'testcommit3948' of github.com:jantman/gitpython_issue_301 +13e455f8e0a8e3f2b8cbd44d73922cef86973421 not-for-merge branch 'testcommit3949' of github.com:jantman/gitpython_issue_301 +e4b34245d67b9eb6f9217478bab4d1d92c1d9df2 not-for-merge branch 'testcommit395' of github.com:jantman/gitpython_issue_301 +23ea6f454d71b34836e99736df567310495a5de2 not-for-merge branch 'testcommit3950' of github.com:jantman/gitpython_issue_301 +cc432fc87c155335c19d09a67bdd9165f6edfa87 not-for-merge branch 'testcommit3951' of github.com:jantman/gitpython_issue_301 +ff70aa4c8aa63a72de2b3fc1e92b9087ac9ac514 not-for-merge branch 'testcommit3952' of github.com:jantman/gitpython_issue_301 +b2e76d965d61397ae2b3f3ccb6b3fc0571d01bb4 not-for-merge branch 'testcommit3953' of github.com:jantman/gitpython_issue_301 +7532a90ad0732713c88cf2b966c1c11b9d8f2ba4 not-for-merge branch 'testcommit3954' of github.com:jantman/gitpython_issue_301 +68cea90b78fa81c749af1918ba924717aefa2646 not-for-merge branch 'testcommit3955' of github.com:jantman/gitpython_issue_301 +72beb00653155a83df4edb3eb3862479fd438595 not-for-merge branch 'testcommit3956' of github.com:jantman/gitpython_issue_301 +34c3ffa21c620f35a597fb2b4f9518244b0b8e5a not-for-merge branch 'testcommit3957' of github.com:jantman/gitpython_issue_301 +8582437515e93151ce6720b7ea29ae300cbc4cf5 not-for-merge branch 'testcommit3958' of github.com:jantman/gitpython_issue_301 +7d535dd2bde187727dbc8eaacae7c761c7af470f not-for-merge branch 'testcommit3959' of github.com:jantman/gitpython_issue_301 +bc0d42c3092a64fbbc5ce32caa81647d70c20cb4 not-for-merge branch 'testcommit396' of github.com:jantman/gitpython_issue_301 +534cf384f669e31ba7f9096a8bb6ec420f8136ff not-for-merge branch 'testcommit3960' of github.com:jantman/gitpython_issue_301 +fa4a9bf037332a4f008166287f3da05d971154ca not-for-merge branch 'testcommit3961' of github.com:jantman/gitpython_issue_301 +c7e1fe9a4b894d71a60473cfa04f557c8383eab8 not-for-merge branch 'testcommit3962' of github.com:jantman/gitpython_issue_301 +b1c1e6335791defeab18021e8661093cf326e7fd not-for-merge branch 'testcommit3963' of github.com:jantman/gitpython_issue_301 +49d42154c2a1375d17eadef801e98e59829bf5c0 not-for-merge branch 'testcommit3964' of github.com:jantman/gitpython_issue_301 +c84e8b83cbb1913dfafa1456fd3e23ffb9b5ba14 not-for-merge branch 'testcommit3965' of github.com:jantman/gitpython_issue_301 +f1fa9558d014e3a1548ff62d9d3d494becdc3a44 not-for-merge branch 'testcommit3966' of github.com:jantman/gitpython_issue_301 +77ca3dff38ebe8062eee6faa595ac2ecfc0b035f not-for-merge branch 'testcommit3967' of github.com:jantman/gitpython_issue_301 +ff856b5506c50535f115c72346c1fba1d19fec47 not-for-merge branch 'testcommit3968' of github.com:jantman/gitpython_issue_301 +ee88a97ab293a58994ec2ac89e993104041df1a8 not-for-merge branch 'testcommit3969' of github.com:jantman/gitpython_issue_301 +876612dd370bea75d1943a6a739b9ffee178d838 not-for-merge branch 'testcommit397' of github.com:jantman/gitpython_issue_301 +261f2a9f0dcf870e06d225d061c0292c27b84a26 not-for-merge branch 'testcommit3970' of github.com:jantman/gitpython_issue_301 +62ee01070a967cbca5281123ed683e9b0b658dab not-for-merge branch 'testcommit3971' of github.com:jantman/gitpython_issue_301 +a82934cbc6b58d6c8b20ca6799be683b76820375 not-for-merge branch 'testcommit3972' of github.com:jantman/gitpython_issue_301 +0c379e1d14aa6877e725642e1736ddb3d10ef4dc not-for-merge branch 'testcommit3973' of github.com:jantman/gitpython_issue_301 +782f11870e125bdea8ed6caf09cc1cd9abb87502 not-for-merge branch 'testcommit3974' of github.com:jantman/gitpython_issue_301 +2d53f9b7fb6575cae61e12a7903d489d845e68ec not-for-merge branch 'testcommit3975' of github.com:jantman/gitpython_issue_301 +d283cecf24f99da4b256cfe7ed88f17c3b1a4a46 not-for-merge branch 'testcommit3976' of github.com:jantman/gitpython_issue_301 +e6734afe8c81a6e0809f7b01ff64625dea7fbdc7 not-for-merge branch 'testcommit3977' of github.com:jantman/gitpython_issue_301 +83e5d2061f3cd84fb9c0a4b231cfe61c30b92fad not-for-merge branch 'testcommit3978' of github.com:jantman/gitpython_issue_301 +1c73e98917df4fab77954699eed0b4be776abb7b not-for-merge branch 'testcommit3979' of github.com:jantman/gitpython_issue_301 +5fa08cb503349586a195155aa475d5ec80efd483 not-for-merge branch 'testcommit398' of github.com:jantman/gitpython_issue_301 +ef8c527035ec9e33ee5ba57657163999ec13eac8 not-for-merge branch 'testcommit3980' of github.com:jantman/gitpython_issue_301 +6b13196ac6155308d6e21633f21ac3da99b3d0fb not-for-merge branch 'testcommit3981' of github.com:jantman/gitpython_issue_301 +88b81d922ec0a4ccb3ead64c8d0b29f079e6a7a3 not-for-merge branch 'testcommit3982' of github.com:jantman/gitpython_issue_301 +cc18ba44027b1114631ce115f686ae0f969804e9 not-for-merge branch 'testcommit3983' of github.com:jantman/gitpython_issue_301 +187d32a59ecc039110528449122d5809800c432c not-for-merge branch 'testcommit3984' of github.com:jantman/gitpython_issue_301 +a9654e8caaf29bc5c0bb5d26d1f2812af6e6c968 not-for-merge branch 'testcommit3985' of github.com:jantman/gitpython_issue_301 +5b3ecadd90fefb523dd8013f198ae560f72d0059 not-for-merge branch 'testcommit3986' of github.com:jantman/gitpython_issue_301 +c662ba860c1b51225553ded9022ee04f80aedd62 not-for-merge branch 'testcommit3987' of github.com:jantman/gitpython_issue_301 +be2f735ddcbf91a3924d55413a0ae29016d3228d not-for-merge branch 'testcommit3988' of github.com:jantman/gitpython_issue_301 +392aa250616fcc992c0bd9ee15e4250e63b07f77 not-for-merge branch 'testcommit3989' of github.com:jantman/gitpython_issue_301 +3827cbdbfd6830b7739150bee9128d83d68aa01d not-for-merge branch 'testcommit399' of github.com:jantman/gitpython_issue_301 +550a61339fd437486766e706c5fe04714f0fce34 not-for-merge branch 'testcommit3990' of github.com:jantman/gitpython_issue_301 +6bc63f3a76a47e336750cb38cccce71ca40a0401 not-for-merge branch 'testcommit3991' of github.com:jantman/gitpython_issue_301 +c797e5ed80f575cc221978020fe812c1c8acc91b not-for-merge branch 'testcommit3992' of github.com:jantman/gitpython_issue_301 +96054ce74df3dc430338cb94c26e7d244fbe6e34 not-for-merge branch 'testcommit3993' of github.com:jantman/gitpython_issue_301 +a291f78b8b373e249aa47abc528a42dfd5fcedf1 not-for-merge branch 'testcommit3994' of github.com:jantman/gitpython_issue_301 +99b9567903c2b71e2e76443860363286f23b30e3 not-for-merge branch 'testcommit3995' of github.com:jantman/gitpython_issue_301 +6f3b47d29dd7167613e590833998bfc547b8a9e4 not-for-merge branch 'testcommit3996' of github.com:jantman/gitpython_issue_301 +c7c6bbadca5655c92a1826a367eaf52ebbdb22aa not-for-merge branch 'testcommit3997' of github.com:jantman/gitpython_issue_301 +efe37e0e58a455ac6dcbca3de86bc2d3f27e1356 not-for-merge branch 'testcommit3998' of github.com:jantman/gitpython_issue_301 +dac06c4f56c9cd01052afe06cfd091ac4916cd62 not-for-merge branch 'testcommit3999' of github.com:jantman/gitpython_issue_301 +c56dda9a31bce0ce44ae875c6ad74af667e459b6 not-for-merge branch 'testcommit4' of github.com:jantman/gitpython_issue_301 +cd19da4bc14cdae6b77a7dbba787a6d2f065b0b0 not-for-merge branch 'testcommit40' of github.com:jantman/gitpython_issue_301 +7abb93dae4104614991985b7d2aef8e54d836147 not-for-merge branch 'testcommit400' of github.com:jantman/gitpython_issue_301 +a3057349cb84f2c3341c8f67e92e7052be0c52e3 not-for-merge branch 'testcommit4000' of github.com:jantman/gitpython_issue_301 +5358762b1ab961cb0398e4a9274d4424b6a10f3a not-for-merge branch 'testcommit4001' of github.com:jantman/gitpython_issue_301 +de0f23b36622345d70001b86f649f08bca6120b9 not-for-merge branch 'testcommit4002' of github.com:jantman/gitpython_issue_301 +79536cee3c4853dd28eff9a0eb9df8e2e69aa978 not-for-merge branch 'testcommit4003' of github.com:jantman/gitpython_issue_301 +348c092e43e6917093a3c5eb244589e30a0748dc not-for-merge branch 'testcommit4004' of github.com:jantman/gitpython_issue_301 +2a18319059144dac173a41028c9702099ab63ba9 not-for-merge branch 'testcommit4005' of github.com:jantman/gitpython_issue_301 +a20c3c9528b17084fe7d626aefe37bbcd9937a1d not-for-merge branch 'testcommit4006' of github.com:jantman/gitpython_issue_301 +f70b4170dc18f96640b761b6ea9446ac37740bbd not-for-merge branch 'testcommit4007' of github.com:jantman/gitpython_issue_301 +2f122f8dc735349b6e26ebc5ab4e809e3f00f73a not-for-merge branch 'testcommit4008' of github.com:jantman/gitpython_issue_301 +33918c425a06438d60e18939c88cb643b6d04d8a not-for-merge branch 'testcommit4009' of github.com:jantman/gitpython_issue_301 +927357356994d3125ac1e12886fe2631dd90f67b not-for-merge branch 'testcommit401' of github.com:jantman/gitpython_issue_301 +cd841ae3cf7d087c3759e657d0d5449738f27ded not-for-merge branch 'testcommit4010' of github.com:jantman/gitpython_issue_301 +10fe8b899896f6b924d1cbe90566f8dfac337cbd not-for-merge branch 'testcommit4011' of github.com:jantman/gitpython_issue_301 +05f77736b3cd428695c60124e1c289a3a4946255 not-for-merge branch 'testcommit4012' of github.com:jantman/gitpython_issue_301 +6f267ccd7c5a93bfb31412597102e6caf89678cf not-for-merge branch 'testcommit4013' of github.com:jantman/gitpython_issue_301 +8b92238d1f138827eb327da6a2516d50e704bd40 not-for-merge branch 'testcommit4014' of github.com:jantman/gitpython_issue_301 +246841451517c0abe79966f7a42ea9ab8b17eff9 not-for-merge branch 'testcommit4015' of github.com:jantman/gitpython_issue_301 +687270d6451fb71008167bb488e6768965ac3380 not-for-merge branch 'testcommit4016' of github.com:jantman/gitpython_issue_301 +3d119d07682eddfdcab617490db33e81fcec4bce not-for-merge branch 'testcommit4017' of github.com:jantman/gitpython_issue_301 +b313749ee7d1558b99264f69f0ccbbc2199606fa not-for-merge branch 'testcommit4018' of github.com:jantman/gitpython_issue_301 +db4015b9928b1b7dd5f503c35f891769d441cd47 not-for-merge branch 'testcommit4019' of github.com:jantman/gitpython_issue_301 +c7e1fbc3d44ead19ec235908ed8ac47471b233ed not-for-merge branch 'testcommit402' of github.com:jantman/gitpython_issue_301 +6bedb5576b0131c7186d33ac1bee197021daa5db not-for-merge branch 'testcommit4020' of github.com:jantman/gitpython_issue_301 +5b1b591cd7167b9a51a2f40da8fc3aaa06e40a56 not-for-merge branch 'testcommit4021' of github.com:jantman/gitpython_issue_301 +f3f98a8fdcf6a316255302b577d4d7846e0ec18f not-for-merge branch 'testcommit4022' of github.com:jantman/gitpython_issue_301 +8da4a37941fc057d795791b4ae589f01fc01bbaf not-for-merge branch 'testcommit4023' of github.com:jantman/gitpython_issue_301 +7e540d9e2434dfdc9dd8d109703d8d7b3163906d not-for-merge branch 'testcommit4024' of github.com:jantman/gitpython_issue_301 +de06085b5ef53091166e2437c99de8c108c4c4b1 not-for-merge branch 'testcommit4025' of github.com:jantman/gitpython_issue_301 +5e54e4db2051564e1b0626a1b5461f217b6939e8 not-for-merge branch 'testcommit4026' of github.com:jantman/gitpython_issue_301 +77d5c8fbea8cecf44a12cde9b29755c683d8454b not-for-merge branch 'testcommit4027' of github.com:jantman/gitpython_issue_301 +c228eeae6ba7dd12f9a9d7fc7c88ea24ca2664f7 not-for-merge branch 'testcommit4028' of github.com:jantman/gitpython_issue_301 +e07cbe543fa0cb2af596f20846f051650f4eeec2 not-for-merge branch 'testcommit4029' of github.com:jantman/gitpython_issue_301 +5d958ec88e74dfe9d2bfef4c88f0b0937c12b786 not-for-merge branch 'testcommit403' of github.com:jantman/gitpython_issue_301 +c0d19655a36c81b44fcda654790e9a2a375339ef not-for-merge branch 'testcommit4030' of github.com:jantman/gitpython_issue_301 +330b75d8f7913e5a6878c619dc4a95aecf6a5ae5 not-for-merge branch 'testcommit4031' of github.com:jantman/gitpython_issue_301 +9d03c61d8f812d62d0074efb2b20b8815024b1c2 not-for-merge branch 'testcommit4032' of github.com:jantman/gitpython_issue_301 +1b836213c97df34c5d26a1c5fc3e8d6aaa323ada not-for-merge branch 'testcommit4033' of github.com:jantman/gitpython_issue_301 +52262971afa1c0cae172eb1bff8a47ec911e469c not-for-merge branch 'testcommit4034' of github.com:jantman/gitpython_issue_301 +c44e48906b25a14c1187b0b7723f795783fafed0 not-for-merge branch 'testcommit4035' of github.com:jantman/gitpython_issue_301 +7842c2ace69308d7d74713f4ebc2a6b46a9fce4d not-for-merge branch 'testcommit4036' of github.com:jantman/gitpython_issue_301 +532d701491c84febbb793b5547a52a6c72be7602 not-for-merge branch 'testcommit4037' of github.com:jantman/gitpython_issue_301 +ce21b5885df28065a0417d23b34ad477020e407f not-for-merge branch 'testcommit4038' of github.com:jantman/gitpython_issue_301 +3927e886289d6a72aa25e992f4eddc4318c676e5 not-for-merge branch 'testcommit4039' of github.com:jantman/gitpython_issue_301 +cbd04044fe1d588f8d61126745d410b81e32b9fb not-for-merge branch 'testcommit404' of github.com:jantman/gitpython_issue_301 +a0fa8b6ddd23659efe72d13c8a5ee4013d4397c7 not-for-merge branch 'testcommit4040' of github.com:jantman/gitpython_issue_301 +ba0eab61c334efeae93d258dc7ac6a2d5ca3a133 not-for-merge branch 'testcommit4041' of github.com:jantman/gitpython_issue_301 +a0cc10b6e2fb3ae452d430c398f72f8229082efb not-for-merge branch 'testcommit4042' of github.com:jantman/gitpython_issue_301 +087089b004fd9b83778da1ded72721be43eae911 not-for-merge branch 'testcommit4043' of github.com:jantman/gitpython_issue_301 +94a527fc009b5b5999f483fee61312712c3dbb25 not-for-merge branch 'testcommit4044' of github.com:jantman/gitpython_issue_301 +2db7da14d9cc0ba84d4b78d559a3db76e312213b not-for-merge branch 'testcommit4045' of github.com:jantman/gitpython_issue_301 +92dd8c1419d56d1ed224ac103242b0027d9b4356 not-for-merge branch 'testcommit4046' of github.com:jantman/gitpython_issue_301 +9fb3f08d7ad6712b2d651793bb350600c70368a2 not-for-merge branch 'testcommit4047' of github.com:jantman/gitpython_issue_301 +3aa6a483a589a9acdc3d47aa6486b415e9a69c10 not-for-merge branch 'testcommit4048' of github.com:jantman/gitpython_issue_301 +fa45581b164ce0e74623bbfb70ecc5dd81fd49c2 not-for-merge branch 'testcommit4049' of github.com:jantman/gitpython_issue_301 +7aedf8e4427db7ec44b57eb2fc0f434fe4a13cd6 not-for-merge branch 'testcommit405' of github.com:jantman/gitpython_issue_301 +09cb9142c378309dec91dfad0c9cdd09af70f543 not-for-merge branch 'testcommit4050' of github.com:jantman/gitpython_issue_301 +3404dc645d9a88d31a54653fc38bad29b4d86944 not-for-merge branch 'testcommit4051' of github.com:jantman/gitpython_issue_301 +f905990221e897bc3ca10a32725a0459315bbaaa not-for-merge branch 'testcommit4052' of github.com:jantman/gitpython_issue_301 +fb811172515a2450d659abeca7df66dfd12992c7 not-for-merge branch 'testcommit4053' of github.com:jantman/gitpython_issue_301 +ff51970eb5375a563186f066f996afdd274ba2ea not-for-merge branch 'testcommit4054' of github.com:jantman/gitpython_issue_301 +8afb80ae78462c69e95a63ad516c378626f0dd21 not-for-merge branch 'testcommit4055' of github.com:jantman/gitpython_issue_301 +db014d419614efa2d5d450e2eb2808a5323101bd not-for-merge branch 'testcommit4056' of github.com:jantman/gitpython_issue_301 +9baca685a34ba36450b2367b9b478ec933dd41f9 not-for-merge branch 'testcommit4057' of github.com:jantman/gitpython_issue_301 +42d5da9ea17416dd47a7d70c3f16a853638b4502 not-for-merge branch 'testcommit4058' of github.com:jantman/gitpython_issue_301 +39bcf12a3ba9dc1f27986ef48b7c98c98923c256 not-for-merge branch 'testcommit4059' of github.com:jantman/gitpython_issue_301 +8509c5938858a35c0da64cb2822f34bb9320769e not-for-merge branch 'testcommit406' of github.com:jantman/gitpython_issue_301 +e88cf4316029e6fa15cb9e34ad41c6ab6c29209a not-for-merge branch 'testcommit4060' of github.com:jantman/gitpython_issue_301 +593e2b8677f1fd16099579283f44b7f46902bbdd not-for-merge branch 'testcommit4061' of github.com:jantman/gitpython_issue_301 +ce4855b2af0d078e077a2d4ab8f31d82b2dc44d8 not-for-merge branch 'testcommit4062' of github.com:jantman/gitpython_issue_301 +c8f1c1b94d6075ef9c6a1fb9a9565b1652fd3c41 not-for-merge branch 'testcommit4063' of github.com:jantman/gitpython_issue_301 +4c54915e6970303ac15fddf4237097286f242ace not-for-merge branch 'testcommit4064' of github.com:jantman/gitpython_issue_301 +3c26a7cce755928ff9e6c605d3b9d8596b7e2aa0 not-for-merge branch 'testcommit4065' of github.com:jantman/gitpython_issue_301 +fc015a34249a5c40548e0d494690a1d743f7ddc8 not-for-merge branch 'testcommit4066' of github.com:jantman/gitpython_issue_301 +f6f9e29e636eacc0f84654498761cde7e40d6d10 not-for-merge branch 'testcommit4067' of github.com:jantman/gitpython_issue_301 +593f3d7d01994f0bdb915ef173e7c0672bfa7149 not-for-merge branch 'testcommit4068' of github.com:jantman/gitpython_issue_301 +e6c1b2533e620be24b622b5f072bc58d9667421a not-for-merge branch 'testcommit4069' of github.com:jantman/gitpython_issue_301 +c3e134eb0e6412c29c8986f3db9a3007c9e904f4 not-for-merge branch 'testcommit407' of github.com:jantman/gitpython_issue_301 +3e865da172caa19dacadec4d1c1ee3cf6379252b not-for-merge branch 'testcommit4070' of github.com:jantman/gitpython_issue_301 +fc8ec56bfada622bd65f15976e68a7df27600b17 not-for-merge branch 'testcommit4071' of github.com:jantman/gitpython_issue_301 +dc2c7f3a1156b816caa095385203fb052522977b not-for-merge branch 'testcommit4072' of github.com:jantman/gitpython_issue_301 +59235cd36e311961707ce294af8b38d52439f53c not-for-merge branch 'testcommit4073' of github.com:jantman/gitpython_issue_301 +75a9dd00c3c1067a8fc73b4bdd889153a24b116d not-for-merge branch 'testcommit4074' of github.com:jantman/gitpython_issue_301 +0155d00d60165e6ace1f7fd482ba27732203aae0 not-for-merge branch 'testcommit4075' of github.com:jantman/gitpython_issue_301 +0c859cacd8decae0adde1bad6cb5eff4e854f950 not-for-merge branch 'testcommit4076' of github.com:jantman/gitpython_issue_301 +a3c0c245314d977cd62878f5cd17cd51826032fa not-for-merge branch 'testcommit4077' of github.com:jantman/gitpython_issue_301 +8f982d3828cbd0982301a7f5162b87676374b429 not-for-merge branch 'testcommit4078' of github.com:jantman/gitpython_issue_301 +9adb13cb65439327f4387d8324446d24900e0ce0 not-for-merge branch 'testcommit4079' of github.com:jantman/gitpython_issue_301 +e8c830c965e1333d23c673d8871a551438033248 not-for-merge branch 'testcommit408' of github.com:jantman/gitpython_issue_301 +e33e7bb720053eb08923e24c94bc9e6d93117601 not-for-merge branch 'testcommit4080' of github.com:jantman/gitpython_issue_301 +0fd0321fa5644ee42e369096288bc320532d5828 not-for-merge branch 'testcommit4081' of github.com:jantman/gitpython_issue_301 +862c7246f818e9cf9454b7df8b245b9c02d96a36 not-for-merge branch 'testcommit4082' of github.com:jantman/gitpython_issue_301 +579be41154adcd76772ccd77a787c70543f511ba not-for-merge branch 'testcommit4083' of github.com:jantman/gitpython_issue_301 +83ee0280bf19603ba7a00b5fba3543aeedd29e2d not-for-merge branch 'testcommit4084' of github.com:jantman/gitpython_issue_301 +dbeb510475029d96f4a2c738c0cd82753d7050d4 not-for-merge branch 'testcommit4085' of github.com:jantman/gitpython_issue_301 +a2ab57cc28a7ec71c8dcd5810dc5f531f0f9ff66 not-for-merge branch 'testcommit4086' of github.com:jantman/gitpython_issue_301 +ee506c723ea7dd65dc484bffdc90421ca0382d4c not-for-merge branch 'testcommit4087' of github.com:jantman/gitpython_issue_301 +ab29a0c7ce83daa6921652c64536113a3aab5b1b not-for-merge branch 'testcommit4088' of github.com:jantman/gitpython_issue_301 +7e1eea2c9ff30af51a4cbcda63f76f35de690d22 not-for-merge branch 'testcommit4089' of github.com:jantman/gitpython_issue_301 +f521958f95fb32d3fb11bb5d0a12b99f42e5a61a not-for-merge branch 'testcommit409' of github.com:jantman/gitpython_issue_301 +18015a187cbd0c4f97d963327d8c985d18c4d041 not-for-merge branch 'testcommit4090' of github.com:jantman/gitpython_issue_301 +007a67f9cbd35fdd5c249c2097fb3453a84f7839 not-for-merge branch 'testcommit4091' of github.com:jantman/gitpython_issue_301 +c2fa57e0ae22c237037085b0ed9eb38987bbfb28 not-for-merge branch 'testcommit4092' of github.com:jantman/gitpython_issue_301 +c67e8a803d00c7f7f4fa8554cb07174dec90bf30 not-for-merge branch 'testcommit4093' of github.com:jantman/gitpython_issue_301 +5907c0458adc0f42b92f64d636366df9c46c955f not-for-merge branch 'testcommit4094' of github.com:jantman/gitpython_issue_301 +732004269dad18459ab93c47ac6a1a74f6eb1da9 not-for-merge branch 'testcommit4095' of github.com:jantman/gitpython_issue_301 +4825afe0d5571f4097082e6db13e9700646b73d7 not-for-merge branch 'testcommit4096' of github.com:jantman/gitpython_issue_301 +69f46865894fd6aa551be5ab6b365c53525c7913 not-for-merge branch 'testcommit4097' of github.com:jantman/gitpython_issue_301 +817444367567e1e3fab26005cf4e867bddc7ada5 not-for-merge branch 'testcommit4098' of github.com:jantman/gitpython_issue_301 +070716d2e8774db20b50e372f288a60e63593d8f not-for-merge branch 'testcommit4099' of github.com:jantman/gitpython_issue_301 +89edc0eebe6f59e088db308d483bbb9e5a565437 not-for-merge branch 'testcommit41' of github.com:jantman/gitpython_issue_301 +1da72c8959746d417c2418c9e99b4c2196feef90 not-for-merge branch 'testcommit410' of github.com:jantman/gitpython_issue_301 +818baafdd71fceda5a715bd85738c5d75071283d not-for-merge branch 'testcommit4100' of github.com:jantman/gitpython_issue_301 +eb6459871bd448752ca35033b907f7d3535e239c not-for-merge branch 'testcommit4101' of github.com:jantman/gitpython_issue_301 +d2c56ca5c14b9bdb0c8ce6f580beb7a02b541903 not-for-merge branch 'testcommit4102' of github.com:jantman/gitpython_issue_301 +a6b12e7cc4344f4301a3f4466ae25a982cbd0ec2 not-for-merge branch 'testcommit4103' of github.com:jantman/gitpython_issue_301 +1e5219ebf4782a5fcf70a18416dfc65cd9c154c0 not-for-merge branch 'testcommit4104' of github.com:jantman/gitpython_issue_301 +0b8e42a3e17ce1f2678f6beab93441dafd799ee6 not-for-merge branch 'testcommit4105' of github.com:jantman/gitpython_issue_301 +8733ae3bdd8e56df7edc80a60101bed66a2761aa not-for-merge branch 'testcommit4106' of github.com:jantman/gitpython_issue_301 +660910e42f1340d71a23bdf66618d5d949a83301 not-for-merge branch 'testcommit4107' of github.com:jantman/gitpython_issue_301 +2f83a8e851dc10370d5ae7e69f6ec4237919f91a not-for-merge branch 'testcommit4108' of github.com:jantman/gitpython_issue_301 +3009ac844a124e04562e301d584cdc73b229df3f not-for-merge branch 'testcommit4109' of github.com:jantman/gitpython_issue_301 +2f7fef1b3362b1fbbb7abae932397f47e212da84 not-for-merge branch 'testcommit411' of github.com:jantman/gitpython_issue_301 +ceb469b927b162691381b74947e7b4612b0963c1 not-for-merge branch 'testcommit4110' of github.com:jantman/gitpython_issue_301 +403281e781f89d5c6097b968a78a63f465ccad1d not-for-merge branch 'testcommit4111' of github.com:jantman/gitpython_issue_301 +6ff326b87b2fd0000fd81cd8f7057e62a79cf9a5 not-for-merge branch 'testcommit4112' of github.com:jantman/gitpython_issue_301 +71ba0e5736c7779c03470939af3585bfd773dcc1 not-for-merge branch 'testcommit4113' of github.com:jantman/gitpython_issue_301 +b5b81f5c311b4b500f63b507bd9cc9355573988b not-for-merge branch 'testcommit4114' of github.com:jantman/gitpython_issue_301 +0ff98aeb88a477c7a1ec227d0115617339b171e3 not-for-merge branch 'testcommit4115' of github.com:jantman/gitpython_issue_301 +5756ac1e1783a34c0937c2fd83e2cc87cb88294b not-for-merge branch 'testcommit4116' of github.com:jantman/gitpython_issue_301 +a82fe6ef0c179e6fe15e03cad16511da5935c90d not-for-merge branch 'testcommit4117' of github.com:jantman/gitpython_issue_301 +ca0ef2aa22ab9dd0f86a87bdf4161c2eaa6583d9 not-for-merge branch 'testcommit4118' of github.com:jantman/gitpython_issue_301 +62c6eaf594bb251a5a87af34209c7f91b0590317 not-for-merge branch 'testcommit4119' of github.com:jantman/gitpython_issue_301 +5c1c2349679962ab3090f9b92d520e825c59a98f not-for-merge branch 'testcommit412' of github.com:jantman/gitpython_issue_301 +037e40cb0438b32ab3edbafb77cf50142ecd3c7a not-for-merge branch 'testcommit4120' of github.com:jantman/gitpython_issue_301 +3584ac42f83e4c531e8f1269a1cf80a70ccd88c7 not-for-merge branch 'testcommit4121' of github.com:jantman/gitpython_issue_301 +243930bd7c93661a57e70777cb8e939df3605435 not-for-merge branch 'testcommit4122' of github.com:jantman/gitpython_issue_301 +9b33f39769700d0fa6d7bb2fde7641f6de192569 not-for-merge branch 'testcommit4123' of github.com:jantman/gitpython_issue_301 +420dd4eb61f9dca8ac8d131664264d48832b7b44 not-for-merge branch 'testcommit4124' of github.com:jantman/gitpython_issue_301 +46f6813377e5dbcf7db21eaf82e8d77191db3340 not-for-merge branch 'testcommit4125' of github.com:jantman/gitpython_issue_301 +ebb254499e982b693c132550c96730d6d0351ab2 not-for-merge branch 'testcommit4126' of github.com:jantman/gitpython_issue_301 +4328f01bb8aaa872c566906ada956c4ee4f4f67d not-for-merge branch 'testcommit4127' of github.com:jantman/gitpython_issue_301 +0c385b6ed2eae12177b6e6720ccf308f712e51ac not-for-merge branch 'testcommit4128' of github.com:jantman/gitpython_issue_301 +bd4f028fc05551e3db377e74607b474823d2c11c not-for-merge branch 'testcommit4129' of github.com:jantman/gitpython_issue_301 +7af96f153306a47598be8147871beecbc1713adf not-for-merge branch 'testcommit413' of github.com:jantman/gitpython_issue_301 +321de3324b896a960db8dc4c6f3cc9316049f3c9 not-for-merge branch 'testcommit4130' of github.com:jantman/gitpython_issue_301 +2ea831a41f424d48a36b4187f4895ccc7f743268 not-for-merge branch 'testcommit4131' of github.com:jantman/gitpython_issue_301 +ee517fd07202141a033f0fdc408c1248a7e60edf not-for-merge branch 'testcommit4132' of github.com:jantman/gitpython_issue_301 +6b0696087264a7cae50e347b448662d644423d48 not-for-merge branch 'testcommit4133' of github.com:jantman/gitpython_issue_301 +fb739d50f566c06ac3a8f575619f994e196ca11b not-for-merge branch 'testcommit4134' of github.com:jantman/gitpython_issue_301 +68537fa01cb57a0231068e3aaa5425fb05e7970d not-for-merge branch 'testcommit4135' of github.com:jantman/gitpython_issue_301 +cb977df44b3e5d453b503480fe3593dffae53120 not-for-merge branch 'testcommit4136' of github.com:jantman/gitpython_issue_301 +6afaf7c4a5d80b914af403dac535346f7a26b4f7 not-for-merge branch 'testcommit4137' of github.com:jantman/gitpython_issue_301 +4a2e96e635d0f5d24bffa54f4b478a8f6253bb8e not-for-merge branch 'testcommit4138' of github.com:jantman/gitpython_issue_301 +eec09e14b29f953fb69d76cf9284c913ea39cf5a not-for-merge branch 'testcommit4139' of github.com:jantman/gitpython_issue_301 +526dfba10b04b3206b4e358a9bac0042022371a3 not-for-merge branch 'testcommit414' of github.com:jantman/gitpython_issue_301 +cf1d48f68aa31104c95ceef661298bdede029dfa not-for-merge branch 'testcommit4140' of github.com:jantman/gitpython_issue_301 +2842eb07b2648b32f83668e2ac308fd19ef5007a not-for-merge branch 'testcommit4141' of github.com:jantman/gitpython_issue_301 +43edf7a48f0fe52dddd282f1f7e6c31ffd82c90d not-for-merge branch 'testcommit4142' of github.com:jantman/gitpython_issue_301 +0314295173356554bbfd2ed009dcb762136e2a07 not-for-merge branch 'testcommit4143' of github.com:jantman/gitpython_issue_301 +3fb38bfca15dd806e978432e37fc0625117ae642 not-for-merge branch 'testcommit4144' of github.com:jantman/gitpython_issue_301 +2e9b25d502914c3f571c642eb870ebd639934391 not-for-merge branch 'testcommit4145' of github.com:jantman/gitpython_issue_301 +92f06134085ee62c40392f7087beefd9b5c4e770 not-for-merge branch 'testcommit4146' of github.com:jantman/gitpython_issue_301 +d486d094cf5cad4931ce81c04fd843c8e56d9786 not-for-merge branch 'testcommit4147' of github.com:jantman/gitpython_issue_301 +00f0dceadbbb627bed8914c00d2bf079fe93351b not-for-merge branch 'testcommit4148' of github.com:jantman/gitpython_issue_301 +e703419af085e56c27f5d17c55661eb1ce3af5e0 not-for-merge branch 'testcommit4149' of github.com:jantman/gitpython_issue_301 +6d00dd33b3b7e767d4a9ff2794e276a05af0a1e2 not-for-merge branch 'testcommit415' of github.com:jantman/gitpython_issue_301 +6365e1653fb25ea02119cea6afad7d7dfbab9d58 not-for-merge branch 'testcommit4150' of github.com:jantman/gitpython_issue_301 +312982ed2307c9d0dc0280b095c68b6bf2f6a3a1 not-for-merge branch 'testcommit4151' of github.com:jantman/gitpython_issue_301 +1dfb00a038f173a535e4f498d4e0142d6a904cba not-for-merge branch 'testcommit4152' of github.com:jantman/gitpython_issue_301 +641f245ded192ca856806ad107316d8762005503 not-for-merge branch 'testcommit4153' of github.com:jantman/gitpython_issue_301 +8297eef8a17bed20b5eb4b874825410c1e33b0fe not-for-merge branch 'testcommit4154' of github.com:jantman/gitpython_issue_301 +811445b71050da518ce1b7d0316b30aa4124bde8 not-for-merge branch 'testcommit4155' of github.com:jantman/gitpython_issue_301 +596554f0231e6760fb0ad42540ab39abaa8eb910 not-for-merge branch 'testcommit4156' of github.com:jantman/gitpython_issue_301 +d8caf2ef1ff98f9a4e4a17af1bd21c1c7c11ad4d not-for-merge branch 'testcommit4157' of github.com:jantman/gitpython_issue_301 +e192684c93e934005574520c4d97d54cd9250874 not-for-merge branch 'testcommit4158' of github.com:jantman/gitpython_issue_301 +a569b7f0872d92d7e8d05aceac8a6455316b82ee not-for-merge branch 'testcommit4159' of github.com:jantman/gitpython_issue_301 +ede0f4bc17837284577159b2b30e039f3319133c not-for-merge branch 'testcommit416' of github.com:jantman/gitpython_issue_301 +dd1ac341efc0b2276a493ce8237f1a9551b9a45b not-for-merge branch 'testcommit4160' of github.com:jantman/gitpython_issue_301 +1fb5bea252847c08f8883c7c98ff55f138145e2a not-for-merge branch 'testcommit4161' of github.com:jantman/gitpython_issue_301 +d2244531e6297f9d69509cdee990d9edda1cd86c not-for-merge branch 'testcommit4162' of github.com:jantman/gitpython_issue_301 +6aebd8879e240e3eeeaed220f4d4a9fadb3d65d2 not-for-merge branch 'testcommit4163' of github.com:jantman/gitpython_issue_301 +1869ad9a3e6186c8b0e432be052cb1f615ed2749 not-for-merge branch 'testcommit4164' of github.com:jantman/gitpython_issue_301 +ab7d63be56fd70f9a97b87ac9c73d85183dacd85 not-for-merge branch 'testcommit4165' of github.com:jantman/gitpython_issue_301 +a63feee9af10ebf68b55a53bd49eeb9acc910d36 not-for-merge branch 'testcommit4166' of github.com:jantman/gitpython_issue_301 +0fb84e138dcc7854069aeaeb51de43a6be7d3977 not-for-merge branch 'testcommit4167' of github.com:jantman/gitpython_issue_301 +58be66059ddb9bcdb0d9723273c5a258dc89bb6a not-for-merge branch 'testcommit4168' of github.com:jantman/gitpython_issue_301 +8d7546be5c1935adf397b9c9b04dbf61e9060d6c not-for-merge branch 'testcommit4169' of github.com:jantman/gitpython_issue_301 +d595e73a3aa8380a47af94552c932c8c8f3241e5 not-for-merge branch 'testcommit417' of github.com:jantman/gitpython_issue_301 +a01209e29512f650662034a527ed481dbfb589e5 not-for-merge branch 'testcommit4170' of github.com:jantman/gitpython_issue_301 +46b36368f40ec0d24799f2d1387e33afcd09af31 not-for-merge branch 'testcommit4171' of github.com:jantman/gitpython_issue_301 +5f4088ef962bd5975c506c64689f4acc6c9a6c63 not-for-merge branch 'testcommit4172' of github.com:jantman/gitpython_issue_301 +853d14a472b7b956f2b96f7d146476a435bba36d not-for-merge branch 'testcommit4173' of github.com:jantman/gitpython_issue_301 +f1ef3acf046598deded8dec1b7577e6c9da78f46 not-for-merge branch 'testcommit4174' of github.com:jantman/gitpython_issue_301 +4b1bde66ab03b07a8a7ee5cc78a9620fdb179be0 not-for-merge branch 'testcommit4175' of github.com:jantman/gitpython_issue_301 +7ce80e49cc97ca221f9544182f7658fd2a35f383 not-for-merge branch 'testcommit4176' of github.com:jantman/gitpython_issue_301 +164003f9d136a6315ccdea77a84d635d0a39b3db not-for-merge branch 'testcommit4177' of github.com:jantman/gitpython_issue_301 +cf67e8485f4e69478c97febe3afd743320033e6e not-for-merge branch 'testcommit4178' of github.com:jantman/gitpython_issue_301 +7541e852756c8f1d9f15f42fa2ad5f2a010e836d not-for-merge branch 'testcommit4179' of github.com:jantman/gitpython_issue_301 +db2cfd26a3b56087b3dbeabfcec0fb3ead96a040 not-for-merge branch 'testcommit418' of github.com:jantman/gitpython_issue_301 +0913d611edc71036484b07c6d5b645b18f3a792f not-for-merge branch 'testcommit4180' of github.com:jantman/gitpython_issue_301 +830af02c4013de4dacd58cbd06f5bdcb74395ce9 not-for-merge branch 'testcommit4181' of github.com:jantman/gitpython_issue_301 +b9d0b88500abc81a0168da29957f193a6df887b2 not-for-merge branch 'testcommit4182' of github.com:jantman/gitpython_issue_301 +ea8af9727d554f6cfe19bb38afad42372a06700b not-for-merge branch 'testcommit4183' of github.com:jantman/gitpython_issue_301 +a0a6bb4cd9cae3e72234f2c977827023b309944b not-for-merge branch 'testcommit4184' of github.com:jantman/gitpython_issue_301 +3be1bb96bc19c7d7d2416fd34dfb2a8aef6db225 not-for-merge branch 'testcommit4185' of github.com:jantman/gitpython_issue_301 +f9ec5ec40e1925c34dc8881c30433ada21c3b2e9 not-for-merge branch 'testcommit4186' of github.com:jantman/gitpython_issue_301 +9822bb09c1c7cb2047e97cecd65cd4f27e826b72 not-for-merge branch 'testcommit4187' of github.com:jantman/gitpython_issue_301 +d2497a02fd99276e6aa78a41d9f2165bf34da7a4 not-for-merge branch 'testcommit4188' of github.com:jantman/gitpython_issue_301 +7109eda66c159e4ed00d6837cdef43048966b8d9 not-for-merge branch 'testcommit4189' of github.com:jantman/gitpython_issue_301 +be6a4c9d66ca1671da35ae0d7ab49d66b31f6e89 not-for-merge branch 'testcommit419' of github.com:jantman/gitpython_issue_301 +ac8bfbb04ed89a85027f608f3fe1e566db959892 not-for-merge branch 'testcommit4190' of github.com:jantman/gitpython_issue_301 +c79bfd51a9c3a15e31f773ef87df159707bd38a3 not-for-merge branch 'testcommit4191' of github.com:jantman/gitpython_issue_301 +37e9a93fa771ef8b8afb6322a8c1fdd3c177a4f5 not-for-merge branch 'testcommit4192' of github.com:jantman/gitpython_issue_301 +f9b09c97b68ed34e520da6dd61a6a26bfe9541c4 not-for-merge branch 'testcommit4193' of github.com:jantman/gitpython_issue_301 +8a6427ce29a8ff7768d3e8c74fa8119b8e43cef9 not-for-merge branch 'testcommit4194' of github.com:jantman/gitpython_issue_301 +a92d1ce80a0c73f13347733d5e892e3c624b2a23 not-for-merge branch 'testcommit4195' of github.com:jantman/gitpython_issue_301 +d621088f8e0d8bda4c9e1fc3da18f3cdbbd66111 not-for-merge branch 'testcommit4196' of github.com:jantman/gitpython_issue_301 +43dfe20ee61bc5752f6e58132696074a6e196db2 not-for-merge branch 'testcommit4197' of github.com:jantman/gitpython_issue_301 +88b37a4a6d56af13b327eac18521ba5442588cbb not-for-merge branch 'testcommit4198' of github.com:jantman/gitpython_issue_301 +baa0963bac8363684d2fa788d7f95b001ef8fd07 not-for-merge branch 'testcommit4199' of github.com:jantman/gitpython_issue_301 +b6cb8b5f76b5f4216c1b8003797a5f777f6f22f4 not-for-merge branch 'testcommit42' of github.com:jantman/gitpython_issue_301 +13a3c9b587f3d835e234e4850d7aaa0ad49fec68 not-for-merge branch 'testcommit420' of github.com:jantman/gitpython_issue_301 +2a0b7a5d3ac6662a9635a3e2b83cc57469384a7f not-for-merge branch 'testcommit4200' of github.com:jantman/gitpython_issue_301 +4702d99bc49b1837942d6e70491f7f6d6f2c47bc not-for-merge branch 'testcommit4201' of github.com:jantman/gitpython_issue_301 +f498b770fbd87982f8db3d3d9c8df0ffd31ad750 not-for-merge branch 'testcommit4202' of github.com:jantman/gitpython_issue_301 +60fc41cfeb9a4be3077658927d54802822d2a553 not-for-merge branch 'testcommit4203' of github.com:jantman/gitpython_issue_301 +724f09f803de62e291194e2390034e144fe4c33d not-for-merge branch 'testcommit4204' of github.com:jantman/gitpython_issue_301 +a97cd718f1a62de320e2905dd9ad10db5b7ebb82 not-for-merge branch 'testcommit4205' of github.com:jantman/gitpython_issue_301 +7407f315d3f648f7410321be7bc3afd3f331dafe not-for-merge branch 'testcommit4206' of github.com:jantman/gitpython_issue_301 +eecb3f22f2cb4946c4762dedd1187df9e75c988b not-for-merge branch 'testcommit4207' of github.com:jantman/gitpython_issue_301 +b47e81cc6216e90a76f78fffcad62f0ae1cf9328 not-for-merge branch 'testcommit4208' of github.com:jantman/gitpython_issue_301 +638eb215cf6acc59fc0132d7686a30f160f2b2a1 not-for-merge branch 'testcommit4209' of github.com:jantman/gitpython_issue_301 +d8b39b4a531163e1b49b6fc6b0de2f117145ed94 not-for-merge branch 'testcommit421' of github.com:jantman/gitpython_issue_301 +618f72bf6dd7f64a428d0939127baf5c9f4dee66 not-for-merge branch 'testcommit4210' of github.com:jantman/gitpython_issue_301 +4fab3c9110a80783a315ae6499a88847331a9088 not-for-merge branch 'testcommit4211' of github.com:jantman/gitpython_issue_301 +a18b0fd70c96ee55fb6f221f60f80a23b53a447b not-for-merge branch 'testcommit4212' of github.com:jantman/gitpython_issue_301 +e343952e29681a4f719a2a96aeb0edeee16dd239 not-for-merge branch 'testcommit4213' of github.com:jantman/gitpython_issue_301 +3f88c66ef96c337a995e2c528cd0fb71e5b054ee not-for-merge branch 'testcommit4214' of github.com:jantman/gitpython_issue_301 +3d2547fb9d22ec3c93b08eb24cceb5c1e9532bbf not-for-merge branch 'testcommit4215' of github.com:jantman/gitpython_issue_301 +7cff183d464b8fa4b47d15b68ccddbadb205f4ff not-for-merge branch 'testcommit4216' of github.com:jantman/gitpython_issue_301 +f93347955813839e6bed7c3ce8b0c11ba6bb5e3e not-for-merge branch 'testcommit4217' of github.com:jantman/gitpython_issue_301 +897f1766cec3671e7aa9605f0bc135836ca5f7d9 not-for-merge branch 'testcommit4218' of github.com:jantman/gitpython_issue_301 +39cac3dd60890a9662c9de24ebe20d3252f603b2 not-for-merge branch 'testcommit4219' of github.com:jantman/gitpython_issue_301 +2f2447ea9dcdb7a457c858283138c71ac23835b0 not-for-merge branch 'testcommit422' of github.com:jantman/gitpython_issue_301 +e5e8c78b3257c591a79420dec599200a44efc6fb not-for-merge branch 'testcommit4220' of github.com:jantman/gitpython_issue_301 +44e9c45405095e4aeedbc2ee2c074010783aa3da not-for-merge branch 'testcommit4221' of github.com:jantman/gitpython_issue_301 +9950ac280ccd680de190963397643861151c1003 not-for-merge branch 'testcommit4222' of github.com:jantman/gitpython_issue_301 +bd780278e3c192a0778eb15bc2314ab814a7ab9c not-for-merge branch 'testcommit4223' of github.com:jantman/gitpython_issue_301 +87b24fbc9d785acdfe906fe0557ff6f29a505d9e not-for-merge branch 'testcommit4224' of github.com:jantman/gitpython_issue_301 +ec1568c0f58745f226d19d91e0b3d4fa05285f37 not-for-merge branch 'testcommit4225' of github.com:jantman/gitpython_issue_301 +cb7cdec01ac52ffceeb374ce52337a48533824f5 not-for-merge branch 'testcommit4226' of github.com:jantman/gitpython_issue_301 +451f49c5876c0ef1a8c33618df4914fa4f61e67d not-for-merge branch 'testcommit4227' of github.com:jantman/gitpython_issue_301 +b39a2a7261821ba8833592131e1b3e07c9c86505 not-for-merge branch 'testcommit4228' of github.com:jantman/gitpython_issue_301 +75e0054cd2cfec9a2df7fdd48e560ac73029f71a not-for-merge branch 'testcommit4229' of github.com:jantman/gitpython_issue_301 +ea2aa5d80589d7cbf4dd2e8771cfe7390ed35a25 not-for-merge branch 'testcommit423' of github.com:jantman/gitpython_issue_301 +c15af982dfe3ae42eb3165be8ba34c5d3263535c not-for-merge branch 'testcommit4230' of github.com:jantman/gitpython_issue_301 +4f71bf5bb31383eb7be0fcb890a456df7ca97778 not-for-merge branch 'testcommit4231' of github.com:jantman/gitpython_issue_301 +fd9c2b8efd831bfe902ce24e8e1d6fa8c4d5fb6f not-for-merge branch 'testcommit4232' of github.com:jantman/gitpython_issue_301 +d7827dc0d42b082cb2c0e294eea4b42af57b8d5a not-for-merge branch 'testcommit4233' of github.com:jantman/gitpython_issue_301 +7f5a6cfb4c77bfb044978ce9b078ef4cb3342538 not-for-merge branch 'testcommit4234' of github.com:jantman/gitpython_issue_301 +c91bbb91791b5c37511d8e787a198814cc07c752 not-for-merge branch 'testcommit4235' of github.com:jantman/gitpython_issue_301 +5207bd77a894c1d3a24e6a6a2240af466644e976 not-for-merge branch 'testcommit4236' of github.com:jantman/gitpython_issue_301 +dc63c8af81665db5ed0d2f6ee7f6073b611ac37f not-for-merge branch 'testcommit4237' of github.com:jantman/gitpython_issue_301 +460bf9fb9b7468abe2def99efd16ac8905d7b4fe not-for-merge branch 'testcommit4238' of github.com:jantman/gitpython_issue_301 +0b37fb22cfa0bc3f31b6a3a05561cd3a369b4e0f not-for-merge branch 'testcommit4239' of github.com:jantman/gitpython_issue_301 +514f54afd508cc6d44d9994b76f220965b17c435 not-for-merge branch 'testcommit424' of github.com:jantman/gitpython_issue_301 +9d0c8f23cb283490a5eb010fde833074d8334da1 not-for-merge branch 'testcommit4240' of github.com:jantman/gitpython_issue_301 +eb70f44b7dfbafc635e01c4973067d9c6c4b06ac not-for-merge branch 'testcommit4241' of github.com:jantman/gitpython_issue_301 +2af3db4c11cde93e22baf140824e07ce5ddc0b37 not-for-merge branch 'testcommit4242' of github.com:jantman/gitpython_issue_301 +bc711556ec35c98de58cfabfbecc7731f0dccab9 not-for-merge branch 'testcommit4243' of github.com:jantman/gitpython_issue_301 +3527cc5f58665930d0437042fde5b8da7d722037 not-for-merge branch 'testcommit4244' of github.com:jantman/gitpython_issue_301 +cf0f8ac1856241fed1384d7e4a04051d2b4fab34 not-for-merge branch 'testcommit4245' of github.com:jantman/gitpython_issue_301 +ecc1bca08f3df927e6195e7719a7809c0af47347 not-for-merge branch 'testcommit4246' of github.com:jantman/gitpython_issue_301 +13c13036ab466217746a36a579031e18757ece2c not-for-merge branch 'testcommit4247' of github.com:jantman/gitpython_issue_301 +37b161a6f900deb8f74d67c8e83d8ac21f0e50c3 not-for-merge branch 'testcommit4248' of github.com:jantman/gitpython_issue_301 +7d778bdb49de4001b01bbab9792465962cb904a7 not-for-merge branch 'testcommit4249' of github.com:jantman/gitpython_issue_301 +f6b253f01493dae4a7e18a7b9a19f1ac34da3ebe not-for-merge branch 'testcommit425' of github.com:jantman/gitpython_issue_301 +b4155ec9e6ad378fc676d579a7105f7d0746624f not-for-merge branch 'testcommit4250' of github.com:jantman/gitpython_issue_301 +09c8cce5e82883d3334cfa38b23d0b97092b061a not-for-merge branch 'testcommit4251' of github.com:jantman/gitpython_issue_301 +af7d268e1568ab553c22013e5ad759c9abc927e5 not-for-merge branch 'testcommit4252' of github.com:jantman/gitpython_issue_301 +801a6c961f9107e92aade3b0e6d209711e63182d not-for-merge branch 'testcommit4253' of github.com:jantman/gitpython_issue_301 +0e13e63de3f9facb70968019db226b91827a3ad1 not-for-merge branch 'testcommit4254' of github.com:jantman/gitpython_issue_301 +11813546595917ddb6ec471662ec24c3962cb0bc not-for-merge branch 'testcommit4255' of github.com:jantman/gitpython_issue_301 +4253fa09c192cd00ca19514faceff1414b7268d7 not-for-merge branch 'testcommit4256' of github.com:jantman/gitpython_issue_301 +83e83cd37ed1eb3473b256ed1311bc709c064dc0 not-for-merge branch 'testcommit4257' of github.com:jantman/gitpython_issue_301 +906912f2bc4438e6bf20edd1d9f002b82f7a0040 not-for-merge branch 'testcommit4258' of github.com:jantman/gitpython_issue_301 +4cb5f6cc38e91a02d52779886e55a731f9fc7779 not-for-merge branch 'testcommit4259' of github.com:jantman/gitpython_issue_301 +b467e3148530a349c31f1e39c1083184a9f44089 not-for-merge branch 'testcommit426' of github.com:jantman/gitpython_issue_301 +670fb528e483588876e5f5095ab0988cc27c7349 not-for-merge branch 'testcommit4260' of github.com:jantman/gitpython_issue_301 +133150487f899adecb4f0ad35b099bea01d6ca30 not-for-merge branch 'testcommit4261' of github.com:jantman/gitpython_issue_301 +b95d4c28a71b54917f6742ff6ff6607765035687 not-for-merge branch 'testcommit4262' of github.com:jantman/gitpython_issue_301 +5faf1e02d778d626d96eddbd55ddd7143a3a9487 not-for-merge branch 'testcommit4263' of github.com:jantman/gitpython_issue_301 +787f40e92001fdd3c10da1dffdab1fc90b34d3cd not-for-merge branch 'testcommit4264' of github.com:jantman/gitpython_issue_301 +6366e0de36ca1246bfeb10fed5add7988cd252e8 not-for-merge branch 'testcommit4265' of github.com:jantman/gitpython_issue_301 +488e8fc2920368456314b0d3c23693a7ab0ef593 not-for-merge branch 'testcommit4266' of github.com:jantman/gitpython_issue_301 +7d1546852a98d66ad956a7b0ae20a78fed70a7a9 not-for-merge branch 'testcommit4267' of github.com:jantman/gitpython_issue_301 +915bb5133921b81c0d4d0f9b568aeb1c28667e15 not-for-merge branch 'testcommit4268' of github.com:jantman/gitpython_issue_301 +83d4cc2f1847da2e7d1f1916cb38e933a12e0c7a not-for-merge branch 'testcommit4269' of github.com:jantman/gitpython_issue_301 +d3afc29d37eec727e05f030418d759f5df728f41 not-for-merge branch 'testcommit427' of github.com:jantman/gitpython_issue_301 +5ebcf6641150cdd72e1d716df40a567bd5d609d2 not-for-merge branch 'testcommit4270' of github.com:jantman/gitpython_issue_301 +7cf692bc8d08e33f4eb87dcc00101f7fee58b650 not-for-merge branch 'testcommit4271' of github.com:jantman/gitpython_issue_301 +f4644fa779aa4feaf7cd17416ee5742d5d4c95d3 not-for-merge branch 'testcommit4272' of github.com:jantman/gitpython_issue_301 +244a48ac5246dbc7f64ac5b8c5705cd5d4727969 not-for-merge branch 'testcommit4273' of github.com:jantman/gitpython_issue_301 +f873f13a19f53d05c0b9a7996a71f52801a731d5 not-for-merge branch 'testcommit4274' of github.com:jantman/gitpython_issue_301 +638a7bb29eace7ea589d1a1b81fde76b60807119 not-for-merge branch 'testcommit4275' of github.com:jantman/gitpython_issue_301 +6bd419b8d460f9bda284e8a55a6ec419113153f1 not-for-merge branch 'testcommit4276' of github.com:jantman/gitpython_issue_301 +4d0a66a4fb0bfc79f86e4cc946a6202f12475cae not-for-merge branch 'testcommit4277' of github.com:jantman/gitpython_issue_301 +8a9b5c6fe777832dec3bd0299b39fe3174c38f75 not-for-merge branch 'testcommit4278' of github.com:jantman/gitpython_issue_301 +dfb9732e0c317c63e6b2fb2172f1bb731060c0ac not-for-merge branch 'testcommit4279' of github.com:jantman/gitpython_issue_301 +45153ac1921c2cc6384c28f66e08ceae0b082825 not-for-merge branch 'testcommit428' of github.com:jantman/gitpython_issue_301 +39a79dd43adb1af47d3ef6594be92f8cdc950f9a not-for-merge branch 'testcommit4280' of github.com:jantman/gitpython_issue_301 +19888fdaac686fb3533830bfc107b8a7863dda7f not-for-merge branch 'testcommit4281' of github.com:jantman/gitpython_issue_301 +3ed3f6be8b6d5558c57e04d12d694b498217aa4d not-for-merge branch 'testcommit4282' of github.com:jantman/gitpython_issue_301 +e4fac5fb397c001944725271a2e185c61e6b5698 not-for-merge branch 'testcommit4283' of github.com:jantman/gitpython_issue_301 +46557475efe2c0047ed1ae346632fc0a3304e3b4 not-for-merge branch 'testcommit4284' of github.com:jantman/gitpython_issue_301 +6f937b095019e8ccabc6e570fea3e512f6ccd0d4 not-for-merge branch 'testcommit4285' of github.com:jantman/gitpython_issue_301 +4b8c62325362460b94756e77eb0260a397a8b940 not-for-merge branch 'testcommit4286' of github.com:jantman/gitpython_issue_301 +fd4a54de5a0c28ce7193a4f611f6a82edae91da6 not-for-merge branch 'testcommit4287' of github.com:jantman/gitpython_issue_301 +5a97284694047ebb82153a61474330a6ed24bdb9 not-for-merge branch 'testcommit4288' of github.com:jantman/gitpython_issue_301 +2b1953ed026320b3e309c844ddd8ed34589d5cbc not-for-merge branch 'testcommit4289' of github.com:jantman/gitpython_issue_301 +d43166c7fe98ebc6e5a06b2dd0798cfb80ff1320 not-for-merge branch 'testcommit429' of github.com:jantman/gitpython_issue_301 +d396b3864db4ac28bbe5db225ec7d1fc4aed78e2 not-for-merge branch 'testcommit4290' of github.com:jantman/gitpython_issue_301 +af1ae6ba8e34b928b8d1d19fb459be5fb8832c44 not-for-merge branch 'testcommit4291' of github.com:jantman/gitpython_issue_301 +9571e2313caa879a37f597ea06955047d733d27d not-for-merge branch 'testcommit4292' of github.com:jantman/gitpython_issue_301 +0007688ec91d82aeab50c7b0b1623bdba762b45f not-for-merge branch 'testcommit4293' of github.com:jantman/gitpython_issue_301 +5d4b155f1fc2ba79b863603c77774b9d61d86b7a not-for-merge branch 'testcommit4294' of github.com:jantman/gitpython_issue_301 +23e4df6d94e2fce57301ca9fc2f6f464ac931a90 not-for-merge branch 'testcommit4295' of github.com:jantman/gitpython_issue_301 +af1e06f054364dede59d1ddda943d4648b9d3f84 not-for-merge branch 'testcommit4296' of github.com:jantman/gitpython_issue_301 +5d44f064ddd8959f582d7169a20f4f55dbbb98ec not-for-merge branch 'testcommit4297' of github.com:jantman/gitpython_issue_301 +5bb5a0c61af6ab4d571b6cab8ea48825d420c802 not-for-merge branch 'testcommit4298' of github.com:jantman/gitpython_issue_301 +f91ee50b35eacb5c084d3458e7b513bff418b74f not-for-merge branch 'testcommit4299' of github.com:jantman/gitpython_issue_301 +aee496009399b41fcf7e1c06e23e7428d72bf8b1 not-for-merge branch 'testcommit43' of github.com:jantman/gitpython_issue_301 +fbb14a0dfe679388d88b53ff11bc6a5195ffc7ff not-for-merge branch 'testcommit430' of github.com:jantman/gitpython_issue_301 +5574f8d6aae042f65aa89b44b5aae443e3b13d7e not-for-merge branch 'testcommit4300' of github.com:jantman/gitpython_issue_301 +311e193e27e89ed7e48f6d2a896866d400e89aa9 not-for-merge branch 'testcommit4301' of github.com:jantman/gitpython_issue_301 +4d100a242fc1dc369ef37eaba0a79a6e988acbc2 not-for-merge branch 'testcommit4302' of github.com:jantman/gitpython_issue_301 +d9c74c740d4dea1c3662fb11b2004007d1e155c5 not-for-merge branch 'testcommit4303' of github.com:jantman/gitpython_issue_301 +d442b2fa124546577e1e4e362cd62005162b83c1 not-for-merge branch 'testcommit4304' of github.com:jantman/gitpython_issue_301 +42efd0e74d02ff60bcc3d5ac80bb441690838948 not-for-merge branch 'testcommit4305' of github.com:jantman/gitpython_issue_301 +2cf16b9a8df342729c360db70ad668cee3d2b2e8 not-for-merge branch 'testcommit4306' of github.com:jantman/gitpython_issue_301 +7aa561fcfcad82962abfda5f7f32d8aff3e49958 not-for-merge branch 'testcommit4307' of github.com:jantman/gitpython_issue_301 +5bbfd4b2da074cd1c28ed8c55630a234ba05ccb6 not-for-merge branch 'testcommit4308' of github.com:jantman/gitpython_issue_301 +00b9cde7e621882412a6ed4deb783ee1719768e8 not-for-merge branch 'testcommit4309' of github.com:jantman/gitpython_issue_301 +6a51a03c3c6113f90d727070ef5c9cce2c90221f not-for-merge branch 'testcommit431' of github.com:jantman/gitpython_issue_301 +084c13331da4dcdba5a20adf7d7d51cc7abd675f not-for-merge branch 'testcommit4310' of github.com:jantman/gitpython_issue_301 +1285f1eef383907b7e8729aab82a1b30c3577ec2 not-for-merge branch 'testcommit4311' of github.com:jantman/gitpython_issue_301 +c1b639f92fbecf6eaacc25fb2c544c50caacc016 not-for-merge branch 'testcommit4312' of github.com:jantman/gitpython_issue_301 +3cd2333b30030eb7e674bd2c88d51c8c419b7f99 not-for-merge branch 'testcommit4313' of github.com:jantman/gitpython_issue_301 +8c40b8b280486bcc8e8b6a761806ac6c1a85bcab not-for-merge branch 'testcommit4314' of github.com:jantman/gitpython_issue_301 +94b640968873e6c6433b271f0c8f276bafae93ff not-for-merge branch 'testcommit4315' of github.com:jantman/gitpython_issue_301 +e21f029326a80242371eec95163e9ad7389f0a14 not-for-merge branch 'testcommit4316' of github.com:jantman/gitpython_issue_301 +5267fcf9ca98941bce280f43e3890f566cc53ae2 not-for-merge branch 'testcommit4317' of github.com:jantman/gitpython_issue_301 +1033147e853e29e467915bdaa91630aa2807ddc1 not-for-merge branch 'testcommit4318' of github.com:jantman/gitpython_issue_301 +4c232fb47a84fa77547014d5d7c6439ad2e5d537 not-for-merge branch 'testcommit4319' of github.com:jantman/gitpython_issue_301 +716fcdd31ff64ee6a0d3080f019beca4ba02a559 not-for-merge branch 'testcommit432' of github.com:jantman/gitpython_issue_301 +340ff849d6f7ad8d0d17018d6410c2ea6c8c8c44 not-for-merge branch 'testcommit4320' of github.com:jantman/gitpython_issue_301 +a96eba39fed5157187b4365243dff532335141a8 not-for-merge branch 'testcommit4321' of github.com:jantman/gitpython_issue_301 +f32af58119d33b096b22e6dbf4c4f392b5843021 not-for-merge branch 'testcommit4322' of github.com:jantman/gitpython_issue_301 +6ba460bc97271a490a39714f1d23a1f3a55cb2d1 not-for-merge branch 'testcommit4323' of github.com:jantman/gitpython_issue_301 +8e8b113f286c699c5e4f75c7272c5fea3669edef not-for-merge branch 'testcommit4324' of github.com:jantman/gitpython_issue_301 +80ef449a1fd98337750b51b618309cf0a128af22 not-for-merge branch 'testcommit4325' of github.com:jantman/gitpython_issue_301 +1d7d9393fd083b671c6afdd09554404f08da4fc0 not-for-merge branch 'testcommit4326' of github.com:jantman/gitpython_issue_301 +2cefa36b723cd374f14a7968c7bd7519f6f685e5 not-for-merge branch 'testcommit4327' of github.com:jantman/gitpython_issue_301 +a845546422b5e07d6411eed48764f9986797fa25 not-for-merge branch 'testcommit4328' of github.com:jantman/gitpython_issue_301 +5d646f97b92d675b8db5942204cba5f999d9130e not-for-merge branch 'testcommit4329' of github.com:jantman/gitpython_issue_301 +7acce46981c83905be9a4e02072b94a5f9965ffe not-for-merge branch 'testcommit433' of github.com:jantman/gitpython_issue_301 +5a69a0ab676c43814aca644c426cb8c97e08c039 not-for-merge branch 'testcommit4330' of github.com:jantman/gitpython_issue_301 +140a6cc8091088e45b6bc0ff07410694f8109068 not-for-merge branch 'testcommit4331' of github.com:jantman/gitpython_issue_301 +c23497f125871beeb4364b8d3a952c8446f5c9de not-for-merge branch 'testcommit4332' of github.com:jantman/gitpython_issue_301 +196e3140aa43c403e2e424bcd3787629618b2e39 not-for-merge branch 'testcommit4333' of github.com:jantman/gitpython_issue_301 +9d20fcdcd129ead7536fc5adebc3828476f86869 not-for-merge branch 'testcommit4334' of github.com:jantman/gitpython_issue_301 +80fe85f82cf7481307df110469856ec6a533231a not-for-merge branch 'testcommit4335' of github.com:jantman/gitpython_issue_301 +4a8e5cca86282ec160126703f4b0045b55214b0c not-for-merge branch 'testcommit4336' of github.com:jantman/gitpython_issue_301 +9575599c2d6da5466019d21e908be8ec55cc624d not-for-merge branch 'testcommit4337' of github.com:jantman/gitpython_issue_301 +b34746e71459701dff9574d9072a57bf2b46ca04 not-for-merge branch 'testcommit4338' of github.com:jantman/gitpython_issue_301 +9e2faf3d687bf3ec22df0c04665665f6edda3f4b not-for-merge branch 'testcommit4339' of github.com:jantman/gitpython_issue_301 +c4a9e6979f47f6d268f3f505ea5c914e2a84d10f not-for-merge branch 'testcommit434' of github.com:jantman/gitpython_issue_301 +7be80ed5327fedd97b4a4fb51f970ae269ef6ebb not-for-merge branch 'testcommit4340' of github.com:jantman/gitpython_issue_301 +9ee7ecea5f4c3107efdced8d341f7ce11e959c34 not-for-merge branch 'testcommit4341' of github.com:jantman/gitpython_issue_301 +3b6e0f8cd15f86a511fc8c4111e97510612eb646 not-for-merge branch 'testcommit4342' of github.com:jantman/gitpython_issue_301 +86688a4cb5cadb5de0c3f53572818220c474a1c9 not-for-merge branch 'testcommit4343' of github.com:jantman/gitpython_issue_301 +fe85fe4ab93d870a17010d6f7d9371cf5ec4c70c not-for-merge branch 'testcommit4344' of github.com:jantman/gitpython_issue_301 +14ffd6b22cf32d80a03f4b1ea648d7546d6ad9c4 not-for-merge branch 'testcommit4345' of github.com:jantman/gitpython_issue_301 +4ddc76d18c0a6de9028661955b3039b6b2f5a7ec not-for-merge branch 'testcommit4346' of github.com:jantman/gitpython_issue_301 +c27586b8fb98dba6859c50424b2a8c0a7223afaa not-for-merge branch 'testcommit4347' of github.com:jantman/gitpython_issue_301 +2a764cc8b1e0040b312d139af119d0594c7c54a9 not-for-merge branch 'testcommit4348' of github.com:jantman/gitpython_issue_301 +ff0cf325cc1215288ed97526c0bfb0fd68ade2f5 not-for-merge branch 'testcommit4349' of github.com:jantman/gitpython_issue_301 +ac4c812ffe9996619c618f8a15d324a363bd08f3 not-for-merge branch 'testcommit435' of github.com:jantman/gitpython_issue_301 +aaaad074a77b9843bac1d26997a304e01755a5cc not-for-merge branch 'testcommit4350' of github.com:jantman/gitpython_issue_301 +3c0e8571390b792f1c413230682b658387e3a17c not-for-merge branch 'testcommit4351' of github.com:jantman/gitpython_issue_301 +1427509de62262be2cbf9546751fdb43d5de79d6 not-for-merge branch 'testcommit4352' of github.com:jantman/gitpython_issue_301 +81d04229225937033ca6453746ce93d7ca5e3ce8 not-for-merge branch 'testcommit4353' of github.com:jantman/gitpython_issue_301 +0275ef86bf06e5238a4bbc17999cc6bb45e0038c not-for-merge branch 'testcommit4354' of github.com:jantman/gitpython_issue_301 +0986f3e6ace68680900ff3148df98ed79dcaebb6 not-for-merge branch 'testcommit4355' of github.com:jantman/gitpython_issue_301 +2a0b383b56ef331fb6970dceafc09e2d0780371c not-for-merge branch 'testcommit4356' of github.com:jantman/gitpython_issue_301 +1d7cb408b21e24969af8b5481ccbdb13a012d9a8 not-for-merge branch 'testcommit4357' of github.com:jantman/gitpython_issue_301 +91db31e6ac4fb113770476646f055e0d8b22aade not-for-merge branch 'testcommit4358' of github.com:jantman/gitpython_issue_301 +3995fd3cad983a3ef009c52b314025a782eb81c2 not-for-merge branch 'testcommit4359' of github.com:jantman/gitpython_issue_301 +ba14a452724d50421bd8583a492f6d90dc1e5a19 not-for-merge branch 'testcommit436' of github.com:jantman/gitpython_issue_301 +ac6c18660e37d361166e2d280a3151cf94d45fa3 not-for-merge branch 'testcommit4360' of github.com:jantman/gitpython_issue_301 +b9caf03fb75f35934204dcc0882a0e2b049a782e not-for-merge branch 'testcommit4361' of github.com:jantman/gitpython_issue_301 +0d107d024ca1373dc9f79af78580a4bd7945493b not-for-merge branch 'testcommit4362' of github.com:jantman/gitpython_issue_301 +ca24929e0cc31c95bb56f53caebdff1f2ed1e006 not-for-merge branch 'testcommit4363' of github.com:jantman/gitpython_issue_301 +7c9db9f4ff79d5df0b7a23da5876333e6d89818e not-for-merge branch 'testcommit4364' of github.com:jantman/gitpython_issue_301 +1eb94c645731c79c1ae4a4860035499214ede558 not-for-merge branch 'testcommit4365' of github.com:jantman/gitpython_issue_301 +2a5941a4d01730d4b7c9dc4aff3341b9e0be9d75 not-for-merge branch 'testcommit4366' of github.com:jantman/gitpython_issue_301 +12b07f1e22b39615516df67706385dbcc892a81f not-for-merge branch 'testcommit4367' of github.com:jantman/gitpython_issue_301 +6fe46856866fee5d1635800a8c2fc6d7f77da3ee not-for-merge branch 'testcommit4368' of github.com:jantman/gitpython_issue_301 +a37d2576244e0373bfc079feb8250f6f48022889 not-for-merge branch 'testcommit4369' of github.com:jantman/gitpython_issue_301 +f08eb2fe67d845661c162a1314b1e971dc958aea not-for-merge branch 'testcommit437' of github.com:jantman/gitpython_issue_301 +013fccb95a5292e5187d71ec7f3955e066c61380 not-for-merge branch 'testcommit4370' of github.com:jantman/gitpython_issue_301 +26589907f89b42ea589d4c235b623f49129bcbe2 not-for-merge branch 'testcommit4371' of github.com:jantman/gitpython_issue_301 +3a260bcaca46f71af634e74f56d01675a5d1c234 not-for-merge branch 'testcommit4372' of github.com:jantman/gitpython_issue_301 +6631205619df6c4945f4ef6fee309bc4f08d6dd0 not-for-merge branch 'testcommit4373' of github.com:jantman/gitpython_issue_301 +30cce39b0fc954e160b4cf1786a3a0ffa1b4617a not-for-merge branch 'testcommit4374' of github.com:jantman/gitpython_issue_301 +3c9b98640cfb0fe2559ae1da633f24d1f9a3752a not-for-merge branch 'testcommit4375' of github.com:jantman/gitpython_issue_301 +109259958a79146928d24246b85f82584977591a not-for-merge branch 'testcommit4376' of github.com:jantman/gitpython_issue_301 +edc6ece880a4a6ba5371e86e654a90bd70e9814b not-for-merge branch 'testcommit4377' of github.com:jantman/gitpython_issue_301 +896b9318cce73a5d4b9ea224a5f07789ff0e2be1 not-for-merge branch 'testcommit4378' of github.com:jantman/gitpython_issue_301 +80ae702e5bbe02eb6f6c7d145ae45280e3805905 not-for-merge branch 'testcommit4379' of github.com:jantman/gitpython_issue_301 +c6fcb9d00eb6eca0ad31407ffcf7894cd2c66908 not-for-merge branch 'testcommit438' of github.com:jantman/gitpython_issue_301 +2a8434dd5638b40d6aa9afeb5e8050be71b5f2a9 not-for-merge branch 'testcommit4380' of github.com:jantman/gitpython_issue_301 +33cdc26326e82563fcccc0635bd32c0a9060ac29 not-for-merge branch 'testcommit4381' of github.com:jantman/gitpython_issue_301 +6462df3856f4381080d97952bdc304ba4afc6573 not-for-merge branch 'testcommit4382' of github.com:jantman/gitpython_issue_301 +1f35196cf44caa4defebd1ac22c1e11253937253 not-for-merge branch 'testcommit4383' of github.com:jantman/gitpython_issue_301 +3dd85de6ac0840858fa1938a682c48fe2d79e93a not-for-merge branch 'testcommit4384' of github.com:jantman/gitpython_issue_301 +78f3ffdf5843761f0b9d91327659458e5ade1992 not-for-merge branch 'testcommit4385' of github.com:jantman/gitpython_issue_301 +255aab25276304702809cae1805991b3448b43a7 not-for-merge branch 'testcommit4386' of github.com:jantman/gitpython_issue_301 +d3133c9a226cca1193dcf58a0b560abcae22b12f not-for-merge branch 'testcommit4387' of github.com:jantman/gitpython_issue_301 +3e1829471df059580c6bb730abd76bdc8e7a66a9 not-for-merge branch 'testcommit4388' of github.com:jantman/gitpython_issue_301 +8914187181985887f6af95a07c74e9282ffdfa38 not-for-merge branch 'testcommit4389' of github.com:jantman/gitpython_issue_301 +f1a2cdaa81973020bad670e9e074d99f88dae293 not-for-merge branch 'testcommit439' of github.com:jantman/gitpython_issue_301 +c464e22cd642e69f63335cf17b9e4cbb6f379db6 not-for-merge branch 'testcommit4390' of github.com:jantman/gitpython_issue_301 +ec5898ad0e01985584914442c3869515ac612ad4 not-for-merge branch 'testcommit4391' of github.com:jantman/gitpython_issue_301 +16181dde49d85141b925a2a2c1e96b70dcea7833 not-for-merge branch 'testcommit4392' of github.com:jantman/gitpython_issue_301 +ca873166546896a14cb250d3815792e54921ec36 not-for-merge branch 'testcommit4393' of github.com:jantman/gitpython_issue_301 +b81fdbf0fbb0d00fc56f910424fc715f610933ce not-for-merge branch 'testcommit4394' of github.com:jantman/gitpython_issue_301 +96c0f27ebaf556208d47d8d059313625ea63175e not-for-merge branch 'testcommit4395' of github.com:jantman/gitpython_issue_301 +ee829021546fd484df753fed86f4adc309fb5293 not-for-merge branch 'testcommit4396' of github.com:jantman/gitpython_issue_301 +02c6f35c3fac8174cb77c70f4989f26e4ce360bb not-for-merge branch 'testcommit4397' of github.com:jantman/gitpython_issue_301 +5ca4479b3504ed523ae86766c355bdcbd1e73fa5 not-for-merge branch 'testcommit4398' of github.com:jantman/gitpython_issue_301 +8e7c8f8b3df7b7ea6c0ec44003c4a2ed6e4085d9 not-for-merge branch 'testcommit4399' of github.com:jantman/gitpython_issue_301 +61e37ba82dace3e06fd6955d565320d7b7f0bffd not-for-merge branch 'testcommit44' of github.com:jantman/gitpython_issue_301 +ac0846b3621936b2deb501254b84d58a77bd4bed not-for-merge branch 'testcommit440' of github.com:jantman/gitpython_issue_301 +64f401c38437344366ce90d633463930cff59c0a not-for-merge branch 'testcommit4400' of github.com:jantman/gitpython_issue_301 +dcc71a253d0c93467835cb9a5675924f19eb6ca7 not-for-merge branch 'testcommit4401' of github.com:jantman/gitpython_issue_301 +afe23e0a87bb85c1e577b8ad0df21ec74ba7f7e6 not-for-merge branch 'testcommit4402' of github.com:jantman/gitpython_issue_301 +a47754516d6b3ebfeb5d5b6b330db5dad7e71eec not-for-merge branch 'testcommit4403' of github.com:jantman/gitpython_issue_301 +770231eaffe884522f76ceddb517bcfa3b93223a not-for-merge branch 'testcommit4404' of github.com:jantman/gitpython_issue_301 +cfe72d6068a5b2157fdfc329756690605145cdae not-for-merge branch 'testcommit4405' of github.com:jantman/gitpython_issue_301 +332825d341c1989de09b5d1648cadd4ae076df08 not-for-merge branch 'testcommit4406' of github.com:jantman/gitpython_issue_301 +1d6f81356dba07b88f7a825590c1bc38cb51993f not-for-merge branch 'testcommit4407' of github.com:jantman/gitpython_issue_301 +3c225b6b84959095a167236d1f42705407b310fb not-for-merge branch 'testcommit4408' of github.com:jantman/gitpython_issue_301 +484243986b1a36da9b34fe66b1a70fd7b3b26f3c not-for-merge branch 'testcommit4409' of github.com:jantman/gitpython_issue_301 +a6360ff76a0e638213eb7e57f94468f671f3578e not-for-merge branch 'testcommit441' of github.com:jantman/gitpython_issue_301 +24be8c59047cee11835b3b0372ba1fd2c2669415 not-for-merge branch 'testcommit4410' of github.com:jantman/gitpython_issue_301 +ed8a54e70e5934d7f06dbaa0a9ada6e77b349459 not-for-merge branch 'testcommit4411' of github.com:jantman/gitpython_issue_301 +1668f330c9128acfff41b0271d79fe1b5f847b3b not-for-merge branch 'testcommit4412' of github.com:jantman/gitpython_issue_301 +08a2f3271b022c4af7bdacdd42440cf3e0c29cac not-for-merge branch 'testcommit4413' of github.com:jantman/gitpython_issue_301 +68687eb014b224870e49d3deab980d8607724bdd not-for-merge branch 'testcommit4414' of github.com:jantman/gitpython_issue_301 +a39ef3389c23b40fed33bd4872019d52cccb1d59 not-for-merge branch 'testcommit4415' of github.com:jantman/gitpython_issue_301 +09e631ddaa77f5f9cf91764fd8b8f3d640d1729b not-for-merge branch 'testcommit4416' of github.com:jantman/gitpython_issue_301 +ce62f947315d2f3174e12f1aed1e25d35cb7919b not-for-merge branch 'testcommit4417' of github.com:jantman/gitpython_issue_301 +9341886a65ceee4c4f88f4c0c6e252081b846c30 not-for-merge branch 'testcommit4418' of github.com:jantman/gitpython_issue_301 +5539763dd7e43d0724ebb5890297c9e7c322567c not-for-merge branch 'testcommit4419' of github.com:jantman/gitpython_issue_301 +7561910a85173068b87b0a43ceba0fdf02eb90bc not-for-merge branch 'testcommit442' of github.com:jantman/gitpython_issue_301 +1f9559092cf0b892eb222fb8c36561c75beefac0 not-for-merge branch 'testcommit4420' of github.com:jantman/gitpython_issue_301 +893ae6d4d2da5dd871ff876c7149b2bddd315c80 not-for-merge branch 'testcommit4421' of github.com:jantman/gitpython_issue_301 +2153a31962cd246e2f463d29426dbb3301357fbd not-for-merge branch 'testcommit4422' of github.com:jantman/gitpython_issue_301 +e7f3f423b9a50b96e6b88b738907db880dcb27b1 not-for-merge branch 'testcommit4423' of github.com:jantman/gitpython_issue_301 +871b22c4b71aa3fc2a5448eec97fb976e908f88d not-for-merge branch 'testcommit4424' of github.com:jantman/gitpython_issue_301 +9b210ea69c932e67fdb6212e3f7528398741cd49 not-for-merge branch 'testcommit4425' of github.com:jantman/gitpython_issue_301 +4b495f5ee1ca9968bc74da9d08e1a22de89c68dc not-for-merge branch 'testcommit4426' of github.com:jantman/gitpython_issue_301 +530bc6695a545b3e9355b947cbc0e48ab58c20b5 not-for-merge branch 'testcommit4427' of github.com:jantman/gitpython_issue_301 +b2aa31baeb93a6e9e8f6de5e816a7e334e9f62f2 not-for-merge branch 'testcommit4428' of github.com:jantman/gitpython_issue_301 +e21a5ff906445a7ac2485d3dafa1deee2f6d2814 not-for-merge branch 'testcommit4429' of github.com:jantman/gitpython_issue_301 +e62ff9a21f8febc8e7c36623c37a9d82aa813dd5 not-for-merge branch 'testcommit443' of github.com:jantman/gitpython_issue_301 +c836b6bb65f3f45c14e826e646f643cc9d43b568 not-for-merge branch 'testcommit4430' of github.com:jantman/gitpython_issue_301 +458d237e6a358c9e95f17542053587cfdb66cead not-for-merge branch 'testcommit4431' of github.com:jantman/gitpython_issue_301 +d3e3fb4abbcf775e294e1e98b362d429fa29aa6a not-for-merge branch 'testcommit4432' of github.com:jantman/gitpython_issue_301 +75b1ffd55f5164875b399401f651903bc9d13aec not-for-merge branch 'testcommit4433' of github.com:jantman/gitpython_issue_301 +7fbd039c91fec3fcdf6abd414c483d1baf48454c not-for-merge branch 'testcommit4434' of github.com:jantman/gitpython_issue_301 +a46e7171fbf392718ffa3c1b2c746028e64e87c1 not-for-merge branch 'testcommit4435' of github.com:jantman/gitpython_issue_301 +9ec6b49b6fd2328416da8f029f6badb081ef5ab6 not-for-merge branch 'testcommit4436' of github.com:jantman/gitpython_issue_301 +1689e53776ef3ff7dc3edc08cc6f80bb9a88c2a9 not-for-merge branch 'testcommit4437' of github.com:jantman/gitpython_issue_301 +a8f1aeffb5eaab7ee1008dda703483c6dff1d596 not-for-merge branch 'testcommit4438' of github.com:jantman/gitpython_issue_301 +8ccfd9fd8f15f18f3400052ae3402a2a9c282390 not-for-merge branch 'testcommit4439' of github.com:jantman/gitpython_issue_301 +f0f4bc5484f18e5446c3002b04e1787f640f30fb not-for-merge branch 'testcommit444' of github.com:jantman/gitpython_issue_301 +f12ef9484a30d195e64aca50bfa1bbabae10d091 not-for-merge branch 'testcommit4440' of github.com:jantman/gitpython_issue_301 +d18082d8c786d0f236109da7aa43815a8400f1e6 not-for-merge branch 'testcommit4441' of github.com:jantman/gitpython_issue_301 +4ab1a01d9e2e0978e74bc2a00ee7ed8fe5631804 not-for-merge branch 'testcommit4442' of github.com:jantman/gitpython_issue_301 +98edc5f7a2ccccab98d76549ab08b801609a2c82 not-for-merge branch 'testcommit4443' of github.com:jantman/gitpython_issue_301 +1e045fe0aee479ebc1e5a103fad10d776d59e559 not-for-merge branch 'testcommit4444' of github.com:jantman/gitpython_issue_301 +ba6bc2f9dde70963dfb74c11e7565672e7626393 not-for-merge branch 'testcommit4445' of github.com:jantman/gitpython_issue_301 +98120678f20d151723cb8e3db4429a6028032271 not-for-merge branch 'testcommit4446' of github.com:jantman/gitpython_issue_301 +4a2a9fd1f76c2943d4f0c795d3db9d3ef1e38d89 not-for-merge branch 'testcommit4447' of github.com:jantman/gitpython_issue_301 +3416fff2b5b699b74ef23cf72626c29aae59047d not-for-merge branch 'testcommit4448' of github.com:jantman/gitpython_issue_301 +1b419908b30c8a82ea93f3ac53442d0f27b9efc1 not-for-merge branch 'testcommit4449' of github.com:jantman/gitpython_issue_301 +a34eb83be21492ee1ffc8153a690b645156165c9 not-for-merge branch 'testcommit445' of github.com:jantman/gitpython_issue_301 +73eef8ce8eb2af79070f74fb01e1cc15f7929882 not-for-merge branch 'testcommit4450' of github.com:jantman/gitpython_issue_301 +982c42dc1bb75a868026dda616b7163ac5e54e61 not-for-merge branch 'testcommit4451' of github.com:jantman/gitpython_issue_301 +b11684754a2bc5540dc0fe2496ec74b5bb07235f not-for-merge branch 'testcommit4452' of github.com:jantman/gitpython_issue_301 +b154db37a86c58cd0a355a025b9d9ddfac98426c not-for-merge branch 'testcommit4453' of github.com:jantman/gitpython_issue_301 +2c6be12d4b6e7d994da2dcfd4ea9597363915344 not-for-merge branch 'testcommit4454' of github.com:jantman/gitpython_issue_301 +e8e16d16c300517ddf4714f6e9d1e6a3b5124ab5 not-for-merge branch 'testcommit4455' of github.com:jantman/gitpython_issue_301 +fcb3f88fd07cbbc12e9820ae5012d38bb2898793 not-for-merge branch 'testcommit4456' of github.com:jantman/gitpython_issue_301 +61f31eed4accf13a5bc21858845430a0d417fc00 not-for-merge branch 'testcommit4457' of github.com:jantman/gitpython_issue_301 +462a613b283fe200696f0f284fbfbd8370b7a459 not-for-merge branch 'testcommit4458' of github.com:jantman/gitpython_issue_301 +03780087024c83f19feac587647f2566482fc2a2 not-for-merge branch 'testcommit4459' of github.com:jantman/gitpython_issue_301 +768215b32b7163c4343e34d9b6c978d63155a26c not-for-merge branch 'testcommit446' of github.com:jantman/gitpython_issue_301 +d0f4e69c91790ae29f0de53973696f6e7ed8db48 not-for-merge branch 'testcommit4460' of github.com:jantman/gitpython_issue_301 +bb0df0b91ea17ea42873863c058be67c75e8fcde not-for-merge branch 'testcommit4461' of github.com:jantman/gitpython_issue_301 +21e38139f7b2c06892fea46c8529cf45286f1599 not-for-merge branch 'testcommit4462' of github.com:jantman/gitpython_issue_301 +daff25936287589a073acf0f3de1b687a0932114 not-for-merge branch 'testcommit4463' of github.com:jantman/gitpython_issue_301 +6e6c405bf77b314ea583231b68f444fc2f534517 not-for-merge branch 'testcommit4464' of github.com:jantman/gitpython_issue_301 +85b8d05eeae916db8cd9582a1b032455fec03e35 not-for-merge branch 'testcommit4465' of github.com:jantman/gitpython_issue_301 +2f5eef0d36cc9ea3880f8a8236ef918d6f296c2f not-for-merge branch 'testcommit4466' of github.com:jantman/gitpython_issue_301 +9b8ae1970a6c317c41aaa78fda79ed23fd9cc203 not-for-merge branch 'testcommit4467' of github.com:jantman/gitpython_issue_301 +49995dc5340ef5781d9b75cb9097c3ee19795719 not-for-merge branch 'testcommit4468' of github.com:jantman/gitpython_issue_301 +57dbb470ee19b3bb3503895aa89232d10ae0cb68 not-for-merge branch 'testcommit4469' of github.com:jantman/gitpython_issue_301 +02fa51a6d230ea29d732f63d7b0e8e7080e3c30f not-for-merge branch 'testcommit447' of github.com:jantman/gitpython_issue_301 +4c86fe4cdb7e264e8d33795a25eb394f927226b5 not-for-merge branch 'testcommit4470' of github.com:jantman/gitpython_issue_301 +dc74b4bd2e6b31e2bbf437ec66de1df4d04213ca not-for-merge branch 'testcommit4471' of github.com:jantman/gitpython_issue_301 +1e2b75991f30fe1e1907911539ec4eb0a90aa1df not-for-merge branch 'testcommit4472' of github.com:jantman/gitpython_issue_301 +a143f8242e6ed914cfacd69f6e18220415441f4f not-for-merge branch 'testcommit4473' of github.com:jantman/gitpython_issue_301 +9f6f9911481c401e2c704c5f27c4d18599d3ca88 not-for-merge branch 'testcommit4474' of github.com:jantman/gitpython_issue_301 +0306951a22d3497d6f3b55b30f87aa00cc596ea1 not-for-merge branch 'testcommit4475' of github.com:jantman/gitpython_issue_301 +baec83a9320d29835ebb8259ddd84ef59db3192f not-for-merge branch 'testcommit4476' of github.com:jantman/gitpython_issue_301 +2c060e3144b4abd8605ce6937ea5032ee841766a not-for-merge branch 'testcommit4477' of github.com:jantman/gitpython_issue_301 +d0e70c49b21a171946c5df1174b6566cd0f77834 not-for-merge branch 'testcommit4478' of github.com:jantman/gitpython_issue_301 +d487020cd608c540f538195e9393b91d53315cc1 not-for-merge branch 'testcommit4479' of github.com:jantman/gitpython_issue_301 +6f77230d110cd29367df21c7064034b33006641c not-for-merge branch 'testcommit448' of github.com:jantman/gitpython_issue_301 +1503804d1e69a3473875f27c10bc7e6669489037 not-for-merge branch 'testcommit4480' of github.com:jantman/gitpython_issue_301 +71911d9630dc1848eb8844346d32a269e1fd5d5b not-for-merge branch 'testcommit4481' of github.com:jantman/gitpython_issue_301 +3bf448cf7c218b44895847fcaeaad6b4df33609a not-for-merge branch 'testcommit4482' of github.com:jantman/gitpython_issue_301 +2308f6ec739fe826175c1cc269159ac33cb5029f not-for-merge branch 'testcommit4483' of github.com:jantman/gitpython_issue_301 +28009d32dffa5ad9d9af19d89b303afa79d6bb80 not-for-merge branch 'testcommit4484' of github.com:jantman/gitpython_issue_301 +3f19b0036c8d41113cee002d79cd93c61ea5c969 not-for-merge branch 'testcommit4485' of github.com:jantman/gitpython_issue_301 +e7b450bfa04bcabff4f4ef22dba6534ac8a9d1c6 not-for-merge branch 'testcommit4486' of github.com:jantman/gitpython_issue_301 +03d5834085e5deaa4de5afceec0ef74b2faf6f39 not-for-merge branch 'testcommit4487' of github.com:jantman/gitpython_issue_301 +79e9f953062681b33f6f69fa8d1a3afa524b0a5a not-for-merge branch 'testcommit4488' of github.com:jantman/gitpython_issue_301 +3896f0c0d347f1ca1a937603e0eb0cc5c0e8a9ed not-for-merge branch 'testcommit4489' of github.com:jantman/gitpython_issue_301 +3222a4c8f8d9ab978999a7de5e0e09fdbf3f141a not-for-merge branch 'testcommit449' of github.com:jantman/gitpython_issue_301 +b0393cc09a70998eeeee181133cc0e4aca0f6a4d not-for-merge branch 'testcommit4490' of github.com:jantman/gitpython_issue_301 +0f5c74884edc556ee8e3f300b452907af7333cb3 not-for-merge branch 'testcommit4491' of github.com:jantman/gitpython_issue_301 +49c1040d3a42dde7c755a11778ff38559fa2ab2d not-for-merge branch 'testcommit4492' of github.com:jantman/gitpython_issue_301 +477f10dad8797c1ddc3c48976a81bdc4615a7d5e not-for-merge branch 'testcommit4493' of github.com:jantman/gitpython_issue_301 +36034c8b63628e9c6c2101eb91c0378a5685e452 not-for-merge branch 'testcommit4494' of github.com:jantman/gitpython_issue_301 +5ebd99d12cb446c9d61e64253f1f7c6b7a166350 not-for-merge branch 'testcommit4495' of github.com:jantman/gitpython_issue_301 +86a150364f84db72113605bfa0e9319c052c61a8 not-for-merge branch 'testcommit4496' of github.com:jantman/gitpython_issue_301 +86f6f708ca4c0d4dc1f1daeb43426ac93bbc1b74 not-for-merge branch 'testcommit4497' of github.com:jantman/gitpython_issue_301 +055ac45823ce0bbf19f5da24ae0be52b053c36c7 not-for-merge branch 'testcommit4498' of github.com:jantman/gitpython_issue_301 +3a89e01bd7fc18dc5aa2fcdd5409a10f5853de7c not-for-merge branch 'testcommit4499' of github.com:jantman/gitpython_issue_301 +73dd7c0be1b914fcc1fec86eab6d9d3661496b52 not-for-merge branch 'testcommit45' of github.com:jantman/gitpython_issue_301 +0dd2ed6e4f7042cb99969943f3fc63c8ffe355df not-for-merge branch 'testcommit450' of github.com:jantman/gitpython_issue_301 +79dc09f7654487182d87ce9fd74d3fc3cbe0a3b4 not-for-merge branch 'testcommit4500' of github.com:jantman/gitpython_issue_301 +ec508966ee5a8435db3211379d0eda604bedd838 not-for-merge branch 'testcommit4501' of github.com:jantman/gitpython_issue_301 +5efc0c275d7847bddf817d017fe06fad1972fc21 not-for-merge branch 'testcommit4502' of github.com:jantman/gitpython_issue_301 +a203d127007a8021d98af21750b7b37a479b608a not-for-merge branch 'testcommit4503' of github.com:jantman/gitpython_issue_301 +9edb480c70c0c526257b6a5861dda12cf73d92ae not-for-merge branch 'testcommit4504' of github.com:jantman/gitpython_issue_301 +c6ab6b8e9d51821243892c82fc5ae83676ce8a1e not-for-merge branch 'testcommit4505' of github.com:jantman/gitpython_issue_301 +ee148bebdc788f3727775f2098c020db768cb8df not-for-merge branch 'testcommit4506' of github.com:jantman/gitpython_issue_301 +3e2eef1ab2115e4702a0933922b55622fb9dc7f2 not-for-merge branch 'testcommit4507' of github.com:jantman/gitpython_issue_301 +4fc2bed22b256ed3c89f4f2ecdd446ed4eb3681a not-for-merge branch 'testcommit4508' of github.com:jantman/gitpython_issue_301 +85288ec637fdfac2eac0fa14dafdfeffcc555b57 not-for-merge branch 'testcommit4509' of github.com:jantman/gitpython_issue_301 +f15c44a3e0418d1744bc55a6792643260aadf3a7 not-for-merge branch 'testcommit451' of github.com:jantman/gitpython_issue_301 +8dcf1124e3300f7e97e980641854773925dc0219 not-for-merge branch 'testcommit4510' of github.com:jantman/gitpython_issue_301 +2f43512b0403bb6a0115c8908dbf512c71543a4e not-for-merge branch 'testcommit4511' of github.com:jantman/gitpython_issue_301 +fa2fecf87ce4be361218efc9671299ef7687ea1d not-for-merge branch 'testcommit4512' of github.com:jantman/gitpython_issue_301 +a750ad93641a4742a0df1d5597d1a72d32b71c05 not-for-merge branch 'testcommit4513' of github.com:jantman/gitpython_issue_301 +5b608b684095d75ab10f8051e849469b8ca8f282 not-for-merge branch 'testcommit4514' of github.com:jantman/gitpython_issue_301 +9a2be8e670f476f2d91209e313ba552de651750e not-for-merge branch 'testcommit4515' of github.com:jantman/gitpython_issue_301 +8773f0b671ec549ccf022b3a2b1075549915708b not-for-merge branch 'testcommit4516' of github.com:jantman/gitpython_issue_301 +e03a1827c81ae92f5e081f4b896b52ef8f2c9d38 not-for-merge branch 'testcommit4517' of github.com:jantman/gitpython_issue_301 +1d024712934b464114855de554872c021c56baf5 not-for-merge branch 'testcommit4518' of github.com:jantman/gitpython_issue_301 +6181e5c6057522f68341a29d726f6ac3258cf391 not-for-merge branch 'testcommit4519' of github.com:jantman/gitpython_issue_301 +947c9bcb935560939037df1493ee96ce894fae47 not-for-merge branch 'testcommit452' of github.com:jantman/gitpython_issue_301 +e7be7a00f9d1ffab4febc685d9ae60940c4fc4b5 not-for-merge branch 'testcommit4520' of github.com:jantman/gitpython_issue_301 +3125fbb7d5662be9120ab0653e3fd19fa55ab705 not-for-merge branch 'testcommit4521' of github.com:jantman/gitpython_issue_301 +c5f03834b74d182dac89e53e93e55f4925a2e56e not-for-merge branch 'testcommit4522' of github.com:jantman/gitpython_issue_301 +05bab73860d1f40b74686b51a12fafaf9ff9a7c3 not-for-merge branch 'testcommit4523' of github.com:jantman/gitpython_issue_301 +3c07d9481fc17b11d2eecb23140f392192410f30 not-for-merge branch 'testcommit4524' of github.com:jantman/gitpython_issue_301 +cf386756f6e6a912e1b270ab2eea2f65b817c193 not-for-merge branch 'testcommit4525' of github.com:jantman/gitpython_issue_301 +edb3c66fa31b2d52c1f7cc1548729ec0b2fb36f7 not-for-merge branch 'testcommit4526' of github.com:jantman/gitpython_issue_301 +015af3d1742d6b6f7ab9e118eb8241fbcd098a56 not-for-merge branch 'testcommit4527' of github.com:jantman/gitpython_issue_301 +33a895ef5706a4f4a139693170a9d06654ab6278 not-for-merge branch 'testcommit4528' of github.com:jantman/gitpython_issue_301 +46dbd3d1a9a47fea7b43991a2353d4b089074c19 not-for-merge branch 'testcommit4529' of github.com:jantman/gitpython_issue_301 +8e554f9ca9f25d44597cf9be595f781d52e22a51 not-for-merge branch 'testcommit453' of github.com:jantman/gitpython_issue_301 +9b57c5f9dc4b3a01b70f34838952eaff1d841ce1 not-for-merge branch 'testcommit4530' of github.com:jantman/gitpython_issue_301 +5e4179a3114e2556d9f2c83f764b388704129e6c not-for-merge branch 'testcommit4531' of github.com:jantman/gitpython_issue_301 +d1505343d306477cbcff2a20d4c2569124042ea0 not-for-merge branch 'testcommit4532' of github.com:jantman/gitpython_issue_301 +fd0246b85893780efaee1451f540073926c41779 not-for-merge branch 'testcommit4533' of github.com:jantman/gitpython_issue_301 +b3e38a6f777429304cfe0a4f53f48d5cf20b4525 not-for-merge branch 'testcommit4534' of github.com:jantman/gitpython_issue_301 +4eb3f9ea8d486a41ba4e2c59b71e927633ab5954 not-for-merge branch 'testcommit4535' of github.com:jantman/gitpython_issue_301 +2a61c1c5be59251c47a2d1c02390a43a64c32b97 not-for-merge branch 'testcommit4536' of github.com:jantman/gitpython_issue_301 +d7642896082db75c2b78e815a42ceb59634e11f8 not-for-merge branch 'testcommit4537' of github.com:jantman/gitpython_issue_301 +d2e22e5bc831880e9d56391b976836d838101873 not-for-merge branch 'testcommit4538' of github.com:jantman/gitpython_issue_301 +254b857833f15e0cce02904b99b06f16a2b3bffe not-for-merge branch 'testcommit4539' of github.com:jantman/gitpython_issue_301 +e1e0f6b7cfd6ca2891a0e524093a6e36ada4458d not-for-merge branch 'testcommit454' of github.com:jantman/gitpython_issue_301 +ed58d54ccd60b00f76fa01206f7c2c2db08fc2f9 not-for-merge branch 'testcommit4540' of github.com:jantman/gitpython_issue_301 +f2c7613bae807dcfa0faae73837a7ce1b2e7f74d not-for-merge branch 'testcommit4541' of github.com:jantman/gitpython_issue_301 +85e7b06216123d9efdab7b007e305a917991c461 not-for-merge branch 'testcommit4542' of github.com:jantman/gitpython_issue_301 +b2e6b7d1467beea3f0f02444c67a2861e4bcc250 not-for-merge branch 'testcommit4543' of github.com:jantman/gitpython_issue_301 +c5ceffb5a02c96a88a28e4b58725d073050fadc9 not-for-merge branch 'testcommit4544' of github.com:jantman/gitpython_issue_301 +585a914a77aa81c20ab850b9071b49ca24cc7c59 not-for-merge branch 'testcommit4545' of github.com:jantman/gitpython_issue_301 +0ab26a9d9b51f4cef10bf8affc0e91bb8a88d28d not-for-merge branch 'testcommit4546' of github.com:jantman/gitpython_issue_301 +9a91661d2e4c02765d21d0bae39fcb8029d92a8b not-for-merge branch 'testcommit4547' of github.com:jantman/gitpython_issue_301 +bbea72e6a0f174da8534fd5b0aa612307118d01d not-for-merge branch 'testcommit4548' of github.com:jantman/gitpython_issue_301 +7925ff5c67bdf510f871efc58eae3ad80d75d3d7 not-for-merge branch 'testcommit4549' of github.com:jantman/gitpython_issue_301 +e66324b144117c07de31ca252ec4f4902bd09c7f not-for-merge branch 'testcommit455' of github.com:jantman/gitpython_issue_301 +658c07808fa2edf10c8e93702d5a0588cf1d4767 not-for-merge branch 'testcommit4550' of github.com:jantman/gitpython_issue_301 +d9ca8a905849cdd61616d3ed373777c926185fb0 not-for-merge branch 'testcommit4551' of github.com:jantman/gitpython_issue_301 +bb25773f5062d5dd17419e0f02ea74f0c83e0479 not-for-merge branch 'testcommit4552' of github.com:jantman/gitpython_issue_301 +8f56cc1cc518f7026cbe34deb0228728d08b80a9 not-for-merge branch 'testcommit4553' of github.com:jantman/gitpython_issue_301 +c7806b2de98b595e59f4aeb9e429e07ed4ef4e61 not-for-merge branch 'testcommit4554' of github.com:jantman/gitpython_issue_301 +80a1a3a8805612523b98aba5d25678741f147f25 not-for-merge branch 'testcommit4555' of github.com:jantman/gitpython_issue_301 +28db2ce0f0fd6e9002cc1606ec90ec4b2c55c5f4 not-for-merge branch 'testcommit4556' of github.com:jantman/gitpython_issue_301 +2550a758a9fc6d8ca89d2b5918c390ed1fe95eb8 not-for-merge branch 'testcommit4557' of github.com:jantman/gitpython_issue_301 +826ec403a9e26eabca86eb5b3d90ebd74ecedaad not-for-merge branch 'testcommit4558' of github.com:jantman/gitpython_issue_301 +9ca9666f4039f2c909b78de70b4feac1904c2c2c not-for-merge branch 'testcommit4559' of github.com:jantman/gitpython_issue_301 +09fd9a92ac2b8b59b2f75717d6da22bcb7d67a40 not-for-merge branch 'testcommit456' of github.com:jantman/gitpython_issue_301 +8fe70d8e0395b8e1fac013d554a782991631c44e not-for-merge branch 'testcommit4560' of github.com:jantman/gitpython_issue_301 +97cb59feb11716ad8f9239c4c1db4f3c32f13ca1 not-for-merge branch 'testcommit4561' of github.com:jantman/gitpython_issue_301 +59e0e36d11460a3e25a0f085d273dc59f511df73 not-for-merge branch 'testcommit4562' of github.com:jantman/gitpython_issue_301 +bb3d5e5f5aaba9c05a390ba2d14e7e3dbdb62c89 not-for-merge branch 'testcommit4563' of github.com:jantman/gitpython_issue_301 +aad38e56c6329d6dcfacf22b5c6e0c266899987f not-for-merge branch 'testcommit4564' of github.com:jantman/gitpython_issue_301 +342120a1e9a3446dbe93dee6b46e6c5b115c526e not-for-merge branch 'testcommit4565' of github.com:jantman/gitpython_issue_301 +421eaf0c35080528c97abf311e35dbcaf1b165a9 not-for-merge branch 'testcommit4566' of github.com:jantman/gitpython_issue_301 +8c63ecca5ade238663651a51fc1c43306688b3ab not-for-merge branch 'testcommit4567' of github.com:jantman/gitpython_issue_301 +dc46349cc84b3ebd134352f4e3d085a1245d05eb not-for-merge branch 'testcommit4568' of github.com:jantman/gitpython_issue_301 +aa08a455b7a47d61cad950533824f064893f47be not-for-merge branch 'testcommit4569' of github.com:jantman/gitpython_issue_301 +07423e7709e140650c1a23026dc4b4f20fd8d078 not-for-merge branch 'testcommit457' of github.com:jantman/gitpython_issue_301 +2dc237eb34d2cb0e0f29b8da3d7297ccb48e423e not-for-merge branch 'testcommit4570' of github.com:jantman/gitpython_issue_301 +8288dc53e107c7dee222be3c734f3883d72d2321 not-for-merge branch 'testcommit4571' of github.com:jantman/gitpython_issue_301 +16ea2f5ef9949386c98a7815adf4b0c08455eccb not-for-merge branch 'testcommit4572' of github.com:jantman/gitpython_issue_301 +9c2fc0ccaafb7a1ac3f855b17aa4c9b81b35a0bf not-for-merge branch 'testcommit4573' of github.com:jantman/gitpython_issue_301 +6f18ee22e63de15763cb1cf2fc1b11e5581fbf73 not-for-merge branch 'testcommit4574' of github.com:jantman/gitpython_issue_301 +e8d9da2f024a9f18b4d261e1e762132c29743e01 not-for-merge branch 'testcommit4575' of github.com:jantman/gitpython_issue_301 +8ab57172f2b0cb97e83cd5555a5b5f934d6d580c not-for-merge branch 'testcommit4576' of github.com:jantman/gitpython_issue_301 +94399b3537a44845f708eb24dea1e37c9eee7422 not-for-merge branch 'testcommit4577' of github.com:jantman/gitpython_issue_301 +53c5edab5e0fe7678d08fa224b45c0d64f850235 not-for-merge branch 'testcommit4578' of github.com:jantman/gitpython_issue_301 +b47847671db4eb9544b0387ba5378a8eb45c7c86 not-for-merge branch 'testcommit4579' of github.com:jantman/gitpython_issue_301 +d6fb5d084f31733672154e0be548a252a9ff5cf3 not-for-merge branch 'testcommit458' of github.com:jantman/gitpython_issue_301 +64b84cafc9e1cbefe401c1c5c55ef5a01f5a2a09 not-for-merge branch 'testcommit4580' of github.com:jantman/gitpython_issue_301 +0f9939a4240781b0bf1a8aed9ddde11d372bb075 not-for-merge branch 'testcommit4581' of github.com:jantman/gitpython_issue_301 +482dbd80e6afcad9cec9489fd0cb2e7ad609befa not-for-merge branch 'testcommit4582' of github.com:jantman/gitpython_issue_301 +c09358a8d384d6bb46759acbb061f1f04fe8a68e not-for-merge branch 'testcommit4583' of github.com:jantman/gitpython_issue_301 +a5c8b8fdd504de510dc674e06f5babd81f2196b8 not-for-merge branch 'testcommit4584' of github.com:jantman/gitpython_issue_301 +c42825ca1895a6d3d63d9ed71c8a1f7d8831249e not-for-merge branch 'testcommit4585' of github.com:jantman/gitpython_issue_301 +c885aae0ac42ef4538434c4f698c0f04f534af81 not-for-merge branch 'testcommit4586' of github.com:jantman/gitpython_issue_301 +3db631415e34655ba7437418adccb67cc1cfa482 not-for-merge branch 'testcommit4587' of github.com:jantman/gitpython_issue_301 +9142491a2bb51be30d87d23ad53b9ff6e0633d01 not-for-merge branch 'testcommit4588' of github.com:jantman/gitpython_issue_301 +3d6b3516ab5fe4db7f20ba7133299c870bbbf790 not-for-merge branch 'testcommit4589' of github.com:jantman/gitpython_issue_301 +f14ff148b122843d1ec9ed81be35f4e734257fbd not-for-merge branch 'testcommit459' of github.com:jantman/gitpython_issue_301 +9b3c24a55f6b0afddd3cfe1d0b015b4eac8e242f not-for-merge branch 'testcommit4590' of github.com:jantman/gitpython_issue_301 +0090ead916e6006415c88ffe94ef6c79e8e8f992 not-for-merge branch 'testcommit4591' of github.com:jantman/gitpython_issue_301 +b3579a45da072243e35c8e493086aaf23a8f38c4 not-for-merge branch 'testcommit4592' of github.com:jantman/gitpython_issue_301 +322c404ef226424b0df71176b2d61d852c0906e7 not-for-merge branch 'testcommit4593' of github.com:jantman/gitpython_issue_301 +4488862722bd3ec9c617d7597413fc80704d423c not-for-merge branch 'testcommit4594' of github.com:jantman/gitpython_issue_301 +b1f13540579d513d418822949125421f7dd47021 not-for-merge branch 'testcommit4595' of github.com:jantman/gitpython_issue_301 +a0f0dfbcfa1f3ce3b8bc686c169acfe76a0d38f5 not-for-merge branch 'testcommit4596' of github.com:jantman/gitpython_issue_301 +c4067b52d28097684b6197f8ff71020b82d1a515 not-for-merge branch 'testcommit4597' of github.com:jantman/gitpython_issue_301 +66bef0adb706a07a534a49bb03cb3ff511443377 not-for-merge branch 'testcommit4598' of github.com:jantman/gitpython_issue_301 +e57d4a503cbc7897dc94bcf33c636d89b3f8d96b not-for-merge branch 'testcommit4599' of github.com:jantman/gitpython_issue_301 +4408a6549f07b6bc1d45c560da49ad17e9f57f91 not-for-merge branch 'testcommit46' of github.com:jantman/gitpython_issue_301 +782574411f2628bb41a2453901680843a9324e96 not-for-merge branch 'testcommit460' of github.com:jantman/gitpython_issue_301 +cd449510541e85c8cd7976d65cafb8fb253e0599 not-for-merge branch 'testcommit4600' of github.com:jantman/gitpython_issue_301 +8c7e1fb83c0ed6a23ed0b64e5d0185a80f799426 not-for-merge branch 'testcommit4601' of github.com:jantman/gitpython_issue_301 +5b0821036d347e9db57a4655ce4b80834f1d81ce not-for-merge branch 'testcommit4602' of github.com:jantman/gitpython_issue_301 +ac586d1aef846495bf99b34b88acefab2928fad2 not-for-merge branch 'testcommit4603' of github.com:jantman/gitpython_issue_301 +d899eb9e15dfede86fe3d3d4f5fffc6a98ce7273 not-for-merge branch 'testcommit4604' of github.com:jantman/gitpython_issue_301 +77efa7284a52f3c09a3bec279deff8e8dc712699 not-for-merge branch 'testcommit4605' of github.com:jantman/gitpython_issue_301 +95e9948127295f773864614a6f1869f63e10ffa6 not-for-merge branch 'testcommit4606' of github.com:jantman/gitpython_issue_301 +30923c7e41efe7b8342276ef591509d30c5d33a8 not-for-merge branch 'testcommit4607' of github.com:jantman/gitpython_issue_301 +8644d4c0f68ccd48c0e24ca5a4cf1de16ee6047e not-for-merge branch 'testcommit4608' of github.com:jantman/gitpython_issue_301 +349d2f5dd306cbfa2744d27ae579c5baee7dfda7 not-for-merge branch 'testcommit4609' of github.com:jantman/gitpython_issue_301 +faa26ba9c589d8c57a4900091e54a76efec88537 not-for-merge branch 'testcommit461' of github.com:jantman/gitpython_issue_301 +ec9d76a1f90761bcb43703f1fb6fc0e89c292f03 not-for-merge branch 'testcommit4610' of github.com:jantman/gitpython_issue_301 +c810d1f864579409f206ecd90b84c5c313b2d8aa not-for-merge branch 'testcommit4611' of github.com:jantman/gitpython_issue_301 +d050d02597816b16f4bd3ea51d783f8e253bb2d6 not-for-merge branch 'testcommit4612' of github.com:jantman/gitpython_issue_301 +ee147213b836f1a394c0dcd10231473604770b18 not-for-merge branch 'testcommit4613' of github.com:jantman/gitpython_issue_301 +d2d6443ec55a9c7331f6315671dec8c1d1038a4e not-for-merge branch 'testcommit4614' of github.com:jantman/gitpython_issue_301 +6bc6cd0f52e719a9915ba15dde58e40fc100c261 not-for-merge branch 'testcommit4615' of github.com:jantman/gitpython_issue_301 +c8299c09c063734f127925ab5ea37e92a68824cc not-for-merge branch 'testcommit4616' of github.com:jantman/gitpython_issue_301 +fb650bdfb2324c5d8c33a782e26be5bf3f709f7d not-for-merge branch 'testcommit4617' of github.com:jantman/gitpython_issue_301 +9e0f2197f6cd9f8392167b4fff072f76d445df89 not-for-merge branch 'testcommit4618' of github.com:jantman/gitpython_issue_301 +5e15710d098fee81c9a658bab19c7ccc4f2c4d5e not-for-merge branch 'testcommit4619' of github.com:jantman/gitpython_issue_301 +c722679c7049071d42f504e5e4de3c27565fddc5 not-for-merge branch 'testcommit462' of github.com:jantman/gitpython_issue_301 +0b06eeba1f2a5b8643e341f957d9bc57034049be not-for-merge branch 'testcommit4620' of github.com:jantman/gitpython_issue_301 +4770c53b3d2b686720f1dd589b35a9b496a53d91 not-for-merge branch 'testcommit4621' of github.com:jantman/gitpython_issue_301 +bd1d514c0c62c63ada3e6dd65435042999c7ef06 not-for-merge branch 'testcommit4622' of github.com:jantman/gitpython_issue_301 +32b3b15e0265ec7233f4714f414158d9ea18e34f not-for-merge branch 'testcommit4623' of github.com:jantman/gitpython_issue_301 +2bef3f5bb54a231aecf4578ae5866d2b74202b54 not-for-merge branch 'testcommit4624' of github.com:jantman/gitpython_issue_301 +8d687bbc847a234d3586853091c506fe0c159fbc not-for-merge branch 'testcommit4625' of github.com:jantman/gitpython_issue_301 +2ac3c99a2d0d07607266061392af37326e2dda1e not-for-merge branch 'testcommit4626' of github.com:jantman/gitpython_issue_301 +82bfca714b7ac30c6d3b64ff17fc2b1e38e0507f not-for-merge branch 'testcommit4627' of github.com:jantman/gitpython_issue_301 +1c81a7f9b5710f0b87987b59396661ef30eaf9ac not-for-merge branch 'testcommit4628' of github.com:jantman/gitpython_issue_301 +9038af1f6a7afbc81e7637ba16c4eb01f39e43de not-for-merge branch 'testcommit4629' of github.com:jantman/gitpython_issue_301 +da36800203252ff61e5da0101a6f70c3e5003581 not-for-merge branch 'testcommit463' of github.com:jantman/gitpython_issue_301 +7270cf515a5bc4c3540b2be7369c4e9cbbb0cd48 not-for-merge branch 'testcommit4630' of github.com:jantman/gitpython_issue_301 +26c0c348572c0fc190d83c9479d450f02ab064b0 not-for-merge branch 'testcommit4631' of github.com:jantman/gitpython_issue_301 +eb532de11df9b49f0eb9a96fc847726bcc9bff9f not-for-merge branch 'testcommit4632' of github.com:jantman/gitpython_issue_301 +61a72ded48e60e73bd14e5bcf73a636e4f58edbd not-for-merge branch 'testcommit4633' of github.com:jantman/gitpython_issue_301 +affef25c9b909aea4922443d7bb701dcd35e5640 not-for-merge branch 'testcommit4634' of github.com:jantman/gitpython_issue_301 +3189d8f0527f2671297e9790742736cec364ab69 not-for-merge branch 'testcommit4635' of github.com:jantman/gitpython_issue_301 +ab1475133bcde1635b85034ff08738a83e5caf24 not-for-merge branch 'testcommit4636' of github.com:jantman/gitpython_issue_301 +e76dbf4776d130b3fa2d6d02ea964464c9ddc463 not-for-merge branch 'testcommit4637' of github.com:jantman/gitpython_issue_301 +b20a84157df3ff49e6c1bbe9a853be04073f76ce not-for-merge branch 'testcommit4638' of github.com:jantman/gitpython_issue_301 +0af0fa844c9101d88679134253e525154ce6aabc not-for-merge branch 'testcommit4639' of github.com:jantman/gitpython_issue_301 +bd31695a8840d6e4d8f7214b20d9e0e42ad64def not-for-merge branch 'testcommit464' of github.com:jantman/gitpython_issue_301 +8a989a6e8f497edc4bcb4ab26d2c24b825b3d290 not-for-merge branch 'testcommit4640' of github.com:jantman/gitpython_issue_301 +c6af30e0aa864b535c2ce58206f8b66abbdce65c not-for-merge branch 'testcommit4641' of github.com:jantman/gitpython_issue_301 +10f3979d4f995e20281f747f24ef0a10184e7fe6 not-for-merge branch 'testcommit4642' of github.com:jantman/gitpython_issue_301 +87f9eeac20879c623c09ed6fe3aa83d85d3fa469 not-for-merge branch 'testcommit4643' of github.com:jantman/gitpython_issue_301 +72fecebf9deb4204e261b9735e993fcba99a3856 not-for-merge branch 'testcommit4644' of github.com:jantman/gitpython_issue_301 +bf353ef455b3f6c0ce6d0520f58081d745a3dd6e not-for-merge branch 'testcommit4645' of github.com:jantman/gitpython_issue_301 +31b5910264489a5e18d9c1e16b1e43fec64ef83e not-for-merge branch 'testcommit4646' of github.com:jantman/gitpython_issue_301 +a121373ebc8c96dd09ebb7e1a19ccf147e8d6665 not-for-merge branch 'testcommit4647' of github.com:jantman/gitpython_issue_301 +45a6793496f41c6ae5c7bf6d3aac03a85c95345e not-for-merge branch 'testcommit4648' of github.com:jantman/gitpython_issue_301 +75385fbaef8a4a7d7dc70f47c32a833a5faa62c2 not-for-merge branch 'testcommit4649' of github.com:jantman/gitpython_issue_301 +d0ece462b4caa4411d28f56b47e8b06a2bb59cde not-for-merge branch 'testcommit465' of github.com:jantman/gitpython_issue_301 +a3660e37bd31043060c5edd91089df7efa5e6a35 not-for-merge branch 'testcommit4650' of github.com:jantman/gitpython_issue_301 +42cb9586c8193038d8c4fe1094586ed1d2cb4d38 not-for-merge branch 'testcommit4651' of github.com:jantman/gitpython_issue_301 +d6383d73d8041a5c63c623d3a54c1dd1722d8725 not-for-merge branch 'testcommit4652' of github.com:jantman/gitpython_issue_301 +60c1aa5e56afa1350ba5083f5a3042653cba2efd not-for-merge branch 'testcommit4653' of github.com:jantman/gitpython_issue_301 +0c63743c061e6b6dce14ed65fb035f58adc9f9e8 not-for-merge branch 'testcommit4654' of github.com:jantman/gitpython_issue_301 +60387f4f50d4f4a0b8295fadcc8224a1cd8c4aa2 not-for-merge branch 'testcommit4655' of github.com:jantman/gitpython_issue_301 +9359a45bf9e1a4a224e10138c3299ddd032d9831 not-for-merge branch 'testcommit4656' of github.com:jantman/gitpython_issue_301 +244124a7c26d3a9575718cc6da32664e2e02bcd4 not-for-merge branch 'testcommit4657' of github.com:jantman/gitpython_issue_301 +864fae9ff556b50fda76cbfb5a8569451c62c005 not-for-merge branch 'testcommit4658' of github.com:jantman/gitpython_issue_301 +1c340884744433f70a209238680144dac061468c not-for-merge branch 'testcommit4659' of github.com:jantman/gitpython_issue_301 +de6884046384439ce66bd8b57973e59fd2070d32 not-for-merge branch 'testcommit466' of github.com:jantman/gitpython_issue_301 +2a7223b4d667e726688e01f5cd3c04dcbb3e53c8 not-for-merge branch 'testcommit4660' of github.com:jantman/gitpython_issue_301 +89f7dde7fce1654248c848df1a3c21f966d279ee not-for-merge branch 'testcommit4661' of github.com:jantman/gitpython_issue_301 +eeb0d5d5f6c4403d4961aaed0ce67cc91d22c9ef not-for-merge branch 'testcommit4662' of github.com:jantman/gitpython_issue_301 +0818ece5d463717408a2336b4e8eafcf8ee30087 not-for-merge branch 'testcommit4663' of github.com:jantman/gitpython_issue_301 +66cce34cb7e3955fba12ca63bf45954acc06beae not-for-merge branch 'testcommit4664' of github.com:jantman/gitpython_issue_301 +38dd9e96b48909c4c65e7c51eb437ed333e096a6 not-for-merge branch 'testcommit4665' of github.com:jantman/gitpython_issue_301 +49fcaf8ea1893e25006443cc7387f77e9970a465 not-for-merge branch 'testcommit4666' of github.com:jantman/gitpython_issue_301 +12961e069a5d9f9cc119b23772c65eb98f037987 not-for-merge branch 'testcommit4667' of github.com:jantman/gitpython_issue_301 +61c216acfabccc37ef9f16ba9c25e574114203c9 not-for-merge branch 'testcommit4668' of github.com:jantman/gitpython_issue_301 +e6045ad2ce553da4d2fea96ed6b289e125229c1e not-for-merge branch 'testcommit4669' of github.com:jantman/gitpython_issue_301 +3465e9b44795690978f1559f7421a71a34e82ec2 not-for-merge branch 'testcommit467' of github.com:jantman/gitpython_issue_301 +bf009e13c27e4ee9e39e3eeb6bf23fde6a94b08e not-for-merge branch 'testcommit4670' of github.com:jantman/gitpython_issue_301 +ed864fde0c96eb1ac7758454a35bb57f93896b7e not-for-merge branch 'testcommit4671' of github.com:jantman/gitpython_issue_301 +451fc4c454b548a772ecbce0b005efe1b4baf8e3 not-for-merge branch 'testcommit4672' of github.com:jantman/gitpython_issue_301 +85f7dfa269218ba5259302bea38141d5d66e268d not-for-merge branch 'testcommit4673' of github.com:jantman/gitpython_issue_301 +ad633520a88294e873f81c31ece4df085f479ea2 not-for-merge branch 'testcommit4674' of github.com:jantman/gitpython_issue_301 +80e2b2231f9982f230b6559ab0d20ff01b2ee28d not-for-merge branch 'testcommit4675' of github.com:jantman/gitpython_issue_301 +5e19eda57e362462f6d2caa617114f74c1d4ea50 not-for-merge branch 'testcommit4676' of github.com:jantman/gitpython_issue_301 +b71444a5fe5fdb0c9513cf8898994795ccd5e377 not-for-merge branch 'testcommit4677' of github.com:jantman/gitpython_issue_301 +b2f76d1348824629b925e6d02b2149c4fcb6efb6 not-for-merge branch 'testcommit4678' of github.com:jantman/gitpython_issue_301 +febc2ef270a1c571565ea51068db9216c43ebf43 not-for-merge branch 'testcommit4679' of github.com:jantman/gitpython_issue_301 +b27e44cc67a424b8fcfcbcf99aa1e53a4b7989b6 not-for-merge branch 'testcommit468' of github.com:jantman/gitpython_issue_301 +0aaabf343ecc78088f1cbbf48c5b505bae3c94e7 not-for-merge branch 'testcommit4680' of github.com:jantman/gitpython_issue_301 +f2a9518221de0b8292f9de3bda5c9efaa4fd73b9 not-for-merge branch 'testcommit4681' of github.com:jantman/gitpython_issue_301 +38145f651bb7b6eaea7ed91c60b923ff29d3f86d not-for-merge branch 'testcommit4682' of github.com:jantman/gitpython_issue_301 +59f7ae03055b58f3c3b514cab4fca50741970a6c not-for-merge branch 'testcommit4683' of github.com:jantman/gitpython_issue_301 +d340798e0d7829afe7318e764d9cb00271994693 not-for-merge branch 'testcommit4684' of github.com:jantman/gitpython_issue_301 +2bea460597e9213b4c8ac404eb44402a592ee647 not-for-merge branch 'testcommit4685' of github.com:jantman/gitpython_issue_301 +79ea94aef265ad475a3a1d65e19c414667a273b9 not-for-merge branch 'testcommit4686' of github.com:jantman/gitpython_issue_301 +9cb166ae857224045a9efa518d6898d963a96d74 not-for-merge branch 'testcommit4687' of github.com:jantman/gitpython_issue_301 +296732f4fde007fe3cf22a050d140560dc90291c not-for-merge branch 'testcommit4688' of github.com:jantman/gitpython_issue_301 +daab1842fccb375b7131a243c17b28ed174b3887 not-for-merge branch 'testcommit4689' of github.com:jantman/gitpython_issue_301 +f7b92f16e07c7fb2d7fd3753d7a2de062f5ce481 not-for-merge branch 'testcommit469' of github.com:jantman/gitpython_issue_301 +89c8f14615bc119fc4a75dd68fa1773317776da9 not-for-merge branch 'testcommit4690' of github.com:jantman/gitpython_issue_301 +47b3025258d8f7a623b8fb6174f77dec795a2863 not-for-merge branch 'testcommit4691' of github.com:jantman/gitpython_issue_301 +44447fb702b81b966de9aa2e95b24986f3282dd0 not-for-merge branch 'testcommit4692' of github.com:jantman/gitpython_issue_301 +2f7b08b3d42c0dc91996b6efb9066e6a7bdef7c7 not-for-merge branch 'testcommit4693' of github.com:jantman/gitpython_issue_301 +06899198123eef21db579a79b2c0f269728876dc not-for-merge branch 'testcommit4694' of github.com:jantman/gitpython_issue_301 +424b202bac168d24c6cf69e5003a7d93d37c7333 not-for-merge branch 'testcommit4695' of github.com:jantman/gitpython_issue_301 +ef7fb0252a4f7884338e0b2a71de483cd2690e0b not-for-merge branch 'testcommit4696' of github.com:jantman/gitpython_issue_301 +ec8917df84a02b6eac2cbdb7c23a37bbac2ea669 not-for-merge branch 'testcommit4697' of github.com:jantman/gitpython_issue_301 +07824ed70edda4a87850f042ad729a3da1a04856 not-for-merge branch 'testcommit4698' of github.com:jantman/gitpython_issue_301 +272180c45556c46468fc0bba7dc4cda67707d9e1 not-for-merge branch 'testcommit4699' of github.com:jantman/gitpython_issue_301 +a96b1e88b11c2af67e2e62dcb37e375cd8061da6 not-for-merge branch 'testcommit47' of github.com:jantman/gitpython_issue_301 +4b5f4081febcce059a7224eaa1d818ecee4dbb2d not-for-merge branch 'testcommit470' of github.com:jantman/gitpython_issue_301 +3ee300791ab3256c5c6340252b4f347570b78637 not-for-merge branch 'testcommit4700' of github.com:jantman/gitpython_issue_301 +da60c0e47e78806ffc93597df96b4aedef8ca7ba not-for-merge branch 'testcommit4701' of github.com:jantman/gitpython_issue_301 +98cf757142564087bd538c84912ec089eef09a0b not-for-merge branch 'testcommit4702' of github.com:jantman/gitpython_issue_301 +fb36375ddf1743b4668a4eb14387e0a9ab698842 not-for-merge branch 'testcommit4703' of github.com:jantman/gitpython_issue_301 +a7ec52ca63f42c30deccb00c6585a7f44021536c not-for-merge branch 'testcommit4704' of github.com:jantman/gitpython_issue_301 +efa8fa75318191832949065a754e96c79f9f2ddf not-for-merge branch 'testcommit4705' of github.com:jantman/gitpython_issue_301 +656074d3587cb08c61c4976d10d13c7bc698dde0 not-for-merge branch 'testcommit4706' of github.com:jantman/gitpython_issue_301 +7631e155ebe75f7f356f1aa123623d11bec4a235 not-for-merge branch 'testcommit4707' of github.com:jantman/gitpython_issue_301 +9a9541589878253c55a3c0f322d736a400ee2417 not-for-merge branch 'testcommit4708' of github.com:jantman/gitpython_issue_301 +bf9a1b59414fe5352b273844a9a9e2e5c9047f02 not-for-merge branch 'testcommit4709' of github.com:jantman/gitpython_issue_301 +0b57494572f1ba3d77a1ed467abcdaf6d7996469 not-for-merge branch 'testcommit471' of github.com:jantman/gitpython_issue_301 +9fbae1120c6a5284b8d5c36cd792e53a9bcf64eb not-for-merge branch 'testcommit4710' of github.com:jantman/gitpython_issue_301 +b2c147e9c41853bb862a3a34b3175f1bebf79dfe not-for-merge branch 'testcommit4711' of github.com:jantman/gitpython_issue_301 +25e56b40f5f1001e4dcff44be1377e850bf26cf7 not-for-merge branch 'testcommit4712' of github.com:jantman/gitpython_issue_301 +1268d28c4d6959fbd7c4d7ac6a9ce4e4aaa51076 not-for-merge branch 'testcommit4713' of github.com:jantman/gitpython_issue_301 +5cc5af2fb72044e4502896f5d1b4643a76b34314 not-for-merge branch 'testcommit4714' of github.com:jantman/gitpython_issue_301 +4c9aae9857e38652c972c61779fd26a793db615b not-for-merge branch 'testcommit4715' of github.com:jantman/gitpython_issue_301 +7e0a2d3844b64fdb6538cdf77112e3864861a389 not-for-merge branch 'testcommit4716' of github.com:jantman/gitpython_issue_301 +c0b56ec06503f88a5536a76813f2a8002920de76 not-for-merge branch 'testcommit4717' of github.com:jantman/gitpython_issue_301 +fa349fb4eedc8fe83b212bc50a6cde0ac60dfdf1 not-for-merge branch 'testcommit4718' of github.com:jantman/gitpython_issue_301 +8b89383ed3342e1868a8f15468323556f896b0a5 not-for-merge branch 'testcommit4719' of github.com:jantman/gitpython_issue_301 +57e4f05db54fbbcd1c37dad3ab7c6fda4e28ada4 not-for-merge branch 'testcommit472' of github.com:jantman/gitpython_issue_301 +47baa17d9fdf816cca446906ac6b4ec5bcb810d5 not-for-merge branch 'testcommit4720' of github.com:jantman/gitpython_issue_301 +ef69fd4b86df724bb605b1ce5da3fbef0253e131 not-for-merge branch 'testcommit4721' of github.com:jantman/gitpython_issue_301 +f1add743ee1a3e4ffc5dd4160532fa999c474cdb not-for-merge branch 'testcommit4722' of github.com:jantman/gitpython_issue_301 +1abbbace215189b65786d68e7be908894e79f4d9 not-for-merge branch 'testcommit4723' of github.com:jantman/gitpython_issue_301 +4b583f0793a66358172535514980f507f4b3c101 not-for-merge branch 'testcommit4724' of github.com:jantman/gitpython_issue_301 +01cc8110edda20b344ceb5f0bb14b91f4a67b86d not-for-merge branch 'testcommit4725' of github.com:jantman/gitpython_issue_301 +650118d2905e90bff7f12b9483102136d1a11314 not-for-merge branch 'testcommit4726' of github.com:jantman/gitpython_issue_301 +9876c400fddf34e6d63cb79f63f1cdcde682fa7c not-for-merge branch 'testcommit4727' of github.com:jantman/gitpython_issue_301 +adbf0e2652278a2c5327f8bfcdd82053ab7898ff not-for-merge branch 'testcommit4728' of github.com:jantman/gitpython_issue_301 +0f1b5aa64f3b4f8236750501d52e08c9152d3140 not-for-merge branch 'testcommit4729' of github.com:jantman/gitpython_issue_301 +c5fdd38e3ba69c6339edcff67fc0f35c9c6c8229 not-for-merge branch 'testcommit473' of github.com:jantman/gitpython_issue_301 +a461aaef1e126939d88af1e2ad6568aefa6a5ff8 not-for-merge branch 'testcommit4730' of github.com:jantman/gitpython_issue_301 +f7f1bc6411c66f79dea26d79f79ea6da3ba0d289 not-for-merge branch 'testcommit4731' of github.com:jantman/gitpython_issue_301 +17f0489db85bb2e7a6a279c99ed0162b4f092c5d not-for-merge branch 'testcommit4732' of github.com:jantman/gitpython_issue_301 +b93bd99dc9cd848d747b7ef8d08114422a781b66 not-for-merge branch 'testcommit4733' of github.com:jantman/gitpython_issue_301 +bdb81e21b4ffb025fc258bdff60f33bf60775163 not-for-merge branch 'testcommit4734' of github.com:jantman/gitpython_issue_301 +fdf820206d700a7c2f3533be337dd1450d3b2ae5 not-for-merge branch 'testcommit4735' of github.com:jantman/gitpython_issue_301 +d0516245e042d435ade211d3038623160e4dce6e not-for-merge branch 'testcommit4736' of github.com:jantman/gitpython_issue_301 +5da00cd8aa59bde795892f8273527ff53e255b04 not-for-merge branch 'testcommit4737' of github.com:jantman/gitpython_issue_301 +3a581973ccbca62cd93a6dc5ddb41cf6e0afaaca not-for-merge branch 'testcommit4738' of github.com:jantman/gitpython_issue_301 +30062baab4c3184b8410664fd0366665f9b23f66 not-for-merge branch 'testcommit4739' of github.com:jantman/gitpython_issue_301 +cb90b672c33fc034a4b6c1ba574a94a3c5c0d8c7 not-for-merge branch 'testcommit474' of github.com:jantman/gitpython_issue_301 +367ee76c8836f8ef6f5da5b039e2ccbcdd671d92 not-for-merge branch 'testcommit4740' of github.com:jantman/gitpython_issue_301 +caaafcac3305d9bd2ff6af98791b724b6e95c048 not-for-merge branch 'testcommit4741' of github.com:jantman/gitpython_issue_301 +009ff4492544b991f46550de7a59fbed92019ff4 not-for-merge branch 'testcommit4742' of github.com:jantman/gitpython_issue_301 +8c4c340d4dc7df5ccdf6002b9bc5582db6a240ce not-for-merge branch 'testcommit4743' of github.com:jantman/gitpython_issue_301 +d550ecc2fb82c75e61a42c429237bfd30497e04f not-for-merge branch 'testcommit4744' of github.com:jantman/gitpython_issue_301 +bdfcf93190280e5ba874a39f5eba8fe7d70dcd30 not-for-merge branch 'testcommit4745' of github.com:jantman/gitpython_issue_301 +c4030e1d7b10c4a194493fc4001c02214f401df4 not-for-merge branch 'testcommit4746' of github.com:jantman/gitpython_issue_301 +b1b8a74e7223423bdccbf7240c46d246a5b94707 not-for-merge branch 'testcommit4747' of github.com:jantman/gitpython_issue_301 +7dcdf2507b09496ccd1e6deab9593ecbd54dbcbb not-for-merge branch 'testcommit4748' of github.com:jantman/gitpython_issue_301 +681c0432d22d1af1d9339ebe8a7452820a725b26 not-for-merge branch 'testcommit4749' of github.com:jantman/gitpython_issue_301 +b5737cad7c154b5dc3e63a673f18bd5f36248a8c not-for-merge branch 'testcommit475' of github.com:jantman/gitpython_issue_301 +7e55d9a01f26b536014c7bf6bff32eced4cbc4b5 not-for-merge branch 'testcommit4750' of github.com:jantman/gitpython_issue_301 +57a5a899e81a2aeee5a674fa7b25ab1294e65aa6 not-for-merge branch 'testcommit4751' of github.com:jantman/gitpython_issue_301 +b8ec3f8871a61a3b9b2d209e06270f8ad18658eb not-for-merge branch 'testcommit4752' of github.com:jantman/gitpython_issue_301 +039e57e0809fb429aee18e8ce95167b535ee4053 not-for-merge branch 'testcommit4753' of github.com:jantman/gitpython_issue_301 +ff31f45c8470f99bdf4558d56ad5f977c5579e19 not-for-merge branch 'testcommit4754' of github.com:jantman/gitpython_issue_301 +2cdb3f1ce30a4beeb31a67e1b572bd75aba86a15 not-for-merge branch 'testcommit4755' of github.com:jantman/gitpython_issue_301 +9340574a8286af190322394261d343859c3b9413 not-for-merge branch 'testcommit4756' of github.com:jantman/gitpython_issue_301 +7cc16b46721ea783155f6ad0e2605de5f9fec53c not-for-merge branch 'testcommit4757' of github.com:jantman/gitpython_issue_301 +a28ce7eb446c78b0ac07826b9fbb72e36455c226 not-for-merge branch 'testcommit4758' of github.com:jantman/gitpython_issue_301 +e0d3b75affc218ab68a28c0b14f751134f57db54 not-for-merge branch 'testcommit4759' of github.com:jantman/gitpython_issue_301 +c72b3e087c56a82b2dc6fabe742d7e5bccfce31e not-for-merge branch 'testcommit476' of github.com:jantman/gitpython_issue_301 +f70ad114725aa0eee24804c8498821f4217dd73c not-for-merge branch 'testcommit4760' of github.com:jantman/gitpython_issue_301 +55767fcb78e91d770228492c390eb375e4452181 not-for-merge branch 'testcommit4761' of github.com:jantman/gitpython_issue_301 +caeaaee3e1c0d207898bc2407449dc3bff1bc566 not-for-merge branch 'testcommit4762' of github.com:jantman/gitpython_issue_301 +1a7077fcf2ead60494ee48d8cda8704243cddb52 not-for-merge branch 'testcommit4763' of github.com:jantman/gitpython_issue_301 +a78a6a78a1f362b43d485a5cf51cd5414babc179 not-for-merge branch 'testcommit4764' of github.com:jantman/gitpython_issue_301 +74055d80d474a67b3e683c857fa83b9c1d46172b not-for-merge branch 'testcommit4765' of github.com:jantman/gitpython_issue_301 +3ced591cfbd6b174da051309a52b6d4febf5be50 not-for-merge branch 'testcommit4766' of github.com:jantman/gitpython_issue_301 +703c1df1e6bd58f126335b72feff8ac4e9009f05 not-for-merge branch 'testcommit4767' of github.com:jantman/gitpython_issue_301 +c81a5b76f1d6d57555a51fdeb2da22802df7c30f not-for-merge branch 'testcommit4768' of github.com:jantman/gitpython_issue_301 +9ef553a342ddc71bd9f02ac9c66fc9e645c009a0 not-for-merge branch 'testcommit4769' of github.com:jantman/gitpython_issue_301 +b4d006109bb472e591c75f3b2d0c841605c84ec0 not-for-merge branch 'testcommit477' of github.com:jantman/gitpython_issue_301 +d6fb5bb083d2a27d92063861d66611bf9c31a932 not-for-merge branch 'testcommit4770' of github.com:jantman/gitpython_issue_301 +989ee14f5df38347c9e6758af74e4e945d1c36c8 not-for-merge branch 'testcommit4771' of github.com:jantman/gitpython_issue_301 +df0f5f54f021b36d5660e12fb3f6dd4b6bd3b658 not-for-merge branch 'testcommit4772' of github.com:jantman/gitpython_issue_301 +450738f1cb07a13deef9bcc477390a790efbf7f9 not-for-merge branch 'testcommit4773' of github.com:jantman/gitpython_issue_301 +6364fe5716435df242947f874ff7ef364c270e5d not-for-merge branch 'testcommit4774' of github.com:jantman/gitpython_issue_301 +9c4b655f023e394f8caa6e227d9e202adf1eb2d7 not-for-merge branch 'testcommit4775' of github.com:jantman/gitpython_issue_301 +4f5b46c5dafcbe2c252626d1cf3d5392f1d7f340 not-for-merge branch 'testcommit4776' of github.com:jantman/gitpython_issue_301 +13f1a86587dd48d1ddc9f8bf584b1be292c00965 not-for-merge branch 'testcommit4777' of github.com:jantman/gitpython_issue_301 +59984f06106897542d6553b5d923f9a6ff43dac4 not-for-merge branch 'testcommit4778' of github.com:jantman/gitpython_issue_301 +b6f54bfe2ccf8f253fff6bdf0724cd614623eb9a not-for-merge branch 'testcommit4779' of github.com:jantman/gitpython_issue_301 +0a98fa71a74d51baddcb510252781ef511db7fb2 not-for-merge branch 'testcommit478' of github.com:jantman/gitpython_issue_301 +ceafcfe0f41ca1f1e6488a4e958d39cf2cc4a123 not-for-merge branch 'testcommit4780' of github.com:jantman/gitpython_issue_301 +91c874733d4ea294a17e649faef7fa9af97ec8f1 not-for-merge branch 'testcommit4781' of github.com:jantman/gitpython_issue_301 +d87d4ea406c402656b073b2ddfebf2f108e44e8a not-for-merge branch 'testcommit4782' of github.com:jantman/gitpython_issue_301 +7f2b7476f912fe9d9c6af171dac55f43ab2b397e not-for-merge branch 'testcommit4783' of github.com:jantman/gitpython_issue_301 +dee931d3645e482b98b7c68516c368d58d964e2c not-for-merge branch 'testcommit4784' of github.com:jantman/gitpython_issue_301 +64dd7dfe23166c9a076611b415c930b404c10dd4 not-for-merge branch 'testcommit4785' of github.com:jantman/gitpython_issue_301 +464c257d5f609648955fc8bd0073a67abf88fa6f not-for-merge branch 'testcommit4786' of github.com:jantman/gitpython_issue_301 +e0e9548becf04661a6df870e06471c5171a9873c not-for-merge branch 'testcommit4787' of github.com:jantman/gitpython_issue_301 +de70ce3b10e2b85a1bddbeb54be192a4bcf7a083 not-for-merge branch 'testcommit4788' of github.com:jantman/gitpython_issue_301 +cd12173c1d60544d4c5f48321a6c73f178efd346 not-for-merge branch 'testcommit4789' of github.com:jantman/gitpython_issue_301 +f3c706707e8a4093d448d948338bb47c18884352 not-for-merge branch 'testcommit479' of github.com:jantman/gitpython_issue_301 +4eafb6bbbd03cf9c86c340134bab24f48c61584b not-for-merge branch 'testcommit4790' of github.com:jantman/gitpython_issue_301 +aa6d45c63dee95ad50cb6eab4acad58efe686f82 not-for-merge branch 'testcommit4791' of github.com:jantman/gitpython_issue_301 +89439da78b3358ca7481edafed3a78a666bc925c not-for-merge branch 'testcommit4792' of github.com:jantman/gitpython_issue_301 +fbdf551c0353bd998607c87b3742b2b8fde3f23c not-for-merge branch 'testcommit4793' of github.com:jantman/gitpython_issue_301 +9b1e3da2d5400ab8cee41b1fedadc66606212ffc not-for-merge branch 'testcommit4794' of github.com:jantman/gitpython_issue_301 +818b8717be3f6f737ded2a3c812af33c07399e3b not-for-merge branch 'testcommit4795' of github.com:jantman/gitpython_issue_301 +b5be4374c35cbf2064d35afda06350825fe192e1 not-for-merge branch 'testcommit4796' of github.com:jantman/gitpython_issue_301 +b3f0a68e7d8e111a9941f346fb9b20064a0968f8 not-for-merge branch 'testcommit4797' of github.com:jantman/gitpython_issue_301 +499b056d1e978ebd37f81992a06fcf825d29d2d4 not-for-merge branch 'testcommit4798' of github.com:jantman/gitpython_issue_301 +26763fb6ac7648b952d9eaaa904e0849c3dcd21f not-for-merge branch 'testcommit4799' of github.com:jantman/gitpython_issue_301 +200b93bf3e1739198c0a643d21ffa9ec90171d74 not-for-merge branch 'testcommit48' of github.com:jantman/gitpython_issue_301 +adadd5c09f650d34468764da909b8fc21a493c4d not-for-merge branch 'testcommit480' of github.com:jantman/gitpython_issue_301 +2c1b1d4fecf87b50aaf2d2d1e83000fcf96cd6b2 not-for-merge branch 'testcommit4800' of github.com:jantman/gitpython_issue_301 +7396157ed5f9fbb3913b817a23ca41dc729df8d2 not-for-merge branch 'testcommit4801' of github.com:jantman/gitpython_issue_301 +5646a232b8c5a3cdbf47e7ec1eacd9d8fdae989d not-for-merge branch 'testcommit4802' of github.com:jantman/gitpython_issue_301 +47e107bb03079718c0cffaa62b6c3354a3d2cff6 not-for-merge branch 'testcommit4803' of github.com:jantman/gitpython_issue_301 +8a8e4d1e1c845bbb7cd9d8d21604f51404728eec not-for-merge branch 'testcommit4804' of github.com:jantman/gitpython_issue_301 +486c2a3a72c74dd06cd08c8f20acda06bd9d7909 not-for-merge branch 'testcommit4805' of github.com:jantman/gitpython_issue_301 +c75a2b9b8f52f198712202abc5364234d9eed365 not-for-merge branch 'testcommit4806' of github.com:jantman/gitpython_issue_301 +a80d0c0548d10b6989808a9b40dc800c88486abc not-for-merge branch 'testcommit4807' of github.com:jantman/gitpython_issue_301 +9c80ba3f1f1e52c029bff29cb96401bd575eb015 not-for-merge branch 'testcommit4808' of github.com:jantman/gitpython_issue_301 +78623aedb95842e441c46570e33c85ccda50c56b not-for-merge branch 'testcommit4809' of github.com:jantman/gitpython_issue_301 +c537e917ffad17cf62f79bff77dd8de7aea74d17 not-for-merge branch 'testcommit481' of github.com:jantman/gitpython_issue_301 +3ef5388cea576d59ec3d3806455d98cdcaba75f1 not-for-merge branch 'testcommit4810' of github.com:jantman/gitpython_issue_301 +921cb0104254c6bbeb6d1222a3d98dcbad0921a3 not-for-merge branch 'testcommit4811' of github.com:jantman/gitpython_issue_301 +e826256813339835a2fd7817dd7ebb551674a8bf not-for-merge branch 'testcommit4812' of github.com:jantman/gitpython_issue_301 +2245305b6e787ae1421d3a9fe7adb8f0cfe68851 not-for-merge branch 'testcommit4813' of github.com:jantman/gitpython_issue_301 +b5800727b17dad948826f23c8d3d240ab4a6c707 not-for-merge branch 'testcommit4814' of github.com:jantman/gitpython_issue_301 +e3d954c768058aea363067d4aa5040d696ab0e67 not-for-merge branch 'testcommit4815' of github.com:jantman/gitpython_issue_301 +0348043e0e0a66e3d587fc7af204ca3ffa0989a5 not-for-merge branch 'testcommit4816' of github.com:jantman/gitpython_issue_301 +a7b6bacfd8e540961db384e66b3fdfc66f69ef27 not-for-merge branch 'testcommit4817' of github.com:jantman/gitpython_issue_301 +cb8be592ef228f279241d585ad65055e91dafa0f not-for-merge branch 'testcommit4818' of github.com:jantman/gitpython_issue_301 +2cdc84a696ace92eb37975c3c17aade732cc4bc9 not-for-merge branch 'testcommit4819' of github.com:jantman/gitpython_issue_301 +8019e1daa505af7bbd67ef954439e43f435f9949 not-for-merge branch 'testcommit482' of github.com:jantman/gitpython_issue_301 +ad54168be9509eabbec3c5c88c27c6f90e03a040 not-for-merge branch 'testcommit4820' of github.com:jantman/gitpython_issue_301 +b1915b8a48ad72cdc3d056f88d4df3d9662da702 not-for-merge branch 'testcommit4821' of github.com:jantman/gitpython_issue_301 +21eacb67a9f6b2d5e2be162ba8c13eaf8fa9cef3 not-for-merge branch 'testcommit4822' of github.com:jantman/gitpython_issue_301 +538aa6a4932df946d8314baa898c7bc43fc790e0 not-for-merge branch 'testcommit4823' of github.com:jantman/gitpython_issue_301 +36e843c017c01d88fdeeff2985f3aa8dc760de08 not-for-merge branch 'testcommit4824' of github.com:jantman/gitpython_issue_301 +cc3956673b7a9e74ac134d93f6a8d7749313a7a5 not-for-merge branch 'testcommit4825' of github.com:jantman/gitpython_issue_301 +0effbe4e45f04fcd1f4362b1a1bc87469888af9f not-for-merge branch 'testcommit4826' of github.com:jantman/gitpython_issue_301 +8d64fed50308450a8d5547317197a92782fc4367 not-for-merge branch 'testcommit4827' of github.com:jantman/gitpython_issue_301 +d67b7db4f4d6a8bb90f77fe6c8fd82b19ba77da8 not-for-merge branch 'testcommit4828' of github.com:jantman/gitpython_issue_301 +2fe18c487147cbc37e298e26ea9e1320c1cf5a50 not-for-merge branch 'testcommit4829' of github.com:jantman/gitpython_issue_301 +0c9f5fca72838c6e9e8871872684549932fcc663 not-for-merge branch 'testcommit483' of github.com:jantman/gitpython_issue_301 +ee5a3293882850fbecbe9c4236968f6d1904d6e9 not-for-merge branch 'testcommit4830' of github.com:jantman/gitpython_issue_301 +b7b3cb1d16bc7d7493ffc461210156cade6ef96c not-for-merge branch 'testcommit4831' of github.com:jantman/gitpython_issue_301 +1f4760a0f761cfa3661478799e1ee6e79bf782ab not-for-merge branch 'testcommit4832' of github.com:jantman/gitpython_issue_301 +6a5a19408308f1d3e429cb001fab8c231c94ba63 not-for-merge branch 'testcommit4833' of github.com:jantman/gitpython_issue_301 +3a0ce9008d177d20ea62ad59a7b75714bfa28777 not-for-merge branch 'testcommit4834' of github.com:jantman/gitpython_issue_301 +418970ab8f74f513f3dce5d89aec062ff7a2ff4d not-for-merge branch 'testcommit4835' of github.com:jantman/gitpython_issue_301 +81da625ee9b021e0f861f00bc18b325dd3e26346 not-for-merge branch 'testcommit4836' of github.com:jantman/gitpython_issue_301 +e6d6a495dc34a2ffcf01956ca366a69abe4947f6 not-for-merge branch 'testcommit4837' of github.com:jantman/gitpython_issue_301 +68a03f82fb18ebc338c02b82bb3ef4d3631311c6 not-for-merge branch 'testcommit4838' of github.com:jantman/gitpython_issue_301 +d99051e83311ff60dee3ec6223d4d5836b5c1ceb not-for-merge branch 'testcommit4839' of github.com:jantman/gitpython_issue_301 +1718a4e5492c1ce3b6d68d4b7844cdaff2abfe0c not-for-merge branch 'testcommit484' of github.com:jantman/gitpython_issue_301 +8efcfcd1e8275909b3735a2e5f259ad507aa7c6d not-for-merge branch 'testcommit4840' of github.com:jantman/gitpython_issue_301 +57ff33b7649440420c07dfd1a42dfd32895801ce not-for-merge branch 'testcommit4841' of github.com:jantman/gitpython_issue_301 +389780c26d584a69e1e12b72593cad0cccf1a15d not-for-merge branch 'testcommit4842' of github.com:jantman/gitpython_issue_301 +67ac6b5ca5f689382faaf1f098ad886609bbea70 not-for-merge branch 'testcommit4843' of github.com:jantman/gitpython_issue_301 +0d571b3d912555b057f348d588544edca1446ab6 not-for-merge branch 'testcommit4844' of github.com:jantman/gitpython_issue_301 +ae6ab622df2beebd3263c40a9d1c81a28704b7bb not-for-merge branch 'testcommit4845' of github.com:jantman/gitpython_issue_301 +d7dcf0f24cafc23cda14dfc1331c06964e90dabd not-for-merge branch 'testcommit4846' of github.com:jantman/gitpython_issue_301 +3840a8113886deb33d7ec2e516d08477aba24b55 not-for-merge branch 'testcommit4847' of github.com:jantman/gitpython_issue_301 +400ac52de92299328a9beedf8c37b4fdd0a6bad7 not-for-merge branch 'testcommit4848' of github.com:jantman/gitpython_issue_301 +885af1be7be1af252832db73fa905942feb9099a not-for-merge branch 'testcommit4849' of github.com:jantman/gitpython_issue_301 +58799889a4c4976941d26813a3c995e42157d667 not-for-merge branch 'testcommit485' of github.com:jantman/gitpython_issue_301 +549a624495c164dd9801be4b5e86c5258c70ced0 not-for-merge branch 'testcommit4850' of github.com:jantman/gitpython_issue_301 +cc8b49809f4be6ca20f6650148bfcf4e7d167253 not-for-merge branch 'testcommit4851' of github.com:jantman/gitpython_issue_301 +897eea43202254e365495480c28ac7d95b3b11aa not-for-merge branch 'testcommit4852' of github.com:jantman/gitpython_issue_301 +230a0e7aa3b8f0af4f413179588721566f531e6d not-for-merge branch 'testcommit4853' of github.com:jantman/gitpython_issue_301 +b511ca98acc98036355678f0454b449d10aebfa0 not-for-merge branch 'testcommit4854' of github.com:jantman/gitpython_issue_301 +459b41cdfb4fe9e166c474a847324f11e87b260c not-for-merge branch 'testcommit4855' of github.com:jantman/gitpython_issue_301 +c9ce9b41f7c4a3a05ade72e1d4e6b8e05f107c07 not-for-merge branch 'testcommit4856' of github.com:jantman/gitpython_issue_301 +15b33f0962f2074a7a1f5f82d3e57fe855719ce4 not-for-merge branch 'testcommit4857' of github.com:jantman/gitpython_issue_301 +53b43d6b4fa1156c6f925f3a002f6b14721d17fc not-for-merge branch 'testcommit4858' of github.com:jantman/gitpython_issue_301 +36ac41452fc09093acb685f78387a345392a17f4 not-for-merge branch 'testcommit4859' of github.com:jantman/gitpython_issue_301 +a6e9790bca8c8ac8c34bca4b917c31ea5cfc550c not-for-merge branch 'testcommit486' of github.com:jantman/gitpython_issue_301 +f0fefd42d41fb2c566c0691bd66ff41eff2802bd not-for-merge branch 'testcommit4860' of github.com:jantman/gitpython_issue_301 +e45c32e1a5da64f03b2bd0037622a184700058f2 not-for-merge branch 'testcommit4861' of github.com:jantman/gitpython_issue_301 +a367d5c803f294bf928284408e7d9827c87fdda8 not-for-merge branch 'testcommit4862' of github.com:jantman/gitpython_issue_301 +a821ebd7105c7de61630064ffa4bcbde0065dd3d not-for-merge branch 'testcommit4863' of github.com:jantman/gitpython_issue_301 +cb2b479dd5d3acd07872c4c17ebfcc262f3ef5a8 not-for-merge branch 'testcommit4864' of github.com:jantman/gitpython_issue_301 +99673500cac034ea224d4ac0d4313c25ede78854 not-for-merge branch 'testcommit4865' of github.com:jantman/gitpython_issue_301 +f58e27a10d7fa1584a898fdad49d23b0ab8cfe6d not-for-merge branch 'testcommit4866' of github.com:jantman/gitpython_issue_301 +dfb894a6b797808708203b75572d4af0ca2ca6fd not-for-merge branch 'testcommit4867' of github.com:jantman/gitpython_issue_301 +fc648d5aaf550c2edc2c5297f35abb1be53541d0 not-for-merge branch 'testcommit4868' of github.com:jantman/gitpython_issue_301 +83d4458b27eaa159ccb1e947516cd921908ba0dc not-for-merge branch 'testcommit4869' of github.com:jantman/gitpython_issue_301 +5b1af6038b9684cb8aaa894a8694c5a078ac3026 not-for-merge branch 'testcommit487' of github.com:jantman/gitpython_issue_301 +4351d6a34c69578342e4cbff2550bf581ed3df92 not-for-merge branch 'testcommit4870' of github.com:jantman/gitpython_issue_301 +dbe97c72fc6b972d9d9a4824b02ed911f179ad07 not-for-merge branch 'testcommit4871' of github.com:jantman/gitpython_issue_301 +59c4d3fa8e3e2f790b1836d29f12d7a4e6619502 not-for-merge branch 'testcommit4872' of github.com:jantman/gitpython_issue_301 +78ca87f036905814bc155ea78dad3f90e7025d67 not-for-merge branch 'testcommit4873' of github.com:jantman/gitpython_issue_301 +941741f88d67e2223bd2a1b458271878af065a3e not-for-merge branch 'testcommit4874' of github.com:jantman/gitpython_issue_301 +27e38b8839df81b51a684c46b85e936634420e46 not-for-merge branch 'testcommit4875' of github.com:jantman/gitpython_issue_301 +cfb7361cd6f5c01fccd6d10919741cf6503259ca not-for-merge branch 'testcommit4876' of github.com:jantman/gitpython_issue_301 +bcd78e07e37ae0bad26d301af787e4ae05ed5e02 not-for-merge branch 'testcommit4877' of github.com:jantman/gitpython_issue_301 +74268e975c348732f1578401f30913639b29176c not-for-merge branch 'testcommit4878' of github.com:jantman/gitpython_issue_301 +2e709e84f9cb01f189d1c11e21b14fb9c238abde not-for-merge branch 'testcommit4879' of github.com:jantman/gitpython_issue_301 +22d447e21b635be73ce65ea89213ee2a14305fcd not-for-merge branch 'testcommit488' of github.com:jantman/gitpython_issue_301 +217d13bbcaf4f922dd8e7f8c5efeb1521cca60e8 not-for-merge branch 'testcommit4880' of github.com:jantman/gitpython_issue_301 +73845341832815776dda3af4e50203b2c70aff61 not-for-merge branch 'testcommit4881' of github.com:jantman/gitpython_issue_301 +37843af2396839217856fa86739bce9fe2a1189c not-for-merge branch 'testcommit4882' of github.com:jantman/gitpython_issue_301 +cbf36da6cb52d7105691fc24c49b6c787ec0d8a1 not-for-merge branch 'testcommit4883' of github.com:jantman/gitpython_issue_301 +67fad606b36bf297c9e8c4713c360296d5f6481a not-for-merge branch 'testcommit4884' of github.com:jantman/gitpython_issue_301 +0f6aa2f595dc20b5df6f1430bc80380b16c8e4fe not-for-merge branch 'testcommit4885' of github.com:jantman/gitpython_issue_301 +2052c4a6eb32b78589bd5ac5a9ab1d9f11a6d6ef not-for-merge branch 'testcommit4886' of github.com:jantman/gitpython_issue_301 +f3de71cbd3740e2cdd051612dd37c480c5b7a963 not-for-merge branch 'testcommit4887' of github.com:jantman/gitpython_issue_301 +3d0115a1c2c6eb2541a559c13ee1fe26329868a8 not-for-merge branch 'testcommit4888' of github.com:jantman/gitpython_issue_301 +5877cfa2631cb5f904c9ef6edd4bdcbad6d88926 not-for-merge branch 'testcommit4889' of github.com:jantman/gitpython_issue_301 +6abe493a3a217b737ccc1f736ecda10970a500ca not-for-merge branch 'testcommit489' of github.com:jantman/gitpython_issue_301 +79ff0d0f6515e86dfc6a56f4b69fefe8bdbd38ab not-for-merge branch 'testcommit4890' of github.com:jantman/gitpython_issue_301 +3e80331b0b9db3a68c27f3a39049c37a1d52a6ec not-for-merge branch 'testcommit4891' of github.com:jantman/gitpython_issue_301 +97b84b21639efa5b35774d7e29e8e74155c71b0d not-for-merge branch 'testcommit4892' of github.com:jantman/gitpython_issue_301 +881a573148d1d94fa26b5eb25712784f8d3303f5 not-for-merge branch 'testcommit4893' of github.com:jantman/gitpython_issue_301 +4c9274d49966a9e86eb41a08742669151d9fefcf not-for-merge branch 'testcommit4894' of github.com:jantman/gitpython_issue_301 +87a7e344afe99ff34b85c71181329dc27a0d7832 not-for-merge branch 'testcommit4895' of github.com:jantman/gitpython_issue_301 +1470f6be4490d07647887f7bb75c82d71d027099 not-for-merge branch 'testcommit4896' of github.com:jantman/gitpython_issue_301 +23fad48425144e68c6bdfcc2ecc46ab456ae79fa not-for-merge branch 'testcommit4897' of github.com:jantman/gitpython_issue_301 +6ed3cd5f43f57751f9d05916a888e3077bc21266 not-for-merge branch 'testcommit4898' of github.com:jantman/gitpython_issue_301 +f9f104267a5a3d39f72a8619dc1542329dfb17d3 not-for-merge branch 'testcommit4899' of github.com:jantman/gitpython_issue_301 +510985b3b3736e6a7aa936d7df07593fff9d81fd not-for-merge branch 'testcommit49' of github.com:jantman/gitpython_issue_301 +b62a7ede2089094e8d70fda99926914216f961ce not-for-merge branch 'testcommit490' of github.com:jantman/gitpython_issue_301 +b0c90df5719181b894964f67b1fd154d7f476338 not-for-merge branch 'testcommit4900' of github.com:jantman/gitpython_issue_301 +8f911ad4e49577bbe144de655eab517407d16af6 not-for-merge branch 'testcommit4901' of github.com:jantman/gitpython_issue_301 +f8dcf44b3aedf81229c77218de6c35fa84285a95 not-for-merge branch 'testcommit4902' of github.com:jantman/gitpython_issue_301 +02cd7055c67b2f497c731e99ed0e410ea6ecaf88 not-for-merge branch 'testcommit4903' of github.com:jantman/gitpython_issue_301 +4eb23a530cf38f5bf30b65b049b6f7e1dd2033be not-for-merge branch 'testcommit4904' of github.com:jantman/gitpython_issue_301 +12a5c2302ce9d0bdec0f2bd1b4ffab4446ec7989 not-for-merge branch 'testcommit4905' of github.com:jantman/gitpython_issue_301 +e5c023dbde8fd11c5cda079e13035b1c32c8172e not-for-merge branch 'testcommit4906' of github.com:jantman/gitpython_issue_301 +c64de60a6362eb58b6effe036b75cd5fc80cb29e not-for-merge branch 'testcommit4907' of github.com:jantman/gitpython_issue_301 +47d393f16644c887effc011f1637235bf3a3819f not-for-merge branch 'testcommit4908' of github.com:jantman/gitpython_issue_301 +cde42e18fc0b7854348eaec06dc8d41e2597950d not-for-merge branch 'testcommit4909' of github.com:jantman/gitpython_issue_301 +7470b36ca9a524dcec6419b2e18796afe004fbb7 not-for-merge branch 'testcommit491' of github.com:jantman/gitpython_issue_301 +505a03c18ceb3436ecb2c1c524c78862f624c5c2 not-for-merge branch 'testcommit4910' of github.com:jantman/gitpython_issue_301 +edb075b9b53bdcb9b2cbcf53bc145fa21397875a not-for-merge branch 'testcommit4911' of github.com:jantman/gitpython_issue_301 +64e2cb11ee2a2bbf32c8a254e3e24eaf6547e1c1 not-for-merge branch 'testcommit4912' of github.com:jantman/gitpython_issue_301 +4cafee368fb00cd5a7e16861bb38d472caa2092d not-for-merge branch 'testcommit4913' of github.com:jantman/gitpython_issue_301 +bc63bdf115ae89edf0c53eb07300ed5386c91df9 not-for-merge branch 'testcommit4914' of github.com:jantman/gitpython_issue_301 +01edede31d3e2aa6435169a4ab5469ef5f829674 not-for-merge branch 'testcommit4915' of github.com:jantman/gitpython_issue_301 +1e289687c17dc72840499d7deab12c13c20b1e75 not-for-merge branch 'testcommit4916' of github.com:jantman/gitpython_issue_301 +09b3ce01787c63313cb557cc27bbd71d108c7f74 not-for-merge branch 'testcommit4917' of github.com:jantman/gitpython_issue_301 +4341625b504b8e93a156d4845e430074fe744e85 not-for-merge branch 'testcommit4918' of github.com:jantman/gitpython_issue_301 +a08ca860031c33a0a63912295ab40f4f82d98dd7 not-for-merge branch 'testcommit4919' of github.com:jantman/gitpython_issue_301 +bf4d928c94c62b6b8519c9a40bd32a9e629fa3a8 not-for-merge branch 'testcommit492' of github.com:jantman/gitpython_issue_301 +3ebcfd4634d4ed735b9328a192665d6d49fdd4db not-for-merge branch 'testcommit4920' of github.com:jantman/gitpython_issue_301 +08dd7f6b68635be0c84d6c52a20bcd0ef926c98d not-for-merge branch 'testcommit4921' of github.com:jantman/gitpython_issue_301 +f9515f6b4f521e8e1b56bd742b9c983b543ca9b7 not-for-merge branch 'testcommit4922' of github.com:jantman/gitpython_issue_301 +ef15057d82e6c53b4cd8ad1c8c503537aba98a17 not-for-merge branch 'testcommit4923' of github.com:jantman/gitpython_issue_301 +30942a7d1b72fcf82af83a7a4bace86a254d7028 not-for-merge branch 'testcommit4924' of github.com:jantman/gitpython_issue_301 +2dd9f9c9b24a8e4108e26a78aacd00b8ddca81ee not-for-merge branch 'testcommit4925' of github.com:jantman/gitpython_issue_301 +81ccacd1977d04ae7fad875c880a2f573c38fe39 not-for-merge branch 'testcommit4926' of github.com:jantman/gitpython_issue_301 +22af7cbf1a22a682ed1ed873a606b551f7e178ad not-for-merge branch 'testcommit4927' of github.com:jantman/gitpython_issue_301 +38df393b8ea7f866715de2e7b7cbc5f3764b1e12 not-for-merge branch 'testcommit4928' of github.com:jantman/gitpython_issue_301 +76ffa8b708a880151f8963008fe7adb3b8706c8f not-for-merge branch 'testcommit4929' of github.com:jantman/gitpython_issue_301 +b1921c9a6ab3459cce4da6f14eca55fb8be49b85 not-for-merge branch 'testcommit493' of github.com:jantman/gitpython_issue_301 +9941d21519390af85dc48fba4487457f2ee0fdd5 not-for-merge branch 'testcommit4930' of github.com:jantman/gitpython_issue_301 +dbe3693634c4774007c4938d947e1d38908de0f3 not-for-merge branch 'testcommit4931' of github.com:jantman/gitpython_issue_301 +3c62b047e45d8199841c7a79fd4b6d93e79ed5b1 not-for-merge branch 'testcommit4932' of github.com:jantman/gitpython_issue_301 +d55ea1ef07eddf7685979bf18a79f2d343fea7be not-for-merge branch 'testcommit4933' of github.com:jantman/gitpython_issue_301 +a80b3e2917f7c65e62c56abd2efbd9d9be178430 not-for-merge branch 'testcommit4934' of github.com:jantman/gitpython_issue_301 +1d920f054f6beff2af672d7f8cdc55505330db63 not-for-merge branch 'testcommit4935' of github.com:jantman/gitpython_issue_301 +20fb10bd60a9686bb0abffbf8f66d04fea0ad507 not-for-merge branch 'testcommit4936' of github.com:jantman/gitpython_issue_301 +fcb7919ba53f4ad1f324ee4f1be04f67e3e46e10 not-for-merge branch 'testcommit4937' of github.com:jantman/gitpython_issue_301 +f0e86927244e12669680f385531a2bc304a59518 not-for-merge branch 'testcommit4938' of github.com:jantman/gitpython_issue_301 +75896e016ad72b90b24f961ef1985012c8ad8762 not-for-merge branch 'testcommit4939' of github.com:jantman/gitpython_issue_301 +390507d7e39eee72b5f2b2101ef2d967b42f075f not-for-merge branch 'testcommit494' of github.com:jantman/gitpython_issue_301 +7ee2850f04ef65362d847863be485e8c20545762 not-for-merge branch 'testcommit4940' of github.com:jantman/gitpython_issue_301 +b7df9ebd0c9d6c1ad87230cb40cfd7304ef0ded1 not-for-merge branch 'testcommit4941' of github.com:jantman/gitpython_issue_301 +9878c4c3fb20944ac0d1ae5f96602877e2b4d08e not-for-merge branch 'testcommit4942' of github.com:jantman/gitpython_issue_301 +3424a1f5b5882870bcd6f71e49c3cb27e18784b0 not-for-merge branch 'testcommit4943' of github.com:jantman/gitpython_issue_301 +b4d4c5ddf380e01cc9feb30b0647eb6fbd6cfccb not-for-merge branch 'testcommit4944' of github.com:jantman/gitpython_issue_301 +cf4fe699dc4b659ddc9d35f834098c38b3334cd8 not-for-merge branch 'testcommit4945' of github.com:jantman/gitpython_issue_301 +08e09d0c2f08bf046503b14f4226c829996f3135 not-for-merge branch 'testcommit4946' of github.com:jantman/gitpython_issue_301 +7b1d18fe6627a0f9bb90773c1ecd1e4f64ba6064 not-for-merge branch 'testcommit4947' of github.com:jantman/gitpython_issue_301 +c1d6e6a442ed1fc304be05d7480c01fb446b7603 not-for-merge branch 'testcommit4948' of github.com:jantman/gitpython_issue_301 +cb6fdbad7108957255ca8bc5e162802256d65b73 not-for-merge branch 'testcommit4949' of github.com:jantman/gitpython_issue_301 +74141456452fe752112ac1d66c25cc89e5f2b082 not-for-merge branch 'testcommit495' of github.com:jantman/gitpython_issue_301 +41921333290e8ae60fd848ca3529a129a253809a not-for-merge branch 'testcommit4950' of github.com:jantman/gitpython_issue_301 +a485519d33d2d3b7a424c110b840e1b0f3aa8e56 not-for-merge branch 'testcommit4951' of github.com:jantman/gitpython_issue_301 +c5799d2d7d33331d9ec876c0964ededc709732b6 not-for-merge branch 'testcommit4952' of github.com:jantman/gitpython_issue_301 +aec9836dfd342122e9a0717adda03cf3f2fa4b8b not-for-merge branch 'testcommit4953' of github.com:jantman/gitpython_issue_301 +e9a21002eea37fc3f98002e86ccc40caeb5d4dce not-for-merge branch 'testcommit4954' of github.com:jantman/gitpython_issue_301 +1aa4c09befb791462efe82b481a18b3f5eefb116 not-for-merge branch 'testcommit4955' of github.com:jantman/gitpython_issue_301 +dffe42675a59129b633495a46845c931bf7a7ccf not-for-merge branch 'testcommit4956' of github.com:jantman/gitpython_issue_301 +7c14bfd07f747f60b3fc9870bd7ef3037d012d5d not-for-merge branch 'testcommit4957' of github.com:jantman/gitpython_issue_301 +7a7504d112cc70b71b9167a084ddd068a7648e3e not-for-merge branch 'testcommit4958' of github.com:jantman/gitpython_issue_301 +e3933682182c315a2c813c56d28f555d1730f8c5 not-for-merge branch 'testcommit4959' of github.com:jantman/gitpython_issue_301 +f0c5eaf14ba0a996da7a61c2af2b12727095249f not-for-merge branch 'testcommit496' of github.com:jantman/gitpython_issue_301 +d8d4eb198ec22bfcd0553f90199e67ee41079a53 not-for-merge branch 'testcommit4960' of github.com:jantman/gitpython_issue_301 +9ced83c7c64c19c9a44f9af3b1411cdac9a497cf not-for-merge branch 'testcommit4961' of github.com:jantman/gitpython_issue_301 +e5ad44e062e68856fc5a503abe5da0acee56bda5 not-for-merge branch 'testcommit4962' of github.com:jantman/gitpython_issue_301 +8c5f593cc20b060a0685c181f6d64b3dd8049671 not-for-merge branch 'testcommit4963' of github.com:jantman/gitpython_issue_301 +e8ed0f7c052a83e342ab881e082d09e0f892d0d0 not-for-merge branch 'testcommit4964' of github.com:jantman/gitpython_issue_301 +0309f8820c5e0d23684452fa6f760bd4845d4592 not-for-merge branch 'testcommit4965' of github.com:jantman/gitpython_issue_301 +625a9e136da4ef4129b7ee87e648687628f4106a not-for-merge branch 'testcommit4966' of github.com:jantman/gitpython_issue_301 +a7bef094d0e7d74052135daea1389c21845f04c9 not-for-merge branch 'testcommit4967' of github.com:jantman/gitpython_issue_301 +b8109f706c5111d956df68e00a5bb278fed7c0e4 not-for-merge branch 'testcommit4968' of github.com:jantman/gitpython_issue_301 +2f9f9e14818f891b4dda4d7c74753fb4bcebc31a not-for-merge branch 'testcommit4969' of github.com:jantman/gitpython_issue_301 +2d9f0516c5518662fb5371918b46cf0802b3f8f1 not-for-merge branch 'testcommit497' of github.com:jantman/gitpython_issue_301 +49171969b21cff5d9736e1e381e06725ecd7ffc0 not-for-merge branch 'testcommit4970' of github.com:jantman/gitpython_issue_301 +f3b7d8a1bb36be7a57cfea02836c7b0438453c23 not-for-merge branch 'testcommit4971' of github.com:jantman/gitpython_issue_301 +c9ca82918218a667a129ebe6b7c82ab8b6768957 not-for-merge branch 'testcommit4972' of github.com:jantman/gitpython_issue_301 +fce87465dfa60cbda3467c72280142e3431569d1 not-for-merge branch 'testcommit4973' of github.com:jantman/gitpython_issue_301 +1361add13ade248c688421fb21ee93e7349f0f57 not-for-merge branch 'testcommit4974' of github.com:jantman/gitpython_issue_301 +a525eb62e3fb0f5b02d02d9c5e08aa985e3ec4a4 not-for-merge branch 'testcommit4975' of github.com:jantman/gitpython_issue_301 +5c96c2ad6b52efb59dd67e31364a3ee7cdc6bc8b not-for-merge branch 'testcommit4976' of github.com:jantman/gitpython_issue_301 +8c6db17d2fb4375d474831eb64dd0f9077f7e4cd not-for-merge branch 'testcommit4977' of github.com:jantman/gitpython_issue_301 +768352aab53ad82ca18bc447f260e7a91653d871 not-for-merge branch 'testcommit4978' of github.com:jantman/gitpython_issue_301 +8de9bb7e988981e107b5b7e5705531ea0ad874ea not-for-merge branch 'testcommit4979' of github.com:jantman/gitpython_issue_301 +d82cacaaa7bbdc05b5a469f64807304c828f52b8 not-for-merge branch 'testcommit498' of github.com:jantman/gitpython_issue_301 +6bdb3a36ad45177343c22a40a258a8a3d4caf2bf not-for-merge branch 'testcommit4980' of github.com:jantman/gitpython_issue_301 +e88a90335164f81f77146852a6f6826bc39ca673 not-for-merge branch 'testcommit4981' of github.com:jantman/gitpython_issue_301 +fcc4b30a5cd6a021214ff077f050d497a628cace not-for-merge branch 'testcommit4982' of github.com:jantman/gitpython_issue_301 +1aee91c37e5c6ee5d459c59098195b9934d91d56 not-for-merge branch 'testcommit4983' of github.com:jantman/gitpython_issue_301 +91de3b74af2bbccd42fda1761321e74308daeb2d not-for-merge branch 'testcommit4984' of github.com:jantman/gitpython_issue_301 +c265f38a5a77c17cb6987d3cb391a549e5c470a1 not-for-merge branch 'testcommit4985' of github.com:jantman/gitpython_issue_301 +ba257d81a3e7c073ac07eceab83ce5e7360c0236 not-for-merge branch 'testcommit4986' of github.com:jantman/gitpython_issue_301 +7bacc8b4763735478b5924850182d2762956110f not-for-merge branch 'testcommit4987' of github.com:jantman/gitpython_issue_301 +403850a4dc94c3e5686817f02c6e5310930da393 not-for-merge branch 'testcommit4988' of github.com:jantman/gitpython_issue_301 +15675dfe8634132555b65115c507839e6f63630f not-for-merge branch 'testcommit4989' of github.com:jantman/gitpython_issue_301 +8ab258f6673859db350c50a183397e2e7813658a not-for-merge branch 'testcommit499' of github.com:jantman/gitpython_issue_301 +8f88e38717432f523424e6e26b53f91284514c77 not-for-merge branch 'testcommit4990' of github.com:jantman/gitpython_issue_301 +33e71cec8ab3feeb54ac6965f89b46d2e5b7fde6 not-for-merge branch 'testcommit4991' of github.com:jantman/gitpython_issue_301 +ac8323730e106c430c3d2f654cdefe985ccf5120 not-for-merge branch 'testcommit4992' of github.com:jantman/gitpython_issue_301 +d11cd1b1d61b266559a564f214beee53216dfeac not-for-merge branch 'testcommit4993' of github.com:jantman/gitpython_issue_301 +7f36afe04c62053ed4538287a15191a9835e7a6b not-for-merge branch 'testcommit4994' of github.com:jantman/gitpython_issue_301 +439080bc1fefd57c6f0482119c6cc50ad661039b not-for-merge branch 'testcommit4995' of github.com:jantman/gitpython_issue_301 +5ef621199ec49bd83a6e92785fb003e771c13fa3 not-for-merge branch 'testcommit4996' of github.com:jantman/gitpython_issue_301 +253ae37f21d634ce195ea9732fb8297589842343 not-for-merge branch 'testcommit4997' of github.com:jantman/gitpython_issue_301 +cad2b6270c8f1581eed475980ef507c1c13c56a4 not-for-merge branch 'testcommit4998' of github.com:jantman/gitpython_issue_301 +ffdc41e0afb01d52b3852b0e852eaa2b1714f4d0 not-for-merge branch 'testcommit4999' of github.com:jantman/gitpython_issue_301 +0af5eb0bf5e860a073289c639e38da341d34f3a1 not-for-merge branch 'testcommit5' of github.com:jantman/gitpython_issue_301 +1fb8e354a8f17b5560d571dbec3d2d04630e5db1 not-for-merge branch 'testcommit50' of github.com:jantman/gitpython_issue_301 +fd22aff054f025dc2d08c6a7007c82f3f693a8f2 not-for-merge branch 'testcommit500' of github.com:jantman/gitpython_issue_301 +04636ad640661ce6da5fe153c8ae6ca3813e6426 not-for-merge branch 'testcommit5000' of github.com:jantman/gitpython_issue_301 +3929eee257dd1ce763a485f6bd4196f1fcd8b4e7 not-for-merge branch 'testcommit501' of github.com:jantman/gitpython_issue_301 +0c7b386757f4bcee9015f155303a05bc6096649f not-for-merge branch 'testcommit502' of github.com:jantman/gitpython_issue_301 +cff890adce4a8093d07cd7b42460e9ef4df4eda9 not-for-merge branch 'testcommit503' of github.com:jantman/gitpython_issue_301 +a634d5bc948136bafe7fc03675c32d05bf146572 not-for-merge branch 'testcommit504' of github.com:jantman/gitpython_issue_301 +48a4c5c26662ed94020aeb235da3e6af7b22599f not-for-merge branch 'testcommit505' of github.com:jantman/gitpython_issue_301 +42296adaafec37ddb1c14e836d620df8d2572518 not-for-merge branch 'testcommit506' of github.com:jantman/gitpython_issue_301 +f5e40a173c9f079d03835876a643912452b4c018 not-for-merge branch 'testcommit507' of github.com:jantman/gitpython_issue_301 +b6ccf0b2f15b95166e2b7437bee335a9aa12c892 not-for-merge branch 'testcommit508' of github.com:jantman/gitpython_issue_301 +9ca0c55f8634e4a6819b9c0a8b10cea828fc5fa8 not-for-merge branch 'testcommit509' of github.com:jantman/gitpython_issue_301 +fc903beeec26eaabd0d28193e63129513bc9b1ef not-for-merge branch 'testcommit51' of github.com:jantman/gitpython_issue_301 +549bc6ad6187fccb869d0a6168e372d77b3c696e not-for-merge branch 'testcommit510' of github.com:jantman/gitpython_issue_301 +7dc4bf2f183fc345eccf61ca3e050f986eea0094 not-for-merge branch 'testcommit511' of github.com:jantman/gitpython_issue_301 +92dc359a7c15710db9c6307ed108cfd25b5800c2 not-for-merge branch 'testcommit512' of github.com:jantman/gitpython_issue_301 +608862086a7900b0fad50d0e45ad97f87678d931 not-for-merge branch 'testcommit513' of github.com:jantman/gitpython_issue_301 +da45b6f208df454874278564dd2853d1d090b9b4 not-for-merge branch 'testcommit514' of github.com:jantman/gitpython_issue_301 +efd4a8e69a5c96e76bec21183badc484df531d75 not-for-merge branch 'testcommit515' of github.com:jantman/gitpython_issue_301 +290ac4347c0620f9b1bdc13af9bec52c4b9bce92 not-for-merge branch 'testcommit516' of github.com:jantman/gitpython_issue_301 +a3e1468127ebf8d3f76a9be87bfb690a39e50d33 not-for-merge branch 'testcommit517' of github.com:jantman/gitpython_issue_301 +d24f5b78937f500b6fd700ff1a95da9abe80e1b2 not-for-merge branch 'testcommit518' of github.com:jantman/gitpython_issue_301 +4f68836e2cf25f0b7268e2456470f20f13f11ce0 not-for-merge branch 'testcommit519' of github.com:jantman/gitpython_issue_301 +c6c5525727411cc9d78a0c2f4eaa242a1eaff6a6 not-for-merge branch 'testcommit52' of github.com:jantman/gitpython_issue_301 +a16823103b345e75fd2b925d5c88998964301464 not-for-merge branch 'testcommit520' of github.com:jantman/gitpython_issue_301 +4e9bad0fbd35ec4ee5b0cb43b295d7f47a4e2fad not-for-merge branch 'testcommit521' of github.com:jantman/gitpython_issue_301 +1b8e4e40e281111fff8fa688dde16c9b21fccb79 not-for-merge branch 'testcommit522' of github.com:jantman/gitpython_issue_301 +faa559598c05e004bc8c14ce340f1f0943d65798 not-for-merge branch 'testcommit523' of github.com:jantman/gitpython_issue_301 +1a09317cb738b86360b10ebfc42bbdcba466836b not-for-merge branch 'testcommit524' of github.com:jantman/gitpython_issue_301 +ccbb2cae977d819f4ee64c428eb23e1aa3c98e03 not-for-merge branch 'testcommit525' of github.com:jantman/gitpython_issue_301 +4aeb01401bcc82f1c6e13ec41f8bcf1868de4985 not-for-merge branch 'testcommit526' of github.com:jantman/gitpython_issue_301 +232e5c35ba73a63ef3f323e0306a27081c05043e not-for-merge branch 'testcommit527' of github.com:jantman/gitpython_issue_301 +c113f691326df97ccb2a96c1e9e21495e26adf83 not-for-merge branch 'testcommit528' of github.com:jantman/gitpython_issue_301 +95815a91bba0b0150c2861018d415006b77ad3ab not-for-merge branch 'testcommit529' of github.com:jantman/gitpython_issue_301 +8c5f53ec252f99eab16c4dc16573ea86e2b000bc not-for-merge branch 'testcommit53' of github.com:jantman/gitpython_issue_301 +40b05a4150f165baf5556e2a1f017306c1da68fc not-for-merge branch 'testcommit530' of github.com:jantman/gitpython_issue_301 +842a153e392ac2d58d24d965610560d85f05ca88 not-for-merge branch 'testcommit531' of github.com:jantman/gitpython_issue_301 +98bf19f982d19ad49f93141c940a75ac931888b9 not-for-merge branch 'testcommit532' of github.com:jantman/gitpython_issue_301 +1b3ba5d70b3b3c8a8fd263903ab349715bbd083f not-for-merge branch 'testcommit533' of github.com:jantman/gitpython_issue_301 +2e4e1150cb18211efb7f7552e7c098c3753b4df3 not-for-merge branch 'testcommit534' of github.com:jantman/gitpython_issue_301 +109fa8326711aa79eae84794450757926f007318 not-for-merge branch 'testcommit535' of github.com:jantman/gitpython_issue_301 +83fe1411a6672c06019b22e8e50b792c2735812f not-for-merge branch 'testcommit536' of github.com:jantman/gitpython_issue_301 +da93f0e7fdc10602ef1d7fed03212b30fc6e25d3 not-for-merge branch 'testcommit537' of github.com:jantman/gitpython_issue_301 +b853d2d294410257a1984e3e89113b0e96e6e276 not-for-merge branch 'testcommit538' of github.com:jantman/gitpython_issue_301 +18144d3fdd17179a114bdbcff740c2aa2e72fb20 not-for-merge branch 'testcommit539' of github.com:jantman/gitpython_issue_301 +aeddcc2e051bcfe91963177f4c47dedea3d5659e not-for-merge branch 'testcommit54' of github.com:jantman/gitpython_issue_301 +d3d23bb86d17a6c2c1128df796a110f6ebdaea7c not-for-merge branch 'testcommit540' of github.com:jantman/gitpython_issue_301 +d051497d104640e63aed0227d1fe354506e14b7d not-for-merge branch 'testcommit541' of github.com:jantman/gitpython_issue_301 +0a54721efde832ec7f63fb6afd7afe82abd909ef not-for-merge branch 'testcommit542' of github.com:jantman/gitpython_issue_301 +c87152b239b6753efb165bf3457b81578790d561 not-for-merge branch 'testcommit543' of github.com:jantman/gitpython_issue_301 +7c51b7a83e795fdee8f3bd2b954d46787d7ed51a not-for-merge branch 'testcommit544' of github.com:jantman/gitpython_issue_301 +5ec95a8439bdf6cec8cbcdb3a9e19f899e6f669e not-for-merge branch 'testcommit545' of github.com:jantman/gitpython_issue_301 +40ddbd74f4d0247f923d28c459d0b007ed3cd116 not-for-merge branch 'testcommit546' of github.com:jantman/gitpython_issue_301 +5012509bc27d70ff08efbf290adeba9e5d799846 not-for-merge branch 'testcommit547' of github.com:jantman/gitpython_issue_301 +cb2f62728416f722c48a2d90345a92b394ac4131 not-for-merge branch 'testcommit548' of github.com:jantman/gitpython_issue_301 +ccf0eb3000490a6dab1bb461e49ce482104a9e26 not-for-merge branch 'testcommit549' of github.com:jantman/gitpython_issue_301 +4725bb980022f82f23029db5401951c067962d38 not-for-merge branch 'testcommit55' of github.com:jantman/gitpython_issue_301 +758ba44750649e5635935190e5a66ffdf6a6466f not-for-merge branch 'testcommit550' of github.com:jantman/gitpython_issue_301 +25e56c767e903f2d78ba010cc6ff92c6685d3276 not-for-merge branch 'testcommit551' of github.com:jantman/gitpython_issue_301 +250e57aeb90507b7077c4df6f703dfdadcf0eae3 not-for-merge branch 'testcommit552' of github.com:jantman/gitpython_issue_301 +24ce7c0bdb3fbe6d574c252ed90b17805f461550 not-for-merge branch 'testcommit553' of github.com:jantman/gitpython_issue_301 +52e70454ccc5d47d414348b1b356ebf5cf3757b2 not-for-merge branch 'testcommit554' of github.com:jantman/gitpython_issue_301 +060a2f2ab23ac4d65d4e8e23f5ca02e84b17ce99 not-for-merge branch 'testcommit555' of github.com:jantman/gitpython_issue_301 +623d550c93b4cd6b3f483ab69526a44616d5c675 not-for-merge branch 'testcommit556' of github.com:jantman/gitpython_issue_301 +0c73d52d2b28045f1bcc06a5ab9be45541b44b15 not-for-merge branch 'testcommit557' of github.com:jantman/gitpython_issue_301 +123daf9efaadb9f7a0bc5f2e22aa9800770ab217 not-for-merge branch 'testcommit558' of github.com:jantman/gitpython_issue_301 +c5c00a688df74021314e19844000093524330d03 not-for-merge branch 'testcommit559' of github.com:jantman/gitpython_issue_301 +a6769943f94459a85e67f6cfcaec1ac8bf5a455f not-for-merge branch 'testcommit56' of github.com:jantman/gitpython_issue_301 +a4d3c9a10b734479e5da1be86eff73a8efaf3b64 not-for-merge branch 'testcommit560' of github.com:jantman/gitpython_issue_301 +4e40e25f4f34d2d4dc7dc6ca154329a77119c23c not-for-merge branch 'testcommit561' of github.com:jantman/gitpython_issue_301 +f7074b88b054d426427da675bd5aa4ae2c7af74e not-for-merge branch 'testcommit562' of github.com:jantman/gitpython_issue_301 +21eec875be8bbdc0d6580e1e6d62a73c6a838694 not-for-merge branch 'testcommit563' of github.com:jantman/gitpython_issue_301 +2c8870d58f91ab55e0a1ded8af0303d841bceb60 not-for-merge branch 'testcommit564' of github.com:jantman/gitpython_issue_301 +c6828df5350f4683cc4060bf88906ee747460572 not-for-merge branch 'testcommit565' of github.com:jantman/gitpython_issue_301 +e1d3ca6b3e34875379dcde10598f2e474e11c213 not-for-merge branch 'testcommit566' of github.com:jantman/gitpython_issue_301 +1b44f6c01bc673ddf75aad6cf494f206944063f9 not-for-merge branch 'testcommit567' of github.com:jantman/gitpython_issue_301 +8019000a9c47371d46d738e07a012185676095f8 not-for-merge branch 'testcommit568' of github.com:jantman/gitpython_issue_301 +b75883f1ac14a15a19c846206fb8d02fa7e56c10 not-for-merge branch 'testcommit569' of github.com:jantman/gitpython_issue_301 +bd19a09754f2f3d4383422ae6ec6a6ad37437075 not-for-merge branch 'testcommit57' of github.com:jantman/gitpython_issue_301 +6c7dbe56d550cda42700a13c31a611b469931f3d not-for-merge branch 'testcommit570' of github.com:jantman/gitpython_issue_301 +47710b30158fe92980cb7bab9a603bc70502038e not-for-merge branch 'testcommit571' of github.com:jantman/gitpython_issue_301 +5de460892123d71d3b90b651c1c006ed545f72ea not-for-merge branch 'testcommit572' of github.com:jantman/gitpython_issue_301 +d04e1a23adc2591cef631222414e391734f162d2 not-for-merge branch 'testcommit573' of github.com:jantman/gitpython_issue_301 +c0fc4cf010f30d6c55875899129271883b804d7d not-for-merge branch 'testcommit574' of github.com:jantman/gitpython_issue_301 +6f7c42dad686367fa3cb4ea55f072e7f458d6c3f not-for-merge branch 'testcommit575' of github.com:jantman/gitpython_issue_301 +71c10a37c8331dbf8479d4cd6780f317f2567077 not-for-merge branch 'testcommit576' of github.com:jantman/gitpython_issue_301 +c27aa71279121c759585e8b6f19763feb134c25d not-for-merge branch 'testcommit577' of github.com:jantman/gitpython_issue_301 +dd1e95096c1ce19ca691de1bad5c551d05ee38ec not-for-merge branch 'testcommit578' of github.com:jantman/gitpython_issue_301 +c89a18e0ed67404d1128312f15e17338b0fdb6e5 not-for-merge branch 'testcommit579' of github.com:jantman/gitpython_issue_301 +951b8e3c1341b3a9c677409e3684bfe8ed71f816 not-for-merge branch 'testcommit58' of github.com:jantman/gitpython_issue_301 +5941df890fa59eac905a98cc06d17c812bb44a0c not-for-merge branch 'testcommit580' of github.com:jantman/gitpython_issue_301 +ad2c03d96c4952fab9d26241d8c24f3978130ee3 not-for-merge branch 'testcommit581' of github.com:jantman/gitpython_issue_301 +e4d7916d7aaef1dd5ad86b2f245fb5c4d709c1e1 not-for-merge branch 'testcommit582' of github.com:jantman/gitpython_issue_301 +95cf818ecdd5c1381169e5cd3c1b309693d24224 not-for-merge branch 'testcommit583' of github.com:jantman/gitpython_issue_301 +4deaad8fcb2504357b8239e8c36171255f4ddf13 not-for-merge branch 'testcommit584' of github.com:jantman/gitpython_issue_301 +2bf5962f48db8f1ac36aea8fc94eaf5134002ce9 not-for-merge branch 'testcommit585' of github.com:jantman/gitpython_issue_301 +567e6acedaf03e56c22e0fb15081fc9a86cff0c0 not-for-merge branch 'testcommit586' of github.com:jantman/gitpython_issue_301 +617f2fde588298dd568e858df3bda07d33889eee not-for-merge branch 'testcommit587' of github.com:jantman/gitpython_issue_301 +beab9210ce11a58172a1a6bd306cd31b95f9392a not-for-merge branch 'testcommit588' of github.com:jantman/gitpython_issue_301 +17cd07f2c17cebe35a490f38cf2cbc464099e9a1 not-for-merge branch 'testcommit589' of github.com:jantman/gitpython_issue_301 +3939908522f2ce7f5c6f295feb9160abbdaac2f7 not-for-merge branch 'testcommit59' of github.com:jantman/gitpython_issue_301 +61cc799b25a43c468f70bec3453b521eb013fc42 not-for-merge branch 'testcommit590' of github.com:jantman/gitpython_issue_301 +234800550ccbf53ebf72295e618cfd712b6e9186 not-for-merge branch 'testcommit591' of github.com:jantman/gitpython_issue_301 +46e8f8ed3c390fd78ab07cc9122c666c9f216eeb not-for-merge branch 'testcommit592' of github.com:jantman/gitpython_issue_301 +ed359344f0bde25ec903e0f15b6e9acb4ec3f676 not-for-merge branch 'testcommit593' of github.com:jantman/gitpython_issue_301 +c9ff6b3cce45b56b71510fa3e8ccd3ca88105739 not-for-merge branch 'testcommit594' of github.com:jantman/gitpython_issue_301 +bf57554e2e5f19761452bf25dc921cfed6adc3f5 not-for-merge branch 'testcommit595' of github.com:jantman/gitpython_issue_301 +d3aa5ae79085a2074b65e8fa90a5cc3dcea7453b not-for-merge branch 'testcommit596' of github.com:jantman/gitpython_issue_301 +7ca1dbca8bc643ed05ce31c226e900b8cc6df07f not-for-merge branch 'testcommit597' of github.com:jantman/gitpython_issue_301 +53ec767fa2b8d6dff7456dae62199923463b12b5 not-for-merge branch 'testcommit598' of github.com:jantman/gitpython_issue_301 +3b2a0ae920980ba80a9e0d6cb5d8b64ca566f7dc not-for-merge branch 'testcommit599' of github.com:jantman/gitpython_issue_301 +d88d5a5641ba9aaa29fa6f68a7e79840c3cbcc21 not-for-merge branch 'testcommit6' of github.com:jantman/gitpython_issue_301 +be014996a807dbaef480e269d6002e2ec00a9cd5 not-for-merge branch 'testcommit60' of github.com:jantman/gitpython_issue_301 +3dc27b539fa5f61430263ef3a5f97f5969f91f55 not-for-merge branch 'testcommit600' of github.com:jantman/gitpython_issue_301 +1fa2c894edd2b43a808f84c07aad6fa39840d986 not-for-merge branch 'testcommit601' of github.com:jantman/gitpython_issue_301 +2749624397bedbda9211c568a506438a2f73193b not-for-merge branch 'testcommit602' of github.com:jantman/gitpython_issue_301 +7f6608453db4220a304a522a37d9d4d08cad9319 not-for-merge branch 'testcommit603' of github.com:jantman/gitpython_issue_301 +60ee9dee153d6bc368fe4026bb1feb4cad1a083d not-for-merge branch 'testcommit604' of github.com:jantman/gitpython_issue_301 +341746654511f70dcb4198e55fb05b46de0b7739 not-for-merge branch 'testcommit605' of github.com:jantman/gitpython_issue_301 +4c9f8b40a4fe348313a9043635dec6e582d91f8d not-for-merge branch 'testcommit606' of github.com:jantman/gitpython_issue_301 +5e32b8056cb3c43bcc22eab931d2fd5dd25ba77f not-for-merge branch 'testcommit607' of github.com:jantman/gitpython_issue_301 +adf7c5c59ee4707f4e07592515a5efc81235a993 not-for-merge branch 'testcommit608' of github.com:jantman/gitpython_issue_301 +e7abbb6422f8a77c923b831a905d7729c0e475ef not-for-merge branch 'testcommit609' of github.com:jantman/gitpython_issue_301 +d35c8c7f4a7dd024fc4913b71e7b5b4a68cd23d3 not-for-merge branch 'testcommit61' of github.com:jantman/gitpython_issue_301 +4681d67a662852099961aecb8a56048c7485a111 not-for-merge branch 'testcommit610' of github.com:jantman/gitpython_issue_301 +31cd3cf16d09a0473b01dfabbb1982455509dc6d not-for-merge branch 'testcommit611' of github.com:jantman/gitpython_issue_301 +09d035efaebd1f36048f809a0d3e1541db0c191b not-for-merge branch 'testcommit612' of github.com:jantman/gitpython_issue_301 +cf2f3b18354a4da3c088a0be5fb150c94fd990ea not-for-merge branch 'testcommit613' of github.com:jantman/gitpython_issue_301 +b2003fac21f253ae879ed5561901ee883244feee not-for-merge branch 'testcommit614' of github.com:jantman/gitpython_issue_301 +21483f4244fec57ce9a5561efa23a34711ccfd10 not-for-merge branch 'testcommit615' of github.com:jantman/gitpython_issue_301 +e5c61f4a40f8ce4175364d67b7454007fe40f503 not-for-merge branch 'testcommit616' of github.com:jantman/gitpython_issue_301 +8f9964dfc0eb87e5bfc0c37e1ba64ed647c7adf0 not-for-merge branch 'testcommit617' of github.com:jantman/gitpython_issue_301 +0704a6e6787b35f1642f4d03f4f92ea963e6ae62 not-for-merge branch 'testcommit618' of github.com:jantman/gitpython_issue_301 +66d3d0db7781fe3a6d639edccac31aed08b18d18 not-for-merge branch 'testcommit619' of github.com:jantman/gitpython_issue_301 +18c4b2f8087520dea0c5a22729a6f7646699d75a not-for-merge branch 'testcommit62' of github.com:jantman/gitpython_issue_301 +ed7370db8f1003834aeccc722323e869937980ac not-for-merge branch 'testcommit620' of github.com:jantman/gitpython_issue_301 +eb2b560fa659f4f9a3f46460f7e0b8ca71576540 not-for-merge branch 'testcommit621' of github.com:jantman/gitpython_issue_301 +2317a512aaf6c8945c9dea3f88ca2d6ffb47aec4 not-for-merge branch 'testcommit622' of github.com:jantman/gitpython_issue_301 +8f1bece9607d3b94e96a1bc317551a89624823a4 not-for-merge branch 'testcommit623' of github.com:jantman/gitpython_issue_301 +23c5512563c9ea51e56885e7df9b3db6dd6e3f93 not-for-merge branch 'testcommit624' of github.com:jantman/gitpython_issue_301 +3f4ec629251a4493e59d809235beaf35a58609fb not-for-merge branch 'testcommit625' of github.com:jantman/gitpython_issue_301 +76a29790150998b64c36cc8a06d8c6a82239ec3f not-for-merge branch 'testcommit626' of github.com:jantman/gitpython_issue_301 +6ba7be2aa94a15e9b0b6e89ccf83d2e38a6b4265 not-for-merge branch 'testcommit627' of github.com:jantman/gitpython_issue_301 +2950b40b01bca45e525806a19b01c51e433ca61f not-for-merge branch 'testcommit628' of github.com:jantman/gitpython_issue_301 +198076834d0423635272d993985e49c8328aab29 not-for-merge branch 'testcommit629' of github.com:jantman/gitpython_issue_301 +da8138f8b88d4bf592b773d9169ff4ffc6e19cb2 not-for-merge branch 'testcommit63' of github.com:jantman/gitpython_issue_301 +73afcc153425d72a4c5ca3068b3e9ad3f2fd7b3c not-for-merge branch 'testcommit630' of github.com:jantman/gitpython_issue_301 +745827af54538ba1786b5d96872e975d1eeea5d7 not-for-merge branch 'testcommit631' of github.com:jantman/gitpython_issue_301 +e760bb7a85cbeac419da6e8fd1d5fecbd72bfbd7 not-for-merge branch 'testcommit632' of github.com:jantman/gitpython_issue_301 +12140acfea48e1288e9b6b07b1e06aec54006a4c not-for-merge branch 'testcommit633' of github.com:jantman/gitpython_issue_301 +df63decdbf3d197f22c5a6d4a2eabd8343861d60 not-for-merge branch 'testcommit634' of github.com:jantman/gitpython_issue_301 +11161362a5a6f3a4b5c7b5850c1ebcb8a8b844a0 not-for-merge branch 'testcommit635' of github.com:jantman/gitpython_issue_301 +51b76aae8bdaff7b013526ed245a2455ae5afdd7 not-for-merge branch 'testcommit636' of github.com:jantman/gitpython_issue_301 +8f6e916b4aebd572664d344b48424f514a16fde1 not-for-merge branch 'testcommit637' of github.com:jantman/gitpython_issue_301 +845122213c72d4ac4ca50363910c77081adccae5 not-for-merge branch 'testcommit638' of github.com:jantman/gitpython_issue_301 +8522f13257f677aebff24918a12e35a78e6a8de6 not-for-merge branch 'testcommit639' of github.com:jantman/gitpython_issue_301 +627cb75498069aa04b046935f6ce4b4a230e861d not-for-merge branch 'testcommit64' of github.com:jantman/gitpython_issue_301 +fbed06c60a496fe8167565e36f20f95c11b4da5a not-for-merge branch 'testcommit640' of github.com:jantman/gitpython_issue_301 +a64a21adab51312f4536d840401aa5a34c7cb432 not-for-merge branch 'testcommit641' of github.com:jantman/gitpython_issue_301 +2f48a0befc146eb65271b56d119db00feea56091 not-for-merge branch 'testcommit642' of github.com:jantman/gitpython_issue_301 +43f2d6f1fffbd20bbee16f5a3136efa0d060006c not-for-merge branch 'testcommit643' of github.com:jantman/gitpython_issue_301 +3cb0cbed1c1b12d7ffb0bd3a96f6f55872c831c3 not-for-merge branch 'testcommit644' of github.com:jantman/gitpython_issue_301 +72d15075581fb8ff95b0a21c223d9cae0b20e6ac not-for-merge branch 'testcommit645' of github.com:jantman/gitpython_issue_301 +ea8cb8da43561a36e162dbf0364f94b668825001 not-for-merge branch 'testcommit646' of github.com:jantman/gitpython_issue_301 +f28edddeaac007fdaa892aeceeb3c9f92a8b9859 not-for-merge branch 'testcommit647' of github.com:jantman/gitpython_issue_301 +1d7e581deed1f8ded19f71ebd7a81f7188483ebc not-for-merge branch 'testcommit648' of github.com:jantman/gitpython_issue_301 +5f421574215196b83f3aef58cce5325b1f88a23f not-for-merge branch 'testcommit649' of github.com:jantman/gitpython_issue_301 +76be05ba476e01d87dff2c3b3bbb22048e88abda not-for-merge branch 'testcommit65' of github.com:jantman/gitpython_issue_301 +e78d00a7f2c723c5115d648de340e41bf81bc5a8 not-for-merge branch 'testcommit650' of github.com:jantman/gitpython_issue_301 +1bd51dad748edd6449f49340612cfea775e07b36 not-for-merge branch 'testcommit651' of github.com:jantman/gitpython_issue_301 +8b9980a10f5f645c2b66e0638d3ddf4573e9ff04 not-for-merge branch 'testcommit652' of github.com:jantman/gitpython_issue_301 +88c77092a2742f4d94c02459b67c25cf39002d33 not-for-merge branch 'testcommit653' of github.com:jantman/gitpython_issue_301 +069f6767a2a2f2813b251a32d453d9f51c49c069 not-for-merge branch 'testcommit654' of github.com:jantman/gitpython_issue_301 +78be5eb31dee9f005f6196dc41a47d3cabd36cbd not-for-merge branch 'testcommit655' of github.com:jantman/gitpython_issue_301 +1ca94cac14eb3fcaa4c5aa5de00f6177f28f380a not-for-merge branch 'testcommit656' of github.com:jantman/gitpython_issue_301 +2c5a049a6b315780e9eb8cdb66742ee2f7e94ef3 not-for-merge branch 'testcommit657' of github.com:jantman/gitpython_issue_301 +df4b83ae3ddad319885558ade8153dfcca16b654 not-for-merge branch 'testcommit658' of github.com:jantman/gitpython_issue_301 +7aea97890fc97816f8ef9d234f0550ac294039e8 not-for-merge branch 'testcommit659' of github.com:jantman/gitpython_issue_301 +5c277d39a90efc5b4afaff12a1a57ef8e89b5d78 not-for-merge branch 'testcommit66' of github.com:jantman/gitpython_issue_301 +884e1c2130e34f53823d984adc12487b3f4888ee not-for-merge branch 'testcommit660' of github.com:jantman/gitpython_issue_301 +a9ee4cdd0dcd526dea8a1d53784e906b54509c84 not-for-merge branch 'testcommit661' of github.com:jantman/gitpython_issue_301 +b993dea4c36e6218fedb96991565d36b7214571d not-for-merge branch 'testcommit662' of github.com:jantman/gitpython_issue_301 +cac00eabd9979648c70ecf7971b7a9bdadaa1fbd not-for-merge branch 'testcommit663' of github.com:jantman/gitpython_issue_301 +bfe55c6d8410a108d67788d755f31ddfe08c0d73 not-for-merge branch 'testcommit664' of github.com:jantman/gitpython_issue_301 +f99661586eca2d8cf805b56e0be9650995250139 not-for-merge branch 'testcommit665' of github.com:jantman/gitpython_issue_301 +ea7e7f8fcea34f7f57cebefe192d1ae5c6960bc7 not-for-merge branch 'testcommit666' of github.com:jantman/gitpython_issue_301 +f0ef48f1a3723343854d54938be3404cdcd37a2b not-for-merge branch 'testcommit667' of github.com:jantman/gitpython_issue_301 +74fe8c675f43584cdb506926e6530eb58884cc14 not-for-merge branch 'testcommit668' of github.com:jantman/gitpython_issue_301 +ac574023ec5831f15f164e7c7815f21dd7a27358 not-for-merge branch 'testcommit669' of github.com:jantman/gitpython_issue_301 +8fb42784c9e8dbc0b2cdd94e6398e26a8f6c6f36 not-for-merge branch 'testcommit67' of github.com:jantman/gitpython_issue_301 +ad1501d79d27e570d900caaaf0709d61ae90b1ec not-for-merge branch 'testcommit670' of github.com:jantman/gitpython_issue_301 +326bd1cb5a9a166884d019ef04ffc7bed1a87a6b not-for-merge branch 'testcommit671' of github.com:jantman/gitpython_issue_301 +78f0552f7b777372751670642cd25ae9de91ee89 not-for-merge branch 'testcommit672' of github.com:jantman/gitpython_issue_301 +cfcd7c668f194678141a58ae436dfd8dc9f2b256 not-for-merge branch 'testcommit673' of github.com:jantman/gitpython_issue_301 +e6c8ff319dcdaf62f3d8018d3a6cb4cc4725035b not-for-merge branch 'testcommit674' of github.com:jantman/gitpython_issue_301 +c16b0d9209c8ca377e779015cbe9586dc5320e41 not-for-merge branch 'testcommit675' of github.com:jantman/gitpython_issue_301 +98fc552e8e2903b6c6d653d5eec5a0e574341448 not-for-merge branch 'testcommit676' of github.com:jantman/gitpython_issue_301 +16338f5805d7aed669526daab276f2e6e8c223fb not-for-merge branch 'testcommit677' of github.com:jantman/gitpython_issue_301 +dbb5253584ed1e15d2c66c0678543cce677d0ec3 not-for-merge branch 'testcommit678' of github.com:jantman/gitpython_issue_301 +3e63c8410712516148820233d33213bcea8e0ddb not-for-merge branch 'testcommit679' of github.com:jantman/gitpython_issue_301 +31f5481a21aafa64fbdcbecd340b68dc71d1ac74 not-for-merge branch 'testcommit68' of github.com:jantman/gitpython_issue_301 +a4713b2b5df4ba141e8c47c76a17bd581efe5373 not-for-merge branch 'testcommit680' of github.com:jantman/gitpython_issue_301 +6d15215387c6414ce441b897d8259f10cbd697a6 not-for-merge branch 'testcommit681' of github.com:jantman/gitpython_issue_301 +dad0e5c7f4d03a5379722a1778f23814ea8c081a not-for-merge branch 'testcommit682' of github.com:jantman/gitpython_issue_301 +05849c2a5baf4c5feae6783e5f01970ead6848ce not-for-merge branch 'testcommit683' of github.com:jantman/gitpython_issue_301 +c077a04458b1866ddde6145ffed6134ab9c29835 not-for-merge branch 'testcommit684' of github.com:jantman/gitpython_issue_301 +bafc54e5b9f1e76400f36997cedf3b1821128f71 not-for-merge branch 'testcommit685' of github.com:jantman/gitpython_issue_301 +1bd29c18d689fd51b67f0fd05972b59eb20e365c not-for-merge branch 'testcommit686' of github.com:jantman/gitpython_issue_301 +072573094d2a6c680d3a30b413a2d0efb4642b5a not-for-merge branch 'testcommit687' of github.com:jantman/gitpython_issue_301 +3e96284863d4dbf5f3c8b7131a094421fc51401d not-for-merge branch 'testcommit688' of github.com:jantman/gitpython_issue_301 +eac126d52b81365b66affd7fc9a34bbf45999113 not-for-merge branch 'testcommit689' of github.com:jantman/gitpython_issue_301 +51e19904d1cd3626b601b476c131ceb94d50fb4f not-for-merge branch 'testcommit69' of github.com:jantman/gitpython_issue_301 +96106803bb7bd6871975333d466e9e0dbc7c3045 not-for-merge branch 'testcommit690' of github.com:jantman/gitpython_issue_301 +8853692d533f739dbb55eb84246808e49f9169f1 not-for-merge branch 'testcommit691' of github.com:jantman/gitpython_issue_301 +e1190f7fdf6bb90ee5fe5a22ffcb2401efc45384 not-for-merge branch 'testcommit692' of github.com:jantman/gitpython_issue_301 +16b364efd801bd7185c61152e568c2227debb59d not-for-merge branch 'testcommit693' of github.com:jantman/gitpython_issue_301 +82fb07032592eb5e733db9d8460b990b0827873c not-for-merge branch 'testcommit694' of github.com:jantman/gitpython_issue_301 +04bbdc81ac25a5c6f3cf72ec772a15623a44b079 not-for-merge branch 'testcommit695' of github.com:jantman/gitpython_issue_301 +1c05bbbcf7571ec72897b1b4c023563c5b5e7e9a not-for-merge branch 'testcommit696' of github.com:jantman/gitpython_issue_301 +a7d383f01a4f0d1e0db8a72b30a4e09ca6eeb1ff not-for-merge branch 'testcommit697' of github.com:jantman/gitpython_issue_301 +f7c40dea2fa82c4fd7b1828886ad483c39537035 not-for-merge branch 'testcommit698' of github.com:jantman/gitpython_issue_301 +cdeb9507884b51bd3d2a1e62233bf5646ed7955e not-for-merge branch 'testcommit699' of github.com:jantman/gitpython_issue_301 +7183b4adb38d53d300d2fc415ff60b3aaf551a1a not-for-merge branch 'testcommit7' of github.com:jantman/gitpython_issue_301 +73bc7a9757a4487556e16aa997905dcf19fc3a6f not-for-merge branch 'testcommit70' of github.com:jantman/gitpython_issue_301 +1899686e3007b533f5d4d6a8c4dff48e17f7f0f3 not-for-merge branch 'testcommit700' of github.com:jantman/gitpython_issue_301 +e192639756e885dd519f421f24c9c90b3b9ac0bb not-for-merge branch 'testcommit701' of github.com:jantman/gitpython_issue_301 +9fa971b4a7280068b0bf6e83d5358f6a055cfb02 not-for-merge branch 'testcommit702' of github.com:jantman/gitpython_issue_301 +0ad2a758f289227ecbbe7d600c866a2f2e8a62ef not-for-merge branch 'testcommit703' of github.com:jantman/gitpython_issue_301 +c15718e655ef80b75ebd7f79a5a2b3f2a46824f6 not-for-merge branch 'testcommit704' of github.com:jantman/gitpython_issue_301 +b061bf5f0866a35a97230b5e33ed255cd07d2555 not-for-merge branch 'testcommit705' of github.com:jantman/gitpython_issue_301 +89a7ae7d960b83c8368eb16866ddd50208f2759a not-for-merge branch 'testcommit706' of github.com:jantman/gitpython_issue_301 +430da8812bf3b75970bfaa145a88d262a610476f not-for-merge branch 'testcommit707' of github.com:jantman/gitpython_issue_301 +c5e9864885520d4fd30d9bb2fb3230a72e5ab47a not-for-merge branch 'testcommit708' of github.com:jantman/gitpython_issue_301 +5ccb0ca0351a099e5aa85d0bbfffc5fb72f90b8c not-for-merge branch 'testcommit709' of github.com:jantman/gitpython_issue_301 +a887655df93951efdd3c087f655700eccaffa878 not-for-merge branch 'testcommit71' of github.com:jantman/gitpython_issue_301 +2fc32162cae9ba6984771d6ca640f5ad212d217e not-for-merge branch 'testcommit710' of github.com:jantman/gitpython_issue_301 +7ed10d2777cd37d93995314415b1f0e7a79bc2a6 not-for-merge branch 'testcommit711' of github.com:jantman/gitpython_issue_301 +cac7985c11aca6b76b609f3c5f46301248f69f3d not-for-merge branch 'testcommit712' of github.com:jantman/gitpython_issue_301 +ff775531dd249139228634be0fc50d235646dbe1 not-for-merge branch 'testcommit713' of github.com:jantman/gitpython_issue_301 +46fb240f08a0ebd80838621b919cce9869ba7ed8 not-for-merge branch 'testcommit714' of github.com:jantman/gitpython_issue_301 +c6045e3a04d0fecfb0ec370cbff08e42a2e52019 not-for-merge branch 'testcommit715' of github.com:jantman/gitpython_issue_301 +1fc76560fb2ee848a04e651d7bd6177c78f55395 not-for-merge branch 'testcommit716' of github.com:jantman/gitpython_issue_301 +6ec0bf73c3cbe10ed01b533e373b4939abacfee4 not-for-merge branch 'testcommit717' of github.com:jantman/gitpython_issue_301 +7457e8d1710d76639bbd4924d8977769aacc715d not-for-merge branch 'testcommit718' of github.com:jantman/gitpython_issue_301 +5626b0c7ac4c2406cc5cd8558baa4d43e505f881 not-for-merge branch 'testcommit719' of github.com:jantman/gitpython_issue_301 +9581970f260c3beb3cf2a218ddacc19bd9c0390f not-for-merge branch 'testcommit72' of github.com:jantman/gitpython_issue_301 +8896e8b56495bb6ed1bb8b0bbd21e57c55594ff1 not-for-merge branch 'testcommit720' of github.com:jantman/gitpython_issue_301 +0e7a84a5fb26a272c2155246949d24bcb9868b3d not-for-merge branch 'testcommit721' of github.com:jantman/gitpython_issue_301 +e338b95228b8195f4233406ddd2bc1cd3e4e1afa not-for-merge branch 'testcommit722' of github.com:jantman/gitpython_issue_301 +c0cdb916ead450e7736760fee86c92017eb70cf5 not-for-merge branch 'testcommit723' of github.com:jantman/gitpython_issue_301 +f74e172e0b48b4cc541abae153c3b0f81d11255e not-for-merge branch 'testcommit724' of github.com:jantman/gitpython_issue_301 +81f9cb544c58c521ef48822ebe4423268ebd3206 not-for-merge branch 'testcommit725' of github.com:jantman/gitpython_issue_301 +e15d7403a1a8a21c5b0775911a34c699f016ea52 not-for-merge branch 'testcommit726' of github.com:jantman/gitpython_issue_301 +454255b72d236615c44c8559784615ce5424c812 not-for-merge branch 'testcommit727' of github.com:jantman/gitpython_issue_301 +dac1421221409c0a47492c70a26d8e3d0f75c7e7 not-for-merge branch 'testcommit728' of github.com:jantman/gitpython_issue_301 +877b64fe21a916a7606e8d1276ccc8e2f69b6bde not-for-merge branch 'testcommit729' of github.com:jantman/gitpython_issue_301 +b8b1f22a0d63663b231d5adcf4e02def22e3719a not-for-merge branch 'testcommit73' of github.com:jantman/gitpython_issue_301 +2a1ef0e1957d32330af5115dea9b2266c556da69 not-for-merge branch 'testcommit730' of github.com:jantman/gitpython_issue_301 +3f02d23fb10197ce8dda09f759b79df5e4db3066 not-for-merge branch 'testcommit731' of github.com:jantman/gitpython_issue_301 +e190b285fa5852979953d17a8d410edfa494cc95 not-for-merge branch 'testcommit732' of github.com:jantman/gitpython_issue_301 +8ea77f78ebc4aa91df342ca471b51483a2809b0f not-for-merge branch 'testcommit733' of github.com:jantman/gitpython_issue_301 +d4ea610e186420d3b11b04d908881e30db54aa6e not-for-merge branch 'testcommit734' of github.com:jantman/gitpython_issue_301 +b1e9e6fd118ab60888da33cd86691a039bba3505 not-for-merge branch 'testcommit735' of github.com:jantman/gitpython_issue_301 +987400bab6475050e037229dc28567025ed41ea7 not-for-merge branch 'testcommit736' of github.com:jantman/gitpython_issue_301 +92da208017666e4fb16786d685693783840a2dc8 not-for-merge branch 'testcommit737' of github.com:jantman/gitpython_issue_301 +6a41b5aceaa643f771acf64f1d33e961226bae58 not-for-merge branch 'testcommit738' of github.com:jantman/gitpython_issue_301 +b394bc10d2b7f259aa33d8d8c052c9baa774e613 not-for-merge branch 'testcommit739' of github.com:jantman/gitpython_issue_301 +ce9e8f662287854b9a7191f230500acbc4cf411f not-for-merge branch 'testcommit74' of github.com:jantman/gitpython_issue_301 +89f34de2e420d6a4f65f19dd7c4cf525fba8a07e not-for-merge branch 'testcommit740' of github.com:jantman/gitpython_issue_301 +1850e93bafbe7379151bd180722d694a00d29998 not-for-merge branch 'testcommit741' of github.com:jantman/gitpython_issue_301 +19a5ca727c5e984c79cf36d3592bc143f06014b2 not-for-merge branch 'testcommit742' of github.com:jantman/gitpython_issue_301 +0c9210cea676be08d70dcfd712ba77f103ccf236 not-for-merge branch 'testcommit743' of github.com:jantman/gitpython_issue_301 +886d51b78354d463b2038bc71d9a3f0f973d7d5d not-for-merge branch 'testcommit744' of github.com:jantman/gitpython_issue_301 +59f956bf63b56eeaf4597b71893922967b28ed77 not-for-merge branch 'testcommit745' of github.com:jantman/gitpython_issue_301 +8ba24dee716331408b522a6363bba35e2e584491 not-for-merge branch 'testcommit746' of github.com:jantman/gitpython_issue_301 +26cdee6d11218df8cd489d3fe78a3320a705b3cf not-for-merge branch 'testcommit747' of github.com:jantman/gitpython_issue_301 +bdc94910d8bf361169c940505df3f38d03546efd not-for-merge branch 'testcommit748' of github.com:jantman/gitpython_issue_301 +3ed09f579117f7871ff72d8a618b7ae54e2da511 not-for-merge branch 'testcommit749' of github.com:jantman/gitpython_issue_301 +1f099be01f56caa337d1424e8f7c724ab14efcea not-for-merge branch 'testcommit75' of github.com:jantman/gitpython_issue_301 +5cd06ba8a8eb085ae5ebb6cc2022f2c27ffcc451 not-for-merge branch 'testcommit750' of github.com:jantman/gitpython_issue_301 +f4845edc84bd0e6e5fc51dde1e1826abf2b37d39 not-for-merge branch 'testcommit751' of github.com:jantman/gitpython_issue_301 +4158a930e8ef5043f7469e54aefab0b4cb1be11d not-for-merge branch 'testcommit752' of github.com:jantman/gitpython_issue_301 +793c1fb7ada7ab9d1a6f7757484d96e0877c8e73 not-for-merge branch 'testcommit753' of github.com:jantman/gitpython_issue_301 +31d307ab37d6d1a85f236c74d1abb563c4846114 not-for-merge branch 'testcommit754' of github.com:jantman/gitpython_issue_301 +dd8e37e681a66199a3fdba9895b044f6fe9c752c not-for-merge branch 'testcommit755' of github.com:jantman/gitpython_issue_301 +7e899a31ebe3c9e5c8a94c4576ae9086e695c5e2 not-for-merge branch 'testcommit756' of github.com:jantman/gitpython_issue_301 +a517467124458d1b873cf3ce4d81651c66fa8467 not-for-merge branch 'testcommit757' of github.com:jantman/gitpython_issue_301 +7480231aced2a51b29d90194208301384bc927a2 not-for-merge branch 'testcommit758' of github.com:jantman/gitpython_issue_301 +d642e1a83702107fd1d53b3e31d61e259f782b9d not-for-merge branch 'testcommit759' of github.com:jantman/gitpython_issue_301 +a96ae9402cd6e07d6aed4181b1d1b196d963f4a5 not-for-merge branch 'testcommit76' of github.com:jantman/gitpython_issue_301 +166979d272fb143b2106005e44d1325937d7e48e not-for-merge branch 'testcommit760' of github.com:jantman/gitpython_issue_301 +57a2c3d640be5e40cbf99578f232e4c7bb41d7cb not-for-merge branch 'testcommit761' of github.com:jantman/gitpython_issue_301 +a19600c5700d8f804e23188ce43f557ff63032d2 not-for-merge branch 'testcommit762' of github.com:jantman/gitpython_issue_301 +2a8e7cb5947065a0a55870e91ff758ce5bdbe2c7 not-for-merge branch 'testcommit763' of github.com:jantman/gitpython_issue_301 +9fe59bb8b02a2aa0b8fe1079eb638685c90c5c74 not-for-merge branch 'testcommit764' of github.com:jantman/gitpython_issue_301 +bcad73ce970f39347ebd7943192da4714d0c1ff3 not-for-merge branch 'testcommit765' of github.com:jantman/gitpython_issue_301 +6b265e1b81e908258b386931ad1e8e81f8d45e4e not-for-merge branch 'testcommit766' of github.com:jantman/gitpython_issue_301 +c7a07cb6a4dd4c6f049b9245bc3b919c5490d923 not-for-merge branch 'testcommit767' of github.com:jantman/gitpython_issue_301 +4434db27b53b14fbf959f9e1f02fdcd36fe31a14 not-for-merge branch 'testcommit768' of github.com:jantman/gitpython_issue_301 +6b2a85d383b56f3316093d12d9906a0f6247573b not-for-merge branch 'testcommit769' of github.com:jantman/gitpython_issue_301 +c062acc5601fa599b463d642d07317e48adbfab1 not-for-merge branch 'testcommit77' of github.com:jantman/gitpython_issue_301 +f99ccbf211c5b2f2f16426a62f1bd9dbea379cbe not-for-merge branch 'testcommit770' of github.com:jantman/gitpython_issue_301 +cd67820d2f9d38394193d893a9c82096331bcb7f not-for-merge branch 'testcommit771' of github.com:jantman/gitpython_issue_301 +c91ff851021f50244909e09346fc94221e01c323 not-for-merge branch 'testcommit772' of github.com:jantman/gitpython_issue_301 +eb99193107afabab6575e95e562c1912476d9630 not-for-merge branch 'testcommit773' of github.com:jantman/gitpython_issue_301 +b748524e74a350954eecd5acd2bcd9c124b59259 not-for-merge branch 'testcommit774' of github.com:jantman/gitpython_issue_301 +e67af751060ca25134c041876c72d48e683c3b48 not-for-merge branch 'testcommit775' of github.com:jantman/gitpython_issue_301 +7dc8c9b97ed3742c788d18313c89f200e886e41f not-for-merge branch 'testcommit776' of github.com:jantman/gitpython_issue_301 +3956f65a7571d7c2f5d1e3cf29661be5ac96af07 not-for-merge branch 'testcommit777' of github.com:jantman/gitpython_issue_301 +238f4b8f9490c19675aa8f1b6ea77b880c417399 not-for-merge branch 'testcommit778' of github.com:jantman/gitpython_issue_301 +87f45209d9940b028fd878c82412404782319955 not-for-merge branch 'testcommit779' of github.com:jantman/gitpython_issue_301 +ce18d422ff680722062ea828991c46d082c2536b not-for-merge branch 'testcommit78' of github.com:jantman/gitpython_issue_301 +daec64ad43ee1cd043480cf84abfbf5abde21503 not-for-merge branch 'testcommit780' of github.com:jantman/gitpython_issue_301 +71d94edd149a1669af2f42ef57ff1c4be554a848 not-for-merge branch 'testcommit781' of github.com:jantman/gitpython_issue_301 +77af70977625b000241f3cc70b3e04632b439e0b not-for-merge branch 'testcommit782' of github.com:jantman/gitpython_issue_301 +2044acd8aaf317b212f0647ec66c396614c86048 not-for-merge branch 'testcommit783' of github.com:jantman/gitpython_issue_301 +355c7a6bb5f38fd4de427f4af5f27bd169177384 not-for-merge branch 'testcommit784' of github.com:jantman/gitpython_issue_301 +8484dc4c34524cad0c0a015ad024a739dc94d59d not-for-merge branch 'testcommit785' of github.com:jantman/gitpython_issue_301 +ac37a36346041a279f2c6a8905d7aea552d6469d not-for-merge branch 'testcommit786' of github.com:jantman/gitpython_issue_301 +bc81c331e7c0f8ad60dde277ebefd982fe67aec6 not-for-merge branch 'testcommit787' of github.com:jantman/gitpython_issue_301 +6f74eb3284e47b22a7ffb9aa996859f49b423cb3 not-for-merge branch 'testcommit788' of github.com:jantman/gitpython_issue_301 +8e89376be1e0e2fa71ab9330b6e4bbe88663b630 not-for-merge branch 'testcommit789' of github.com:jantman/gitpython_issue_301 +547d3b7654bb21c6586f818294e97a6865af7092 not-for-merge branch 'testcommit79' of github.com:jantman/gitpython_issue_301 +1f61ac5478750f5c4cb97d51a4f7379c988466a1 not-for-merge branch 'testcommit790' of github.com:jantman/gitpython_issue_301 +7522207812d15b512013dd48fe8979cbf4859441 not-for-merge branch 'testcommit791' of github.com:jantman/gitpython_issue_301 +563959a9a8afde03c9807821b0899484a7c7e714 not-for-merge branch 'testcommit792' of github.com:jantman/gitpython_issue_301 +3ea2d3492e0df6a7ca33c99f182b809d21e5a230 not-for-merge branch 'testcommit793' of github.com:jantman/gitpython_issue_301 +7288c2e0d6eb9841dda155e34bdddea94605ccff not-for-merge branch 'testcommit794' of github.com:jantman/gitpython_issue_301 +4392e67cd444b0aa57bf952e76cd5bbc8ae29841 not-for-merge branch 'testcommit795' of github.com:jantman/gitpython_issue_301 +20194f78cc6e12eb5c8635dddb872a3cf4334a4d not-for-merge branch 'testcommit796' of github.com:jantman/gitpython_issue_301 +86b3de8a0b071e13867cede0e16b65bff18cbd86 not-for-merge branch 'testcommit797' of github.com:jantman/gitpython_issue_301 +62c6cd3dce0343368d32b7a8cb070f4bb1ebd569 not-for-merge branch 'testcommit798' of github.com:jantman/gitpython_issue_301 +c26c787fe5e2e1d8783f82ace7ec064215582205 not-for-merge branch 'testcommit799' of github.com:jantman/gitpython_issue_301 +e22365ff704d8b81a68af0149bdd1a2b5ec88109 not-for-merge branch 'testcommit8' of github.com:jantman/gitpython_issue_301 +b95f2a5c8a4dc15afe7aae95c29ef283326fe5cd not-for-merge branch 'testcommit80' of github.com:jantman/gitpython_issue_301 +be583784fd6a5ab7f87f1d13117a5f1c4abd0424 not-for-merge branch 'testcommit800' of github.com:jantman/gitpython_issue_301 +337754426fef018eab4923ca29374819264adce8 not-for-merge branch 'testcommit801' of github.com:jantman/gitpython_issue_301 +3f622f9a54ada76c6a85cc76465fee1fe97d81be not-for-merge branch 'testcommit802' of github.com:jantman/gitpython_issue_301 +4cbed8c6448c7ce8fd86d0f15e382aa2c22102e6 not-for-merge branch 'testcommit803' of github.com:jantman/gitpython_issue_301 +8f823f815655a125a7e1b1850d5e3d03077fc153 not-for-merge branch 'testcommit804' of github.com:jantman/gitpython_issue_301 +abce3b56852fb86e797ba047df312cf15d59b49a not-for-merge branch 'testcommit805' of github.com:jantman/gitpython_issue_301 +086bc8be85bbc99f2f851d3a1fdc3f8367da2399 not-for-merge branch 'testcommit806' of github.com:jantman/gitpython_issue_301 +ed8a4fee7608bdb5741e697262624dae65f07f07 not-for-merge branch 'testcommit807' of github.com:jantman/gitpython_issue_301 +6ccf8903a397c9565237763b117431016d1b35ae not-for-merge branch 'testcommit808' of github.com:jantman/gitpython_issue_301 +b01316b4523997a00ebae0c309fb53d5f1b6c857 not-for-merge branch 'testcommit809' of github.com:jantman/gitpython_issue_301 +456c75d54ca7385d900765ee15db2260e15580a6 not-for-merge branch 'testcommit81' of github.com:jantman/gitpython_issue_301 +49045cb7f6345e7fb715bcbf8a010c0d8e9ea56d not-for-merge branch 'testcommit810' of github.com:jantman/gitpython_issue_301 +2bb588a62356c2b30ac2e8ce618252d905ece92b not-for-merge branch 'testcommit811' of github.com:jantman/gitpython_issue_301 +9ad36c46ffe634096d911dd3c83e2fb6f09d3bdb not-for-merge branch 'testcommit812' of github.com:jantman/gitpython_issue_301 +470f29e406e589b8fc14ae6d3a8dc4b15e01b907 not-for-merge branch 'testcommit813' of github.com:jantman/gitpython_issue_301 +2618fcdc88feda29c8b0d11ffb40889f28707a3e not-for-merge branch 'testcommit814' of github.com:jantman/gitpython_issue_301 +c8ce90a3e686bb5a5d430cbfa76ea622988e6e50 not-for-merge branch 'testcommit815' of github.com:jantman/gitpython_issue_301 +e1f2cbb958e56f8490cc02f00086420404f94335 not-for-merge branch 'testcommit816' of github.com:jantman/gitpython_issue_301 +2a1a21ca972c7cbc22e78072657f417b9370d4f6 not-for-merge branch 'testcommit817' of github.com:jantman/gitpython_issue_301 +74fee87b0abe2b2ed07da35be4c77648e34d3eda not-for-merge branch 'testcommit818' of github.com:jantman/gitpython_issue_301 +a6c6f6b64e7633729a0d819e7b78f1b58537ea07 not-for-merge branch 'testcommit819' of github.com:jantman/gitpython_issue_301 +3b84aadc6c3ee800a72c39ac1ad2c975e923ef49 not-for-merge branch 'testcommit82' of github.com:jantman/gitpython_issue_301 +73d9510a26e2d4695b85dcbecdfe4c581c88eec3 not-for-merge branch 'testcommit820' of github.com:jantman/gitpython_issue_301 +1381c18adb0f5e5a350e25b200a7654001839f69 not-for-merge branch 'testcommit821' of github.com:jantman/gitpython_issue_301 +1fe1c0b9d2d019717391d193783beb9202fec97e not-for-merge branch 'testcommit822' of github.com:jantman/gitpython_issue_301 +e9d7dcb5c2e8e8b217d1f9ffa33ab90c55ace089 not-for-merge branch 'testcommit823' of github.com:jantman/gitpython_issue_301 +70fb2bbe50f7f32f7072a0adda6c263c313c699b not-for-merge branch 'testcommit824' of github.com:jantman/gitpython_issue_301 +a3df832a7fc2e8051c2ce2ec1eb34b458518fb1e not-for-merge branch 'testcommit825' of github.com:jantman/gitpython_issue_301 +04e6a980300fc5e78a12e98366fd0c6f037f60f3 not-for-merge branch 'testcommit826' of github.com:jantman/gitpython_issue_301 +65097224fed766e9dfaafe780eee5c3bd1ad4dff not-for-merge branch 'testcommit827' of github.com:jantman/gitpython_issue_301 +bdecb866f6e154fbd267b11fa9c1ddf9ea6633cd not-for-merge branch 'testcommit828' of github.com:jantman/gitpython_issue_301 +35f974b9ba357014f155eff8968e55b8f1ec925a not-for-merge branch 'testcommit829' of github.com:jantman/gitpython_issue_301 +2196661743c6cde6466a7fe54c6765490b34833f not-for-merge branch 'testcommit83' of github.com:jantman/gitpython_issue_301 +a9d8255cb273568fa0791f94982483a9b4bb7384 not-for-merge branch 'testcommit830' of github.com:jantman/gitpython_issue_301 +7bda83dcd876a0812b9da7d056c8bfb052cbcb29 not-for-merge branch 'testcommit831' of github.com:jantman/gitpython_issue_301 +94ce61f4fe4a67d51908cb0370a8ede163b559f1 not-for-merge branch 'testcommit832' of github.com:jantman/gitpython_issue_301 +3fe76e6b8f4835ce9bf6007a1f2a8f1f106c683c not-for-merge branch 'testcommit833' of github.com:jantman/gitpython_issue_301 +45a3ecf57ada742770e94823c1dfa76d61d26516 not-for-merge branch 'testcommit834' of github.com:jantman/gitpython_issue_301 +1ce7b8d0499ab282963a3e5d2af204631da19dfd not-for-merge branch 'testcommit835' of github.com:jantman/gitpython_issue_301 +24db116f6749039117fcf900f5ba1cbc3277a527 not-for-merge branch 'testcommit836' of github.com:jantman/gitpython_issue_301 +e02accccfe173b0bb00c23825f668ab928be6562 not-for-merge branch 'testcommit837' of github.com:jantman/gitpython_issue_301 +f48fe50fb71f0c99e728c556602cfee3d4a66676 not-for-merge branch 'testcommit838' of github.com:jantman/gitpython_issue_301 +a75c6bd3394f98e391379076426b000288961ca0 not-for-merge branch 'testcommit839' of github.com:jantman/gitpython_issue_301 +dab51e9ed7240cf0e1aa1c2e41e09512e0a0212d not-for-merge branch 'testcommit84' of github.com:jantman/gitpython_issue_301 +bc69f3990de88e9332b578df8aa5e482281e445c not-for-merge branch 'testcommit840' of github.com:jantman/gitpython_issue_301 +72292f3cec24b4fc02622bdd2504b167536892da not-for-merge branch 'testcommit841' of github.com:jantman/gitpython_issue_301 +5d2c335f11cacdef97632a8857cd94236466e10b not-for-merge branch 'testcommit842' of github.com:jantman/gitpython_issue_301 +c336aaed145dbca8df378aaa87de1e375d61f31e not-for-merge branch 'testcommit843' of github.com:jantman/gitpython_issue_301 +01e5add3f9da49312bb06dea24b1ee4b309661ad not-for-merge branch 'testcommit844' of github.com:jantman/gitpython_issue_301 +dd44113da5bc3c9db5afd60e4cdf7aabf77f13b0 not-for-merge branch 'testcommit845' of github.com:jantman/gitpython_issue_301 +f9b2e9b19e6a7ca5def62baba856eb23cf1b70df not-for-merge branch 'testcommit846' of github.com:jantman/gitpython_issue_301 +c4528bab51e8e143af02d89f1be992247a55b8ac not-for-merge branch 'testcommit847' of github.com:jantman/gitpython_issue_301 +263ebf73275454133026eaef301d2edc64def3ff not-for-merge branch 'testcommit848' of github.com:jantman/gitpython_issue_301 +9f50779d0eb726452891d41a322b4746ddbf1017 not-for-merge branch 'testcommit849' of github.com:jantman/gitpython_issue_301 +857a64baf52860c4871a5c946bbba75a70f4f2c3 not-for-merge branch 'testcommit85' of github.com:jantman/gitpython_issue_301 +192837cae9a502b486030a056d26ab079303f3f2 not-for-merge branch 'testcommit850' of github.com:jantman/gitpython_issue_301 +f116298dcecef5cb1efc05b4bddbd9de4c10141b not-for-merge branch 'testcommit851' of github.com:jantman/gitpython_issue_301 +db4b905889959bc98e7eea2bdfed2283c5c1d6f9 not-for-merge branch 'testcommit852' of github.com:jantman/gitpython_issue_301 +bb74c3344b5abfaa9324ba397d7f3240fdc48f96 not-for-merge branch 'testcommit853' of github.com:jantman/gitpython_issue_301 +4643826485e09942a1899007d4c8107d2666adc3 not-for-merge branch 'testcommit854' of github.com:jantman/gitpython_issue_301 +f75f908a38b129342700b58017933ed680fe9784 not-for-merge branch 'testcommit855' of github.com:jantman/gitpython_issue_301 +4bd9edb27bb1a60058290e51b1880ac83a6e1a23 not-for-merge branch 'testcommit856' of github.com:jantman/gitpython_issue_301 +1b6ddeff4575e6dc5c921f502394d2a98b869a57 not-for-merge branch 'testcommit857' of github.com:jantman/gitpython_issue_301 +706c0624b714ba02fcbc33fbab76c8137860d59d not-for-merge branch 'testcommit858' of github.com:jantman/gitpython_issue_301 +d9126406160c2d952c8ccb15bbd220fab3943132 not-for-merge branch 'testcommit859' of github.com:jantman/gitpython_issue_301 +4371ccd5279b6caa3650aaf096ab607a6fb32d7a not-for-merge branch 'testcommit86' of github.com:jantman/gitpython_issue_301 +5c811bb95fbd3883c15ec39e078d6a4658e2ca4c not-for-merge branch 'testcommit860' of github.com:jantman/gitpython_issue_301 +b26ae7564bfa9cac13c6b505116283c1c38cf1ec not-for-merge branch 'testcommit861' of github.com:jantman/gitpython_issue_301 +d8beba9621f6930a36278b1c12b695dafbc0080e not-for-merge branch 'testcommit862' of github.com:jantman/gitpython_issue_301 +b35b1700d020dbf197ab2d059888bb904e6ac8ad not-for-merge branch 'testcommit863' of github.com:jantman/gitpython_issue_301 +8ff06252963757a07e6cc9586081691944753618 not-for-merge branch 'testcommit864' of github.com:jantman/gitpython_issue_301 +ffb11f1630667373b452ff797d7a2f97779c4fc1 not-for-merge branch 'testcommit865' of github.com:jantman/gitpython_issue_301 +85b1806fd544a139192702b24384e60e6f4763a1 not-for-merge branch 'testcommit866' of github.com:jantman/gitpython_issue_301 +2cacf0dad6331b9d03ec4b27ba444ab4f1f3020e not-for-merge branch 'testcommit867' of github.com:jantman/gitpython_issue_301 +5873103c91ffef02f7f27f08ed9408d81260db8d not-for-merge branch 'testcommit868' of github.com:jantman/gitpython_issue_301 +25cc2a2301a25f873b64c2e7050a50f1851e4e79 not-for-merge branch 'testcommit869' of github.com:jantman/gitpython_issue_301 +43fb9d702d1ea39abb68c3932e29038a281918ae not-for-merge branch 'testcommit87' of github.com:jantman/gitpython_issue_301 +3c8bc3ba3a801d0624f4a7dcbb6b02c6cf70fd9a not-for-merge branch 'testcommit870' of github.com:jantman/gitpython_issue_301 +74fec1d315e2a22f74bab34913ee32f5d81eba22 not-for-merge branch 'testcommit871' of github.com:jantman/gitpython_issue_301 +b2ec8c6d408edc78a457775d05fcd376e819878b not-for-merge branch 'testcommit872' of github.com:jantman/gitpython_issue_301 +a259dee43dbf1c837c8db4308b833de974a10e13 not-for-merge branch 'testcommit873' of github.com:jantman/gitpython_issue_301 +92357dbe4a97256110a2fc9831d159e6cb32031d not-for-merge branch 'testcommit874' of github.com:jantman/gitpython_issue_301 +6b2329d76d3a0f310dcb38a0feb10521b28618fb not-for-merge branch 'testcommit875' of github.com:jantman/gitpython_issue_301 +be0507f5e36a8a46e72d6f0562a29b64eabd4199 not-for-merge branch 'testcommit876' of github.com:jantman/gitpython_issue_301 +d4f981b78c2c17bdeaa556ee943c6772b8160a4a not-for-merge branch 'testcommit877' of github.com:jantman/gitpython_issue_301 +531885c676fd1c29d8cf8b44919cd93509819261 not-for-merge branch 'testcommit878' of github.com:jantman/gitpython_issue_301 +38dfc4b5fa08900be867481294cb16b783c31920 not-for-merge branch 'testcommit879' of github.com:jantman/gitpython_issue_301 +9b7ffdfe4ed10799c09ab6b974e7799bad4a8845 not-for-merge branch 'testcommit88' of github.com:jantman/gitpython_issue_301 +af9727f11fb5f575858232555259c26516370a52 not-for-merge branch 'testcommit880' of github.com:jantman/gitpython_issue_301 +405787bc9202686f631f7e10d92e4f10f7db5095 not-for-merge branch 'testcommit881' of github.com:jantman/gitpython_issue_301 +27b613a73fc19c8013cfae392420de3cad34b391 not-for-merge branch 'testcommit882' of github.com:jantman/gitpython_issue_301 +a7399203b425cfa5b9cb142c83702909bb757f34 not-for-merge branch 'testcommit883' of github.com:jantman/gitpython_issue_301 +6554ab095e70116f4dd7a6476690e6b5165ce37b not-for-merge branch 'testcommit884' of github.com:jantman/gitpython_issue_301 +d34363cd1553d0c97c915e201ba5140c5abd256d not-for-merge branch 'testcommit885' of github.com:jantman/gitpython_issue_301 +2f1a8817ed3066eea7bfa1045cc983fef4a1d979 not-for-merge branch 'testcommit886' of github.com:jantman/gitpython_issue_301 +92be475c2d9fbefeeac0b252527c05b1749d39eb not-for-merge branch 'testcommit887' of github.com:jantman/gitpython_issue_301 +7451f6cba84e3dbbd917724dceafbd6d2fbce922 not-for-merge branch 'testcommit888' of github.com:jantman/gitpython_issue_301 +68841ca3d6b26ed389f0fae6e50dc17ac50fe308 not-for-merge branch 'testcommit889' of github.com:jantman/gitpython_issue_301 +df7d39fd5f4f172c40fe8d66c5a99f0565dd02c4 not-for-merge branch 'testcommit89' of github.com:jantman/gitpython_issue_301 +b6064cd192e6407c23c8205aa684a33d102349f1 not-for-merge branch 'testcommit890' of github.com:jantman/gitpython_issue_301 +c5ea72773bca57f176f6a9cfa099960e55293fcd not-for-merge branch 'testcommit891' of github.com:jantman/gitpython_issue_301 +2cbd695ccafd9b6d01e30cce08e8a98e100bbbf5 not-for-merge branch 'testcommit892' of github.com:jantman/gitpython_issue_301 +c462af6ae86b081646e8ccf25b8beed6ce6b15be not-for-merge branch 'testcommit893' of github.com:jantman/gitpython_issue_301 +7efd6d02e05b290244af6ff38d5277b5909896e7 not-for-merge branch 'testcommit894' of github.com:jantman/gitpython_issue_301 +b448349d8d8ad82a3d3c358b075cab296223b13c not-for-merge branch 'testcommit895' of github.com:jantman/gitpython_issue_301 +5a19033021213cadbe74d075149eee603e03c2fe not-for-merge branch 'testcommit896' of github.com:jantman/gitpython_issue_301 +77d42dafd2a77adbe5708f0b5720cba288c67df7 not-for-merge branch 'testcommit897' of github.com:jantman/gitpython_issue_301 +14bf733e5bf6608ec9a46f00efc21c309672f5a4 not-for-merge branch 'testcommit898' of github.com:jantman/gitpython_issue_301 +c7fafa5dc37a5d7e8eeb3b0365b0ea5ca4dd59ed not-for-merge branch 'testcommit899' of github.com:jantman/gitpython_issue_301 +ddeb69069843fb15f6b10de1dc05a3c2d8d6f7b3 not-for-merge branch 'testcommit9' of github.com:jantman/gitpython_issue_301 +db1d1aef2dfbaeab03bbf79130c1d946f76d2552 not-for-merge branch 'testcommit90' of github.com:jantman/gitpython_issue_301 +8191d99d60de3b7bff3678ea8d6329288e6deb94 not-for-merge branch 'testcommit900' of github.com:jantman/gitpython_issue_301 +870799f09a1771d4e1b14ff630d7080c1c323b80 not-for-merge branch 'testcommit901' of github.com:jantman/gitpython_issue_301 +34553a2a109de7fa7c40562be791094dc38a4ea1 not-for-merge branch 'testcommit902' of github.com:jantman/gitpython_issue_301 +80686c2fa5f4e26a3b50674fd199c144d26d57e0 not-for-merge branch 'testcommit903' of github.com:jantman/gitpython_issue_301 +c03519559b29176e1f5a253b66a09deaf013dbc1 not-for-merge branch 'testcommit904' of github.com:jantman/gitpython_issue_301 +f43d67c99625ba3503dc54edbfa4839431647491 not-for-merge branch 'testcommit905' of github.com:jantman/gitpython_issue_301 +689ffc1f1af5190b6b60900ab707ba9d037605e7 not-for-merge branch 'testcommit906' of github.com:jantman/gitpython_issue_301 +3bdfe86fa164e932ccfcc40e242eaf8d594e175f not-for-merge branch 'testcommit907' of github.com:jantman/gitpython_issue_301 +2f91a021d9c53d26e0c4fea76068896ae2958618 not-for-merge branch 'testcommit908' of github.com:jantman/gitpython_issue_301 +4a32b92cc914285aed38efa28332c0767e24406f not-for-merge branch 'testcommit909' of github.com:jantman/gitpython_issue_301 +1c477dbd6b3792daf18e066b88dce2fe74b288e0 not-for-merge branch 'testcommit91' of github.com:jantman/gitpython_issue_301 +9ca271b0bb951a869329642c5c60bc44fa87407d not-for-merge branch 'testcommit910' of github.com:jantman/gitpython_issue_301 +e05b6b8e5a21a81e7e70d090dde3cdbc2a5d9e8b not-for-merge branch 'testcommit911' of github.com:jantman/gitpython_issue_301 +1da90dbd26103b7db343da16c72c8b1a4ae94fb6 not-for-merge branch 'testcommit912' of github.com:jantman/gitpython_issue_301 +72bc1782f11af5400bf22a20c760e948b2bf72ef not-for-merge branch 'testcommit913' of github.com:jantman/gitpython_issue_301 +8e9d28e51744305addbbfc53e5d7feb2903b9410 not-for-merge branch 'testcommit914' of github.com:jantman/gitpython_issue_301 +994c6eb5668504424fd7a98c28cdbef37cb9ff73 not-for-merge branch 'testcommit915' of github.com:jantman/gitpython_issue_301 +569ff3f875b87899fb713eeb1e9008ea1ca041e0 not-for-merge branch 'testcommit916' of github.com:jantman/gitpython_issue_301 +ea51b9934dae7202c9abcc92b40bd68b74a22863 not-for-merge branch 'testcommit917' of github.com:jantman/gitpython_issue_301 +e1d5c68be4b10e5053458437f764bcb3a3460f28 not-for-merge branch 'testcommit918' of github.com:jantman/gitpython_issue_301 +a82eadcce378b5c5e28c5a73df00f4ca9cc8eb49 not-for-merge branch 'testcommit919' of github.com:jantman/gitpython_issue_301 +c99c941dd47de731e839f79ad8946ab4d7fc2a01 not-for-merge branch 'testcommit92' of github.com:jantman/gitpython_issue_301 +7833a3f9b0d40c883c10e60906458e95e1158167 not-for-merge branch 'testcommit920' of github.com:jantman/gitpython_issue_301 +c1ea75e900bdc5d1e2756382c7c3acfc855ddc68 not-for-merge branch 'testcommit921' of github.com:jantman/gitpython_issue_301 +d653f8b3ba76ca15f42a535ce5ea71e36734c19c not-for-merge branch 'testcommit922' of github.com:jantman/gitpython_issue_301 +01e2567f414733b5866700e40e3cc615c104fcb4 not-for-merge branch 'testcommit923' of github.com:jantman/gitpython_issue_301 +7223e84697d7aa76e4ef610ff82047658887bd3a not-for-merge branch 'testcommit924' of github.com:jantman/gitpython_issue_301 +2edcd7a4765f35d21d69f540d54dac6689b408a5 not-for-merge branch 'testcommit925' of github.com:jantman/gitpython_issue_301 +a7292b4052beddef33922bfeb945f7288f51633f not-for-merge branch 'testcommit926' of github.com:jantman/gitpython_issue_301 +5229940e781a4b24df3fe61e566f1ed0e1e719ee not-for-merge branch 'testcommit927' of github.com:jantman/gitpython_issue_301 +1a18a9623ad47a410d70950e3216ecd6d3d51cec not-for-merge branch 'testcommit928' of github.com:jantman/gitpython_issue_301 +2a2ddee059cc26fda65b888c6020d34df4d39153 not-for-merge branch 'testcommit929' of github.com:jantman/gitpython_issue_301 +3a5d7becb833f3768d2fa89e9bc11dd55691013f not-for-merge branch 'testcommit93' of github.com:jantman/gitpython_issue_301 +9de8f439bbb5c4133151dcae86172f2f0c08dcaf not-for-merge branch 'testcommit930' of github.com:jantman/gitpython_issue_301 +03ebc2491870c9edaa736730a74989b29d59ad12 not-for-merge branch 'testcommit931' of github.com:jantman/gitpython_issue_301 +5629019959fa16374908dac26f82110939a20bd9 not-for-merge branch 'testcommit932' of github.com:jantman/gitpython_issue_301 +07c2cd8af15bb63546ff1cb00a556c00addd02cb not-for-merge branch 'testcommit933' of github.com:jantman/gitpython_issue_301 +b502a556ed01876eab05543437e4ca7f16f6313a not-for-merge branch 'testcommit934' of github.com:jantman/gitpython_issue_301 +7ad8d641cfd6eb63e5bc20c8194217b972011ffd not-for-merge branch 'testcommit935' of github.com:jantman/gitpython_issue_301 +f35d4c665a07a5f3caa665317a14df107a13e8bc not-for-merge branch 'testcommit936' of github.com:jantman/gitpython_issue_301 +18298a892629335371c8d227c10838dcd097cdc0 not-for-merge branch 'testcommit937' of github.com:jantman/gitpython_issue_301 +7a2fb16ff4676731898d30b7a5680e5f36a0db18 not-for-merge branch 'testcommit938' of github.com:jantman/gitpython_issue_301 +8bc647785d3f30333835a4fd3a2b593afd959e03 not-for-merge branch 'testcommit939' of github.com:jantman/gitpython_issue_301 +88d02da30d56f223205f17745319ad470cc5e50c not-for-merge branch 'testcommit94' of github.com:jantman/gitpython_issue_301 +9e2c28704be19a06f5e537fa1027a9d16d05580e not-for-merge branch 'testcommit940' of github.com:jantman/gitpython_issue_301 +00d80aeebdc48333a6493162cc04356286c4f137 not-for-merge branch 'testcommit941' of github.com:jantman/gitpython_issue_301 +db7a4a8abdb4da8b9391654046985aba8681f5e7 not-for-merge branch 'testcommit942' of github.com:jantman/gitpython_issue_301 +f6493cf384ec938945ab03221b6a4c033ac0140f not-for-merge branch 'testcommit943' of github.com:jantman/gitpython_issue_301 +eb15f69556fb0ef743effae07f24a5f49a6bdabd not-for-merge branch 'testcommit944' of github.com:jantman/gitpython_issue_301 +7c1bd8e8476a2d4bf6f6df3f6f938ecc74411079 not-for-merge branch 'testcommit945' of github.com:jantman/gitpython_issue_301 +dab6d7eff111c750ab78417e1fee2cd3f484704f not-for-merge branch 'testcommit946' of github.com:jantman/gitpython_issue_301 +9b5e699798aecc59fdfef25bcc300e02e516903b not-for-merge branch 'testcommit947' of github.com:jantman/gitpython_issue_301 +be15cb66adf5cc5e478871d5cf45123003d6d80c not-for-merge branch 'testcommit948' of github.com:jantman/gitpython_issue_301 +041d42e3ec17eb17d40da3584e471a4817c0ac71 not-for-merge branch 'testcommit949' of github.com:jantman/gitpython_issue_301 +42f148a4d88bd9f84bd4180e6653ee95f5d66963 not-for-merge branch 'testcommit95' of github.com:jantman/gitpython_issue_301 +85067470dc6f14ceb385f1035247a6094118d222 not-for-merge branch 'testcommit950' of github.com:jantman/gitpython_issue_301 +ec6ea31822f656d4b3c9f61ab40f14fb6a18d48f not-for-merge branch 'testcommit951' of github.com:jantman/gitpython_issue_301 +34c7638ef0f83dd28a1aea94def9632ab88f6ea3 not-for-merge branch 'testcommit952' of github.com:jantman/gitpython_issue_301 +f768494abb215923b298698fb98a946ac03e1534 not-for-merge branch 'testcommit953' of github.com:jantman/gitpython_issue_301 +8b677c09d1cd1bc9e99f0b8e1d7104b04b80ad23 not-for-merge branch 'testcommit954' of github.com:jantman/gitpython_issue_301 +fb929d38cfa371beb0f82cf389548a86ae178f3b not-for-merge branch 'testcommit955' of github.com:jantman/gitpython_issue_301 +7e8b2bf8812ac582bd4ddfc3a11f54e92beabff2 not-for-merge branch 'testcommit956' of github.com:jantman/gitpython_issue_301 +e00814adbacabcc029b68ad63a6678eaec2b18d6 not-for-merge branch 'testcommit957' of github.com:jantman/gitpython_issue_301 +c709ad362edb2660bde94c535c9801de72b9f4aa not-for-merge branch 'testcommit958' of github.com:jantman/gitpython_issue_301 +e6c560ae9dbc82ddeabc37b35f9c7e769fc1b83e not-for-merge branch 'testcommit959' of github.com:jantman/gitpython_issue_301 +7350766195eb4e0efa2cdc5395476102e89e8739 not-for-merge branch 'testcommit96' of github.com:jantman/gitpython_issue_301 +1da965408f9cfbd2b0b33c70cc25ffae984cd5e6 not-for-merge branch 'testcommit960' of github.com:jantman/gitpython_issue_301 +1c6f8f8ddebc8fcfd609161fdc2857bc2df8d6c5 not-for-merge branch 'testcommit961' of github.com:jantman/gitpython_issue_301 +dac5f4787fd02377109b81d33f55f3c607f08038 not-for-merge branch 'testcommit962' of github.com:jantman/gitpython_issue_301 +c5f82782b5461a0f8f1b545bd05eca99cf2ac966 not-for-merge branch 'testcommit963' of github.com:jantman/gitpython_issue_301 +01e098c0474b1b456585567a7f59a46bcdf2852d not-for-merge branch 'testcommit964' of github.com:jantman/gitpython_issue_301 +e2379f316416cf11e02149bb837d46739fd95d66 not-for-merge branch 'testcommit965' of github.com:jantman/gitpython_issue_301 +3094f713109366bd730c62b6ea9faf89886f9c5b not-for-merge branch 'testcommit966' of github.com:jantman/gitpython_issue_301 +a2bfdf2fb5a15894d0971078397213957aac07fe not-for-merge branch 'testcommit967' of github.com:jantman/gitpython_issue_301 +3a466c2d6adfec6d43e1deaa8f224333e0278be4 not-for-merge branch 'testcommit968' of github.com:jantman/gitpython_issue_301 +9c989b9d76e9030761c88b9427fc01438a88a440 not-for-merge branch 'testcommit969' of github.com:jantman/gitpython_issue_301 +59d79380ecf45464fe0144bc9f0e099e25aa1584 not-for-merge branch 'testcommit97' of github.com:jantman/gitpython_issue_301 +008ca4360db0ada336536e3b8a652a8ffac607a2 not-for-merge branch 'testcommit970' of github.com:jantman/gitpython_issue_301 +23bf63d4060155e3931722522fd021cdebebde20 not-for-merge branch 'testcommit971' of github.com:jantman/gitpython_issue_301 +e85611780ec2757972052f1451f0b74e0285fbd7 not-for-merge branch 'testcommit972' of github.com:jantman/gitpython_issue_301 +fca57448b3409828758880d3182fb75a053b4a9b not-for-merge branch 'testcommit973' of github.com:jantman/gitpython_issue_301 +bfe65a58f4a65632c73cbe9f5546b0b41ec0d8f1 not-for-merge branch 'testcommit974' of github.com:jantman/gitpython_issue_301 +c6bcf9deb2e6eff1dc28bd2e8a0a2fccc9fa1bc3 not-for-merge branch 'testcommit975' of github.com:jantman/gitpython_issue_301 +02a2cd795746b89516269b01431ce796cfe06c40 not-for-merge branch 'testcommit976' of github.com:jantman/gitpython_issue_301 +8b18d2b77f8366c9bcdbb2caaa0040ef8b9b2931 not-for-merge branch 'testcommit977' of github.com:jantman/gitpython_issue_301 +ae908980739b37067ee02a348b313c0a3323eb5f not-for-merge branch 'testcommit978' of github.com:jantman/gitpython_issue_301 +cf7cc673d8d782e1bf3d16fc97483863a5bb5365 not-for-merge branch 'testcommit979' of github.com:jantman/gitpython_issue_301 +b0a2585798ac2ddce9402b4ce691e74835eb720b not-for-merge branch 'testcommit98' of github.com:jantman/gitpython_issue_301 +a978fc0409b6de22b8b6370096d3b90ac068192d not-for-merge branch 'testcommit980' of github.com:jantman/gitpython_issue_301 +db73a55c656fb27edf3bb185d651e1afc434a4de not-for-merge branch 'testcommit981' of github.com:jantman/gitpython_issue_301 +869e3005fcf1a31c8610bd9519aa2835d746cc52 not-for-merge branch 'testcommit982' of github.com:jantman/gitpython_issue_301 +91b2dc537d6b6b1db9b8732cce7de1e8fcb5e8d9 not-for-merge branch 'testcommit983' of github.com:jantman/gitpython_issue_301 +a6daa63e5d654891e0f349d7a2bf25b2a8a3d5ed not-for-merge branch 'testcommit984' of github.com:jantman/gitpython_issue_301 +362f670649c92e62320f7c93f8ebad6aad53e37d not-for-merge branch 'testcommit985' of github.com:jantman/gitpython_issue_301 +82a11e9226bdd02d3f25b83c1016ebe112a760b9 not-for-merge branch 'testcommit986' of github.com:jantman/gitpython_issue_301 +8213be4548925d305f1603c4ad383d54fe10a301 not-for-merge branch 'testcommit987' of github.com:jantman/gitpython_issue_301 +05ce60b3d5d7c6bfbc1e4c586ef45d24ee280d7e not-for-merge branch 'testcommit988' of github.com:jantman/gitpython_issue_301 +3b4fa29aec584fa83d99f4b05a3bd40863c41a42 not-for-merge branch 'testcommit989' of github.com:jantman/gitpython_issue_301 +69f46edc5faeadf15648f991790bd1cc6d40a7ad not-for-merge branch 'testcommit99' of github.com:jantman/gitpython_issue_301 +e0534a599e72daa8d934d99477ee4d80af670ac7 not-for-merge branch 'testcommit990' of github.com:jantman/gitpython_issue_301 +446fb5e2501d498c0b49ba3a0fc2e44a0c7cdc6e not-for-merge branch 'testcommit991' of github.com:jantman/gitpython_issue_301 +138eadf0395e5d53303c871932575211b2a81ca0 not-for-merge branch 'testcommit992' of github.com:jantman/gitpython_issue_301 +cf5652cce3d15e8dd1f108c306e0873c47b92760 not-for-merge branch 'testcommit993' of github.com:jantman/gitpython_issue_301 +e1fc3bf4a22a3cb484fb17a8a672fe0ce7d844e3 not-for-merge branch 'testcommit994' of github.com:jantman/gitpython_issue_301 +97d24159a5aeed8b1a3c5c25c4517fad4e1ca987 not-for-merge branch 'testcommit995' of github.com:jantman/gitpython_issue_301 +90ab5f7a82fb9c539b3e319db2ebb8adc9fb01f5 not-for-merge branch 'testcommit996' of github.com:jantman/gitpython_issue_301 +5dd4efeb4aa45c18d76648b3958869e2c799c4be not-for-merge branch 'testcommit997' of github.com:jantman/gitpython_issue_301 +5f48d52c7bcf27e7e48f3655022794169fe2d5b0 not-for-merge branch 'testcommit998' of github.com:jantman/gitpython_issue_301 +fe62b52ad79d032f6275227cb74782ff952e30f8 not-for-merge branch 'testcommit999' of github.com:jantman/gitpython_issue_301 diff --git a/git/test/fixtures/issue-301_stderr b/git/test/fixtures/issue-301_stderr new file mode 100644 index 000000000..3da0ed157 --- /dev/null +++ b/git/test/fixtures/issue-301_stderr @@ -0,0 +1,5002 @@ +From github.com:jantman/gitpython_issue_301 + = [up to date] master -> origin/master + = [up to date] testcommit1 -> origin/testcommit1 + = [up to date] testcommit10 -> origin/testcommit10 + = [up to date] testcommit100 -> origin/testcommit100 + = [up to date] testcommit1000 -> origin/testcommit1000 + = [up to date] testcommit1001 -> origin/testcommit1001 + = [up to date] testcommit1002 -> origin/testcommit1002 + = [up to date] testcommit1003 -> origin/testcommit1003 + = [up to date] testcommit1004 -> origin/testcommit1004 + = [up to date] testcommit1005 -> origin/testcommit1005 + = [up to date] testcommit1006 -> origin/testcommit1006 + = [up to date] testcommit1007 -> origin/testcommit1007 + = [up to date] testcommit1008 -> origin/testcommit1008 + = [up to date] testcommit1009 -> origin/testcommit1009 + = [up to date] testcommit101 -> origin/testcommit101 + = [up to date] testcommit1010 -> origin/testcommit1010 + = [up to date] testcommit1011 -> origin/testcommit1011 + = [up to date] testcommit1012 -> origin/testcommit1012 + = [up to date] testcommit1013 -> origin/testcommit1013 + = [up to date] testcommit1014 -> origin/testcommit1014 + = [up to date] testcommit1015 -> origin/testcommit1015 + = [up to date] testcommit1016 -> origin/testcommit1016 + = [up to date] testcommit1017 -> origin/testcommit1017 + = [up to date] testcommit1018 -> origin/testcommit1018 + = [up to date] testcommit1019 -> origin/testcommit1019 + = [up to date] testcommit102 -> origin/testcommit102 + = [up to date] testcommit1020 -> origin/testcommit1020 + = [up to date] testcommit1021 -> origin/testcommit1021 + = [up to date] testcommit1022 -> origin/testcommit1022 + = [up to date] testcommit1023 -> origin/testcommit1023 + = [up to date] testcommit1024 -> origin/testcommit1024 + = [up to date] testcommit1025 -> origin/testcommit1025 + = [up to date] testcommit1026 -> origin/testcommit1026 + = [up to date] testcommit1027 -> origin/testcommit1027 + = [up to date] testcommit1028 -> origin/testcommit1028 + = [up to date] testcommit1029 -> origin/testcommit1029 + = [up to date] testcommit103 -> origin/testcommit103 + = [up to date] testcommit1030 -> origin/testcommit1030 + = [up to date] testcommit1031 -> origin/testcommit1031 + = [up to date] testcommit1032 -> origin/testcommit1032 + = [up to date] testcommit1033 -> origin/testcommit1033 + = [up to date] testcommit1034 -> origin/testcommit1034 + = [up to date] testcommit1035 -> origin/testcommit1035 + = [up to date] testcommit1036 -> origin/testcommit1036 + = [up to date] testcommit1037 -> origin/testcommit1037 + = [up to date] testcommit1038 -> origin/testcommit1038 + = [up to date] testcommit1039 -> origin/testcommit1039 + = [up to date] testcommit104 -> origin/testcommit104 + = [up to date] testcommit1040 -> origin/testcommit1040 + = [up to date] testcommit1041 -> origin/testcommit1041 + = [up to date] testcommit1042 -> origin/testcommit1042 + = [up to date] testcommit1043 -> origin/testcommit1043 + = [up to date] testcommit1044 -> origin/testcommit1044 + = [up to date] testcommit1045 -> origin/testcommit1045 + = [up to date] testcommit1046 -> origin/testcommit1046 + = [up to date] testcommit1047 -> origin/testcommit1047 + = [up to date] testcommit1048 -> origin/testcommit1048 + = [up to date] testcommit1049 -> origin/testcommit1049 + = [up to date] testcommit105 -> origin/testcommit105 + = [up to date] testcommit1050 -> origin/testcommit1050 + = [up to date] testcommit1051 -> origin/testcommit1051 + = [up to date] testcommit1052 -> origin/testcommit1052 + = [up to date] testcommit1053 -> origin/testcommit1053 + = [up to date] testcommit1054 -> origin/testcommit1054 + = [up to date] testcommit1055 -> origin/testcommit1055 + = [up to date] testcommit1056 -> origin/testcommit1056 + = [up to date] testcommit1057 -> origin/testcommit1057 + = [up to date] testcommit1058 -> origin/testcommit1058 + = [up to date] testcommit1059 -> origin/testcommit1059 + = [up to date] testcommit106 -> origin/testcommit106 + = [up to date] testcommit1060 -> origin/testcommit1060 + = [up to date] testcommit1061 -> origin/testcommit1061 + = [up to date] testcommit1062 -> origin/testcommit1062 + = [up to date] testcommit1063 -> origin/testcommit1063 + = [up to date] testcommit1064 -> origin/testcommit1064 + = [up to date] testcommit1065 -> origin/testcommit1065 + = [up to date] testcommit1066 -> origin/testcommit1066 + = [up to date] testcommit1067 -> origin/testcommit1067 + = [up to date] testcommit1068 -> origin/testcommit1068 + = [up to date] testcommit1069 -> origin/testcommit1069 + = [up to date] testcommit107 -> origin/testcommit107 + = [up to date] testcommit1070 -> origin/testcommit1070 + = [up to date] testcommit1071 -> origin/testcommit1071 + = [up to date] testcommit1072 -> origin/testcommit1072 + = [up to date] testcommit1073 -> origin/testcommit1073 + = [up to date] testcommit1074 -> origin/testcommit1074 + = [up to date] testcommit1075 -> origin/testcommit1075 + = [up to date] testcommit1076 -> origin/testcommit1076 + = [up to date] testcommit1077 -> origin/testcommit1077 + = [up to date] testcommit1078 -> origin/testcommit1078 + = [up to date] testcommit1079 -> origin/testcommit1079 + = [up to date] testcommit108 -> origin/testcommit108 + = [up to date] testcommit1080 -> origin/testcommit1080 + = [up to date] testcommit1081 -> origin/testcommit1081 + = [up to date] testcommit1082 -> origin/testcommit1082 + = [up to date] testcommit1083 -> origin/testcommit1083 + = [up to date] testcommit1084 -> origin/testcommit1084 + = [up to date] testcommit1085 -> origin/testcommit1085 + = [up to date] testcommit1086 -> origin/testcommit1086 + = [up to date] testcommit1087 -> origin/testcommit1087 + = [up to date] testcommit1088 -> origin/testcommit1088 + = [up to date] testcommit1089 -> origin/testcommit1089 + = [up to date] testcommit109 -> origin/testcommit109 + = [up to date] testcommit1090 -> origin/testcommit1090 + = [up to date] testcommit1091 -> origin/testcommit1091 + = [up to date] testcommit1092 -> origin/testcommit1092 + = [up to date] testcommit1093 -> origin/testcommit1093 + = [up to date] testcommit1094 -> origin/testcommit1094 + = [up to date] testcommit1095 -> origin/testcommit1095 + = [up to date] testcommit1096 -> origin/testcommit1096 + = [up to date] testcommit1097 -> origin/testcommit1097 + = [up to date] testcommit1098 -> origin/testcommit1098 + = [up to date] testcommit1099 -> origin/testcommit1099 + = [up to date] testcommit11 -> origin/testcommit11 + = [up to date] testcommit110 -> origin/testcommit110 + = [up to date] testcommit1100 -> origin/testcommit1100 + = [up to date] testcommit1101 -> origin/testcommit1101 + = [up to date] testcommit1102 -> origin/testcommit1102 + = [up to date] testcommit1103 -> origin/testcommit1103 + = [up to date] testcommit1104 -> origin/testcommit1104 + = [up to date] testcommit1105 -> origin/testcommit1105 + = [up to date] testcommit1106 -> origin/testcommit1106 + = [up to date] testcommit1107 -> origin/testcommit1107 + = [up to date] testcommit1108 -> origin/testcommit1108 + = [up to date] testcommit1109 -> origin/testcommit1109 + = [up to date] testcommit111 -> origin/testcommit111 + = [up to date] testcommit1110 -> origin/testcommit1110 + = [up to date] testcommit1111 -> origin/testcommit1111 + = [up to date] testcommit1112 -> origin/testcommit1112 + = [up to date] testcommit1113 -> origin/testcommit1113 + = [up to date] testcommit1114 -> origin/testcommit1114 + = [up to date] testcommit1115 -> origin/testcommit1115 + = [up to date] testcommit1116 -> origin/testcommit1116 + = [up to date] testcommit1117 -> origin/testcommit1117 + = [up to date] testcommit1118 -> origin/testcommit1118 + = [up to date] testcommit1119 -> origin/testcommit1119 + = [up to date] testcommit112 -> origin/testcommit112 + = [up to date] testcommit1120 -> origin/testcommit1120 + = [up to date] testcommit1121 -> origin/testcommit1121 + = [up to date] testcommit1122 -> origin/testcommit1122 + = [up to date] testcommit1123 -> origin/testcommit1123 + = [up to date] testcommit1124 -> origin/testcommit1124 + = [up to date] testcommit1125 -> origin/testcommit1125 + = [up to date] testcommit1126 -> origin/testcommit1126 + = [up to date] testcommit1127 -> origin/testcommit1127 + = [up to date] testcommit1128 -> origin/testcommit1128 + = [up to date] testcommit1129 -> origin/testcommit1129 + = [up to date] testcommit113 -> origin/testcommit113 + = [up to date] testcommit1130 -> origin/testcommit1130 + = [up to date] testcommit1131 -> origin/testcommit1131 + = [up to date] testcommit1132 -> origin/testcommit1132 + = [up to date] testcommit1133 -> origin/testcommit1133 + = [up to date] testcommit1134 -> origin/testcommit1134 + = [up to date] testcommit1135 -> origin/testcommit1135 + = [up to date] testcommit1136 -> origin/testcommit1136 + = [up to date] testcommit1137 -> origin/testcommit1137 + = [up to date] testcommit1138 -> origin/testcommit1138 + = [up to date] testcommit1139 -> origin/testcommit1139 + = [up to date] testcommit114 -> origin/testcommit114 + = [up to date] testcommit1140 -> origin/testcommit1140 + = [up to date] testcommit1141 -> origin/testcommit1141 + = [up to date] testcommit1142 -> origin/testcommit1142 + = [up to date] testcommit1143 -> origin/testcommit1143 + = [up to date] testcommit1144 -> origin/testcommit1144 + = [up to date] testcommit1145 -> origin/testcommit1145 + = [up to date] testcommit1146 -> origin/testcommit1146 + = [up to date] testcommit1147 -> origin/testcommit1147 + = [up to date] testcommit1148 -> origin/testcommit1148 + = [up to date] testcommit1149 -> origin/testcommit1149 + = [up to date] testcommit115 -> origin/testcommit115 + = [up to date] testcommit1150 -> origin/testcommit1150 + = [up to date] testcommit1151 -> origin/testcommit1151 + = [up to date] testcommit1152 -> origin/testcommit1152 + = [up to date] testcommit1153 -> origin/testcommit1153 + = [up to date] testcommit1154 -> origin/testcommit1154 + = [up to date] testcommit1155 -> origin/testcommit1155 + = [up to date] testcommit1156 -> origin/testcommit1156 + = [up to date] testcommit1157 -> origin/testcommit1157 + = [up to date] testcommit1158 -> origin/testcommit1158 + = [up to date] testcommit1159 -> origin/testcommit1159 + = [up to date] testcommit116 -> origin/testcommit116 + = [up to date] testcommit1160 -> origin/testcommit1160 + = [up to date] testcommit1161 -> origin/testcommit1161 + = [up to date] testcommit1162 -> origin/testcommit1162 + = [up to date] testcommit1163 -> origin/testcommit1163 + = [up to date] testcommit1164 -> origin/testcommit1164 + = [up to date] testcommit1165 -> origin/testcommit1165 + = [up to date] testcommit1166 -> origin/testcommit1166 + = [up to date] testcommit1167 -> origin/testcommit1167 + = [up to date] testcommit1168 -> origin/testcommit1168 + = [up to date] testcommit1169 -> origin/testcommit1169 + = [up to date] testcommit117 -> origin/testcommit117 + = [up to date] testcommit1170 -> origin/testcommit1170 + = [up to date] testcommit1171 -> origin/testcommit1171 + = [up to date] testcommit1172 -> origin/testcommit1172 + = [up to date] testcommit1173 -> origin/testcommit1173 + = [up to date] testcommit1174 -> origin/testcommit1174 + = [up to date] testcommit1175 -> origin/testcommit1175 + = [up to date] testcommit1176 -> origin/testcommit1176 + = [up to date] testcommit1177 -> origin/testcommit1177 + = [up to date] testcommit1178 -> origin/testcommit1178 + = [up to date] testcommit1179 -> origin/testcommit1179 + = [up to date] testcommit118 -> origin/testcommit118 + = [up to date] testcommit1180 -> origin/testcommit1180 + = [up to date] testcommit1181 -> origin/testcommit1181 + = [up to date] testcommit1182 -> origin/testcommit1182 + = [up to date] testcommit1183 -> origin/testcommit1183 + = [up to date] testcommit1184 -> origin/testcommit1184 + = [up to date] testcommit1185 -> origin/testcommit1185 + = [up to date] testcommit1186 -> origin/testcommit1186 + = [up to date] testcommit1187 -> origin/testcommit1187 + = [up to date] testcommit1188 -> origin/testcommit1188 + = [up to date] testcommit1189 -> origin/testcommit1189 + = [up to date] testcommit119 -> origin/testcommit119 + = [up to date] testcommit1190 -> origin/testcommit1190 + = [up to date] testcommit1191 -> origin/testcommit1191 + = [up to date] testcommit1192 -> origin/testcommit1192 + = [up to date] testcommit1193 -> origin/testcommit1193 + = [up to date] testcommit1194 -> origin/testcommit1194 + = [up to date] testcommit1195 -> origin/testcommit1195 + = [up to date] testcommit1196 -> origin/testcommit1196 + = [up to date] testcommit1197 -> origin/testcommit1197 + = [up to date] testcommit1198 -> origin/testcommit1198 + = [up to date] testcommit1199 -> origin/testcommit1199 + = [up to date] testcommit12 -> origin/testcommit12 + = [up to date] testcommit120 -> origin/testcommit120 + = [up to date] testcommit1200 -> origin/testcommit1200 + = [up to date] testcommit1201 -> origin/testcommit1201 + = [up to date] testcommit1202 -> origin/testcommit1202 + = [up to date] testcommit1203 -> origin/testcommit1203 + = [up to date] testcommit1204 -> origin/testcommit1204 + = [up to date] testcommit1205 -> origin/testcommit1205 + = [up to date] testcommit1206 -> origin/testcommit1206 + = [up to date] testcommit1207 -> origin/testcommit1207 + = [up to date] testcommit1208 -> origin/testcommit1208 + = [up to date] testcommit1209 -> origin/testcommit1209 + = [up to date] testcommit121 -> origin/testcommit121 + = [up to date] testcommit1210 -> origin/testcommit1210 + = [up to date] testcommit1211 -> origin/testcommit1211 + = [up to date] testcommit1212 -> origin/testcommit1212 + = [up to date] testcommit1213 -> origin/testcommit1213 + = [up to date] testcommit1214 -> origin/testcommit1214 + = [up to date] testcommit1215 -> origin/testcommit1215 + = [up to date] testcommit1216 -> origin/testcommit1216 + = [up to date] testcommit1217 -> origin/testcommit1217 + = [up to date] testcommit1218 -> origin/testcommit1218 + = [up to date] testcommit1219 -> origin/testcommit1219 + = [up to date] testcommit122 -> origin/testcommit122 + = [up to date] testcommit1220 -> origin/testcommit1220 + = [up to date] testcommit1221 -> origin/testcommit1221 + = [up to date] testcommit1222 -> origin/testcommit1222 + = [up to date] testcommit1223 -> origin/testcommit1223 + = [up to date] testcommit1224 -> origin/testcommit1224 + = [up to date] testcommit1225 -> origin/testcommit1225 + = [up to date] testcommit1226 -> origin/testcommit1226 + = [up to date] testcommit1227 -> origin/testcommit1227 + = [up to date] testcommit1228 -> origin/testcommit1228 + = [up to date] testcommit1229 -> origin/testcommit1229 + = [up to date] testcommit123 -> origin/testcommit123 + = [up to date] testcommit1230 -> origin/testcommit1230 + = [up to date] testcommit1231 -> origin/testcommit1231 + = [up to date] testcommit1232 -> origin/testcommit1232 + = [up to date] testcommit1233 -> origin/testcommit1233 + = [up to date] testcommit1234 -> origin/testcommit1234 + = [up to date] testcommit1235 -> origin/testcommit1235 + = [up to date] testcommit1236 -> origin/testcommit1236 + = [up to date] testcommit1237 -> origin/testcommit1237 + = [up to date] testcommit1238 -> origin/testcommit1238 + = [up to date] testcommit1239 -> origin/testcommit1239 + = [up to date] testcommit124 -> origin/testcommit124 + = [up to date] testcommit1240 -> origin/testcommit1240 + = [up to date] testcommit1241 -> origin/testcommit1241 + = [up to date] testcommit1242 -> origin/testcommit1242 + = [up to date] testcommit1243 -> origin/testcommit1243 + = [up to date] testcommit1244 -> origin/testcommit1244 + = [up to date] testcommit1245 -> origin/testcommit1245 + = [up to date] testcommit1246 -> origin/testcommit1246 + = [up to date] testcommit1247 -> origin/testcommit1247 + = [up to date] testcommit1248 -> origin/testcommit1248 + = [up to date] testcommit1249 -> origin/testcommit1249 + = [up to date] testcommit125 -> origin/testcommit125 + = [up to date] testcommit1250 -> origin/testcommit1250 + = [up to date] testcommit1251 -> origin/testcommit1251 + = [up to date] testcommit1252 -> origin/testcommit1252 + = [up to date] testcommit1253 -> origin/testcommit1253 + = [up to date] testcommit1254 -> origin/testcommit1254 + = [up to date] testcommit1255 -> origin/testcommit1255 + = [up to date] testcommit1256 -> origin/testcommit1256 + = [up to date] testcommit1257 -> origin/testcommit1257 + = [up to date] testcommit1258 -> origin/testcommit1258 + = [up to date] testcommit1259 -> origin/testcommit1259 + = [up to date] testcommit126 -> origin/testcommit126 + = [up to date] testcommit1260 -> origin/testcommit1260 + = [up to date] testcommit1261 -> origin/testcommit1261 + = [up to date] testcommit1262 -> origin/testcommit1262 + = [up to date] testcommit1263 -> origin/testcommit1263 + = [up to date] testcommit1264 -> origin/testcommit1264 + = [up to date] testcommit1265 -> origin/testcommit1265 + = [up to date] testcommit1266 -> origin/testcommit1266 + = [up to date] testcommit1267 -> origin/testcommit1267 + = [up to date] testcommit1268 -> origin/testcommit1268 + = [up to date] testcommit1269 -> origin/testcommit1269 + = [up to date] testcommit127 -> origin/testcommit127 + = [up to date] testcommit1270 -> origin/testcommit1270 + = [up to date] testcommit1271 -> origin/testcommit1271 + = [up to date] testcommit1272 -> origin/testcommit1272 + = [up to date] testcommit1273 -> origin/testcommit1273 + = [up to date] testcommit1274 -> origin/testcommit1274 + = [up to date] testcommit1275 -> origin/testcommit1275 + = [up to date] testcommit1276 -> origin/testcommit1276 + = [up to date] testcommit1277 -> origin/testcommit1277 + = [up to date] testcommit1278 -> origin/testcommit1278 + = [up to date] testcommit1279 -> origin/testcommit1279 + = [up to date] testcommit128 -> origin/testcommit128 + = [up to date] testcommit1280 -> origin/testcommit1280 + = [up to date] testcommit1281 -> origin/testcommit1281 + = [up to date] testcommit1282 -> origin/testcommit1282 + = [up to date] testcommit1283 -> origin/testcommit1283 + = [up to date] testcommit1284 -> origin/testcommit1284 + = [up to date] testcommit1285 -> origin/testcommit1285 + = [up to date] testcommit1286 -> origin/testcommit1286 + = [up to date] testcommit1287 -> origin/testcommit1287 + = [up to date] testcommit1288 -> origin/testcommit1288 + = [up to date] testcommit1289 -> origin/testcommit1289 + = [up to date] testcommit129 -> origin/testcommit129 + = [up to date] testcommit1290 -> origin/testcommit1290 + = [up to date] testcommit1291 -> origin/testcommit1291 + = [up to date] testcommit1292 -> origin/testcommit1292 + = [up to date] testcommit1293 -> origin/testcommit1293 + = [up to date] testcommit1294 -> origin/testcommit1294 + = [up to date] testcommit1295 -> origin/testcommit1295 + = [up to date] testcommit1296 -> origin/testcommit1296 + = [up to date] testcommit1297 -> origin/testcommit1297 + = [up to date] testcommit1298 -> origin/testcommit1298 + = [up to date] testcommit1299 -> origin/testcommit1299 + = [up to date] testcommit13 -> origin/testcommit13 + = [up to date] testcommit130 -> origin/testcommit130 + = [up to date] testcommit1300 -> origin/testcommit1300 + = [up to date] testcommit1301 -> origin/testcommit1301 + = [up to date] testcommit1302 -> origin/testcommit1302 + = [up to date] testcommit1303 -> origin/testcommit1303 + = [up to date] testcommit1304 -> origin/testcommit1304 + = [up to date] testcommit1305 -> origin/testcommit1305 + = [up to date] testcommit1306 -> origin/testcommit1306 + = [up to date] testcommit1307 -> origin/testcommit1307 + = [up to date] testcommit1308 -> origin/testcommit1308 + = [up to date] testcommit1309 -> origin/testcommit1309 + = [up to date] testcommit131 -> origin/testcommit131 + = [up to date] testcommit1310 -> origin/testcommit1310 + = [up to date] testcommit1311 -> origin/testcommit1311 + = [up to date] testcommit1312 -> origin/testcommit1312 + = [up to date] testcommit1313 -> origin/testcommit1313 + = [up to date] testcommit1314 -> origin/testcommit1314 + = [up to date] testcommit1315 -> origin/testcommit1315 + = [up to date] testcommit1316 -> origin/testcommit1316 + = [up to date] testcommit1317 -> origin/testcommit1317 + = [up to date] testcommit1318 -> origin/testcommit1318 + = [up to date] testcommit1319 -> origin/testcommit1319 + = [up to date] testcommit132 -> origin/testcommit132 + = [up to date] testcommit1320 -> origin/testcommit1320 + = [up to date] testcommit1321 -> origin/testcommit1321 + = [up to date] testcommit1322 -> origin/testcommit1322 + = [up to date] testcommit1323 -> origin/testcommit1323 + = [up to date] testcommit1324 -> origin/testcommit1324 + = [up to date] testcommit1325 -> origin/testcommit1325 + = [up to date] testcommit1326 -> origin/testcommit1326 + = [up to date] testcommit1327 -> origin/testcommit1327 + = [up to date] testcommit1328 -> origin/testcommit1328 + = [up to date] testcommit1329 -> origin/testcommit1329 + = [up to date] testcommit133 -> origin/testcommit133 + = [up to date] testcommit1330 -> origin/testcommit1330 + = [up to date] testcommit1331 -> origin/testcommit1331 + = [up to date] testcommit1332 -> origin/testcommit1332 + = [up to date] testcommit1333 -> origin/testcommit1333 + = [up to date] testcommit1334 -> origin/testcommit1334 + = [up to date] testcommit1335 -> origin/testcommit1335 + = [up to date] testcommit1336 -> origin/testcommit1336 + = [up to date] testcommit1337 -> origin/testcommit1337 + = [up to date] testcommit1338 -> origin/testcommit1338 + = [up to date] testcommit1339 -> origin/testcommit1339 + = [up to date] testcommit134 -> origin/testcommit134 + = [up to date] testcommit1340 -> origin/testcommit1340 + = [up to date] testcommit1341 -> origin/testcommit1341 + = [up to date] testcommit1342 -> origin/testcommit1342 + = [up to date] testcommit1343 -> origin/testcommit1343 + = [up to date] testcommit1344 -> origin/testcommit1344 + = [up to date] testcommit1345 -> origin/testcommit1345 + = [up to date] testcommit1346 -> origin/testcommit1346 + = [up to date] testcommit1347 -> origin/testcommit1347 + = [up to date] testcommit1348 -> origin/testcommit1348 + = [up to date] testcommit1349 -> origin/testcommit1349 + = [up to date] testcommit135 -> origin/testcommit135 + = [up to date] testcommit1350 -> origin/testcommit1350 + = [up to date] testcommit1351 -> origin/testcommit1351 + = [up to date] testcommit1352 -> origin/testcommit1352 + = [up to date] testcommit1353 -> origin/testcommit1353 + = [up to date] testcommit1354 -> origin/testcommit1354 + = [up to date] testcommit1355 -> origin/testcommit1355 + = [up to date] testcommit1356 -> origin/testcommit1356 + = [up to date] testcommit1357 -> origin/testcommit1357 + = [up to date] testcommit1358 -> origin/testcommit1358 + = [up to date] testcommit1359 -> origin/testcommit1359 + = [up to date] testcommit136 -> origin/testcommit136 + = [up to date] testcommit1360 -> origin/testcommit1360 + = [up to date] testcommit1361 -> origin/testcommit1361 + = [up to date] testcommit1362 -> origin/testcommit1362 + = [up to date] testcommit1363 -> origin/testcommit1363 + = [up to date] testcommit1364 -> origin/testcommit1364 + = [up to date] testcommit1365 -> origin/testcommit1365 + = [up to date] testcommit1366 -> origin/testcommit1366 + = [up to date] testcommit1367 -> origin/testcommit1367 + = [up to date] testcommit1368 -> origin/testcommit1368 + = [up to date] testcommit1369 -> origin/testcommit1369 + = [up to date] testcommit137 -> origin/testcommit137 + = [up to date] testcommit1370 -> origin/testcommit1370 + = [up to date] testcommit1371 -> origin/testcommit1371 + = [up to date] testcommit1372 -> origin/testcommit1372 + = [up to date] testcommit1373 -> origin/testcommit1373 + = [up to date] testcommit1374 -> origin/testcommit1374 + = [up to date] testcommit1375 -> origin/testcommit1375 + = [up to date] testcommit1376 -> origin/testcommit1376 + = [up to date] testcommit1377 -> origin/testcommit1377 + = [up to date] testcommit1378 -> origin/testcommit1378 + = [up to date] testcommit1379 -> origin/testcommit1379 + = [up to date] testcommit138 -> origin/testcommit138 + = [up to date] testcommit1380 -> origin/testcommit1380 + = [up to date] testcommit1381 -> origin/testcommit1381 + = [up to date] testcommit1382 -> origin/testcommit1382 + = [up to date] testcommit1383 -> origin/testcommit1383 + = [up to date] testcommit1384 -> origin/testcommit1384 + = [up to date] testcommit1385 -> origin/testcommit1385 + = [up to date] testcommit1386 -> origin/testcommit1386 + = [up to date] testcommit1387 -> origin/testcommit1387 + = [up to date] testcommit1388 -> origin/testcommit1388 + = [up to date] testcommit1389 -> origin/testcommit1389 + = [up to date] testcommit139 -> origin/testcommit139 + = [up to date] testcommit1390 -> origin/testcommit1390 + = [up to date] testcommit1391 -> origin/testcommit1391 + = [up to date] testcommit1392 -> origin/testcommit1392 + = [up to date] testcommit1393 -> origin/testcommit1393 + = [up to date] testcommit1394 -> origin/testcommit1394 + = [up to date] testcommit1395 -> origin/testcommit1395 + = [up to date] testcommit1396 -> origin/testcommit1396 + = [up to date] testcommit1397 -> origin/testcommit1397 + = [up to date] testcommit1398 -> origin/testcommit1398 + = [up to date] testcommit1399 -> origin/testcommit1399 + = [up to date] testcommit14 -> origin/testcommit14 + = [up to date] testcommit140 -> origin/testcommit140 + = [up to date] testcommit1400 -> origin/testcommit1400 + = [up to date] testcommit1401 -> origin/testcommit1401 + = [up to date] testcommit1402 -> origin/testcommit1402 + = [up to date] testcommit1403 -> origin/testcommit1403 + = [up to date] testcommit1404 -> origin/testcommit1404 + = [up to date] testcommit1405 -> origin/testcommit1405 + = [up to date] testcommit1406 -> origin/testcommit1406 + = [up to date] testcommit1407 -> origin/testcommit1407 + = [up to date] testcommit1408 -> origin/testcommit1408 + = [up to date] testcommit1409 -> origin/testcommit1409 + = [up to date] testcommit141 -> origin/testcommit141 + = [up to date] testcommit1410 -> origin/testcommit1410 + = [up to date] testcommit1411 -> origin/testcommit1411 + = [up to date] testcommit1412 -> origin/testcommit1412 + = [up to date] testcommit1413 -> origin/testcommit1413 + = [up to date] testcommit1414 -> origin/testcommit1414 + = [up to date] testcommit1415 -> origin/testcommit1415 + = [up to date] testcommit1416 -> origin/testcommit1416 + = [up to date] testcommit1417 -> origin/testcommit1417 + = [up to date] testcommit1418 -> origin/testcommit1418 + = [up to date] testcommit1419 -> origin/testcommit1419 + = [up to date] testcommit142 -> origin/testcommit142 + = [up to date] testcommit1420 -> origin/testcommit1420 + = [up to date] testcommit1421 -> origin/testcommit1421 + = [up to date] testcommit1422 -> origin/testcommit1422 + = [up to date] testcommit1423 -> origin/testcommit1423 + = [up to date] testcommit1424 -> origin/testcommit1424 + = [up to date] testcommit1425 -> origin/testcommit1425 + = [up to date] testcommit1426 -> origin/testcommit1426 + = [up to date] testcommit1427 -> origin/testcommit1427 + = [up to date] testcommit1428 -> origin/testcommit1428 + = [up to date] testcommit1429 -> origin/testcommit1429 + = [up to date] testcommit143 -> origin/testcommit143 + = [up to date] testcommit1430 -> origin/testcommit1430 + = [up to date] testcommit1431 -> origin/testcommit1431 + = [up to date] testcommit1432 -> origin/testcommit1432 + = [up to date] testcommit1433 -> origin/testcommit1433 + = [up to date] testcommit1434 -> origin/testcommit1434 + = [up to date] testcommit1435 -> origin/testcommit1435 + = [up to date] testcommit1436 -> origin/testcommit1436 + = [up to date] testcommit1437 -> origin/testcommit1437 + = [up to date] testcommit1438 -> origin/testcommit1438 + = [up to date] testcommit1439 -> origin/testcommit1439 + = [up to date] testcommit144 -> origin/testcommit144 + = [up to date] testcommit1440 -> origin/testcommit1440 + = [up to date] testcommit1441 -> origin/testcommit1441 + = [up to date] testcommit1442 -> origin/testcommit1442 + = [up to date] testcommit1443 -> origin/testcommit1443 + = [up to date] testcommit1444 -> origin/testcommit1444 + = [up to date] testcommit1445 -> origin/testcommit1445 + = [up to date] testcommit1446 -> origin/testcommit1446 + = [up to date] testcommit1447 -> origin/testcommit1447 + = [up to date] testcommit1448 -> origin/testcommit1448 + = [up to date] testcommit1449 -> origin/testcommit1449 + = [up to date] testcommit145 -> origin/testcommit145 + = [up to date] testcommit1450 -> origin/testcommit1450 + = [up to date] testcommit1451 -> origin/testcommit1451 + = [up to date] testcommit1452 -> origin/testcommit1452 + = [up to date] testcommit1453 -> origin/testcommit1453 + = [up to date] testcommit1454 -> origin/testcommit1454 + = [up to date] testcommit1455 -> origin/testcommit1455 + = [up to date] testcommit1456 -> origin/testcommit1456 + = [up to date] testcommit1457 -> origin/testcommit1457 + = [up to date] testcommit1458 -> origin/testcommit1458 + = [up to date] testcommit1459 -> origin/testcommit1459 + = [up to date] testcommit146 -> origin/testcommit146 + = [up to date] testcommit1460 -> origin/testcommit1460 + = [up to date] testcommit1461 -> origin/testcommit1461 + = [up to date] testcommit1462 -> origin/testcommit1462 + = [up to date] testcommit1463 -> origin/testcommit1463 + = [up to date] testcommit1464 -> origin/testcommit1464 + = [up to date] testcommit1465 -> origin/testcommit1465 + = [up to date] testcommit1466 -> origin/testcommit1466 + = [up to date] testcommit1467 -> origin/testcommit1467 + = [up to date] testcommit1468 -> origin/testcommit1468 + = [up to date] testcommit1469 -> origin/testcommit1469 + = [up to date] testcommit147 -> origin/testcommit147 + = [up to date] testcommit1470 -> origin/testcommit1470 + = [up to date] testcommit1471 -> origin/testcommit1471 + = [up to date] testcommit1472 -> origin/testcommit1472 + = [up to date] testcommit1473 -> origin/testcommit1473 + = [up to date] testcommit1474 -> origin/testcommit1474 + = [up to date] testcommit1475 -> origin/testcommit1475 + = [up to date] testcommit1476 -> origin/testcommit1476 + = [up to date] testcommit1477 -> origin/testcommit1477 + = [up to date] testcommit1478 -> origin/testcommit1478 + = [up to date] testcommit1479 -> origin/testcommit1479 + = [up to date] testcommit148 -> origin/testcommit148 + = [up to date] testcommit1480 -> origin/testcommit1480 + = [up to date] testcommit1481 -> origin/testcommit1481 + = [up to date] testcommit1482 -> origin/testcommit1482 + = [up to date] testcommit1483 -> origin/testcommit1483 + = [up to date] testcommit1484 -> origin/testcommit1484 + = [up to date] testcommit1485 -> origin/testcommit1485 + = [up to date] testcommit1486 -> origin/testcommit1486 + = [up to date] testcommit1487 -> origin/testcommit1487 + = [up to date] testcommit1488 -> origin/testcommit1488 + = [up to date] testcommit1489 -> origin/testcommit1489 + = [up to date] testcommit149 -> origin/testcommit149 + = [up to date] testcommit1490 -> origin/testcommit1490 + = [up to date] testcommit1491 -> origin/testcommit1491 + = [up to date] testcommit1492 -> origin/testcommit1492 + = [up to date] testcommit1493 -> origin/testcommit1493 + = [up to date] testcommit1494 -> origin/testcommit1494 + = [up to date] testcommit1495 -> origin/testcommit1495 + = [up to date] testcommit1496 -> origin/testcommit1496 + = [up to date] testcommit1497 -> origin/testcommit1497 + = [up to date] testcommit1498 -> origin/testcommit1498 + = [up to date] testcommit1499 -> origin/testcommit1499 + = [up to date] testcommit15 -> origin/testcommit15 + = [up to date] testcommit150 -> origin/testcommit150 + = [up to date] testcommit1500 -> origin/testcommit1500 + = [up to date] testcommit1501 -> origin/testcommit1501 + = [up to date] testcommit1502 -> origin/testcommit1502 + = [up to date] testcommit1503 -> origin/testcommit1503 + = [up to date] testcommit1504 -> origin/testcommit1504 + = [up to date] testcommit1505 -> origin/testcommit1505 + = [up to date] testcommit1506 -> origin/testcommit1506 + = [up to date] testcommit1507 -> origin/testcommit1507 + = [up to date] testcommit1508 -> origin/testcommit1508 + = [up to date] testcommit1509 -> origin/testcommit1509 + = [up to date] testcommit151 -> origin/testcommit151 + = [up to date] testcommit1510 -> origin/testcommit1510 + = [up to date] testcommit1511 -> origin/testcommit1511 + = [up to date] testcommit1512 -> origin/testcommit1512 + = [up to date] testcommit1513 -> origin/testcommit1513 + = [up to date] testcommit1514 -> origin/testcommit1514 + = [up to date] testcommit1515 -> origin/testcommit1515 + = [up to date] testcommit1516 -> origin/testcommit1516 + = [up to date] testcommit1517 -> origin/testcommit1517 + = [up to date] testcommit1518 -> origin/testcommit1518 + = [up to date] testcommit1519 -> origin/testcommit1519 + = [up to date] testcommit152 -> origin/testcommit152 + = [up to date] testcommit1520 -> origin/testcommit1520 + = [up to date] testcommit1521 -> origin/testcommit1521 + = [up to date] testcommit1522 -> origin/testcommit1522 + = [up to date] testcommit1523 -> origin/testcommit1523 + = [up to date] testcommit1524 -> origin/testcommit1524 + = [up to date] testcommit1525 -> origin/testcommit1525 + = [up to date] testcommit1526 -> origin/testcommit1526 + = [up to date] testcommit1527 -> origin/testcommit1527 + = [up to date] testcommit1528 -> origin/testcommit1528 + = [up to date] testcommit1529 -> origin/testcommit1529 + = [up to date] testcommit153 -> origin/testcommit153 + = [up to date] testcommit1530 -> origin/testcommit1530 + = [up to date] testcommit1531 -> origin/testcommit1531 + = [up to date] testcommit1532 -> origin/testcommit1532 + = [up to date] testcommit1533 -> origin/testcommit1533 + = [up to date] testcommit1534 -> origin/testcommit1534 + = [up to date] testcommit1535 -> origin/testcommit1535 + = [up to date] testcommit1536 -> origin/testcommit1536 + = [up to date] testcommit1537 -> origin/testcommit1537 + = [up to date] testcommit1538 -> origin/testcommit1538 + = [up to date] testcommit1539 -> origin/testcommit1539 + = [up to date] testcommit154 -> origin/testcommit154 + = [up to date] testcommit1540 -> origin/testcommit1540 + = [up to date] testcommit1541 -> origin/testcommit1541 + = [up to date] testcommit1542 -> origin/testcommit1542 + = [up to date] testcommit1543 -> origin/testcommit1543 + = [up to date] testcommit1544 -> origin/testcommit1544 + = [up to date] testcommit1545 -> origin/testcommit1545 + = [up to date] testcommit1546 -> origin/testcommit1546 + = [up to date] testcommit1547 -> origin/testcommit1547 + = [up to date] testcommit1548 -> origin/testcommit1548 + = [up to date] testcommit1549 -> origin/testcommit1549 + = [up to date] testcommit155 -> origin/testcommit155 + = [up to date] testcommit1550 -> origin/testcommit1550 + = [up to date] testcommit1551 -> origin/testcommit1551 + = [up to date] testcommit1552 -> origin/testcommit1552 + = [up to date] testcommit1553 -> origin/testcommit1553 + = [up to date] testcommit1554 -> origin/testcommit1554 + = [up to date] testcommit1555 -> origin/testcommit1555 + = [up to date] testcommit1556 -> origin/testcommit1556 + = [up to date] testcommit1557 -> origin/testcommit1557 + = [up to date] testcommit1558 -> origin/testcommit1558 + = [up to date] testcommit1559 -> origin/testcommit1559 + = [up to date] testcommit156 -> origin/testcommit156 + = [up to date] testcommit1560 -> origin/testcommit1560 + = [up to date] testcommit1561 -> origin/testcommit1561 + = [up to date] testcommit1562 -> origin/testcommit1562 + = [up to date] testcommit1563 -> origin/testcommit1563 + = [up to date] testcommit1564 -> origin/testcommit1564 + = [up to date] testcommit1565 -> origin/testcommit1565 + = [up to date] testcommit1566 -> origin/testcommit1566 + = [up to date] testcommit1567 -> origin/testcommit1567 + = [up to date] testcommit1568 -> origin/testcommit1568 + = [up to date] testcommit1569 -> origin/testcommit1569 + = [up to date] testcommit157 -> origin/testcommit157 + = [up to date] testcommit1570 -> origin/testcommit1570 + = [up to date] testcommit1571 -> origin/testcommit1571 + = [up to date] testcommit1572 -> origin/testcommit1572 + = [up to date] testcommit1573 -> origin/testcommit1573 + = [up to date] testcommit1574 -> origin/testcommit1574 + = [up to date] testcommit1575 -> origin/testcommit1575 + = [up to date] testcommit1576 -> origin/testcommit1576 + = [up to date] testcommit1577 -> origin/testcommit1577 + = [up to date] testcommit1578 -> origin/testcommit1578 + = [up to date] testcommit1579 -> origin/testcommit1579 + = [up to date] testcommit158 -> origin/testcommit158 + = [up to date] testcommit1580 -> origin/testcommit1580 + = [up to date] testcommit1581 -> origin/testcommit1581 + = [up to date] testcommit1582 -> origin/testcommit1582 + = [up to date] testcommit1583 -> origin/testcommit1583 + = [up to date] testcommit1584 -> origin/testcommit1584 + = [up to date] testcommit1585 -> origin/testcommit1585 + = [up to date] testcommit1586 -> origin/testcommit1586 + = [up to date] testcommit1587 -> origin/testcommit1587 + = [up to date] testcommit1588 -> origin/testcommit1588 + = [up to date] testcommit1589 -> origin/testcommit1589 + = [up to date] testcommit159 -> origin/testcommit159 + = [up to date] testcommit1590 -> origin/testcommit1590 + = [up to date] testcommit1591 -> origin/testcommit1591 + = [up to date] testcommit1592 -> origin/testcommit1592 + = [up to date] testcommit1593 -> origin/testcommit1593 + = [up to date] testcommit1594 -> origin/testcommit1594 + = [up to date] testcommit1595 -> origin/testcommit1595 + = [up to date] testcommit1596 -> origin/testcommit1596 + = [up to date] testcommit1597 -> origin/testcommit1597 + = [up to date] testcommit1598 -> origin/testcommit1598 + = [up to date] testcommit1599 -> origin/testcommit1599 + = [up to date] testcommit16 -> origin/testcommit16 + = [up to date] testcommit160 -> origin/testcommit160 + = [up to date] testcommit1600 -> origin/testcommit1600 + = [up to date] testcommit1601 -> origin/testcommit1601 + = [up to date] testcommit1602 -> origin/testcommit1602 + = [up to date] testcommit1603 -> origin/testcommit1603 + = [up to date] testcommit1604 -> origin/testcommit1604 + = [up to date] testcommit1605 -> origin/testcommit1605 + = [up to date] testcommit1606 -> origin/testcommit1606 + = [up to date] testcommit1607 -> origin/testcommit1607 + = [up to date] testcommit1608 -> origin/testcommit1608 + = [up to date] testcommit1609 -> origin/testcommit1609 + = [up to date] testcommit161 -> origin/testcommit161 + = [up to date] testcommit1610 -> origin/testcommit1610 + = [up to date] testcommit1611 -> origin/testcommit1611 + = [up to date] testcommit1612 -> origin/testcommit1612 + = [up to date] testcommit1613 -> origin/testcommit1613 + = [up to date] testcommit1614 -> origin/testcommit1614 + = [up to date] testcommit1615 -> origin/testcommit1615 + = [up to date] testcommit1616 -> origin/testcommit1616 + = [up to date] testcommit1617 -> origin/testcommit1617 + = [up to date] testcommit1618 -> origin/testcommit1618 + = [up to date] testcommit1619 -> origin/testcommit1619 + = [up to date] testcommit162 -> origin/testcommit162 + = [up to date] testcommit1620 -> origin/testcommit1620 + = [up to date] testcommit1621 -> origin/testcommit1621 + = [up to date] testcommit1622 -> origin/testcommit1622 + = [up to date] testcommit1623 -> origin/testcommit1623 + = [up to date] testcommit1624 -> origin/testcommit1624 + = [up to date] testcommit1625 -> origin/testcommit1625 + = [up to date] testcommit1626 -> origin/testcommit1626 + = [up to date] testcommit1627 -> origin/testcommit1627 + = [up to date] testcommit1628 -> origin/testcommit1628 + = [up to date] testcommit1629 -> origin/testcommit1629 + = [up to date] testcommit163 -> origin/testcommit163 + = [up to date] testcommit1630 -> origin/testcommit1630 + = [up to date] testcommit1631 -> origin/testcommit1631 + = [up to date] testcommit1632 -> origin/testcommit1632 + = [up to date] testcommit1633 -> origin/testcommit1633 + = [up to date] testcommit1634 -> origin/testcommit1634 + = [up to date] testcommit1635 -> origin/testcommit1635 + = [up to date] testcommit1636 -> origin/testcommit1636 + = [up to date] testcommit1637 -> origin/testcommit1637 + = [up to date] testcommit1638 -> origin/testcommit1638 + = [up to date] testcommit1639 -> origin/testcommit1639 + = [up to date] testcommit164 -> origin/testcommit164 + = [up to date] testcommit1640 -> origin/testcommit1640 + = [up to date] testcommit1641 -> origin/testcommit1641 + = [up to date] testcommit1642 -> origin/testcommit1642 + = [up to date] testcommit1643 -> origin/testcommit1643 + = [up to date] testcommit1644 -> origin/testcommit1644 + = [up to date] testcommit1645 -> origin/testcommit1645 + = [up to date] testcommit1646 -> origin/testcommit1646 + = [up to date] testcommit1647 -> origin/testcommit1647 + = [up to date] testcommit1648 -> origin/testcommit1648 + = [up to date] testcommit1649 -> origin/testcommit1649 + = [up to date] testcommit165 -> origin/testcommit165 + = [up to date] testcommit1650 -> origin/testcommit1650 + = [up to date] testcommit1651 -> origin/testcommit1651 + = [up to date] testcommit1652 -> origin/testcommit1652 + = [up to date] testcommit1653 -> origin/testcommit1653 + = [up to date] testcommit1654 -> origin/testcommit1654 + = [up to date] testcommit1655 -> origin/testcommit1655 + = [up to date] testcommit1656 -> origin/testcommit1656 + = [up to date] testcommit1657 -> origin/testcommit1657 + = [up to date] testcommit1658 -> origin/testcommit1658 + = [up to date] testcommit1659 -> origin/testcommit1659 + = [up to date] testcommit166 -> origin/testcommit166 + = [up to date] testcommit1660 -> origin/testcommit1660 + = [up to date] testcommit1661 -> origin/testcommit1661 + = [up to date] testcommit1662 -> origin/testcommit1662 + = [up to date] testcommit1663 -> origin/testcommit1663 + = [up to date] testcommit1664 -> origin/testcommit1664 + = [up to date] testcommit1665 -> origin/testcommit1665 + = [up to date] testcommit1666 -> origin/testcommit1666 + = [up to date] testcommit1667 -> origin/testcommit1667 + = [up to date] testcommit1668 -> origin/testcommit1668 + = [up to date] testcommit1669 -> origin/testcommit1669 + = [up to date] testcommit167 -> origin/testcommit167 + = [up to date] testcommit1670 -> origin/testcommit1670 + = [up to date] testcommit1671 -> origin/testcommit1671 + = [up to date] testcommit1672 -> origin/testcommit1672 + = [up to date] testcommit1673 -> origin/testcommit1673 + = [up to date] testcommit1674 -> origin/testcommit1674 + = [up to date] testcommit1675 -> origin/testcommit1675 + = [up to date] testcommit1676 -> origin/testcommit1676 + = [up to date] testcommit1677 -> origin/testcommit1677 + = [up to date] testcommit1678 -> origin/testcommit1678 + = [up to date] testcommit1679 -> origin/testcommit1679 + = [up to date] testcommit168 -> origin/testcommit168 + = [up to date] testcommit1680 -> origin/testcommit1680 + = [up to date] testcommit1681 -> origin/testcommit1681 + = [up to date] testcommit1682 -> origin/testcommit1682 + = [up to date] testcommit1683 -> origin/testcommit1683 + = [up to date] testcommit1684 -> origin/testcommit1684 + = [up to date] testcommit1685 -> origin/testcommit1685 + = [up to date] testcommit1686 -> origin/testcommit1686 + = [up to date] testcommit1687 -> origin/testcommit1687 + = [up to date] testcommit1688 -> origin/testcommit1688 + = [up to date] testcommit1689 -> origin/testcommit1689 + = [up to date] testcommit169 -> origin/testcommit169 + = [up to date] testcommit1690 -> origin/testcommit1690 + = [up to date] testcommit1691 -> origin/testcommit1691 + = [up to date] testcommit1692 -> origin/testcommit1692 + = [up to date] testcommit1693 -> origin/testcommit1693 + = [up to date] testcommit1694 -> origin/testcommit1694 + = [up to date] testcommit1695 -> origin/testcommit1695 + = [up to date] testcommit1696 -> origin/testcommit1696 + = [up to date] testcommit1697 -> origin/testcommit1697 + = [up to date] testcommit1698 -> origin/testcommit1698 + = [up to date] testcommit1699 -> origin/testcommit1699 + = [up to date] testcommit17 -> origin/testcommit17 + = [up to date] testcommit170 -> origin/testcommit170 + = [up to date] testcommit1700 -> origin/testcommit1700 + = [up to date] testcommit1701 -> origin/testcommit1701 + = [up to date] testcommit1702 -> origin/testcommit1702 + = [up to date] testcommit1703 -> origin/testcommit1703 + = [up to date] testcommit1704 -> origin/testcommit1704 + = [up to date] testcommit1705 -> origin/testcommit1705 + = [up to date] testcommit1706 -> origin/testcommit1706 + = [up to date] testcommit1707 -> origin/testcommit1707 + = [up to date] testcommit1708 -> origin/testcommit1708 + = [up to date] testcommit1709 -> origin/testcommit1709 + = [up to date] testcommit171 -> origin/testcommit171 + = [up to date] testcommit1710 -> origin/testcommit1710 + = [up to date] testcommit1711 -> origin/testcommit1711 + = [up to date] testcommit1712 -> origin/testcommit1712 + = [up to date] testcommit1713 -> origin/testcommit1713 + = [up to date] testcommit1714 -> origin/testcommit1714 + = [up to date] testcommit1715 -> origin/testcommit1715 + = [up to date] testcommit1716 -> origin/testcommit1716 + = [up to date] testcommit1717 -> origin/testcommit1717 + = [up to date] testcommit1718 -> origin/testcommit1718 + = [up to date] testcommit1719 -> origin/testcommit1719 + = [up to date] testcommit172 -> origin/testcommit172 + = [up to date] testcommit1720 -> origin/testcommit1720 + = [up to date] testcommit1721 -> origin/testcommit1721 + = [up to date] testcommit1722 -> origin/testcommit1722 + = [up to date] testcommit1723 -> origin/testcommit1723 + = [up to date] testcommit1724 -> origin/testcommit1724 + = [up to date] testcommit1725 -> origin/testcommit1725 + = [up to date] testcommit1726 -> origin/testcommit1726 + = [up to date] testcommit1727 -> origin/testcommit1727 + = [up to date] testcommit1728 -> origin/testcommit1728 + = [up to date] testcommit1729 -> origin/testcommit1729 + = [up to date] testcommit173 -> origin/testcommit173 + = [up to date] testcommit1730 -> origin/testcommit1730 + = [up to date] testcommit1731 -> origin/testcommit1731 + = [up to date] testcommit1732 -> origin/testcommit1732 + = [up to date] testcommit1733 -> origin/testcommit1733 + = [up to date] testcommit1734 -> origin/testcommit1734 + = [up to date] testcommit1735 -> origin/testcommit1735 + = [up to date] testcommit1736 -> origin/testcommit1736 + = [up to date] testcommit1737 -> origin/testcommit1737 + = [up to date] testcommit1738 -> origin/testcommit1738 + = [up to date] testcommit1739 -> origin/testcommit1739 + = [up to date] testcommit174 -> origin/testcommit174 + = [up to date] testcommit1740 -> origin/testcommit1740 + = [up to date] testcommit1741 -> origin/testcommit1741 + = [up to date] testcommit1742 -> origin/testcommit1742 + = [up to date] testcommit1743 -> origin/testcommit1743 + = [up to date] testcommit1744 -> origin/testcommit1744 + = [up to date] testcommit1745 -> origin/testcommit1745 + = [up to date] testcommit1746 -> origin/testcommit1746 + = [up to date] testcommit1747 -> origin/testcommit1747 + = [up to date] testcommit1748 -> origin/testcommit1748 + = [up to date] testcommit1749 -> origin/testcommit1749 + = [up to date] testcommit175 -> origin/testcommit175 + = [up to date] testcommit1750 -> origin/testcommit1750 + = [up to date] testcommit1751 -> origin/testcommit1751 + = [up to date] testcommit1752 -> origin/testcommit1752 + = [up to date] testcommit1753 -> origin/testcommit1753 + = [up to date] testcommit1754 -> origin/testcommit1754 + = [up to date] testcommit1755 -> origin/testcommit1755 + = [up to date] testcommit1756 -> origin/testcommit1756 + = [up to date] testcommit1757 -> origin/testcommit1757 + = [up to date] testcommit1758 -> origin/testcommit1758 + = [up to date] testcommit1759 -> origin/testcommit1759 + = [up to date] testcommit176 -> origin/testcommit176 + = [up to date] testcommit1760 -> origin/testcommit1760 + = [up to date] testcommit1761 -> origin/testcommit1761 + = [up to date] testcommit1762 -> origin/testcommit1762 + = [up to date] testcommit1763 -> origin/testcommit1763 + = [up to date] testcommit1764 -> origin/testcommit1764 + = [up to date] testcommit1765 -> origin/testcommit1765 + = [up to date] testcommit1766 -> origin/testcommit1766 + = [up to date] testcommit1767 -> origin/testcommit1767 + = [up to date] testcommit1768 -> origin/testcommit1768 + = [up to date] testcommit1769 -> origin/testcommit1769 + = [up to date] testcommit177 -> origin/testcommit177 + = [up to date] testcommit1770 -> origin/testcommit1770 + = [up to date] testcommit1771 -> origin/testcommit1771 + = [up to date] testcommit1772 -> origin/testcommit1772 + = [up to date] testcommit1773 -> origin/testcommit1773 + = [up to date] testcommit1774 -> origin/testcommit1774 + = [up to date] testcommit1775 -> origin/testcommit1775 + = [up to date] testcommit1776 -> origin/testcommit1776 + = [up to date] testcommit1777 -> origin/testcommit1777 + = [up to date] testcommit1778 -> origin/testcommit1778 + = [up to date] testcommit1779 -> origin/testcommit1779 + = [up to date] testcommit178 -> origin/testcommit178 + = [up to date] testcommit1780 -> origin/testcommit1780 + = [up to date] testcommit1781 -> origin/testcommit1781 + = [up to date] testcommit1782 -> origin/testcommit1782 + = [up to date] testcommit1783 -> origin/testcommit1783 + = [up to date] testcommit1784 -> origin/testcommit1784 + = [up to date] testcommit1785 -> origin/testcommit1785 + = [up to date] testcommit1786 -> origin/testcommit1786 + = [up to date] testcommit1787 -> origin/testcommit1787 + = [up to date] testcommit1788 -> origin/testcommit1788 + = [up to date] testcommit1789 -> origin/testcommit1789 + = [up to date] testcommit179 -> origin/testcommit179 + = [up to date] testcommit1790 -> origin/testcommit1790 + = [up to date] testcommit1791 -> origin/testcommit1791 + = [up to date] testcommit1792 -> origin/testcommit1792 + = [up to date] testcommit1793 -> origin/testcommit1793 + = [up to date] testcommit1794 -> origin/testcommit1794 + = [up to date] testcommit1795 -> origin/testcommit1795 + = [up to date] testcommit1796 -> origin/testcommit1796 + = [up to date] testcommit1797 -> origin/testcommit1797 + = [up to date] testcommit1798 -> origin/testcommit1798 + = [up to date] testcommit1799 -> origin/testcommit1799 + = [up to date] testcommit18 -> origin/testcommit18 + = [up to date] testcommit180 -> origin/testcommit180 + = [up to date] testcommit1800 -> origin/testcommit1800 + = [up to date] testcommit1801 -> origin/testcommit1801 + = [up to date] testcommit1802 -> origin/testcommit1802 + = [up to date] testcommit1803 -> origin/testcommit1803 + = [up to date] testcommit1804 -> origin/testcommit1804 + = [up to date] testcommit1805 -> origin/testcommit1805 + = [up to date] testcommit1806 -> origin/testcommit1806 + = [up to date] testcommit1807 -> origin/testcommit1807 + = [up to date] testcommit1808 -> origin/testcommit1808 + = [up to date] testcommit1809 -> origin/testcommit1809 + = [up to date] testcommit181 -> origin/testcommit181 + = [up to date] testcommit1810 -> origin/testcommit1810 + = [up to date] testcommit1811 -> origin/testcommit1811 + = [up to date] testcommit1812 -> origin/testcommit1812 + = [up to date] testcommit1813 -> origin/testcommit1813 + = [up to date] testcommit1814 -> origin/testcommit1814 + = [up to date] testcommit1815 -> origin/testcommit1815 + = [up to date] testcommit1816 -> origin/testcommit1816 + = [up to date] testcommit1817 -> origin/testcommit1817 + = [up to date] testcommit1818 -> origin/testcommit1818 + = [up to date] testcommit1819 -> origin/testcommit1819 + = [up to date] testcommit182 -> origin/testcommit182 + = [up to date] testcommit1820 -> origin/testcommit1820 + = [up to date] testcommit1821 -> origin/testcommit1821 + = [up to date] testcommit1822 -> origin/testcommit1822 + = [up to date] testcommit1823 -> origin/testcommit1823 + = [up to date] testcommit1824 -> origin/testcommit1824 + = [up to date] testcommit1825 -> origin/testcommit1825 + = [up to date] testcommit1826 -> origin/testcommit1826 + = [up to date] testcommit1827 -> origin/testcommit1827 + = [up to date] testcommit1828 -> origin/testcommit1828 + = [up to date] testcommit1829 -> origin/testcommit1829 + = [up to date] testcommit183 -> origin/testcommit183 + = [up to date] testcommit1830 -> origin/testcommit1830 + = [up to date] testcommit1831 -> origin/testcommit1831 + = [up to date] testcommit1832 -> origin/testcommit1832 + = [up to date] testcommit1833 -> origin/testcommit1833 + = [up to date] testcommit1834 -> origin/testcommit1834 + = [up to date] testcommit1835 -> origin/testcommit1835 + = [up to date] testcommit1836 -> origin/testcommit1836 + = [up to date] testcommit1837 -> origin/testcommit1837 + = [up to date] testcommit1838 -> origin/testcommit1838 + = [up to date] testcommit1839 -> origin/testcommit1839 + = [up to date] testcommit184 -> origin/testcommit184 + = [up to date] testcommit1840 -> origin/testcommit1840 + = [up to date] testcommit1841 -> origin/testcommit1841 + = [up to date] testcommit1842 -> origin/testcommit1842 + = [up to date] testcommit1843 -> origin/testcommit1843 + = [up to date] testcommit1844 -> origin/testcommit1844 + = [up to date] testcommit1845 -> origin/testcommit1845 + = [up to date] testcommit1846 -> origin/testcommit1846 + = [up to date] testcommit1847 -> origin/testcommit1847 + = [up to date] testcommit1848 -> origin/testcommit1848 + = [up to date] testcommit1849 -> origin/testcommit1849 + = [up to date] testcommit185 -> origin/testcommit185 + = [up to date] testcommit1850 -> origin/testcommit1850 + = [up to date] testcommit1851 -> origin/testcommit1851 + = [up to date] testcommit1852 -> origin/testcommit1852 + = [up to date] testcommit1853 -> origin/testcommit1853 + = [up to date] testcommit1854 -> origin/testcommit1854 + = [up to date] testcommit1855 -> origin/testcommit1855 + = [up to date] testcommit1856 -> origin/testcommit1856 + = [up to date] testcommit1857 -> origin/testcommit1857 + = [up to date] testcommit1858 -> origin/testcommit1858 + = [up to date] testcommit1859 -> origin/testcommit1859 + = [up to date] testcommit186 -> origin/testcommit186 + = [up to date] testcommit1860 -> origin/testcommit1860 + = [up to date] testcommit1861 -> origin/testcommit1861 + = [up to date] testcommit1862 -> origin/testcommit1862 + = [up to date] testcommit1863 -> origin/testcommit1863 + = [up to date] testcommit1864 -> origin/testcommit1864 + = [up to date] testcommit1865 -> origin/testcommit1865 + = [up to date] testcommit1866 -> origin/testcommit1866 + = [up to date] testcommit1867 -> origin/testcommit1867 + = [up to date] testcommit1868 -> origin/testcommit1868 + = [up to date] testcommit1869 -> origin/testcommit1869 + = [up to date] testcommit187 -> origin/testcommit187 + = [up to date] testcommit1870 -> origin/testcommit1870 + = [up to date] testcommit1871 -> origin/testcommit1871 + = [up to date] testcommit1872 -> origin/testcommit1872 + = [up to date] testcommit1873 -> origin/testcommit1873 + = [up to date] testcommit1874 -> origin/testcommit1874 + = [up to date] testcommit1875 -> origin/testcommit1875 + = [up to date] testcommit1876 -> origin/testcommit1876 + = [up to date] testcommit1877 -> origin/testcommit1877 + = [up to date] testcommit1878 -> origin/testcommit1878 + = [up to date] testcommit1879 -> origin/testcommit1879 + = [up to date] testcommit188 -> origin/testcommit188 + = [up to date] testcommit1880 -> origin/testcommit1880 + = [up to date] testcommit1881 -> origin/testcommit1881 + = [up to date] testcommit1882 -> origin/testcommit1882 + = [up to date] testcommit1883 -> origin/testcommit1883 + = [up to date] testcommit1884 -> origin/testcommit1884 + = [up to date] testcommit1885 -> origin/testcommit1885 + = [up to date] testcommit1886 -> origin/testcommit1886 + = [up to date] testcommit1887 -> origin/testcommit1887 + = [up to date] testcommit1888 -> origin/testcommit1888 + = [up to date] testcommit1889 -> origin/testcommit1889 + = [up to date] testcommit189 -> origin/testcommit189 + = [up to date] testcommit1890 -> origin/testcommit1890 + = [up to date] testcommit1891 -> origin/testcommit1891 + = [up to date] testcommit1892 -> origin/testcommit1892 + = [up to date] testcommit1893 -> origin/testcommit1893 + = [up to date] testcommit1894 -> origin/testcommit1894 + = [up to date] testcommit1895 -> origin/testcommit1895 + = [up to date] testcommit1896 -> origin/testcommit1896 + = [up to date] testcommit1897 -> origin/testcommit1897 + = [up to date] testcommit1898 -> origin/testcommit1898 + = [up to date] testcommit1899 -> origin/testcommit1899 + = [up to date] testcommit19 -> origin/testcommit19 + = [up to date] testcommit190 -> origin/testcommit190 + = [up to date] testcommit1900 -> origin/testcommit1900 + = [up to date] testcommit1901 -> origin/testcommit1901 + = [up to date] testcommit1902 -> origin/testcommit1902 + = [up to date] testcommit1903 -> origin/testcommit1903 + = [up to date] testcommit1904 -> origin/testcommit1904 + = [up to date] testcommit1905 -> origin/testcommit1905 + = [up to date] testcommit1906 -> origin/testcommit1906 + = [up to date] testcommit1907 -> origin/testcommit1907 + = [up to date] testcommit1908 -> origin/testcommit1908 + = [up to date] testcommit1909 -> origin/testcommit1909 + = [up to date] testcommit191 -> origin/testcommit191 + = [up to date] testcommit1910 -> origin/testcommit1910 + = [up to date] testcommit1911 -> origin/testcommit1911 + = [up to date] testcommit1912 -> origin/testcommit1912 + = [up to date] testcommit1913 -> origin/testcommit1913 + = [up to date] testcommit1914 -> origin/testcommit1914 + = [up to date] testcommit1915 -> origin/testcommit1915 + = [up to date] testcommit1916 -> origin/testcommit1916 + = [up to date] testcommit1917 -> origin/testcommit1917 + = [up to date] testcommit1918 -> origin/testcommit1918 + = [up to date] testcommit1919 -> origin/testcommit1919 + = [up to date] testcommit192 -> origin/testcommit192 + = [up to date] testcommit1920 -> origin/testcommit1920 + = [up to date] testcommit1921 -> origin/testcommit1921 + = [up to date] testcommit1922 -> origin/testcommit1922 + = [up to date] testcommit1923 -> origin/testcommit1923 + = [up to date] testcommit1924 -> origin/testcommit1924 + = [up to date] testcommit1925 -> origin/testcommit1925 + = [up to date] testcommit1926 -> origin/testcommit1926 + = [up to date] testcommit1927 -> origin/testcommit1927 + = [up to date] testcommit1928 -> origin/testcommit1928 + = [up to date] testcommit1929 -> origin/testcommit1929 + = [up to date] testcommit193 -> origin/testcommit193 + = [up to date] testcommit1930 -> origin/testcommit1930 + = [up to date] testcommit1931 -> origin/testcommit1931 + = [up to date] testcommit1932 -> origin/testcommit1932 + = [up to date] testcommit1933 -> origin/testcommit1933 + = [up to date] testcommit1934 -> origin/testcommit1934 + = [up to date] testcommit1935 -> origin/testcommit1935 + = [up to date] testcommit1936 -> origin/testcommit1936 + = [up to date] testcommit1937 -> origin/testcommit1937 + = [up to date] testcommit1938 -> origin/testcommit1938 + = [up to date] testcommit1939 -> origin/testcommit1939 + = [up to date] testcommit194 -> origin/testcommit194 + = [up to date] testcommit1940 -> origin/testcommit1940 + = [up to date] testcommit1941 -> origin/testcommit1941 + = [up to date] testcommit1942 -> origin/testcommit1942 + = [up to date] testcommit1943 -> origin/testcommit1943 + = [up to date] testcommit1944 -> origin/testcommit1944 + = [up to date] testcommit1945 -> origin/testcommit1945 + = [up to date] testcommit1946 -> origin/testcommit1946 + = [up to date] testcommit1947 -> origin/testcommit1947 + = [up to date] testcommit1948 -> origin/testcommit1948 + = [up to date] testcommit1949 -> origin/testcommit1949 + = [up to date] testcommit195 -> origin/testcommit195 + = [up to date] testcommit1950 -> origin/testcommit1950 + = [up to date] testcommit1951 -> origin/testcommit1951 + = [up to date] testcommit1952 -> origin/testcommit1952 + = [up to date] testcommit1953 -> origin/testcommit1953 + = [up to date] testcommit1954 -> origin/testcommit1954 + = [up to date] testcommit1955 -> origin/testcommit1955 + = [up to date] testcommit1956 -> origin/testcommit1956 + = [up to date] testcommit1957 -> origin/testcommit1957 + = [up to date] testcommit1958 -> origin/testcommit1958 + = [up to date] testcommit1959 -> origin/testcommit1959 + = [up to date] testcommit196 -> origin/testcommit196 + = [up to date] testcommit1960 -> origin/testcommit1960 + = [up to date] testcommit1961 -> origin/testcommit1961 + = [up to date] testcommit1962 -> origin/testcommit1962 + = [up to date] testcommit1963 -> origin/testcommit1963 + = [up to date] testcommit1964 -> origin/testcommit1964 + = [up to date] testcommit1965 -> origin/testcommit1965 + = [up to date] testcommit1966 -> origin/testcommit1966 + = [up to date] testcommit1967 -> origin/testcommit1967 + = [up to date] testcommit1968 -> origin/testcommit1968 + = [up to date] testcommit1969 -> origin/testcommit1969 + = [up to date] testcommit197 -> origin/testcommit197 + = [up to date] testcommit1970 -> origin/testcommit1970 + = [up to date] testcommit1971 -> origin/testcommit1971 + = [up to date] testcommit1972 -> origin/testcommit1972 + = [up to date] testcommit1973 -> origin/testcommit1973 + = [up to date] testcommit1974 -> origin/testcommit1974 + = [up to date] testcommit1975 -> origin/testcommit1975 + = [up to date] testcommit1976 -> origin/testcommit1976 + = [up to date] testcommit1977 -> origin/testcommit1977 + = [up to date] testcommit1978 -> origin/testcommit1978 + = [up to date] testcommit1979 -> origin/testcommit1979 + = [up to date] testcommit198 -> origin/testcommit198 + = [up to date] testcommit1980 -> origin/testcommit1980 + = [up to date] testcommit1981 -> origin/testcommit1981 + = [up to date] testcommit1982 -> origin/testcommit1982 + = [up to date] testcommit1983 -> origin/testcommit1983 + = [up to date] testcommit1984 -> origin/testcommit1984 + = [up to date] testcommit1985 -> origin/testcommit1985 + = [up to date] testcommit1986 -> origin/testcommit1986 + = [up to date] testcommit1987 -> origin/testcommit1987 + = [up to date] testcommit1988 -> origin/testcommit1988 + = [up to date] testcommit1989 -> origin/testcommit1989 + = [up to date] testcommit199 -> origin/testcommit199 + = [up to date] testcommit1990 -> origin/testcommit1990 + = [up to date] testcommit1991 -> origin/testcommit1991 + = [up to date] testcommit1992 -> origin/testcommit1992 + = [up to date] testcommit1993 -> origin/testcommit1993 + = [up to date] testcommit1994 -> origin/testcommit1994 + = [up to date] testcommit1995 -> origin/testcommit1995 + = [up to date] testcommit1996 -> origin/testcommit1996 + = [up to date] testcommit1997 -> origin/testcommit1997 + = [up to date] testcommit1998 -> origin/testcommit1998 + = [up to date] testcommit1999 -> origin/testcommit1999 + = [up to date] testcommit2 -> origin/testcommit2 + = [up to date] testcommit20 -> origin/testcommit20 + = [up to date] testcommit200 -> origin/testcommit200 + = [up to date] testcommit2000 -> origin/testcommit2000 + = [up to date] testcommit2001 -> origin/testcommit2001 + = [up to date] testcommit2002 -> origin/testcommit2002 + = [up to date] testcommit2003 -> origin/testcommit2003 + = [up to date] testcommit2004 -> origin/testcommit2004 + = [up to date] testcommit2005 -> origin/testcommit2005 + = [up to date] testcommit2006 -> origin/testcommit2006 + = [up to date] testcommit2007 -> origin/testcommit2007 + = [up to date] testcommit2008 -> origin/testcommit2008 + = [up to date] testcommit2009 -> origin/testcommit2009 + = [up to date] testcommit201 -> origin/testcommit201 + = [up to date] testcommit2010 -> origin/testcommit2010 + = [up to date] testcommit2011 -> origin/testcommit2011 + = [up to date] testcommit2012 -> origin/testcommit2012 + = [up to date] testcommit2013 -> origin/testcommit2013 + = [up to date] testcommit2014 -> origin/testcommit2014 + = [up to date] testcommit2015 -> origin/testcommit2015 + = [up to date] testcommit2016 -> origin/testcommit2016 + = [up to date] testcommit2017 -> origin/testcommit2017 + = [up to date] testcommit2018 -> origin/testcommit2018 + = [up to date] testcommit2019 -> origin/testcommit2019 + = [up to date] testcommit202 -> origin/testcommit202 + = [up to date] testcommit2020 -> origin/testcommit2020 + = [up to date] testcommit2021 -> origin/testcommit2021 + = [up to date] testcommit2022 -> origin/testcommit2022 + = [up to date] testcommit2023 -> origin/testcommit2023 + = [up to date] testcommit2024 -> origin/testcommit2024 + = [up to date] testcommit2025 -> origin/testcommit2025 + = [up to date] testcommit2026 -> origin/testcommit2026 + = [up to date] testcommit2027 -> origin/testcommit2027 + = [up to date] testcommit2028 -> origin/testcommit2028 + = [up to date] testcommit2029 -> origin/testcommit2029 + = [up to date] testcommit203 -> origin/testcommit203 + = [up to date] testcommit2030 -> origin/testcommit2030 + = [up to date] testcommit2031 -> origin/testcommit2031 + = [up to date] testcommit2032 -> origin/testcommit2032 + = [up to date] testcommit2033 -> origin/testcommit2033 + = [up to date] testcommit2034 -> origin/testcommit2034 + = [up to date] testcommit2035 -> origin/testcommit2035 + = [up to date] testcommit2036 -> origin/testcommit2036 + = [up to date] testcommit2037 -> origin/testcommit2037 + = [up to date] testcommit2038 -> origin/testcommit2038 + = [up to date] testcommit2039 -> origin/testcommit2039 + = [up to date] testcommit204 -> origin/testcommit204 + = [up to date] testcommit2040 -> origin/testcommit2040 + = [up to date] testcommit2041 -> origin/testcommit2041 + = [up to date] testcommit2042 -> origin/testcommit2042 + = [up to date] testcommit2043 -> origin/testcommit2043 + = [up to date] testcommit2044 -> origin/testcommit2044 + = [up to date] testcommit2045 -> origin/testcommit2045 + = [up to date] testcommit2046 -> origin/testcommit2046 + = [up to date] testcommit2047 -> origin/testcommit2047 + = [up to date] testcommit2048 -> origin/testcommit2048 + = [up to date] testcommit2049 -> origin/testcommit2049 + = [up to date] testcommit205 -> origin/testcommit205 + = [up to date] testcommit2050 -> origin/testcommit2050 + = [up to date] testcommit2051 -> origin/testcommit2051 + = [up to date] testcommit2052 -> origin/testcommit2052 + = [up to date] testcommit2053 -> origin/testcommit2053 + = [up to date] testcommit2054 -> origin/testcommit2054 + = [up to date] testcommit2055 -> origin/testcommit2055 + = [up to date] testcommit2056 -> origin/testcommit2056 + = [up to date] testcommit2057 -> origin/testcommit2057 + = [up to date] testcommit2058 -> origin/testcommit2058 + = [up to date] testcommit2059 -> origin/testcommit2059 + = [up to date] testcommit206 -> origin/testcommit206 + = [up to date] testcommit2060 -> origin/testcommit2060 + = [up to date] testcommit2061 -> origin/testcommit2061 + = [up to date] testcommit2062 -> origin/testcommit2062 + = [up to date] testcommit2063 -> origin/testcommit2063 + = [up to date] testcommit2064 -> origin/testcommit2064 + = [up to date] testcommit2065 -> origin/testcommit2065 + = [up to date] testcommit2066 -> origin/testcommit2066 + = [up to date] testcommit2067 -> origin/testcommit2067 + = [up to date] testcommit2068 -> origin/testcommit2068 + = [up to date] testcommit2069 -> origin/testcommit2069 + = [up to date] testcommit207 -> origin/testcommit207 + = [up to date] testcommit2070 -> origin/testcommit2070 + = [up to date] testcommit2071 -> origin/testcommit2071 + = [up to date] testcommit2072 -> origin/testcommit2072 + = [up to date] testcommit2073 -> origin/testcommit2073 + = [up to date] testcommit2074 -> origin/testcommit2074 + = [up to date] testcommit2075 -> origin/testcommit2075 + = [up to date] testcommit2076 -> origin/testcommit2076 + = [up to date] testcommit2077 -> origin/testcommit2077 + = [up to date] testcommit2078 -> origin/testcommit2078 + = [up to date] testcommit2079 -> origin/testcommit2079 + = [up to date] testcommit208 -> origin/testcommit208 + = [up to date] testcommit2080 -> origin/testcommit2080 + = [up to date] testcommit2081 -> origin/testcommit2081 + = [up to date] testcommit2082 -> origin/testcommit2082 + = [up to date] testcommit2083 -> origin/testcommit2083 + = [up to date] testcommit2084 -> origin/testcommit2084 + = [up to date] testcommit2085 -> origin/testcommit2085 + = [up to date] testcommit2086 -> origin/testcommit2086 + = [up to date] testcommit2087 -> origin/testcommit2087 + = [up to date] testcommit2088 -> origin/testcommit2088 + = [up to date] testcommit2089 -> origin/testcommit2089 + = [up to date] testcommit209 -> origin/testcommit209 + = [up to date] testcommit2090 -> origin/testcommit2090 + = [up to date] testcommit2091 -> origin/testcommit2091 + = [up to date] testcommit2092 -> origin/testcommit2092 + = [up to date] testcommit2093 -> origin/testcommit2093 + = [up to date] testcommit2094 -> origin/testcommit2094 + = [up to date] testcommit2095 -> origin/testcommit2095 + = [up to date] testcommit2096 -> origin/testcommit2096 + = [up to date] testcommit2097 -> origin/testcommit2097 + = [up to date] testcommit2098 -> origin/testcommit2098 + = [up to date] testcommit2099 -> origin/testcommit2099 + = [up to date] testcommit21 -> origin/testcommit21 + = [up to date] testcommit210 -> origin/testcommit210 + = [up to date] testcommit2100 -> origin/testcommit2100 + = [up to date] testcommit2101 -> origin/testcommit2101 + = [up to date] testcommit2102 -> origin/testcommit2102 + = [up to date] testcommit2103 -> origin/testcommit2103 + = [up to date] testcommit2104 -> origin/testcommit2104 + = [up to date] testcommit2105 -> origin/testcommit2105 + = [up to date] testcommit2106 -> origin/testcommit2106 + = [up to date] testcommit2107 -> origin/testcommit2107 + = [up to date] testcommit2108 -> origin/testcommit2108 + = [up to date] testcommit2109 -> origin/testcommit2109 + = [up to date] testcommit211 -> origin/testcommit211 + = [up to date] testcommit2110 -> origin/testcommit2110 + = [up to date] testcommit2111 -> origin/testcommit2111 + = [up to date] testcommit2112 -> origin/testcommit2112 + = [up to date] testcommit2113 -> origin/testcommit2113 + = [up to date] testcommit2114 -> origin/testcommit2114 + = [up to date] testcommit2115 -> origin/testcommit2115 + = [up to date] testcommit2116 -> origin/testcommit2116 + = [up to date] testcommit2117 -> origin/testcommit2117 + = [up to date] testcommit2118 -> origin/testcommit2118 + = [up to date] testcommit2119 -> origin/testcommit2119 + = [up to date] testcommit212 -> origin/testcommit212 + = [up to date] testcommit2120 -> origin/testcommit2120 + = [up to date] testcommit2121 -> origin/testcommit2121 + = [up to date] testcommit2122 -> origin/testcommit2122 + = [up to date] testcommit2123 -> origin/testcommit2123 + = [up to date] testcommit2124 -> origin/testcommit2124 + = [up to date] testcommit2125 -> origin/testcommit2125 + = [up to date] testcommit2126 -> origin/testcommit2126 + = [up to date] testcommit2127 -> origin/testcommit2127 + = [up to date] testcommit2128 -> origin/testcommit2128 + = [up to date] testcommit2129 -> origin/testcommit2129 + = [up to date] testcommit213 -> origin/testcommit213 + = [up to date] testcommit2130 -> origin/testcommit2130 + = [up to date] testcommit2131 -> origin/testcommit2131 + = [up to date] testcommit2132 -> origin/testcommit2132 + = [up to date] testcommit2133 -> origin/testcommit2133 + = [up to date] testcommit2134 -> origin/testcommit2134 + = [up to date] testcommit2135 -> origin/testcommit2135 + = [up to date] testcommit2136 -> origin/testcommit2136 + = [up to date] testcommit2137 -> origin/testcommit2137 + = [up to date] testcommit2138 -> origin/testcommit2138 + = [up to date] testcommit2139 -> origin/testcommit2139 + = [up to date] testcommit214 -> origin/testcommit214 + = [up to date] testcommit2140 -> origin/testcommit2140 + = [up to date] testcommit2141 -> origin/testcommit2141 + = [up to date] testcommit2142 -> origin/testcommit2142 + = [up to date] testcommit2143 -> origin/testcommit2143 + = [up to date] testcommit2144 -> origin/testcommit2144 + = [up to date] testcommit2145 -> origin/testcommit2145 + = [up to date] testcommit2146 -> origin/testcommit2146 + = [up to date] testcommit2147 -> origin/testcommit2147 + = [up to date] testcommit2148 -> origin/testcommit2148 + = [up to date] testcommit2149 -> origin/testcommit2149 + = [up to date] testcommit215 -> origin/testcommit215 + = [up to date] testcommit2150 -> origin/testcommit2150 + = [up to date] testcommit2151 -> origin/testcommit2151 + = [up to date] testcommit2152 -> origin/testcommit2152 + = [up to date] testcommit2153 -> origin/testcommit2153 + = [up to date] testcommit2154 -> origin/testcommit2154 + = [up to date] testcommit2155 -> origin/testcommit2155 + = [up to date] testcommit2156 -> origin/testcommit2156 + = [up to date] testcommit2157 -> origin/testcommit2157 + = [up to date] testcommit2158 -> origin/testcommit2158 + = [up to date] testcommit2159 -> origin/testcommit2159 + = [up to date] testcommit216 -> origin/testcommit216 + = [up to date] testcommit2160 -> origin/testcommit2160 + = [up to date] testcommit2161 -> origin/testcommit2161 + = [up to date] testcommit2162 -> origin/testcommit2162 + = [up to date] testcommit2163 -> origin/testcommit2163 + = [up to date] testcommit2164 -> origin/testcommit2164 + = [up to date] testcommit2165 -> origin/testcommit2165 + = [up to date] testcommit2166 -> origin/testcommit2166 + = [up to date] testcommit2167 -> origin/testcommit2167 + = [up to date] testcommit2168 -> origin/testcommit2168 + = [up to date] testcommit2169 -> origin/testcommit2169 + = [up to date] testcommit217 -> origin/testcommit217 + = [up to date] testcommit2170 -> origin/testcommit2170 + = [up to date] testcommit2171 -> origin/testcommit2171 + = [up to date] testcommit2172 -> origin/testcommit2172 + = [up to date] testcommit2173 -> origin/testcommit2173 + = [up to date] testcommit2174 -> origin/testcommit2174 + = [up to date] testcommit2175 -> origin/testcommit2175 + = [up to date] testcommit2176 -> origin/testcommit2176 + = [up to date] testcommit2177 -> origin/testcommit2177 + = [up to date] testcommit2178 -> origin/testcommit2178 + = [up to date] testcommit2179 -> origin/testcommit2179 + = [up to date] testcommit218 -> origin/testcommit218 + = [up to date] testcommit2180 -> origin/testcommit2180 + = [up to date] testcommit2181 -> origin/testcommit2181 + = [up to date] testcommit2182 -> origin/testcommit2182 + = [up to date] testcommit2183 -> origin/testcommit2183 + = [up to date] testcommit2184 -> origin/testcommit2184 + = [up to date] testcommit2185 -> origin/testcommit2185 + = [up to date] testcommit2186 -> origin/testcommit2186 + = [up to date] testcommit2187 -> origin/testcommit2187 + = [up to date] testcommit2188 -> origin/testcommit2188 + = [up to date] testcommit2189 -> origin/testcommit2189 + = [up to date] testcommit219 -> origin/testcommit219 + = [up to date] testcommit2190 -> origin/testcommit2190 + = [up to date] testcommit2191 -> origin/testcommit2191 + = [up to date] testcommit2192 -> origin/testcommit2192 + = [up to date] testcommit2193 -> origin/testcommit2193 + = [up to date] testcommit2194 -> origin/testcommit2194 + = [up to date] testcommit2195 -> origin/testcommit2195 + = [up to date] testcommit2196 -> origin/testcommit2196 + = [up to date] testcommit2197 -> origin/testcommit2197 + = [up to date] testcommit2198 -> origin/testcommit2198 + = [up to date] testcommit2199 -> origin/testcommit2199 + = [up to date] testcommit22 -> origin/testcommit22 + = [up to date] testcommit220 -> origin/testcommit220 + = [up to date] testcommit2200 -> origin/testcommit2200 + = [up to date] testcommit2201 -> origin/testcommit2201 + = [up to date] testcommit2202 -> origin/testcommit2202 + = [up to date] testcommit2203 -> origin/testcommit2203 + = [up to date] testcommit2204 -> origin/testcommit2204 + = [up to date] testcommit2205 -> origin/testcommit2205 + = [up to date] testcommit2206 -> origin/testcommit2206 + = [up to date] testcommit2207 -> origin/testcommit2207 + = [up to date] testcommit2208 -> origin/testcommit2208 + = [up to date] testcommit2209 -> origin/testcommit2209 + = [up to date] testcommit221 -> origin/testcommit221 + = [up to date] testcommit2210 -> origin/testcommit2210 + = [up to date] testcommit2211 -> origin/testcommit2211 + = [up to date] testcommit2212 -> origin/testcommit2212 + = [up to date] testcommit2213 -> origin/testcommit2213 + = [up to date] testcommit2214 -> origin/testcommit2214 + = [up to date] testcommit2215 -> origin/testcommit2215 + = [up to date] testcommit2216 -> origin/testcommit2216 + = [up to date] testcommit2217 -> origin/testcommit2217 + = [up to date] testcommit2218 -> origin/testcommit2218 + = [up to date] testcommit2219 -> origin/testcommit2219 + = [up to date] testcommit222 -> origin/testcommit222 + = [up to date] testcommit2220 -> origin/testcommit2220 + = [up to date] testcommit2221 -> origin/testcommit2221 + = [up to date] testcommit2222 -> origin/testcommit2222 + = [up to date] testcommit2223 -> origin/testcommit2223 + = [up to date] testcommit2224 -> origin/testcommit2224 + = [up to date] testcommit2225 -> origin/testcommit2225 + = [up to date] testcommit2226 -> origin/testcommit2226 + = [up to date] testcommit2227 -> origin/testcommit2227 + = [up to date] testcommit2228 -> origin/testcommit2228 + = [up to date] testcommit2229 -> origin/testcommit2229 + = [up to date] testcommit223 -> origin/testcommit223 + = [up to date] testcommit2230 -> origin/testcommit2230 + = [up to date] testcommit2231 -> origin/testcommit2231 + = [up to date] testcommit2232 -> origin/testcommit2232 + = [up to date] testcommit2233 -> origin/testcommit2233 + = [up to date] testcommit2234 -> origin/testcommit2234 + = [up to date] testcommit2235 -> origin/testcommit2235 + = [up to date] testcommit2236 -> origin/testcommit2236 + = [up to date] testcommit2237 -> origin/testcommit2237 + = [up to date] testcommit2238 -> origin/testcommit2238 + = [up to date] testcommit2239 -> origin/testcommit2239 + = [up to date] testcommit224 -> origin/testcommit224 + = [up to date] testcommit2240 -> origin/testcommit2240 + = [up to date] testcommit2241 -> origin/testcommit2241 + = [up to date] testcommit2242 -> origin/testcommit2242 + = [up to date] testcommit2243 -> origin/testcommit2243 + = [up to date] testcommit2244 -> origin/testcommit2244 + = [up to date] testcommit2245 -> origin/testcommit2245 + = [up to date] testcommit2246 -> origin/testcommit2246 + = [up to date] testcommit2247 -> origin/testcommit2247 + = [up to date] testcommit2248 -> origin/testcommit2248 + = [up to date] testcommit2249 -> origin/testcommit2249 + = [up to date] testcommit225 -> origin/testcommit225 + = [up to date] testcommit2250 -> origin/testcommit2250 + = [up to date] testcommit2251 -> origin/testcommit2251 + = [up to date] testcommit2252 -> origin/testcommit2252 + = [up to date] testcommit2253 -> origin/testcommit2253 + = [up to date] testcommit2254 -> origin/testcommit2254 + = [up to date] testcommit2255 -> origin/testcommit2255 + = [up to date] testcommit2256 -> origin/testcommit2256 + = [up to date] testcommit2257 -> origin/testcommit2257 + = [up to date] testcommit2258 -> origin/testcommit2258 + = [up to date] testcommit2259 -> origin/testcommit2259 + = [up to date] testcommit226 -> origin/testcommit226 + = [up to date] testcommit2260 -> origin/testcommit2260 + = [up to date] testcommit2261 -> origin/testcommit2261 + = [up to date] testcommit2262 -> origin/testcommit2262 + = [up to date] testcommit2263 -> origin/testcommit2263 + = [up to date] testcommit2264 -> origin/testcommit2264 + = [up to date] testcommit2265 -> origin/testcommit2265 + = [up to date] testcommit2266 -> origin/testcommit2266 + = [up to date] testcommit2267 -> origin/testcommit2267 + = [up to date] testcommit2268 -> origin/testcommit2268 + = [up to date] testcommit2269 -> origin/testcommit2269 + = [up to date] testcommit227 -> origin/testcommit227 + = [up to date] testcommit2270 -> origin/testcommit2270 + = [up to date] testcommit2271 -> origin/testcommit2271 + = [up to date] testcommit2272 -> origin/testcommit2272 + = [up to date] testcommit2273 -> origin/testcommit2273 + = [up to date] testcommit2274 -> origin/testcommit2274 + = [up to date] testcommit2275 -> origin/testcommit2275 + = [up to date] testcommit2276 -> origin/testcommit2276 + = [up to date] testcommit2277 -> origin/testcommit2277 + = [up to date] testcommit2278 -> origin/testcommit2278 + = [up to date] testcommit2279 -> origin/testcommit2279 + = [up to date] testcommit228 -> origin/testcommit228 + = [up to date] testcommit2280 -> origin/testcommit2280 + = [up to date] testcommit2281 -> origin/testcommit2281 + = [up to date] testcommit2282 -> origin/testcommit2282 + = [up to date] testcommit2283 -> origin/testcommit2283 + = [up to date] testcommit2284 -> origin/testcommit2284 + = [up to date] testcommit2285 -> origin/testcommit2285 + = [up to date] testcommit2286 -> origin/testcommit2286 + = [up to date] testcommit2287 -> origin/testcommit2287 + = [up to date] testcommit2288 -> origin/testcommit2288 + = [up to date] testcommit2289 -> origin/testcommit2289 + = [up to date] testcommit229 -> origin/testcommit229 + = [up to date] testcommit2290 -> origin/testcommit2290 + = [up to date] testcommit2291 -> origin/testcommit2291 + = [up to date] testcommit2292 -> origin/testcommit2292 + = [up to date] testcommit2293 -> origin/testcommit2293 + = [up to date] testcommit2294 -> origin/testcommit2294 + = [up to date] testcommit2295 -> origin/testcommit2295 + = [up to date] testcommit2296 -> origin/testcommit2296 + = [up to date] testcommit2297 -> origin/testcommit2297 + = [up to date] testcommit2298 -> origin/testcommit2298 + = [up to date] testcommit2299 -> origin/testcommit2299 + = [up to date] testcommit23 -> origin/testcommit23 + = [up to date] testcommit230 -> origin/testcommit230 + = [up to date] testcommit2300 -> origin/testcommit2300 + = [up to date] testcommit2301 -> origin/testcommit2301 + = [up to date] testcommit2302 -> origin/testcommit2302 + = [up to date] testcommit2303 -> origin/testcommit2303 + = [up to date] testcommit2304 -> origin/testcommit2304 + = [up to date] testcommit2305 -> origin/testcommit2305 + = [up to date] testcommit2306 -> origin/testcommit2306 + = [up to date] testcommit2307 -> origin/testcommit2307 + = [up to date] testcommit2308 -> origin/testcommit2308 + = [up to date] testcommit2309 -> origin/testcommit2309 + = [up to date] testcommit231 -> origin/testcommit231 + = [up to date] testcommit2310 -> origin/testcommit2310 + = [up to date] testcommit2311 -> origin/testcommit2311 + = [up to date] testcommit2312 -> origin/testcommit2312 + = [up to date] testcommit2313 -> origin/testcommit2313 + = [up to date] testcommit2314 -> origin/testcommit2314 + = [up to date] testcommit2315 -> origin/testcommit2315 + = [up to date] testcommit2316 -> origin/testcommit2316 + = [up to date] testcommit2317 -> origin/testcommit2317 + = [up to date] testcommit2318 -> origin/testcommit2318 + = [up to date] testcommit2319 -> origin/testcommit2319 + = [up to date] testcommit232 -> origin/testcommit232 + = [up to date] testcommit2320 -> origin/testcommit2320 + = [up to date] testcommit2321 -> origin/testcommit2321 + = [up to date] testcommit2322 -> origin/testcommit2322 + = [up to date] testcommit2323 -> origin/testcommit2323 + = [up to date] testcommit2324 -> origin/testcommit2324 + = [up to date] testcommit2325 -> origin/testcommit2325 + = [up to date] testcommit2326 -> origin/testcommit2326 + = [up to date] testcommit2327 -> origin/testcommit2327 + = [up to date] testcommit2328 -> origin/testcommit2328 + = [up to date] testcommit2329 -> origin/testcommit2329 + = [up to date] testcommit233 -> origin/testcommit233 + = [up to date] testcommit2330 -> origin/testcommit2330 + = [up to date] testcommit2331 -> origin/testcommit2331 + = [up to date] testcommit2332 -> origin/testcommit2332 + = [up to date] testcommit2333 -> origin/testcommit2333 + = [up to date] testcommit2334 -> origin/testcommit2334 + = [up to date] testcommit2335 -> origin/testcommit2335 + = [up to date] testcommit2336 -> origin/testcommit2336 + = [up to date] testcommit2337 -> origin/testcommit2337 + = [up to date] testcommit2338 -> origin/testcommit2338 + = [up to date] testcommit2339 -> origin/testcommit2339 + = [up to date] testcommit234 -> origin/testcommit234 + = [up to date] testcommit2340 -> origin/testcommit2340 + = [up to date] testcommit2341 -> origin/testcommit2341 + = [up to date] testcommit2342 -> origin/testcommit2342 + = [up to date] testcommit2343 -> origin/testcommit2343 + = [up to date] testcommit2344 -> origin/testcommit2344 + = [up to date] testcommit2345 -> origin/testcommit2345 + = [up to date] testcommit2346 -> origin/testcommit2346 + = [up to date] testcommit2347 -> origin/testcommit2347 + = [up to date] testcommit2348 -> origin/testcommit2348 + = [up to date] testcommit2349 -> origin/testcommit2349 + = [up to date] testcommit235 -> origin/testcommit235 + = [up to date] testcommit2350 -> origin/testcommit2350 + = [up to date] testcommit2351 -> origin/testcommit2351 + = [up to date] testcommit2352 -> origin/testcommit2352 + = [up to date] testcommit2353 -> origin/testcommit2353 + = [up to date] testcommit2354 -> origin/testcommit2354 + = [up to date] testcommit2355 -> origin/testcommit2355 + = [up to date] testcommit2356 -> origin/testcommit2356 + = [up to date] testcommit2357 -> origin/testcommit2357 + = [up to date] testcommit2358 -> origin/testcommit2358 + = [up to date] testcommit2359 -> origin/testcommit2359 + = [up to date] testcommit236 -> origin/testcommit236 + = [up to date] testcommit2360 -> origin/testcommit2360 + = [up to date] testcommit2361 -> origin/testcommit2361 + = [up to date] testcommit2362 -> origin/testcommit2362 + = [up to date] testcommit2363 -> origin/testcommit2363 + = [up to date] testcommit2364 -> origin/testcommit2364 + = [up to date] testcommit2365 -> origin/testcommit2365 + = [up to date] testcommit2366 -> origin/testcommit2366 + = [up to date] testcommit2367 -> origin/testcommit2367 + = [up to date] testcommit2368 -> origin/testcommit2368 + = [up to date] testcommit2369 -> origin/testcommit2369 + = [up to date] testcommit237 -> origin/testcommit237 + = [up to date] testcommit2370 -> origin/testcommit2370 + = [up to date] testcommit2371 -> origin/testcommit2371 + = [up to date] testcommit2372 -> origin/testcommit2372 + = [up to date] testcommit2373 -> origin/testcommit2373 + = [up to date] testcommit2374 -> origin/testcommit2374 + = [up to date] testcommit2375 -> origin/testcommit2375 + = [up to date] testcommit2376 -> origin/testcommit2376 + = [up to date] testcommit2377 -> origin/testcommit2377 + = [up to date] testcommit2378 -> origin/testcommit2378 + = [up to date] testcommit2379 -> origin/testcommit2379 + = [up to date] testcommit238 -> origin/testcommit238 + = [up to date] testcommit2380 -> origin/testcommit2380 + = [up to date] testcommit2381 -> origin/testcommit2381 + = [up to date] testcommit2382 -> origin/testcommit2382 + = [up to date] testcommit2383 -> origin/testcommit2383 + = [up to date] testcommit2384 -> origin/testcommit2384 + = [up to date] testcommit2385 -> origin/testcommit2385 + = [up to date] testcommit2386 -> origin/testcommit2386 + = [up to date] testcommit2387 -> origin/testcommit2387 + = [up to date] testcommit2388 -> origin/testcommit2388 + = [up to date] testcommit2389 -> origin/testcommit2389 + = [up to date] testcommit239 -> origin/testcommit239 + = [up to date] testcommit2390 -> origin/testcommit2390 + = [up to date] testcommit2391 -> origin/testcommit2391 + = [up to date] testcommit2392 -> origin/testcommit2392 + = [up to date] testcommit2393 -> origin/testcommit2393 + = [up to date] testcommit2394 -> origin/testcommit2394 + = [up to date] testcommit2395 -> origin/testcommit2395 + = [up to date] testcommit2396 -> origin/testcommit2396 + = [up to date] testcommit2397 -> origin/testcommit2397 + = [up to date] testcommit2398 -> origin/testcommit2398 + = [up to date] testcommit2399 -> origin/testcommit2399 + = [up to date] testcommit24 -> origin/testcommit24 + = [up to date] testcommit240 -> origin/testcommit240 + = [up to date] testcommit2400 -> origin/testcommit2400 + = [up to date] testcommit2401 -> origin/testcommit2401 + = [up to date] testcommit2402 -> origin/testcommit2402 + = [up to date] testcommit2403 -> origin/testcommit2403 + = [up to date] testcommit2404 -> origin/testcommit2404 + = [up to date] testcommit2405 -> origin/testcommit2405 + = [up to date] testcommit2406 -> origin/testcommit2406 + = [up to date] testcommit2407 -> origin/testcommit2407 + = [up to date] testcommit2408 -> origin/testcommit2408 + = [up to date] testcommit2409 -> origin/testcommit2409 + = [up to date] testcommit241 -> origin/testcommit241 + = [up to date] testcommit2410 -> origin/testcommit2410 + = [up to date] testcommit2411 -> origin/testcommit2411 + = [up to date] testcommit2412 -> origin/testcommit2412 + = [up to date] testcommit2413 -> origin/testcommit2413 + = [up to date] testcommit2414 -> origin/testcommit2414 + = [up to date] testcommit2415 -> origin/testcommit2415 + = [up to date] testcommit2416 -> origin/testcommit2416 + = [up to date] testcommit2417 -> origin/testcommit2417 + = [up to date] testcommit2418 -> origin/testcommit2418 + = [up to date] testcommit2419 -> origin/testcommit2419 + = [up to date] testcommit242 -> origin/testcommit242 + = [up to date] testcommit2420 -> origin/testcommit2420 + = [up to date] testcommit2421 -> origin/testcommit2421 + = [up to date] testcommit2422 -> origin/testcommit2422 + = [up to date] testcommit2423 -> origin/testcommit2423 + = [up to date] testcommit2424 -> origin/testcommit2424 + = [up to date] testcommit2425 -> origin/testcommit2425 + = [up to date] testcommit2426 -> origin/testcommit2426 + = [up to date] testcommit2427 -> origin/testcommit2427 + = [up to date] testcommit2428 -> origin/testcommit2428 + = [up to date] testcommit2429 -> origin/testcommit2429 + = [up to date] testcommit243 -> origin/testcommit243 + = [up to date] testcommit2430 -> origin/testcommit2430 + = [up to date] testcommit2431 -> origin/testcommit2431 + = [up to date] testcommit2432 -> origin/testcommit2432 + = [up to date] testcommit2433 -> origin/testcommit2433 + = [up to date] testcommit2434 -> origin/testcommit2434 + = [up to date] testcommit2435 -> origin/testcommit2435 + = [up to date] testcommit2436 -> origin/testcommit2436 + = [up to date] testcommit2437 -> origin/testcommit2437 + = [up to date] testcommit2438 -> origin/testcommit2438 + = [up to date] testcommit2439 -> origin/testcommit2439 + = [up to date] testcommit244 -> origin/testcommit244 + = [up to date] testcommit2440 -> origin/testcommit2440 + = [up to date] testcommit2441 -> origin/testcommit2441 + = [up to date] testcommit2442 -> origin/testcommit2442 + = [up to date] testcommit2443 -> origin/testcommit2443 + = [up to date] testcommit2444 -> origin/testcommit2444 + = [up to date] testcommit2445 -> origin/testcommit2445 + = [up to date] testcommit2446 -> origin/testcommit2446 + = [up to date] testcommit2447 -> origin/testcommit2447 + = [up to date] testcommit2448 -> origin/testcommit2448 + = [up to date] testcommit2449 -> origin/testcommit2449 + = [up to date] testcommit245 -> origin/testcommit245 + = [up to date] testcommit2450 -> origin/testcommit2450 + = [up to date] testcommit2451 -> origin/testcommit2451 + = [up to date] testcommit2452 -> origin/testcommit2452 + = [up to date] testcommit2453 -> origin/testcommit2453 + = [up to date] testcommit2454 -> origin/testcommit2454 + = [up to date] testcommit2455 -> origin/testcommit2455 + = [up to date] testcommit2456 -> origin/testcommit2456 + = [up to date] testcommit2457 -> origin/testcommit2457 + = [up to date] testcommit2458 -> origin/testcommit2458 + = [up to date] testcommit2459 -> origin/testcommit2459 + = [up to date] testcommit246 -> origin/testcommit246 + = [up to date] testcommit2460 -> origin/testcommit2460 + = [up to date] testcommit2461 -> origin/testcommit2461 + = [up to date] testcommit2462 -> origin/testcommit2462 + = [up to date] testcommit2463 -> origin/testcommit2463 + = [up to date] testcommit2464 -> origin/testcommit2464 + = [up to date] testcommit2465 -> origin/testcommit2465 + = [up to date] testcommit2466 -> origin/testcommit2466 + = [up to date] testcommit2467 -> origin/testcommit2467 + = [up to date] testcommit2468 -> origin/testcommit2468 + = [up to date] testcommit2469 -> origin/testcommit2469 + = [up to date] testcommit247 -> origin/testcommit247 + = [up to date] testcommit2470 -> origin/testcommit2470 + = [up to date] testcommit2471 -> origin/testcommit2471 + = [up to date] testcommit2472 -> origin/testcommit2472 + = [up to date] testcommit2473 -> origin/testcommit2473 + = [up to date] testcommit2474 -> origin/testcommit2474 + = [up to date] testcommit2475 -> origin/testcommit2475 + = [up to date] testcommit2476 -> origin/testcommit2476 + = [up to date] testcommit2477 -> origin/testcommit2477 + = [up to date] testcommit2478 -> origin/testcommit2478 + = [up to date] testcommit2479 -> origin/testcommit2479 + = [up to date] testcommit248 -> origin/testcommit248 + = [up to date] testcommit2480 -> origin/testcommit2480 + = [up to date] testcommit2481 -> origin/testcommit2481 + = [up to date] testcommit2482 -> origin/testcommit2482 + = [up to date] testcommit2483 -> origin/testcommit2483 + = [up to date] testcommit2484 -> origin/testcommit2484 + = [up to date] testcommit2485 -> origin/testcommit2485 + = [up to date] testcommit2486 -> origin/testcommit2486 + = [up to date] testcommit2487 -> origin/testcommit2487 + = [up to date] testcommit2488 -> origin/testcommit2488 + = [up to date] testcommit2489 -> origin/testcommit2489 + = [up to date] testcommit249 -> origin/testcommit249 + = [up to date] testcommit2490 -> origin/testcommit2490 + = [up to date] testcommit2491 -> origin/testcommit2491 + = [up to date] testcommit2492 -> origin/testcommit2492 + = [up to date] testcommit2493 -> origin/testcommit2493 + = [up to date] testcommit2494 -> origin/testcommit2494 + = [up to date] testcommit2495 -> origin/testcommit2495 + = [up to date] testcommit2496 -> origin/testcommit2496 + = [up to date] testcommit2497 -> origin/testcommit2497 + = [up to date] testcommit2498 -> origin/testcommit2498 + = [up to date] testcommit2499 -> origin/testcommit2499 + = [up to date] testcommit25 -> origin/testcommit25 + = [up to date] testcommit250 -> origin/testcommit250 + = [up to date] testcommit2500 -> origin/testcommit2500 + = [up to date] testcommit2501 -> origin/testcommit2501 + = [up to date] testcommit2502 -> origin/testcommit2502 + = [up to date] testcommit2503 -> origin/testcommit2503 + = [up to date] testcommit2504 -> origin/testcommit2504 + = [up to date] testcommit2505 -> origin/testcommit2505 + = [up to date] testcommit2506 -> origin/testcommit2506 + = [up to date] testcommit2507 -> origin/testcommit2507 + = [up to date] testcommit2508 -> origin/testcommit2508 + = [up to date] testcommit2509 -> origin/testcommit2509 + = [up to date] testcommit251 -> origin/testcommit251 + = [up to date] testcommit2510 -> origin/testcommit2510 + = [up to date] testcommit2511 -> origin/testcommit2511 + = [up to date] testcommit2512 -> origin/testcommit2512 + = [up to date] testcommit2513 -> origin/testcommit2513 + = [up to date] testcommit2514 -> origin/testcommit2514 + = [up to date] testcommit2515 -> origin/testcommit2515 + = [up to date] testcommit2516 -> origin/testcommit2516 + = [up to date] testcommit2517 -> origin/testcommit2517 + = [up to date] testcommit2518 -> origin/testcommit2518 + = [up to date] testcommit2519 -> origin/testcommit2519 + = [up to date] testcommit252 -> origin/testcommit252 + = [up to date] testcommit2520 -> origin/testcommit2520 + = [up to date] testcommit2521 -> origin/testcommit2521 + = [up to date] testcommit2522 -> origin/testcommit2522 + = [up to date] testcommit2523 -> origin/testcommit2523 + = [up to date] testcommit2524 -> origin/testcommit2524 + = [up to date] testcommit2525 -> origin/testcommit2525 + = [up to date] testcommit2526 -> origin/testcommit2526 + = [up to date] testcommit2527 -> origin/testcommit2527 + = [up to date] testcommit2528 -> origin/testcommit2528 + = [up to date] testcommit2529 -> origin/testcommit2529 + = [up to date] testcommit253 -> origin/testcommit253 + = [up to date] testcommit2530 -> origin/testcommit2530 + = [up to date] testcommit2531 -> origin/testcommit2531 + = [up to date] testcommit2532 -> origin/testcommit2532 + = [up to date] testcommit2533 -> origin/testcommit2533 + = [up to date] testcommit2534 -> origin/testcommit2534 + = [up to date] testcommit2535 -> origin/testcommit2535 + = [up to date] testcommit2536 -> origin/testcommit2536 + = [up to date] testcommit2537 -> origin/testcommit2537 + = [up to date] testcommit2538 -> origin/testcommit2538 + = [up to date] testcommit2539 -> origin/testcommit2539 + = [up to date] testcommit254 -> origin/testcommit254 + = [up to date] testcommit2540 -> origin/testcommit2540 + = [up to date] testcommit2541 -> origin/testcommit2541 + = [up to date] testcommit2542 -> origin/testcommit2542 + = [up to date] testcommit2543 -> origin/testcommit2543 + = [up to date] testcommit2544 -> origin/testcommit2544 + = [up to date] testcommit2545 -> origin/testcommit2545 + = [up to date] testcommit2546 -> origin/testcommit2546 + = [up to date] testcommit2547 -> origin/testcommit2547 + = [up to date] testcommit2548 -> origin/testcommit2548 + = [up to date] testcommit2549 -> origin/testcommit2549 + = [up to date] testcommit255 -> origin/testcommit255 + = [up to date] testcommit2550 -> origin/testcommit2550 + = [up to date] testcommit2551 -> origin/testcommit2551 + = [up to date] testcommit2552 -> origin/testcommit2552 + = [up to date] testcommit2553 -> origin/testcommit2553 + = [up to date] testcommit2554 -> origin/testcommit2554 + = [up to date] testcommit2555 -> origin/testcommit2555 + = [up to date] testcommit2556 -> origin/testcommit2556 + = [up to date] testcommit2557 -> origin/testcommit2557 + = [up to date] testcommit2558 -> origin/testcommit2558 + = [up to date] testcommit2559 -> origin/testcommit2559 + = [up to date] testcommit256 -> origin/testcommit256 + = [up to date] testcommit2560 -> origin/testcommit2560 + = [up to date] testcommit2561 -> origin/testcommit2561 + = [up to date] testcommit2562 -> origin/testcommit2562 + = [up to date] testcommit2563 -> origin/testcommit2563 + = [up to date] testcommit2564 -> origin/testcommit2564 + = [up to date] testcommit2565 -> origin/testcommit2565 + = [up to date] testcommit2566 -> origin/testcommit2566 + = [up to date] testcommit2567 -> origin/testcommit2567 + = [up to date] testcommit2568 -> origin/testcommit2568 + = [up to date] testcommit2569 -> origin/testcommit2569 + = [up to date] testcommit257 -> origin/testcommit257 + = [up to date] testcommit2570 -> origin/testcommit2570 + = [up to date] testcommit2571 -> origin/testcommit2571 + = [up to date] testcommit2572 -> origin/testcommit2572 + = [up to date] testcommit2573 -> origin/testcommit2573 + = [up to date] testcommit2574 -> origin/testcommit2574 + = [up to date] testcommit2575 -> origin/testcommit2575 + = [up to date] testcommit2576 -> origin/testcommit2576 + = [up to date] testcommit2577 -> origin/testcommit2577 + = [up to date] testcommit2578 -> origin/testcommit2578 + = [up to date] testcommit2579 -> origin/testcommit2579 + = [up to date] testcommit258 -> origin/testcommit258 + = [up to date] testcommit2580 -> origin/testcommit2580 + = [up to date] testcommit2581 -> origin/testcommit2581 + = [up to date] testcommit2582 -> origin/testcommit2582 + = [up to date] testcommit2583 -> origin/testcommit2583 + = [up to date] testcommit2584 -> origin/testcommit2584 + = [up to date] testcommit2585 -> origin/testcommit2585 + = [up to date] testcommit2586 -> origin/testcommit2586 + = [up to date] testcommit2587 -> origin/testcommit2587 + = [up to date] testcommit2588 -> origin/testcommit2588 + = [up to date] testcommit2589 -> origin/testcommit2589 + = [up to date] testcommit259 -> origin/testcommit259 + = [up to date] testcommit2590 -> origin/testcommit2590 + = [up to date] testcommit2591 -> origin/testcommit2591 + = [up to date] testcommit2592 -> origin/testcommit2592 + = [up to date] testcommit2593 -> origin/testcommit2593 + = [up to date] testcommit2594 -> origin/testcommit2594 + = [up to date] testcommit2595 -> origin/testcommit2595 + = [up to date] testcommit2596 -> origin/testcommit2596 + = [up to date] testcommit2597 -> origin/testcommit2597 + = [up to date] testcommit2598 -> origin/testcommit2598 + = [up to date] testcommit2599 -> origin/testcommit2599 + = [up to date] testcommit26 -> origin/testcommit26 + = [up to date] testcommit260 -> origin/testcommit260 + = [up to date] testcommit2600 -> origin/testcommit2600 + = [up to date] testcommit2601 -> origin/testcommit2601 + = [up to date] testcommit2602 -> origin/testcommit2602 + = [up to date] testcommit2603 -> origin/testcommit2603 + = [up to date] testcommit2604 -> origin/testcommit2604 + = [up to date] testcommit2605 -> origin/testcommit2605 + = [up to date] testcommit2606 -> origin/testcommit2606 + = [up to date] testcommit2607 -> origin/testcommit2607 + = [up to date] testcommit2608 -> origin/testcommit2608 + = [up to date] testcommit2609 -> origin/testcommit2609 + = [up to date] testcommit261 -> origin/testcommit261 + = [up to date] testcommit2610 -> origin/testcommit2610 + = [up to date] testcommit2611 -> origin/testcommit2611 + = [up to date] testcommit2612 -> origin/testcommit2612 + = [up to date] testcommit2613 -> origin/testcommit2613 + = [up to date] testcommit2614 -> origin/testcommit2614 + = [up to date] testcommit2615 -> origin/testcommit2615 + = [up to date] testcommit2616 -> origin/testcommit2616 + = [up to date] testcommit2617 -> origin/testcommit2617 + = [up to date] testcommit2618 -> origin/testcommit2618 + = [up to date] testcommit2619 -> origin/testcommit2619 + = [up to date] testcommit262 -> origin/testcommit262 + = [up to date] testcommit2620 -> origin/testcommit2620 + = [up to date] testcommit2621 -> origin/testcommit2621 + = [up to date] testcommit2622 -> origin/testcommit2622 + = [up to date] testcommit2623 -> origin/testcommit2623 + = [up to date] testcommit2624 -> origin/testcommit2624 + = [up to date] testcommit2625 -> origin/testcommit2625 + = [up to date] testcommit2626 -> origin/testcommit2626 + = [up to date] testcommit2627 -> origin/testcommit2627 + = [up to date] testcommit2628 -> origin/testcommit2628 + = [up to date] testcommit2629 -> origin/testcommit2629 + = [up to date] testcommit263 -> origin/testcommit263 + = [up to date] testcommit2630 -> origin/testcommit2630 + = [up to date] testcommit2631 -> origin/testcommit2631 + = [up to date] testcommit2632 -> origin/testcommit2632 + = [up to date] testcommit2633 -> origin/testcommit2633 + = [up to date] testcommit2634 -> origin/testcommit2634 + = [up to date] testcommit2635 -> origin/testcommit2635 + = [up to date] testcommit2636 -> origin/testcommit2636 + = [up to date] testcommit2637 -> origin/testcommit2637 + = [up to date] testcommit2638 -> origin/testcommit2638 + = [up to date] testcommit2639 -> origin/testcommit2639 + = [up to date] testcommit264 -> origin/testcommit264 + = [up to date] testcommit2640 -> origin/testcommit2640 + = [up to date] testcommit2641 -> origin/testcommit2641 + = [up to date] testcommit2642 -> origin/testcommit2642 + = [up to date] testcommit2643 -> origin/testcommit2643 + = [up to date] testcommit2644 -> origin/testcommit2644 + = [up to date] testcommit2645 -> origin/testcommit2645 + = [up to date] testcommit2646 -> origin/testcommit2646 + = [up to date] testcommit2647 -> origin/testcommit2647 + = [up to date] testcommit2648 -> origin/testcommit2648 + = [up to date] testcommit2649 -> origin/testcommit2649 + = [up to date] testcommit265 -> origin/testcommit265 + = [up to date] testcommit2650 -> origin/testcommit2650 + = [up to date] testcommit2651 -> origin/testcommit2651 + = [up to date] testcommit2652 -> origin/testcommit2652 + = [up to date] testcommit2653 -> origin/testcommit2653 + = [up to date] testcommit2654 -> origin/testcommit2654 + = [up to date] testcommit2655 -> origin/testcommit2655 + = [up to date] testcommit2656 -> origin/testcommit2656 + = [up to date] testcommit2657 -> origin/testcommit2657 + = [up to date] testcommit2658 -> origin/testcommit2658 + = [up to date] testcommit2659 -> origin/testcommit2659 + = [up to date] testcommit266 -> origin/testcommit266 + = [up to date] testcommit2660 -> origin/testcommit2660 + = [up to date] testcommit2661 -> origin/testcommit2661 + = [up to date] testcommit2662 -> origin/testcommit2662 + = [up to date] testcommit2663 -> origin/testcommit2663 + = [up to date] testcommit2664 -> origin/testcommit2664 + = [up to date] testcommit2665 -> origin/testcommit2665 + = [up to date] testcommit2666 -> origin/testcommit2666 + = [up to date] testcommit2667 -> origin/testcommit2667 + = [up to date] testcommit2668 -> origin/testcommit2668 + = [up to date] testcommit2669 -> origin/testcommit2669 + = [up to date] testcommit267 -> origin/testcommit267 + = [up to date] testcommit2670 -> origin/testcommit2670 + = [up to date] testcommit2671 -> origin/testcommit2671 + = [up to date] testcommit2672 -> origin/testcommit2672 + = [up to date] testcommit2673 -> origin/testcommit2673 + = [up to date] testcommit2674 -> origin/testcommit2674 + = [up to date] testcommit2675 -> origin/testcommit2675 + = [up to date] testcommit2676 -> origin/testcommit2676 + = [up to date] testcommit2677 -> origin/testcommit2677 + = [up to date] testcommit2678 -> origin/testcommit2678 + = [up to date] testcommit2679 -> origin/testcommit2679 + = [up to date] testcommit268 -> origin/testcommit268 + = [up to date] testcommit2680 -> origin/testcommit2680 + = [up to date] testcommit2681 -> origin/testcommit2681 + = [up to date] testcommit2682 -> origin/testcommit2682 + = [up to date] testcommit2683 -> origin/testcommit2683 + = [up to date] testcommit2684 -> origin/testcommit2684 + = [up to date] testcommit2685 -> origin/testcommit2685 + = [up to date] testcommit2686 -> origin/testcommit2686 + = [up to date] testcommit2687 -> origin/testcommit2687 + = [up to date] testcommit2688 -> origin/testcommit2688 + = [up to date] testcommit2689 -> origin/testcommit2689 + = [up to date] testcommit269 -> origin/testcommit269 + = [up to date] testcommit2690 -> origin/testcommit2690 + = [up to date] testcommit2691 -> origin/testcommit2691 + = [up to date] testcommit2692 -> origin/testcommit2692 + = [up to date] testcommit2693 -> origin/testcommit2693 + = [up to date] testcommit2694 -> origin/testcommit2694 + = [up to date] testcommit2695 -> origin/testcommit2695 + = [up to date] testcommit2696 -> origin/testcommit2696 + = [up to date] testcommit2697 -> origin/testcommit2697 + = [up to date] testcommit2698 -> origin/testcommit2698 + = [up to date] testcommit2699 -> origin/testcommit2699 + = [up to date] testcommit27 -> origin/testcommit27 + = [up to date] testcommit270 -> origin/testcommit270 + = [up to date] testcommit2700 -> origin/testcommit2700 + = [up to date] testcommit2701 -> origin/testcommit2701 + = [up to date] testcommit2702 -> origin/testcommit2702 + = [up to date] testcommit2703 -> origin/testcommit2703 + = [up to date] testcommit2704 -> origin/testcommit2704 + = [up to date] testcommit2705 -> origin/testcommit2705 + = [up to date] testcommit2706 -> origin/testcommit2706 + = [up to date] testcommit2707 -> origin/testcommit2707 + = [up to date] testcommit2708 -> origin/testcommit2708 + = [up to date] testcommit2709 -> origin/testcommit2709 + = [up to date] testcommit271 -> origin/testcommit271 + = [up to date] testcommit2710 -> origin/testcommit2710 + = [up to date] testcommit2711 -> origin/testcommit2711 + = [up to date] testcommit2712 -> origin/testcommit2712 + = [up to date] testcommit2713 -> origin/testcommit2713 + = [up to date] testcommit2714 -> origin/testcommit2714 + = [up to date] testcommit2715 -> origin/testcommit2715 + = [up to date] testcommit2716 -> origin/testcommit2716 + = [up to date] testcommit2717 -> origin/testcommit2717 + = [up to date] testcommit2718 -> origin/testcommit2718 + = [up to date] testcommit2719 -> origin/testcommit2719 + = [up to date] testcommit272 -> origin/testcommit272 + = [up to date] testcommit2720 -> origin/testcommit2720 + = [up to date] testcommit2721 -> origin/testcommit2721 + = [up to date] testcommit2722 -> origin/testcommit2722 + = [up to date] testcommit2723 -> origin/testcommit2723 + = [up to date] testcommit2724 -> origin/testcommit2724 + = [up to date] testcommit2725 -> origin/testcommit2725 + = [up to date] testcommit2726 -> origin/testcommit2726 + = [up to date] testcommit2727 -> origin/testcommit2727 + = [up to date] testcommit2728 -> origin/testcommit2728 + = [up to date] testcommit2729 -> origin/testcommit2729 + = [up to date] testcommit273 -> origin/testcommit273 + = [up to date] testcommit2730 -> origin/testcommit2730 + = [up to date] testcommit2731 -> origin/testcommit2731 + = [up to date] testcommit2732 -> origin/testcommit2732 + = [up to date] testcommit2733 -> origin/testcommit2733 + = [up to date] testcommit2734 -> origin/testcommit2734 + = [up to date] testcommit2735 -> origin/testcommit2735 + = [up to date] testcommit2736 -> origin/testcommit2736 + = [up to date] testcommit2737 -> origin/testcommit2737 + = [up to date] testcommit2738 -> origin/testcommit2738 + = [up to date] testcommit2739 -> origin/testcommit2739 + = [up to date] testcommit274 -> origin/testcommit274 + = [up to date] testcommit2740 -> origin/testcommit2740 + = [up to date] testcommit2741 -> origin/testcommit2741 + = [up to date] testcommit2742 -> origin/testcommit2742 + = [up to date] testcommit2743 -> origin/testcommit2743 + = [up to date] testcommit2744 -> origin/testcommit2744 + = [up to date] testcommit2745 -> origin/testcommit2745 + = [up to date] testcommit2746 -> origin/testcommit2746 + = [up to date] testcommit2747 -> origin/testcommit2747 + = [up to date] testcommit2748 -> origin/testcommit2748 + = [up to date] testcommit2749 -> origin/testcommit2749 + = [up to date] testcommit275 -> origin/testcommit275 + = [up to date] testcommit2750 -> origin/testcommit2750 + = [up to date] testcommit2751 -> origin/testcommit2751 + = [up to date] testcommit2752 -> origin/testcommit2752 + = [up to date] testcommit2753 -> origin/testcommit2753 + = [up to date] testcommit2754 -> origin/testcommit2754 + = [up to date] testcommit2755 -> origin/testcommit2755 + = [up to date] testcommit2756 -> origin/testcommit2756 + = [up to date] testcommit2757 -> origin/testcommit2757 + = [up to date] testcommit2758 -> origin/testcommit2758 + = [up to date] testcommit2759 -> origin/testcommit2759 + = [up to date] testcommit276 -> origin/testcommit276 + = [up to date] testcommit2760 -> origin/testcommit2760 + = [up to date] testcommit2761 -> origin/testcommit2761 + = [up to date] testcommit2762 -> origin/testcommit2762 + = [up to date] testcommit2763 -> origin/testcommit2763 + = [up to date] testcommit2764 -> origin/testcommit2764 + = [up to date] testcommit2765 -> origin/testcommit2765 + = [up to date] testcommit2766 -> origin/testcommit2766 + = [up to date] testcommit2767 -> origin/testcommit2767 + = [up to date] testcommit2768 -> origin/testcommit2768 + = [up to date] testcommit2769 -> origin/testcommit2769 + = [up to date] testcommit277 -> origin/testcommit277 + = [up to date] testcommit2770 -> origin/testcommit2770 + = [up to date] testcommit2771 -> origin/testcommit2771 + = [up to date] testcommit2772 -> origin/testcommit2772 + = [up to date] testcommit2773 -> origin/testcommit2773 + = [up to date] testcommit2774 -> origin/testcommit2774 + = [up to date] testcommit2775 -> origin/testcommit2775 + = [up to date] testcommit2776 -> origin/testcommit2776 + = [up to date] testcommit2777 -> origin/testcommit2777 + = [up to date] testcommit2778 -> origin/testcommit2778 + = [up to date] testcommit2779 -> origin/testcommit2779 + = [up to date] testcommit278 -> origin/testcommit278 + = [up to date] testcommit2780 -> origin/testcommit2780 + = [up to date] testcommit2781 -> origin/testcommit2781 + = [up to date] testcommit2782 -> origin/testcommit2782 + = [up to date] testcommit2783 -> origin/testcommit2783 + = [up to date] testcommit2784 -> origin/testcommit2784 + = [up to date] testcommit2785 -> origin/testcommit2785 + = [up to date] testcommit2786 -> origin/testcommit2786 + = [up to date] testcommit2787 -> origin/testcommit2787 + = [up to date] testcommit2788 -> origin/testcommit2788 + = [up to date] testcommit2789 -> origin/testcommit2789 + = [up to date] testcommit279 -> origin/testcommit279 + = [up to date] testcommit2790 -> origin/testcommit2790 + = [up to date] testcommit2791 -> origin/testcommit2791 + = [up to date] testcommit2792 -> origin/testcommit2792 + = [up to date] testcommit2793 -> origin/testcommit2793 + = [up to date] testcommit2794 -> origin/testcommit2794 + = [up to date] testcommit2795 -> origin/testcommit2795 + = [up to date] testcommit2796 -> origin/testcommit2796 + = [up to date] testcommit2797 -> origin/testcommit2797 + = [up to date] testcommit2798 -> origin/testcommit2798 + = [up to date] testcommit2799 -> origin/testcommit2799 + = [up to date] testcommit28 -> origin/testcommit28 + = [up to date] testcommit280 -> origin/testcommit280 + = [up to date] testcommit2800 -> origin/testcommit2800 + = [up to date] testcommit2801 -> origin/testcommit2801 + = [up to date] testcommit2802 -> origin/testcommit2802 + = [up to date] testcommit2803 -> origin/testcommit2803 + = [up to date] testcommit2804 -> origin/testcommit2804 + = [up to date] testcommit2805 -> origin/testcommit2805 + = [up to date] testcommit2806 -> origin/testcommit2806 + = [up to date] testcommit2807 -> origin/testcommit2807 + = [up to date] testcommit2808 -> origin/testcommit2808 + = [up to date] testcommit2809 -> origin/testcommit2809 + = [up to date] testcommit281 -> origin/testcommit281 + = [up to date] testcommit2810 -> origin/testcommit2810 + = [up to date] testcommit2811 -> origin/testcommit2811 + = [up to date] testcommit2812 -> origin/testcommit2812 + = [up to date] testcommit2813 -> origin/testcommit2813 + = [up to date] testcommit2814 -> origin/testcommit2814 + = [up to date] testcommit2815 -> origin/testcommit2815 + = [up to date] testcommit2816 -> origin/testcommit2816 + = [up to date] testcommit2817 -> origin/testcommit2817 + = [up to date] testcommit2818 -> origin/testcommit2818 + = [up to date] testcommit2819 -> origin/testcommit2819 + = [up to date] testcommit282 -> origin/testcommit282 + = [up to date] testcommit2820 -> origin/testcommit2820 + = [up to date] testcommit2821 -> origin/testcommit2821 + = [up to date] testcommit2822 -> origin/testcommit2822 + = [up to date] testcommit2823 -> origin/testcommit2823 + = [up to date] testcommit2824 -> origin/testcommit2824 + = [up to date] testcommit2825 -> origin/testcommit2825 + = [up to date] testcommit2826 -> origin/testcommit2826 + = [up to date] testcommit2827 -> origin/testcommit2827 + = [up to date] testcommit2828 -> origin/testcommit2828 + = [up to date] testcommit2829 -> origin/testcommit2829 + = [up to date] testcommit283 -> origin/testcommit283 + = [up to date] testcommit2830 -> origin/testcommit2830 + = [up to date] testcommit2831 -> origin/testcommit2831 + = [up to date] testcommit2832 -> origin/testcommit2832 + = [up to date] testcommit2833 -> origin/testcommit2833 + = [up to date] testcommit2834 -> origin/testcommit2834 + = [up to date] testcommit2835 -> origin/testcommit2835 + = [up to date] testcommit2836 -> origin/testcommit2836 + = [up to date] testcommit2837 -> origin/testcommit2837 + = [up to date] testcommit2838 -> origin/testcommit2838 + = [up to date] testcommit2839 -> origin/testcommit2839 + = [up to date] testcommit284 -> origin/testcommit284 + = [up to date] testcommit2840 -> origin/testcommit2840 + = [up to date] testcommit2841 -> origin/testcommit2841 + = [up to date] testcommit2842 -> origin/testcommit2842 + = [up to date] testcommit2843 -> origin/testcommit2843 + = [up to date] testcommit2844 -> origin/testcommit2844 + = [up to date] testcommit2845 -> origin/testcommit2845 + = [up to date] testcommit2846 -> origin/testcommit2846 + = [up to date] testcommit2847 -> origin/testcommit2847 + = [up to date] testcommit2848 -> origin/testcommit2848 + = [up to date] testcommit2849 -> origin/testcommit2849 + = [up to date] testcommit285 -> origin/testcommit285 + = [up to date] testcommit2850 -> origin/testcommit2850 + = [up to date] testcommit2851 -> origin/testcommit2851 + = [up to date] testcommit2852 -> origin/testcommit2852 + = [up to date] testcommit2853 -> origin/testcommit2853 + = [up to date] testcommit2854 -> origin/testcommit2854 + = [up to date] testcommit2855 -> origin/testcommit2855 + = [up to date] testcommit2856 -> origin/testcommit2856 + = [up to date] testcommit2857 -> origin/testcommit2857 + = [up to date] testcommit2858 -> origin/testcommit2858 + = [up to date] testcommit2859 -> origin/testcommit2859 + = [up to date] testcommit286 -> origin/testcommit286 + = [up to date] testcommit2860 -> origin/testcommit2860 + = [up to date] testcommit2861 -> origin/testcommit2861 + = [up to date] testcommit2862 -> origin/testcommit2862 + = [up to date] testcommit2863 -> origin/testcommit2863 + = [up to date] testcommit2864 -> origin/testcommit2864 + = [up to date] testcommit2865 -> origin/testcommit2865 + = [up to date] testcommit2866 -> origin/testcommit2866 + = [up to date] testcommit2867 -> origin/testcommit2867 + = [up to date] testcommit2868 -> origin/testcommit2868 + = [up to date] testcommit2869 -> origin/testcommit2869 + = [up to date] testcommit287 -> origin/testcommit287 + = [up to date] testcommit2870 -> origin/testcommit2870 + = [up to date] testcommit2871 -> origin/testcommit2871 + = [up to date] testcommit2872 -> origin/testcommit2872 + = [up to date] testcommit2873 -> origin/testcommit2873 + = [up to date] testcommit2874 -> origin/testcommit2874 + = [up to date] testcommit2875 -> origin/testcommit2875 + = [up to date] testcommit2876 -> origin/testcommit2876 + = [up to date] testcommit2877 -> origin/testcommit2877 + = [up to date] testcommit2878 -> origin/testcommit2878 + = [up to date] testcommit2879 -> origin/testcommit2879 + = [up to date] testcommit288 -> origin/testcommit288 + = [up to date] testcommit2880 -> origin/testcommit2880 + = [up to date] testcommit2881 -> origin/testcommit2881 + = [up to date] testcommit2882 -> origin/testcommit2882 + = [up to date] testcommit2883 -> origin/testcommit2883 + = [up to date] testcommit2884 -> origin/testcommit2884 + = [up to date] testcommit2885 -> origin/testcommit2885 + = [up to date] testcommit2886 -> origin/testcommit2886 + = [up to date] testcommit2887 -> origin/testcommit2887 + = [up to date] testcommit2888 -> origin/testcommit2888 + = [up to date] testcommit2889 -> origin/testcommit2889 + = [up to date] testcommit289 -> origin/testcommit289 + = [up to date] testcommit2890 -> origin/testcommit2890 + = [up to date] testcommit2891 -> origin/testcommit2891 + = [up to date] testcommit2892 -> origin/testcommit2892 + = [up to date] testcommit2893 -> origin/testcommit2893 + = [up to date] testcommit2894 -> origin/testcommit2894 + = [up to date] testcommit2895 -> origin/testcommit2895 + = [up to date] testcommit2896 -> origin/testcommit2896 + = [up to date] testcommit2897 -> origin/testcommit2897 + = [up to date] testcommit2898 -> origin/testcommit2898 + = [up to date] testcommit2899 -> origin/testcommit2899 + = [up to date] testcommit29 -> origin/testcommit29 + = [up to date] testcommit290 -> origin/testcommit290 + = [up to date] testcommit2900 -> origin/testcommit2900 + = [up to date] testcommit2901 -> origin/testcommit2901 + = [up to date] testcommit2902 -> origin/testcommit2902 + = [up to date] testcommit2903 -> origin/testcommit2903 + = [up to date] testcommit2904 -> origin/testcommit2904 + = [up to date] testcommit2905 -> origin/testcommit2905 + = [up to date] testcommit2906 -> origin/testcommit2906 + = [up to date] testcommit2907 -> origin/testcommit2907 + = [up to date] testcommit2908 -> origin/testcommit2908 + = [up to date] testcommit2909 -> origin/testcommit2909 + = [up to date] testcommit291 -> origin/testcommit291 + = [up to date] testcommit2910 -> origin/testcommit2910 + = [up to date] testcommit2911 -> origin/testcommit2911 + = [up to date] testcommit2912 -> origin/testcommit2912 + = [up to date] testcommit2913 -> origin/testcommit2913 + = [up to date] testcommit2914 -> origin/testcommit2914 + = [up to date] testcommit2915 -> origin/testcommit2915 + = [up to date] testcommit2916 -> origin/testcommit2916 + = [up to date] testcommit2917 -> origin/testcommit2917 + = [up to date] testcommit2918 -> origin/testcommit2918 + = [up to date] testcommit2919 -> origin/testcommit2919 + = [up to date] testcommit292 -> origin/testcommit292 + = [up to date] testcommit2920 -> origin/testcommit2920 + = [up to date] testcommit2921 -> origin/testcommit2921 + = [up to date] testcommit2922 -> origin/testcommit2922 + = [up to date] testcommit2923 -> origin/testcommit2923 + = [up to date] testcommit2924 -> origin/testcommit2924 + = [up to date] testcommit2925 -> origin/testcommit2925 + = [up to date] testcommit2926 -> origin/testcommit2926 + = [up to date] testcommit2927 -> origin/testcommit2927 + = [up to date] testcommit2928 -> origin/testcommit2928 + = [up to date] testcommit2929 -> origin/testcommit2929 + = [up to date] testcommit293 -> origin/testcommit293 + = [up to date] testcommit2930 -> origin/testcommit2930 + = [up to date] testcommit2931 -> origin/testcommit2931 + = [up to date] testcommit2932 -> origin/testcommit2932 + = [up to date] testcommit2933 -> origin/testcommit2933 + = [up to date] testcommit2934 -> origin/testcommit2934 + = [up to date] testcommit2935 -> origin/testcommit2935 + = [up to date] testcommit2936 -> origin/testcommit2936 + = [up to date] testcommit2937 -> origin/testcommit2937 + = [up to date] testcommit2938 -> origin/testcommit2938 + = [up to date] testcommit2939 -> origin/testcommit2939 + = [up to date] testcommit294 -> origin/testcommit294 + = [up to date] testcommit2940 -> origin/testcommit2940 + = [up to date] testcommit2941 -> origin/testcommit2941 + = [up to date] testcommit2942 -> origin/testcommit2942 + = [up to date] testcommit2943 -> origin/testcommit2943 + = [up to date] testcommit2944 -> origin/testcommit2944 + = [up to date] testcommit2945 -> origin/testcommit2945 + = [up to date] testcommit2946 -> origin/testcommit2946 + = [up to date] testcommit2947 -> origin/testcommit2947 + = [up to date] testcommit2948 -> origin/testcommit2948 + = [up to date] testcommit2949 -> origin/testcommit2949 + = [up to date] testcommit295 -> origin/testcommit295 + = [up to date] testcommit2950 -> origin/testcommit2950 + = [up to date] testcommit2951 -> origin/testcommit2951 + = [up to date] testcommit2952 -> origin/testcommit2952 + = [up to date] testcommit2953 -> origin/testcommit2953 + = [up to date] testcommit2954 -> origin/testcommit2954 + = [up to date] testcommit2955 -> origin/testcommit2955 + = [up to date] testcommit2956 -> origin/testcommit2956 + = [up to date] testcommit2957 -> origin/testcommit2957 + = [up to date] testcommit2958 -> origin/testcommit2958 + = [up to date] testcommit2959 -> origin/testcommit2959 + = [up to date] testcommit296 -> origin/testcommit296 + = [up to date] testcommit2960 -> origin/testcommit2960 + = [up to date] testcommit2961 -> origin/testcommit2961 + = [up to date] testcommit2962 -> origin/testcommit2962 + = [up to date] testcommit2963 -> origin/testcommit2963 + = [up to date] testcommit2964 -> origin/testcommit2964 + = [up to date] testcommit2965 -> origin/testcommit2965 + = [up to date] testcommit2966 -> origin/testcommit2966 + = [up to date] testcommit2967 -> origin/testcommit2967 + = [up to date] testcommit2968 -> origin/testcommit2968 + = [up to date] testcommit2969 -> origin/testcommit2969 + = [up to date] testcommit297 -> origin/testcommit297 + = [up to date] testcommit2970 -> origin/testcommit2970 + = [up to date] testcommit2971 -> origin/testcommit2971 + = [up to date] testcommit2972 -> origin/testcommit2972 + = [up to date] testcommit2973 -> origin/testcommit2973 + = [up to date] testcommit2974 -> origin/testcommit2974 + = [up to date] testcommit2975 -> origin/testcommit2975 + = [up to date] testcommit2976 -> origin/testcommit2976 + = [up to date] testcommit2977 -> origin/testcommit2977 + = [up to date] testcommit2978 -> origin/testcommit2978 + = [up to date] testcommit2979 -> origin/testcommit2979 + = [up to date] testcommit298 -> origin/testcommit298 + = [up to date] testcommit2980 -> origin/testcommit2980 + = [up to date] testcommit2981 -> origin/testcommit2981 + = [up to date] testcommit2982 -> origin/testcommit2982 + = [up to date] testcommit2983 -> origin/testcommit2983 + = [up to date] testcommit2984 -> origin/testcommit2984 + = [up to date] testcommit2985 -> origin/testcommit2985 + = [up to date] testcommit2986 -> origin/testcommit2986 + = [up to date] testcommit2987 -> origin/testcommit2987 + = [up to date] testcommit2988 -> origin/testcommit2988 + = [up to date] testcommit2989 -> origin/testcommit2989 + = [up to date] testcommit299 -> origin/testcommit299 + = [up to date] testcommit2990 -> origin/testcommit2990 + = [up to date] testcommit2991 -> origin/testcommit2991 + = [up to date] testcommit2992 -> origin/testcommit2992 + = [up to date] testcommit2993 -> origin/testcommit2993 + = [up to date] testcommit2994 -> origin/testcommit2994 + = [up to date] testcommit2995 -> origin/testcommit2995 + = [up to date] testcommit2996 -> origin/testcommit2996 + = [up to date] testcommit2997 -> origin/testcommit2997 + = [up to date] testcommit2998 -> origin/testcommit2998 + = [up to date] testcommit2999 -> origin/testcommit2999 + = [up to date] testcommit3 -> origin/testcommit3 + = [up to date] testcommit30 -> origin/testcommit30 + = [up to date] testcommit300 -> origin/testcommit300 + = [up to date] testcommit3000 -> origin/testcommit3000 + = [up to date] testcommit3001 -> origin/testcommit3001 + = [up to date] testcommit3002 -> origin/testcommit3002 + = [up to date] testcommit3003 -> origin/testcommit3003 + = [up to date] testcommit3004 -> origin/testcommit3004 + = [up to date] testcommit3005 -> origin/testcommit3005 + = [up to date] testcommit3006 -> origin/testcommit3006 + = [up to date] testcommit3007 -> origin/testcommit3007 + = [up to date] testcommit3008 -> origin/testcommit3008 + = [up to date] testcommit3009 -> origin/testcommit3009 + = [up to date] testcommit301 -> origin/testcommit301 + = [up to date] testcommit3010 -> origin/testcommit3010 + = [up to date] testcommit3011 -> origin/testcommit3011 + = [up to date] testcommit3012 -> origin/testcommit3012 + = [up to date] testcommit3013 -> origin/testcommit3013 + = [up to date] testcommit3014 -> origin/testcommit3014 + = [up to date] testcommit3015 -> origin/testcommit3015 + = [up to date] testcommit3016 -> origin/testcommit3016 + = [up to date] testcommit3017 -> origin/testcommit3017 + = [up to date] testcommit3018 -> origin/testcommit3018 + = [up to date] testcommit3019 -> origin/testcommit3019 + = [up to date] testcommit302 -> origin/testcommit302 + = [up to date] testcommit3020 -> origin/testcommit3020 + = [up to date] testcommit3021 -> origin/testcommit3021 + = [up to date] testcommit3022 -> origin/testcommit3022 + = [up to date] testcommit3023 -> origin/testcommit3023 + = [up to date] testcommit3024 -> origin/testcommit3024 + = [up to date] testcommit3025 -> origin/testcommit3025 + = [up to date] testcommit3026 -> origin/testcommit3026 + = [up to date] testcommit3027 -> origin/testcommit3027 + = [up to date] testcommit3028 -> origin/testcommit3028 + = [up to date] testcommit3029 -> origin/testcommit3029 + = [up to date] testcommit303 -> origin/testcommit303 + = [up to date] testcommit3030 -> origin/testcommit3030 + = [up to date] testcommit3031 -> origin/testcommit3031 + = [up to date] testcommit3032 -> origin/testcommit3032 + = [up to date] testcommit3033 -> origin/testcommit3033 + = [up to date] testcommit3034 -> origin/testcommit3034 + = [up to date] testcommit3035 -> origin/testcommit3035 + = [up to date] testcommit3036 -> origin/testcommit3036 + = [up to date] testcommit3037 -> origin/testcommit3037 + = [up to date] testcommit3038 -> origin/testcommit3038 + = [up to date] testcommit3039 -> origin/testcommit3039 + = [up to date] testcommit304 -> origin/testcommit304 + = [up to date] testcommit3040 -> origin/testcommit3040 + = [up to date] testcommit3041 -> origin/testcommit3041 + = [up to date] testcommit3042 -> origin/testcommit3042 + = [up to date] testcommit3043 -> origin/testcommit3043 + = [up to date] testcommit3044 -> origin/testcommit3044 + = [up to date] testcommit3045 -> origin/testcommit3045 + = [up to date] testcommit3046 -> origin/testcommit3046 + = [up to date] testcommit3047 -> origin/testcommit3047 + = [up to date] testcommit3048 -> origin/testcommit3048 + = [up to date] testcommit3049 -> origin/testcommit3049 + = [up to date] testcommit305 -> origin/testcommit305 + = [up to date] testcommit3050 -> origin/testcommit3050 + = [up to date] testcommit3051 -> origin/testcommit3051 + = [up to date] testcommit3052 -> origin/testcommit3052 + = [up to date] testcommit3053 -> origin/testcommit3053 + = [up to date] testcommit3054 -> origin/testcommit3054 + = [up to date] testcommit3055 -> origin/testcommit3055 + = [up to date] testcommit3056 -> origin/testcommit3056 + = [up to date] testcommit3057 -> origin/testcommit3057 + = [up to date] testcommit3058 -> origin/testcommit3058 + = [up to date] testcommit3059 -> origin/testcommit3059 + = [up to date] testcommit306 -> origin/testcommit306 + = [up to date] testcommit3060 -> origin/testcommit3060 + = [up to date] testcommit3061 -> origin/testcommit3061 + = [up to date] testcommit3062 -> origin/testcommit3062 + = [up to date] testcommit3063 -> origin/testcommit3063 + = [up to date] testcommit3064 -> origin/testcommit3064 + = [up to date] testcommit3065 -> origin/testcommit3065 + = [up to date] testcommit3066 -> origin/testcommit3066 + = [up to date] testcommit3067 -> origin/testcommit3067 + = [up to date] testcommit3068 -> origin/testcommit3068 + = [up to date] testcommit3069 -> origin/testcommit3069 + = [up to date] testcommit307 -> origin/testcommit307 + = [up to date] testcommit3070 -> origin/testcommit3070 + = [up to date] testcommit3071 -> origin/testcommit3071 + = [up to date] testcommit3072 -> origin/testcommit3072 + = [up to date] testcommit3073 -> origin/testcommit3073 + = [up to date] testcommit3074 -> origin/testcommit3074 + = [up to date] testcommit3075 -> origin/testcommit3075 + = [up to date] testcommit3076 -> origin/testcommit3076 + = [up to date] testcommit3077 -> origin/testcommit3077 + = [up to date] testcommit3078 -> origin/testcommit3078 + = [up to date] testcommit3079 -> origin/testcommit3079 + = [up to date] testcommit308 -> origin/testcommit308 + = [up to date] testcommit3080 -> origin/testcommit3080 + = [up to date] testcommit3081 -> origin/testcommit3081 + = [up to date] testcommit3082 -> origin/testcommit3082 + = [up to date] testcommit3083 -> origin/testcommit3083 + = [up to date] testcommit3084 -> origin/testcommit3084 + = [up to date] testcommit3085 -> origin/testcommit3085 + = [up to date] testcommit3086 -> origin/testcommit3086 + = [up to date] testcommit3087 -> origin/testcommit3087 + = [up to date] testcommit3088 -> origin/testcommit3088 + = [up to date] testcommit3089 -> origin/testcommit3089 + = [up to date] testcommit309 -> origin/testcommit309 + = [up to date] testcommit3090 -> origin/testcommit3090 + = [up to date] testcommit3091 -> origin/testcommit3091 + = [up to date] testcommit3092 -> origin/testcommit3092 + = [up to date] testcommit3093 -> origin/testcommit3093 + = [up to date] testcommit3094 -> origin/testcommit3094 + = [up to date] testcommit3095 -> origin/testcommit3095 + = [up to date] testcommit3096 -> origin/testcommit3096 + = [up to date] testcommit3097 -> origin/testcommit3097 + = [up to date] testcommit3098 -> origin/testcommit3098 + = [up to date] testcommit3099 -> origin/testcommit3099 + = [up to date] testcommit31 -> origin/testcommit31 + = [up to date] testcommit310 -> origin/testcommit310 + = [up to date] testcommit3100 -> origin/testcommit3100 + = [up to date] testcommit3101 -> origin/testcommit3101 + = [up to date] testcommit3102 -> origin/testcommit3102 + = [up to date] testcommit3103 -> origin/testcommit3103 + = [up to date] testcommit3104 -> origin/testcommit3104 + = [up to date] testcommit3105 -> origin/testcommit3105 + = [up to date] testcommit3106 -> origin/testcommit3106 + = [up to date] testcommit3107 -> origin/testcommit3107 + = [up to date] testcommit3108 -> origin/testcommit3108 + = [up to date] testcommit3109 -> origin/testcommit3109 + = [up to date] testcommit311 -> origin/testcommit311 + = [up to date] testcommit3110 -> origin/testcommit3110 + = [up to date] testcommit3111 -> origin/testcommit3111 + = [up to date] testcommit3112 -> origin/testcommit3112 + = [up to date] testcommit3113 -> origin/testcommit3113 + = [up to date] testcommit3114 -> origin/testcommit3114 + = [up to date] testcommit3115 -> origin/testcommit3115 + = [up to date] testcommit3116 -> origin/testcommit3116 + = [up to date] testcommit3117 -> origin/testcommit3117 + = [up to date] testcommit3118 -> origin/testcommit3118 + = [up to date] testcommit3119 -> origin/testcommit3119 + = [up to date] testcommit312 -> origin/testcommit312 + = [up to date] testcommit3120 -> origin/testcommit3120 + = [up to date] testcommit3121 -> origin/testcommit3121 + = [up to date] testcommit3122 -> origin/testcommit3122 + = [up to date] testcommit3123 -> origin/testcommit3123 + = [up to date] testcommit3124 -> origin/testcommit3124 + = [up to date] testcommit3125 -> origin/testcommit3125 + = [up to date] testcommit3126 -> origin/testcommit3126 + = [up to date] testcommit3127 -> origin/testcommit3127 + = [up to date] testcommit3128 -> origin/testcommit3128 + = [up to date] testcommit3129 -> origin/testcommit3129 + = [up to date] testcommit313 -> origin/testcommit313 + = [up to date] testcommit3130 -> origin/testcommit3130 + = [up to date] testcommit3131 -> origin/testcommit3131 + = [up to date] testcommit3132 -> origin/testcommit3132 + = [up to date] testcommit3133 -> origin/testcommit3133 + = [up to date] testcommit3134 -> origin/testcommit3134 + = [up to date] testcommit3135 -> origin/testcommit3135 + = [up to date] testcommit3136 -> origin/testcommit3136 + = [up to date] testcommit3137 -> origin/testcommit3137 + = [up to date] testcommit3138 -> origin/testcommit3138 + = [up to date] testcommit3139 -> origin/testcommit3139 + = [up to date] testcommit314 -> origin/testcommit314 + = [up to date] testcommit3140 -> origin/testcommit3140 + = [up to date] testcommit3141 -> origin/testcommit3141 + = [up to date] testcommit3142 -> origin/testcommit3142 + = [up to date] testcommit3143 -> origin/testcommit3143 + = [up to date] testcommit3144 -> origin/testcommit3144 + = [up to date] testcommit3145 -> origin/testcommit3145 + = [up to date] testcommit3146 -> origin/testcommit3146 + = [up to date] testcommit3147 -> origin/testcommit3147 + = [up to date] testcommit3148 -> origin/testcommit3148 + = [up to date] testcommit3149 -> origin/testcommit3149 + = [up to date] testcommit315 -> origin/testcommit315 + = [up to date] testcommit3150 -> origin/testcommit3150 + = [up to date] testcommit3151 -> origin/testcommit3151 + = [up to date] testcommit3152 -> origin/testcommit3152 + = [up to date] testcommit3153 -> origin/testcommit3153 + = [up to date] testcommit3154 -> origin/testcommit3154 + = [up to date] testcommit3155 -> origin/testcommit3155 + = [up to date] testcommit3156 -> origin/testcommit3156 + = [up to date] testcommit3157 -> origin/testcommit3157 + = [up to date] testcommit3158 -> origin/testcommit3158 + = [up to date] testcommit3159 -> origin/testcommit3159 + = [up to date] testcommit316 -> origin/testcommit316 + = [up to date] testcommit3160 -> origin/testcommit3160 + = [up to date] testcommit3161 -> origin/testcommit3161 + = [up to date] testcommit3162 -> origin/testcommit3162 + = [up to date] testcommit3163 -> origin/testcommit3163 + = [up to date] testcommit3164 -> origin/testcommit3164 + = [up to date] testcommit3165 -> origin/testcommit3165 + = [up to date] testcommit3166 -> origin/testcommit3166 + = [up to date] testcommit3167 -> origin/testcommit3167 + = [up to date] testcommit3168 -> origin/testcommit3168 + = [up to date] testcommit3169 -> origin/testcommit3169 + = [up to date] testcommit317 -> origin/testcommit317 + = [up to date] testcommit3170 -> origin/testcommit3170 + = [up to date] testcommit3171 -> origin/testcommit3171 + = [up to date] testcommit3172 -> origin/testcommit3172 + = [up to date] testcommit3173 -> origin/testcommit3173 + = [up to date] testcommit3174 -> origin/testcommit3174 + = [up to date] testcommit3175 -> origin/testcommit3175 + = [up to date] testcommit3176 -> origin/testcommit3176 + = [up to date] testcommit3177 -> origin/testcommit3177 + = [up to date] testcommit3178 -> origin/testcommit3178 + = [up to date] testcommit3179 -> origin/testcommit3179 + = [up to date] testcommit318 -> origin/testcommit318 + = [up to date] testcommit3180 -> origin/testcommit3180 + = [up to date] testcommit3181 -> origin/testcommit3181 + = [up to date] testcommit3182 -> origin/testcommit3182 + = [up to date] testcommit3183 -> origin/testcommit3183 + = [up to date] testcommit3184 -> origin/testcommit3184 + = [up to date] testcommit3185 -> origin/testcommit3185 + = [up to date] testcommit3186 -> origin/testcommit3186 + = [up to date] testcommit3187 -> origin/testcommit3187 + = [up to date] testcommit3188 -> origin/testcommit3188 + = [up to date] testcommit3189 -> origin/testcommit3189 + = [up to date] testcommit319 -> origin/testcommit319 + = [up to date] testcommit3190 -> origin/testcommit3190 + = [up to date] testcommit3191 -> origin/testcommit3191 + = [up to date] testcommit3192 -> origin/testcommit3192 + = [up to date] testcommit3193 -> origin/testcommit3193 + = [up to date] testcommit3194 -> origin/testcommit3194 + = [up to date] testcommit3195 -> origin/testcommit3195 + = [up to date] testcommit3196 -> origin/testcommit3196 + = [up to date] testcommit3197 -> origin/testcommit3197 + = [up to date] testcommit3198 -> origin/testcommit3198 + = [up to date] testcommit3199 -> origin/testcommit3199 + = [up to date] testcommit32 -> origin/testcommit32 + = [up to date] testcommit320 -> origin/testcommit320 + = [up to date] testcommit3200 -> origin/testcommit3200 + = [up to date] testcommit3201 -> origin/testcommit3201 + = [up to date] testcommit3202 -> origin/testcommit3202 + = [up to date] testcommit3203 -> origin/testcommit3203 + = [up to date] testcommit3204 -> origin/testcommit3204 + = [up to date] testcommit3205 -> origin/testcommit3205 + = [up to date] testcommit3206 -> origin/testcommit3206 + = [up to date] testcommit3207 -> origin/testcommit3207 + = [up to date] testcommit3208 -> origin/testcommit3208 + = [up to date] testcommit3209 -> origin/testcommit3209 + = [up to date] testcommit321 -> origin/testcommit321 + = [up to date] testcommit3210 -> origin/testcommit3210 + = [up to date] testcommit3211 -> origin/testcommit3211 + = [up to date] testcommit3212 -> origin/testcommit3212 + = [up to date] testcommit3213 -> origin/testcommit3213 + = [up to date] testcommit3214 -> origin/testcommit3214 + = [up to date] testcommit3215 -> origin/testcommit3215 + = [up to date] testcommit3216 -> origin/testcommit3216 + = [up to date] testcommit3217 -> origin/testcommit3217 + = [up to date] testcommit3218 -> origin/testcommit3218 + = [up to date] testcommit3219 -> origin/testcommit3219 + = [up to date] testcommit322 -> origin/testcommit322 + = [up to date] testcommit3220 -> origin/testcommit3220 + = [up to date] testcommit3221 -> origin/testcommit3221 + = [up to date] testcommit3222 -> origin/testcommit3222 + = [up to date] testcommit3223 -> origin/testcommit3223 + = [up to date] testcommit3224 -> origin/testcommit3224 + = [up to date] testcommit3225 -> origin/testcommit3225 + = [up to date] testcommit3226 -> origin/testcommit3226 + = [up to date] testcommit3227 -> origin/testcommit3227 + = [up to date] testcommit3228 -> origin/testcommit3228 + = [up to date] testcommit3229 -> origin/testcommit3229 + = [up to date] testcommit323 -> origin/testcommit323 + = [up to date] testcommit3230 -> origin/testcommit3230 + = [up to date] testcommit3231 -> origin/testcommit3231 + = [up to date] testcommit3232 -> origin/testcommit3232 + = [up to date] testcommit3233 -> origin/testcommit3233 + = [up to date] testcommit3234 -> origin/testcommit3234 + = [up to date] testcommit3235 -> origin/testcommit3235 + = [up to date] testcommit3236 -> origin/testcommit3236 + = [up to date] testcommit3237 -> origin/testcommit3237 + = [up to date] testcommit3238 -> origin/testcommit3238 + = [up to date] testcommit3239 -> origin/testcommit3239 + = [up to date] testcommit324 -> origin/testcommit324 + = [up to date] testcommit3240 -> origin/testcommit3240 + = [up to date] testcommit3241 -> origin/testcommit3241 + = [up to date] testcommit3242 -> origin/testcommit3242 + = [up to date] testcommit3243 -> origin/testcommit3243 + = [up to date] testcommit3244 -> origin/testcommit3244 + = [up to date] testcommit3245 -> origin/testcommit3245 + = [up to date] testcommit3246 -> origin/testcommit3246 + = [up to date] testcommit3247 -> origin/testcommit3247 + = [up to date] testcommit3248 -> origin/testcommit3248 + = [up to date] testcommit3249 -> origin/testcommit3249 + = [up to date] testcommit325 -> origin/testcommit325 + = [up to date] testcommit3250 -> origin/testcommit3250 + = [up to date] testcommit3251 -> origin/testcommit3251 + = [up to date] testcommit3252 -> origin/testcommit3252 + = [up to date] testcommit3253 -> origin/testcommit3253 + = [up to date] testcommit3254 -> origin/testcommit3254 + = [up to date] testcommit3255 -> origin/testcommit3255 + = [up to date] testcommit3256 -> origin/testcommit3256 + = [up to date] testcommit3257 -> origin/testcommit3257 + = [up to date] testcommit3258 -> origin/testcommit3258 + = [up to date] testcommit3259 -> origin/testcommit3259 + = [up to date] testcommit326 -> origin/testcommit326 + = [up to date] testcommit3260 -> origin/testcommit3260 + = [up to date] testcommit3261 -> origin/testcommit3261 + = [up to date] testcommit3262 -> origin/testcommit3262 + = [up to date] testcommit3263 -> origin/testcommit3263 + = [up to date] testcommit3264 -> origin/testcommit3264 + = [up to date] testcommit3265 -> origin/testcommit3265 + = [up to date] testcommit3266 -> origin/testcommit3266 + = [up to date] testcommit3267 -> origin/testcommit3267 + = [up to date] testcommit3268 -> origin/testcommit3268 + = [up to date] testcommit3269 -> origin/testcommit3269 + = [up to date] testcommit327 -> origin/testcommit327 + = [up to date] testcommit3270 -> origin/testcommit3270 + = [up to date] testcommit3271 -> origin/testcommit3271 + = [up to date] testcommit3272 -> origin/testcommit3272 + = [up to date] testcommit3273 -> origin/testcommit3273 + = [up to date] testcommit3274 -> origin/testcommit3274 + = [up to date] testcommit3275 -> origin/testcommit3275 + = [up to date] testcommit3276 -> origin/testcommit3276 + = [up to date] testcommit3277 -> origin/testcommit3277 + = [up to date] testcommit3278 -> origin/testcommit3278 + = [up to date] testcommit3279 -> origin/testcommit3279 + = [up to date] testcommit328 -> origin/testcommit328 + = [up to date] testcommit3280 -> origin/testcommit3280 + = [up to date] testcommit3281 -> origin/testcommit3281 + = [up to date] testcommit3282 -> origin/testcommit3282 + = [up to date] testcommit3283 -> origin/testcommit3283 + = [up to date] testcommit3284 -> origin/testcommit3284 + = [up to date] testcommit3285 -> origin/testcommit3285 + = [up to date] testcommit3286 -> origin/testcommit3286 + = [up to date] testcommit3287 -> origin/testcommit3287 + = [up to date] testcommit3288 -> origin/testcommit3288 + = [up to date] testcommit3289 -> origin/testcommit3289 + = [up to date] testcommit329 -> origin/testcommit329 + = [up to date] testcommit3290 -> origin/testcommit3290 + = [up to date] testcommit3291 -> origin/testcommit3291 + = [up to date] testcommit3292 -> origin/testcommit3292 + = [up to date] testcommit3293 -> origin/testcommit3293 + = [up to date] testcommit3294 -> origin/testcommit3294 + = [up to date] testcommit3295 -> origin/testcommit3295 + = [up to date] testcommit3296 -> origin/testcommit3296 + = [up to date] testcommit3297 -> origin/testcommit3297 + = [up to date] testcommit3298 -> origin/testcommit3298 + = [up to date] testcommit3299 -> origin/testcommit3299 + = [up to date] testcommit33 -> origin/testcommit33 + = [up to date] testcommit330 -> origin/testcommit330 + = [up to date] testcommit3300 -> origin/testcommit3300 + = [up to date] testcommit3301 -> origin/testcommit3301 + = [up to date] testcommit3302 -> origin/testcommit3302 + = [up to date] testcommit3303 -> origin/testcommit3303 + = [up to date] testcommit3304 -> origin/testcommit3304 + = [up to date] testcommit3305 -> origin/testcommit3305 + = [up to date] testcommit3306 -> origin/testcommit3306 + = [up to date] testcommit3307 -> origin/testcommit3307 + = [up to date] testcommit3308 -> origin/testcommit3308 + = [up to date] testcommit3309 -> origin/testcommit3309 + = [up to date] testcommit331 -> origin/testcommit331 + = [up to date] testcommit3310 -> origin/testcommit3310 + = [up to date] testcommit3311 -> origin/testcommit3311 + = [up to date] testcommit3312 -> origin/testcommit3312 + = [up to date] testcommit3313 -> origin/testcommit3313 + = [up to date] testcommit3314 -> origin/testcommit3314 + = [up to date] testcommit3315 -> origin/testcommit3315 + = [up to date] testcommit3316 -> origin/testcommit3316 + = [up to date] testcommit3317 -> origin/testcommit3317 + = [up to date] testcommit3318 -> origin/testcommit3318 + = [up to date] testcommit3319 -> origin/testcommit3319 + = [up to date] testcommit332 -> origin/testcommit332 + = [up to date] testcommit3320 -> origin/testcommit3320 + = [up to date] testcommit3321 -> origin/testcommit3321 + = [up to date] testcommit3322 -> origin/testcommit3322 + = [up to date] testcommit3323 -> origin/testcommit3323 + = [up to date] testcommit3324 -> origin/testcommit3324 + = [up to date] testcommit3325 -> origin/testcommit3325 + = [up to date] testcommit3326 -> origin/testcommit3326 + = [up to date] testcommit3327 -> origin/testcommit3327 + = [up to date] testcommit3328 -> origin/testcommit3328 + = [up to date] testcommit3329 -> origin/testcommit3329 + = [up to date] testcommit333 -> origin/testcommit333 + = [up to date] testcommit3330 -> origin/testcommit3330 + = [up to date] testcommit3331 -> origin/testcommit3331 + = [up to date] testcommit3332 -> origin/testcommit3332 + = [up to date] testcommit3333 -> origin/testcommit3333 + = [up to date] testcommit3334 -> origin/testcommit3334 + = [up to date] testcommit3335 -> origin/testcommit3335 + = [up to date] testcommit3336 -> origin/testcommit3336 + = [up to date] testcommit3337 -> origin/testcommit3337 + = [up to date] testcommit3338 -> origin/testcommit3338 + = [up to date] testcommit3339 -> origin/testcommit3339 + = [up to date] testcommit334 -> origin/testcommit334 + = [up to date] testcommit3340 -> origin/testcommit3340 + = [up to date] testcommit3341 -> origin/testcommit3341 + = [up to date] testcommit3342 -> origin/testcommit3342 + = [up to date] testcommit3343 -> origin/testcommit3343 + = [up to date] testcommit3344 -> origin/testcommit3344 + = [up to date] testcommit3345 -> origin/testcommit3345 + = [up to date] testcommit3346 -> origin/testcommit3346 + = [up to date] testcommit3347 -> origin/testcommit3347 + = [up to date] testcommit3348 -> origin/testcommit3348 + = [up to date] testcommit3349 -> origin/testcommit3349 + = [up to date] testcommit335 -> origin/testcommit335 + = [up to date] testcommit3350 -> origin/testcommit3350 + = [up to date] testcommit3351 -> origin/testcommit3351 + = [up to date] testcommit3352 -> origin/testcommit3352 + = [up to date] testcommit3353 -> origin/testcommit3353 + = [up to date] testcommit3354 -> origin/testcommit3354 + = [up to date] testcommit3355 -> origin/testcommit3355 + = [up to date] testcommit3356 -> origin/testcommit3356 + = [up to date] testcommit3357 -> origin/testcommit3357 + = [up to date] testcommit3358 -> origin/testcommit3358 + = [up to date] testcommit3359 -> origin/testcommit3359 + = [up to date] testcommit336 -> origin/testcommit336 + = [up to date] testcommit3360 -> origin/testcommit3360 + = [up to date] testcommit3361 -> origin/testcommit3361 + = [up to date] testcommit3362 -> origin/testcommit3362 + = [up to date] testcommit3363 -> origin/testcommit3363 + = [up to date] testcommit3364 -> origin/testcommit3364 + = [up to date] testcommit3365 -> origin/testcommit3365 + = [up to date] testcommit3366 -> origin/testcommit3366 + = [up to date] testcommit3367 -> origin/testcommit3367 + = [up to date] testcommit3368 -> origin/testcommit3368 + = [up to date] testcommit3369 -> origin/testcommit3369 + = [up to date] testcommit337 -> origin/testcommit337 + = [up to date] testcommit3370 -> origin/testcommit3370 + = [up to date] testcommit3371 -> origin/testcommit3371 + = [up to date] testcommit3372 -> origin/testcommit3372 + = [up to date] testcommit3373 -> origin/testcommit3373 + = [up to date] testcommit3374 -> origin/testcommit3374 + = [up to date] testcommit3375 -> origin/testcommit3375 + = [up to date] testcommit3376 -> origin/testcommit3376 + = [up to date] testcommit3377 -> origin/testcommit3377 + = [up to date] testcommit3378 -> origin/testcommit3378 + = [up to date] testcommit3379 -> origin/testcommit3379 + = [up to date] testcommit338 -> origin/testcommit338 + = [up to date] testcommit3380 -> origin/testcommit3380 + = [up to date] testcommit3381 -> origin/testcommit3381 + = [up to date] testcommit3382 -> origin/testcommit3382 + = [up to date] testcommit3383 -> origin/testcommit3383 + = [up to date] testcommit3384 -> origin/testcommit3384 + = [up to date] testcommit3385 -> origin/testcommit3385 + = [up to date] testcommit3386 -> origin/testcommit3386 + = [up to date] testcommit3387 -> origin/testcommit3387 + = [up to date] testcommit3388 -> origin/testcommit3388 + = [up to date] testcommit3389 -> origin/testcommit3389 + = [up to date] testcommit339 -> origin/testcommit339 + = [up to date] testcommit3390 -> origin/testcommit3390 + = [up to date] testcommit3391 -> origin/testcommit3391 + = [up to date] testcommit3392 -> origin/testcommit3392 + = [up to date] testcommit3393 -> origin/testcommit3393 + = [up to date] testcommit3394 -> origin/testcommit3394 + = [up to date] testcommit3395 -> origin/testcommit3395 + = [up to date] testcommit3396 -> origin/testcommit3396 + = [up to date] testcommit3397 -> origin/testcommit3397 + = [up to date] testcommit3398 -> origin/testcommit3398 + = [up to date] testcommit3399 -> origin/testcommit3399 + = [up to date] testcommit34 -> origin/testcommit34 + = [up to date] testcommit340 -> origin/testcommit340 + = [up to date] testcommit3400 -> origin/testcommit3400 + = [up to date] testcommit3401 -> origin/testcommit3401 + = [up to date] testcommit3402 -> origin/testcommit3402 + = [up to date] testcommit3403 -> origin/testcommit3403 + = [up to date] testcommit3404 -> origin/testcommit3404 + = [up to date] testcommit3405 -> origin/testcommit3405 + = [up to date] testcommit3406 -> origin/testcommit3406 + = [up to date] testcommit3407 -> origin/testcommit3407 + = [up to date] testcommit3408 -> origin/testcommit3408 + = [up to date] testcommit3409 -> origin/testcommit3409 + = [up to date] testcommit341 -> origin/testcommit341 + = [up to date] testcommit3410 -> origin/testcommit3410 + = [up to date] testcommit3411 -> origin/testcommit3411 + = [up to date] testcommit3412 -> origin/testcommit3412 + = [up to date] testcommit3413 -> origin/testcommit3413 + = [up to date] testcommit3414 -> origin/testcommit3414 + = [up to date] testcommit3415 -> origin/testcommit3415 + = [up to date] testcommit3416 -> origin/testcommit3416 + = [up to date] testcommit3417 -> origin/testcommit3417 + = [up to date] testcommit3418 -> origin/testcommit3418 + = [up to date] testcommit3419 -> origin/testcommit3419 + = [up to date] testcommit342 -> origin/testcommit342 + = [up to date] testcommit3420 -> origin/testcommit3420 + = [up to date] testcommit3421 -> origin/testcommit3421 + = [up to date] testcommit3422 -> origin/testcommit3422 + = [up to date] testcommit3423 -> origin/testcommit3423 + = [up to date] testcommit3424 -> origin/testcommit3424 + = [up to date] testcommit3425 -> origin/testcommit3425 + = [up to date] testcommit3426 -> origin/testcommit3426 + = [up to date] testcommit3427 -> origin/testcommit3427 + = [up to date] testcommit3428 -> origin/testcommit3428 + = [up to date] testcommit3429 -> origin/testcommit3429 + = [up to date] testcommit343 -> origin/testcommit343 + = [up to date] testcommit3430 -> origin/testcommit3430 + = [up to date] testcommit3431 -> origin/testcommit3431 + = [up to date] testcommit3432 -> origin/testcommit3432 + = [up to date] testcommit3433 -> origin/testcommit3433 + = [up to date] testcommit3434 -> origin/testcommit3434 + = [up to date] testcommit3435 -> origin/testcommit3435 + = [up to date] testcommit3436 -> origin/testcommit3436 + = [up to date] testcommit3437 -> origin/testcommit3437 + = [up to date] testcommit3438 -> origin/testcommit3438 + = [up to date] testcommit3439 -> origin/testcommit3439 + = [up to date] testcommit344 -> origin/testcommit344 + = [up to date] testcommit3440 -> origin/testcommit3440 + = [up to date] testcommit3441 -> origin/testcommit3441 + = [up to date] testcommit3442 -> origin/testcommit3442 + = [up to date] testcommit3443 -> origin/testcommit3443 + = [up to date] testcommit3444 -> origin/testcommit3444 + = [up to date] testcommit3445 -> origin/testcommit3445 + = [up to date] testcommit3446 -> origin/testcommit3446 + = [up to date] testcommit3447 -> origin/testcommit3447 + = [up to date] testcommit3448 -> origin/testcommit3448 + = [up to date] testcommit3449 -> origin/testcommit3449 + = [up to date] testcommit345 -> origin/testcommit345 + = [up to date] testcommit3450 -> origin/testcommit3450 + = [up to date] testcommit3451 -> origin/testcommit3451 + = [up to date] testcommit3452 -> origin/testcommit3452 + = [up to date] testcommit3453 -> origin/testcommit3453 + = [up to date] testcommit3454 -> origin/testcommit3454 + = [up to date] testcommit3455 -> origin/testcommit3455 + = [up to date] testcommit3456 -> origin/testcommit3456 + = [up to date] testcommit3457 -> origin/testcommit3457 + = [up to date] testcommit3458 -> origin/testcommit3458 + = [up to date] testcommit3459 -> origin/testcommit3459 + = [up to date] testcommit346 -> origin/testcommit346 + = [up to date] testcommit3460 -> origin/testcommit3460 + = [up to date] testcommit3461 -> origin/testcommit3461 + = [up to date] testcommit3462 -> origin/testcommit3462 + = [up to date] testcommit3463 -> origin/testcommit3463 + = [up to date] testcommit3464 -> origin/testcommit3464 + = [up to date] testcommit3465 -> origin/testcommit3465 + = [up to date] testcommit3466 -> origin/testcommit3466 + = [up to date] testcommit3467 -> origin/testcommit3467 + = [up to date] testcommit3468 -> origin/testcommit3468 + = [up to date] testcommit3469 -> origin/testcommit3469 + = [up to date] testcommit347 -> origin/testcommit347 + = [up to date] testcommit3470 -> origin/testcommit3470 + = [up to date] testcommit3471 -> origin/testcommit3471 + = [up to date] testcommit3472 -> origin/testcommit3472 + = [up to date] testcommit3473 -> origin/testcommit3473 + = [up to date] testcommit3474 -> origin/testcommit3474 + = [up to date] testcommit3475 -> origin/testcommit3475 + = [up to date] testcommit3476 -> origin/testcommit3476 + = [up to date] testcommit3477 -> origin/testcommit3477 + = [up to date] testcommit3478 -> origin/testcommit3478 + = [up to date] testcommit3479 -> origin/testcommit3479 + = [up to date] testcommit348 -> origin/testcommit348 + = [up to date] testcommit3480 -> origin/testcommit3480 + = [up to date] testcommit3481 -> origin/testcommit3481 + = [up to date] testcommit3482 -> origin/testcommit3482 + = [up to date] testcommit3483 -> origin/testcommit3483 + = [up to date] testcommit3484 -> origin/testcommit3484 + = [up to date] testcommit3485 -> origin/testcommit3485 + = [up to date] testcommit3486 -> origin/testcommit3486 + = [up to date] testcommit3487 -> origin/testcommit3487 + = [up to date] testcommit3488 -> origin/testcommit3488 + = [up to date] testcommit3489 -> origin/testcommit3489 + = [up to date] testcommit349 -> origin/testcommit349 + = [up to date] testcommit3490 -> origin/testcommit3490 + = [up to date] testcommit3491 -> origin/testcommit3491 + = [up to date] testcommit3492 -> origin/testcommit3492 + = [up to date] testcommit3493 -> origin/testcommit3493 + = [up to date] testcommit3494 -> origin/testcommit3494 + = [up to date] testcommit3495 -> origin/testcommit3495 + = [up to date] testcommit3496 -> origin/testcommit3496 + = [up to date] testcommit3497 -> origin/testcommit3497 + = [up to date] testcommit3498 -> origin/testcommit3498 + = [up to date] testcommit3499 -> origin/testcommit3499 + = [up to date] testcommit35 -> origin/testcommit35 + = [up to date] testcommit350 -> origin/testcommit350 + = [up to date] testcommit3500 -> origin/testcommit3500 + = [up to date] testcommit3501 -> origin/testcommit3501 + = [up to date] testcommit3502 -> origin/testcommit3502 + = [up to date] testcommit3503 -> origin/testcommit3503 + = [up to date] testcommit3504 -> origin/testcommit3504 + = [up to date] testcommit3505 -> origin/testcommit3505 + = [up to date] testcommit3506 -> origin/testcommit3506 + = [up to date] testcommit3507 -> origin/testcommit3507 + = [up to date] testcommit3508 -> origin/testcommit3508 + = [up to date] testcommit3509 -> origin/testcommit3509 + = [up to date] testcommit351 -> origin/testcommit351 + = [up to date] testcommit3510 -> origin/testcommit3510 + = [up to date] testcommit3511 -> origin/testcommit3511 + = [up to date] testcommit3512 -> origin/testcommit3512 + = [up to date] testcommit3513 -> origin/testcommit3513 + = [up to date] testcommit3514 -> origin/testcommit3514 + = [up to date] testcommit3515 -> origin/testcommit3515 + = [up to date] testcommit3516 -> origin/testcommit3516 + = [up to date] testcommit3517 -> origin/testcommit3517 + = [up to date] testcommit3518 -> origin/testcommit3518 + = [up to date] testcommit3519 -> origin/testcommit3519 + = [up to date] testcommit352 -> origin/testcommit352 + = [up to date] testcommit3520 -> origin/testcommit3520 + = [up to date] testcommit3521 -> origin/testcommit3521 + = [up to date] testcommit3522 -> origin/testcommit3522 + = [up to date] testcommit3523 -> origin/testcommit3523 + = [up to date] testcommit3524 -> origin/testcommit3524 + = [up to date] testcommit3525 -> origin/testcommit3525 + = [up to date] testcommit3526 -> origin/testcommit3526 + = [up to date] testcommit3527 -> origin/testcommit3527 + = [up to date] testcommit3528 -> origin/testcommit3528 + = [up to date] testcommit3529 -> origin/testcommit3529 + = [up to date] testcommit353 -> origin/testcommit353 + = [up to date] testcommit3530 -> origin/testcommit3530 + = [up to date] testcommit3531 -> origin/testcommit3531 + = [up to date] testcommit3532 -> origin/testcommit3532 + = [up to date] testcommit3533 -> origin/testcommit3533 + = [up to date] testcommit3534 -> origin/testcommit3534 + = [up to date] testcommit3535 -> origin/testcommit3535 + = [up to date] testcommit3536 -> origin/testcommit3536 + = [up to date] testcommit3537 -> origin/testcommit3537 + = [up to date] testcommit3538 -> origin/testcommit3538 + = [up to date] testcommit3539 -> origin/testcommit3539 + = [up to date] testcommit354 -> origin/testcommit354 + = [up to date] testcommit3540 -> origin/testcommit3540 + = [up to date] testcommit3541 -> origin/testcommit3541 + = [up to date] testcommit3542 -> origin/testcommit3542 + = [up to date] testcommit3543 -> origin/testcommit3543 + = [up to date] testcommit3544 -> origin/testcommit3544 + = [up to date] testcommit3545 -> origin/testcommit3545 + = [up to date] testcommit3546 -> origin/testcommit3546 + = [up to date] testcommit3547 -> origin/testcommit3547 + = [up to date] testcommit3548 -> origin/testcommit3548 + = [up to date] testcommit3549 -> origin/testcommit3549 + = [up to date] testcommit355 -> origin/testcommit355 + = [up to date] testcommit3550 -> origin/testcommit3550 + = [up to date] testcommit3551 -> origin/testcommit3551 + = [up to date] testcommit3552 -> origin/testcommit3552 + = [up to date] testcommit3553 -> origin/testcommit3553 + = [up to date] testcommit3554 -> origin/testcommit3554 + = [up to date] testcommit3555 -> origin/testcommit3555 + = [up to date] testcommit3556 -> origin/testcommit3556 + = [up to date] testcommit3557 -> origin/testcommit3557 + = [up to date] testcommit3558 -> origin/testcommit3558 + = [up to date] testcommit3559 -> origin/testcommit3559 + = [up to date] testcommit356 -> origin/testcommit356 + = [up to date] testcommit3560 -> origin/testcommit3560 + = [up to date] testcommit3561 -> origin/testcommit3561 + = [up to date] testcommit3562 -> origin/testcommit3562 + = [up to date] testcommit3563 -> origin/testcommit3563 + = [up to date] testcommit3564 -> origin/testcommit3564 + = [up to date] testcommit3565 -> origin/testcommit3565 + = [up to date] testcommit3566 -> origin/testcommit3566 + = [up to date] testcommit3567 -> origin/testcommit3567 + = [up to date] testcommit3568 -> origin/testcommit3568 + = [up to date] testcommit3569 -> origin/testcommit3569 + = [up to date] testcommit357 -> origin/testcommit357 + = [up to date] testcommit3570 -> origin/testcommit3570 + = [up to date] testcommit3571 -> origin/testcommit3571 + = [up to date] testcommit3572 -> origin/testcommit3572 + = [up to date] testcommit3573 -> origin/testcommit3573 + = [up to date] testcommit3574 -> origin/testcommit3574 + = [up to date] testcommit3575 -> origin/testcommit3575 + = [up to date] testcommit3576 -> origin/testcommit3576 + = [up to date] testcommit3577 -> origin/testcommit3577 + = [up to date] testcommit3578 -> origin/testcommit3578 + = [up to date] testcommit3579 -> origin/testcommit3579 + = [up to date] testcommit358 -> origin/testcommit358 + = [up to date] testcommit3580 -> origin/testcommit3580 + = [up to date] testcommit3581 -> origin/testcommit3581 + = [up to date] testcommit3582 -> origin/testcommit3582 + = [up to date] testcommit3583 -> origin/testcommit3583 + = [up to date] testcommit3584 -> origin/testcommit3584 + = [up to date] testcommit3585 -> origin/testcommit3585 + = [up to date] testcommit3586 -> origin/testcommit3586 + = [up to date] testcommit3587 -> origin/testcommit3587 + = [up to date] testcommit3588 -> origin/testcommit3588 + = [up to date] testcommit3589 -> origin/testcommit3589 + = [up to date] testcommit359 -> origin/testcommit359 + = [up to date] testcommit3590 -> origin/testcommit3590 + = [up to date] testcommit3591 -> origin/testcommit3591 + = [up to date] testcommit3592 -> origin/testcommit3592 + = [up to date] testcommit3593 -> origin/testcommit3593 + = [up to date] testcommit3594 -> origin/testcommit3594 + = [up to date] testcommit3595 -> origin/testcommit3595 + = [up to date] testcommit3596 -> origin/testcommit3596 + = [up to date] testcommit3597 -> origin/testcommit3597 + = [up to date] testcommit3598 -> origin/testcommit3598 + = [up to date] testcommit3599 -> origin/testcommit3599 + = [up to date] testcommit36 -> origin/testcommit36 + = [up to date] testcommit360 -> origin/testcommit360 + = [up to date] testcommit3600 -> origin/testcommit3600 + = [up to date] testcommit3601 -> origin/testcommit3601 + = [up to date] testcommit3602 -> origin/testcommit3602 + = [up to date] testcommit3603 -> origin/testcommit3603 + = [up to date] testcommit3604 -> origin/testcommit3604 + = [up to date] testcommit3605 -> origin/testcommit3605 + = [up to date] testcommit3606 -> origin/testcommit3606 + = [up to date] testcommit3607 -> origin/testcommit3607 + = [up to date] testcommit3608 -> origin/testcommit3608 + = [up to date] testcommit3609 -> origin/testcommit3609 + = [up to date] testcommit361 -> origin/testcommit361 + = [up to date] testcommit3610 -> origin/testcommit3610 + = [up to date] testcommit3611 -> origin/testcommit3611 + = [up to date] testcommit3612 -> origin/testcommit3612 + = [up to date] testcommit3613 -> origin/testcommit3613 + = [up to date] testcommit3614 -> origin/testcommit3614 + = [up to date] testcommit3615 -> origin/testcommit3615 + = [up to date] testcommit3616 -> origin/testcommit3616 + = [up to date] testcommit3617 -> origin/testcommit3617 + = [up to date] testcommit3618 -> origin/testcommit3618 + = [up to date] testcommit3619 -> origin/testcommit3619 + = [up to date] testcommit362 -> origin/testcommit362 + = [up to date] testcommit3620 -> origin/testcommit3620 + = [up to date] testcommit3621 -> origin/testcommit3621 + = [up to date] testcommit3622 -> origin/testcommit3622 + = [up to date] testcommit3623 -> origin/testcommit3623 + = [up to date] testcommit3624 -> origin/testcommit3624 + = [up to date] testcommit3625 -> origin/testcommit3625 + = [up to date] testcommit3626 -> origin/testcommit3626 + = [up to date] testcommit3627 -> origin/testcommit3627 + = [up to date] testcommit3628 -> origin/testcommit3628 + = [up to date] testcommit3629 -> origin/testcommit3629 + = [up to date] testcommit363 -> origin/testcommit363 + = [up to date] testcommit3630 -> origin/testcommit3630 + = [up to date] testcommit3631 -> origin/testcommit3631 + = [up to date] testcommit3632 -> origin/testcommit3632 + = [up to date] testcommit3633 -> origin/testcommit3633 + = [up to date] testcommit3634 -> origin/testcommit3634 + = [up to date] testcommit3635 -> origin/testcommit3635 + = [up to date] testcommit3636 -> origin/testcommit3636 + = [up to date] testcommit3637 -> origin/testcommit3637 + = [up to date] testcommit3638 -> origin/testcommit3638 + = [up to date] testcommit3639 -> origin/testcommit3639 + = [up to date] testcommit364 -> origin/testcommit364 + = [up to date] testcommit3640 -> origin/testcommit3640 + = [up to date] testcommit3641 -> origin/testcommit3641 + = [up to date] testcommit3642 -> origin/testcommit3642 + = [up to date] testcommit3643 -> origin/testcommit3643 + = [up to date] testcommit3644 -> origin/testcommit3644 + = [up to date] testcommit3645 -> origin/testcommit3645 + = [up to date] testcommit3646 -> origin/testcommit3646 + = [up to date] testcommit3647 -> origin/testcommit3647 + = [up to date] testcommit3648 -> origin/testcommit3648 + = [up to date] testcommit3649 -> origin/testcommit3649 + = [up to date] testcommit365 -> origin/testcommit365 + = [up to date] testcommit3650 -> origin/testcommit3650 + = [up to date] testcommit3651 -> origin/testcommit3651 + = [up to date] testcommit3652 -> origin/testcommit3652 + = [up to date] testcommit3653 -> origin/testcommit3653 + = [up to date] testcommit3654 -> origin/testcommit3654 + = [up to date] testcommit3655 -> origin/testcommit3655 + = [up to date] testcommit3656 -> origin/testcommit3656 + = [up to date] testcommit3657 -> origin/testcommit3657 + = [up to date] testcommit3658 -> origin/testcommit3658 + = [up to date] testcommit3659 -> origin/testcommit3659 + = [up to date] testcommit366 -> origin/testcommit366 + = [up to date] testcommit3660 -> origin/testcommit3660 + = [up to date] testcommit3661 -> origin/testcommit3661 + = [up to date] testcommit3662 -> origin/testcommit3662 + = [up to date] testcommit3663 -> origin/testcommit3663 + = [up to date] testcommit3664 -> origin/testcommit3664 + = [up to date] testcommit3665 -> origin/testcommit3665 + = [up to date] testcommit3666 -> origin/testcommit3666 + = [up to date] testcommit3667 -> origin/testcommit3667 + = [up to date] testcommit3668 -> origin/testcommit3668 + = [up to date] testcommit3669 -> origin/testcommit3669 + = [up to date] testcommit367 -> origin/testcommit367 + = [up to date] testcommit3670 -> origin/testcommit3670 + = [up to date] testcommit3671 -> origin/testcommit3671 + = [up to date] testcommit3672 -> origin/testcommit3672 + = [up to date] testcommit3673 -> origin/testcommit3673 + = [up to date] testcommit3674 -> origin/testcommit3674 + = [up to date] testcommit3675 -> origin/testcommit3675 + = [up to date] testcommit3676 -> origin/testcommit3676 + = [up to date] testcommit3677 -> origin/testcommit3677 + = [up to date] testcommit3678 -> origin/testcommit3678 + = [up to date] testcommit3679 -> origin/testcommit3679 + = [up to date] testcommit368 -> origin/testcommit368 + = [up to date] testcommit3680 -> origin/testcommit3680 + = [up to date] testcommit3681 -> origin/testcommit3681 + = [up to date] testcommit3682 -> origin/testcommit3682 + = [up to date] testcommit3683 -> origin/testcommit3683 + = [up to date] testcommit3684 -> origin/testcommit3684 + = [up to date] testcommit3685 -> origin/testcommit3685 + = [up to date] testcommit3686 -> origin/testcommit3686 + = [up to date] testcommit3687 -> origin/testcommit3687 + = [up to date] testcommit3688 -> origin/testcommit3688 + = [up to date] testcommit3689 -> origin/testcommit3689 + = [up to date] testcommit369 -> origin/testcommit369 + = [up to date] testcommit3690 -> origin/testcommit3690 + = [up to date] testcommit3691 -> origin/testcommit3691 + = [up to date] testcommit3692 -> origin/testcommit3692 + = [up to date] testcommit3693 -> origin/testcommit3693 + = [up to date] testcommit3694 -> origin/testcommit3694 + = [up to date] testcommit3695 -> origin/testcommit3695 + = [up to date] testcommit3696 -> origin/testcommit3696 + = [up to date] testcommit3697 -> origin/testcommit3697 + = [up to date] testcommit3698 -> origin/testcommit3698 + = [up to date] testcommit3699 -> origin/testcommit3699 + = [up to date] testcommit37 -> origin/testcommit37 + = [up to date] testcommit370 -> origin/testcommit370 + = [up to date] testcommit3700 -> origin/testcommit3700 + = [up to date] testcommit3701 -> origin/testcommit3701 + = [up to date] testcommit3702 -> origin/testcommit3702 + = [up to date] testcommit3703 -> origin/testcommit3703 + = [up to date] testcommit3704 -> origin/testcommit3704 + = [up to date] testcommit3705 -> origin/testcommit3705 + = [up to date] testcommit3706 -> origin/testcommit3706 + = [up to date] testcommit3707 -> origin/testcommit3707 + = [up to date] testcommit3708 -> origin/testcommit3708 + = [up to date] testcommit3709 -> origin/testcommit3709 + = [up to date] testcommit371 -> origin/testcommit371 + = [up to date] testcommit3710 -> origin/testcommit3710 + = [up to date] testcommit3711 -> origin/testcommit3711 + = [up to date] testcommit3712 -> origin/testcommit3712 + = [up to date] testcommit3713 -> origin/testcommit3713 + = [up to date] testcommit3714 -> origin/testcommit3714 + = [up to date] testcommit3715 -> origin/testcommit3715 + = [up to date] testcommit3716 -> origin/testcommit3716 + = [up to date] testcommit3717 -> origin/testcommit3717 + = [up to date] testcommit3718 -> origin/testcommit3718 + = [up to date] testcommit3719 -> origin/testcommit3719 + = [up to date] testcommit372 -> origin/testcommit372 + = [up to date] testcommit3720 -> origin/testcommit3720 + = [up to date] testcommit3721 -> origin/testcommit3721 + = [up to date] testcommit3722 -> origin/testcommit3722 + = [up to date] testcommit3723 -> origin/testcommit3723 + = [up to date] testcommit3724 -> origin/testcommit3724 + = [up to date] testcommit3725 -> origin/testcommit3725 + = [up to date] testcommit3726 -> origin/testcommit3726 + = [up to date] testcommit3727 -> origin/testcommit3727 + = [up to date] testcommit3728 -> origin/testcommit3728 + = [up to date] testcommit3729 -> origin/testcommit3729 + = [up to date] testcommit373 -> origin/testcommit373 + = [up to date] testcommit3730 -> origin/testcommit3730 + = [up to date] testcommit3731 -> origin/testcommit3731 + = [up to date] testcommit3732 -> origin/testcommit3732 + = [up to date] testcommit3733 -> origin/testcommit3733 + = [up to date] testcommit3734 -> origin/testcommit3734 + = [up to date] testcommit3735 -> origin/testcommit3735 + = [up to date] testcommit3736 -> origin/testcommit3736 + = [up to date] testcommit3737 -> origin/testcommit3737 + = [up to date] testcommit3738 -> origin/testcommit3738 + = [up to date] testcommit3739 -> origin/testcommit3739 + = [up to date] testcommit374 -> origin/testcommit374 + = [up to date] testcommit3740 -> origin/testcommit3740 + = [up to date] testcommit3741 -> origin/testcommit3741 + = [up to date] testcommit3742 -> origin/testcommit3742 + = [up to date] testcommit3743 -> origin/testcommit3743 + = [up to date] testcommit3744 -> origin/testcommit3744 + = [up to date] testcommit3745 -> origin/testcommit3745 + = [up to date] testcommit3746 -> origin/testcommit3746 + = [up to date] testcommit3747 -> origin/testcommit3747 + = [up to date] testcommit3748 -> origin/testcommit3748 + = [up to date] testcommit3749 -> origin/testcommit3749 + = [up to date] testcommit375 -> origin/testcommit375 + = [up to date] testcommit3750 -> origin/testcommit3750 + = [up to date] testcommit3751 -> origin/testcommit3751 + = [up to date] testcommit3752 -> origin/testcommit3752 + = [up to date] testcommit3753 -> origin/testcommit3753 + = [up to date] testcommit3754 -> origin/testcommit3754 + = [up to date] testcommit3755 -> origin/testcommit3755 + = [up to date] testcommit3756 -> origin/testcommit3756 + = [up to date] testcommit3757 -> origin/testcommit3757 + = [up to date] testcommit3758 -> origin/testcommit3758 + = [up to date] testcommit3759 -> origin/testcommit3759 + = [up to date] testcommit376 -> origin/testcommit376 + = [up to date] testcommit3760 -> origin/testcommit3760 + = [up to date] testcommit3761 -> origin/testcommit3761 + = [up to date] testcommit3762 -> origin/testcommit3762 + = [up to date] testcommit3763 -> origin/testcommit3763 + = [up to date] testcommit3764 -> origin/testcommit3764 + = [up to date] testcommit3765 -> origin/testcommit3765 + = [up to date] testcommit3766 -> origin/testcommit3766 + = [up to date] testcommit3767 -> origin/testcommit3767 + = [up to date] testcommit3768 -> origin/testcommit3768 + = [up to date] testcommit3769 -> origin/testcommit3769 + = [up to date] testcommit377 -> origin/testcommit377 + = [up to date] testcommit3770 -> origin/testcommit3770 + = [up to date] testcommit3771 -> origin/testcommit3771 + = [up to date] testcommit3772 -> origin/testcommit3772 + = [up to date] testcommit3773 -> origin/testcommit3773 + = [up to date] testcommit3774 -> origin/testcommit3774 + = [up to date] testcommit3775 -> origin/testcommit3775 + = [up to date] testcommit3776 -> origin/testcommit3776 + = [up to date] testcommit3777 -> origin/testcommit3777 + = [up to date] testcommit3778 -> origin/testcommit3778 + = [up to date] testcommit3779 -> origin/testcommit3779 + = [up to date] testcommit378 -> origin/testcommit378 + = [up to date] testcommit3780 -> origin/testcommit3780 + = [up to date] testcommit3781 -> origin/testcommit3781 + = [up to date] testcommit3782 -> origin/testcommit3782 + = [up to date] testcommit3783 -> origin/testcommit3783 + = [up to date] testcommit3784 -> origin/testcommit3784 + = [up to date] testcommit3785 -> origin/testcommit3785 + = [up to date] testcommit3786 -> origin/testcommit3786 + = [up to date] testcommit3787 -> origin/testcommit3787 + = [up to date] testcommit3788 -> origin/testcommit3788 + = [up to date] testcommit3789 -> origin/testcommit3789 + = [up to date] testcommit379 -> origin/testcommit379 + = [up to date] testcommit3790 -> origin/testcommit3790 + = [up to date] testcommit3791 -> origin/testcommit3791 + = [up to date] testcommit3792 -> origin/testcommit3792 + = [up to date] testcommit3793 -> origin/testcommit3793 + = [up to date] testcommit3794 -> origin/testcommit3794 + = [up to date] testcommit3795 -> origin/testcommit3795 + = [up to date] testcommit3796 -> origin/testcommit3796 + = [up to date] testcommit3797 -> origin/testcommit3797 + = [up to date] testcommit3798 -> origin/testcommit3798 + = [up to date] testcommit3799 -> origin/testcommit3799 + = [up to date] testcommit38 -> origin/testcommit38 + = [up to date] testcommit380 -> origin/testcommit380 + = [up to date] testcommit3800 -> origin/testcommit3800 + = [up to date] testcommit3801 -> origin/testcommit3801 + = [up to date] testcommit3802 -> origin/testcommit3802 + = [up to date] testcommit3803 -> origin/testcommit3803 + = [up to date] testcommit3804 -> origin/testcommit3804 + = [up to date] testcommit3805 -> origin/testcommit3805 + = [up to date] testcommit3806 -> origin/testcommit3806 + = [up to date] testcommit3807 -> origin/testcommit3807 + = [up to date] testcommit3808 -> origin/testcommit3808 + = [up to date] testcommit3809 -> origin/testcommit3809 + = [up to date] testcommit381 -> origin/testcommit381 + = [up to date] testcommit3810 -> origin/testcommit3810 + = [up to date] testcommit3811 -> origin/testcommit3811 + = [up to date] testcommit3812 -> origin/testcommit3812 + = [up to date] testcommit3813 -> origin/testcommit3813 + = [up to date] testcommit3814 -> origin/testcommit3814 + = [up to date] testcommit3815 -> origin/testcommit3815 + = [up to date] testcommit3816 -> origin/testcommit3816 + = [up to date] testcommit3817 -> origin/testcommit3817 + = [up to date] testcommit3818 -> origin/testcommit3818 + = [up to date] testcommit3819 -> origin/testcommit3819 + = [up to date] testcommit382 -> origin/testcommit382 + = [up to date] testcommit3820 -> origin/testcommit3820 + = [up to date] testcommit3821 -> origin/testcommit3821 + = [up to date] testcommit3822 -> origin/testcommit3822 + = [up to date] testcommit3823 -> origin/testcommit3823 + = [up to date] testcommit3824 -> origin/testcommit3824 + = [up to date] testcommit3825 -> origin/testcommit3825 + = [up to date] testcommit3826 -> origin/testcommit3826 + = [up to date] testcommit3827 -> origin/testcommit3827 + = [up to date] testcommit3828 -> origin/testcommit3828 + = [up to date] testcommit3829 -> origin/testcommit3829 + = [up to date] testcommit383 -> origin/testcommit383 + = [up to date] testcommit3830 -> origin/testcommit3830 + = [up to date] testcommit3831 -> origin/testcommit3831 + = [up to date] testcommit3832 -> origin/testcommit3832 + = [up to date] testcommit3833 -> origin/testcommit3833 + = [up to date] testcommit3834 -> origin/testcommit3834 + = [up to date] testcommit3835 -> origin/testcommit3835 + = [up to date] testcommit3836 -> origin/testcommit3836 + = [up to date] testcommit3837 -> origin/testcommit3837 + = [up to date] testcommit3838 -> origin/testcommit3838 + = [up to date] testcommit3839 -> origin/testcommit3839 + = [up to date] testcommit384 -> origin/testcommit384 + = [up to date] testcommit3840 -> origin/testcommit3840 + = [up to date] testcommit3841 -> origin/testcommit3841 + = [up to date] testcommit3842 -> origin/testcommit3842 + = [up to date] testcommit3843 -> origin/testcommit3843 + = [up to date] testcommit3844 -> origin/testcommit3844 + = [up to date] testcommit3845 -> origin/testcommit3845 + = [up to date] testcommit3846 -> origin/testcommit3846 + = [up to date] testcommit3847 -> origin/testcommit3847 + = [up to date] testcommit3848 -> origin/testcommit3848 + = [up to date] testcommit3849 -> origin/testcommit3849 + = [up to date] testcommit385 -> origin/testcommit385 + = [up to date] testcommit3850 -> origin/testcommit3850 + = [up to date] testcommit3851 -> origin/testcommit3851 + = [up to date] testcommit3852 -> origin/testcommit3852 + = [up to date] testcommit3853 -> origin/testcommit3853 + = [up to date] testcommit3854 -> origin/testcommit3854 + = [up to date] testcommit3855 -> origin/testcommit3855 + = [up to date] testcommit3856 -> origin/testcommit3856 + = [up to date] testcommit3857 -> origin/testcommit3857 + = [up to date] testcommit3858 -> origin/testcommit3858 + = [up to date] testcommit3859 -> origin/testcommit3859 + = [up to date] testcommit386 -> origin/testcommit386 + = [up to date] testcommit3860 -> origin/testcommit3860 + = [up to date] testcommit3861 -> origin/testcommit3861 + = [up to date] testcommit3862 -> origin/testcommit3862 + = [up to date] testcommit3863 -> origin/testcommit3863 + = [up to date] testcommit3864 -> origin/testcommit3864 + = [up to date] testcommit3865 -> origin/testcommit3865 + = [up to date] testcommit3866 -> origin/testcommit3866 + = [up to date] testcommit3867 -> origin/testcommit3867 + = [up to date] testcommit3868 -> origin/testcommit3868 + = [up to date] testcommit3869 -> origin/testcommit3869 + = [up to date] testcommit387 -> origin/testcommit387 + = [up to date] testcommit3870 -> origin/testcommit3870 + = [up to date] testcommit3871 -> origin/testcommit3871 + = [up to date] testcommit3872 -> origin/testcommit3872 + = [up to date] testcommit3873 -> origin/testcommit3873 + = [up to date] testcommit3874 -> origin/testcommit3874 + = [up to date] testcommit3875 -> origin/testcommit3875 + = [up to date] testcommit3876 -> origin/testcommit3876 + = [up to date] testcommit3877 -> origin/testcommit3877 + = [up to date] testcommit3878 -> origin/testcommit3878 + = [up to date] testcommit3879 -> origin/testcommit3879 + = [up to date] testcommit388 -> origin/testcommit388 + = [up to date] testcommit3880 -> origin/testcommit3880 + = [up to date] testcommit3881 -> origin/testcommit3881 + = [up to date] testcommit3882 -> origin/testcommit3882 + = [up to date] testcommit3883 -> origin/testcommit3883 + = [up to date] testcommit3884 -> origin/testcommit3884 + = [up to date] testcommit3885 -> origin/testcommit3885 + = [up to date] testcommit3886 -> origin/testcommit3886 + = [up to date] testcommit3887 -> origin/testcommit3887 + = [up to date] testcommit3888 -> origin/testcommit3888 + = [up to date] testcommit3889 -> origin/testcommit3889 + = [up to date] testcommit389 -> origin/testcommit389 + = [up to date] testcommit3890 -> origin/testcommit3890 + = [up to date] testcommit3891 -> origin/testcommit3891 + = [up to date] testcommit3892 -> origin/testcommit3892 + = [up to date] testcommit3893 -> origin/testcommit3893 + = [up to date] testcommit3894 -> origin/testcommit3894 + = [up to date] testcommit3895 -> origin/testcommit3895 + = [up to date] testcommit3896 -> origin/testcommit3896 + = [up to date] testcommit3897 -> origin/testcommit3897 + = [up to date] testcommit3898 -> origin/testcommit3898 + = [up to date] testcommit3899 -> origin/testcommit3899 + = [up to date] testcommit39 -> origin/testcommit39 + = [up to date] testcommit390 -> origin/testcommit390 + = [up to date] testcommit3900 -> origin/testcommit3900 + = [up to date] testcommit3901 -> origin/testcommit3901 + = [up to date] testcommit3902 -> origin/testcommit3902 + = [up to date] testcommit3903 -> origin/testcommit3903 + = [up to date] testcommit3904 -> origin/testcommit3904 + = [up to date] testcommit3905 -> origin/testcommit3905 + = [up to date] testcommit3906 -> origin/testcommit3906 + = [up to date] testcommit3907 -> origin/testcommit3907 + = [up to date] testcommit3908 -> origin/testcommit3908 + = [up to date] testcommit3909 -> origin/testcommit3909 + = [up to date] testcommit391 -> origin/testcommit391 + = [up to date] testcommit3910 -> origin/testcommit3910 + = [up to date] testcommit3911 -> origin/testcommit3911 + = [up to date] testcommit3912 -> origin/testcommit3912 + = [up to date] testcommit3913 -> origin/testcommit3913 + = [up to date] testcommit3914 -> origin/testcommit3914 + = [up to date] testcommit3915 -> origin/testcommit3915 + = [up to date] testcommit3916 -> origin/testcommit3916 + = [up to date] testcommit3917 -> origin/testcommit3917 + = [up to date] testcommit3918 -> origin/testcommit3918 + = [up to date] testcommit3919 -> origin/testcommit3919 + = [up to date] testcommit392 -> origin/testcommit392 + = [up to date] testcommit3920 -> origin/testcommit3920 + = [up to date] testcommit3921 -> origin/testcommit3921 + = [up to date] testcommit3922 -> origin/testcommit3922 + = [up to date] testcommit3923 -> origin/testcommit3923 + = [up to date] testcommit3924 -> origin/testcommit3924 + = [up to date] testcommit3925 -> origin/testcommit3925 + = [up to date] testcommit3926 -> origin/testcommit3926 + = [up to date] testcommit3927 -> origin/testcommit3927 + = [up to date] testcommit3928 -> origin/testcommit3928 + = [up to date] testcommit3929 -> origin/testcommit3929 + = [up to date] testcommit393 -> origin/testcommit393 + = [up to date] testcommit3930 -> origin/testcommit3930 + = [up to date] testcommit3931 -> origin/testcommit3931 + = [up to date] testcommit3932 -> origin/testcommit3932 + = [up to date] testcommit3933 -> origin/testcommit3933 + = [up to date] testcommit3934 -> origin/testcommit3934 + = [up to date] testcommit3935 -> origin/testcommit3935 + = [up to date] testcommit3936 -> origin/testcommit3936 + = [up to date] testcommit3937 -> origin/testcommit3937 + = [up to date] testcommit3938 -> origin/testcommit3938 + = [up to date] testcommit3939 -> origin/testcommit3939 + = [up to date] testcommit394 -> origin/testcommit394 + = [up to date] testcommit3940 -> origin/testcommit3940 + = [up to date] testcommit3941 -> origin/testcommit3941 + = [up to date] testcommit3942 -> origin/testcommit3942 + = [up to date] testcommit3943 -> origin/testcommit3943 + = [up to date] testcommit3944 -> origin/testcommit3944 + = [up to date] testcommit3945 -> origin/testcommit3945 + = [up to date] testcommit3946 -> origin/testcommit3946 + = [up to date] testcommit3947 -> origin/testcommit3947 + = [up to date] testcommit3948 -> origin/testcommit3948 + = [up to date] testcommit3949 -> origin/testcommit3949 + = [up to date] testcommit395 -> origin/testcommit395 + = [up to date] testcommit3950 -> origin/testcommit3950 + = [up to date] testcommit3951 -> origin/testcommit3951 + = [up to date] testcommit3952 -> origin/testcommit3952 + = [up to date] testcommit3953 -> origin/testcommit3953 + = [up to date] testcommit3954 -> origin/testcommit3954 + = [up to date] testcommit3955 -> origin/testcommit3955 + = [up to date] testcommit3956 -> origin/testcommit3956 + = [up to date] testcommit3957 -> origin/testcommit3957 + = [up to date] testcommit3958 -> origin/testcommit3958 + = [up to date] testcommit3959 -> origin/testcommit3959 + = [up to date] testcommit396 -> origin/testcommit396 + = [up to date] testcommit3960 -> origin/testcommit3960 + = [up to date] testcommit3961 -> origin/testcommit3961 + = [up to date] testcommit3962 -> origin/testcommit3962 + = [up to date] testcommit3963 -> origin/testcommit3963 + = [up to date] testcommit3964 -> origin/testcommit3964 + = [up to date] testcommit3965 -> origin/testcommit3965 + = [up to date] testcommit3966 -> origin/testcommit3966 + = [up to date] testcommit3967 -> origin/testcommit3967 + = [up to date] testcommit3968 -> origin/testcommit3968 + = [up to date] testcommit3969 -> origin/testcommit3969 + = [up to date] testcommit397 -> origin/testcommit397 + = [up to date] testcommit3970 -> origin/testcommit3970 + = [up to date] testcommit3971 -> origin/testcommit3971 + = [up to date] testcommit3972 -> origin/testcommit3972 + = [up to date] testcommit3973 -> origin/testcommit3973 + = [up to date] testcommit3974 -> origin/testcommit3974 + = [up to date] testcommit3975 -> origin/testcommit3975 + = [up to date] testcommit3976 -> origin/testcommit3976 + = [up to date] testcommit3977 -> origin/testcommit3977 + = [up to date] testcommit3978 -> origin/testcommit3978 + = [up to date] testcommit3979 -> origin/testcommit3979 + = [up to date] testcommit398 -> origin/testcommit398 + = [up to date] testcommit3980 -> origin/testcommit3980 + = [up to date] testcommit3981 -> origin/testcommit3981 + = [up to date] testcommit3982 -> origin/testcommit3982 + = [up to date] testcommit3983 -> origin/testcommit3983 + = [up to date] testcommit3984 -> origin/testcommit3984 + = [up to date] testcommit3985 -> origin/testcommit3985 + = [up to date] testcommit3986 -> origin/testcommit3986 + = [up to date] testcommit3987 -> origin/testcommit3987 + = [up to date] testcommit3988 -> origin/testcommit3988 + = [up to date] testcommit3989 -> origin/testcommit3989 + = [up to date] testcommit399 -> origin/testcommit399 + = [up to date] testcommit3990 -> origin/testcommit3990 + = [up to date] testcommit3991 -> origin/testcommit3991 + = [up to date] testcommit3992 -> origin/testcommit3992 + = [up to date] testcommit3993 -> origin/testcommit3993 + = [up to date] testcommit3994 -> origin/testcommit3994 + = [up to date] testcommit3995 -> origin/testcommit3995 + = [up to date] testcommit3996 -> origin/testcommit3996 + = [up to date] testcommit3997 -> origin/testcommit3997 + = [up to date] testcommit3998 -> origin/testcommit3998 + = [up to date] testcommit3999 -> origin/testcommit3999 + = [up to date] testcommit4 -> origin/testcommit4 + = [up to date] testcommit40 -> origin/testcommit40 + = [up to date] testcommit400 -> origin/testcommit400 + = [up to date] testcommit4000 -> origin/testcommit4000 + = [up to date] testcommit4001 -> origin/testcommit4001 + = [up to date] testcommit4002 -> origin/testcommit4002 + = [up to date] testcommit4003 -> origin/testcommit4003 + = [up to date] testcommit4004 -> origin/testcommit4004 + = [up to date] testcommit4005 -> origin/testcommit4005 + = [up to date] testcommit4006 -> origin/testcommit4006 + = [up to date] testcommit4007 -> origin/testcommit4007 + = [up to date] testcommit4008 -> origin/testcommit4008 + = [up to date] testcommit4009 -> origin/testcommit4009 + = [up to date] testcommit401 -> origin/testcommit401 + = [up to date] testcommit4010 -> origin/testcommit4010 + = [up to date] testcommit4011 -> origin/testcommit4011 + = [up to date] testcommit4012 -> origin/testcommit4012 + = [up to date] testcommit4013 -> origin/testcommit4013 + = [up to date] testcommit4014 -> origin/testcommit4014 + = [up to date] testcommit4015 -> origin/testcommit4015 + = [up to date] testcommit4016 -> origin/testcommit4016 + = [up to date] testcommit4017 -> origin/testcommit4017 + = [up to date] testcommit4018 -> origin/testcommit4018 + = [up to date] testcommit4019 -> origin/testcommit4019 + = [up to date] testcommit402 -> origin/testcommit402 + = [up to date] testcommit4020 -> origin/testcommit4020 + = [up to date] testcommit4021 -> origin/testcommit4021 + = [up to date] testcommit4022 -> origin/testcommit4022 + = [up to date] testcommit4023 -> origin/testcommit4023 + = [up to date] testcommit4024 -> origin/testcommit4024 + = [up to date] testcommit4025 -> origin/testcommit4025 + = [up to date] testcommit4026 -> origin/testcommit4026 + = [up to date] testcommit4027 -> origin/testcommit4027 + = [up to date] testcommit4028 -> origin/testcommit4028 + = [up to date] testcommit4029 -> origin/testcommit4029 + = [up to date] testcommit403 -> origin/testcommit403 + = [up to date] testcommit4030 -> origin/testcommit4030 + = [up to date] testcommit4031 -> origin/testcommit4031 + = [up to date] testcommit4032 -> origin/testcommit4032 + = [up to date] testcommit4033 -> origin/testcommit4033 + = [up to date] testcommit4034 -> origin/testcommit4034 + = [up to date] testcommit4035 -> origin/testcommit4035 + = [up to date] testcommit4036 -> origin/testcommit4036 + = [up to date] testcommit4037 -> origin/testcommit4037 + = [up to date] testcommit4038 -> origin/testcommit4038 + = [up to date] testcommit4039 -> origin/testcommit4039 + = [up to date] testcommit404 -> origin/testcommit404 + = [up to date] testcommit4040 -> origin/testcommit4040 + = [up to date] testcommit4041 -> origin/testcommit4041 + = [up to date] testcommit4042 -> origin/testcommit4042 + = [up to date] testcommit4043 -> origin/testcommit4043 + = [up to date] testcommit4044 -> origin/testcommit4044 + = [up to date] testcommit4045 -> origin/testcommit4045 + = [up to date] testcommit4046 -> origin/testcommit4046 + = [up to date] testcommit4047 -> origin/testcommit4047 + = [up to date] testcommit4048 -> origin/testcommit4048 + = [up to date] testcommit4049 -> origin/testcommit4049 + = [up to date] testcommit405 -> origin/testcommit405 + = [up to date] testcommit4050 -> origin/testcommit4050 + = [up to date] testcommit4051 -> origin/testcommit4051 + = [up to date] testcommit4052 -> origin/testcommit4052 + = [up to date] testcommit4053 -> origin/testcommit4053 + = [up to date] testcommit4054 -> origin/testcommit4054 + = [up to date] testcommit4055 -> origin/testcommit4055 + = [up to date] testcommit4056 -> origin/testcommit4056 + = [up to date] testcommit4057 -> origin/testcommit4057 + = [up to date] testcommit4058 -> origin/testcommit4058 + = [up to date] testcommit4059 -> origin/testcommit4059 + = [up to date] testcommit406 -> origin/testcommit406 + = [up to date] testcommit4060 -> origin/testcommit4060 + = [up to date] testcommit4061 -> origin/testcommit4061 + = [up to date] testcommit4062 -> origin/testcommit4062 + = [up to date] testcommit4063 -> origin/testcommit4063 + = [up to date] testcommit4064 -> origin/testcommit4064 + = [up to date] testcommit4065 -> origin/testcommit4065 + = [up to date] testcommit4066 -> origin/testcommit4066 + = [up to date] testcommit4067 -> origin/testcommit4067 + = [up to date] testcommit4068 -> origin/testcommit4068 + = [up to date] testcommit4069 -> origin/testcommit4069 + = [up to date] testcommit407 -> origin/testcommit407 + = [up to date] testcommit4070 -> origin/testcommit4070 + = [up to date] testcommit4071 -> origin/testcommit4071 + = [up to date] testcommit4072 -> origin/testcommit4072 + = [up to date] testcommit4073 -> origin/testcommit4073 + = [up to date] testcommit4074 -> origin/testcommit4074 + = [up to date] testcommit4075 -> origin/testcommit4075 + = [up to date] testcommit4076 -> origin/testcommit4076 + = [up to date] testcommit4077 -> origin/testcommit4077 + = [up to date] testcommit4078 -> origin/testcommit4078 + = [up to date] testcommit4079 -> origin/testcommit4079 + = [up to date] testcommit408 -> origin/testcommit408 + = [up to date] testcommit4080 -> origin/testcommit4080 + = [up to date] testcommit4081 -> origin/testcommit4081 + = [up to date] testcommit4082 -> origin/testcommit4082 + = [up to date] testcommit4083 -> origin/testcommit4083 + = [up to date] testcommit4084 -> origin/testcommit4084 + = [up to date] testcommit4085 -> origin/testcommit4085 + = [up to date] testcommit4086 -> origin/testcommit4086 + = [up to date] testcommit4087 -> origin/testcommit4087 + = [up to date] testcommit4088 -> origin/testcommit4088 + = [up to date] testcommit4089 -> origin/testcommit4089 + = [up to date] testcommit409 -> origin/testcommit409 + = [up to date] testcommit4090 -> origin/testcommit4090 + = [up to date] testcommit4091 -> origin/testcommit4091 + = [up to date] testcommit4092 -> origin/testcommit4092 + = [up to date] testcommit4093 -> origin/testcommit4093 + = [up to date] testcommit4094 -> origin/testcommit4094 + = [up to date] testcommit4095 -> origin/testcommit4095 + = [up to date] testcommit4096 -> origin/testcommit4096 + = [up to date] testcommit4097 -> origin/testcommit4097 + = [up to date] testcommit4098 -> origin/testcommit4098 + = [up to date] testcommit4099 -> origin/testcommit4099 + = [up to date] testcommit41 -> origin/testcommit41 + = [up to date] testcommit410 -> origin/testcommit410 + = [up to date] testcommit4100 -> origin/testcommit4100 + = [up to date] testcommit4101 -> origin/testcommit4101 + = [up to date] testcommit4102 -> origin/testcommit4102 + = [up to date] testcommit4103 -> origin/testcommit4103 + = [up to date] testcommit4104 -> origin/testcommit4104 + = [up to date] testcommit4105 -> origin/testcommit4105 + = [up to date] testcommit4106 -> origin/testcommit4106 + = [up to date] testcommit4107 -> origin/testcommit4107 + = [up to date] testcommit4108 -> origin/testcommit4108 + = [up to date] testcommit4109 -> origin/testcommit4109 + = [up to date] testcommit411 -> origin/testcommit411 + = [up to date] testcommit4110 -> origin/testcommit4110 + = [up to date] testcommit4111 -> origin/testcommit4111 + = [up to date] testcommit4112 -> origin/testcommit4112 + = [up to date] testcommit4113 -> origin/testcommit4113 + = [up to date] testcommit4114 -> origin/testcommit4114 + = [up to date] testcommit4115 -> origin/testcommit4115 + = [up to date] testcommit4116 -> origin/testcommit4116 + = [up to date] testcommit4117 -> origin/testcommit4117 + = [up to date] testcommit4118 -> origin/testcommit4118 + = [up to date] testcommit4119 -> origin/testcommit4119 + = [up to date] testcommit412 -> origin/testcommit412 + = [up to date] testcommit4120 -> origin/testcommit4120 + = [up to date] testcommit4121 -> origin/testcommit4121 + = [up to date] testcommit4122 -> origin/testcommit4122 + = [up to date] testcommit4123 -> origin/testcommit4123 + = [up to date] testcommit4124 -> origin/testcommit4124 + = [up to date] testcommit4125 -> origin/testcommit4125 + = [up to date] testcommit4126 -> origin/testcommit4126 + = [up to date] testcommit4127 -> origin/testcommit4127 + = [up to date] testcommit4128 -> origin/testcommit4128 + = [up to date] testcommit4129 -> origin/testcommit4129 + = [up to date] testcommit413 -> origin/testcommit413 + = [up to date] testcommit4130 -> origin/testcommit4130 + = [up to date] testcommit4131 -> origin/testcommit4131 + = [up to date] testcommit4132 -> origin/testcommit4132 + = [up to date] testcommit4133 -> origin/testcommit4133 + = [up to date] testcommit4134 -> origin/testcommit4134 + = [up to date] testcommit4135 -> origin/testcommit4135 + = [up to date] testcommit4136 -> origin/testcommit4136 + = [up to date] testcommit4137 -> origin/testcommit4137 + = [up to date] testcommit4138 -> origin/testcommit4138 + = [up to date] testcommit4139 -> origin/testcommit4139 + = [up to date] testcommit414 -> origin/testcommit414 + = [up to date] testcommit4140 -> origin/testcommit4140 + = [up to date] testcommit4141 -> origin/testcommit4141 + = [up to date] testcommit4142 -> origin/testcommit4142 + = [up to date] testcommit4143 -> origin/testcommit4143 + = [up to date] testcommit4144 -> origin/testcommit4144 + = [up to date] testcommit4145 -> origin/testcommit4145 + = [up to date] testcommit4146 -> origin/testcommit4146 + = [up to date] testcommit4147 -> origin/testcommit4147 + = [up to date] testcommit4148 -> origin/testcommit4148 + = [up to date] testcommit4149 -> origin/testcommit4149 + = [up to date] testcommit415 -> origin/testcommit415 + = [up to date] testcommit4150 -> origin/testcommit4150 + = [up to date] testcommit4151 -> origin/testcommit4151 + = [up to date] testcommit4152 -> origin/testcommit4152 + = [up to date] testcommit4153 -> origin/testcommit4153 + = [up to date] testcommit4154 -> origin/testcommit4154 + = [up to date] testcommit4155 -> origin/testcommit4155 + = [up to date] testcommit4156 -> origin/testcommit4156 + = [up to date] testcommit4157 -> origin/testcommit4157 + = [up to date] testcommit4158 -> origin/testcommit4158 + = [up to date] testcommit4159 -> origin/testcommit4159 + = [up to date] testcommit416 -> origin/testcommit416 + = [up to date] testcommit4160 -> origin/testcommit4160 + = [up to date] testcommit4161 -> origin/testcommit4161 + = [up to date] testcommit4162 -> origin/testcommit4162 + = [up to date] testcommit4163 -> origin/testcommit4163 + = [up to date] testcommit4164 -> origin/testcommit4164 + = [up to date] testcommit4165 -> origin/testcommit4165 + = [up to date] testcommit4166 -> origin/testcommit4166 + = [up to date] testcommit4167 -> origin/testcommit4167 + = [up to date] testcommit4168 -> origin/testcommit4168 + = [up to date] testcommit4169 -> origin/testcommit4169 + = [up to date] testcommit417 -> origin/testcommit417 + = [up to date] testcommit4170 -> origin/testcommit4170 + = [up to date] testcommit4171 -> origin/testcommit4171 + = [up to date] testcommit4172 -> origin/testcommit4172 + = [up to date] testcommit4173 -> origin/testcommit4173 + = [up to date] testcommit4174 -> origin/testcommit4174 + = [up to date] testcommit4175 -> origin/testcommit4175 + = [up to date] testcommit4176 -> origin/testcommit4176 + = [up to date] testcommit4177 -> origin/testcommit4177 + = [up to date] testcommit4178 -> origin/testcommit4178 + = [up to date] testcommit4179 -> origin/testcommit4179 + = [up to date] testcommit418 -> origin/testcommit418 + = [up to date] testcommit4180 -> origin/testcommit4180 + = [up to date] testcommit4181 -> origin/testcommit4181 + = [up to date] testcommit4182 -> origin/testcommit4182 + = [up to date] testcommit4183 -> origin/testcommit4183 + = [up to date] testcommit4184 -> origin/testcommit4184 + = [up to date] testcommit4185 -> origin/testcommit4185 + = [up to date] testcommit4186 -> origin/testcommit4186 + = [up to date] testcommit4187 -> origin/testcommit4187 + = [up to date] testcommit4188 -> origin/testcommit4188 + = [up to date] testcommit4189 -> origin/testcommit4189 + = [up to date] testcommit419 -> origin/testcommit419 + = [up to date] testcommit4190 -> origin/testcommit4190 + = [up to date] testcommit4191 -> origin/testcommit4191 + = [up to date] testcommit4192 -> origin/testcommit4192 + = [up to date] testcommit4193 -> origin/testcommit4193 + = [up to date] testcommit4194 -> origin/testcommit4194 + = [up to date] testcommit4195 -> origin/testcommit4195 + = [up to date] testcommit4196 -> origin/testcommit4196 + = [up to date] testcommit4197 -> origin/testcommit4197 + = [up to date] testcommit4198 -> origin/testcommit4198 + = [up to date] testcommit4199 -> origin/testcommit4199 + = [up to date] testcommit42 -> origin/testcommit42 + = [up to date] testcommit420 -> origin/testcommit420 + = [up to date] testcommit4200 -> origin/testcommit4200 + = [up to date] testcommit4201 -> origin/testcommit4201 + = [up to date] testcommit4202 -> origin/testcommit4202 + = [up to date] testcommit4203 -> origin/testcommit4203 + = [up to date] testcommit4204 -> origin/testcommit4204 + = [up to date] testcommit4205 -> origin/testcommit4205 + = [up to date] testcommit4206 -> origin/testcommit4206 + = [up to date] testcommit4207 -> origin/testcommit4207 + = [up to date] testcommit4208 -> origin/testcommit4208 + = [up to date] testcommit4209 -> origin/testcommit4209 + = [up to date] testcommit421 -> origin/testcommit421 + = [up to date] testcommit4210 -> origin/testcommit4210 + = [up to date] testcommit4211 -> origin/testcommit4211 + = [up to date] testcommit4212 -> origin/testcommit4212 + = [up to date] testcommit4213 -> origin/testcommit4213 + = [up to date] testcommit4214 -> origin/testcommit4214 + = [up to date] testcommit4215 -> origin/testcommit4215 + = [up to date] testcommit4216 -> origin/testcommit4216 + = [up to date] testcommit4217 -> origin/testcommit4217 + = [up to date] testcommit4218 -> origin/testcommit4218 + = [up to date] testcommit4219 -> origin/testcommit4219 + = [up to date] testcommit422 -> origin/testcommit422 + = [up to date] testcommit4220 -> origin/testcommit4220 + = [up to date] testcommit4221 -> origin/testcommit4221 + = [up to date] testcommit4222 -> origin/testcommit4222 + = [up to date] testcommit4223 -> origin/testcommit4223 + = [up to date] testcommit4224 -> origin/testcommit4224 + = [up to date] testcommit4225 -> origin/testcommit4225 + = [up to date] testcommit4226 -> origin/testcommit4226 + = [up to date] testcommit4227 -> origin/testcommit4227 + = [up to date] testcommit4228 -> origin/testcommit4228 + = [up to date] testcommit4229 -> origin/testcommit4229 + = [up to date] testcommit423 -> origin/testcommit423 + = [up to date] testcommit4230 -> origin/testcommit4230 + = [up to date] testcommit4231 -> origin/testcommit4231 + = [up to date] testcommit4232 -> origin/testcommit4232 + = [up to date] testcommit4233 -> origin/testcommit4233 + = [up to date] testcommit4234 -> origin/testcommit4234 + = [up to date] testcommit4235 -> origin/testcommit4235 + = [up to date] testcommit4236 -> origin/testcommit4236 + = [up to date] testcommit4237 -> origin/testcommit4237 + = [up to date] testcommit4238 -> origin/testcommit4238 + = [up to date] testcommit4239 -> origin/testcommit4239 + = [up to date] testcommit424 -> origin/testcommit424 + = [up to date] testcommit4240 -> origin/testcommit4240 + = [up to date] testcommit4241 -> origin/testcommit4241 + = [up to date] testcommit4242 -> origin/testcommit4242 + = [up to date] testcommit4243 -> origin/testcommit4243 + = [up to date] testcommit4244 -> origin/testcommit4244 + = [up to date] testcommit4245 -> origin/testcommit4245 + = [up to date] testcommit4246 -> origin/testcommit4246 + = [up to date] testcommit4247 -> origin/testcommit4247 + = [up to date] testcommit4248 -> origin/testcommit4248 + = [up to date] testcommit4249 -> origin/testcommit4249 + = [up to date] testcommit425 -> origin/testcommit425 + = [up to date] testcommit4250 -> origin/testcommit4250 + = [up to date] testcommit4251 -> origin/testcommit4251 + = [up to date] testcommit4252 -> origin/testcommit4252 + = [up to date] testcommit4253 -> origin/testcommit4253 + = [up to date] testcommit4254 -> origin/testcommit4254 + = [up to date] testcommit4255 -> origin/testcommit4255 + = [up to date] testcommit4256 -> origin/testcommit4256 + = [up to date] testcommit4257 -> origin/testcommit4257 + = [up to date] testcommit4258 -> origin/testcommit4258 + = [up to date] testcommit4259 -> origin/testcommit4259 + = [up to date] testcommit426 -> origin/testcommit426 + = [up to date] testcommit4260 -> origin/testcommit4260 + = [up to date] testcommit4261 -> origin/testcommit4261 + = [up to date] testcommit4262 -> origin/testcommit4262 + = [up to date] testcommit4263 -> origin/testcommit4263 + = [up to date] testcommit4264 -> origin/testcommit4264 + = [up to date] testcommit4265 -> origin/testcommit4265 + = [up to date] testcommit4266 -> origin/testcommit4266 + = [up to date] testcommit4267 -> origin/testcommit4267 + = [up to date] testcommit4268 -> origin/testcommit4268 + = [up to date] testcommit4269 -> origin/testcommit4269 + = [up to date] testcommit427 -> origin/testcommit427 + = [up to date] testcommit4270 -> origin/testcommit4270 + = [up to date] testcommit4271 -> origin/testcommit4271 + = [up to date] testcommit4272 -> origin/testcommit4272 + = [up to date] testcommit4273 -> origin/testcommit4273 + = [up to date] testcommit4274 -> origin/testcommit4274 + = [up to date] testcommit4275 -> origin/testcommit4275 + = [up to date] testcommit4276 -> origin/testcommit4276 + = [up to date] testcommit4277 -> origin/testcommit4277 + = [up to date] testcommit4278 -> origin/testcommit4278 + = [up to date] testcommit4279 -> origin/testcommit4279 + = [up to date] testcommit428 -> origin/testcommit428 + = [up to date] testcommit4280 -> origin/testcommit4280 + = [up to date] testcommit4281 -> origin/testcommit4281 + = [up to date] testcommit4282 -> origin/testcommit4282 + = [up to date] testcommit4283 -> origin/testcommit4283 + = [up to date] testcommit4284 -> origin/testcommit4284 + = [up to date] testcommit4285 -> origin/testcommit4285 + = [up to date] testcommit4286 -> origin/testcommit4286 + = [up to date] testcommit4287 -> origin/testcommit4287 + = [up to date] testcommit4288 -> origin/testcommit4288 + = [up to date] testcommit4289 -> origin/testcommit4289 + = [up to date] testcommit429 -> origin/testcommit429 + = [up to date] testcommit4290 -> origin/testcommit4290 + = [up to date] testcommit4291 -> origin/testcommit4291 + = [up to date] testcommit4292 -> origin/testcommit4292 + = [up to date] testcommit4293 -> origin/testcommit4293 + = [up to date] testcommit4294 -> origin/testcommit4294 + = [up to date] testcommit4295 -> origin/testcommit4295 + = [up to date] testcommit4296 -> origin/testcommit4296 + = [up to date] testcommit4297 -> origin/testcommit4297 + = [up to date] testcommit4298 -> origin/testcommit4298 + = [up to date] testcommit4299 -> origin/testcommit4299 + = [up to date] testcommit43 -> origin/testcommit43 + = [up to date] testcommit430 -> origin/testcommit430 + = [up to date] testcommit4300 -> origin/testcommit4300 + = [up to date] testcommit4301 -> origin/testcommit4301 + = [up to date] testcommit4302 -> origin/testcommit4302 + = [up to date] testcommit4303 -> origin/testcommit4303 + = [up to date] testcommit4304 -> origin/testcommit4304 + = [up to date] testcommit4305 -> origin/testcommit4305 + = [up to date] testcommit4306 -> origin/testcommit4306 + = [up to date] testcommit4307 -> origin/testcommit4307 + = [up to date] testcommit4308 -> origin/testcommit4308 + = [up to date] testcommit4309 -> origin/testcommit4309 + = [up to date] testcommit431 -> origin/testcommit431 + = [up to date] testcommit4310 -> origin/testcommit4310 + = [up to date] testcommit4311 -> origin/testcommit4311 + = [up to date] testcommit4312 -> origin/testcommit4312 + = [up to date] testcommit4313 -> origin/testcommit4313 + = [up to date] testcommit4314 -> origin/testcommit4314 + = [up to date] testcommit4315 -> origin/testcommit4315 + = [up to date] testcommit4316 -> origin/testcommit4316 + = [up to date] testcommit4317 -> origin/testcommit4317 + = [up to date] testcommit4318 -> origin/testcommit4318 + = [up to date] testcommit4319 -> origin/testcommit4319 + = [up to date] testcommit432 -> origin/testcommit432 + = [up to date] testcommit4320 -> origin/testcommit4320 + = [up to date] testcommit4321 -> origin/testcommit4321 + = [up to date] testcommit4322 -> origin/testcommit4322 + = [up to date] testcommit4323 -> origin/testcommit4323 + = [up to date] testcommit4324 -> origin/testcommit4324 + = [up to date] testcommit4325 -> origin/testcommit4325 + = [up to date] testcommit4326 -> origin/testcommit4326 + = [up to date] testcommit4327 -> origin/testcommit4327 + = [up to date] testcommit4328 -> origin/testcommit4328 + = [up to date] testcommit4329 -> origin/testcommit4329 + = [up to date] testcommit433 -> origin/testcommit433 + = [up to date] testcommit4330 -> origin/testcommit4330 + = [up to date] testcommit4331 -> origin/testcommit4331 + = [up to date] testcommit4332 -> origin/testcommit4332 + = [up to date] testcommit4333 -> origin/testcommit4333 + = [up to date] testcommit4334 -> origin/testcommit4334 + = [up to date] testcommit4335 -> origin/testcommit4335 + = [up to date] testcommit4336 -> origin/testcommit4336 + = [up to date] testcommit4337 -> origin/testcommit4337 + = [up to date] testcommit4338 -> origin/testcommit4338 + = [up to date] testcommit4339 -> origin/testcommit4339 + = [up to date] testcommit434 -> origin/testcommit434 + = [up to date] testcommit4340 -> origin/testcommit4340 + = [up to date] testcommit4341 -> origin/testcommit4341 + = [up to date] testcommit4342 -> origin/testcommit4342 + = [up to date] testcommit4343 -> origin/testcommit4343 + = [up to date] testcommit4344 -> origin/testcommit4344 + = [up to date] testcommit4345 -> origin/testcommit4345 + = [up to date] testcommit4346 -> origin/testcommit4346 + = [up to date] testcommit4347 -> origin/testcommit4347 + = [up to date] testcommit4348 -> origin/testcommit4348 + = [up to date] testcommit4349 -> origin/testcommit4349 + = [up to date] testcommit435 -> origin/testcommit435 + = [up to date] testcommit4350 -> origin/testcommit4350 + = [up to date] testcommit4351 -> origin/testcommit4351 + = [up to date] testcommit4352 -> origin/testcommit4352 + = [up to date] testcommit4353 -> origin/testcommit4353 + = [up to date] testcommit4354 -> origin/testcommit4354 + = [up to date] testcommit4355 -> origin/testcommit4355 + = [up to date] testcommit4356 -> origin/testcommit4356 + = [up to date] testcommit4357 -> origin/testcommit4357 + = [up to date] testcommit4358 -> origin/testcommit4358 + = [up to date] testcommit4359 -> origin/testcommit4359 + = [up to date] testcommit436 -> origin/testcommit436 + = [up to date] testcommit4360 -> origin/testcommit4360 + = [up to date] testcommit4361 -> origin/testcommit4361 + = [up to date] testcommit4362 -> origin/testcommit4362 + = [up to date] testcommit4363 -> origin/testcommit4363 + = [up to date] testcommit4364 -> origin/testcommit4364 + = [up to date] testcommit4365 -> origin/testcommit4365 + = [up to date] testcommit4366 -> origin/testcommit4366 + = [up to date] testcommit4367 -> origin/testcommit4367 + = [up to date] testcommit4368 -> origin/testcommit4368 + = [up to date] testcommit4369 -> origin/testcommit4369 + = [up to date] testcommit437 -> origin/testcommit437 + = [up to date] testcommit4370 -> origin/testcommit4370 + = [up to date] testcommit4371 -> origin/testcommit4371 + = [up to date] testcommit4372 -> origin/testcommit4372 + = [up to date] testcommit4373 -> origin/testcommit4373 + = [up to date] testcommit4374 -> origin/testcommit4374 + = [up to date] testcommit4375 -> origin/testcommit4375 + = [up to date] testcommit4376 -> origin/testcommit4376 + = [up to date] testcommit4377 -> origin/testcommit4377 + = [up to date] testcommit4378 -> origin/testcommit4378 + = [up to date] testcommit4379 -> origin/testcommit4379 + = [up to date] testcommit438 -> origin/testcommit438 + = [up to date] testcommit4380 -> origin/testcommit4380 + = [up to date] testcommit4381 -> origin/testcommit4381 + = [up to date] testcommit4382 -> origin/testcommit4382 + = [up to date] testcommit4383 -> origin/testcommit4383 + = [up to date] testcommit4384 -> origin/testcommit4384 + = [up to date] testcommit4385 -> origin/testcommit4385 + = [up to date] testcommit4386 -> origin/testcommit4386 + = [up to date] testcommit4387 -> origin/testcommit4387 + = [up to date] testcommit4388 -> origin/testcommit4388 + = [up to date] testcommit4389 -> origin/testcommit4389 + = [up to date] testcommit439 -> origin/testcommit439 + = [up to date] testcommit4390 -> origin/testcommit4390 + = [up to date] testcommit4391 -> origin/testcommit4391 + = [up to date] testcommit4392 -> origin/testcommit4392 + = [up to date] testcommit4393 -> origin/testcommit4393 + = [up to date] testcommit4394 -> origin/testcommit4394 + = [up to date] testcommit4395 -> origin/testcommit4395 + = [up to date] testcommit4396 -> origin/testcommit4396 + = [up to date] testcommit4397 -> origin/testcommit4397 + = [up to date] testcommit4398 -> origin/testcommit4398 + = [up to date] testcommit4399 -> origin/testcommit4399 + = [up to date] testcommit44 -> origin/testcommit44 + = [up to date] testcommit440 -> origin/testcommit440 + = [up to date] testcommit4400 -> origin/testcommit4400 + = [up to date] testcommit4401 -> origin/testcommit4401 + = [up to date] testcommit4402 -> origin/testcommit4402 + = [up to date] testcommit4403 -> origin/testcommit4403 + = [up to date] testcommit4404 -> origin/testcommit4404 + = [up to date] testcommit4405 -> origin/testcommit4405 + = [up to date] testcommit4406 -> origin/testcommit4406 + = [up to date] testcommit4407 -> origin/testcommit4407 + = [up to date] testcommit4408 -> origin/testcommit4408 + = [up to date] testcommit4409 -> origin/testcommit4409 + = [up to date] testcommit441 -> origin/testcommit441 + = [up to date] testcommit4410 -> origin/testcommit4410 + = [up to date] testcommit4411 -> origin/testcommit4411 + = [up to date] testcommit4412 -> origin/testcommit4412 + = [up to date] testcommit4413 -> origin/testcommit4413 + = [up to date] testcommit4414 -> origin/testcommit4414 + = [up to date] testcommit4415 -> origin/testcommit4415 + = [up to date] testcommit4416 -> origin/testcommit4416 + = [up to date] testcommit4417 -> origin/testcommit4417 + = [up to date] testcommit4418 -> origin/testcommit4418 + = [up to date] testcommit4419 -> origin/testcommit4419 + = [up to date] testcommit442 -> origin/testcommit442 + = [up to date] testcommit4420 -> origin/testcommit4420 + = [up to date] testcommit4421 -> origin/testcommit4421 + = [up to date] testcommit4422 -> origin/testcommit4422 + = [up to date] testcommit4423 -> origin/testcommit4423 + = [up to date] testcommit4424 -> origin/testcommit4424 + = [up to date] testcommit4425 -> origin/testcommit4425 + = [up to date] testcommit4426 -> origin/testcommit4426 + = [up to date] testcommit4427 -> origin/testcommit4427 + = [up to date] testcommit4428 -> origin/testcommit4428 + = [up to date] testcommit4429 -> origin/testcommit4429 + = [up to date] testcommit443 -> origin/testcommit443 + = [up to date] testcommit4430 -> origin/testcommit4430 + = [up to date] testcommit4431 -> origin/testcommit4431 + = [up to date] testcommit4432 -> origin/testcommit4432 + = [up to date] testcommit4433 -> origin/testcommit4433 + = [up to date] testcommit4434 -> origin/testcommit4434 + = [up to date] testcommit4435 -> origin/testcommit4435 + = [up to date] testcommit4436 -> origin/testcommit4436 + = [up to date] testcommit4437 -> origin/testcommit4437 + = [up to date] testcommit4438 -> origin/testcommit4438 + = [up to date] testcommit4439 -> origin/testcommit4439 + = [up to date] testcommit444 -> origin/testcommit444 + = [up to date] testcommit4440 -> origin/testcommit4440 + = [up to date] testcommit4441 -> origin/testcommit4441 + = [up to date] testcommit4442 -> origin/testcommit4442 + = [up to date] testcommit4443 -> origin/testcommit4443 + = [up to date] testcommit4444 -> origin/testcommit4444 + = [up to date] testcommit4445 -> origin/testcommit4445 + = [up to date] testcommit4446 -> origin/testcommit4446 + = [up to date] testcommit4447 -> origin/testcommit4447 + = [up to date] testcommit4448 -> origin/testcommit4448 + = [up to date] testcommit4449 -> origin/testcommit4449 + = [up to date] testcommit445 -> origin/testcommit445 + = [up to date] testcommit4450 -> origin/testcommit4450 + = [up to date] testcommit4451 -> origin/testcommit4451 + = [up to date] testcommit4452 -> origin/testcommit4452 + = [up to date] testcommit4453 -> origin/testcommit4453 + = [up to date] testcommit4454 -> origin/testcommit4454 + = [up to date] testcommit4455 -> origin/testcommit4455 + = [up to date] testcommit4456 -> origin/testcommit4456 + = [up to date] testcommit4457 -> origin/testcommit4457 + = [up to date] testcommit4458 -> origin/testcommit4458 + = [up to date] testcommit4459 -> origin/testcommit4459 + = [up to date] testcommit446 -> origin/testcommit446 + = [up to date] testcommit4460 -> origin/testcommit4460 + = [up to date] testcommit4461 -> origin/testcommit4461 + = [up to date] testcommit4462 -> origin/testcommit4462 + = [up to date] testcommit4463 -> origin/testcommit4463 + = [up to date] testcommit4464 -> origin/testcommit4464 + = [up to date] testcommit4465 -> origin/testcommit4465 + = [up to date] testcommit4466 -> origin/testcommit4466 + = [up to date] testcommit4467 -> origin/testcommit4467 + = [up to date] testcommit4468 -> origin/testcommit4468 + = [up to date] testcommit4469 -> origin/testcommit4469 + = [up to date] testcommit447 -> origin/testcommit447 + = [up to date] testcommit4470 -> origin/testcommit4470 + = [up to date] testcommit4471 -> origin/testcommit4471 + = [up to date] testcommit4472 -> origin/testcommit4472 + = [up to date] testcommit4473 -> origin/testcommit4473 + = [up to date] testcommit4474 -> origin/testcommit4474 + = [up to date] testcommit4475 -> origin/testcommit4475 + = [up to date] testcommit4476 -> origin/testcommit4476 + = [up to date] testcommit4477 -> origin/testcommit4477 + = [up to date] testcommit4478 -> origin/testcommit4478 + = [up to date] testcommit4479 -> origin/testcommit4479 + = [up to date] testcommit448 -> origin/testcommit448 + = [up to date] testcommit4480 -> origin/testcommit4480 + = [up to date] testcommit4481 -> origin/testcommit4481 + = [up to date] testcommit4482 -> origin/testcommit4482 + = [up to date] testcommit4483 -> origin/testcommit4483 + = [up to date] testcommit4484 -> origin/testcommit4484 + = [up to date] testcommit4485 -> origin/testcommit4485 + = [up to date] testcommit4486 -> origin/testcommit4486 + = [up to date] testcommit4487 -> origin/testcommit4487 + = [up to date] testcommit4488 -> origin/testcommit4488 + = [up to date] testcommit4489 -> origin/testcommit4489 + = [up to date] testcommit449 -> origin/testcommit449 + = [up to date] testcommit4490 -> origin/testcommit4490 + = [up to date] testcommit4491 -> origin/testcommit4491 + = [up to date] testcommit4492 -> origin/testcommit4492 + = [up to date] testcommit4493 -> origin/testcommit4493 + = [up to date] testcommit4494 -> origin/testcommit4494 + = [up to date] testcommit4495 -> origin/testcommit4495 + = [up to date] testcommit4496 -> origin/testcommit4496 + = [up to date] testcommit4497 -> origin/testcommit4497 + = [up to date] testcommit4498 -> origin/testcommit4498 + = [up to date] testcommit4499 -> origin/testcommit4499 + = [up to date] testcommit45 -> origin/testcommit45 + = [up to date] testcommit450 -> origin/testcommit450 + = [up to date] testcommit4500 -> origin/testcommit4500 + = [up to date] testcommit4501 -> origin/testcommit4501 + = [up to date] testcommit4502 -> origin/testcommit4502 + = [up to date] testcommit4503 -> origin/testcommit4503 + = [up to date] testcommit4504 -> origin/testcommit4504 + = [up to date] testcommit4505 -> origin/testcommit4505 + = [up to date] testcommit4506 -> origin/testcommit4506 + = [up to date] testcommit4507 -> origin/testcommit4507 + = [up to date] testcommit4508 -> origin/testcommit4508 + = [up to date] testcommit4509 -> origin/testcommit4509 + = [up to date] testcommit451 -> origin/testcommit451 + = [up to date] testcommit4510 -> origin/testcommit4510 + = [up to date] testcommit4511 -> origin/testcommit4511 + = [up to date] testcommit4512 -> origin/testcommit4512 + = [up to date] testcommit4513 -> origin/testcommit4513 + = [up to date] testcommit4514 -> origin/testcommit4514 + = [up to date] testcommit4515 -> origin/testcommit4515 + = [up to date] testcommit4516 -> origin/testcommit4516 + = [up to date] testcommit4517 -> origin/testcommit4517 + = [up to date] testcommit4518 -> origin/testcommit4518 + = [up to date] testcommit4519 -> origin/testcommit4519 + = [up to date] testcommit452 -> origin/testcommit452 + = [up to date] testcommit4520 -> origin/testcommit4520 + = [up to date] testcommit4521 -> origin/testcommit4521 + = [up to date] testcommit4522 -> origin/testcommit4522 + = [up to date] testcommit4523 -> origin/testcommit4523 + = [up to date] testcommit4524 -> origin/testcommit4524 + = [up to date] testcommit4525 -> origin/testcommit4525 + = [up to date] testcommit4526 -> origin/testcommit4526 + = [up to date] testcommit4527 -> origin/testcommit4527 + = [up to date] testcommit4528 -> origin/testcommit4528 + = [up to date] testcommit4529 -> origin/testcommit4529 + = [up to date] testcommit453 -> origin/testcommit453 + = [up to date] testcommit4530 -> origin/testcommit4530 + = [up to date] testcommit4531 -> origin/testcommit4531 + = [up to date] testcommit4532 -> origin/testcommit4532 + = [up to date] testcommit4533 -> origin/testcommit4533 + = [up to date] testcommit4534 -> origin/testcommit4534 + = [up to date] testcommit4535 -> origin/testcommit4535 + = [up to date] testcommit4536 -> origin/testcommit4536 + = [up to date] testcommit4537 -> origin/testcommit4537 + = [up to date] testcommit4538 -> origin/testcommit4538 + = [up to date] testcommit4539 -> origin/testcommit4539 + = [up to date] testcommit454 -> origin/testcommit454 + = [up to date] testcommit4540 -> origin/testcommit4540 + = [up to date] testcommit4541 -> origin/testcommit4541 + = [up to date] testcommit4542 -> origin/testcommit4542 + = [up to date] testcommit4543 -> origin/testcommit4543 + = [up to date] testcommit4544 -> origin/testcommit4544 + = [up to date] testcommit4545 -> origin/testcommit4545 + = [up to date] testcommit4546 -> origin/testcommit4546 + = [up to date] testcommit4547 -> origin/testcommit4547 + = [up to date] testcommit4548 -> origin/testcommit4548 + = [up to date] testcommit4549 -> origin/testcommit4549 + = [up to date] testcommit455 -> origin/testcommit455 + = [up to date] testcommit4550 -> origin/testcommit4550 + = [up to date] testcommit4551 -> origin/testcommit4551 + = [up to date] testcommit4552 -> origin/testcommit4552 + = [up to date] testcommit4553 -> origin/testcommit4553 + = [up to date] testcommit4554 -> origin/testcommit4554 + = [up to date] testcommit4555 -> origin/testcommit4555 + = [up to date] testcommit4556 -> origin/testcommit4556 + = [up to date] testcommit4557 -> origin/testcommit4557 + = [up to date] testcommit4558 -> origin/testcommit4558 + = [up to date] testcommit4559 -> origin/testcommit4559 + = [up to date] testcommit456 -> origin/testcommit456 + = [up to date] testcommit4560 -> origin/testcommit4560 + = [up to date] testcommit4561 -> origin/testcommit4561 + = [up to date] testcommit4562 -> origin/testcommit4562 + = [up to date] testcommit4563 -> origin/testcommit4563 + = [up to date] testcommit4564 -> origin/testcommit4564 + = [up to date] testcommit4565 -> origin/testcommit4565 + = [up to date] testcommit4566 -> origin/testcommit4566 + = [up to date] testcommit4567 -> origin/testcommit4567 + = [up to date] testcommit4568 -> origin/testcommit4568 + = [up to date] testcommit4569 -> origin/testcommit4569 + = [up to date] testcommit457 -> origin/testcommit457 + = [up to date] testcommit4570 -> origin/testcommit4570 + = [up to date] testcommit4571 -> origin/testcommit4571 + = [up to date] testcommit4572 -> origin/testcommit4572 + = [up to date] testcommit4573 -> origin/testcommit4573 + = [up to date] testcommit4574 -> origin/testcommit4574 + = [up to date] testcommit4575 -> origin/testcommit4575 + = [up to date] testcommit4576 -> origin/testcommit4576 + = [up to date] testcommit4577 -> origin/testcommit4577 + = [up to date] testcommit4578 -> origin/testcommit4578 + = [up to date] testcommit4579 -> origin/testcommit4579 + = [up to date] testcommit458 -> origin/testcommit458 + = [up to date] testcommit4580 -> origin/testcommit4580 + = [up to date] testcommit4581 -> origin/testcommit4581 + = [up to date] testcommit4582 -> origin/testcommit4582 + = [up to date] testcommit4583 -> origin/testcommit4583 + = [up to date] testcommit4584 -> origin/testcommit4584 + = [up to date] testcommit4585 -> origin/testcommit4585 + = [up to date] testcommit4586 -> origin/testcommit4586 + = [up to date] testcommit4587 -> origin/testcommit4587 + = [up to date] testcommit4588 -> origin/testcommit4588 + = [up to date] testcommit4589 -> origin/testcommit4589 + = [up to date] testcommit459 -> origin/testcommit459 + = [up to date] testcommit4590 -> origin/testcommit4590 + = [up to date] testcommit4591 -> origin/testcommit4591 + = [up to date] testcommit4592 -> origin/testcommit4592 + = [up to date] testcommit4593 -> origin/testcommit4593 + = [up to date] testcommit4594 -> origin/testcommit4594 + = [up to date] testcommit4595 -> origin/testcommit4595 + = [up to date] testcommit4596 -> origin/testcommit4596 + = [up to date] testcommit4597 -> origin/testcommit4597 + = [up to date] testcommit4598 -> origin/testcommit4598 + = [up to date] testcommit4599 -> origin/testcommit4599 + = [up to date] testcommit46 -> origin/testcommit46 + = [up to date] testcommit460 -> origin/testcommit460 + = [up to date] testcommit4600 -> origin/testcommit4600 + = [up to date] testcommit4601 -> origin/testcommit4601 + = [up to date] testcommit4602 -> origin/testcommit4602 + = [up to date] testcommit4603 -> origin/testcommit4603 + = [up to date] testcommit4604 -> origin/testcommit4604 + = [up to date] testcommit4605 -> origin/testcommit4605 + = [up to date] testcommit4606 -> origin/testcommit4606 + = [up to date] testcommit4607 -> origin/testcommit4607 + = [up to date] testcommit4608 -> origin/testcommit4608 + = [up to date] testcommit4609 -> origin/testcommit4609 + = [up to date] testcommit461 -> origin/testcommit461 + = [up to date] testcommit4610 -> origin/testcommit4610 + = [up to date] testcommit4611 -> origin/testcommit4611 + = [up to date] testcommit4612 -> origin/testcommit4612 + = [up to date] testcommit4613 -> origin/testcommit4613 + = [up to date] testcommit4614 -> origin/testcommit4614 + = [up to date] testcommit4615 -> origin/testcommit4615 + = [up to date] testcommit4616 -> origin/testcommit4616 + = [up to date] testcommit4617 -> origin/testcommit4617 + = [up to date] testcommit4618 -> origin/testcommit4618 + = [up to date] testcommit4619 -> origin/testcommit4619 + = [up to date] testcommit462 -> origin/testcommit462 + = [up to date] testcommit4620 -> origin/testcommit4620 + = [up to date] testcommit4621 -> origin/testcommit4621 + = [up to date] testcommit4622 -> origin/testcommit4622 + = [up to date] testcommit4623 -> origin/testcommit4623 + = [up to date] testcommit4624 -> origin/testcommit4624 + = [up to date] testcommit4625 -> origin/testcommit4625 + = [up to date] testcommit4626 -> origin/testcommit4626 + = [up to date] testcommit4627 -> origin/testcommit4627 + = [up to date] testcommit4628 -> origin/testcommit4628 + = [up to date] testcommit4629 -> origin/testcommit4629 + = [up to date] testcommit463 -> origin/testcommit463 + = [up to date] testcommit4630 -> origin/testcommit4630 + = [up to date] testcommit4631 -> origin/testcommit4631 + = [up to date] testcommit4632 -> origin/testcommit4632 + = [up to date] testcommit4633 -> origin/testcommit4633 + = [up to date] testcommit4634 -> origin/testcommit4634 + = [up to date] testcommit4635 -> origin/testcommit4635 + = [up to date] testcommit4636 -> origin/testcommit4636 + = [up to date] testcommit4637 -> origin/testcommit4637 + = [up to date] testcommit4638 -> origin/testcommit4638 + = [up to date] testcommit4639 -> origin/testcommit4639 + = [up to date] testcommit464 -> origin/testcommit464 + = [up to date] testcommit4640 -> origin/testcommit4640 + = [up to date] testcommit4641 -> origin/testcommit4641 + = [up to date] testcommit4642 -> origin/testcommit4642 + = [up to date] testcommit4643 -> origin/testcommit4643 + = [up to date] testcommit4644 -> origin/testcommit4644 + = [up to date] testcommit4645 -> origin/testcommit4645 + = [up to date] testcommit4646 -> origin/testcommit4646 + = [up to date] testcommit4647 -> origin/testcommit4647 + = [up to date] testcommit4648 -> origin/testcommit4648 + = [up to date] testcommit4649 -> origin/testcommit4649 + = [up to date] testcommit465 -> origin/testcommit465 + = [up to date] testcommit4650 -> origin/testcommit4650 + = [up to date] testcommit4651 -> origin/testcommit4651 + = [up to date] testcommit4652 -> origin/testcommit4652 + = [up to date] testcommit4653 -> origin/testcommit4653 + = [up to date] testcommit4654 -> origin/testcommit4654 + = [up to date] testcommit4655 -> origin/testcommit4655 + = [up to date] testcommit4656 -> origin/testcommit4656 + = [up to date] testcommit4657 -> origin/testcommit4657 + = [up to date] testcommit4658 -> origin/testcommit4658 + = [up to date] testcommit4659 -> origin/testcommit4659 + = [up to date] testcommit466 -> origin/testcommit466 + = [up to date] testcommit4660 -> origin/testcommit4660 + = [up to date] testcommit4661 -> origin/testcommit4661 + = [up to date] testcommit4662 -> origin/testcommit4662 + = [up to date] testcommit4663 -> origin/testcommit4663 + = [up to date] testcommit4664 -> origin/testcommit4664 + = [up to date] testcommit4665 -> origin/testcommit4665 + = [up to date] testcommit4666 -> origin/testcommit4666 + = [up to date] testcommit4667 -> origin/testcommit4667 + = [up to date] testcommit4668 -> origin/testcommit4668 + = [up to date] testcommit4669 -> origin/testcommit4669 + = [up to date] testcommit467 -> origin/testcommit467 + = [up to date] testcommit4670 -> origin/testcommit4670 + = [up to date] testcommit4671 -> origin/testcommit4671 + = [up to date] testcommit4672 -> origin/testcommit4672 + = [up to date] testcommit4673 -> origin/testcommit4673 + = [up to date] testcommit4674 -> origin/testcommit4674 + = [up to date] testcommit4675 -> origin/testcommit4675 + = [up to date] testcommit4676 -> origin/testcommit4676 + = [up to date] testcommit4677 -> origin/testcommit4677 + = [up to date] testcommit4678 -> origin/testcommit4678 + = [up to date] testcommit4679 -> origin/testcommit4679 + = [up to date] testcommit468 -> origin/testcommit468 + = [up to date] testcommit4680 -> origin/testcommit4680 + = [up to date] testcommit4681 -> origin/testcommit4681 + = [up to date] testcommit4682 -> origin/testcommit4682 + = [up to date] testcommit4683 -> origin/testcommit4683 + = [up to date] testcommit4684 -> origin/testcommit4684 + = [up to date] testcommit4685 -> origin/testcommit4685 + = [up to date] testcommit4686 -> origin/testcommit4686 + = [up to date] testcommit4687 -> origin/testcommit4687 + = [up to date] testcommit4688 -> origin/testcommit4688 + = [up to date] testcommit4689 -> origin/testcommit4689 + = [up to date] testcommit469 -> origin/testcommit469 + = [up to date] testcommit4690 -> origin/testcommit4690 + = [up to date] testcommit4691 -> origin/testcommit4691 + = [up to date] testcommit4692 -> origin/testcommit4692 + = [up to date] testcommit4693 -> origin/testcommit4693 + = [up to date] testcommit4694 -> origin/testcommit4694 + = [up to date] testcommit4695 -> origin/testcommit4695 + = [up to date] testcommit4696 -> origin/testcommit4696 + = [up to date] testcommit4697 -> origin/testcommit4697 + = [up to date] testcommit4698 -> origin/testcommit4698 + = [up to date] testcommit4699 -> origin/testcommit4699 + = [up to date] testcommit47 -> origin/testcommit47 + = [up to date] testcommit470 -> origin/testcommit470 + = [up to date] testcommit4700 -> origin/testcommit4700 + = [up to date] testcommit4701 -> origin/testcommit4701 + = [up to date] testcommit4702 -> origin/testcommit4702 + = [up to date] testcommit4703 -> origin/testcommit4703 + = [up to date] testcommit4704 -> origin/testcommit4704 + = [up to date] testcommit4705 -> origin/testcommit4705 + = [up to date] testcommit4706 -> origin/testcommit4706 + = [up to date] testcommit4707 -> origin/testcommit4707 + = [up to date] testcommit4708 -> origin/testcommit4708 + = [up to date] testcommit4709 -> origin/testcommit4709 + = [up to date] testcommit471 -> origin/testcommit471 + = [up to date] testcommit4710 -> origin/testcommit4710 + = [up to date] testcommit4711 -> origin/testcommit4711 + = [up to date] testcommit4712 -> origin/testcommit4712 + = [up to date] testcommit4713 -> origin/testcommit4713 + = [up to date] testcommit4714 -> origin/testcommit4714 + = [up to date] testcommit4715 -> origin/testcommit4715 + = [up to date] testcommit4716 -> origin/testcommit4716 + = [up to date] testcommit4717 -> origin/testcommit4717 + = [up to date] testcommit4718 -> origin/testcommit4718 + = [up to date] testcommit4719 -> origin/testcommit4719 + = [up to date] testcommit472 -> origin/testcommit472 + = [up to date] testcommit4720 -> origin/testcommit4720 + = [up to date] testcommit4721 -> origin/testcommit4721 + = [up to date] testcommit4722 -> origin/testcommit4722 + = [up to date] testcommit4723 -> origin/testcommit4723 + = [up to date] testcommit4724 -> origin/testcommit4724 + = [up to date] testcommit4725 -> origin/testcommit4725 + = [up to date] testcommit4726 -> origin/testcommit4726 + = [up to date] testcommit4727 -> origin/testcommit4727 + = [up to date] testcommit4728 -> origin/testcommit4728 + = [up to date] testcommit4729 -> origin/testcommit4729 + = [up to date] testcommit473 -> origin/testcommit473 + = [up to date] testcommit4730 -> origin/testcommit4730 + = [up to date] testcommit4731 -> origin/testcommit4731 + = [up to date] testcommit4732 -> origin/testcommit4732 + = [up to date] testcommit4733 -> origin/testcommit4733 + = [up to date] testcommit4734 -> origin/testcommit4734 + = [up to date] testcommit4735 -> origin/testcommit4735 + = [up to date] testcommit4736 -> origin/testcommit4736 + = [up to date] testcommit4737 -> origin/testcommit4737 + = [up to date] testcommit4738 -> origin/testcommit4738 + = [up to date] testcommit4739 -> origin/testcommit4739 + = [up to date] testcommit474 -> origin/testcommit474 + = [up to date] testcommit4740 -> origin/testcommit4740 + = [up to date] testcommit4741 -> origin/testcommit4741 + = [up to date] testcommit4742 -> origin/testcommit4742 + = [up to date] testcommit4743 -> origin/testcommit4743 + = [up to date] testcommit4744 -> origin/testcommit4744 + = [up to date] testcommit4745 -> origin/testcommit4745 + = [up to date] testcommit4746 -> origin/testcommit4746 + = [up to date] testcommit4747 -> origin/testcommit4747 + = [up to date] testcommit4748 -> origin/testcommit4748 + = [up to date] testcommit4749 -> origin/testcommit4749 + = [up to date] testcommit475 -> origin/testcommit475 + = [up to date] testcommit4750 -> origin/testcommit4750 + = [up to date] testcommit4751 -> origin/testcommit4751 + = [up to date] testcommit4752 -> origin/testcommit4752 + = [up to date] testcommit4753 -> origin/testcommit4753 + = [up to date] testcommit4754 -> origin/testcommit4754 + = [up to date] testcommit4755 -> origin/testcommit4755 + = [up to date] testcommit4756 -> origin/testcommit4756 + = [up to date] testcommit4757 -> origin/testcommit4757 + = [up to date] testcommit4758 -> origin/testcommit4758 + = [up to date] testcommit4759 -> origin/testcommit4759 + = [up to date] testcommit476 -> origin/testcommit476 + = [up to date] testcommit4760 -> origin/testcommit4760 + = [up to date] testcommit4761 -> origin/testcommit4761 + = [up to date] testcommit4762 -> origin/testcommit4762 + = [up to date] testcommit4763 -> origin/testcommit4763 + = [up to date] testcommit4764 -> origin/testcommit4764 + = [up to date] testcommit4765 -> origin/testcommit4765 + = [up to date] testcommit4766 -> origin/testcommit4766 + = [up to date] testcommit4767 -> origin/testcommit4767 + = [up to date] testcommit4768 -> origin/testcommit4768 + = [up to date] testcommit4769 -> origin/testcommit4769 + = [up to date] testcommit477 -> origin/testcommit477 + = [up to date] testcommit4770 -> origin/testcommit4770 + = [up to date] testcommit4771 -> origin/testcommit4771 + = [up to date] testcommit4772 -> origin/testcommit4772 + = [up to date] testcommit4773 -> origin/testcommit4773 + = [up to date] testcommit4774 -> origin/testcommit4774 + = [up to date] testcommit4775 -> origin/testcommit4775 + = [up to date] testcommit4776 -> origin/testcommit4776 + = [up to date] testcommit4777 -> origin/testcommit4777 + = [up to date] testcommit4778 -> origin/testcommit4778 + = [up to date] testcommit4779 -> origin/testcommit4779 + = [up to date] testcommit478 -> origin/testcommit478 + = [up to date] testcommit4780 -> origin/testcommit4780 + = [up to date] testcommit4781 -> origin/testcommit4781 + = [up to date] testcommit4782 -> origin/testcommit4782 + = [up to date] testcommit4783 -> origin/testcommit4783 + = [up to date] testcommit4784 -> origin/testcommit4784 + = [up to date] testcommit4785 -> origin/testcommit4785 + = [up to date] testcommit4786 -> origin/testcommit4786 + = [up to date] testcommit4787 -> origin/testcommit4787 + = [up to date] testcommit4788 -> origin/testcommit4788 + = [up to date] testcommit4789 -> origin/testcommit4789 + = [up to date] testcommit479 -> origin/testcommit479 + = [up to date] testcommit4790 -> origin/testcommit4790 + = [up to date] testcommit4791 -> origin/testcommit4791 + = [up to date] testcommit4792 -> origin/testcommit4792 + = [up to date] testcommit4793 -> origin/testcommit4793 + = [up to date] testcommit4794 -> origin/testcommit4794 + = [up to date] testcommit4795 -> origin/testcommit4795 + = [up to date] testcommit4796 -> origin/testcommit4796 + = [up to date] testcommit4797 -> origin/testcommit4797 + = [up to date] testcommit4798 -> origin/testcommit4798 + = [up to date] testcommit4799 -> origin/testcommit4799 + = [up to date] testcommit48 -> origin/testcommit48 + = [up to date] testcommit480 -> origin/testcommit480 + = [up to date] testcommit4800 -> origin/testcommit4800 + = [up to date] testcommit4801 -> origin/testcommit4801 + = [up to date] testcommit4802 -> origin/testcommit4802 + = [up to date] testcommit4803 -> origin/testcommit4803 + = [up to date] testcommit4804 -> origin/testcommit4804 + = [up to date] testcommit4805 -> origin/testcommit4805 + = [up to date] testcommit4806 -> origin/testcommit4806 + = [up to date] testcommit4807 -> origin/testcommit4807 + = [up to date] testcommit4808 -> origin/testcommit4808 + = [up to date] testcommit4809 -> origin/testcommit4809 + = [up to date] testcommit481 -> origin/testcommit481 + = [up to date] testcommit4810 -> origin/testcommit4810 + = [up to date] testcommit4811 -> origin/testcommit4811 + = [up to date] testcommit4812 -> origin/testcommit4812 + = [up to date] testcommit4813 -> origin/testcommit4813 + = [up to date] testcommit4814 -> origin/testcommit4814 + = [up to date] testcommit4815 -> origin/testcommit4815 + = [up to date] testcommit4816 -> origin/testcommit4816 + = [up to date] testcommit4817 -> origin/testcommit4817 + = [up to date] testcommit4818 -> origin/testcommit4818 + = [up to date] testcommit4819 -> origin/testcommit4819 + = [up to date] testcommit482 -> origin/testcommit482 + = [up to date] testcommit4820 -> origin/testcommit4820 + = [up to date] testcommit4821 -> origin/testcommit4821 + = [up to date] testcommit4822 -> origin/testcommit4822 + = [up to date] testcommit4823 -> origin/testcommit4823 + = [up to date] testcommit4824 -> origin/testcommit4824 + = [up to date] testcommit4825 -> origin/testcommit4825 + = [up to date] testcommit4826 -> origin/testcommit4826 + = [up to date] testcommit4827 -> origin/testcommit4827 + = [up to date] testcommit4828 -> origin/testcommit4828 + = [up to date] testcommit4829 -> origin/testcommit4829 + = [up to date] testcommit483 -> origin/testcommit483 + = [up to date] testcommit4830 -> origin/testcommit4830 + = [up to date] testcommit4831 -> origin/testcommit4831 + = [up to date] testcommit4832 -> origin/testcommit4832 + = [up to date] testcommit4833 -> origin/testcommit4833 + = [up to date] testcommit4834 -> origin/testcommit4834 + = [up to date] testcommit4835 -> origin/testcommit4835 + = [up to date] testcommit4836 -> origin/testcommit4836 + = [up to date] testcommit4837 -> origin/testcommit4837 + = [up to date] testcommit4838 -> origin/testcommit4838 + = [up to date] testcommit4839 -> origin/testcommit4839 + = [up to date] testcommit484 -> origin/testcommit484 + = [up to date] testcommit4840 -> origin/testcommit4840 + = [up to date] testcommit4841 -> origin/testcommit4841 + = [up to date] testcommit4842 -> origin/testcommit4842 + = [up to date] testcommit4843 -> origin/testcommit4843 + = [up to date] testcommit4844 -> origin/testcommit4844 + = [up to date] testcommit4845 -> origin/testcommit4845 + = [up to date] testcommit4846 -> origin/testcommit4846 + = [up to date] testcommit4847 -> origin/testcommit4847 + = [up to date] testcommit4848 -> origin/testcommit4848 + = [up to date] testcommit4849 -> origin/testcommit4849 + = [up to date] testcommit485 -> origin/testcommit485 + = [up to date] testcommit4850 -> origin/testcommit4850 + = [up to date] testcommit4851 -> origin/testcommit4851 + = [up to date] testcommit4852 -> origin/testcommit4852 + = [up to date] testcommit4853 -> origin/testcommit4853 + = [up to date] testcommit4854 -> origin/testcommit4854 + = [up to date] testcommit4855 -> origin/testcommit4855 + = [up to date] testcommit4856 -> origin/testcommit4856 + = [up to date] testcommit4857 -> origin/testcommit4857 + = [up to date] testcommit4858 -> origin/testcommit4858 + = [up to date] testcommit4859 -> origin/testcommit4859 + = [up to date] testcommit486 -> origin/testcommit486 + = [up to date] testcommit4860 -> origin/testcommit4860 + = [up to date] testcommit4861 -> origin/testcommit4861 + = [up to date] testcommit4862 -> origin/testcommit4862 + = [up to date] testcommit4863 -> origin/testcommit4863 + = [up to date] testcommit4864 -> origin/testcommit4864 + = [up to date] testcommit4865 -> origin/testcommit4865 + = [up to date] testcommit4866 -> origin/testcommit4866 + = [up to date] testcommit4867 -> origin/testcommit4867 + = [up to date] testcommit4868 -> origin/testcommit4868 + = [up to date] testcommit4869 -> origin/testcommit4869 + = [up to date] testcommit487 -> origin/testcommit487 + = [up to date] testcommit4870 -> origin/testcommit4870 + = [up to date] testcommit4871 -> origin/testcommit4871 + = [up to date] testcommit4872 -> origin/testcommit4872 + = [up to date] testcommit4873 -> origin/testcommit4873 + = [up to date] testcommit4874 -> origin/testcommit4874 + = [up to date] testcommit4875 -> origin/testcommit4875 + = [up to date] testcommit4876 -> origin/testcommit4876 + = [up to date] testcommit4877 -> origin/testcommit4877 + = [up to date] testcommit4878 -> origin/testcommit4878 + = [up to date] testcommit4879 -> origin/testcommit4879 + = [up to date] testcommit488 -> origin/testcommit488 + = [up to date] testcommit4880 -> origin/testcommit4880 + = [up to date] testcommit4881 -> origin/testcommit4881 + = [up to date] testcommit4882 -> origin/testcommit4882 + = [up to date] testcommit4883 -> origin/testcommit4883 + = [up to date] testcommit4884 -> origin/testcommit4884 + = [up to date] testcommit4885 -> origin/testcommit4885 + = [up to date] testcommit4886 -> origin/testcommit4886 + = [up to date] testcommit4887 -> origin/testcommit4887 + = [up to date] testcommit4888 -> origin/testcommit4888 + = [up to date] testcommit4889 -> origin/testcommit4889 + = [up to date] testcommit489 -> origin/testcommit489 + = [up to date] testcommit4890 -> origin/testcommit4890 + = [up to date] testcommit4891 -> origin/testcommit4891 + = [up to date] testcommit4892 -> origin/testcommit4892 + = [up to date] testcommit4893 -> origin/testcommit4893 + = [up to date] testcommit4894 -> origin/testcommit4894 + = [up to date] testcommit4895 -> origin/testcommit4895 + = [up to date] testcommit4896 -> origin/testcommit4896 + = [up to date] testcommit4897 -> origin/testcommit4897 + = [up to date] testcommit4898 -> origin/testcommit4898 + = [up to date] testcommit4899 -> origin/testcommit4899 + = [up to date] testcommit49 -> origin/testcommit49 + = [up to date] testcommit490 -> origin/testcommit490 + = [up to date] testcommit4900 -> origin/testcommit4900 + = [up to date] testcommit4901 -> origin/testcommit4901 + = [up to date] testcommit4902 -> origin/testcommit4902 + = [up to date] testcommit4903 -> origin/testcommit4903 + = [up to date] testcommit4904 -> origin/testcommit4904 + = [up to date] testcommit4905 -> origin/testcommit4905 + = [up to date] testcommit4906 -> origin/testcommit4906 + = [up to date] testcommit4907 -> origin/testcommit4907 + = [up to date] testcommit4908 -> origin/testcommit4908 + = [up to date] testcommit4909 -> origin/testcommit4909 + = [up to date] testcommit491 -> origin/testcommit491 + = [up to date] testcommit4910 -> origin/testcommit4910 + = [up to date] testcommit4911 -> origin/testcommit4911 + = [up to date] testcommit4912 -> origin/testcommit4912 + = [up to date] testcommit4913 -> origin/testcommit4913 + = [up to date] testcommit4914 -> origin/testcommit4914 + = [up to date] testcommit4915 -> origin/testcommit4915 + = [up to date] testcommit4916 -> origin/testcommit4916 + = [up to date] testcommit4917 -> origin/testcommit4917 + = [up to date] testcommit4918 -> origin/testcommit4918 + = [up to date] testcommit4919 -> origin/testcommit4919 + = [up to date] testcommit492 -> origin/testcommit492 + = [up to date] testcommit4920 -> origin/testcommit4920 + = [up to date] testcommit4921 -> origin/testcommit4921 + = [up to date] testcommit4922 -> origin/testcommit4922 + = [up to date] testcommit4923 -> origin/testcommit4923 + = [up to date] testcommit4924 -> origin/testcommit4924 + = [up to date] testcommit4925 -> origin/testcommit4925 + = [up to date] testcommit4926 -> origin/testcommit4926 + = [up to date] testcommit4927 -> origin/testcommit4927 + = [up to date] testcommit4928 -> origin/testcommit4928 + = [up to date] testcommit4929 -> origin/testcommit4929 + = [up to date] testcommit493 -> origin/testcommit493 + = [up to date] testcommit4930 -> origin/testcommit4930 + = [up to date] testcommit4931 -> origin/testcommit4931 + = [up to date] testcommit4932 -> origin/testcommit4932 + = [up to date] testcommit4933 -> origin/testcommit4933 + = [up to date] testcommit4934 -> origin/testcommit4934 + = [up to date] testcommit4935 -> origin/testcommit4935 + = [up to date] testcommit4936 -> origin/testcommit4936 + = [up to date] testcommit4937 -> origin/testcommit4937 + = [up to date] testcommit4938 -> origin/testcommit4938 + = [up to date] testcommit4939 -> origin/testcommit4939 + = [up to date] testcommit494 -> origin/testcommit494 + = [up to date] testcommit4940 -> origin/testcommit4940 + = [up to date] testcommit4941 -> origin/testcommit4941 + = [up to date] testcommit4942 -> origin/testcommit4942 + = [up to date] testcommit4943 -> origin/testcommit4943 + = [up to date] testcommit4944 -> origin/testcommit4944 + = [up to date] testcommit4945 -> origin/testcommit4945 + = [up to date] testcommit4946 -> origin/testcommit4946 + = [up to date] testcommit4947 -> origin/testcommit4947 + = [up to date] testcommit4948 -> origin/testcommit4948 + = [up to date] testcommit4949 -> origin/testcommit4949 + = [up to date] testcommit495 -> origin/testcommit495 + = [up to date] testcommit4950 -> origin/testcommit4950 + = [up to date] testcommit4951 -> origin/testcommit4951 + = [up to date] testcommit4952 -> origin/testcommit4952 + = [up to date] testcommit4953 -> origin/testcommit4953 + = [up to date] testcommit4954 -> origin/testcommit4954 + = [up to date] testcommit4955 -> origin/testcommit4955 + = [up to date] testcommit4956 -> origin/testcommit4956 + = [up to date] testcommit4957 -> origin/testcommit4957 + = [up to date] testcommit4958 -> origin/testcommit4958 + = [up to date] testcommit4959 -> origin/testcommit4959 + = [up to date] testcommit496 -> origin/testcommit496 + = [up to date] testcommit4960 -> origin/testcommit4960 + = [up to date] testcommit4961 -> origin/testcommit4961 + = [up to date] testcommit4962 -> origin/testcommit4962 + = [up to date] testcommit4963 -> origin/testcommit4963 + = [up to date] testcommit4964 -> origin/testcommit4964 + = [up to date] testcommit4965 -> origin/testcommit4965 + = [up to date] testcommit4966 -> origin/testcommit4966 + = [up to date] testcommit4967 -> origin/testcommit4967 + = [up to date] testcommit4968 -> origin/testcommit4968 + = [up to date] testcommit4969 -> origin/testcommit4969 + = [up to date] testcommit497 -> origin/testcommit497 + = [up to date] testcommit4970 -> origin/testcommit4970 + = [up to date] testcommit4971 -> origin/testcommit4971 + = [up to date] testcommit4972 -> origin/testcommit4972 + = [up to date] testcommit4973 -> origin/testcommit4973 + = [up to date] testcommit4974 -> origin/testcommit4974 + = [up to date] testcommit4975 -> origin/testcommit4975 + = [up to date] testcommit4976 -> origin/testcommit4976 + = [up to date] testcommit4977 -> origin/testcommit4977 + = [up to date] testcommit4978 -> origin/testcommit4978 + = [up to date] testcommit4979 -> origin/testcommit4979 + = [up to date] testcommit498 -> origin/testcommit498 + = [up to date] testcommit4980 -> origin/testcommit4980 + = [up to date] testcommit4981 -> origin/testcommit4981 + = [up to date] testcommit4982 -> origin/testcommit4982 + = [up to date] testcommit4983 -> origin/testcommit4983 + = [up to date] testcommit4984 -> origin/testcommit4984 + = [up to date] testcommit4985 -> origin/testcommit4985 + = [up to date] testcommit4986 -> origin/testcommit4986 + = [up to date] testcommit4987 -> origin/testcommit4987 + = [up to date] testcommit4988 -> origin/testcommit4988 + = [up to date] testcommit4989 -> origin/testcommit4989 + = [up to date] testcommit499 -> origin/testcommit499 + = [up to date] testcommit4990 -> origin/testcommit4990 + = [up to date] testcommit4991 -> origin/testcommit4991 + = [up to date] testcommit4992 -> origin/testcommit4992 + = [up to date] testcommit4993 -> origin/testcommit4993 + = [up to date] testcommit4994 -> origin/testcommit4994 + = [up to date] testcommit4995 -> origin/testcommit4995 + = [up to date] testcommit4996 -> origin/testcommit4996 + = [up to date] testcommit4997 -> origin/testcommit4997 + = [up to date] testcommit4998 -> origin/testcommit4998 + = [up to date] testcommit4999 -> origin/testcommit4999 + = [up to date] testcommit5 -> origin/testcommit5 + = [up to date] testcommit50 -> origin/testcommit50 + = [up to date] testcommit500 -> origin/testcommit500 + = [up to date] testcommit5000 -> origin/testcommit5000 + = [up to date] testcommit501 -> origin/testcommit501 + = [up to date] testcommit502 -> origin/testcommit502 + = [up to date] testcommit503 -> origin/testcommit503 + = [up to date] testcommit504 -> origin/testcommit504 + = [up to date] testcommit505 -> origin/testcommit505 + = [up to date] testcommit506 -> origin/testcommit506 + = [up to date] testcommit507 -> origin/testcommit507 + = [up to date] testcommit508 -> origin/testcommit508 + = [up to date] testcommit509 -> origin/testcommit509 + = [up to date] testcommit51 -> origin/testcommit51 + = [up to date] testcommit510 -> origin/testcommit510 + = [up to date] testcommit511 -> origin/testcommit511 + = [up to date] testcommit512 -> origin/testcommit512 + = [up to date] testcommit513 -> origin/testcommit513 + = [up to date] testcommit514 -> origin/testcommit514 + = [up to date] testcommit515 -> origin/testcommit515 + = [up to date] testcommit516 -> origin/testcommit516 + = [up to date] testcommit517 -> origin/testcommit517 + = [up to date] testcommit518 -> origin/testcommit518 + = [up to date] testcommit519 -> origin/testcommit519 + = [up to date] testcommit52 -> origin/testcommit52 + = [up to date] testcommit520 -> origin/testcommit520 + = [up to date] testcommit521 -> origin/testcommit521 + = [up to date] testcommit522 -> origin/testcommit522 + = [up to date] testcommit523 -> origin/testcommit523 + = [up to date] testcommit524 -> origin/testcommit524 + = [up to date] testcommit525 -> origin/testcommit525 + = [up to date] testcommit526 -> origin/testcommit526 + = [up to date] testcommit527 -> origin/testcommit527 + = [up to date] testcommit528 -> origin/testcommit528 + = [up to date] testcommit529 -> origin/testcommit529 + = [up to date] testcommit53 -> origin/testcommit53 + = [up to date] testcommit530 -> origin/testcommit530 + = [up to date] testcommit531 -> origin/testcommit531 + = [up to date] testcommit532 -> origin/testcommit532 + = [up to date] testcommit533 -> origin/testcommit533 + = [up to date] testcommit534 -> origin/testcommit534 + = [up to date] testcommit535 -> origin/testcommit535 + = [up to date] testcommit536 -> origin/testcommit536 + = [up to date] testcommit537 -> origin/testcommit537 + = [up to date] testcommit538 -> origin/testcommit538 + = [up to date] testcommit539 -> origin/testcommit539 + = [up to date] testcommit54 -> origin/testcommit54 + = [up to date] testcommit540 -> origin/testcommit540 + = [up to date] testcommit541 -> origin/testcommit541 + = [up to date] testcommit542 -> origin/testcommit542 + = [up to date] testcommit543 -> origin/testcommit543 + = [up to date] testcommit544 -> origin/testcommit544 + = [up to date] testcommit545 -> origin/testcommit545 + = [up to date] testcommit546 -> origin/testcommit546 + = [up to date] testcommit547 -> origin/testcommit547 + = [up to date] testcommit548 -> origin/testcommit548 + = [up to date] testcommit549 -> origin/testcommit549 + = [up to date] testcommit55 -> origin/testcommit55 + = [up to date] testcommit550 -> origin/testcommit550 + = [up to date] testcommit551 -> origin/testcommit551 + = [up to date] testcommit552 -> origin/testcommit552 + = [up to date] testcommit553 -> origin/testcommit553 + = [up to date] testcommit554 -> origin/testcommit554 + = [up to date] testcommit555 -> origin/testcommit555 + = [up to date] testcommit556 -> origin/testcommit556 + = [up to date] testcommit557 -> origin/testcommit557 + = [up to date] testcommit558 -> origin/testcommit558 + = [up to date] testcommit559 -> origin/testcommit559 + = [up to date] testcommit56 -> origin/testcommit56 + = [up to date] testcommit560 -> origin/testcommit560 + = [up to date] testcommit561 -> origin/testcommit561 + = [up to date] testcommit562 -> origin/testcommit562 + = [up to date] testcommit563 -> origin/testcommit563 + = [up to date] testcommit564 -> origin/testcommit564 + = [up to date] testcommit565 -> origin/testcommit565 + = [up to date] testcommit566 -> origin/testcommit566 + = [up to date] testcommit567 -> origin/testcommit567 + = [up to date] testcommit568 -> origin/testcommit568 + = [up to date] testcommit569 -> origin/testcommit569 + = [up to date] testcommit57 -> origin/testcommit57 + = [up to date] testcommit570 -> origin/testcommit570 + = [up to date] testcommit571 -> origin/testcommit571 + = [up to date] testcommit572 -> origin/testcommit572 + = [up to date] testcommit573 -> origin/testcommit573 + = [up to date] testcommit574 -> origin/testcommit574 + = [up to date] testcommit575 -> origin/testcommit575 + = [up to date] testcommit576 -> origin/testcommit576 + = [up to date] testcommit577 -> origin/testcommit577 + = [up to date] testcommit578 -> origin/testcommit578 + = [up to date] testcommit579 -> origin/testcommit579 + = [up to date] testcommit58 -> origin/testcommit58 + = [up to date] testcommit580 -> origin/testcommit580 + = [up to date] testcommit581 -> origin/testcommit581 + = [up to date] testcommit582 -> origin/testcommit582 + = [up to date] testcommit583 -> origin/testcommit583 + = [up to date] testcommit584 -> origin/testcommit584 + = [up to date] testcommit585 -> origin/testcommit585 + = [up to date] testcommit586 -> origin/testcommit586 + = [up to date] testcommit587 -> origin/testcommit587 + = [up to date] testcommit588 -> origin/testcommit588 + = [up to date] testcommit589 -> origin/testcommit589 + = [up to date] testcommit59 -> origin/testcommit59 + = [up to date] testcommit590 -> origin/testcommit590 + = [up to date] testcommit591 -> origin/testcommit591 + = [up to date] testcommit592 -> origin/testcommit592 + = [up to date] testcommit593 -> origin/testcommit593 + = [up to date] testcommit594 -> origin/testcommit594 + = [up to date] testcommit595 -> origin/testcommit595 + = [up to date] testcommit596 -> origin/testcommit596 + = [up to date] testcommit597 -> origin/testcommit597 + = [up to date] testcommit598 -> origin/testcommit598 + = [up to date] testcommit599 -> origin/testcommit599 + = [up to date] testcommit6 -> origin/testcommit6 + = [up to date] testcommit60 -> origin/testcommit60 + = [up to date] testcommit600 -> origin/testcommit600 + = [up to date] testcommit601 -> origin/testcommit601 + = [up to date] testcommit602 -> origin/testcommit602 + = [up to date] testcommit603 -> origin/testcommit603 + = [up to date] testcommit604 -> origin/testcommit604 + = [up to date] testcommit605 -> origin/testcommit605 + = [up to date] testcommit606 -> origin/testcommit606 + = [up to date] testcommit607 -> origin/testcommit607 + = [up to date] testcommit608 -> origin/testcommit608 + = [up to date] testcommit609 -> origin/testcommit609 + = [up to date] testcommit61 -> origin/testcommit61 + = [up to date] testcommit610 -> origin/testcommit610 + = [up to date] testcommit611 -> origin/testcommit611 + = [up to date] testcommit612 -> origin/testcommit612 + = [up to date] testcommit613 -> origin/testcommit613 + = [up to date] testcommit614 -> origin/testcommit614 + = [up to date] testcommit615 -> origin/testcommit615 + = [up to date] testcommit616 -> origin/testcommit616 + = [up to date] testcommit617 -> origin/testcommit617 + = [up to date] testcommit618 -> origin/testcommit618 + = [up to date] testcommit619 -> origin/testcommit619 + = [up to date] testcommit62 -> origin/testcommit62 + = [up to date] testcommit620 -> origin/testcommit620 + = [up to date] testcommit621 -> origin/testcommit621 + = [up to date] testcommit622 -> origin/testcommit622 + = [up to date] testcommit623 -> origin/testcommit623 + = [up to date] testcommit624 -> origin/testcommit624 + = [up to date] testcommit625 -> origin/testcommit625 + = [up to date] testcommit626 -> origin/testcommit626 + = [up to date] testcommit627 -> origin/testcommit627 + = [up to date] testcommit628 -> origin/testcommit628 + = [up to date] testcommit629 -> origin/testcommit629 + = [up to date] testcommit63 -> origin/testcommit63 + = [up to date] testcommit630 -> origin/testcommit630 + = [up to date] testcommit631 -> origin/testcommit631 + = [up to date] testcommit632 -> origin/testcommit632 + = [up to date] testcommit633 -> origin/testcommit633 + = [up to date] testcommit634 -> origin/testcommit634 + = [up to date] testcommit635 -> origin/testcommit635 + = [up to date] testcommit636 -> origin/testcommit636 + = [up to date] testcommit637 -> origin/testcommit637 + = [up to date] testcommit638 -> origin/testcommit638 + = [up to date] testcommit639 -> origin/testcommit639 + = [up to date] testcommit64 -> origin/testcommit64 + = [up to date] testcommit640 -> origin/testcommit640 + = [up to date] testcommit641 -> origin/testcommit641 + = [up to date] testcommit642 -> origin/testcommit642 + = [up to date] testcommit643 -> origin/testcommit643 + = [up to date] testcommit644 -> origin/testcommit644 + = [up to date] testcommit645 -> origin/testcommit645 + = [up to date] testcommit646 -> origin/testcommit646 + = [up to date] testcommit647 -> origin/testcommit647 + = [up to date] testcommit648 -> origin/testcommit648 + = [up to date] testcommit649 -> origin/testcommit649 + = [up to date] testcommit65 -> origin/testcommit65 + = [up to date] testcommit650 -> origin/testcommit650 + = [up to date] testcommit651 -> origin/testcommit651 + = [up to date] testcommit652 -> origin/testcommit652 + = [up to date] testcommit653 -> origin/testcommit653 + = [up to date] testcommit654 -> origin/testcommit654 + = [up to date] testcommit655 -> origin/testcommit655 + = [up to date] testcommit656 -> origin/testcommit656 + = [up to date] testcommit657 -> origin/testcommit657 + = [up to date] testcommit658 -> origin/testcommit658 + = [up to date] testcommit659 -> origin/testcommit659 + = [up to date] testcommit66 -> origin/testcommit66 + = [up to date] testcommit660 -> origin/testcommit660 + = [up to date] testcommit661 -> origin/testcommit661 + = [up to date] testcommit662 -> origin/testcommit662 + = [up to date] testcommit663 -> origin/testcommit663 + = [up to date] testcommit664 -> origin/testcommit664 + = [up to date] testcommit665 -> origin/testcommit665 + = [up to date] testcommit666 -> origin/testcommit666 + = [up to date] testcommit667 -> origin/testcommit667 + = [up to date] testcommit668 -> origin/testcommit668 + = [up to date] testcommit669 -> origin/testcommit669 + = [up to date] testcommit67 -> origin/testcommit67 + = [up to date] testcommit670 -> origin/testcommit670 + = [up to date] testcommit671 -> origin/testcommit671 + = [up to date] testcommit672 -> origin/testcommit672 + = [up to date] testcommit673 -> origin/testcommit673 + = [up to date] testcommit674 -> origin/testcommit674 + = [up to date] testcommit675 -> origin/testcommit675 + = [up to date] testcommit676 -> origin/testcommit676 + = [up to date] testcommit677 -> origin/testcommit677 + = [up to date] testcommit678 -> origin/testcommit678 + = [up to date] testcommit679 -> origin/testcommit679 + = [up to date] testcommit68 -> origin/testcommit68 + = [up to date] testcommit680 -> origin/testcommit680 + = [up to date] testcommit681 -> origin/testcommit681 + = [up to date] testcommit682 -> origin/testcommit682 + = [up to date] testcommit683 -> origin/testcommit683 + = [up to date] testcommit684 -> origin/testcommit684 + = [up to date] testcommit685 -> origin/testcommit685 + = [up to date] testcommit686 -> origin/testcommit686 + = [up to date] testcommit687 -> origin/testcommit687 + = [up to date] testcommit688 -> origin/testcommit688 + = [up to date] testcommit689 -> origin/testcommit689 + = [up to date] testcommit69 -> origin/testcommit69 + = [up to date] testcommit690 -> origin/testcommit690 + = [up to date] testcommit691 -> origin/testcommit691 + = [up to date] testcommit692 -> origin/testcommit692 + = [up to date] testcommit693 -> origin/testcommit693 + = [up to date] testcommit694 -> origin/testcommit694 + = [up to date] testcommit695 -> origin/testcommit695 + = [up to date] testcommit696 -> origin/testcommit696 + = [up to date] testcommit697 -> origin/testcommit697 + = [up to date] testcommit698 -> origin/testcommit698 + = [up to date] testcommit699 -> origin/testcommit699 + = [up to date] testcommit7 -> origin/testcommit7 + = [up to date] testcommit70 -> origin/testcommit70 + = [up to date] testcommit700 -> origin/testcommit700 + = [up to date] testcommit701 -> origin/testcommit701 + = [up to date] testcommit702 -> origin/testcommit702 + = [up to date] testcommit703 -> origin/testcommit703 + = [up to date] testcommit704 -> origin/testcommit704 + = [up to date] testcommit705 -> origin/testcommit705 + = [up to date] testcommit706 -> origin/testcommit706 + = [up to date] testcommit707 -> origin/testcommit707 + = [up to date] testcommit708 -> origin/testcommit708 + = [up to date] testcommit709 -> origin/testcommit709 + = [up to date] testcommit71 -> origin/testcommit71 + = [up to date] testcommit710 -> origin/testcommit710 + = [up to date] testcommit711 -> origin/testcommit711 + = [up to date] testcommit712 -> origin/testcommit712 + = [up to date] testcommit713 -> origin/testcommit713 + = [up to date] testcommit714 -> origin/testcommit714 + = [up to date] testcommit715 -> origin/testcommit715 + = [up to date] testcommit716 -> origin/testcommit716 + = [up to date] testcommit717 -> origin/testcommit717 + = [up to date] testcommit718 -> origin/testcommit718 + = [up to date] testcommit719 -> origin/testcommit719 + = [up to date] testcommit72 -> origin/testcommit72 + = [up to date] testcommit720 -> origin/testcommit720 + = [up to date] testcommit721 -> origin/testcommit721 + = [up to date] testcommit722 -> origin/testcommit722 + = [up to date] testcommit723 -> origin/testcommit723 + = [up to date] testcommit724 -> origin/testcommit724 + = [up to date] testcommit725 -> origin/testcommit725 + = [up to date] testcommit726 -> origin/testcommit726 + = [up to date] testcommit727 -> origin/testcommit727 + = [up to date] testcommit728 -> origin/testcommit728 + = [up to date] testcommit729 -> origin/testcommit729 + = [up to date] testcommit73 -> origin/testcommit73 + = [up to date] testcommit730 -> origin/testcommit730 + = [up to date] testcommit731 -> origin/testcommit731 + = [up to date] testcommit732 -> origin/testcommit732 + = [up to date] testcommit733 -> origin/testcommit733 + = [up to date] testcommit734 -> origin/testcommit734 + = [up to date] testcommit735 -> origin/testcommit735 + = [up to date] testcommit736 -> origin/testcommit736 + = [up to date] testcommit737 -> origin/testcommit737 + = [up to date] testcommit738 -> origin/testcommit738 + = [up to date] testcommit739 -> origin/testcommit739 + = [up to date] testcommit74 -> origin/testcommit74 + = [up to date] testcommit740 -> origin/testcommit740 + = [up to date] testcommit741 -> origin/testcommit741 + = [up to date] testcommit742 -> origin/testcommit742 + = [up to date] testcommit743 -> origin/testcommit743 + = [up to date] testcommit744 -> origin/testcommit744 + = [up to date] testcommit745 -> origin/testcommit745 + = [up to date] testcommit746 -> origin/testcommit746 + = [up to date] testcommit747 -> origin/testcommit747 + = [up to date] testcommit748 -> origin/testcommit748 + = [up to date] testcommit749 -> origin/testcommit749 + = [up to date] testcommit75 -> origin/testcommit75 + = [up to date] testcommit750 -> origin/testcommit750 + = [up to date] testcommit751 -> origin/testcommit751 + = [up to date] testcommit752 -> origin/testcommit752 + = [up to date] testcommit753 -> origin/testcommit753 + = [up to date] testcommit754 -> origin/testcommit754 + = [up to date] testcommit755 -> origin/testcommit755 + = [up to date] testcommit756 -> origin/testcommit756 + = [up to date] testcommit757 -> origin/testcommit757 + = [up to date] testcommit758 -> origin/testcommit758 + = [up to date] testcommit759 -> origin/testcommit759 + = [up to date] testcommit76 -> origin/testcommit76 + = [up to date] testcommit760 -> origin/testcommit760 + = [up to date] testcommit761 -> origin/testcommit761 + = [up to date] testcommit762 -> origin/testcommit762 + = [up to date] testcommit763 -> origin/testcommit763 + = [up to date] testcommit764 -> origin/testcommit764 + = [up to date] testcommit765 -> origin/testcommit765 + = [up to date] testcommit766 -> origin/testcommit766 + = [up to date] testcommit767 -> origin/testcommit767 + = [up to date] testcommit768 -> origin/testcommit768 + = [up to date] testcommit769 -> origin/testcommit769 + = [up to date] testcommit77 -> origin/testcommit77 + = [up to date] testcommit770 -> origin/testcommit770 + = [up to date] testcommit771 -> origin/testcommit771 + = [up to date] testcommit772 -> origin/testcommit772 + = [up to date] testcommit773 -> origin/testcommit773 + = [up to date] testcommit774 -> origin/testcommit774 + = [up to date] testcommit775 -> origin/testcommit775 + = [up to date] testcommit776 -> origin/testcommit776 + = [up to date] testcommit777 -> origin/testcommit777 + = [up to date] testcommit778 -> origin/testcommit778 + = [up to date] testcommit779 -> origin/testcommit779 + = [up to date] testcommit78 -> origin/testcommit78 + = [up to date] testcommit780 -> origin/testcommit780 + = [up to date] testcommit781 -> origin/testcommit781 + = [up to date] testcommit782 -> origin/testcommit782 + = [up to date] testcommit783 -> origin/testcommit783 + = [up to date] testcommit784 -> origin/testcommit784 + = [up to date] testcommit785 -> origin/testcommit785 + = [up to date] testcommit786 -> origin/testcommit786 + = [up to date] testcommit787 -> origin/testcommit787 + = [up to date] testcommit788 -> origin/testcommit788 + = [up to date] testcommit789 -> origin/testcommit789 + = [up to date] testcommit79 -> origin/testcommit79 + = [up to date] testcommit790 -> origin/testcommit790 + = [up to date] testcommit791 -> origin/testcommit791 + = [up to date] testcommit792 -> origin/testcommit792 + = [up to date] testcommit793 -> origin/testcommit793 + = [up to date] testcommit794 -> origin/testcommit794 + = [up to date] testcommit795 -> origin/testcommit795 + = [up to date] testcommit796 -> origin/testcommit796 + = [up to date] testcommit797 -> origin/testcommit797 + = [up to date] testcommit798 -> origin/testcommit798 + = [up to date] testcommit799 -> origin/testcommit799 + = [up to date] testcommit8 -> origin/testcommit8 + = [up to date] testcommit80 -> origin/testcommit80 + = [up to date] testcommit800 -> origin/testcommit800 + = [up to date] testcommit801 -> origin/testcommit801 + = [up to date] testcommit802 -> origin/testcommit802 + = [up to date] testcommit803 -> origin/testcommit803 + = [up to date] testcommit804 -> origin/testcommit804 + = [up to date] testcommit805 -> origin/testcommit805 + = [up to date] testcommit806 -> origin/testcommit806 + = [up to date] testcommit807 -> origin/testcommit807 + = [up to date] testcommit808 -> origin/testcommit808 + = [up to date] testcommit809 -> origin/testcommit809 + = [up to date] testcommit81 -> origin/testcommit81 + = [up to date] testcommit810 -> origin/testcommit810 + = [up to date] testcommit811 -> origin/testcommit811 + = [up to date] testcommit812 -> origin/testcommit812 + = [up to date] testcommit813 -> origin/testcommit813 + = [up to date] testcommit814 -> origin/testcommit814 + = [up to date] testcommit815 -> origin/testcommit815 + = [up to date] testcommit816 -> origin/testcommit816 + = [up to date] testcommit817 -> origin/testcommit817 + = [up to date] testcommit818 -> origin/testcommit818 + = [up to date] testcommit819 -> origin/testcommit819 + = [up to date] testcommit82 -> origin/testcommit82 + = [up to date] testcommit820 -> origin/testcommit820 + = [up to date] testcommit821 -> origin/testcommit821 + = [up to date] testcommit822 -> origin/testcommit822 + = [up to date] testcommit823 -> origin/testcommit823 + = [up to date] testcommit824 -> origin/testcommit824 + = [up to date] testcommit825 -> origin/testcommit825 + = [up to date] testcommit826 -> origin/testcommit826 + = [up to date] testcommit827 -> origin/testcommit827 + = [up to date] testcommit828 -> origin/testcommit828 + = [up to date] testcommit829 -> origin/testcommit829 + = [up to date] testcommit83 -> origin/testcommit83 + = [up to date] testcommit830 -> origin/testcommit830 + = [up to date] testcommit831 -> origin/testcommit831 + = [up to date] testcommit832 -> origin/testcommit832 + = [up to date] testcommit833 -> origin/testcommit833 + = [up to date] testcommit834 -> origin/testcommit834 + = [up to date] testcommit835 -> origin/testcommit835 + = [up to date] testcommit836 -> origin/testcommit836 + = [up to date] testcommit837 -> origin/testcommit837 + = [up to date] testcommit838 -> origin/testcommit838 + = [up to date] testcommit839 -> origin/testcommit839 + = [up to date] testcommit84 -> origin/testcommit84 + = [up to date] testcommit840 -> origin/testcommit840 + = [up to date] testcommit841 -> origin/testcommit841 + = [up to date] testcommit842 -> origin/testcommit842 + = [up to date] testcommit843 -> origin/testcommit843 + = [up to date] testcommit844 -> origin/testcommit844 + = [up to date] testcommit845 -> origin/testcommit845 + = [up to date] testcommit846 -> origin/testcommit846 + = [up to date] testcommit847 -> origin/testcommit847 + = [up to date] testcommit848 -> origin/testcommit848 + = [up to date] testcommit849 -> origin/testcommit849 + = [up to date] testcommit85 -> origin/testcommit85 + = [up to date] testcommit850 -> origin/testcommit850 + = [up to date] testcommit851 -> origin/testcommit851 + = [up to date] testcommit852 -> origin/testcommit852 + = [up to date] testcommit853 -> origin/testcommit853 + = [up to date] testcommit854 -> origin/testcommit854 + = [up to date] testcommit855 -> origin/testcommit855 + = [up to date] testcommit856 -> origin/testcommit856 + = [up to date] testcommit857 -> origin/testcommit857 + = [up to date] testcommit858 -> origin/testcommit858 + = [up to date] testcommit859 -> origin/testcommit859 + = [up to date] testcommit86 -> origin/testcommit86 + = [up to date] testcommit860 -> origin/testcommit860 + = [up to date] testcommit861 -> origin/testcommit861 + = [up to date] testcommit862 -> origin/testcommit862 + = [up to date] testcommit863 -> origin/testcommit863 + = [up to date] testcommit864 -> origin/testcommit864 + = [up to date] testcommit865 -> origin/testcommit865 + = [up to date] testcommit866 -> origin/testcommit866 + = [up to date] testcommit867 -> origin/testcommit867 + = [up to date] testcommit868 -> origin/testcommit868 + = [up to date] testcommit869 -> origin/testcommit869 + = [up to date] testcommit87 -> origin/testcommit87 + = [up to date] testcommit870 -> origin/testcommit870 + = [up to date] testcommit871 -> origin/testcommit871 + = [up to date] testcommit872 -> origin/testcommit872 + = [up to date] testcommit873 -> origin/testcommit873 + = [up to date] testcommit874 -> origin/testcommit874 + = [up to date] testcommit875 -> origin/testcommit875 + = [up to date] testcommit876 -> origin/testcommit876 + = [up to date] testcommit877 -> origin/testcommit877 + = [up to date] testcommit878 -> origin/testcommit878 + = [up to date] testcommit879 -> origin/testcommit879 + = [up to date] testcommit88 -> origin/testcommit88 + = [up to date] testcommit880 -> origin/testcommit880 + = [up to date] testcommit881 -> origin/testcommit881 + = [up to date] testcommit882 -> origin/testcommit882 + = [up to date] testcommit883 -> origin/testcommit883 + = [up to date] testcommit884 -> origin/testcommit884 + = [up to date] testcommit885 -> origin/testcommit885 + = [up to date] testcommit886 -> origin/testcommit886 + = [up to date] testcommit887 -> origin/testcommit887 + = [up to date] testcommit888 -> origin/testcommit888 + = [up to date] testcommit889 -> origin/testcommit889 + = [up to date] testcommit89 -> origin/testcommit89 + = [up to date] testcommit890 -> origin/testcommit890 + = [up to date] testcommit891 -> origin/testcommit891 + = [up to date] testcommit892 -> origin/testcommit892 + = [up to date] testcommit893 -> origin/testcommit893 + = [up to date] testcommit894 -> origin/testcommit894 + = [up to date] testcommit895 -> origin/testcommit895 + = [up to date] testcommit896 -> origin/testcommit896 + = [up to date] testcommit897 -> origin/testcommit897 + = [up to date] testcommit898 -> origin/testcommit898 + = [up to date] testcommit899 -> origin/testcommit899 + = [up to date] testcommit9 -> origin/testcommit9 + = [up to date] testcommit90 -> origin/testcommit90 + = [up to date] testcommit900 -> origin/testcommit900 + = [up to date] testcommit901 -> origin/testcommit901 + = [up to date] testcommit902 -> origin/testcommit902 + = [up to date] testcommit903 -> origin/testcommit903 + = [up to date] testcommit904 -> origin/testcommit904 + = [up to date] testcommit905 -> origin/testcommit905 + = [up to date] testcommit906 -> origin/testcommit906 + = [up to date] testcommit907 -> origin/testcommit907 + = [up to date] testcommit908 -> origin/testcommit908 + = [up to date] testcommit909 -> origin/testcommit909 + = [up to date] testcommit91 -> origin/testcommit91 + = [up to date] testcommit910 -> origin/testcommit910 + = [up to date] testcommit911 -> origin/testcommit911 + = [up to date] testcommit912 -> origin/testcommit912 + = [up to date] testcommit913 -> origin/testcommit913 + = [up to date] testcommit914 -> origin/testcommit914 + = [up to date] testcommit915 -> origin/testcommit915 + = [up to date] testcommit916 -> origin/testcommit916 + = [up to date] testcommit917 -> origin/testcommit917 + = [up to date] testcommit918 -> origin/testcommit918 + = [up to date] testcommit919 -> origin/testcommit919 + = [up to date] testcommit92 -> origin/testcommit92 + = [up to date] testcommit920 -> origin/testcommit920 + = [up to date] testcommit921 -> origin/testcommit921 + = [up to date] testcommit922 -> origin/testcommit922 + = [up to date] testcommit923 -> origin/testcommit923 + = [up to date] testcommit924 -> origin/testcommit924 + = [up to date] testcommit925 -> origin/testcommit925 + = [up to date] testcommit926 -> origin/testcommit926 + = [up to date] testcommit927 -> origin/testcommit927 + = [up to date] testcommit928 -> origin/testcommit928 + = [up to date] testcommit929 -> origin/testcommit929 + = [up to date] testcommit93 -> origin/testcommit93 + = [up to date] testcommit930 -> origin/testcommit930 + = [up to date] testcommit931 -> origin/testcommit931 + = [up to date] testcommit932 -> origin/testcommit932 + = [up to date] testcommit933 -> origin/testcommit933 + = [up to date] testcommit934 -> origin/testcommit934 + = [up to date] testcommit935 -> origin/testcommit935 + = [up to date] testcommit936 -> origin/testcommit936 + = [up to date] testcommit937 -> origin/testcommit937 + = [up to date] testcommit938 -> origin/testcommit938 + = [up to date] testcommit939 -> origin/testcommit939 + = [up to date] testcommit94 -> origin/testcommit94 + = [up to date] testcommit940 -> origin/testcommit940 + = [up to date] testcommit941 -> origin/testcommit941 + = [up to date] testcommit942 -> origin/testcommit942 + = [up to date] testcommit943 -> origin/testcommit943 + = [up to date] testcommit944 -> origin/testcommit944 + = [up to date] testcommit945 -> origin/testcommit945 + = [up to date] testcommit946 -> origin/testcommit946 + = [up to date] testcommit947 -> origin/testcommit947 + = [up to date] testcommit948 -> origin/testcommit948 + = [up to date] testcommit949 -> origin/testcommit949 + = [up to date] testcommit95 -> origin/testcommit95 + = [up to date] testcommit950 -> origin/testcommit950 + = [up to date] testcommit951 -> origin/testcommit951 + = [up to date] testcommit952 -> origin/testcommit952 + = [up to date] testcommit953 -> origin/testcommit953 + = [up to date] testcommit954 -> origin/testcommit954 + = [up to date] testcommit955 -> origin/testcommit955 + = [up to date] testcommit956 -> origin/testcommit956 + = [up to date] testcommit957 -> origin/testcommit957 + = [up to date] testcommit958 -> origin/testcommit958 + = [up to date] testcommit959 -> origin/testcommit959 + = [up to date] testcommit96 -> origin/testcommit96 + = [up to date] testcommit960 -> origin/testcommit960 + = [up to date] testcommit961 -> origin/testcommit961 + = [up to date] testcommit962 -> origin/testcommit962 + = [up to date] testcommit963 -> origin/testcommit963 + = [up to date] testcommit964 -> origin/testcommit964 + = [up to date] testcommit965 -> origin/testcommit965 + = [up to date] testcommit966 -> origin/testcommit966 + = [up to date] testcommit967 -> origin/testcommit967 + = [up to date] testcommit968 -> origin/testcommit968 + = [up to date] testcommit969 -> origin/testcommit969 + = [up to date] testcommit97 -> origin/testcommit97 + = [up to date] testcommit970 -> origin/testcommit970 + = [up to date] testcommit971 -> origin/testcommit971 + = [up to date] testcommit972 -> origin/testcommit972 + = [up to date] testcommit973 -> origin/testcommit973 + = [up to date] testcommit974 -> origin/testcommit974 + = [up to date] testcommit975 -> origin/testcommit975 + = [up to date] testcommit976 -> origin/testcommit976 + = [up to date] testcommit977 -> origin/testcommit977 + = [up to date] testcommit978 -> origin/testcommit978 + = [up to date] testcommit979 -> origin/testcommit979 + = [up to date] testcommit98 -> origin/testcommit98 + = [up to date] testcommit980 -> origin/testcommit980 + = [up to date] testcommit981 -> origin/testcommit981 + = [up to date] testcommit982 -> origin/testcommit982 + = [up to date] testcommit983 -> origin/testcommit983 + = [up to date] testcommit984 -> origin/testcommit984 + = [up to date] testcommit985 -> origin/testcommit985 + = [up to date] testcommit986 -> origin/testcommit986 + = [up to date] testcommit987 -> origin/testcommit987 + = [up to date] testcommit988 -> origin/testcommit988 + = [up to date] testcommit989 -> origin/testcommit989 + = [up to date] testcommit99 -> origin/testcommit99 + = [up to date] testcommit990 -> origin/testcommit990 + = [up to date] testcommit991 -> origin/testcommit991 + = [up to date] testcommit992 -> origin/testcommit992 + = [up to date] testcommit993 -> origin/testcommit993 + = [up to date] testcommit994 -> origin/testcommit994 + = [up to date] testcommit995 -> origin/testcommit995 + = [up to date] testcommit996 -> origin/testcommit996 + = [up to date] testcommit997 -> origin/testcommit997 + = [up to date] testcommit998 -> origin/testcommit998 + = [up to date] testcommit999 -> origin/testcommit999 diff --git a/git/test/test_git.py b/git/test/test_git.py index 51da5f975..f7442257c 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -22,6 +22,7 @@ GitCommandNotFound, Repo ) +from git.cmd import _deplete_buffer from gitdb.test.lib import with_rw_directory from git.compat import PY3 @@ -204,3 +205,19 @@ def test_environment(self, rw_dir): # end # end # end if select.poll exists + + def test_dispatch_lines(self): + for path, line_count in ((fixture_path('issue-301_stderr'), 5002), + (fixture_path('issue-301_FETCH_HEAD'), 5001)): + count = [0] + def counter(line): + count[0] += 1 + + fd = os.open(path, os.O_RDONLY) + buf_list = [b''] + lines_parsed = _deplete_buffer(fd, counter, buf_list) + os.close(fd) + + assert lines_parsed == line_count + assert count[0] == line_count + # end for each file to read From 6d0f693184884ffac97908397b074e208c63742b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 12:01:54 +0200 Subject: [PATCH 0227/2790] test(remote): make assertion less verbose --- git/remote.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/git/remote.py b/git/remote.py index c9da19791..4871ea5fc 100644 --- a/git/remote.py +++ b/git/remote.py @@ -573,8 +573,9 @@ def my_progress_handler(line): fp.close() # NOTE: We assume to fetch at least enough progress lines to allow matching each fetch head line with it. - assert len(fetch_info_lines) >= len(fetch_head_info), "len(%s) <= len(%s)" % (fetch_head_info, - fetch_info_lines) + l_fil = len(fetch_info_lines) + l_fhi = len(fetch_head_info) + assert l_fil >= l_fhi, "len(%s) <= len(%s)" % (l_fil, l_fhi) output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info)) From 36dbe7e9b55a09c68ba179bcf2c3d3e1b7898ef3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 12:40:57 +0200 Subject: [PATCH 0228/2790] test(git): remove unnecessary fixture Test was adjusted as well to parse only a single file which simulates stderr output. --- git/test/fixtures/issue-301_FETCH_HEAD | 5001 ------------------------ git/test/test_git.py | 26 +- 2 files changed, 12 insertions(+), 5015 deletions(-) delete mode 100644 git/test/fixtures/issue-301_FETCH_HEAD diff --git a/git/test/fixtures/issue-301_FETCH_HEAD b/git/test/fixtures/issue-301_FETCH_HEAD deleted file mode 100644 index 17a81664d..000000000 --- a/git/test/fixtures/issue-301_FETCH_HEAD +++ /dev/null @@ -1,5001 +0,0 @@ -f78f35d9dab6228d31f5767733ad7a35abb66eb5 branch 'master' of github.com:jantman/gitpython_issue_301 -813bb61a2f1fb04814b7f15145881ea73cd133cc not-for-merge branch 'testcommit1' of github.com:jantman/gitpython_issue_301 -74b231851fb084c47066e7e7648a14136c7c299d not-for-merge branch 'testcommit10' of github.com:jantman/gitpython_issue_301 -1cb5483706293ea69fafb91c786234e6e65ad689 not-for-merge branch 'testcommit100' of github.com:jantman/gitpython_issue_301 -0d82e65448bcc2c6682b21cf85f7c96ed040df70 not-for-merge branch 'testcommit1000' of github.com:jantman/gitpython_issue_301 -057f1fdad7209439aa9114f0262fb9c4d33200d0 not-for-merge branch 'testcommit1001' of github.com:jantman/gitpython_issue_301 -15d69d4aee5526eb411e54dc397134dee26b2283 not-for-merge branch 'testcommit1002' of github.com:jantman/gitpython_issue_301 -b0e2c328992b65ec1fd6208caa4a3dd4cc37f9d7 not-for-merge branch 'testcommit1003' of github.com:jantman/gitpython_issue_301 -87060a7536049854ef45968da61f5770abdaedc4 not-for-merge branch 'testcommit1004' of github.com:jantman/gitpython_issue_301 -d8d3f321891ca92ee293d06ed87a064a1fe62677 not-for-merge branch 'testcommit1005' of github.com:jantman/gitpython_issue_301 -7115c362226c07137043eed46b2e5a98a69cc43f not-for-merge branch 'testcommit1006' of github.com:jantman/gitpython_issue_301 -ba5f552c10b5c8508d83ed32ac5bf67001629b20 not-for-merge branch 'testcommit1007' of github.com:jantman/gitpython_issue_301 -03fde1b9f89ecf6a785517163f16005119fc680e not-for-merge branch 'testcommit1008' of github.com:jantman/gitpython_issue_301 -b6ae330511eaac90bb3c845e955c886a777568e7 not-for-merge branch 'testcommit1009' of github.com:jantman/gitpython_issue_301 -fae4350e6e080b5a02b37acd8b82b4c5b6562549 not-for-merge branch 'testcommit101' of github.com:jantman/gitpython_issue_301 -a291c06e6ab3aa92ecc4016038f2d917522cbe57 not-for-merge branch 'testcommit1010' of github.com:jantman/gitpython_issue_301 -dd5bbd0857ed5b6065c241f55319f7390e3db09c not-for-merge branch 'testcommit1011' of github.com:jantman/gitpython_issue_301 -d64ea9fbb015aa75e8b0baabc0a139c65a473526 not-for-merge branch 'testcommit1012' of github.com:jantman/gitpython_issue_301 -5b82157edda8f2a2ef46b15e386d4c616eab3226 not-for-merge branch 'testcommit1013' of github.com:jantman/gitpython_issue_301 -1e54cf4e8bbc10acab0a376276ae54076c68200f not-for-merge branch 'testcommit1014' of github.com:jantman/gitpython_issue_301 -c132323053db7a8ee9f20476b3b40277fe1005b7 not-for-merge branch 'testcommit1015' of github.com:jantman/gitpython_issue_301 -68f5e4e2e2901044a58443b72c55acd15a30cb5d not-for-merge branch 'testcommit1016' of github.com:jantman/gitpython_issue_301 -a49783e1fb03a15e9d57888821a41d49ee5d9753 not-for-merge branch 'testcommit1017' of github.com:jantman/gitpython_issue_301 -c7d0e081d606dea226968d51277dc2c9a02583eb not-for-merge branch 'testcommit1018' of github.com:jantman/gitpython_issue_301 -33de4b6e4e3fe03893686549e855751e65fe0d3e not-for-merge branch 'testcommit1019' of github.com:jantman/gitpython_issue_301 -2a58c9b7e1b797cc978f9dbcfd896ac4520725aa not-for-merge branch 'testcommit102' of github.com:jantman/gitpython_issue_301 -c66ae862a6acd990e11ec0d2fdf99449930c61a4 not-for-merge branch 'testcommit1020' of github.com:jantman/gitpython_issue_301 -a306c22db519841f9457c13bf63ac1d4d2c436ac not-for-merge branch 'testcommit1021' of github.com:jantman/gitpython_issue_301 -7e4f0c9300a171e3d3dea6120d5826ac2a750f58 not-for-merge branch 'testcommit1022' of github.com:jantman/gitpython_issue_301 -1a30379b859495d9ff8c1ed612c1d9fc17000541 not-for-merge branch 'testcommit1023' of github.com:jantman/gitpython_issue_301 -f35d38a1c6e4ba013f3fbcd9b833152038bf4b2b not-for-merge branch 'testcommit1024' of github.com:jantman/gitpython_issue_301 -a23ec8ef4e5591c19a1160826cd1707edcc323ff not-for-merge branch 'testcommit1025' of github.com:jantman/gitpython_issue_301 -086c8dc0652cf0872decec7ec15f568b692f2b79 not-for-merge branch 'testcommit1026' of github.com:jantman/gitpython_issue_301 -fbec4b838cff070bfa44262d92bd3348aa0c49df not-for-merge branch 'testcommit1027' of github.com:jantman/gitpython_issue_301 -e1db0463d7d4b9b879193e287cfb3e57afad8545 not-for-merge branch 'testcommit1028' of github.com:jantman/gitpython_issue_301 -daf9d90c758f46d1eaeedbdd9777765eeeb41b16 not-for-merge branch 'testcommit1029' of github.com:jantman/gitpython_issue_301 -e4a78df9c577229cb8e4e19c5fd68f861e6bcd54 not-for-merge branch 'testcommit103' of github.com:jantman/gitpython_issue_301 -ca2bd8768ddf3353366ded2cb0c45a2378415728 not-for-merge branch 'testcommit1030' of github.com:jantman/gitpython_issue_301 -3bd79462e516e4b6042edde2247db47dc6998cee not-for-merge branch 'testcommit1031' of github.com:jantman/gitpython_issue_301 -0b5c7a6c18d0dad345f9c862c34a053ba3ff03dd not-for-merge branch 'testcommit1032' of github.com:jantman/gitpython_issue_301 -133a759b81ec33386d55e1abdc6b175512ebd7be not-for-merge branch 'testcommit1033' of github.com:jantman/gitpython_issue_301 -ff11d39a567ca85619fecd22665ce0111d9f5bf3 not-for-merge branch 'testcommit1034' of github.com:jantman/gitpython_issue_301 -b474a98c90debc1aa1c78e53fdafd2fa46b5c507 not-for-merge branch 'testcommit1035' of github.com:jantman/gitpython_issue_301 -51a6e4eaedee9cd13c5df6fbb32dfce7c57d5126 not-for-merge branch 'testcommit1036' of github.com:jantman/gitpython_issue_301 -dfe09cab749db84038eee918e71706030ab5b1be not-for-merge branch 'testcommit1037' of github.com:jantman/gitpython_issue_301 -0867b340c832c30f63196bc69fb88fd14ff3b6c2 not-for-merge branch 'testcommit1038' of github.com:jantman/gitpython_issue_301 -9485d0cc1dee71fc8c9faac84eb9d29768d03b2b not-for-merge branch 'testcommit1039' of github.com:jantman/gitpython_issue_301 -e88c09f111fd3922e7ccf44660afbe169f3f1eeb not-for-merge branch 'testcommit104' of github.com:jantman/gitpython_issue_301 -36c52368b69c03153dab376f915cbf8e7630dc7e not-for-merge branch 'testcommit1040' of github.com:jantman/gitpython_issue_301 -cd82e0f6ee3c171011228cb2e8f363a9da925fb8 not-for-merge branch 'testcommit1041' of github.com:jantman/gitpython_issue_301 -4f49ea944a6c0c398220b90378370c105170046f not-for-merge branch 'testcommit1042' of github.com:jantman/gitpython_issue_301 -1917539f10f2b4838ef2f994eb10a1d460a0f650 not-for-merge branch 'testcommit1043' of github.com:jantman/gitpython_issue_301 -82e70e8e03b24a24a0373f4192d8aecc9f1cd172 not-for-merge branch 'testcommit1044' of github.com:jantman/gitpython_issue_301 -92b53b8ae31d0629dc47b8f1c26404c7746d02f2 not-for-merge branch 'testcommit1045' of github.com:jantman/gitpython_issue_301 -1708c4ea98cece372c63d3351a036e6a7f2cd888 not-for-merge branch 'testcommit1046' of github.com:jantman/gitpython_issue_301 -775a094cad4abd26b46f3bd76983720f0f7555a7 not-for-merge branch 'testcommit1047' of github.com:jantman/gitpython_issue_301 -62f14aec2a95e69f2f6cefae5a169a2213f0979a not-for-merge branch 'testcommit1048' of github.com:jantman/gitpython_issue_301 -a89a06c658550fbf08f7febeb879a18e8cd0d0ea not-for-merge branch 'testcommit1049' of github.com:jantman/gitpython_issue_301 -e6dc222522a5bd977c1ac0c7fe6da6d2266c63e4 not-for-merge branch 'testcommit105' of github.com:jantman/gitpython_issue_301 -081d87eac78da472a5ffc0fe0f2dc291ebb149e9 not-for-merge branch 'testcommit1050' of github.com:jantman/gitpython_issue_301 -cbc215ca6c83abdc61551a836d7a28904a62d085 not-for-merge branch 'testcommit1051' of github.com:jantman/gitpython_issue_301 -c217b655f666dcef95f2c7d94a347142f64dc8e7 not-for-merge branch 'testcommit1052' of github.com:jantman/gitpython_issue_301 -1a2639fe5bb81d58fc1e440cd0de13542f30ede0 not-for-merge branch 'testcommit1053' of github.com:jantman/gitpython_issue_301 -e26f97c6030a35eecf7529db67891b2a5e62fc65 not-for-merge branch 'testcommit1054' of github.com:jantman/gitpython_issue_301 -21ef95611a661a26982384eca4d6de1deec05019 not-for-merge branch 'testcommit1055' of github.com:jantman/gitpython_issue_301 -45cddb9b4249654b010ec2eb1bf8e0335f790a71 not-for-merge branch 'testcommit1056' of github.com:jantman/gitpython_issue_301 -7be0d0f80bdef478e0b7c807385eecdee966cd36 not-for-merge branch 'testcommit1057' of github.com:jantman/gitpython_issue_301 -657248968c110f9fb1176fc6a7885edf65cd15d8 not-for-merge branch 'testcommit1058' of github.com:jantman/gitpython_issue_301 -47b6e1ce23a3825ae5562028f627da4fc16b0e6a not-for-merge branch 'testcommit1059' of github.com:jantman/gitpython_issue_301 -30b94663b5f4cbef4851cb4f6e8cee8c773fc1f6 not-for-merge branch 'testcommit106' of github.com:jantman/gitpython_issue_301 -360052485cbc5662afa083468e54b6d510076a06 not-for-merge branch 'testcommit1060' of github.com:jantman/gitpython_issue_301 -058a069963bc1140c31d0f29c39d635b0470a075 not-for-merge branch 'testcommit1061' of github.com:jantman/gitpython_issue_301 -be9d2205c3435645fbeb619825650bf3e608528a not-for-merge branch 'testcommit1062' of github.com:jantman/gitpython_issue_301 -cb1d7c4180bbfe8048b16081b49cce7d459f76a5 not-for-merge branch 'testcommit1063' of github.com:jantman/gitpython_issue_301 -a18d81ab79bfd95a0db0186ec98bfa69e2110fd5 not-for-merge branch 'testcommit1064' of github.com:jantman/gitpython_issue_301 -d77a1368f70c8bcb861646b3671d00979f3eb9b3 not-for-merge branch 'testcommit1065' of github.com:jantman/gitpython_issue_301 -7f37ec5d5dd7c8ae9ddc384b01bb96e10dc1aec7 not-for-merge branch 'testcommit1066' of github.com:jantman/gitpython_issue_301 -405505546f113b75d9b802cb8141595275a2efcb not-for-merge branch 'testcommit1067' of github.com:jantman/gitpython_issue_301 -27c56c91701905fa665f1fced077332e46e873df not-for-merge branch 'testcommit1068' of github.com:jantman/gitpython_issue_301 -afbb0a989463065043e6a4b2346e380c80294221 not-for-merge branch 'testcommit1069' of github.com:jantman/gitpython_issue_301 -6b30eeeb7b070b6c27edebc96973249f8225ed91 not-for-merge branch 'testcommit107' of github.com:jantman/gitpython_issue_301 -b11e6d299ea7e12939ced678695dee2050dc9edb not-for-merge branch 'testcommit1070' of github.com:jantman/gitpython_issue_301 -4c3de2f4ada98d216fc053a0187159f8bcffbb07 not-for-merge branch 'testcommit1071' of github.com:jantman/gitpython_issue_301 -e4b1931a7d5746c3b1d1a8f0c0275c501cda16bd not-for-merge branch 'testcommit1072' of github.com:jantman/gitpython_issue_301 -2bf742d78ade4aeffd07c6f18fc834f5e2885d8d not-for-merge branch 'testcommit1073' of github.com:jantman/gitpython_issue_301 -3da6bf729de2650f17c0cd68350549d51c4ce5d5 not-for-merge branch 'testcommit1074' of github.com:jantman/gitpython_issue_301 -b98266702d45a342e9717b4051bf40aa00376767 not-for-merge branch 'testcommit1075' of github.com:jantman/gitpython_issue_301 -032f33390c64f58e6d7c7f30d130c2254fd2daac not-for-merge branch 'testcommit1076' of github.com:jantman/gitpython_issue_301 -665c4528e45a6cbb6bb77dc0abf25a396459f3f0 not-for-merge branch 'testcommit1077' of github.com:jantman/gitpython_issue_301 -c2521839c44c1c2f9b2cb421927c09637ad86a09 not-for-merge branch 'testcommit1078' of github.com:jantman/gitpython_issue_301 -c6baebe98130dfa62a85d34237711af6fc751b66 not-for-merge branch 'testcommit1079' of github.com:jantman/gitpython_issue_301 -711f48c1dc1bf9a0fe7d7dfdd4bbeb8d90756a24 not-for-merge branch 'testcommit108' of github.com:jantman/gitpython_issue_301 -d01f1a495c951de18dc9c63072ad1452a474a37f not-for-merge branch 'testcommit1080' of github.com:jantman/gitpython_issue_301 -ce21f34ce9171e7671213e70594301a96c28eef7 not-for-merge branch 'testcommit1081' of github.com:jantman/gitpython_issue_301 -5f0e3ca0aa91eb6cf87a8a1522e7b349e9786651 not-for-merge branch 'testcommit1082' of github.com:jantman/gitpython_issue_301 -31482a712ef4f499376c09e6e6db34e28d25a2bd not-for-merge branch 'testcommit1083' of github.com:jantman/gitpython_issue_301 -4cb0da37944358fa42bcee36dac42f2999d1d96c not-for-merge branch 'testcommit1084' of github.com:jantman/gitpython_issue_301 -17df70989870fea0d0f8a64b55ed8b62bf430541 not-for-merge branch 'testcommit1085' of github.com:jantman/gitpython_issue_301 -7cac5985ca2795958bfa9ff8489f055d768d5c2b not-for-merge branch 'testcommit1086' of github.com:jantman/gitpython_issue_301 -606bffc22073d5d42042ea3d33be235458bbbef6 not-for-merge branch 'testcommit1087' of github.com:jantman/gitpython_issue_301 -30b0e5295a1d82e3401a88097784f0d1939c1666 not-for-merge branch 'testcommit1088' of github.com:jantman/gitpython_issue_301 -3d0e8effe1aae0591459621b5fdcd5fdb7f7ad53 not-for-merge branch 'testcommit1089' of github.com:jantman/gitpython_issue_301 -4289c5f725b6c51b64399bf43d4bd55969225146 not-for-merge branch 'testcommit109' of github.com:jantman/gitpython_issue_301 -1caa617f02115fe9ae372d4f13bb885d78e94dff not-for-merge branch 'testcommit1090' of github.com:jantman/gitpython_issue_301 -ac3be29d3e1e82548e54093630c3a69231dd735f not-for-merge branch 'testcommit1091' of github.com:jantman/gitpython_issue_301 -ed7c2973e590c4a938c3985b08f91558b68cb37d not-for-merge branch 'testcommit1092' of github.com:jantman/gitpython_issue_301 -bdefdd16ab5d5e95cc1b32b8fdff47a125151949 not-for-merge branch 'testcommit1093' of github.com:jantman/gitpython_issue_301 -38cff866165cddda64c291565c158ee3c780fb66 not-for-merge branch 'testcommit1094' of github.com:jantman/gitpython_issue_301 -12cfe834195d2c50bc774fdcf8811a4d1e5876bd not-for-merge branch 'testcommit1095' of github.com:jantman/gitpython_issue_301 -4ae27f31ee4cb5c4faa79ad9193ae2f963eb9b06 not-for-merge branch 'testcommit1096' of github.com:jantman/gitpython_issue_301 -b7ab182d4840ed5ae95f11b173649c9beb79912e not-for-merge branch 'testcommit1097' of github.com:jantman/gitpython_issue_301 -672ffcd369a825f73d284a74059f5f19f736ff6d not-for-merge branch 'testcommit1098' of github.com:jantman/gitpython_issue_301 -c93a97da2e71a559ff7e03782979bf355b3e1136 not-for-merge branch 'testcommit1099' of github.com:jantman/gitpython_issue_301 -55cb6f9568e7a100d09d00164f5dd7b0535e4310 not-for-merge branch 'testcommit11' of github.com:jantman/gitpython_issue_301 -9dcffbb783f71c611bef7141399c10dda819d468 not-for-merge branch 'testcommit110' of github.com:jantman/gitpython_issue_301 -e53af6e7a2f361864dda512199cb6a38292755ae not-for-merge branch 'testcommit1100' of github.com:jantman/gitpython_issue_301 -e7a5c09b0b88deaf241fe6514b5cc0bb6bb6cb45 not-for-merge branch 'testcommit1101' of github.com:jantman/gitpython_issue_301 -2218dafaef4f8d31712a6cdc7fbeac770c3ae896 not-for-merge branch 'testcommit1102' of github.com:jantman/gitpython_issue_301 -ef5a88d0daeb8861ca59fbdd261b09641fc30575 not-for-merge branch 'testcommit1103' of github.com:jantman/gitpython_issue_301 -7a1dac58789c9bc72da312fead7e8925e9ff3b3b not-for-merge branch 'testcommit1104' of github.com:jantman/gitpython_issue_301 -fd182a64f6fefd07e80df51cab24e2e3ff997404 not-for-merge branch 'testcommit1105' of github.com:jantman/gitpython_issue_301 -2870deb98332e9bf702926a27d219068df2a5734 not-for-merge branch 'testcommit1106' of github.com:jantman/gitpython_issue_301 -e1e3f1228c9aae832efb3ce813eacd18e799af1c not-for-merge branch 'testcommit1107' of github.com:jantman/gitpython_issue_301 -b83df5064e6ca92bf23f4e8893d0d895794491c2 not-for-merge branch 'testcommit1108' of github.com:jantman/gitpython_issue_301 -ba699e788131115d827e013b8b536db517c08b9e not-for-merge branch 'testcommit1109' of github.com:jantman/gitpython_issue_301 -20e0be248c4ef3ec27fe5c1c470a6914cb459395 not-for-merge branch 'testcommit111' of github.com:jantman/gitpython_issue_301 -09e22ef75bd95b357570f7a4ce1eaf5c78518926 not-for-merge branch 'testcommit1110' of github.com:jantman/gitpython_issue_301 -cbfa17e2e435273f83cfc4c86b7665445b627ec7 not-for-merge branch 'testcommit1111' of github.com:jantman/gitpython_issue_301 -69e2c4783070ca246c2911cd78477a1f5cae442a not-for-merge branch 'testcommit1112' of github.com:jantman/gitpython_issue_301 -122ac4d63172d44674c5fc339d0393f4b60f1b1f not-for-merge branch 'testcommit1113' of github.com:jantman/gitpython_issue_301 -07e3b6dc5419875073c52fb3f8401a6d4644a891 not-for-merge branch 'testcommit1114' of github.com:jantman/gitpython_issue_301 -c601acd83e899ee23af369fc73ffbe3134d48de2 not-for-merge branch 'testcommit1115' of github.com:jantman/gitpython_issue_301 -e50cfc4d294fdf07524142815662cc33b87b705b not-for-merge branch 'testcommit1116' of github.com:jantman/gitpython_issue_301 -d7acf565b440e6b00f8edfb3d540fa839cd273ab not-for-merge branch 'testcommit1117' of github.com:jantman/gitpython_issue_301 -1eac6a459b15b563b5f43bdc6f97df4711a600df not-for-merge branch 'testcommit1118' of github.com:jantman/gitpython_issue_301 -1fd3fe8021b31637516f531be4848fe83b59b1cf not-for-merge branch 'testcommit1119' of github.com:jantman/gitpython_issue_301 -a62a45f2d78c4ca178fcef92d5f6de1ddbfb4746 not-for-merge branch 'testcommit112' of github.com:jantman/gitpython_issue_301 -199af89fec1154e4d40bd6507365b4cba4c29a94 not-for-merge branch 'testcommit1120' of github.com:jantman/gitpython_issue_301 -0f3e33d551325fe2fdd88659fb4b6331b90521a3 not-for-merge branch 'testcommit1121' of github.com:jantman/gitpython_issue_301 -a0e70e450c770c3b916cf5dad60619fd95956dfc not-for-merge branch 'testcommit1122' of github.com:jantman/gitpython_issue_301 -547dbcd351e72f99181118fec4778fd0648f6ff0 not-for-merge branch 'testcommit1123' of github.com:jantman/gitpython_issue_301 -2b3446f6c54478603f594a1f7fa2dc4729101106 not-for-merge branch 'testcommit1124' of github.com:jantman/gitpython_issue_301 -3f415e48bd54b0eb8db4f3c5899ab376d0e3aeb7 not-for-merge branch 'testcommit1125' of github.com:jantman/gitpython_issue_301 -c27e72d137dcd985138d438e3e3a16e08d1355b6 not-for-merge branch 'testcommit1126' of github.com:jantman/gitpython_issue_301 -633b426e10f2fd0e16ff3a0da736349058722815 not-for-merge branch 'testcommit1127' of github.com:jantman/gitpython_issue_301 -d2a581ad637e7e8060288c6d43d8226c021a3f42 not-for-merge branch 'testcommit1128' of github.com:jantman/gitpython_issue_301 -efac764b787df54fe2dabea8f32e02ecbd6a2ddb not-for-merge branch 'testcommit1129' of github.com:jantman/gitpython_issue_301 -1333282639ec695f5a595ac2f56248337c5b1838 not-for-merge branch 'testcommit113' of github.com:jantman/gitpython_issue_301 -a5969e439375214fc465fd1f09b31fae1bdf7ee7 not-for-merge branch 'testcommit1130' of github.com:jantman/gitpython_issue_301 -3e67a1c7a8103e1d6fb91b1a83f7fef821a7dbac not-for-merge branch 'testcommit1131' of github.com:jantman/gitpython_issue_301 -8ae97d7a41c1c09e23252a9b546f895492a7ec4b not-for-merge branch 'testcommit1132' of github.com:jantman/gitpython_issue_301 -7cbd6c26fd6402de4375c87a7b0e1fddef7a0632 not-for-merge branch 'testcommit1133' of github.com:jantman/gitpython_issue_301 -a93a37fc6632a843ba746eb4090f0d3cc31dd876 not-for-merge branch 'testcommit1134' of github.com:jantman/gitpython_issue_301 -ecc257ed5ee7dc26110a3cfa75cf1251e04c4ca1 not-for-merge branch 'testcommit1135' of github.com:jantman/gitpython_issue_301 -b4c3c3f6e0f6867b25e926f72ab4c7840a1f23bd not-for-merge branch 'testcommit1136' of github.com:jantman/gitpython_issue_301 -fba79db2fff2531d982a3ee0bf86a904a315adcd not-for-merge branch 'testcommit1137' of github.com:jantman/gitpython_issue_301 -97ec8bf454187944227f639b2348f9089f8a2a23 not-for-merge branch 'testcommit1138' of github.com:jantman/gitpython_issue_301 -09632791d06f73ea50f628e1e720ad8a874f58e7 not-for-merge branch 'testcommit1139' of github.com:jantman/gitpython_issue_301 -1d82fe9bb1c761912fc5c8598af055c26f380aca not-for-merge branch 'testcommit114' of github.com:jantman/gitpython_issue_301 -c9e9b0c05e64778a55ccf0ee26ef199fc57a5d7b not-for-merge branch 'testcommit1140' of github.com:jantman/gitpython_issue_301 -11bc154798db96737fd5fea7f35c7f164db165e1 not-for-merge branch 'testcommit1141' of github.com:jantman/gitpython_issue_301 -4c9e4e24f790fd1512e5908aaf77e86b46e5339a not-for-merge branch 'testcommit1142' of github.com:jantman/gitpython_issue_301 -8a804d4bb492e080bad2b2190b65bfe711b71f40 not-for-merge branch 'testcommit1143' of github.com:jantman/gitpython_issue_301 -0951f67dd9b8563482047b7b74176df3f1c9a429 not-for-merge branch 'testcommit1144' of github.com:jantman/gitpython_issue_301 -1c363695812110631a945a84489b6997c9136018 not-for-merge branch 'testcommit1145' of github.com:jantman/gitpython_issue_301 -b004ea4ffd2f9905e0e6cebb08cac5fc40918015 not-for-merge branch 'testcommit1146' of github.com:jantman/gitpython_issue_301 -b33c28ba069959c30370195a6010e9c91075788a not-for-merge branch 'testcommit1147' of github.com:jantman/gitpython_issue_301 -b09105acb2591685646e1c69bbfce9a24569ed75 not-for-merge branch 'testcommit1148' of github.com:jantman/gitpython_issue_301 -07f1efa2dff41cf6c562c90cf57a85d15791d4fc not-for-merge branch 'testcommit1149' of github.com:jantman/gitpython_issue_301 -873878b0a7e3d057124fbeef30099162e4dcf1a0 not-for-merge branch 'testcommit115' of github.com:jantman/gitpython_issue_301 -025d348dce7f01d0fc1a4acb9bb24309002a4749 not-for-merge branch 'testcommit1150' of github.com:jantman/gitpython_issue_301 -7ebd68d136bcac39d9b9a7178328b650a1c839a7 not-for-merge branch 'testcommit1151' of github.com:jantman/gitpython_issue_301 -7203b4ddf827bc0e312d942177831147eb5b6841 not-for-merge branch 'testcommit1152' of github.com:jantman/gitpython_issue_301 -cfc0cda3154ed7494f172801a99ddcbc11b12996 not-for-merge branch 'testcommit1153' of github.com:jantman/gitpython_issue_301 -45549e31b199ac0e5c16f53b3e2b6712650d715a not-for-merge branch 'testcommit1154' of github.com:jantman/gitpython_issue_301 -cbaa071137433d5314acf6e85b8174e4994c276a not-for-merge branch 'testcommit1155' of github.com:jantman/gitpython_issue_301 -a46da4d72bb8497b803191b1d3b13730ab49f766 not-for-merge branch 'testcommit1156' of github.com:jantman/gitpython_issue_301 -17aec3730c7682b9057803a3d990c85961a6ce44 not-for-merge branch 'testcommit1157' of github.com:jantman/gitpython_issue_301 -e7558b39811d49f3c4b386a38419e960fbd95382 not-for-merge branch 'testcommit1158' of github.com:jantman/gitpython_issue_301 -ddff4bf440241ec9a5c03b16ca7be2df8a46eb1e not-for-merge branch 'testcommit1159' of github.com:jantman/gitpython_issue_301 -eddc98b14ac57fdf5260183110265682f8906cee not-for-merge branch 'testcommit116' of github.com:jantman/gitpython_issue_301 -96568821f122d5610878a7797dc353a396150360 not-for-merge branch 'testcommit1160' of github.com:jantman/gitpython_issue_301 -4b7ffafad4febcad43b5f4902c2229c303b16696 not-for-merge branch 'testcommit1161' of github.com:jantman/gitpython_issue_301 -03f487eceaa0b9e7b2800c6078cf852249af82c9 not-for-merge branch 'testcommit1162' of github.com:jantman/gitpython_issue_301 -92f4da7b29f0b9b007265e7254d1acfd0c12725f not-for-merge branch 'testcommit1163' of github.com:jantman/gitpython_issue_301 -d513e6a13759a435426ae2ded67f1ec066ca0a13 not-for-merge branch 'testcommit1164' of github.com:jantman/gitpython_issue_301 -7dc838ff52ec8c791573160e2d9fd5513ba13365 not-for-merge branch 'testcommit1165' of github.com:jantman/gitpython_issue_301 -31ff5fa84b887aec02c9f1031be27e6c76d68e00 not-for-merge branch 'testcommit1166' of github.com:jantman/gitpython_issue_301 -ac987b3df23e22c9c4bc7504c3efc44605db7f07 not-for-merge branch 'testcommit1167' of github.com:jantman/gitpython_issue_301 -d2c26f2766e8d62685df28ca8b854c01df6cc1b4 not-for-merge branch 'testcommit1168' of github.com:jantman/gitpython_issue_301 -53ca1a605398e207c601d87613a4bb23c27e03e1 not-for-merge branch 'testcommit1169' of github.com:jantman/gitpython_issue_301 -ce925e45d8fcfe942f1e0b4d9e08601ebb580919 not-for-merge branch 'testcommit117' of github.com:jantman/gitpython_issue_301 -1a3b00146f94811d76fcd676de68b78e4e78ea61 not-for-merge branch 'testcommit1170' of github.com:jantman/gitpython_issue_301 -e224395b2fc68666892914e730ef12c4d69c88e3 not-for-merge branch 'testcommit1171' of github.com:jantman/gitpython_issue_301 -d6d72aada4c36698dd3fe6c7773c8ba643b9703a not-for-merge branch 'testcommit1172' of github.com:jantman/gitpython_issue_301 -9124e4622f87f3ec4250d8ed3113482c07b2d68b not-for-merge branch 'testcommit1173' of github.com:jantman/gitpython_issue_301 -15928c4d9a627836dc5eb88e559f320dd1ee2283 not-for-merge branch 'testcommit1174' of github.com:jantman/gitpython_issue_301 -18567d26548b12ffc09ede23f16b57b18cb43310 not-for-merge branch 'testcommit1175' of github.com:jantman/gitpython_issue_301 -5547f331d7c55ff1973bd536d40a92841e7ce035 not-for-merge branch 'testcommit1176' of github.com:jantman/gitpython_issue_301 -2ca1c5ca13be4c28c0e73b1961cb7682bcb3ea1a not-for-merge branch 'testcommit1177' of github.com:jantman/gitpython_issue_301 -208509ce8e39a3be1c9b6e2d99eafa89fd1cf684 not-for-merge branch 'testcommit1178' of github.com:jantman/gitpython_issue_301 -644d579fada2ada76b4d51be94fa8393654be214 not-for-merge branch 'testcommit1179' of github.com:jantman/gitpython_issue_301 -fee627a495ce3c9780c5b2bd740f6d9e437b9d6e not-for-merge branch 'testcommit118' of github.com:jantman/gitpython_issue_301 -ff311ba7e3b485bbe9d1c3705df5d605b2476a89 not-for-merge branch 'testcommit1180' of github.com:jantman/gitpython_issue_301 -a78eac859cdda172a5c9721c5c36e44907c192f7 not-for-merge branch 'testcommit1181' of github.com:jantman/gitpython_issue_301 -a897b2f084a65c47ccc0331c565a9a20c04ebcbc not-for-merge branch 'testcommit1182' of github.com:jantman/gitpython_issue_301 -d262fbce249a1832e461a26357897580df1f2932 not-for-merge branch 'testcommit1183' of github.com:jantman/gitpython_issue_301 -7ffc89d7b9a94632bb8ff5f0a3e7d35de3eccf13 not-for-merge branch 'testcommit1184' of github.com:jantman/gitpython_issue_301 -1a0e0df0e8c291d108baa981e65d0722786efe27 not-for-merge branch 'testcommit1185' of github.com:jantman/gitpython_issue_301 -95e905cad2c6d6a4ff010cceac8d4a60d9505fa6 not-for-merge branch 'testcommit1186' of github.com:jantman/gitpython_issue_301 -ea03310563b0d64d0eb7001ff78b1e22f38a0bf1 not-for-merge branch 'testcommit1187' of github.com:jantman/gitpython_issue_301 -223c152e55c2d986b6974f8b3423a2fb5a253b48 not-for-merge branch 'testcommit1188' of github.com:jantman/gitpython_issue_301 -8565160a8ded00222fd9d8dcd603a7524e4ee17f not-for-merge branch 'testcommit1189' of github.com:jantman/gitpython_issue_301 -dd7eabc192578056bf93932039a6cca81cc6fb31 not-for-merge branch 'testcommit119' of github.com:jantman/gitpython_issue_301 -5068432d1d3b7ac57fdeb67e0dac55bd3cc0888d not-for-merge branch 'testcommit1190' of github.com:jantman/gitpython_issue_301 -e56dea1cc059761ae0cf5099f2fee179efa1010a not-for-merge branch 'testcommit1191' of github.com:jantman/gitpython_issue_301 -a0673e3b53f347ca3aa658be042271528bb61880 not-for-merge branch 'testcommit1192' of github.com:jantman/gitpython_issue_301 -6aaefc469bc1ccc7099038a5a4e4ef2e4817e40a not-for-merge branch 'testcommit1193' of github.com:jantman/gitpython_issue_301 -201d665fe94dab10938153a637728e7b2ca3e17a not-for-merge branch 'testcommit1194' of github.com:jantman/gitpython_issue_301 -eedc465ddb5fc8d47e7bd4823e607db3dd93a190 not-for-merge branch 'testcommit1195' of github.com:jantman/gitpython_issue_301 -f0fa95cd65fe1dec9dfb0beb82fefc2c5a17e7b5 not-for-merge branch 'testcommit1196' of github.com:jantman/gitpython_issue_301 -97804411c5bab39edae1238a98a99ff55124e4d7 not-for-merge branch 'testcommit1197' of github.com:jantman/gitpython_issue_301 -daf886b0396d37ddf5be47f23d862246ce01bc26 not-for-merge branch 'testcommit1198' of github.com:jantman/gitpython_issue_301 -9326044f3cae96bb56555630c3f9d1280fc76858 not-for-merge branch 'testcommit1199' of github.com:jantman/gitpython_issue_301 -f7346357820a98dd830ab33f714aa7d0c7eddbcb not-for-merge branch 'testcommit12' of github.com:jantman/gitpython_issue_301 -c8ae02d70be5592704e42ac1fcb0d13cf8a7b4fe not-for-merge branch 'testcommit120' of github.com:jantman/gitpython_issue_301 -1a7cece8c70eb73485b5144cd9b0d460b2f49c83 not-for-merge branch 'testcommit1200' of github.com:jantman/gitpython_issue_301 -c273dc35f9668fd0d76bfd1e740cd1867c5b4db7 not-for-merge branch 'testcommit1201' of github.com:jantman/gitpython_issue_301 -19d27a3d8c1f8791cf93053a025e0b8d5ea0f415 not-for-merge branch 'testcommit1202' of github.com:jantman/gitpython_issue_301 -c0c3d079a5ad9cb5804b4887384e1d36d22267c0 not-for-merge branch 'testcommit1203' of github.com:jantman/gitpython_issue_301 -b3734aaca05fa0a678efcc3b9c1fef6ab8dbc18e not-for-merge branch 'testcommit1204' of github.com:jantman/gitpython_issue_301 -f6436a629721d356a980ab75a216db5a82306d81 not-for-merge branch 'testcommit1205' of github.com:jantman/gitpython_issue_301 -7fe5dcbf48e5c46a8c765cb9ff7d4d79f4aed662 not-for-merge branch 'testcommit1206' of github.com:jantman/gitpython_issue_301 -4733001f193d7adaa2373497c0dde4df63ddf9c2 not-for-merge branch 'testcommit1207' of github.com:jantman/gitpython_issue_301 -f3236bfa507baa2ad0a3b9364b7333d25ffbe465 not-for-merge branch 'testcommit1208' of github.com:jantman/gitpython_issue_301 -5bd9c0bf26bb7b13c46d11370442d2df58f86414 not-for-merge branch 'testcommit1209' of github.com:jantman/gitpython_issue_301 -37afc3365b9dc38f5060539b8a607679a66105ec not-for-merge branch 'testcommit121' of github.com:jantman/gitpython_issue_301 -6c2898e7d320b52ad15ac99dc1b182e0282f5ce6 not-for-merge branch 'testcommit1210' of github.com:jantman/gitpython_issue_301 -10d235e4ba482d7d8e130e8e4caee72d210851d0 not-for-merge branch 'testcommit1211' of github.com:jantman/gitpython_issue_301 -d32b703e1f5d1202a84fe8b7a5802004f3d0c4b7 not-for-merge branch 'testcommit1212' of github.com:jantman/gitpython_issue_301 -33359c5b379e60f699eabc9f4f5dd9a996eb6d52 not-for-merge branch 'testcommit1213' of github.com:jantman/gitpython_issue_301 -224fc55c881e41d3021ecb1c2d4bde6e24625964 not-for-merge branch 'testcommit1214' of github.com:jantman/gitpython_issue_301 -9bc61997f25937d8c432ec03e6c9a6fc0dcec3e0 not-for-merge branch 'testcommit1215' of github.com:jantman/gitpython_issue_301 -a26f66075c9be07dec5fa0080fe77d8b40f00e9a not-for-merge branch 'testcommit1216' of github.com:jantman/gitpython_issue_301 -e1f7848720c2c482da0f0aae2960e039e293ba02 not-for-merge branch 'testcommit1217' of github.com:jantman/gitpython_issue_301 -8023fd647a1b9084210842cccc33328e9b34c488 not-for-merge branch 'testcommit1218' of github.com:jantman/gitpython_issue_301 -3089eb6f9b4bc6d21d8cabf6efed5ef19ddf147e not-for-merge branch 'testcommit1219' of github.com:jantman/gitpython_issue_301 -3f8921965ebe3783d820ab4c86ee792abe2119f5 not-for-merge branch 'testcommit122' of github.com:jantman/gitpython_issue_301 -ddbe2c92c86118f1845bcb0838816df97aa87076 not-for-merge branch 'testcommit1220' of github.com:jantman/gitpython_issue_301 -99c87e055d0b50065bd41268e854b9e620b4bc28 not-for-merge branch 'testcommit1221' of github.com:jantman/gitpython_issue_301 -d67a6d82d83bffa3094f581208e1b42f0dea48fd not-for-merge branch 'testcommit1222' of github.com:jantman/gitpython_issue_301 -ed82e93f0a65931744846b0339173cb4467e542a not-for-merge branch 'testcommit1223' of github.com:jantman/gitpython_issue_301 -4b937668a267d2834b5d3cb04e71e5ccacdbf5f9 not-for-merge branch 'testcommit1224' of github.com:jantman/gitpython_issue_301 -6d4f87d580c4c7d03aa1197aaeac1a090d77a94e not-for-merge branch 'testcommit1225' of github.com:jantman/gitpython_issue_301 -7a2d34f9652aafa466dc2e7468bc2c242c5aa9ec not-for-merge branch 'testcommit1226' of github.com:jantman/gitpython_issue_301 -6649172a7854ed8210c75680a3bfb3d65d8d8c1f not-for-merge branch 'testcommit1227' of github.com:jantman/gitpython_issue_301 -c6ec1586a8104013066ee5821d42db649460b27c not-for-merge branch 'testcommit1228' of github.com:jantman/gitpython_issue_301 -1531579d34a1f19ec0d7a78dc83a3c9ae05aa721 not-for-merge branch 'testcommit1229' of github.com:jantman/gitpython_issue_301 -fa3fa7d446c26c2f015c2f6dd61f1e2138a8d6c9 not-for-merge branch 'testcommit123' of github.com:jantman/gitpython_issue_301 -7fb6c9a6731548024169343733bab02b751724a6 not-for-merge branch 'testcommit1230' of github.com:jantman/gitpython_issue_301 -a684a7296369c1fd0b54857ac8e8678f54d3e011 not-for-merge branch 'testcommit1231' of github.com:jantman/gitpython_issue_301 -3908d0dc256277b9ab5099b947701c269fe81d42 not-for-merge branch 'testcommit1232' of github.com:jantman/gitpython_issue_301 -a3445f55ec1c9dc41ce44a9051d3c83b44043349 not-for-merge branch 'testcommit1233' of github.com:jantman/gitpython_issue_301 -f9a5f80ad16ade559d1d53ac8d01c661aae45b19 not-for-merge branch 'testcommit1234' of github.com:jantman/gitpython_issue_301 -4dfd70925886f4f7c0e384d505e0d9367a774ca0 not-for-merge branch 'testcommit1235' of github.com:jantman/gitpython_issue_301 -bbdd8d4d857523a14f0ab7632fd82414cbca2a8e not-for-merge branch 'testcommit1236' of github.com:jantman/gitpython_issue_301 -1c526ea4948f0dd6a4843f5e139cdbde8cde684a not-for-merge branch 'testcommit1237' of github.com:jantman/gitpython_issue_301 -7c8354a6bad3b80bfdcc897ba4bdbab3dfdb065d not-for-merge branch 'testcommit1238' of github.com:jantman/gitpython_issue_301 -5550055865f962179c1435f2c407e15985c1f05f not-for-merge branch 'testcommit1239' of github.com:jantman/gitpython_issue_301 -e2b6345c9afe44a57698169b9fed2b7d404dbfb8 not-for-merge branch 'testcommit124' of github.com:jantman/gitpython_issue_301 -200330e705ca4b61acbc9bb299240a4c5513e74b not-for-merge branch 'testcommit1240' of github.com:jantman/gitpython_issue_301 -7f0bb6240776c6ee7b469adfa63cfd9d8dfecb59 not-for-merge branch 'testcommit1241' of github.com:jantman/gitpython_issue_301 -59674d33dade0dca533159833f16a54e7eb5fba7 not-for-merge branch 'testcommit1242' of github.com:jantman/gitpython_issue_301 -b49f392bd60038daa7addae08e03b4e8966f3bf8 not-for-merge branch 'testcommit1243' of github.com:jantman/gitpython_issue_301 -12daf7cd0173681aa72241fa101fd55ccd0ad014 not-for-merge branch 'testcommit1244' of github.com:jantman/gitpython_issue_301 -b2de7b56d619c18c341df03cdd9d390b6a84550d not-for-merge branch 'testcommit1245' of github.com:jantman/gitpython_issue_301 -0e24d5f1bd3c6ce0df6ac1028c2b136880d64b4b not-for-merge branch 'testcommit1246' of github.com:jantman/gitpython_issue_301 -8edb0a11c2cb2bd670e65680ac6b2dfa247a5fa2 not-for-merge branch 'testcommit1247' of github.com:jantman/gitpython_issue_301 -13a2a7044617fde9da4ca68c7706ef5f3142c700 not-for-merge branch 'testcommit1248' of github.com:jantman/gitpython_issue_301 -c6b92b8f948d7eec32c08d48f74b18e5aab36364 not-for-merge branch 'testcommit1249' of github.com:jantman/gitpython_issue_301 -3dcfa77f3c552a95208f9cefdc1cacd9dd32c810 not-for-merge branch 'testcommit125' of github.com:jantman/gitpython_issue_301 -c5aeba94b0db763d7e967b9c2e5c57aca3a5da3c not-for-merge branch 'testcommit1250' of github.com:jantman/gitpython_issue_301 -1c8f5177549888d810047dcabfb5422a0864b84c not-for-merge branch 'testcommit1251' of github.com:jantman/gitpython_issue_301 -65c8c35ca7151800b8eb1fe3d4c9fbb79d6229f4 not-for-merge branch 'testcommit1252' of github.com:jantman/gitpython_issue_301 -9435f03a3164fc4bd5b0662df3de534e1a31deb4 not-for-merge branch 'testcommit1253' of github.com:jantman/gitpython_issue_301 -a6a7752eb5528afc49ac57bdcbce8086e8405f15 not-for-merge branch 'testcommit1254' of github.com:jantman/gitpython_issue_301 -ba85742d3ecf45b4cd2f10ae8415cad77b205dad not-for-merge branch 'testcommit1255' of github.com:jantman/gitpython_issue_301 -3862f60a0578ab367c9101d71a1e57e79a69d437 not-for-merge branch 'testcommit1256' of github.com:jantman/gitpython_issue_301 -aaa3e1f7b4ae8a33f3b8ab7ff3cfd1581669bd8d not-for-merge branch 'testcommit1257' of github.com:jantman/gitpython_issue_301 -602f3b372e63e48b5a6a9045b79822eed47d7bcd not-for-merge branch 'testcommit1258' of github.com:jantman/gitpython_issue_301 -48d61a52461a222cfae9dddebd0f9d8d5569bc30 not-for-merge branch 'testcommit1259' of github.com:jantman/gitpython_issue_301 -c0345930edb1c6b64819db1a74c995e9d33d9dc3 not-for-merge branch 'testcommit126' of github.com:jantman/gitpython_issue_301 -b2d7b7f9d81b01701c93500df462aa3db9cbe02f not-for-merge branch 'testcommit1260' of github.com:jantman/gitpython_issue_301 -d4055c32978c932959b6a27682696e74e695777b not-for-merge branch 'testcommit1261' of github.com:jantman/gitpython_issue_301 -d8226cd372fcba01784c60085dd4700089612f0c not-for-merge branch 'testcommit1262' of github.com:jantman/gitpython_issue_301 -f0a2bfd3d906267dfeb4e476b63bc155405b15bf not-for-merge branch 'testcommit1263' of github.com:jantman/gitpython_issue_301 -8d29fdc6f8fafe5449920b3195428aa66cae8868 not-for-merge branch 'testcommit1264' of github.com:jantman/gitpython_issue_301 -fe487724ba78a69b6ffef1b0c5c2758e9eb4fa34 not-for-merge branch 'testcommit1265' of github.com:jantman/gitpython_issue_301 -0a61a6f00479d0e40929132d20d2d6bd989fc7c6 not-for-merge branch 'testcommit1266' of github.com:jantman/gitpython_issue_301 -e217bbc3907220e09f37554e45759d8d7845ceed not-for-merge branch 'testcommit1267' of github.com:jantman/gitpython_issue_301 -c0f97a4fdb47d6610d0f597597e7b440a2830c96 not-for-merge branch 'testcommit1268' of github.com:jantman/gitpython_issue_301 -5616c697e5f3641b3b89d7571c34cd68d8173cf7 not-for-merge branch 'testcommit1269' of github.com:jantman/gitpython_issue_301 -a8627944a005270fb5c89f8b5aea3b550738057d not-for-merge branch 'testcommit127' of github.com:jantman/gitpython_issue_301 -4a5029178f86a2d8d0f75499abb010f1c8d88598 not-for-merge branch 'testcommit1270' of github.com:jantman/gitpython_issue_301 -b6a75d09b3f33e2469812e0b94460168201867ca not-for-merge branch 'testcommit1271' of github.com:jantman/gitpython_issue_301 -0263e0e2c7a269ba254f3c5d6cbda9c50a8a11bf not-for-merge branch 'testcommit1272' of github.com:jantman/gitpython_issue_301 -0cf0b2c48109cf906c4f799b2fb115b9d65cb1cb not-for-merge branch 'testcommit1273' of github.com:jantman/gitpython_issue_301 -1f98a2f26b55d95ced1ffa639a6b56780ded9b4d not-for-merge branch 'testcommit1274' of github.com:jantman/gitpython_issue_301 -c922c196018e49890a391c8071ed3ed682b16133 not-for-merge branch 'testcommit1275' of github.com:jantman/gitpython_issue_301 -801a6946cfabbe8a45b61ff102e406f7c9f6c341 not-for-merge branch 'testcommit1276' of github.com:jantman/gitpython_issue_301 -b7b814b9562a2466a881354efaef1e9e64612fc1 not-for-merge branch 'testcommit1277' of github.com:jantman/gitpython_issue_301 -b16acccce3d80a1cb2f6d594e7197c89eeb5dd9d not-for-merge branch 'testcommit1278' of github.com:jantman/gitpython_issue_301 -a66150c4c5548ddaaef5054c671660e4e6ba894f not-for-merge branch 'testcommit1279' of github.com:jantman/gitpython_issue_301 -fdbcb6fb2b480e5f46a0fab92f42b3eb80db1bc3 not-for-merge branch 'testcommit128' of github.com:jantman/gitpython_issue_301 -40958f670c56537c3b028a8b67fd878e5724ecd3 not-for-merge branch 'testcommit1280' of github.com:jantman/gitpython_issue_301 -16e640590f1b4007d81da333c17d3bbd08cba561 not-for-merge branch 'testcommit1281' of github.com:jantman/gitpython_issue_301 -6b23eabf5f3da092cbae17b0e1e0e180e5785725 not-for-merge branch 'testcommit1282' of github.com:jantman/gitpython_issue_301 -18345f72e075b8952a0bfa4de2425857c428a348 not-for-merge branch 'testcommit1283' of github.com:jantman/gitpython_issue_301 -2740274ec39b89e3e7655ffd297b0c9d54c56b12 not-for-merge branch 'testcommit1284' of github.com:jantman/gitpython_issue_301 -328c0fd03b055a15fc77ff46bc29bcab39a7d896 not-for-merge branch 'testcommit1285' of github.com:jantman/gitpython_issue_301 -97fa973768e0779f0ebe4cca9a1f4d657ff89563 not-for-merge branch 'testcommit1286' of github.com:jantman/gitpython_issue_301 -472466ea520e1178faec9e6da3f45ed6e08c8a57 not-for-merge branch 'testcommit1287' of github.com:jantman/gitpython_issue_301 -55487cbe72c4d0452f21df644af6872090ccaf95 not-for-merge branch 'testcommit1288' of github.com:jantman/gitpython_issue_301 -ddcb315e54934cbc96c4651fd263cfdab6b0d157 not-for-merge branch 'testcommit1289' of github.com:jantman/gitpython_issue_301 -35111dc8446354ce2c61b885b5d81d00d0067f87 not-for-merge branch 'testcommit129' of github.com:jantman/gitpython_issue_301 -389a12bf807abdb68cf9258da631df6e17f4983c not-for-merge branch 'testcommit1290' of github.com:jantman/gitpython_issue_301 -1da47c0973bf8d9c2d15712b317d27d778623965 not-for-merge branch 'testcommit1291' of github.com:jantman/gitpython_issue_301 -e1544f6ad6c2236c67702a98dc44faa5470f4ca8 not-for-merge branch 'testcommit1292' of github.com:jantman/gitpython_issue_301 -f09ca7832ca5c7348dadac88d0e2020b3b90deff not-for-merge branch 'testcommit1293' of github.com:jantman/gitpython_issue_301 -41a7a3b448dd4f48e47527c043ba7381174a7181 not-for-merge branch 'testcommit1294' of github.com:jantman/gitpython_issue_301 -45f152403fab6fcb74cb5f696295bce7c35ae262 not-for-merge branch 'testcommit1295' of github.com:jantman/gitpython_issue_301 -331f9f77d469e268d86ba0e00ddfb9744a88740e not-for-merge branch 'testcommit1296' of github.com:jantman/gitpython_issue_301 -3ae655a0237dc2600c4691fad6da754771a9d733 not-for-merge branch 'testcommit1297' of github.com:jantman/gitpython_issue_301 -629b87c5252c2d75612340623e6919fb34eb68f5 not-for-merge branch 'testcommit1298' of github.com:jantman/gitpython_issue_301 -4a439a3f5a92c2264e0aed1a9cd92bb99a71ff91 not-for-merge branch 'testcommit1299' of github.com:jantman/gitpython_issue_301 -f21a2ed894533cfd439abef2d015716aa870bc2b not-for-merge branch 'testcommit13' of github.com:jantman/gitpython_issue_301 -494bc67a7e8562f6e55602b633c218129871e516 not-for-merge branch 'testcommit130' of github.com:jantman/gitpython_issue_301 -4448225334875001fc4e7ef1dd38ff2a1e82ca8f not-for-merge branch 'testcommit1300' of github.com:jantman/gitpython_issue_301 -c903bd75677a46688a118d35a900e902b7420024 not-for-merge branch 'testcommit1301' of github.com:jantman/gitpython_issue_301 -17e21c3221fc62b3c66507fe8c0f253c52e939d9 not-for-merge branch 'testcommit1302' of github.com:jantman/gitpython_issue_301 -8c63e973b927c3ed557e07e0241201a655f45621 not-for-merge branch 'testcommit1303' of github.com:jantman/gitpython_issue_301 -ce6b131c441b000cb16ee58e4bd12753ac06a6f8 not-for-merge branch 'testcommit1304' of github.com:jantman/gitpython_issue_301 -b807eab7a0da60ed68f3411cce38a8d912fd6b56 not-for-merge branch 'testcommit1305' of github.com:jantman/gitpython_issue_301 -6d1f426b09d1bd2ed433d2b67d33b4edf5a65b1b not-for-merge branch 'testcommit1306' of github.com:jantman/gitpython_issue_301 -9db3aa543d64aff701190a4b5b2adc44020c2b0a not-for-merge branch 'testcommit1307' of github.com:jantman/gitpython_issue_301 -59b34e0112c83e58640c1d7af3d5823d006620b0 not-for-merge branch 'testcommit1308' of github.com:jantman/gitpython_issue_301 -9429570db3230fcc3bb64eaf80f07c0b4d77c1d4 not-for-merge branch 'testcommit1309' of github.com:jantman/gitpython_issue_301 -035173ba6f0408792a81d823fa8447fa128218de not-for-merge branch 'testcommit131' of github.com:jantman/gitpython_issue_301 -0cd395fe7cee54ba3a192ab3bed45ccf5e3680e5 not-for-merge branch 'testcommit1310' of github.com:jantman/gitpython_issue_301 -305c17ab30d4adfbb7c7ec2e6747323f8bfe109b not-for-merge branch 'testcommit1311' of github.com:jantman/gitpython_issue_301 -20da0bac5c179f36f753cb8fa7a7d8317276e181 not-for-merge branch 'testcommit1312' of github.com:jantman/gitpython_issue_301 -100847fa1b521ad5eab501b5cd0ab43b6b8c7340 not-for-merge branch 'testcommit1313' of github.com:jantman/gitpython_issue_301 -6fd07bf74d0593922bde9d00fd1394314011c292 not-for-merge branch 'testcommit1314' of github.com:jantman/gitpython_issue_301 -a7c8ffff394a98335df5d1e432dcaccb200ba468 not-for-merge branch 'testcommit1315' of github.com:jantman/gitpython_issue_301 -1a045affcd539c4649a1618a640a69dc197bf6de not-for-merge branch 'testcommit1316' of github.com:jantman/gitpython_issue_301 -0a3d476403e1b9ead6b9c498e8a12912d0341762 not-for-merge branch 'testcommit1317' of github.com:jantman/gitpython_issue_301 -6f784c0c418669b5c4941b54666fa85b0ed9faac not-for-merge branch 'testcommit1318' of github.com:jantman/gitpython_issue_301 -aec10eaee00908d2ebe35f67d9e9b1aa0d9ac1bc not-for-merge branch 'testcommit1319' of github.com:jantman/gitpython_issue_301 -66f2619ed5a9b5ab1da9c171730a95cff1f69d7e not-for-merge branch 'testcommit132' of github.com:jantman/gitpython_issue_301 -7ec982ab4b6a521d508fb4f8b025adefb7db1fd7 not-for-merge branch 'testcommit1320' of github.com:jantman/gitpython_issue_301 -fcc0270a252d3a4a61185399d2c2e308845e1b59 not-for-merge branch 'testcommit1321' of github.com:jantman/gitpython_issue_301 -ad2b5ea7137907042e6bb070cddbf9e251551482 not-for-merge branch 'testcommit1322' of github.com:jantman/gitpython_issue_301 -74a5045d67df103d53b42c9b1fd698fda85b1689 not-for-merge branch 'testcommit1323' of github.com:jantman/gitpython_issue_301 -cebebbc2b2323e0b5f7f9b72740ea25b7771e65e not-for-merge branch 'testcommit1324' of github.com:jantman/gitpython_issue_301 -f4aad42eea9ec42ac97c865901601520544debed not-for-merge branch 'testcommit1325' of github.com:jantman/gitpython_issue_301 -a1921397f68b1b79f842219905991996f5e35129 not-for-merge branch 'testcommit1326' of github.com:jantman/gitpython_issue_301 -391075a8fb1835406ca75d93aa9dba2346e0f23f not-for-merge branch 'testcommit1327' of github.com:jantman/gitpython_issue_301 -800c2370259a213f3bb5a56d6ebbb83e2be36afe not-for-merge branch 'testcommit1328' of github.com:jantman/gitpython_issue_301 -8b794b4e7293049294b1f79813b9380537071f1f not-for-merge branch 'testcommit1329' of github.com:jantman/gitpython_issue_301 -1b30ed2886d442d33b15674ca4da71e94520061b not-for-merge branch 'testcommit133' of github.com:jantman/gitpython_issue_301 -108d1f0269b5a8c2c04b478466bd54b6d107bbdb not-for-merge branch 'testcommit1330' of github.com:jantman/gitpython_issue_301 -c6b5cc45062bbae816b9604330dc43bbe4421a89 not-for-merge branch 'testcommit1331' of github.com:jantman/gitpython_issue_301 -2a560b8afc0c624895d0655a8f07f6c3c035d5b0 not-for-merge branch 'testcommit1332' of github.com:jantman/gitpython_issue_301 -090943c2ca312cb140270ebe5572054962749115 not-for-merge branch 'testcommit1333' of github.com:jantman/gitpython_issue_301 -ec3f55826f769fe2f9d54de75a2664abd8cd2ce3 not-for-merge branch 'testcommit1334' of github.com:jantman/gitpython_issue_301 -a37598f237ff29c6e3a95954e05ec3ca28847d67 not-for-merge branch 'testcommit1335' of github.com:jantman/gitpython_issue_301 -37e28e8550c13b53916cbaaa652cf133055ae972 not-for-merge branch 'testcommit1336' of github.com:jantman/gitpython_issue_301 -7ffa0ba56766f3fc6030cae79ca21322a41ac44b not-for-merge branch 'testcommit1337' of github.com:jantman/gitpython_issue_301 -630444aaea5b26a478e40785a78d329cc26f9fb5 not-for-merge branch 'testcommit1338' of github.com:jantman/gitpython_issue_301 -2f85dba18ba1d4e185f182ca537ac2770dd27f80 not-for-merge branch 'testcommit1339' of github.com:jantman/gitpython_issue_301 -1c8da6c47058e4a8b887e2efdbd73c88fc9ad563 not-for-merge branch 'testcommit134' of github.com:jantman/gitpython_issue_301 -c3e0b7890c84fc6ec99e755c93bd67df21994f1f not-for-merge branch 'testcommit1340' of github.com:jantman/gitpython_issue_301 -5f72be5cb0bccd8d40e059cd967fb18002e2d7cc not-for-merge branch 'testcommit1341' of github.com:jantman/gitpython_issue_301 -f3fd85d022e8a1f56d4a71437d1d60ed5f89e50d not-for-merge branch 'testcommit1342' of github.com:jantman/gitpython_issue_301 -e2800a5f6819a486ab157fc4b1a57b767c5d86e0 not-for-merge branch 'testcommit1343' of github.com:jantman/gitpython_issue_301 -968488acb290d9a17f6ef2fb6b37ff2589b5b296 not-for-merge branch 'testcommit1344' of github.com:jantman/gitpython_issue_301 -ac63d0b8c2ef2861d1100c892651c8bbff068a01 not-for-merge branch 'testcommit1345' of github.com:jantman/gitpython_issue_301 -c1ea47152d583858ca9fd0ce2b4e2ee826df68c9 not-for-merge branch 'testcommit1346' of github.com:jantman/gitpython_issue_301 -536706a293a82565722193bd5ced953ddc81ef71 not-for-merge branch 'testcommit1347' of github.com:jantman/gitpython_issue_301 -49c194bca48052418474b9a5a358dc0fa60dbf34 not-for-merge branch 'testcommit1348' of github.com:jantman/gitpython_issue_301 -50a77638cd0e9bcfebb6c95794f72a42006c93a1 not-for-merge branch 'testcommit1349' of github.com:jantman/gitpython_issue_301 -599aaccca44ac72d0e136a4370c85cf32bdf8841 not-for-merge branch 'testcommit135' of github.com:jantman/gitpython_issue_301 -21a51222a4510ca00bc049c49252616a67238e6c not-for-merge branch 'testcommit1350' of github.com:jantman/gitpython_issue_301 -b4581d67c4ee0019b16fbbc90914aa83b5bbed10 not-for-merge branch 'testcommit1351' of github.com:jantman/gitpython_issue_301 -68c48f52ae3cb2d7425df2d7520eaa724279e659 not-for-merge branch 'testcommit1352' of github.com:jantman/gitpython_issue_301 -a6acaba93617fd99a423b43ced738d0d2698452a not-for-merge branch 'testcommit1353' of github.com:jantman/gitpython_issue_301 -29bbd78089ab9826112c93139b35d6236fca24bd not-for-merge branch 'testcommit1354' of github.com:jantman/gitpython_issue_301 -dd1538461b459bb703a9d4cc22e9b83f22e09b38 not-for-merge branch 'testcommit1355' of github.com:jantman/gitpython_issue_301 -69fc8d428059f97980c2e49c94f44ece0d22841e not-for-merge branch 'testcommit1356' of github.com:jantman/gitpython_issue_301 -068a4d5712d78c18f9bff5d11ce01dc5ece6e776 not-for-merge branch 'testcommit1357' of github.com:jantman/gitpython_issue_301 -6c7b12bb8050f90f5f4a5c259c54100ef6f214d8 not-for-merge branch 'testcommit1358' of github.com:jantman/gitpython_issue_301 -1695fdad1aa06c3ce280b6a370d107b5a81ea14b not-for-merge branch 'testcommit1359' of github.com:jantman/gitpython_issue_301 -7171ec0e3d018afd0466ff16eb17645f2f42fa88 not-for-merge branch 'testcommit136' of github.com:jantman/gitpython_issue_301 -1451ea5b2992026f12c835f6e4d13147723c86c1 not-for-merge branch 'testcommit1360' of github.com:jantman/gitpython_issue_301 -2665d1b8e9d3d10916795e851569dd28f1315d26 not-for-merge branch 'testcommit1361' of github.com:jantman/gitpython_issue_301 -7b93cf6b45cc2057bec223725a06e604ce698060 not-for-merge branch 'testcommit1362' of github.com:jantman/gitpython_issue_301 -3de5760230ae6eec8d4790b06ff2355f2090f3e6 not-for-merge branch 'testcommit1363' of github.com:jantman/gitpython_issue_301 -5d1b0c128f0760f4a3731b91cbe897f014ce59ce not-for-merge branch 'testcommit1364' of github.com:jantman/gitpython_issue_301 -415f762fbd9150a2334afa18590403f1e07da971 not-for-merge branch 'testcommit1365' of github.com:jantman/gitpython_issue_301 -c26f250b54270b02b3ee88687d9ce0f985c48527 not-for-merge branch 'testcommit1366' of github.com:jantman/gitpython_issue_301 -f924dc2cf152a31271062b101ac56ca47f898cca not-for-merge branch 'testcommit1367' of github.com:jantman/gitpython_issue_301 -fce412e5d24537fcfca38dab83e97ec5636fe409 not-for-merge branch 'testcommit1368' of github.com:jantman/gitpython_issue_301 -fa1d82fcf27b513d7e6a5850310fb336a7267c2c not-for-merge branch 'testcommit1369' of github.com:jantman/gitpython_issue_301 -fa577d62d9ea9a59d3fa79454458d2b1ad9ab0e9 not-for-merge branch 'testcommit137' of github.com:jantman/gitpython_issue_301 -8453631771aed0740ed55400beea87fb5fd35305 not-for-merge branch 'testcommit1370' of github.com:jantman/gitpython_issue_301 -327b3a70cbd49d5f5795bd1d94352f8caa124de9 not-for-merge branch 'testcommit1371' of github.com:jantman/gitpython_issue_301 -9f6a9bde6a17ca688011f67105168e59f704a9c7 not-for-merge branch 'testcommit1372' of github.com:jantman/gitpython_issue_301 -6ae0eed5fb0412a6197e86f41152de503a3d2a66 not-for-merge branch 'testcommit1373' of github.com:jantman/gitpython_issue_301 -0bd81c3ac896c39fae5b1890219a30bc5b533942 not-for-merge branch 'testcommit1374' of github.com:jantman/gitpython_issue_301 -d2b9b79b6c03742e9f0460ba33f7f9cf3972b6c3 not-for-merge branch 'testcommit1375' of github.com:jantman/gitpython_issue_301 -93d38c570071fb1c2d432c8c89c83aac4cc55148 not-for-merge branch 'testcommit1376' of github.com:jantman/gitpython_issue_301 -88fbc6ed6740a8f323e077afcab4fe67a589f677 not-for-merge branch 'testcommit1377' of github.com:jantman/gitpython_issue_301 -120dad271ccec5028a8d1f2e0102714cea8a6161 not-for-merge branch 'testcommit1378' of github.com:jantman/gitpython_issue_301 -c43da9ffa4dec5920ea7ca265194783e21d56180 not-for-merge branch 'testcommit1379' of github.com:jantman/gitpython_issue_301 -656d4a02e083b6b7159b9a54722cd2e4154769b4 not-for-merge branch 'testcommit138' of github.com:jantman/gitpython_issue_301 -7ff2c1c9392f66a3a1aadb3c1afe8263c81834db not-for-merge branch 'testcommit1380' of github.com:jantman/gitpython_issue_301 -334e3481ed565733cc4cd83da48cc608d6b18c5b not-for-merge branch 'testcommit1381' of github.com:jantman/gitpython_issue_301 -547ba0ed34920aedf2b2dcdf4c29db0c828b7d89 not-for-merge branch 'testcommit1382' of github.com:jantman/gitpython_issue_301 -5365ba7bc3048827f64774d2239838ad09f8704f not-for-merge branch 'testcommit1383' of github.com:jantman/gitpython_issue_301 -17f62d19a61711130f8b56461c0b2bd264bf4db2 not-for-merge branch 'testcommit1384' of github.com:jantman/gitpython_issue_301 -40ee983bdcc9875bb347c39feabbf0546c72414a not-for-merge branch 'testcommit1385' of github.com:jantman/gitpython_issue_301 -607feaef441b4b705755e1ba2c2b59df4a496a27 not-for-merge branch 'testcommit1386' of github.com:jantman/gitpython_issue_301 -d0fffc2c3e679b3adba6b53b7d1a39218160fada not-for-merge branch 'testcommit1387' of github.com:jantman/gitpython_issue_301 -884583a7cee5bd6aeabc4309ddc1417db97a41a7 not-for-merge branch 'testcommit1388' of github.com:jantman/gitpython_issue_301 -05801c213bdaecf8d63188e9334269b46ea2c3c8 not-for-merge branch 'testcommit1389' of github.com:jantman/gitpython_issue_301 -8fb690c72fd4f3dfd8e2dec723ee559ff3fe4f4e not-for-merge branch 'testcommit139' of github.com:jantman/gitpython_issue_301 -3c91d8ae1a388fe9d0072c2e10958e0a8805a134 not-for-merge branch 'testcommit1390' of github.com:jantman/gitpython_issue_301 -0bbf7f583b0e161b36cdbbee09735fa5f97d63ff not-for-merge branch 'testcommit1391' of github.com:jantman/gitpython_issue_301 -8c05f87af535a7241b5cfa7d17fce9a6b9803794 not-for-merge branch 'testcommit1392' of github.com:jantman/gitpython_issue_301 -2d77ca8dc95cc6db4e65d318ee63d1bb55a1249c not-for-merge branch 'testcommit1393' of github.com:jantman/gitpython_issue_301 -8267efe64d7c56dc618d6131aeaba2f0d2510af3 not-for-merge branch 'testcommit1394' of github.com:jantman/gitpython_issue_301 -54587c6d2ac8dd8a4cadf73fdeeecfe14fed1188 not-for-merge branch 'testcommit1395' of github.com:jantman/gitpython_issue_301 -d04061c0732cb32b6c16a9f44135fc3d1ef06528 not-for-merge branch 'testcommit1396' of github.com:jantman/gitpython_issue_301 -d56fae58887fabed6fce908f3499bcf6a5e6a629 not-for-merge branch 'testcommit1397' of github.com:jantman/gitpython_issue_301 -2655f52f7f3c0cd68bcafdd6d3e27a88d91e80af not-for-merge branch 'testcommit1398' of github.com:jantman/gitpython_issue_301 -5c5e35d52cae040ab351d289586075d3411b8309 not-for-merge branch 'testcommit1399' of github.com:jantman/gitpython_issue_301 -4726511baada4463aad73f8383e53e896693ba0c not-for-merge branch 'testcommit14' of github.com:jantman/gitpython_issue_301 -75f6dd4cc0c0da3f0d4da04505ada25aa48fad8c not-for-merge branch 'testcommit140' of github.com:jantman/gitpython_issue_301 -5c3b8654292c21ce23e52655efeb6d2c9d48b8a7 not-for-merge branch 'testcommit1400' of github.com:jantman/gitpython_issue_301 -ece449a362ab9bd156a16f692806900d01d4e6e3 not-for-merge branch 'testcommit1401' of github.com:jantman/gitpython_issue_301 -e229a0b1c01a350974a8fb6d7090e99ac72ea24b not-for-merge branch 'testcommit1402' of github.com:jantman/gitpython_issue_301 -983ea6b69afc11d039fff2d90a8ab0aa9f57a264 not-for-merge branch 'testcommit1403' of github.com:jantman/gitpython_issue_301 -6a670d0d8eb05924afdf12c5b40bd71cc90e74d8 not-for-merge branch 'testcommit1404' of github.com:jantman/gitpython_issue_301 -a7a58e9a3f1c91fdb621f9d3f2a9ac366e3a92c8 not-for-merge branch 'testcommit1405' of github.com:jantman/gitpython_issue_301 -599cf8662e948ef4016bb1ed3ebdfb8b13aed572 not-for-merge branch 'testcommit1406' of github.com:jantman/gitpython_issue_301 -16e46ea6714b6dfb32f232a8985a422b67ac983f not-for-merge branch 'testcommit1407' of github.com:jantman/gitpython_issue_301 -957d130f85b71849427335084963502aa05ccaa6 not-for-merge branch 'testcommit1408' of github.com:jantman/gitpython_issue_301 -785e285d11fdbada098e46b9a86d58a3bdb08b6f not-for-merge branch 'testcommit1409' of github.com:jantman/gitpython_issue_301 -b5e3dbf786c02e87d06201d389c31013a7b8aa93 not-for-merge branch 'testcommit141' of github.com:jantman/gitpython_issue_301 -77d0537a8dad05ae596c076528c5408313a0e2c9 not-for-merge branch 'testcommit1410' of github.com:jantman/gitpython_issue_301 -adc84570b78ec2b9a2c4f0d053b66e8d2f2582fe not-for-merge branch 'testcommit1411' of github.com:jantman/gitpython_issue_301 -c2c9b46234369d9b873d0dd955d6a79bf1a05091 not-for-merge branch 'testcommit1412' of github.com:jantman/gitpython_issue_301 -c64ff88a370ef5391212a0240ef770999feaf2a2 not-for-merge branch 'testcommit1413' of github.com:jantman/gitpython_issue_301 -e5daeddc97d52195369fcfc06ffa95887b7d8570 not-for-merge branch 'testcommit1414' of github.com:jantman/gitpython_issue_301 -b46da404b60c03445b95ef496230b98572996c23 not-for-merge branch 'testcommit1415' of github.com:jantman/gitpython_issue_301 -ac747c9e6b8aa80d5a364eac1dd20893e0c9452e not-for-merge branch 'testcommit1416' of github.com:jantman/gitpython_issue_301 -6e24e93eb0c36e7385d3645963ad2291ea07d8e6 not-for-merge branch 'testcommit1417' of github.com:jantman/gitpython_issue_301 -9bff17506fdba526f5d6f37d07ff0010612b913f not-for-merge branch 'testcommit1418' of github.com:jantman/gitpython_issue_301 -eed0494f7a94755da24df44d76fc9561a93e9231 not-for-merge branch 'testcommit1419' of github.com:jantman/gitpython_issue_301 -d59c8cfd0e2632214d992acc8a2ada48fb99c1a7 not-for-merge branch 'testcommit142' of github.com:jantman/gitpython_issue_301 -66382cbf8bf06fdd3d7a73021bbc9173f7f1c891 not-for-merge branch 'testcommit1420' of github.com:jantman/gitpython_issue_301 -6d566d47d2bc4cdff93aec5173e3590d760ff0b6 not-for-merge branch 'testcommit1421' of github.com:jantman/gitpython_issue_301 -5a2f1ed4caaf1214368dbc6d3ea59c96e7e4cada not-for-merge branch 'testcommit1422' of github.com:jantman/gitpython_issue_301 -5636e4ae3be13ad559c5178585d4314eb6c6fc76 not-for-merge branch 'testcommit1423' of github.com:jantman/gitpython_issue_301 -2893e152d7bb86e5cf5696a7cc67c0337f839cae not-for-merge branch 'testcommit1424' of github.com:jantman/gitpython_issue_301 -109b55abbf02eb019d62bd7d0f83d6c5a3f91e4d not-for-merge branch 'testcommit1425' of github.com:jantman/gitpython_issue_301 -f7ffe7889b02e77ba06cac4da445026274d9bbcc not-for-merge branch 'testcommit1426' of github.com:jantman/gitpython_issue_301 -b591ec82f57675e4d15b7383e3e7298439155515 not-for-merge branch 'testcommit1427' of github.com:jantman/gitpython_issue_301 -7814e65fbb105c16809b64bc160b29ecbd71a737 not-for-merge branch 'testcommit1428' of github.com:jantman/gitpython_issue_301 -e9613fd04c5f790f6ecfd471273e3135f9c8fc3b not-for-merge branch 'testcommit1429' of github.com:jantman/gitpython_issue_301 -751c556322c3b253f202bab845ae75c7e0050ce0 not-for-merge branch 'testcommit143' of github.com:jantman/gitpython_issue_301 -878beda79cdb770a7ac8b7a38b7bf64093fc1e9e not-for-merge branch 'testcommit1430' of github.com:jantman/gitpython_issue_301 -e09a0534302467f45dc40f681093da0400c4e16b not-for-merge branch 'testcommit1431' of github.com:jantman/gitpython_issue_301 -03920d2537bb0af033f2781470dfad9e4f928045 not-for-merge branch 'testcommit1432' of github.com:jantman/gitpython_issue_301 -a026589497c2339a4681945c3d44e6ff1f114ea5 not-for-merge branch 'testcommit1433' of github.com:jantman/gitpython_issue_301 -a60aa6a46260f5cc944d1883093a9dca42812efc not-for-merge branch 'testcommit1434' of github.com:jantman/gitpython_issue_301 -60c68b580842211bc7b52f2d3d732831192f2751 not-for-merge branch 'testcommit1435' of github.com:jantman/gitpython_issue_301 -8c27e485dcde72e394cacda328e2c6a1c911e690 not-for-merge branch 'testcommit1436' of github.com:jantman/gitpython_issue_301 -f92a2a3fd520f09279d55118929f8f0a60923212 not-for-merge branch 'testcommit1437' of github.com:jantman/gitpython_issue_301 -e08e75b4a0c5c312863815e0d2995791cbeb79bf not-for-merge branch 'testcommit1438' of github.com:jantman/gitpython_issue_301 -0826414258dc8f2aa7e53682de5a030b1abd1334 not-for-merge branch 'testcommit1439' of github.com:jantman/gitpython_issue_301 -1c8762cd27d2d9933f276fc9473cda2d1105260f not-for-merge branch 'testcommit144' of github.com:jantman/gitpython_issue_301 -0ce5cd7a105e6e49eb917a42e649f5a09ef2077b not-for-merge branch 'testcommit1440' of github.com:jantman/gitpython_issue_301 -c54682d73f0c05e27492efadc663aa0e3405d57a not-for-merge branch 'testcommit1441' of github.com:jantman/gitpython_issue_301 -f5fd49d1c115855c6d0b54827474721b94378244 not-for-merge branch 'testcommit1442' of github.com:jantman/gitpython_issue_301 -76644651115238b697c6194208657dcbf4143e27 not-for-merge branch 'testcommit1443' of github.com:jantman/gitpython_issue_301 -75461c2c2c6285824cdda80b457cda002f9086e4 not-for-merge branch 'testcommit1444' of github.com:jantman/gitpython_issue_301 -7378bc3ff8998f46c63768e8393800a59b7fc35e not-for-merge branch 'testcommit1445' of github.com:jantman/gitpython_issue_301 -b16795522622b92968da9e1928b7b80ee6546077 not-for-merge branch 'testcommit1446' of github.com:jantman/gitpython_issue_301 -0eca19cb4c6145b23862b99022a2aff2402dce60 not-for-merge branch 'testcommit1447' of github.com:jantman/gitpython_issue_301 -3ef5fffe847b4f25d99b4d5612148fa3ee898df9 not-for-merge branch 'testcommit1448' of github.com:jantman/gitpython_issue_301 -8a5ba8271985ebcdb570b83f962d7eb415a6d2a6 not-for-merge branch 'testcommit1449' of github.com:jantman/gitpython_issue_301 -e1cf0b981cd04172dd15bf52225670bf72fbad1c not-for-merge branch 'testcommit145' of github.com:jantman/gitpython_issue_301 -3e8f4489ab3d5346cb4a56f0d9adb31219b00ce4 not-for-merge branch 'testcommit1450' of github.com:jantman/gitpython_issue_301 -a1c3a54c9945bab499bcb358ce39667020b7c24e not-for-merge branch 'testcommit1451' of github.com:jantman/gitpython_issue_301 -cccae833e676a4e191e57d0cf3b242002980487f not-for-merge branch 'testcommit1452' of github.com:jantman/gitpython_issue_301 -e00c41829cb079ca75920b5b0a5aeaa468c9c4d1 not-for-merge branch 'testcommit1453' of github.com:jantman/gitpython_issue_301 -01cbf8b4aa117d517b27aca0ae6055fa8f7fc8c4 not-for-merge branch 'testcommit1454' of github.com:jantman/gitpython_issue_301 -bb625c024577d05ed5b80f7589b6fa0762a2ce9a not-for-merge branch 'testcommit1455' of github.com:jantman/gitpython_issue_301 -542b3f67aec5fda47d549ea4fac06f6dc2d81266 not-for-merge branch 'testcommit1456' of github.com:jantman/gitpython_issue_301 -1df81514238f60420352aeb0b8b1e8ef8940be20 not-for-merge branch 'testcommit1457' of github.com:jantman/gitpython_issue_301 -2c9b131ce00fd209511183e91226aecbe23871fc not-for-merge branch 'testcommit1458' of github.com:jantman/gitpython_issue_301 -9dea49e925f3d983d81187a11d6e43107e4e07f9 not-for-merge branch 'testcommit1459' of github.com:jantman/gitpython_issue_301 -76cc1ea240b1afd1b5b14ea6b17dd17b9ad26a8d not-for-merge branch 'testcommit146' of github.com:jantman/gitpython_issue_301 -17f0a8b1ef58bf1ed5a3597f9f630dc9cf96a535 not-for-merge branch 'testcommit1460' of github.com:jantman/gitpython_issue_301 -95cbd4446e3625a99fc3eb58dee75a16b7a125e8 not-for-merge branch 'testcommit1461' of github.com:jantman/gitpython_issue_301 -be47e3c01c730f1bab9e0f647bdcc410d51d7f72 not-for-merge branch 'testcommit1462' of github.com:jantman/gitpython_issue_301 -dcd84e12282b940ca5758dae08e145a77889840d not-for-merge branch 'testcommit1463' of github.com:jantman/gitpython_issue_301 -de0e91e8deff615cb9edbf86ab623f447122bd0a not-for-merge branch 'testcommit1464' of github.com:jantman/gitpython_issue_301 -f85d1552408cbc977595ce55538635a3d77ffbb7 not-for-merge branch 'testcommit1465' of github.com:jantman/gitpython_issue_301 -0914c4772336f58ab8d5d4f0400f791a2838ed73 not-for-merge branch 'testcommit1466' of github.com:jantman/gitpython_issue_301 -d76095c2b62a7fd7e145527caf25b9bdbf3be7e0 not-for-merge branch 'testcommit1467' of github.com:jantman/gitpython_issue_301 -b8fb4dd09d2a14318f13d6343b00d375da7ad7bf not-for-merge branch 'testcommit1468' of github.com:jantman/gitpython_issue_301 -24f1251b6024f4fa0e986f2b621d309d6d98a274 not-for-merge branch 'testcommit1469' of github.com:jantman/gitpython_issue_301 -eebb725b455af404490ae91868cd59dacad68dc0 not-for-merge branch 'testcommit147' of github.com:jantman/gitpython_issue_301 -5a25e5ad11bdf333d42c86ce2783e7dc6ef4e728 not-for-merge branch 'testcommit1470' of github.com:jantman/gitpython_issue_301 -14791de397b91f889fb65744134de2551a92ca9b not-for-merge branch 'testcommit1471' of github.com:jantman/gitpython_issue_301 -d460635551e17cdb12a33d4cf60e2aada303f3e3 not-for-merge branch 'testcommit1472' of github.com:jantman/gitpython_issue_301 -63d962f8b1e90cfca325781c3021b43c833c84a1 not-for-merge branch 'testcommit1473' of github.com:jantman/gitpython_issue_301 -613acc762aea65a529cc1048a5876e63f2ae3926 not-for-merge branch 'testcommit1474' of github.com:jantman/gitpython_issue_301 -3f9c5796d2cb4d87eded6a8b61e2c35de4a699e3 not-for-merge branch 'testcommit1475' of github.com:jantman/gitpython_issue_301 -d0ab75bb005fd791dcac9840bf77b6f76f6f2163 not-for-merge branch 'testcommit1476' of github.com:jantman/gitpython_issue_301 -732592f3672e860640097bc84f8dcfe4c70efeac not-for-merge branch 'testcommit1477' of github.com:jantman/gitpython_issue_301 -eb01539e9c6f912568c1f6ff53716482fcd3a0b6 not-for-merge branch 'testcommit1478' of github.com:jantman/gitpython_issue_301 -0ab8f6378bd855ee8ba37e6c71002dbeffbd0021 not-for-merge branch 'testcommit1479' of github.com:jantman/gitpython_issue_301 -f925cc2654717f3caa5b5c9bc73f599d1589aecd not-for-merge branch 'testcommit148' of github.com:jantman/gitpython_issue_301 -5c800024acbf87def2003412d8ebe1d3c02382a0 not-for-merge branch 'testcommit1480' of github.com:jantman/gitpython_issue_301 -1bc1af20805f0168b9d010cb831e6c1afcc33f1a not-for-merge branch 'testcommit1481' of github.com:jantman/gitpython_issue_301 -40671840a08d7d5c6d5ec7bfe34b918f70dae670 not-for-merge branch 'testcommit1482' of github.com:jantman/gitpython_issue_301 -b70d127503bea543a79fdf5f7b0ea79e7528a3ac not-for-merge branch 'testcommit1483' of github.com:jantman/gitpython_issue_301 -7d1d90e2d40119a9f28ddbedcf3bbffd240ca01d not-for-merge branch 'testcommit1484' of github.com:jantman/gitpython_issue_301 -87634e0107f8271c19bd007d92fed603cd4ce147 not-for-merge branch 'testcommit1485' of github.com:jantman/gitpython_issue_301 -65e5dfe7f018ec5fb86cee88dab50ab4e7cb577e not-for-merge branch 'testcommit1486' of github.com:jantman/gitpython_issue_301 -ce45cf98b6bc8ebabccf859dd0dba03038dd7771 not-for-merge branch 'testcommit1487' of github.com:jantman/gitpython_issue_301 -461d648f16935721c60f526a825e4f039e37cec5 not-for-merge branch 'testcommit1488' of github.com:jantman/gitpython_issue_301 -5da3162b12f51e37758c1540b968cd90a09760db not-for-merge branch 'testcommit1489' of github.com:jantman/gitpython_issue_301 -9f323a17eab0f79fb7fb9e8ddf914fa6dde29d55 not-for-merge branch 'testcommit149' of github.com:jantman/gitpython_issue_301 -1d6e759dbf5e131bff0d55dd5a22bc47511217a8 not-for-merge branch 'testcommit1490' of github.com:jantman/gitpython_issue_301 -f55393eec66f03f2afa40c66e9918be9126eab87 not-for-merge branch 'testcommit1491' of github.com:jantman/gitpython_issue_301 -fc79d0c7e33f23339ffd5407830f869037c9f27b not-for-merge branch 'testcommit1492' of github.com:jantman/gitpython_issue_301 -2545311dc5c38526ec76d748c02bdde229abf531 not-for-merge branch 'testcommit1493' of github.com:jantman/gitpython_issue_301 -b4b7d62982a0923a44bf7c516dd672916c8820cf not-for-merge branch 'testcommit1494' of github.com:jantman/gitpython_issue_301 -ebc603a2a72f48be3d837f7514fac0cfef7d2969 not-for-merge branch 'testcommit1495' of github.com:jantman/gitpython_issue_301 -103db9bb1f5141b0d7a244433db5717900fd3ae5 not-for-merge branch 'testcommit1496' of github.com:jantman/gitpython_issue_301 -9f30b022b6820651e5f3201abe7aeaf3822adb4a not-for-merge branch 'testcommit1497' of github.com:jantman/gitpython_issue_301 -8e9f16ac3b2e5fcfc4f7737bb6fe8b24e534c15b not-for-merge branch 'testcommit1498' of github.com:jantman/gitpython_issue_301 -9db4b13f9276608e091a62c0eab4521904a88264 not-for-merge branch 'testcommit1499' of github.com:jantman/gitpython_issue_301 -49bddd3914d645360e84e6498071af1afea3c5e0 not-for-merge branch 'testcommit15' of github.com:jantman/gitpython_issue_301 -bb5cc8f03023e98e11bd9c5cd49532f08e2c2765 not-for-merge branch 'testcommit150' of github.com:jantman/gitpython_issue_301 -916b544185250bf5ed8eb0c6aa4e394fdf221f4c not-for-merge branch 'testcommit1500' of github.com:jantman/gitpython_issue_301 -6427dd73a3d5c93590cf7228b61137b9fee087e3 not-for-merge branch 'testcommit1501' of github.com:jantman/gitpython_issue_301 -935f5ed8b757dab968cbbbf42a0f77bfcc0c63ac not-for-merge branch 'testcommit1502' of github.com:jantman/gitpython_issue_301 -68454496677a256483e43f56bc34904b9e8523bb not-for-merge branch 'testcommit1503' of github.com:jantman/gitpython_issue_301 -dca9cb4d53936a01cbe15a064090c9255335f1f6 not-for-merge branch 'testcommit1504' of github.com:jantman/gitpython_issue_301 -c28e4ad5ced66cff068583f322befdeca36e36ca not-for-merge branch 'testcommit1505' of github.com:jantman/gitpython_issue_301 -1939fa5c6c0f3655a1c9c20f470e3f5d7efd2abc not-for-merge branch 'testcommit1506' of github.com:jantman/gitpython_issue_301 -acb9956bb17e66cfced8560fb10e687d115ce2a9 not-for-merge branch 'testcommit1507' of github.com:jantman/gitpython_issue_301 -d5f12d9ec9f4abe2a53e6d9c915920f1ddb65d26 not-for-merge branch 'testcommit1508' of github.com:jantman/gitpython_issue_301 -68597980198108b9f3b1fd69d86cfec928c44a57 not-for-merge branch 'testcommit1509' of github.com:jantman/gitpython_issue_301 -19a11c92eaa8b14c29b40ab4652c88917e0d82ba not-for-merge branch 'testcommit151' of github.com:jantman/gitpython_issue_301 -2f62659eeab67d3cf6af26aab007cf4e98018243 not-for-merge branch 'testcommit1510' of github.com:jantman/gitpython_issue_301 -cea5714dcd1ed7b7ea509c468c7e6411dc90f97a not-for-merge branch 'testcommit1511' of github.com:jantman/gitpython_issue_301 -6b881fde50652360b80c40f9781aaf1cecc2540b not-for-merge branch 'testcommit1512' of github.com:jantman/gitpython_issue_301 -56c54736f9db449ec4328225936a09fe10dbd77b not-for-merge branch 'testcommit1513' of github.com:jantman/gitpython_issue_301 -4285825003148e431c42615256c60e3cc79718d6 not-for-merge branch 'testcommit1514' of github.com:jantman/gitpython_issue_301 -b1a1ddb347f091dd95a226cdbd1016d985f1a4c4 not-for-merge branch 'testcommit1515' of github.com:jantman/gitpython_issue_301 -6915361469eb8b12e37529baece150c9bdd5209e not-for-merge branch 'testcommit1516' of github.com:jantman/gitpython_issue_301 -bf47373aa74331906ca2061cd4dff3c849620012 not-for-merge branch 'testcommit1517' of github.com:jantman/gitpython_issue_301 -790e951a9cccef0efdb071b5908856c7234ccb70 not-for-merge branch 'testcommit1518' of github.com:jantman/gitpython_issue_301 -b344455d22cce84e1980c85ca10a252123a2afbf not-for-merge branch 'testcommit1519' of github.com:jantman/gitpython_issue_301 -d73de06aa85e2a038474180a916dc28078e58e7a not-for-merge branch 'testcommit152' of github.com:jantman/gitpython_issue_301 -0663488b790dff422b9e55d05c0582a37c261dcb not-for-merge branch 'testcommit1520' of github.com:jantman/gitpython_issue_301 -18310f9b218d3109be53c1d1207b4425e3750a7e not-for-merge branch 'testcommit1521' of github.com:jantman/gitpython_issue_301 -021ff01fc39c4004a71f541c74419bf34e13946b not-for-merge branch 'testcommit1522' of github.com:jantman/gitpython_issue_301 -fd3192409fa51d64bbdf763fa28d0312f991bd00 not-for-merge branch 'testcommit1523' of github.com:jantman/gitpython_issue_301 -ca72ddade4d6a425a3a1c7e23621efbe1e683fdd not-for-merge branch 'testcommit1524' of github.com:jantman/gitpython_issue_301 -d8f5efa762fac4bcc1a609771ad631994d47075d not-for-merge branch 'testcommit1525' of github.com:jantman/gitpython_issue_301 -014109d57ebc82db386efd991c3f0306c9e0c9fc not-for-merge branch 'testcommit1526' of github.com:jantman/gitpython_issue_301 -d2f88294086b349aee47e1c2583b793a7217c12a not-for-merge branch 'testcommit1527' of github.com:jantman/gitpython_issue_301 -1bdcf41766b58f948ac1234d7cada8cd84ea8353 not-for-merge branch 'testcommit1528' of github.com:jantman/gitpython_issue_301 -4a82d9c1726fd8d295caa79b0c11a7081930efc4 not-for-merge branch 'testcommit1529' of github.com:jantman/gitpython_issue_301 -88acb3a048bc7462245aee92ff416a7d1326c7e6 not-for-merge branch 'testcommit153' of github.com:jantman/gitpython_issue_301 -53740bd0f71e4437108692bbb5eab13e7080b9c0 not-for-merge branch 'testcommit1530' of github.com:jantman/gitpython_issue_301 -cc170ddeb8795b03437d8b6b66c8eb120681c6e9 not-for-merge branch 'testcommit1531' of github.com:jantman/gitpython_issue_301 -ca270b9cdd8dd830b7a1aefb11d497844c177fc5 not-for-merge branch 'testcommit1532' of github.com:jantman/gitpython_issue_301 -a9508a2bed561e9d42daab3fa8f9bdaef24f7c98 not-for-merge branch 'testcommit1533' of github.com:jantman/gitpython_issue_301 -7d983b395be594b4c176f8e1b877563d8d8b8a32 not-for-merge branch 'testcommit1534' of github.com:jantman/gitpython_issue_301 -2d99f61b35871a26a7757cd06b24cc346a7fbc08 not-for-merge branch 'testcommit1535' of github.com:jantman/gitpython_issue_301 -98c70845bf6ea06fffdfc8cb1e04421da56d32d2 not-for-merge branch 'testcommit1536' of github.com:jantman/gitpython_issue_301 -6b685cef946864ca4537597235b9cd7922339ccd not-for-merge branch 'testcommit1537' of github.com:jantman/gitpython_issue_301 -596f92d56373889516018d2a0d62d1e0be44f7ff not-for-merge branch 'testcommit1538' of github.com:jantman/gitpython_issue_301 -48f9b75503b05dca164438382b1dd39031765cf2 not-for-merge branch 'testcommit1539' of github.com:jantman/gitpython_issue_301 -cf37b7dfbfe7b9e622667d3e22673495e137e6cc not-for-merge branch 'testcommit154' of github.com:jantman/gitpython_issue_301 -a1c3c9ffac555af44a0228d5e18863910fc2d58c not-for-merge branch 'testcommit1540' of github.com:jantman/gitpython_issue_301 -36564e147643020d4f4ba11dfba9582d0f73924e not-for-merge branch 'testcommit1541' of github.com:jantman/gitpython_issue_301 -02d84edcda5eb865375a57ed72acc86856ecff7b not-for-merge branch 'testcommit1542' of github.com:jantman/gitpython_issue_301 -eb5afb4f57bb40f9f6ffeda49ced67a3637d8460 not-for-merge branch 'testcommit1543' of github.com:jantman/gitpython_issue_301 -d63b1c3408777ed3b450526e46cfd65e9bbd9885 not-for-merge branch 'testcommit1544' of github.com:jantman/gitpython_issue_301 -bdf59cb5b718020fb4d8f0643c02e49dd485cd83 not-for-merge branch 'testcommit1545' of github.com:jantman/gitpython_issue_301 -e1789dbb967e6a718127d6da3eedff1ead7ef2d4 not-for-merge branch 'testcommit1546' of github.com:jantman/gitpython_issue_301 -7567f6baa5c50b2be4f9153e545cb3ab9183b460 not-for-merge branch 'testcommit1547' of github.com:jantman/gitpython_issue_301 -214a180a48a370995aaf9b909400b193d0129d8e not-for-merge branch 'testcommit1548' of github.com:jantman/gitpython_issue_301 -62f291223bb9e119e744a02785fe98ef77024621 not-for-merge branch 'testcommit1549' of github.com:jantman/gitpython_issue_301 -9ab28926076e91c723d0fb83a776a1239bc3341b not-for-merge branch 'testcommit155' of github.com:jantman/gitpython_issue_301 -34a4f7c246333916355fbf1cc35946191514a709 not-for-merge branch 'testcommit1550' of github.com:jantman/gitpython_issue_301 -cc1d2ec0a2235a4269dd2181d7148c7718522f82 not-for-merge branch 'testcommit1551' of github.com:jantman/gitpython_issue_301 -879078ec94b13cf1463bdb166fabd4baf0cff50c not-for-merge branch 'testcommit1552' of github.com:jantman/gitpython_issue_301 -0e3c1c98de99f105f63eafa38b09d76d7382d866 not-for-merge branch 'testcommit1553' of github.com:jantman/gitpython_issue_301 -7a0c46baa01c7c4648da428e8b58c291443ad54f not-for-merge branch 'testcommit1554' of github.com:jantman/gitpython_issue_301 -ff574a86c2e347789d9694a47d60d2d8e169e2f3 not-for-merge branch 'testcommit1555' of github.com:jantman/gitpython_issue_301 -76f590259454f06b930627f23269c6c3d5ee2ce2 not-for-merge branch 'testcommit1556' of github.com:jantman/gitpython_issue_301 -da2157f6811e634235763006c5959802b461f894 not-for-merge branch 'testcommit1557' of github.com:jantman/gitpython_issue_301 -0dd252eefa8704c306b781f3455989dd1cedfba5 not-for-merge branch 'testcommit1558' of github.com:jantman/gitpython_issue_301 -7433facdfc8ab33451edd3ed0bf3f5e5edf3cf1d not-for-merge branch 'testcommit1559' of github.com:jantman/gitpython_issue_301 -2594991d8757a52b527e815ce778c2572980e45f not-for-merge branch 'testcommit156' of github.com:jantman/gitpython_issue_301 -e81bd7448a3719d1740bbbb3d1f544572bcad5d3 not-for-merge branch 'testcommit1560' of github.com:jantman/gitpython_issue_301 -5cec4c4c14601ade981b1cc60c448af28970d0f1 not-for-merge branch 'testcommit1561' of github.com:jantman/gitpython_issue_301 -80ab8d39387d8e6694d2ce9684d80588950f79b6 not-for-merge branch 'testcommit1562' of github.com:jantman/gitpython_issue_301 -cc137c2e47112206a8d6e750d46c24b3b637f697 not-for-merge branch 'testcommit1563' of github.com:jantman/gitpython_issue_301 -ac61d2bf6673b8e110f10cc9c42e90066fbcb72b not-for-merge branch 'testcommit1564' of github.com:jantman/gitpython_issue_301 -838dd9daaa19a4726b0a001815275f285a580729 not-for-merge branch 'testcommit1565' of github.com:jantman/gitpython_issue_301 -bf4c5329605a2fb6f4a539002bd3e3c2087eb9bd not-for-merge branch 'testcommit1566' of github.com:jantman/gitpython_issue_301 -cebf60864006a20775f97f5074fb66c1f1cb5f03 not-for-merge branch 'testcommit1567' of github.com:jantman/gitpython_issue_301 -e22f9e6d72f4f2661304f2a8c87278e6edf4653d not-for-merge branch 'testcommit1568' of github.com:jantman/gitpython_issue_301 -5005f1f512e4ae12bd37d8dae63d506f053fd324 not-for-merge branch 'testcommit1569' of github.com:jantman/gitpython_issue_301 -b680c1de7df5195d1ccadd4dd04c66b9c9819351 not-for-merge branch 'testcommit157' of github.com:jantman/gitpython_issue_301 -d4bbaaf733f9c1b00eacf3cff3edb1f48ed5eba7 not-for-merge branch 'testcommit1570' of github.com:jantman/gitpython_issue_301 -b349e6a719aaab13a9899ca5f42e1008833528b9 not-for-merge branch 'testcommit1571' of github.com:jantman/gitpython_issue_301 -c1c0e29d1c07babd468f2b83c9a613c1bad5ed9a not-for-merge branch 'testcommit1572' of github.com:jantman/gitpython_issue_301 -6438939856cf16434ac6e555e90d3d1d42736753 not-for-merge branch 'testcommit1573' of github.com:jantman/gitpython_issue_301 -2e3ee0fc3091fdc76d5a9d877320f5ff74ab8110 not-for-merge branch 'testcommit1574' of github.com:jantman/gitpython_issue_301 -095fc82fb187815ba6db7b4a6197c45d317d7a58 not-for-merge branch 'testcommit1575' of github.com:jantman/gitpython_issue_301 -c980eeb039f50261d13575f1d336dc2f8509a9d3 not-for-merge branch 'testcommit1576' of github.com:jantman/gitpython_issue_301 -4f5bb947cfa79513359adc2435dba82580ca8944 not-for-merge branch 'testcommit1577' of github.com:jantman/gitpython_issue_301 -3c6945e4b2bf816f851bd5bd2cf5b3b3cb4afc2d not-for-merge branch 'testcommit1578' of github.com:jantman/gitpython_issue_301 -9dcd46de494dce8bf9a2f8dbadc17ddd31c73fdb not-for-merge branch 'testcommit1579' of github.com:jantman/gitpython_issue_301 -e3bfbd933582135ae2a20a4a4fe0ec87437567b8 not-for-merge branch 'testcommit158' of github.com:jantman/gitpython_issue_301 -c40237fb172d3fadbc0404bcadade4cdb2ee0ade not-for-merge branch 'testcommit1580' of github.com:jantman/gitpython_issue_301 -2a76d75520c5bdc8cad08a08018b5cd233cce742 not-for-merge branch 'testcommit1581' of github.com:jantman/gitpython_issue_301 -2a61132e79a7c4239bd122f8fc0f32b4a7773485 not-for-merge branch 'testcommit1582' of github.com:jantman/gitpython_issue_301 -e77b2a82f89b603ba2ddc38a55ccd87b2e63ab9b not-for-merge branch 'testcommit1583' of github.com:jantman/gitpython_issue_301 -e01bf50eb6d5bc0c10227ea98f740a4b8e7c523c not-for-merge branch 'testcommit1584' of github.com:jantman/gitpython_issue_301 -cabeb6276d4bac20eb08bafe185dbd671573ea28 not-for-merge branch 'testcommit1585' of github.com:jantman/gitpython_issue_301 -b755f13ffae142ba63aa5de560380868b63c6bb7 not-for-merge branch 'testcommit1586' of github.com:jantman/gitpython_issue_301 -8e155be59b4fb4f05fa1fa32f810fc215e066854 not-for-merge branch 'testcommit1587' of github.com:jantman/gitpython_issue_301 -841d44b5a414b2748c146715d1b0fed83b7bc529 not-for-merge branch 'testcommit1588' of github.com:jantman/gitpython_issue_301 -d619cd2fd5550600f84bd3beabe0005f3374fb0f not-for-merge branch 'testcommit1589' of github.com:jantman/gitpython_issue_301 -20b3fe06318887494ffb740efcf61941543af21f not-for-merge branch 'testcommit159' of github.com:jantman/gitpython_issue_301 -3650c820a2041e335b85f2c95ed09c6f23675558 not-for-merge branch 'testcommit1590' of github.com:jantman/gitpython_issue_301 -bfca0510b8a065b30c99fec11a0627a2526c9fcb not-for-merge branch 'testcommit1591' of github.com:jantman/gitpython_issue_301 -3f7076e6b9abd042e32760c56a0c0fcc78900df7 not-for-merge branch 'testcommit1592' of github.com:jantman/gitpython_issue_301 -04e31557480f11ba3b36af5d94e4eecdb226fcf9 not-for-merge branch 'testcommit1593' of github.com:jantman/gitpython_issue_301 -5152dd72d4f4e591612efae7bd6d6d69b8bfcf3f not-for-merge branch 'testcommit1594' of github.com:jantman/gitpython_issue_301 -b043f271d52e6aeb8e8d8327f76577857d270463 not-for-merge branch 'testcommit1595' of github.com:jantman/gitpython_issue_301 -97091b0cc3afeda6f4ea5d2169a9248a84aa89f5 not-for-merge branch 'testcommit1596' of github.com:jantman/gitpython_issue_301 -20501c93afb9daaba1e8f722c6df9a7227b5699c not-for-merge branch 'testcommit1597' of github.com:jantman/gitpython_issue_301 -f1e3a584c4b5165500e45fd8b9d90dab1f88bc34 not-for-merge branch 'testcommit1598' of github.com:jantman/gitpython_issue_301 -8d6060504de76dae957f34a4f6062dbdfc1a0c9a not-for-merge branch 'testcommit1599' of github.com:jantman/gitpython_issue_301 -51715f00ed3bd74a9cabda3a5764f441bf7d7747 not-for-merge branch 'testcommit16' of github.com:jantman/gitpython_issue_301 -ee26d3bcca07a687ea24910a75e331e50fe425b2 not-for-merge branch 'testcommit160' of github.com:jantman/gitpython_issue_301 -88fcfc140a29254703197053ffd8ce8b97f18dd4 not-for-merge branch 'testcommit1600' of github.com:jantman/gitpython_issue_301 -54b7a9212fb4fac1501580b8a82fd082c16a48e1 not-for-merge branch 'testcommit1601' of github.com:jantman/gitpython_issue_301 -01a43d8556e4ec0ec721ecbca5bfb994202a7164 not-for-merge branch 'testcommit1602' of github.com:jantman/gitpython_issue_301 -e0ea60b45972cf017b3eb1f34dd5da22c58e25bd not-for-merge branch 'testcommit1603' of github.com:jantman/gitpython_issue_301 -5b97a3ad71633476b6777f2c15bf93b59bbee12e not-for-merge branch 'testcommit1604' of github.com:jantman/gitpython_issue_301 -03ae858875b823a13643111fe47767d28b38eb0d not-for-merge branch 'testcommit1605' of github.com:jantman/gitpython_issue_301 -dad5564bb110cbd7e71775ad60ec149d40428596 not-for-merge branch 'testcommit1606' of github.com:jantman/gitpython_issue_301 -fa6f7c64020cbe02820473275ec940574323438e not-for-merge branch 'testcommit1607' of github.com:jantman/gitpython_issue_301 -91445c284841653c355ab47751945fbd864cab0a not-for-merge branch 'testcommit1608' of github.com:jantman/gitpython_issue_301 -5eb23347b6ad4c69c29571597e7b59bcce10e57e not-for-merge branch 'testcommit1609' of github.com:jantman/gitpython_issue_301 -316a5ebc6bfc76183c96ab5b65203a220d7007b8 not-for-merge branch 'testcommit161' of github.com:jantman/gitpython_issue_301 -2eb84493ea0abdcb68bf0a3188fc4697c9518878 not-for-merge branch 'testcommit1610' of github.com:jantman/gitpython_issue_301 -e01be3719b69e9b6ef4b4a035b902a523ca61621 not-for-merge branch 'testcommit1611' of github.com:jantman/gitpython_issue_301 -4b78b1973832dbe7edb12f2cd385a675d6ea3b8a not-for-merge branch 'testcommit1612' of github.com:jantman/gitpython_issue_301 -80f56954b1a413e1f82bb8405f1c4284815b3349 not-for-merge branch 'testcommit1613' of github.com:jantman/gitpython_issue_301 -da59a486ef8b85065d78bc250beae98f6f69dc23 not-for-merge branch 'testcommit1614' of github.com:jantman/gitpython_issue_301 -4b647cf43a587444a0c8058eeb1c3e3ecfffaa55 not-for-merge branch 'testcommit1615' of github.com:jantman/gitpython_issue_301 -5351ff4f6a502843e7a46ef040ab34a066fb3e85 not-for-merge branch 'testcommit1616' of github.com:jantman/gitpython_issue_301 -124798481a921f72d9f7a068e677db141c152f8f not-for-merge branch 'testcommit1617' of github.com:jantman/gitpython_issue_301 -649069bdfed25075ded515c03b0780445f19163a not-for-merge branch 'testcommit1618' of github.com:jantman/gitpython_issue_301 -887d29af466e4ce5004544a27dabe1b2b381e9f2 not-for-merge branch 'testcommit1619' of github.com:jantman/gitpython_issue_301 -23da4ee4613d6622330659d38203a9d15d9b5c06 not-for-merge branch 'testcommit162' of github.com:jantman/gitpython_issue_301 -55f4439bb8d0cd5c2ce8281da842901fc130759e not-for-merge branch 'testcommit1620' of github.com:jantman/gitpython_issue_301 -425d1a75400476479592a4a35dbca5b5ee58dca3 not-for-merge branch 'testcommit1621' of github.com:jantman/gitpython_issue_301 -b46188fbab438f824fd5c2e2b7eb332169c61700 not-for-merge branch 'testcommit1622' of github.com:jantman/gitpython_issue_301 -450d8af7ca93c67e3945ded1fe376f9ba647c3d1 not-for-merge branch 'testcommit1623' of github.com:jantman/gitpython_issue_301 -7203ba2871ecb7ab98229eca11d893b12eda208c not-for-merge branch 'testcommit1624' of github.com:jantman/gitpython_issue_301 -04b0fce3774f057370451809f620df3300836c8b not-for-merge branch 'testcommit1625' of github.com:jantman/gitpython_issue_301 -995a81f7fa9bb7452433874d3c0bb612716fe29c not-for-merge branch 'testcommit1626' of github.com:jantman/gitpython_issue_301 -13c3b70455fae4f04bdddab4b01e6429de266a1e not-for-merge branch 'testcommit1627' of github.com:jantman/gitpython_issue_301 -c8062aacf300b5a5748833d2b0515ec53084fd36 not-for-merge branch 'testcommit1628' of github.com:jantman/gitpython_issue_301 -2d184ec6eeeb533346eb8ce95143b7d0f41540a8 not-for-merge branch 'testcommit1629' of github.com:jantman/gitpython_issue_301 -6c4c8d47c73597ec5f456ede3378266f73c21a41 not-for-merge branch 'testcommit163' of github.com:jantman/gitpython_issue_301 -7e7e5b0dd00ad3e8c700d0afd31764e70493e024 not-for-merge branch 'testcommit1630' of github.com:jantman/gitpython_issue_301 -7bced094d8258c88c3fcc2f84f29758d46de2532 not-for-merge branch 'testcommit1631' of github.com:jantman/gitpython_issue_301 -9aeb36d25cfacc04a2eb368d630c9c4dfd8dccef not-for-merge branch 'testcommit1632' of github.com:jantman/gitpython_issue_301 -21eea88981978b579c2cd4c0bcc7a094573fe566 not-for-merge branch 'testcommit1633' of github.com:jantman/gitpython_issue_301 -920c716ed0a9ec5fd710a81b7d095954a25738d0 not-for-merge branch 'testcommit1634' of github.com:jantman/gitpython_issue_301 -7be9490bc59a2ebbfe7b6748d8c83844b309230b not-for-merge branch 'testcommit1635' of github.com:jantman/gitpython_issue_301 -cc158b64449fed6974a27fca95dd0283185659ea not-for-merge branch 'testcommit1636' of github.com:jantman/gitpython_issue_301 -0e543cdec8f166a09567e53380902d1fd8a9f289 not-for-merge branch 'testcommit1637' of github.com:jantman/gitpython_issue_301 -a927e6e98f184025c53599c378a81c0068c474c5 not-for-merge branch 'testcommit1638' of github.com:jantman/gitpython_issue_301 -0c02e31c28f55f2947e62db6b6f611f0255b7f86 not-for-merge branch 'testcommit1639' of github.com:jantman/gitpython_issue_301 -8c2edc1a4054b99abffac89fb9cb42035e7d7f05 not-for-merge branch 'testcommit164' of github.com:jantman/gitpython_issue_301 -8257baeb721b1f5da232aaf1561d464b36318dab not-for-merge branch 'testcommit1640' of github.com:jantman/gitpython_issue_301 -dc930c97929121548cf376ba686245f9de115856 not-for-merge branch 'testcommit1641' of github.com:jantman/gitpython_issue_301 -0eef8aa1b6b51f6b570318d3e10030014b6c8f57 not-for-merge branch 'testcommit1642' of github.com:jantman/gitpython_issue_301 -91f581110fa9b277e558636a8d1c0b97dc021a5c not-for-merge branch 'testcommit1643' of github.com:jantman/gitpython_issue_301 -d31e836536e19f411f1d937764ef73d7d4248d8c not-for-merge branch 'testcommit1644' of github.com:jantman/gitpython_issue_301 -acd68ef6c0081ac7e87f59d39d44b3c31226f2be not-for-merge branch 'testcommit1645' of github.com:jantman/gitpython_issue_301 -e31707befd405a946a09a7f590c9d3c0ece10102 not-for-merge branch 'testcommit1646' of github.com:jantman/gitpython_issue_301 -b5552e4a07fbacb942d7701003e69328ccfda217 not-for-merge branch 'testcommit1647' of github.com:jantman/gitpython_issue_301 -8657ec4ec4a69cfa30bca004deeebe8a0763d519 not-for-merge branch 'testcommit1648' of github.com:jantman/gitpython_issue_301 -9f4b001ca5caeaba4d20bec146b860a03c963c59 not-for-merge branch 'testcommit1649' of github.com:jantman/gitpython_issue_301 -5df73ebf4ac671de1b2e312254d0724930e6ecf1 not-for-merge branch 'testcommit165' of github.com:jantman/gitpython_issue_301 -5dee05455b33cf1948a86026ac02cbf147fcd407 not-for-merge branch 'testcommit1650' of github.com:jantman/gitpython_issue_301 -4296f7bbb45fad1127b3f94ee404cd41de46efd8 not-for-merge branch 'testcommit1651' of github.com:jantman/gitpython_issue_301 -e53d9ebcc826e483cdd64d33d343dd392aa2477b not-for-merge branch 'testcommit1652' of github.com:jantman/gitpython_issue_301 -b4e4d76cb8775c8991f049d27d31d2f9ae08b3a2 not-for-merge branch 'testcommit1653' of github.com:jantman/gitpython_issue_301 -4916bc4ea8391f074f6f40c8ad454c320333c8ba not-for-merge branch 'testcommit1654' of github.com:jantman/gitpython_issue_301 -20dda5d66dfc5b3b4c9482c85f6999c5c94a5a96 not-for-merge branch 'testcommit1655' of github.com:jantman/gitpython_issue_301 -d305d8a81f8f97f038b2350224a09e14aa0f1269 not-for-merge branch 'testcommit1656' of github.com:jantman/gitpython_issue_301 -d1ad1a4be6e04374e70000586039451e12e8760e not-for-merge branch 'testcommit1657' of github.com:jantman/gitpython_issue_301 -8599221f04d327bd2e8fe75c8a5978478e5160eb not-for-merge branch 'testcommit1658' of github.com:jantman/gitpython_issue_301 -77e8af461dffc49a65ffafa2069d0637a03b6e2f not-for-merge branch 'testcommit1659' of github.com:jantman/gitpython_issue_301 -e674692376d94e4045297c6605528db48b3f5a65 not-for-merge branch 'testcommit166' of github.com:jantman/gitpython_issue_301 -4a05c50a5fd7964cd344c2bdcfae8b3f7e6c24d6 not-for-merge branch 'testcommit1660' of github.com:jantman/gitpython_issue_301 -db34830bba0949420349112b6576784f90c87d12 not-for-merge branch 'testcommit1661' of github.com:jantman/gitpython_issue_301 -fd3ca37cc312ac5264d527ea5b426ec741422875 not-for-merge branch 'testcommit1662' of github.com:jantman/gitpython_issue_301 -d7a21eac10911c6be058dfde1bdf2a22a3a1ffaf not-for-merge branch 'testcommit1663' of github.com:jantman/gitpython_issue_301 -9838f351ecb571d225a405936be39bf693777970 not-for-merge branch 'testcommit1664' of github.com:jantman/gitpython_issue_301 -67dbdb5df8bcdc1a2797e4d1d18a0cdcef4a87bd not-for-merge branch 'testcommit1665' of github.com:jantman/gitpython_issue_301 -71a0f3be409ab0ecdadb502c7b87f1e488512b2d not-for-merge branch 'testcommit1666' of github.com:jantman/gitpython_issue_301 -e5f3f4f29174b4309d98d3ae1e5b0bf42c86d015 not-for-merge branch 'testcommit1667' of github.com:jantman/gitpython_issue_301 -87b8199de60dc046068d6de09fbd4c5c3159c101 not-for-merge branch 'testcommit1668' of github.com:jantman/gitpython_issue_301 -e483d78d2b9a30d3924ec813578b998ff83daf4b not-for-merge branch 'testcommit1669' of github.com:jantman/gitpython_issue_301 -7b530a2823c61aafffaf33080815aa62d5f03597 not-for-merge branch 'testcommit167' of github.com:jantman/gitpython_issue_301 -cc5109681fceeddd2d238f984ef4b4313a3a5b82 not-for-merge branch 'testcommit1670' of github.com:jantman/gitpython_issue_301 -fafe083a4fffaf64d64f770aaf63b3afe8982f3a not-for-merge branch 'testcommit1671' of github.com:jantman/gitpython_issue_301 -78e289bd27b332f91850dac36c459a1acff62148 not-for-merge branch 'testcommit1672' of github.com:jantman/gitpython_issue_301 -43da7df955813959570889f303c90f40a3f8d1ad not-for-merge branch 'testcommit1673' of github.com:jantman/gitpython_issue_301 -2efda24923ed03c29d1783fd4bb1a28f097ec7cd not-for-merge branch 'testcommit1674' of github.com:jantman/gitpython_issue_301 -2928898d6acf23e430fa0b4690a0d1d8a49054cd not-for-merge branch 'testcommit1675' of github.com:jantman/gitpython_issue_301 -86a620b3e5e169505edf19729d24be503ba3aeda not-for-merge branch 'testcommit1676' of github.com:jantman/gitpython_issue_301 -a8f5fd4ab564d94a5e3d1b6546fdffebec20cbd3 not-for-merge branch 'testcommit1677' of github.com:jantman/gitpython_issue_301 -167ec7cfa902ed4f5398edd20b1eaea6f136d46c not-for-merge branch 'testcommit1678' of github.com:jantman/gitpython_issue_301 -f96260b7d51729e4183185721ae3630ea3dc9afa not-for-merge branch 'testcommit1679' of github.com:jantman/gitpython_issue_301 -9563d15f939b1355c75aa5df204688fbd9b02076 not-for-merge branch 'testcommit168' of github.com:jantman/gitpython_issue_301 -e3edd5b16f3a21d6273def1befe6a1564e1d92e9 not-for-merge branch 'testcommit1680' of github.com:jantman/gitpython_issue_301 -199d30ef89eacc69e4aa0b648f2186679db90201 not-for-merge branch 'testcommit1681' of github.com:jantman/gitpython_issue_301 -7b1b81bef1871fe78825ddb3fa5c3b738485b70b not-for-merge branch 'testcommit1682' of github.com:jantman/gitpython_issue_301 -9732e5be5208ffd53bb520bd023e026ada0d6f9b not-for-merge branch 'testcommit1683' of github.com:jantman/gitpython_issue_301 -64e37147f52bfda924a82fb6c49db7e29d635e5c not-for-merge branch 'testcommit1684' of github.com:jantman/gitpython_issue_301 -83408bc5fc9e795c3f9af1346a236117f58f6017 not-for-merge branch 'testcommit1685' of github.com:jantman/gitpython_issue_301 -d6585114ff811dfbf84777fc450cef310c1f2115 not-for-merge branch 'testcommit1686' of github.com:jantman/gitpython_issue_301 -2c25e972cdd7ffb23a8e8f2035cf3064b451f428 not-for-merge branch 'testcommit1687' of github.com:jantman/gitpython_issue_301 -6be3986e954f06904e42b4112e50c5c94129341c not-for-merge branch 'testcommit1688' of github.com:jantman/gitpython_issue_301 -19cafa3a9a32a15ce962258c20a5aa2f54073421 not-for-merge branch 'testcommit1689' of github.com:jantman/gitpython_issue_301 -abc5208751255a5438a70622e997cd8d8dc8ab8d not-for-merge branch 'testcommit169' of github.com:jantman/gitpython_issue_301 -d2bd80b0b245b5811ea0023b49eb313aa623cc73 not-for-merge branch 'testcommit1690' of github.com:jantman/gitpython_issue_301 -ba5af95bc0bb17dda9153fe3260851f1ba32eef6 not-for-merge branch 'testcommit1691' of github.com:jantman/gitpython_issue_301 -8a5d13ade36d3d13b88ce5a002759eb93d15a530 not-for-merge branch 'testcommit1692' of github.com:jantman/gitpython_issue_301 -3d25478ffe9e5405c55fd3cbfc50f95828416b40 not-for-merge branch 'testcommit1693' of github.com:jantman/gitpython_issue_301 -4f98d634c8ce258af6621b592f8e919714f58591 not-for-merge branch 'testcommit1694' of github.com:jantman/gitpython_issue_301 -80f0c5bbaf098a5a3216eaa5ea3dfa5b0975c67e not-for-merge branch 'testcommit1695' of github.com:jantman/gitpython_issue_301 -497abd3a219636dcce25f7bba1c326f8a5f2a817 not-for-merge branch 'testcommit1696' of github.com:jantman/gitpython_issue_301 -35f0c66a0aa7d66ed49b41a61e587865f377207a not-for-merge branch 'testcommit1697' of github.com:jantman/gitpython_issue_301 -0593838a1e001f484289284579dbb583dc1f629b not-for-merge branch 'testcommit1698' of github.com:jantman/gitpython_issue_301 -75a249673929f0a7b0ef701c2fb78eb22a62f6b7 not-for-merge branch 'testcommit1699' of github.com:jantman/gitpython_issue_301 -f1858aa74ffd6304a8a9d5ce313b203ef6b567c7 not-for-merge branch 'testcommit17' of github.com:jantman/gitpython_issue_301 -eed67e47ef9689d322749c252619e701a8ef6aef not-for-merge branch 'testcommit170' of github.com:jantman/gitpython_issue_301 -13a042f4ec30842a7ad03adb088a90d1ee11a707 not-for-merge branch 'testcommit1700' of github.com:jantman/gitpython_issue_301 -785e72b36b79599f87d1d53e96a1b395c863591d not-for-merge branch 'testcommit1701' of github.com:jantman/gitpython_issue_301 -36e095b5c2d0c8c7b26ed6b3bec5310c09e80038 not-for-merge branch 'testcommit1702' of github.com:jantman/gitpython_issue_301 -39624f00997409b930c3f9b7263ace28a24ec46b not-for-merge branch 'testcommit1703' of github.com:jantman/gitpython_issue_301 -018ffcd8350ab2fd09ad76b754e751153cb0e779 not-for-merge branch 'testcommit1704' of github.com:jantman/gitpython_issue_301 -0c44b134b6ae525bdc43357db545dc2aefd3e829 not-for-merge branch 'testcommit1705' of github.com:jantman/gitpython_issue_301 -3af2130b75088d66af06d7f10fbde7923b4f8c72 not-for-merge branch 'testcommit1706' of github.com:jantman/gitpython_issue_301 -84aa63d7e6565dcbd8056be5c2e7a0ac02660c39 not-for-merge branch 'testcommit1707' of github.com:jantman/gitpython_issue_301 -cf8229f1e6615a6287d35b89f22630150f4ed4ea not-for-merge branch 'testcommit1708' of github.com:jantman/gitpython_issue_301 -435aa1496b33fe020ee2c5ad0e1c82e2c001884c not-for-merge branch 'testcommit1709' of github.com:jantman/gitpython_issue_301 -4bfe3f5cdafe04f558cc75f5c9417b5cd204d664 not-for-merge branch 'testcommit171' of github.com:jantman/gitpython_issue_301 -3cec3aceb6d0d0d071f37c3323a0ea66bc251692 not-for-merge branch 'testcommit1710' of github.com:jantman/gitpython_issue_301 -c419267e954d5b5a8e78366c1f9464d10f9ef42a not-for-merge branch 'testcommit1711' of github.com:jantman/gitpython_issue_301 -2e50eaca740459a048a4e0d03b8068a14a4fd8c9 not-for-merge branch 'testcommit1712' of github.com:jantman/gitpython_issue_301 -05a6360631b25f87169b130488b400046d7e8b72 not-for-merge branch 'testcommit1713' of github.com:jantman/gitpython_issue_301 -d2bef685fd8557ed0c4b6da09be20ab8e5f7c506 not-for-merge branch 'testcommit1714' of github.com:jantman/gitpython_issue_301 -42fc3b6baf3c5359dd3d83cf3b7522756b84f9f2 not-for-merge branch 'testcommit1715' of github.com:jantman/gitpython_issue_301 -977b3f428bc87e3858d32ef0530a9d108fa8ee58 not-for-merge branch 'testcommit1716' of github.com:jantman/gitpython_issue_301 -0c74b5fcef818fc4bc2d79dfbc7a77ff010c669d not-for-merge branch 'testcommit1717' of github.com:jantman/gitpython_issue_301 -81eba4c0c063b9eeeba37019ad99c288d18a1a6e not-for-merge branch 'testcommit1718' of github.com:jantman/gitpython_issue_301 -e115ae2d8cf613bc2f7cdd65849573b9ef655fe7 not-for-merge branch 'testcommit1719' of github.com:jantman/gitpython_issue_301 -feebfa9c558a72f0e6fbf07a410649459394c945 not-for-merge branch 'testcommit172' of github.com:jantman/gitpython_issue_301 -b798a31ddf914cf4e8dce58ea81424085bc828cf not-for-merge branch 'testcommit1720' of github.com:jantman/gitpython_issue_301 -a2f21ad95388b9bdc83f5b036e49ad3a59faf662 not-for-merge branch 'testcommit1721' of github.com:jantman/gitpython_issue_301 -ee3593539a074f157377029ebd457f5ce79c7787 not-for-merge branch 'testcommit1722' of github.com:jantman/gitpython_issue_301 -77c8db37ec1fe95371da2d28b2136ae1e056068d not-for-merge branch 'testcommit1723' of github.com:jantman/gitpython_issue_301 -2a17f54ea840907e3c989964c0d1b25d46700129 not-for-merge branch 'testcommit1724' of github.com:jantman/gitpython_issue_301 -145a72f2ad67e860ab709ac1f0089fcfebd10d7f not-for-merge branch 'testcommit1725' of github.com:jantman/gitpython_issue_301 -1758871b844f23a516b8fd6b7963af1b54c59c7c not-for-merge branch 'testcommit1726' of github.com:jantman/gitpython_issue_301 -249884bba6ffea38e15d79655c078c91edcebbc5 not-for-merge branch 'testcommit1727' of github.com:jantman/gitpython_issue_301 -0c071d79997485324fe04bd53122cc30e5040854 not-for-merge branch 'testcommit1728' of github.com:jantman/gitpython_issue_301 -19ac8fe2266de524d7ae713351589683fc8fce87 not-for-merge branch 'testcommit1729' of github.com:jantman/gitpython_issue_301 -6d25e5ebdf0caea6ffa519101a290681050c9321 not-for-merge branch 'testcommit173' of github.com:jantman/gitpython_issue_301 -a1bc2f8dcefa485f577dcd8ffe8dbf6a364b34aa not-for-merge branch 'testcommit1730' of github.com:jantman/gitpython_issue_301 -5d23f3d3df92019b97ddf9417a993aef2b1d6e6c not-for-merge branch 'testcommit1731' of github.com:jantman/gitpython_issue_301 -d4d4141efc28302ce75b75c624a6e9cadb645735 not-for-merge branch 'testcommit1732' of github.com:jantman/gitpython_issue_301 -e4c216314c7d06fb77eec4653c6083358cb80b42 not-for-merge branch 'testcommit1733' of github.com:jantman/gitpython_issue_301 -56f2f7abe4be1fa5400bd64324f9aa1a4a1356fc not-for-merge branch 'testcommit1734' of github.com:jantman/gitpython_issue_301 -8a133817b56f84bca0cb5b08e2e7f18d5fae2dea not-for-merge branch 'testcommit1735' of github.com:jantman/gitpython_issue_301 -cbd17f293f7737d27471de54073d774462ba0315 not-for-merge branch 'testcommit1736' of github.com:jantman/gitpython_issue_301 -da693e68d6a432f0278f86cdcea9e183a0aa6c9a not-for-merge branch 'testcommit1737' of github.com:jantman/gitpython_issue_301 -3b853c103bb5c93f694101404809a1110e777e76 not-for-merge branch 'testcommit1738' of github.com:jantman/gitpython_issue_301 -afa244ffaf28e8c1dfd0d9429057ba1179a9d87a not-for-merge branch 'testcommit1739' of github.com:jantman/gitpython_issue_301 -b8db4b8a962025e7928600519fee10d8f31ca989 not-for-merge branch 'testcommit174' of github.com:jantman/gitpython_issue_301 -94ab1e714c30005895b1f5071d087036f9438fbf not-for-merge branch 'testcommit1740' of github.com:jantman/gitpython_issue_301 -7584b60ce88fceff1934fe33d56d99b4e707b6eb not-for-merge branch 'testcommit1741' of github.com:jantman/gitpython_issue_301 -3c04882b298516750a420e3b86b8cead611de556 not-for-merge branch 'testcommit1742' of github.com:jantman/gitpython_issue_301 -ff0ff2b4f3fc4a56e2039f5bcc1d4b48fa4694d4 not-for-merge branch 'testcommit1743' of github.com:jantman/gitpython_issue_301 -c944606356fa772421d63a3831872fa80759e1ea not-for-merge branch 'testcommit1744' of github.com:jantman/gitpython_issue_301 -c037dfc37769bf098ccc35ea17f13da4b091d467 not-for-merge branch 'testcommit1745' of github.com:jantman/gitpython_issue_301 -f8243d6265cb83171b849430b08e6b9e0aaca2a1 not-for-merge branch 'testcommit1746' of github.com:jantman/gitpython_issue_301 -4b8de2e6244f8e075fe9835cb0691620c2f55e40 not-for-merge branch 'testcommit1747' of github.com:jantman/gitpython_issue_301 -c44f79a7389a42f179b1ca35e67ec73b66793c85 not-for-merge branch 'testcommit1748' of github.com:jantman/gitpython_issue_301 -ca07212a570425fb258d6c48e11c406f41e9768f not-for-merge branch 'testcommit1749' of github.com:jantman/gitpython_issue_301 -a389ebf629081e793e11aa2badbbcd4c9e4c9b6b not-for-merge branch 'testcommit175' of github.com:jantman/gitpython_issue_301 -7036826e32b137bf3f8c03c4869094e4fc8cacdf not-for-merge branch 'testcommit1750' of github.com:jantman/gitpython_issue_301 -b79ee8f3977272c3e7fa65a885c2869ea698c6be not-for-merge branch 'testcommit1751' of github.com:jantman/gitpython_issue_301 -656cfcd61b9176741c238d42d0ff67b736213eab not-for-merge branch 'testcommit1752' of github.com:jantman/gitpython_issue_301 -09ab47f528fdafd11674e6feccfea970759e95d1 not-for-merge branch 'testcommit1753' of github.com:jantman/gitpython_issue_301 -12791a995ca7bbec5894bc4587218a5574375bcd not-for-merge branch 'testcommit1754' of github.com:jantman/gitpython_issue_301 -505dfb948521eb672d89964910099355ac05f352 not-for-merge branch 'testcommit1755' of github.com:jantman/gitpython_issue_301 -18d988ce7f21409100bf908af9a65ceec88fbbbc not-for-merge branch 'testcommit1756' of github.com:jantman/gitpython_issue_301 -464f7eb01a67f0f4b1a5527c2f6cb9fb0b902850 not-for-merge branch 'testcommit1757' of github.com:jantman/gitpython_issue_301 -7777f0b27b5b4b616af3a25800ca039ce5f64735 not-for-merge branch 'testcommit1758' of github.com:jantman/gitpython_issue_301 -2cf2e156711c8447d38135ab891ef7ab99f8909f not-for-merge branch 'testcommit1759' of github.com:jantman/gitpython_issue_301 -680f52a755dd762cbfb8ce63690325f1018dd2eb not-for-merge branch 'testcommit176' of github.com:jantman/gitpython_issue_301 -a2d8e82487ee3c81d162b62c86077d783b5f2f0a not-for-merge branch 'testcommit1760' of github.com:jantman/gitpython_issue_301 -e4d2ab7181728e5cd3ebbec114aeac3c75cc1fc5 not-for-merge branch 'testcommit1761' of github.com:jantman/gitpython_issue_301 -d70382a7fe3fa38c3b601dba1b5739d56e8dd3ee not-for-merge branch 'testcommit1762' of github.com:jantman/gitpython_issue_301 -5457883dcff74f97364ac2d24473153c7b54ef4f not-for-merge branch 'testcommit1763' of github.com:jantman/gitpython_issue_301 -c05964492e4f7123a57e8311c7785ba1612c916c not-for-merge branch 'testcommit1764' of github.com:jantman/gitpython_issue_301 -8bdc0ddcf11ffde4de2b07c8d8e37b7a38832f4e not-for-merge branch 'testcommit1765' of github.com:jantman/gitpython_issue_301 -16ba021ab2b9b12d3f50f3c84be0cd64e7a3493b not-for-merge branch 'testcommit1766' of github.com:jantman/gitpython_issue_301 -4c7982e81a053dd4fd4a6eef04ea254cafa4d1cc not-for-merge branch 'testcommit1767' of github.com:jantman/gitpython_issue_301 -c1e49bf2a2cca4c225672e9f1312fb2dca985eac not-for-merge branch 'testcommit1768' of github.com:jantman/gitpython_issue_301 -ed8ce226415a90a7b5b26471a2a60abd3c2a777c not-for-merge branch 'testcommit1769' of github.com:jantman/gitpython_issue_301 -7e1689d99dcd2dcf9b61167ca76eed38efb97727 not-for-merge branch 'testcommit177' of github.com:jantman/gitpython_issue_301 -7c51dacd4c870dbf7d01a6a6ccfc38f99a021648 not-for-merge branch 'testcommit1770' of github.com:jantman/gitpython_issue_301 -038b7879a64314c75c926714f582c64701a720a7 not-for-merge branch 'testcommit1771' of github.com:jantman/gitpython_issue_301 -8e1c3c9a0c6324043e1df49bb6fafcaefaa250c3 not-for-merge branch 'testcommit1772' of github.com:jantman/gitpython_issue_301 -e4682c8a580ae53f7205e37c9a7c61ef56e6e343 not-for-merge branch 'testcommit1773' of github.com:jantman/gitpython_issue_301 -1ef48c413c83915ef69df200749fee774589f37b not-for-merge branch 'testcommit1774' of github.com:jantman/gitpython_issue_301 -c85c2b03553a893b79c43dc8ce02b517274b7641 not-for-merge branch 'testcommit1775' of github.com:jantman/gitpython_issue_301 -1ebf97ca05f0786164baf5df37da6092e25bec7c not-for-merge branch 'testcommit1776' of github.com:jantman/gitpython_issue_301 -1b73e428e2d807f7aab05ade12b578363ac95f54 not-for-merge branch 'testcommit1777' of github.com:jantman/gitpython_issue_301 -8094124c88dc71694e345cd4bcdab17ea77685b0 not-for-merge branch 'testcommit1778' of github.com:jantman/gitpython_issue_301 -5aac80e94f8f6d7d3dcbfafdf53684ba780a472a not-for-merge branch 'testcommit1779' of github.com:jantman/gitpython_issue_301 -337a2c620365d535a8806cb8a97611498f546393 not-for-merge branch 'testcommit178' of github.com:jantman/gitpython_issue_301 -88bb4d19ac7c33ec8cf790afe1969adb2fa8fa20 not-for-merge branch 'testcommit1780' of github.com:jantman/gitpython_issue_301 -4fa805cb667c45017a2793a1dbfc42c0da826f38 not-for-merge branch 'testcommit1781' of github.com:jantman/gitpython_issue_301 -b0eea3a2bf5fb9b2255dc2573bc5566900081b83 not-for-merge branch 'testcommit1782' of github.com:jantman/gitpython_issue_301 -e7184bdd13fec2dbe1da840df93afa9763187816 not-for-merge branch 'testcommit1783' of github.com:jantman/gitpython_issue_301 -915764496d5848526ad6f5e7f3ef927475fe28b0 not-for-merge branch 'testcommit1784' of github.com:jantman/gitpython_issue_301 -f896d8c33441a1330fadd8cd6b0976e51f7eeb92 not-for-merge branch 'testcommit1785' of github.com:jantman/gitpython_issue_301 -7d0265049fda8818295ed80306966f813f718adf not-for-merge branch 'testcommit1786' of github.com:jantman/gitpython_issue_301 -b36a62c3c7ab58bc5f1477053811fc0eff603334 not-for-merge branch 'testcommit1787' of github.com:jantman/gitpython_issue_301 -383dc5e6dbfb51e0f2496c7459ef6008c1224800 not-for-merge branch 'testcommit1788' of github.com:jantman/gitpython_issue_301 -2dcb853f11cb77c1e92693e79196a18cbb967427 not-for-merge branch 'testcommit1789' of github.com:jantman/gitpython_issue_301 -34bfa9918224ab28801b902dc941aeb19a6b6a6e not-for-merge branch 'testcommit179' of github.com:jantman/gitpython_issue_301 -ee89f56a65bc2359f9f19811e82ad65a5bbcc5a6 not-for-merge branch 'testcommit1790' of github.com:jantman/gitpython_issue_301 -59211de8b846411a4189ac423edb8c3111428581 not-for-merge branch 'testcommit1791' of github.com:jantman/gitpython_issue_301 -86eb74e96cc9024c42801b656bd9dbb97ba396e2 not-for-merge branch 'testcommit1792' of github.com:jantman/gitpython_issue_301 -9f4ce593ecf8e2c8715121e608fd0f6e3ac720e3 not-for-merge branch 'testcommit1793' of github.com:jantman/gitpython_issue_301 -d85543e5da4962a757ffb05d1e8c272f36610fa6 not-for-merge branch 'testcommit1794' of github.com:jantman/gitpython_issue_301 -858c367cac3a2f802b7d43ef8ed1d39ed7c92bac not-for-merge branch 'testcommit1795' of github.com:jantman/gitpython_issue_301 -48b880232a584b1638f9b4f387253cefac5e0b19 not-for-merge branch 'testcommit1796' of github.com:jantman/gitpython_issue_301 -c19ddaaa777f015917700db5e4a0b473ffa23228 not-for-merge branch 'testcommit1797' of github.com:jantman/gitpython_issue_301 -183c27cea9542f9eaf00652690f714118b82e497 not-for-merge branch 'testcommit1798' of github.com:jantman/gitpython_issue_301 -d43c27e4a2f796107cc820ec64e88bc548a4908c not-for-merge branch 'testcommit1799' of github.com:jantman/gitpython_issue_301 -266da296b8352ac64d930db071b4708fa16a8e61 not-for-merge branch 'testcommit18' of github.com:jantman/gitpython_issue_301 -a39f025c550653974adc776389cfe2872902f2d8 not-for-merge branch 'testcommit180' of github.com:jantman/gitpython_issue_301 -7ea3d120db4efdf3d9f1a90187596b7382dbe44a not-for-merge branch 'testcommit1800' of github.com:jantman/gitpython_issue_301 -a6e9f6ee8b3b861e78d798fd021295107942ec00 not-for-merge branch 'testcommit1801' of github.com:jantman/gitpython_issue_301 -804061be93cabcb9e16e146e5c5272e548647ab9 not-for-merge branch 'testcommit1802' of github.com:jantman/gitpython_issue_301 -57c3909407e1de7cddeec1831d3fc524ce2dbca0 not-for-merge branch 'testcommit1803' of github.com:jantman/gitpython_issue_301 -e4a9777ec6ea2c932781d8000b6be72873602eb9 not-for-merge branch 'testcommit1804' of github.com:jantman/gitpython_issue_301 -85c2a6c6077cc988838634ca47de8f2e30ee09a4 not-for-merge branch 'testcommit1805' of github.com:jantman/gitpython_issue_301 -8213cefa3cc56a1471c9458598e1330ac54a0491 not-for-merge branch 'testcommit1806' of github.com:jantman/gitpython_issue_301 -42969669be9bb1793a5d5bff0dbe7ba950975032 not-for-merge branch 'testcommit1807' of github.com:jantman/gitpython_issue_301 -3a97c3b910d8fc187e4ebee831eedbeeadd48cf7 not-for-merge branch 'testcommit1808' of github.com:jantman/gitpython_issue_301 -485ae429b26eccae13376af0c437f3b82b85bc1d not-for-merge branch 'testcommit1809' of github.com:jantman/gitpython_issue_301 -b218cd50685d0d340099d6b2421ce68afed3668e not-for-merge branch 'testcommit181' of github.com:jantman/gitpython_issue_301 -f1de28491a8fdcc1d8a623f848d7544c17832d28 not-for-merge branch 'testcommit1810' of github.com:jantman/gitpython_issue_301 -3e335a23bf3b183a42e48f68f27499e8f89d483f not-for-merge branch 'testcommit1811' of github.com:jantman/gitpython_issue_301 -1aef53acb7aada8cd66a7e2bd5470af3be70848b not-for-merge branch 'testcommit1812' of github.com:jantman/gitpython_issue_301 -f6ef449a7fd6585f1ff7102e9efd2cd0eb8fa444 not-for-merge branch 'testcommit1813' of github.com:jantman/gitpython_issue_301 -4664a12e68eebb4b989e18bd8fb3f9311ad31fdd not-for-merge branch 'testcommit1814' of github.com:jantman/gitpython_issue_301 -e866a69b8f1b41f714e2bce9960f0b928ffd1ed7 not-for-merge branch 'testcommit1815' of github.com:jantman/gitpython_issue_301 -b616d4e319ffc189378adb8df71262fb1cfc38f2 not-for-merge branch 'testcommit1816' of github.com:jantman/gitpython_issue_301 -f2d6c738bf0496e8b7cd716281af360dbe8cd0cc not-for-merge branch 'testcommit1817' of github.com:jantman/gitpython_issue_301 -c620aa5797ea5a95193caa66081835b9e0cc863d not-for-merge branch 'testcommit1818' of github.com:jantman/gitpython_issue_301 -b9c8b579e7a65d8121e76680174cfe49332d6cc1 not-for-merge branch 'testcommit1819' of github.com:jantman/gitpython_issue_301 -3fc529676fbe17fe0ee98d61ea51e458fd2f4981 not-for-merge branch 'testcommit182' of github.com:jantman/gitpython_issue_301 -35f3f4ee8532e4102de68601447dbed817ec1146 not-for-merge branch 'testcommit1820' of github.com:jantman/gitpython_issue_301 -569528e9b8ea723b17f47a38eb9a7a7fdfda8ca0 not-for-merge branch 'testcommit1821' of github.com:jantman/gitpython_issue_301 -b18ddc6f8b13e69a0b494332a7b39f5a185f11b3 not-for-merge branch 'testcommit1822' of github.com:jantman/gitpython_issue_301 -d8447475015455a3c4354d319172b671775805fc not-for-merge branch 'testcommit1823' of github.com:jantman/gitpython_issue_301 -7444b7324d6db09eabbb55f427d1cfe93139fe10 not-for-merge branch 'testcommit1824' of github.com:jantman/gitpython_issue_301 -f20141cf3ed002349e1370a7afd46ca897f403ac not-for-merge branch 'testcommit1825' of github.com:jantman/gitpython_issue_301 -978999a7dbf7df440674145fca017b4831e0699a not-for-merge branch 'testcommit1826' of github.com:jantman/gitpython_issue_301 -2cae161128dce81a9e32af949c280feae2d246b0 not-for-merge branch 'testcommit1827' of github.com:jantman/gitpython_issue_301 -ee7d8c2c04378b50a4aeca245190a2844982aa68 not-for-merge branch 'testcommit1828' of github.com:jantman/gitpython_issue_301 -8867ff6c7957ca8ebd7288165e2fb3862b642360 not-for-merge branch 'testcommit1829' of github.com:jantman/gitpython_issue_301 -780c632a91974acff1834312edcfd1bda1c536d2 not-for-merge branch 'testcommit183' of github.com:jantman/gitpython_issue_301 -a1cc2f742303af886466dd7dab4a099a99fc32a1 not-for-merge branch 'testcommit1830' of github.com:jantman/gitpython_issue_301 -2c56bd79ff43c088498ec3d5fb8fc3db30bde07f not-for-merge branch 'testcommit1831' of github.com:jantman/gitpython_issue_301 -5da9f9bd17a36c89ad4c3f94cdc8e884e1a03ded not-for-merge branch 'testcommit1832' of github.com:jantman/gitpython_issue_301 -ae4093938cbbf54b7e74d0e6055f53cc864e7536 not-for-merge branch 'testcommit1833' of github.com:jantman/gitpython_issue_301 -84808c336d3a13c0ff29df712e84ed49fca3bce4 not-for-merge branch 'testcommit1834' of github.com:jantman/gitpython_issue_301 -ce6e47d20bac6d1a2a2715fa9d648dc3a3f2506c not-for-merge branch 'testcommit1835' of github.com:jantman/gitpython_issue_301 -ad31adcf5dc691286ec0c20c002cea7ecc12d4b2 not-for-merge branch 'testcommit1836' of github.com:jantman/gitpython_issue_301 -41f8aac0b083e61972565bd2bbf7891fb73abe7e not-for-merge branch 'testcommit1837' of github.com:jantman/gitpython_issue_301 -870e0b08349ef131d8d264da5fff15eb83e914e4 not-for-merge branch 'testcommit1838' of github.com:jantman/gitpython_issue_301 -a5fd1d028453c37372b322d1d608c28e81f5c420 not-for-merge branch 'testcommit1839' of github.com:jantman/gitpython_issue_301 -20658778ac5ed481db9ea80e95f1d8752c188ac6 not-for-merge branch 'testcommit184' of github.com:jantman/gitpython_issue_301 -2e3026f5b46660df7b73227fb92a5adfb1817810 not-for-merge branch 'testcommit1840' of github.com:jantman/gitpython_issue_301 -5578d0f801419114409867b90ed19226949ea205 not-for-merge branch 'testcommit1841' of github.com:jantman/gitpython_issue_301 -6d43300cf93c03325a7bb4a2a461a50e02f9df6e not-for-merge branch 'testcommit1842' of github.com:jantman/gitpython_issue_301 -1f4a10a6d9cca6d103dc73bb2526a167ba74623f not-for-merge branch 'testcommit1843' of github.com:jantman/gitpython_issue_301 -b1e489f194ed7e33631c50599397f5f98ca905fb not-for-merge branch 'testcommit1844' of github.com:jantman/gitpython_issue_301 -74b22f3fa9499603b35265bd769d11e145202a2c not-for-merge branch 'testcommit1845' of github.com:jantman/gitpython_issue_301 -73a7a34b2e4a325f66f90e30a962e119b84bb016 not-for-merge branch 'testcommit1846' of github.com:jantman/gitpython_issue_301 -953e9ecead0933d084edc3cbb94a398658a96a86 not-for-merge branch 'testcommit1847' of github.com:jantman/gitpython_issue_301 -f9d67de25b470ea080e9e0d755bf5b761c3b41dc not-for-merge branch 'testcommit1848' of github.com:jantman/gitpython_issue_301 -5bcc71603f97f457e270eaa7c00d693055b3494c not-for-merge branch 'testcommit1849' of github.com:jantman/gitpython_issue_301 -b5d08f76dca1410680a9d8720f429d780d192ae2 not-for-merge branch 'testcommit185' of github.com:jantman/gitpython_issue_301 -05faabf11011feabe8874a39ac3adc1aa0a82f6c not-for-merge branch 'testcommit1850' of github.com:jantman/gitpython_issue_301 -a4a2375e3d4200e86c2c0971708a757c43a10f3b not-for-merge branch 'testcommit1851' of github.com:jantman/gitpython_issue_301 -9e4d1e8aa308c65fcaeb0865de2c3e7c13ae0f25 not-for-merge branch 'testcommit1852' of github.com:jantman/gitpython_issue_301 -83dc080d2d8c303f8635c2b539a7325ccc4e1d41 not-for-merge branch 'testcommit1853' of github.com:jantman/gitpython_issue_301 -41fcbbc29b8d5cf072d73850d36c7aacaef7ace7 not-for-merge branch 'testcommit1854' of github.com:jantman/gitpython_issue_301 -867bd112b5b3e04883ff78593f9a69f2132157cc not-for-merge branch 'testcommit1855' of github.com:jantman/gitpython_issue_301 -6fe4083b87ebfb975179b6254fe183efa6becdd6 not-for-merge branch 'testcommit1856' of github.com:jantman/gitpython_issue_301 -2892280e7769749260729581c525bcdf1501e040 not-for-merge branch 'testcommit1857' of github.com:jantman/gitpython_issue_301 -8f66c277db601e992c1bf9527a7c075aa4b9298c not-for-merge branch 'testcommit1858' of github.com:jantman/gitpython_issue_301 -3a9b11e5f46efe9cfdf5583d57b7b1d7158aabbc not-for-merge branch 'testcommit1859' of github.com:jantman/gitpython_issue_301 -df67e67a8177edc60ccb88748e8fdc13c6e892b3 not-for-merge branch 'testcommit186' of github.com:jantman/gitpython_issue_301 -4237e91283d333ae37f1d3c631e938e0346d638c not-for-merge branch 'testcommit1860' of github.com:jantman/gitpython_issue_301 -2f679ff04fd269e77154d64fce7217f1a9a4cd17 not-for-merge branch 'testcommit1861' of github.com:jantman/gitpython_issue_301 -600b88357afb29e0daa124ac0e4506a7e3aecdba not-for-merge branch 'testcommit1862' of github.com:jantman/gitpython_issue_301 -72016792bd5142a9c334a4a0e9aebc794d2ee64f not-for-merge branch 'testcommit1863' of github.com:jantman/gitpython_issue_301 -a9530a54d7ab0354039f37c274d3647151769e73 not-for-merge branch 'testcommit1864' of github.com:jantman/gitpython_issue_301 -604fbdda57b3380c01923bbd0308ac232d57ea2c not-for-merge branch 'testcommit1865' of github.com:jantman/gitpython_issue_301 -3e09ac8fae95622e48c2efca65fcfdd25be8f546 not-for-merge branch 'testcommit1866' of github.com:jantman/gitpython_issue_301 -ed47de3fd958bab5ebd4ab9c1793e38938a08f2d not-for-merge branch 'testcommit1867' of github.com:jantman/gitpython_issue_301 -d00e57ab856270aac66ea834b2548318d64683f5 not-for-merge branch 'testcommit1868' of github.com:jantman/gitpython_issue_301 -5f2cdfa6e75b414b9c96c55828a33b4f764a4045 not-for-merge branch 'testcommit1869' of github.com:jantman/gitpython_issue_301 -db7ad70804c3ccfb62289030984d092d3e65ba55 not-for-merge branch 'testcommit187' of github.com:jantman/gitpython_issue_301 -fb8fcf39db46332b5fc18ddbb859722a8a100425 not-for-merge branch 'testcommit1870' of github.com:jantman/gitpython_issue_301 -c6669a89c2c72fa9c27eb6f9209da561f9f7e16a not-for-merge branch 'testcommit1871' of github.com:jantman/gitpython_issue_301 -d85ada1987bec8d624269c6533104405b7a57b4f not-for-merge branch 'testcommit1872' of github.com:jantman/gitpython_issue_301 -2f26942eed17b5411afffa3bba43508dc8e0a4ea not-for-merge branch 'testcommit1873' of github.com:jantman/gitpython_issue_301 -3ec3023cc52d12796c687782ff4bfa44311a47b6 not-for-merge branch 'testcommit1874' of github.com:jantman/gitpython_issue_301 -1de9b4ea31ba7b943cf894184c0a1dee2c588591 not-for-merge branch 'testcommit1875' of github.com:jantman/gitpython_issue_301 -036d33e27bb548bb00361672726bc58eaafb8fac not-for-merge branch 'testcommit1876' of github.com:jantman/gitpython_issue_301 -d77378ba3adfe4757f10177cd5c0820d39895a76 not-for-merge branch 'testcommit1877' of github.com:jantman/gitpython_issue_301 -d2fa4853ab409e3de448388a61acc9229cfd2e25 not-for-merge branch 'testcommit1878' of github.com:jantman/gitpython_issue_301 -3a37ac453453a13acd6129281444a66410eee34a not-for-merge branch 'testcommit1879' of github.com:jantman/gitpython_issue_301 -213750fda1ca114664ecaae18907db9acebf365f not-for-merge branch 'testcommit188' of github.com:jantman/gitpython_issue_301 -fa5023261ea9bedc302cbb767ece2fdb0707dd94 not-for-merge branch 'testcommit1880' of github.com:jantman/gitpython_issue_301 -ee3848220ae1dc40a55397f145718e030e157250 not-for-merge branch 'testcommit1881' of github.com:jantman/gitpython_issue_301 -9879f03bdb8ccaf2a3bd1e578dfbcfd75f3fd0d4 not-for-merge branch 'testcommit1882' of github.com:jantman/gitpython_issue_301 -6fc002dc221dbd2e4f87e3e5ef7fc4e31d49c05d not-for-merge branch 'testcommit1883' of github.com:jantman/gitpython_issue_301 -1be1b0042d5548ce9a8e0b478a84969dfb3b761f not-for-merge branch 'testcommit1884' of github.com:jantman/gitpython_issue_301 -f7edee3809ecbcfc40ae8cff9a749df059716c8b not-for-merge branch 'testcommit1885' of github.com:jantman/gitpython_issue_301 -989b0dfe78b9203a6b6c748f2496eabdcd0ff332 not-for-merge branch 'testcommit1886' of github.com:jantman/gitpython_issue_301 -64627515852dc163a3e994d686254ef79a9d3e73 not-for-merge branch 'testcommit1887' of github.com:jantman/gitpython_issue_301 -218bf90069181de27a07341e16382fc770ebe103 not-for-merge branch 'testcommit1888' of github.com:jantman/gitpython_issue_301 -4467172bc7f066f1ec71182d682e183cfaad3640 not-for-merge branch 'testcommit1889' of github.com:jantman/gitpython_issue_301 -9ee056b8b66566801c1ad03408992000225890f0 not-for-merge branch 'testcommit189' of github.com:jantman/gitpython_issue_301 -6e9107a5c3f636eba3e8b6384883091124112bf5 not-for-merge branch 'testcommit1890' of github.com:jantman/gitpython_issue_301 -90417ade803f6fc49f189971e3dc248f86dc0717 not-for-merge branch 'testcommit1891' of github.com:jantman/gitpython_issue_301 -b421ed8dae75691ef86e8b39121abd2d6c0c1cec not-for-merge branch 'testcommit1892' of github.com:jantman/gitpython_issue_301 -7189f28c476083dc9cfd4ed46679b3555130f61c not-for-merge branch 'testcommit1893' of github.com:jantman/gitpython_issue_301 -8af7998de46c2a951d19243a67f2e4480c30da48 not-for-merge branch 'testcommit1894' of github.com:jantman/gitpython_issue_301 -6e1be6146a3fab7dc49435db2f3074c1a14a64d1 not-for-merge branch 'testcommit1895' of github.com:jantman/gitpython_issue_301 -25c44412f5cd70c96a1f10f04fbf69d2b6bdacb5 not-for-merge branch 'testcommit1896' of github.com:jantman/gitpython_issue_301 -dc88de9f5c26c37a1ad38be1826bffd8f0a01baf not-for-merge branch 'testcommit1897' of github.com:jantman/gitpython_issue_301 -3b6cb9a9224dc96917e180eb6e504618b8a1891b not-for-merge branch 'testcommit1898' of github.com:jantman/gitpython_issue_301 -5dc35df7933809e15c5f0ba1c780ee7b63b1564d not-for-merge branch 'testcommit1899' of github.com:jantman/gitpython_issue_301 -220aaf1a08f0ac3d63f4eb5e2b30567d7853943b not-for-merge branch 'testcommit19' of github.com:jantman/gitpython_issue_301 -f53cd8b70e08bd30b27355af50f4ed2c8dffa59c not-for-merge branch 'testcommit190' of github.com:jantman/gitpython_issue_301 -c511c9b48f5ed3f912060780cdb488ca17c712a1 not-for-merge branch 'testcommit1900' of github.com:jantman/gitpython_issue_301 -923bbdac8a194c569d4e9bb18e57f00114fecb97 not-for-merge branch 'testcommit1901' of github.com:jantman/gitpython_issue_301 -93f3861e25d152b0d0ed10f1d712f213b3b10509 not-for-merge branch 'testcommit1902' of github.com:jantman/gitpython_issue_301 -88fb82bdf8c750c3676e27bfccaa6e18c0138f51 not-for-merge branch 'testcommit1903' of github.com:jantman/gitpython_issue_301 -adafd95ca199b546ff57ba93483394bfec3708ed not-for-merge branch 'testcommit1904' of github.com:jantman/gitpython_issue_301 -1686018fcac0aa8b054d38ba29a5459655886f12 not-for-merge branch 'testcommit1905' of github.com:jantman/gitpython_issue_301 -0d6a17df7f7e162e5d35939eaf73e2b0d8fd12f2 not-for-merge branch 'testcommit1906' of github.com:jantman/gitpython_issue_301 -291d931b731bc7499c5baa31d8e2edbb5693270e not-for-merge branch 'testcommit1907' of github.com:jantman/gitpython_issue_301 -83d5c871907a96c1e175097534e0063f328d3b5e not-for-merge branch 'testcommit1908' of github.com:jantman/gitpython_issue_301 -6fbe2161e2a1bf892d1a12f94460b1dc61f66300 not-for-merge branch 'testcommit1909' of github.com:jantman/gitpython_issue_301 -d473b288492a2a19b5690bcc031c48d66fb54634 not-for-merge branch 'testcommit191' of github.com:jantman/gitpython_issue_301 -5ae9cf3b1ffc833b6478da483c33ef8f689687cc not-for-merge branch 'testcommit1910' of github.com:jantman/gitpython_issue_301 -f5b58a81dc338df3dbc6e3e91276c39a40220591 not-for-merge branch 'testcommit1911' of github.com:jantman/gitpython_issue_301 -ddd81ed64b1ee518057547b746a6397da5354f9e not-for-merge branch 'testcommit1912' of github.com:jantman/gitpython_issue_301 -8496fd9edac6b1884a67b83ec325680079fdd988 not-for-merge branch 'testcommit1913' of github.com:jantman/gitpython_issue_301 -1cecb1472a8bef0642319a1075b933e8370dbd73 not-for-merge branch 'testcommit1914' of github.com:jantman/gitpython_issue_301 -18789d62daf6a555d7a9114c302cf70431fb0a26 not-for-merge branch 'testcommit1915' of github.com:jantman/gitpython_issue_301 -680e5f74e22c22b424b57a1a7bec05fcd65f75fc not-for-merge branch 'testcommit1916' of github.com:jantman/gitpython_issue_301 -52982dd3c3b301aa492dc7d071e5bea6f02eb394 not-for-merge branch 'testcommit1917' of github.com:jantman/gitpython_issue_301 -7dabf5246dbd92d700f18c8f654ff8514f74bfe2 not-for-merge branch 'testcommit1918' of github.com:jantman/gitpython_issue_301 -32b3929c977aa6669df40942889662d1e4a0bb53 not-for-merge branch 'testcommit1919' of github.com:jantman/gitpython_issue_301 -0d2e9dccf2db1a5ebccc446d45bb92560e0671d6 not-for-merge branch 'testcommit192' of github.com:jantman/gitpython_issue_301 -693abc79496c543c6ecfcfd34f03b18aa8d20714 not-for-merge branch 'testcommit1920' of github.com:jantman/gitpython_issue_301 -de6586a141c3ba21015d382d09485271bca82e6a not-for-merge branch 'testcommit1921' of github.com:jantman/gitpython_issue_301 -98325a18d3d783b687bfd5a79425d772b014b8ae not-for-merge branch 'testcommit1922' of github.com:jantman/gitpython_issue_301 -f81c14aa29872bb0bf0e4e75d5aa5965f497d19c not-for-merge branch 'testcommit1923' of github.com:jantman/gitpython_issue_301 -99eac10f66303a3380ef70b80a5e39c5b52c0d4d not-for-merge branch 'testcommit1924' of github.com:jantman/gitpython_issue_301 -fae3b74591bacd155c3ef0ea977f44bcf5dad2f0 not-for-merge branch 'testcommit1925' of github.com:jantman/gitpython_issue_301 -89b9c61f8d0e5378c70e52b1d73e57d4c091f1a6 not-for-merge branch 'testcommit1926' of github.com:jantman/gitpython_issue_301 -3197ac4831d5bfb8691454608d3cafc9c7e3c93b not-for-merge branch 'testcommit1927' of github.com:jantman/gitpython_issue_301 -891b92af0a2aea94bbe606774db75387e45b3e95 not-for-merge branch 'testcommit1928' of github.com:jantman/gitpython_issue_301 -cc20c764b80e997f8170da4626a2f79b83fcf93e not-for-merge branch 'testcommit1929' of github.com:jantman/gitpython_issue_301 -5508cd0f6b52a7f6a0685b4d0e380462b0443fcb not-for-merge branch 'testcommit193' of github.com:jantman/gitpython_issue_301 -328fd7c99087f84cf66f9f9bd66b2ccee60c1a3a not-for-merge branch 'testcommit1930' of github.com:jantman/gitpython_issue_301 -5919f2872aa4523a2cc24e9f0cfeb36c0bb9f7c5 not-for-merge branch 'testcommit1931' of github.com:jantman/gitpython_issue_301 -6c98df3f6e1928f3d5c2e760aec27781e15e3350 not-for-merge branch 'testcommit1932' of github.com:jantman/gitpython_issue_301 -b0da6afecaa7a46dddae3faefe45b531a2ffdbaf not-for-merge branch 'testcommit1933' of github.com:jantman/gitpython_issue_301 -3b488f746b8103b0538258026c98a3b1888dcbbb not-for-merge branch 'testcommit1934' of github.com:jantman/gitpython_issue_301 -a47fc611318333eebdd408ae00302605018b09de not-for-merge branch 'testcommit1935' of github.com:jantman/gitpython_issue_301 -c26d1c29b49a47c7931ba74c0aa432e662e70cec not-for-merge branch 'testcommit1936' of github.com:jantman/gitpython_issue_301 -85defd47144200dc9e46952f919ba238ce43669b not-for-merge branch 'testcommit1937' of github.com:jantman/gitpython_issue_301 -b6ca1685ff3f478a3b1b586b5a33be9bafa792f2 not-for-merge branch 'testcommit1938' of github.com:jantman/gitpython_issue_301 -b3be66c05a8a441c5f12f2efff179cb540562b48 not-for-merge branch 'testcommit1939' of github.com:jantman/gitpython_issue_301 -543b87fc78bdcc49d5671c0a62c1d5105ec77d38 not-for-merge branch 'testcommit194' of github.com:jantman/gitpython_issue_301 -0b959dd020661964c8218ea5de5599ab984220c2 not-for-merge branch 'testcommit1940' of github.com:jantman/gitpython_issue_301 -1faf86aa17e7ad5ff7b23eb4c16e38ef8f2d0690 not-for-merge branch 'testcommit1941' of github.com:jantman/gitpython_issue_301 -0b939dff38392cb14848fb290eee9c95edcde0b9 not-for-merge branch 'testcommit1942' of github.com:jantman/gitpython_issue_301 -a47e40fdd6dc56d7425b06ecea583c165c9c13b7 not-for-merge branch 'testcommit1943' of github.com:jantman/gitpython_issue_301 -4144729c03059784bb0343ac92979430bcae6f4b not-for-merge branch 'testcommit1944' of github.com:jantman/gitpython_issue_301 -ec9b84d239228b0ef8c0782939be5848305b81b0 not-for-merge branch 'testcommit1945' of github.com:jantman/gitpython_issue_301 -cfd09461d0cb2383e3ea5139abcf28048f25adde not-for-merge branch 'testcommit1946' of github.com:jantman/gitpython_issue_301 -dfcb171ff0a332a4953e0caf9cabd7250fe0947d not-for-merge branch 'testcommit1947' of github.com:jantman/gitpython_issue_301 -775652f64cd08ecfb952f9b6b4604203680cd317 not-for-merge branch 'testcommit1948' of github.com:jantman/gitpython_issue_301 -0893b760f7b0f2e922d5de7b877dec077dd36640 not-for-merge branch 'testcommit1949' of github.com:jantman/gitpython_issue_301 -e449f2f4177140c119824f37a309295dab59ac87 not-for-merge branch 'testcommit195' of github.com:jantman/gitpython_issue_301 -7c0431100e7acf7c5b285588047ef4a50bc6659b not-for-merge branch 'testcommit1950' of github.com:jantman/gitpython_issue_301 -a52aca2a831b48e1e2472a14c84020a9724c9c96 not-for-merge branch 'testcommit1951' of github.com:jantman/gitpython_issue_301 -de608cb3dc7f2aa87fec7e153a906f9f17c80837 not-for-merge branch 'testcommit1952' of github.com:jantman/gitpython_issue_301 -39d39098213b01a587269f07e84d72d569580ed4 not-for-merge branch 'testcommit1953' of github.com:jantman/gitpython_issue_301 -f33606a986117e407a83a3f2388bc2995318479c not-for-merge branch 'testcommit1954' of github.com:jantman/gitpython_issue_301 -31acc304ea0b1bbe70ab271e8b42f98fbd6f789f not-for-merge branch 'testcommit1955' of github.com:jantman/gitpython_issue_301 -b16345a7c541e725ad419fdd34477df2e4b241a8 not-for-merge branch 'testcommit1956' of github.com:jantman/gitpython_issue_301 -d48ea5bec69ae2589b9253e18006faa12be873c5 not-for-merge branch 'testcommit1957' of github.com:jantman/gitpython_issue_301 -129904abc54b8d0da7c01159554374110361e4e8 not-for-merge branch 'testcommit1958' of github.com:jantman/gitpython_issue_301 -10550b108d3ab4dab11cd2e51f4230fa84e5698d not-for-merge branch 'testcommit1959' of github.com:jantman/gitpython_issue_301 -5475601c8cb6dd661aa8d254fd0a22ccd5edb40f not-for-merge branch 'testcommit196' of github.com:jantman/gitpython_issue_301 -c1a58ace9e56f85b446dceeecaeb29bee9d30d29 not-for-merge branch 'testcommit1960' of github.com:jantman/gitpython_issue_301 -66f80513f5896feb64665beade166ed2b3281ebc not-for-merge branch 'testcommit1961' of github.com:jantman/gitpython_issue_301 -83847018e335a2eda1ef51ab4949ede9af7a7886 not-for-merge branch 'testcommit1962' of github.com:jantman/gitpython_issue_301 -4dfe5c4510811ba700c0b724cbd53908b53a2985 not-for-merge branch 'testcommit1963' of github.com:jantman/gitpython_issue_301 -40679050e70f119f74ac830bac5f01b4340ca85a not-for-merge branch 'testcommit1964' of github.com:jantman/gitpython_issue_301 -1e84d496c6cf7df2397be13dc5e38cd0bd3bedcf not-for-merge branch 'testcommit1965' of github.com:jantman/gitpython_issue_301 -1acee900bad3858c67ee0eda6626a391686f6ea6 not-for-merge branch 'testcommit1966' of github.com:jantman/gitpython_issue_301 -6691c51726a3d2487363058b9057160cf40af444 not-for-merge branch 'testcommit1967' of github.com:jantman/gitpython_issue_301 -c5238c7ed8bedb15b0ced4b23f230f9ad818c268 not-for-merge branch 'testcommit1968' of github.com:jantman/gitpython_issue_301 -1652913e59f1d6f423ac39b819d3abffb5d37249 not-for-merge branch 'testcommit1969' of github.com:jantman/gitpython_issue_301 -a9e49032e626534ac14460069a6b58abaaf25293 not-for-merge branch 'testcommit197' of github.com:jantman/gitpython_issue_301 -9867d8239fd528bd43e315b5970fdafcb98750ca not-for-merge branch 'testcommit1970' of github.com:jantman/gitpython_issue_301 -15eda2a4ba455c371dc1c51157063103e2373dc0 not-for-merge branch 'testcommit1971' of github.com:jantman/gitpython_issue_301 -f8a8bbe11fe5df102ac2e93630dffffd31940013 not-for-merge branch 'testcommit1972' of github.com:jantman/gitpython_issue_301 -2a924bb97e1b63527547c140004db7605f644968 not-for-merge branch 'testcommit1973' of github.com:jantman/gitpython_issue_301 -c705750c3d09dc94205febf54d182745cd783013 not-for-merge branch 'testcommit1974' of github.com:jantman/gitpython_issue_301 -555f0827b9b57ad9adc209a83b86e31e86034a17 not-for-merge branch 'testcommit1975' of github.com:jantman/gitpython_issue_301 -10c92be4fae1e1253912123067a777642a90c1ae not-for-merge branch 'testcommit1976' of github.com:jantman/gitpython_issue_301 -b1763448fb927bb34a0572c4a5c31a57d5a05f48 not-for-merge branch 'testcommit1977' of github.com:jantman/gitpython_issue_301 -660eec3d26c484156395d01a823e13690d738687 not-for-merge branch 'testcommit1978' of github.com:jantman/gitpython_issue_301 -6cfc5683435ceb67f5b80009b3bc2f1efada8ad1 not-for-merge branch 'testcommit1979' of github.com:jantman/gitpython_issue_301 -f2e92247fa80eebb41458c1729568729c8246684 not-for-merge branch 'testcommit198' of github.com:jantman/gitpython_issue_301 -d81047445092cb18629b46ebd6f0d11e4c2a810a not-for-merge branch 'testcommit1980' of github.com:jantman/gitpython_issue_301 -81428dbdac46c41db9153552d0fdca2a72daf506 not-for-merge branch 'testcommit1981' of github.com:jantman/gitpython_issue_301 -00633b02e703aeabc17f826e3b0a139301b16f49 not-for-merge branch 'testcommit1982' of github.com:jantman/gitpython_issue_301 -1a8b203a5fbdee45b0532385db534bf382ff5287 not-for-merge branch 'testcommit1983' of github.com:jantman/gitpython_issue_301 -c2f91552a53fef9dcee85ae4c144b55ee09d3e30 not-for-merge branch 'testcommit1984' of github.com:jantman/gitpython_issue_301 -26e54f7b2f3e319803b167fe5b2ff1f06212570a not-for-merge branch 'testcommit1985' of github.com:jantman/gitpython_issue_301 -dca7165ba32510d1755a13f959b0c80a9e6156fd not-for-merge branch 'testcommit1986' of github.com:jantman/gitpython_issue_301 -04636ea5e77bb0f9e0502270de92db4ef1b2644d not-for-merge branch 'testcommit1987' of github.com:jantman/gitpython_issue_301 -8a1bca9afe0daccf0c8d9ae4ecde4de7728ecacb not-for-merge branch 'testcommit1988' of github.com:jantman/gitpython_issue_301 -b397da7b0e20364f935187d25d03edd6cd91fb95 not-for-merge branch 'testcommit1989' of github.com:jantman/gitpython_issue_301 -537940b94f85ede631a4b275d8ae06e4b60f1f66 not-for-merge branch 'testcommit199' of github.com:jantman/gitpython_issue_301 -287c8fcc4e113a5097a0875f9a666ee84601c714 not-for-merge branch 'testcommit1990' of github.com:jantman/gitpython_issue_301 -4c98df3ad54ced7973008202e2a206ae135613e4 not-for-merge branch 'testcommit1991' of github.com:jantman/gitpython_issue_301 -994b9d6324942b9f1be8489b000ef98a2bb1dc85 not-for-merge branch 'testcommit1992' of github.com:jantman/gitpython_issue_301 -851e9b1db49ada6869d26168807743d79de03cc7 not-for-merge branch 'testcommit1993' of github.com:jantman/gitpython_issue_301 -43d9b77aead53682556b27c548db7c71218e6a10 not-for-merge branch 'testcommit1994' of github.com:jantman/gitpython_issue_301 -eac06dcf8daba6afd1f1b6ee158eb90ff4f4c762 not-for-merge branch 'testcommit1995' of github.com:jantman/gitpython_issue_301 -7245b63f5fde58669fa7b4bc02461a1f7be3feed not-for-merge branch 'testcommit1996' of github.com:jantman/gitpython_issue_301 -29cffc2d30ea896637d0306eaccc56e8b303f526 not-for-merge branch 'testcommit1997' of github.com:jantman/gitpython_issue_301 -b0ed236be933d51a608c4c487eed68d5f8df4756 not-for-merge branch 'testcommit1998' of github.com:jantman/gitpython_issue_301 -bfcb133bfdbc820feabdd8c9a493242bc8934e3f not-for-merge branch 'testcommit1999' of github.com:jantman/gitpython_issue_301 -53108067022b48267310024c8afa284e2bed535f not-for-merge branch 'testcommit2' of github.com:jantman/gitpython_issue_301 -4b64c0b181f4c8c29e3a5f869edfd181f9d5b27a not-for-merge branch 'testcommit20' of github.com:jantman/gitpython_issue_301 -aa2986db9b2c7d9625556b2b0647a76d34c0a82e not-for-merge branch 'testcommit200' of github.com:jantman/gitpython_issue_301 -1c55ca130bb9555c157feb4d0836092d6cffebee not-for-merge branch 'testcommit2000' of github.com:jantman/gitpython_issue_301 -08438c7b848733d61f6b4c76ffaa4e4e0d4e4872 not-for-merge branch 'testcommit2001' of github.com:jantman/gitpython_issue_301 -bc5263a39707949786feae2a8ed5434ba7b68146 not-for-merge branch 'testcommit2002' of github.com:jantman/gitpython_issue_301 -492a5a913e1cae4c4f5269168460476ee26a193c not-for-merge branch 'testcommit2003' of github.com:jantman/gitpython_issue_301 -b7632ca9c40075621ce033d7798272a43574d416 not-for-merge branch 'testcommit2004' of github.com:jantman/gitpython_issue_301 -1aae06b0501be9cc4ac2c541f4724a7c94179861 not-for-merge branch 'testcommit2005' of github.com:jantman/gitpython_issue_301 -d0b97833e908f3c828e65ab4bf4a3fa7c4446247 not-for-merge branch 'testcommit2006' of github.com:jantman/gitpython_issue_301 -3ff125ac7cbc2b5b3e853b35d4a2db36cfbc66e5 not-for-merge branch 'testcommit2007' of github.com:jantman/gitpython_issue_301 -661468dfda27473b56b5dc1b299a36b6c9ccf671 not-for-merge branch 'testcommit2008' of github.com:jantman/gitpython_issue_301 -2f999211bb3ee8d9294f0bafa3b02f0c67ba0502 not-for-merge branch 'testcommit2009' of github.com:jantman/gitpython_issue_301 -5d21180545220579d8cbc58b9c2f11fa8d147b04 not-for-merge branch 'testcommit201' of github.com:jantman/gitpython_issue_301 -90a098eea5f7c746b1d93aa4dc36152a929b09e4 not-for-merge branch 'testcommit2010' of github.com:jantman/gitpython_issue_301 -7eedc4b237f8d0c7fd32fc3c01faf2bc748ce9f7 not-for-merge branch 'testcommit2011' of github.com:jantman/gitpython_issue_301 -801b225c1ad95f33a0156bc6faf0505fbd319075 not-for-merge branch 'testcommit2012' of github.com:jantman/gitpython_issue_301 -4a53b3bdaa88e2409b4673d6f03670e761136f72 not-for-merge branch 'testcommit2013' of github.com:jantman/gitpython_issue_301 -78539a2aae2b6426c49200b9a8cd6c20c72a69b8 not-for-merge branch 'testcommit2014' of github.com:jantman/gitpython_issue_301 -91dcb65eaa98e1ea77dc7377cb864c2daad1ac23 not-for-merge branch 'testcommit2015' of github.com:jantman/gitpython_issue_301 -73283187d1581ff23cd25946f004125a33e5d194 not-for-merge branch 'testcommit2016' of github.com:jantman/gitpython_issue_301 -ae460348819e2861b619955521abf7c9f7d52352 not-for-merge branch 'testcommit2017' of github.com:jantman/gitpython_issue_301 -e398a9f792345d8f9cda643732bc1f795cf9580c not-for-merge branch 'testcommit2018' of github.com:jantman/gitpython_issue_301 -4ac63bd46912976f467293034404b13b465d0956 not-for-merge branch 'testcommit2019' of github.com:jantman/gitpython_issue_301 -70c0fd8e14566df1adecd0d24f39e3c1990c7a54 not-for-merge branch 'testcommit202' of github.com:jantman/gitpython_issue_301 -fb06ed3204f39f85c7bb97cc2ac2478409c33612 not-for-merge branch 'testcommit2020' of github.com:jantman/gitpython_issue_301 -3c55bc13f5f1b5133d687f5b8ece9e3acaef2dcd not-for-merge branch 'testcommit2021' of github.com:jantman/gitpython_issue_301 -010812300617f659cb5201c5ba9bd1cb0afdd44d not-for-merge branch 'testcommit2022' of github.com:jantman/gitpython_issue_301 -21f4591f7b9b8264f002b74f0b14d5c3319b0b8d not-for-merge branch 'testcommit2023' of github.com:jantman/gitpython_issue_301 -1e1852e92df494ca4d0fa39f4ac7fddf2fe78c12 not-for-merge branch 'testcommit2024' of github.com:jantman/gitpython_issue_301 -807ed61e5141fe53d2f07759b3d6d22c0b9fb4f5 not-for-merge branch 'testcommit2025' of github.com:jantman/gitpython_issue_301 -e476905b6793bc7bf56e8ce604d5ec2517e6a33a not-for-merge branch 'testcommit2026' of github.com:jantman/gitpython_issue_301 -84154d33f06e118b6979c1d08d75715a5831faba not-for-merge branch 'testcommit2027' of github.com:jantman/gitpython_issue_301 -db95b369a94947a6bf5686e20cdc1f2906237c43 not-for-merge branch 'testcommit2028' of github.com:jantman/gitpython_issue_301 -a4d33325424942acaed2b6e85842752df032e119 not-for-merge branch 'testcommit2029' of github.com:jantman/gitpython_issue_301 -88b01984ebc75d8920c4b18397b4945b19ae4a27 not-for-merge branch 'testcommit203' of github.com:jantman/gitpython_issue_301 -7a9bb1725ed15b664a7b911af91f5c99cf11543f not-for-merge branch 'testcommit2030' of github.com:jantman/gitpython_issue_301 -907ab997798f7176699eceb72cd6f8c186be0a49 not-for-merge branch 'testcommit2031' of github.com:jantman/gitpython_issue_301 -b272b675225f8bbc7f0e7f8b1a84841858299de9 not-for-merge branch 'testcommit2032' of github.com:jantman/gitpython_issue_301 -0389aabd3e43e3b8968cebd456149b0629a05812 not-for-merge branch 'testcommit2033' of github.com:jantman/gitpython_issue_301 -eed7a4b3a15618700b0693c13168dc69ffe19800 not-for-merge branch 'testcommit2034' of github.com:jantman/gitpython_issue_301 -a76d126953b261b2d8b99b09cc2bafb049c61fe6 not-for-merge branch 'testcommit2035' of github.com:jantman/gitpython_issue_301 -2722685e618d6287e1e14881567dd045640bd63e not-for-merge branch 'testcommit2036' of github.com:jantman/gitpython_issue_301 -54b0a794a4af0eb4e3f858f36395df97b7aa04ef not-for-merge branch 'testcommit2037' of github.com:jantman/gitpython_issue_301 -d0ba849a60c09b63a69c42dd1e1c5dbf68d85a7e not-for-merge branch 'testcommit2038' of github.com:jantman/gitpython_issue_301 -e1aaf841d54292077d97854924069d6ea5374042 not-for-merge branch 'testcommit2039' of github.com:jantman/gitpython_issue_301 -d1715181a14d1d642f64c819fcfc6e7298a5028f not-for-merge branch 'testcommit204' of github.com:jantman/gitpython_issue_301 -3fc496ce4811acf970b3041c671f49a2383394eb not-for-merge branch 'testcommit2040' of github.com:jantman/gitpython_issue_301 -3303cdf9a4269e9b3570f301724ee500793b823b not-for-merge branch 'testcommit2041' of github.com:jantman/gitpython_issue_301 -e6bb5b9baf5d3984dfebd8fe54f8067f4857d118 not-for-merge branch 'testcommit2042' of github.com:jantman/gitpython_issue_301 -b2657a0eb93212e363e6658fae13ef78fe9672e4 not-for-merge branch 'testcommit2043' of github.com:jantman/gitpython_issue_301 -c86cd67936ff170ef7ae8807b77d7c24be15b28b not-for-merge branch 'testcommit2044' of github.com:jantman/gitpython_issue_301 -cd4d269a740d25f686dc53b0c73d6514824df535 not-for-merge branch 'testcommit2045' of github.com:jantman/gitpython_issue_301 -e409b35b829dcde2f5629a296650a60514d3a75a not-for-merge branch 'testcommit2046' of github.com:jantman/gitpython_issue_301 -1ad2ab1062c46205b983ca4722c85422303e9588 not-for-merge branch 'testcommit2047' of github.com:jantman/gitpython_issue_301 -224d3aaefc27aa276d4aa057a985f3e3a17a8e1d not-for-merge branch 'testcommit2048' of github.com:jantman/gitpython_issue_301 -72ab2ebcbfac4963792727ab548fec7e4594be9c not-for-merge branch 'testcommit2049' of github.com:jantman/gitpython_issue_301 -8c42ec38f6a1bf1d34a667c339892b2bee559b59 not-for-merge branch 'testcommit205' of github.com:jantman/gitpython_issue_301 -7bf331d6e6da551bbb624af73e9fafcbcb58e3bf not-for-merge branch 'testcommit2050' of github.com:jantman/gitpython_issue_301 -0c646cd25088aea8d7ae6280ed8cecc34b971caf not-for-merge branch 'testcommit2051' of github.com:jantman/gitpython_issue_301 -bc2baa505331ba40ae76f6d7d8d919aacd0b0bb5 not-for-merge branch 'testcommit2052' of github.com:jantman/gitpython_issue_301 -9b404ed714296ffff1821a499a94341daaf4ba3d not-for-merge branch 'testcommit2053' of github.com:jantman/gitpython_issue_301 -8c04d004c2a1c6cfdb86a71a1a1d3eac7aa972f1 not-for-merge branch 'testcommit2054' of github.com:jantman/gitpython_issue_301 -d9f5760f3a2280736d396ceee12eadc306c76fcb not-for-merge branch 'testcommit2055' of github.com:jantman/gitpython_issue_301 -78a169a3413761baf83babce753fee67b9ce8e91 not-for-merge branch 'testcommit2056' of github.com:jantman/gitpython_issue_301 -6e079667ea52cd68b5d239fb070d518a16991e23 not-for-merge branch 'testcommit2057' of github.com:jantman/gitpython_issue_301 -701f24f67ba4e8d576a1f52bc66f5343d1e2880c not-for-merge branch 'testcommit2058' of github.com:jantman/gitpython_issue_301 -2a0a5ddfaf07f8b96e6140de33df2b02822d0a2f not-for-merge branch 'testcommit2059' of github.com:jantman/gitpython_issue_301 -8bf20777ff988f203003605ca6ceda8d5f0d05d2 not-for-merge branch 'testcommit206' of github.com:jantman/gitpython_issue_301 -e30a8f96cf55dc0e60e14666784d526de9565756 not-for-merge branch 'testcommit2060' of github.com:jantman/gitpython_issue_301 -803ca5ee2e46064005325d016a8aab5ced89611c not-for-merge branch 'testcommit2061' of github.com:jantman/gitpython_issue_301 -dd530c9af40d3410a3e7ec026330e6be23b6290c not-for-merge branch 'testcommit2062' of github.com:jantman/gitpython_issue_301 -0d9edbe99ff2fb52b42a3e1f30f3ab5fdf5631e2 not-for-merge branch 'testcommit2063' of github.com:jantman/gitpython_issue_301 -54b1dd961799815a5d91c3bb268e5b7b3a27b3d5 not-for-merge branch 'testcommit2064' of github.com:jantman/gitpython_issue_301 -6d52395ffe8dec0aedd12ec0b222a0a81fdb6981 not-for-merge branch 'testcommit2065' of github.com:jantman/gitpython_issue_301 -b8e59384de712d7f234a0af92678f8052de3be1d not-for-merge branch 'testcommit2066' of github.com:jantman/gitpython_issue_301 -ea3cc26dae85a099fe01b5c7f88bbdb1444fd555 not-for-merge branch 'testcommit2067' of github.com:jantman/gitpython_issue_301 -50045950ef26dc8b6ac4cba026fbaec492722424 not-for-merge branch 'testcommit2068' of github.com:jantman/gitpython_issue_301 -e32629d2babc6b5e825fbc479bc2cf79cf579334 not-for-merge branch 'testcommit2069' of github.com:jantman/gitpython_issue_301 -adbe7127f57aa32b9b8dff66ab733db2b011a765 not-for-merge branch 'testcommit207' of github.com:jantman/gitpython_issue_301 -9de7498541220de007901d3f47a32797d2e4ed08 not-for-merge branch 'testcommit2070' of github.com:jantman/gitpython_issue_301 -52c3b7720459e3148bd2eca5827c1ed402e95f9d not-for-merge branch 'testcommit2071' of github.com:jantman/gitpython_issue_301 -098d4312dfa3a593fa8070c82a10dfc149f0ede1 not-for-merge branch 'testcommit2072' of github.com:jantman/gitpython_issue_301 -4e41f29d48f976d6f7bf711ed7e285cfd1740edb not-for-merge branch 'testcommit2073' of github.com:jantman/gitpython_issue_301 -e8fa1aa09a15c02ad7616b8ea8d67a963a505f39 not-for-merge branch 'testcommit2074' of github.com:jantman/gitpython_issue_301 -61141cf55e6e91128f993702259a0dab3c37ff45 not-for-merge branch 'testcommit2075' of github.com:jantman/gitpython_issue_301 -c88f97ae7d8da34099435b62a4c7c3420f9b7e47 not-for-merge branch 'testcommit2076' of github.com:jantman/gitpython_issue_301 -2a653191fecbb83f36f44a47441c388db7e3fd16 not-for-merge branch 'testcommit2077' of github.com:jantman/gitpython_issue_301 -ab06b6e29095d7a616aaa85a8730c3e1072452b8 not-for-merge branch 'testcommit2078' of github.com:jantman/gitpython_issue_301 -c3da56ed9085783ab99c68e94a2fba7696043466 not-for-merge branch 'testcommit2079' of github.com:jantman/gitpython_issue_301 -c9fc27b383454fd4f36d0f0af3b2ddae4f3af644 not-for-merge branch 'testcommit208' of github.com:jantman/gitpython_issue_301 -b3c4763847f74b876d48e4de25cebf00c368b050 not-for-merge branch 'testcommit2080' of github.com:jantman/gitpython_issue_301 -933e7b7a8a4a4205ff9068ff0e8ea3b4fa1f9c69 not-for-merge branch 'testcommit2081' of github.com:jantman/gitpython_issue_301 -4ff71c9a1b4c692255abe9efabf8ab204fef3444 not-for-merge branch 'testcommit2082' of github.com:jantman/gitpython_issue_301 -3bc8c2ceb63c924d6bb1796ca05b49b16e022aad not-for-merge branch 'testcommit2083' of github.com:jantman/gitpython_issue_301 -b3b4dffba229e8e750b6e1f0cdeac9724d6fede2 not-for-merge branch 'testcommit2084' of github.com:jantman/gitpython_issue_301 -589095c3dc28656bec1eeb98d3186f6e6e4eb93c not-for-merge branch 'testcommit2085' of github.com:jantman/gitpython_issue_301 -43521cd647b00ce0f048441b30c5201392f60b94 not-for-merge branch 'testcommit2086' of github.com:jantman/gitpython_issue_301 -dc654d85720c762ea947f643fdf9c8c0cef3f2db not-for-merge branch 'testcommit2087' of github.com:jantman/gitpython_issue_301 -737fecdfc813ddb296e5947f0ac1923ef94016d4 not-for-merge branch 'testcommit2088' of github.com:jantman/gitpython_issue_301 -c0f5b5bf065a4ea637666982e9c96ed430c223c2 not-for-merge branch 'testcommit2089' of github.com:jantman/gitpython_issue_301 -87e62dc1b4ae5b6589081196a6e4a2a38148f257 not-for-merge branch 'testcommit209' of github.com:jantman/gitpython_issue_301 -d58d1a2c81afa35b114a5a5c7f6b8ee8c0874493 not-for-merge branch 'testcommit2090' of github.com:jantman/gitpython_issue_301 -bca85b054c28412c7bbd14db967d117c70ed3fcb not-for-merge branch 'testcommit2091' of github.com:jantman/gitpython_issue_301 -944f5f403c7889f63e057693a7fcbe592596e8e2 not-for-merge branch 'testcommit2092' of github.com:jantman/gitpython_issue_301 -10fb545a1689d9dcebf153252cd712eadda54ec1 not-for-merge branch 'testcommit2093' of github.com:jantman/gitpython_issue_301 -348b09a885a1f14a229f48442538521652e7000f not-for-merge branch 'testcommit2094' of github.com:jantman/gitpython_issue_301 -b53e195a0ed4f6158016ce0053adf2c87747bea0 not-for-merge branch 'testcommit2095' of github.com:jantman/gitpython_issue_301 -2d0e43431c0c303fa86419d4d68f1144ec9c9401 not-for-merge branch 'testcommit2096' of github.com:jantman/gitpython_issue_301 -088e536627e3ac850a45a23a11dc537ed99d6a3d not-for-merge branch 'testcommit2097' of github.com:jantman/gitpython_issue_301 -56128f0e64da26840a077fe9d9d2475d5f72b53a not-for-merge branch 'testcommit2098' of github.com:jantman/gitpython_issue_301 -1199f6633c5175ea6dae75b41cd5704f5a82fe5e not-for-merge branch 'testcommit2099' of github.com:jantman/gitpython_issue_301 -88f9bc8d5cfa2f7d8f44a7932ad5eb0589f83d49 not-for-merge branch 'testcommit21' of github.com:jantman/gitpython_issue_301 -b55ac7114cf44c418884a89e1bc025e31296bc34 not-for-merge branch 'testcommit210' of github.com:jantman/gitpython_issue_301 -a6ddad73109311f67107d8d2a6f7c8b4f9e0bb4b not-for-merge branch 'testcommit2100' of github.com:jantman/gitpython_issue_301 -22eaa580d0a12f5dc0e44df158bce76dee7f72ab not-for-merge branch 'testcommit2101' of github.com:jantman/gitpython_issue_301 -70838db5282ab7c85022b50dfd6c49d3baf2a93f not-for-merge branch 'testcommit2102' of github.com:jantman/gitpython_issue_301 -25683acb50bbf967a7df021a8487c8d349a4ca86 not-for-merge branch 'testcommit2103' of github.com:jantman/gitpython_issue_301 -31219498719b7e77586e5d8f6db4ded15f723040 not-for-merge branch 'testcommit2104' of github.com:jantman/gitpython_issue_301 -e0bffd68bfdb96ed3716dd58ce07d6c729b11785 not-for-merge branch 'testcommit2105' of github.com:jantman/gitpython_issue_301 -cd82858a17c7363b6fd3515144fefe5a56dc7e74 not-for-merge branch 'testcommit2106' of github.com:jantman/gitpython_issue_301 -580c999f64e205938fd6e98922812b805600540a not-for-merge branch 'testcommit2107' of github.com:jantman/gitpython_issue_301 -2467f3034fc4ece410caae23e20ba3fc7eba2331 not-for-merge branch 'testcommit2108' of github.com:jantman/gitpython_issue_301 -02587028064459c611958fa48a35f32ae6abca4a not-for-merge branch 'testcommit2109' of github.com:jantman/gitpython_issue_301 -014ea8627f0e04308cc694e18072be2000c63061 not-for-merge branch 'testcommit211' of github.com:jantman/gitpython_issue_301 -a4c91c49b02771b9d3ffc1664b30a000da25bdd5 not-for-merge branch 'testcommit2110' of github.com:jantman/gitpython_issue_301 -1a0e42d20b0e165bccc11ee3ce04fd266efa069b not-for-merge branch 'testcommit2111' of github.com:jantman/gitpython_issue_301 -671c756e9c1f12ce614661283107c2141b6aa467 not-for-merge branch 'testcommit2112' of github.com:jantman/gitpython_issue_301 -50859356e8e6a6deede992700d04e4e0994ac21b not-for-merge branch 'testcommit2113' of github.com:jantman/gitpython_issue_301 -03e80098a0b5694a94630b60559d4b3cf706d4bb not-for-merge branch 'testcommit2114' of github.com:jantman/gitpython_issue_301 -5d774047f702ffebecdd1c240ca5e22568c40d67 not-for-merge branch 'testcommit2115' of github.com:jantman/gitpython_issue_301 -38cd37aa27cf8778cd03c25d3844bee28be0e4e2 not-for-merge branch 'testcommit2116' of github.com:jantman/gitpython_issue_301 -3ebdf1d0f7bbc7c3281243e04cdb0a37953615a1 not-for-merge branch 'testcommit2117' of github.com:jantman/gitpython_issue_301 -faf8149f2fb0310b4cef8a5c8bd08fcb19871650 not-for-merge branch 'testcommit2118' of github.com:jantman/gitpython_issue_301 -d9c7dbfc5760deae5430ba277f520c11b0234934 not-for-merge branch 'testcommit2119' of github.com:jantman/gitpython_issue_301 -0ca47ebfee475a1b7d08d93214e04640ab8b0f26 not-for-merge branch 'testcommit212' of github.com:jantman/gitpython_issue_301 -20cd08766e458f11e3025e89597eca1cdc9ead14 not-for-merge branch 'testcommit2120' of github.com:jantman/gitpython_issue_301 -d47bb030fa4ca7cf4d444cf81af39ff12c0f859d not-for-merge branch 'testcommit2121' of github.com:jantman/gitpython_issue_301 -3c412e7a8f80ee3f8757c04813a604140bb75d2b not-for-merge branch 'testcommit2122' of github.com:jantman/gitpython_issue_301 -3d2098eea85e2b9dd24d2a0e8d1b466601ba7377 not-for-merge branch 'testcommit2123' of github.com:jantman/gitpython_issue_301 -5cc560e6755209edf3366b1a06f2844f03dff412 not-for-merge branch 'testcommit2124' of github.com:jantman/gitpython_issue_301 -658b867abb60dc9b0e7e06cd69372dfe9757e45c not-for-merge branch 'testcommit2125' of github.com:jantman/gitpython_issue_301 -601e61b34142833d466157d5867f05d30c0f0389 not-for-merge branch 'testcommit2126' of github.com:jantman/gitpython_issue_301 -9afa45ced9ec9418210025570ef092ae1df010dc not-for-merge branch 'testcommit2127' of github.com:jantman/gitpython_issue_301 -28701add626c8e2abff1265f6cd9b9dca0f69acc not-for-merge branch 'testcommit2128' of github.com:jantman/gitpython_issue_301 -b92b4a2b2670e8ec1988d7839cbd269478d45cff not-for-merge branch 'testcommit2129' of github.com:jantman/gitpython_issue_301 -be19aeac45e4e9fa17bb776a197518e8c1d69358 not-for-merge branch 'testcommit213' of github.com:jantman/gitpython_issue_301 -bbc571c4239049af443ef8810d0c89b70b9c222a not-for-merge branch 'testcommit2130' of github.com:jantman/gitpython_issue_301 -c8b58cea73a075a3525e7cd6dc2cb397fbf8c3b5 not-for-merge branch 'testcommit2131' of github.com:jantman/gitpython_issue_301 -1406c93e99ab85e82fd8012b73d6202cf5fc90cb not-for-merge branch 'testcommit2132' of github.com:jantman/gitpython_issue_301 -c1c5fe54d4e8eff4bd25a8f3f0c2ae6190e65426 not-for-merge branch 'testcommit2133' of github.com:jantman/gitpython_issue_301 -d84c1477131eee9aa40aa03f8baf768e6b38e749 not-for-merge branch 'testcommit2134' of github.com:jantman/gitpython_issue_301 -d6508030909b293c9e1aa0b98202b601b0d53aa6 not-for-merge branch 'testcommit2135' of github.com:jantman/gitpython_issue_301 -b796b9d671c42eecb344cb8c1701bed5f4eb97c1 not-for-merge branch 'testcommit2136' of github.com:jantman/gitpython_issue_301 -54e7f971551131ee9f4543880ccea06306a66884 not-for-merge branch 'testcommit2137' of github.com:jantman/gitpython_issue_301 -e6f998469a976859308de5cdd3ed9c06725e5ed0 not-for-merge branch 'testcommit2138' of github.com:jantman/gitpython_issue_301 -5bb90ca9f7d05d4aed65aba2e132e4705904bc61 not-for-merge branch 'testcommit2139' of github.com:jantman/gitpython_issue_301 -099b1dfb55e9cd5318833187123b8d8dadb913d4 not-for-merge branch 'testcommit214' of github.com:jantman/gitpython_issue_301 -80af9a8e0846db3905031cf6e4f281ffc91b4018 not-for-merge branch 'testcommit2140' of github.com:jantman/gitpython_issue_301 -ab8ad878a222331e67eb14ea8cb9588565fbec10 not-for-merge branch 'testcommit2141' of github.com:jantman/gitpython_issue_301 -12bf019dc1ac208168314a4f60282ce8343ccfa2 not-for-merge branch 'testcommit2142' of github.com:jantman/gitpython_issue_301 -989310e594bbba654b1870338920e8b9eee9954b not-for-merge branch 'testcommit2143' of github.com:jantman/gitpython_issue_301 -6de94835a3983402c20b80a2ffe3247e0714f8ad not-for-merge branch 'testcommit2144' of github.com:jantman/gitpython_issue_301 -07724a8c81eb949d15b6e56ab9e0cfa2f22dc4f6 not-for-merge branch 'testcommit2145' of github.com:jantman/gitpython_issue_301 -c5684b5152e118041e91c64c3c580f112b8118cf not-for-merge branch 'testcommit2146' of github.com:jantman/gitpython_issue_301 -94437beaa3b270502b8f7c5681bc2e52beaf528a not-for-merge branch 'testcommit2147' of github.com:jantman/gitpython_issue_301 -b0c543c034cc346ab3a89081522891cad11551b4 not-for-merge branch 'testcommit2148' of github.com:jantman/gitpython_issue_301 -96dd00d9b572c95b7885083b32e46b0d515ec2af not-for-merge branch 'testcommit2149' of github.com:jantman/gitpython_issue_301 -84a85406d770cfdebf99e1fe20f97b55458ab346 not-for-merge branch 'testcommit215' of github.com:jantman/gitpython_issue_301 -815d1aff1b28e14b51141dc2b2a7574c0ff40794 not-for-merge branch 'testcommit2150' of github.com:jantman/gitpython_issue_301 -d6e5a366f59f2023931338f4e6221f46d41880c6 not-for-merge branch 'testcommit2151' of github.com:jantman/gitpython_issue_301 -dee0470cf06c3f587a3f925e4321874f134da86b not-for-merge branch 'testcommit2152' of github.com:jantman/gitpython_issue_301 -6cb062ec7e01a7487ecabfc63bd9c8af1013ce2b not-for-merge branch 'testcommit2153' of github.com:jantman/gitpython_issue_301 -6e582d855acfdcd85d83367f7ffa807f491aa807 not-for-merge branch 'testcommit2154' of github.com:jantman/gitpython_issue_301 -a2a58d171ad6ad7d312bc3c9f5148f37fde23ae2 not-for-merge branch 'testcommit2155' of github.com:jantman/gitpython_issue_301 -e495280d78e5f1a38930dea6dff5d9080f4e5e67 not-for-merge branch 'testcommit2156' of github.com:jantman/gitpython_issue_301 -96192b844473a876ec3e02c82611b40366af69dd not-for-merge branch 'testcommit2157' of github.com:jantman/gitpython_issue_301 -2b223d114595bfebd290a1bb0d2d7c02fcfb204c not-for-merge branch 'testcommit2158' of github.com:jantman/gitpython_issue_301 -f19c6439a77a9beb97e8b1fd3d5ae611547d7449 not-for-merge branch 'testcommit2159' of github.com:jantman/gitpython_issue_301 -62aaf0b54d50fec4fa24d615e5e66a81e824c0a5 not-for-merge branch 'testcommit216' of github.com:jantman/gitpython_issue_301 -15109ae1345629dd3b5bc547db85cb4a20ceed5f not-for-merge branch 'testcommit2160' of github.com:jantman/gitpython_issue_301 -1b0c8c90c0be0b75712e1b0c69ca683a77437268 not-for-merge branch 'testcommit2161' of github.com:jantman/gitpython_issue_301 -db194db01d621130f5424260bfe228d35662e05c not-for-merge branch 'testcommit2162' of github.com:jantman/gitpython_issue_301 -4d567e6e6c50381650d029ff778c15a772ed1ffb not-for-merge branch 'testcommit2163' of github.com:jantman/gitpython_issue_301 -d802cfdc0230a4ebc983928273d7f18d30030a5a not-for-merge branch 'testcommit2164' of github.com:jantman/gitpython_issue_301 -b91d47eeebfa9e64060ad6c1bd1ed14bca69a887 not-for-merge branch 'testcommit2165' of github.com:jantman/gitpython_issue_301 -68cceff05ef4206e1dc540ab5be16c7085d7c6f8 not-for-merge branch 'testcommit2166' of github.com:jantman/gitpython_issue_301 -83fdf5863fb96490392daba6c57eec7d4b30dd58 not-for-merge branch 'testcommit2167' of github.com:jantman/gitpython_issue_301 -90ec826120d8feede3d564a85c32aca75cccd6d7 not-for-merge branch 'testcommit2168' of github.com:jantman/gitpython_issue_301 -6a30e525a10cd75b4e6ec600991ddd7fd2052fb8 not-for-merge branch 'testcommit2169' of github.com:jantman/gitpython_issue_301 -99c95c829774ebdcb48f6e27af58837cde96939e not-for-merge branch 'testcommit217' of github.com:jantman/gitpython_issue_301 -b458fd4c4a571b5cb2cdc9ccf3638255bcbb5fc1 not-for-merge branch 'testcommit2170' of github.com:jantman/gitpython_issue_301 -dd0deb69576b8520a3a51f4dd0a218260496b13f not-for-merge branch 'testcommit2171' of github.com:jantman/gitpython_issue_301 -3f6418e04623eccf154be3fded97a9f0b33ae88c not-for-merge branch 'testcommit2172' of github.com:jantman/gitpython_issue_301 -93f0b47e848861b028b2071ae910662c97fafd04 not-for-merge branch 'testcommit2173' of github.com:jantman/gitpython_issue_301 -8c04c54ab4588a63b7b016cbe6f2a69d739926e4 not-for-merge branch 'testcommit2174' of github.com:jantman/gitpython_issue_301 -c16b529fcb1cd24d230d2b6268d3b6401844677e not-for-merge branch 'testcommit2175' of github.com:jantman/gitpython_issue_301 -7ba1a06a7c9dd33e960014ba8a5a08e4947a1624 not-for-merge branch 'testcommit2176' of github.com:jantman/gitpython_issue_301 -bbd24f0217a786a7e1f55ecc2536955a5cbf355d not-for-merge branch 'testcommit2177' of github.com:jantman/gitpython_issue_301 -8e509137fefdb0788e39f02c0a840df53263d30a not-for-merge branch 'testcommit2178' of github.com:jantman/gitpython_issue_301 -af3575172fba80cb2aed38c1485efe2891cb7626 not-for-merge branch 'testcommit2179' of github.com:jantman/gitpython_issue_301 -2235a270c90cd854ef92ad2475445f2ec92ec2c5 not-for-merge branch 'testcommit218' of github.com:jantman/gitpython_issue_301 -83dfde9ece745dd9d764c759997c5faf81de67f7 not-for-merge branch 'testcommit2180' of github.com:jantman/gitpython_issue_301 -be9b53554346ce75a6ae2dba7deebd609da7a3b7 not-for-merge branch 'testcommit2181' of github.com:jantman/gitpython_issue_301 -7fc754802abf63d562a0337e4a44765a47ab3dc8 not-for-merge branch 'testcommit2182' of github.com:jantman/gitpython_issue_301 -ea889a4a83cdda578eea2ebce139a3d092e189c9 not-for-merge branch 'testcommit2183' of github.com:jantman/gitpython_issue_301 -915b898207e6c10ad85ce537cde77d5b720b985e not-for-merge branch 'testcommit2184' of github.com:jantman/gitpython_issue_301 -44f1b53565fde09489c3d619bf35897c3117d0ce not-for-merge branch 'testcommit2185' of github.com:jantman/gitpython_issue_301 -76387025b53342e79e7d47eb16c00ac54155dc5e not-for-merge branch 'testcommit2186' of github.com:jantman/gitpython_issue_301 -af5d9bf568c1102d0abe2132352b2971251a6055 not-for-merge branch 'testcommit2187' of github.com:jantman/gitpython_issue_301 -bf2a3633354d4bc90b4a0be8115fb957548cb643 not-for-merge branch 'testcommit2188' of github.com:jantman/gitpython_issue_301 -52e82c94094a1701224752b84e79718744da9734 not-for-merge branch 'testcommit2189' of github.com:jantman/gitpython_issue_301 -c957abe469cd839a3851f07a8070fdc69772657d not-for-merge branch 'testcommit219' of github.com:jantman/gitpython_issue_301 -015c1b53220efeb4ee276050e127a289460854bf not-for-merge branch 'testcommit2190' of github.com:jantman/gitpython_issue_301 -dba9b11095f9419d06f1545c8c4d141aaeb13da3 not-for-merge branch 'testcommit2191' of github.com:jantman/gitpython_issue_301 -01102fef4005e1026031be817511b6bb32f2a018 not-for-merge branch 'testcommit2192' of github.com:jantman/gitpython_issue_301 -a94a93d22077ca581df98581602b5f63de83265a not-for-merge branch 'testcommit2193' of github.com:jantman/gitpython_issue_301 -c57aed6475c29fb4c1068e836dc090dfc51ed5cb not-for-merge branch 'testcommit2194' of github.com:jantman/gitpython_issue_301 -934841c9b2532b1507011ad2d606b5ab6b0533e6 not-for-merge branch 'testcommit2195' of github.com:jantman/gitpython_issue_301 -4bacde797a79799883ec8c869d4686ef0ebce11b not-for-merge branch 'testcommit2196' of github.com:jantman/gitpython_issue_301 -447285526d7a77cf1910e1d8d1f385c9548c4eef not-for-merge branch 'testcommit2197' of github.com:jantman/gitpython_issue_301 -e9f77c5809bae5b67d47a695675449e25b13d998 not-for-merge branch 'testcommit2198' of github.com:jantman/gitpython_issue_301 -083778ea18fd74381bca65ce1cb86f320fc46f28 not-for-merge branch 'testcommit2199' of github.com:jantman/gitpython_issue_301 -c7704a628b53301110fd7da48f42b794427ac316 not-for-merge branch 'testcommit22' of github.com:jantman/gitpython_issue_301 -10f1551521884cb5d79ee1b4d5d74a750ae943ba not-for-merge branch 'testcommit220' of github.com:jantman/gitpython_issue_301 -995795626bf16660dd51eb2f695012a752b26976 not-for-merge branch 'testcommit2200' of github.com:jantman/gitpython_issue_301 -ec76fbd61a869ef7775056e5e43f41e39f08db15 not-for-merge branch 'testcommit2201' of github.com:jantman/gitpython_issue_301 -267bf309f8276e3b74640feee30e562cc7b3db50 not-for-merge branch 'testcommit2202' of github.com:jantman/gitpython_issue_301 -c31dc28876b3bbd15f101dfa05f270d25cedb504 not-for-merge branch 'testcommit2203' of github.com:jantman/gitpython_issue_301 -11ff8cfaf747ccb68ca97e0322209e499a6d0402 not-for-merge branch 'testcommit2204' of github.com:jantman/gitpython_issue_301 -e68e051efecd3e4dc921a3aa289e3a94771b0ccc not-for-merge branch 'testcommit2205' of github.com:jantman/gitpython_issue_301 -167c827d6a9bc8e28b368956e551df122d936d2d not-for-merge branch 'testcommit2206' of github.com:jantman/gitpython_issue_301 -c2455da917302cbef53c1a2e0ca0d5a5ff637e47 not-for-merge branch 'testcommit2207' of github.com:jantman/gitpython_issue_301 -a3fb8def5bc8f4669b2dc52a7e7cd9c26580837b not-for-merge branch 'testcommit2208' of github.com:jantman/gitpython_issue_301 -84de96a6471f51d5e4e977344032cd5e7cd6da27 not-for-merge branch 'testcommit2209' of github.com:jantman/gitpython_issue_301 -338f38041c79db054a016228ca740de19899d8cd not-for-merge branch 'testcommit221' of github.com:jantman/gitpython_issue_301 -52aed0bb2abd2e3ac73a1c8c965af25370f5cc83 not-for-merge branch 'testcommit2210' of github.com:jantman/gitpython_issue_301 -3a63ba30e6830a01315285eccb7ad7cc67c43a29 not-for-merge branch 'testcommit2211' of github.com:jantman/gitpython_issue_301 -e4b2801298a0e730b4b4461cabaccd0ba6dd8228 not-for-merge branch 'testcommit2212' of github.com:jantman/gitpython_issue_301 -6da91216f1c578cfb3916dc63fb596d09391b0a0 not-for-merge branch 'testcommit2213' of github.com:jantman/gitpython_issue_301 -22734a486668182247fe702a5750c54487309bdb not-for-merge branch 'testcommit2214' of github.com:jantman/gitpython_issue_301 -a9344b1d40d2dc4265faf138ad70b9552c7fa975 not-for-merge branch 'testcommit2215' of github.com:jantman/gitpython_issue_301 -d05544496e51dd325c7109d6b0a873d9f02347bc not-for-merge branch 'testcommit2216' of github.com:jantman/gitpython_issue_301 -e214275877955a49f368cfbb809c0f3f79b42073 not-for-merge branch 'testcommit2217' of github.com:jantman/gitpython_issue_301 -a0740f193ba7f32a5d085ae3410b3b364cb8f9ea not-for-merge branch 'testcommit2218' of github.com:jantman/gitpython_issue_301 -468fd485a0a57bf3f41b58725faafff55d6e0993 not-for-merge branch 'testcommit2219' of github.com:jantman/gitpython_issue_301 -c589bd88e349769b934576f505096e3b94994fa4 not-for-merge branch 'testcommit222' of github.com:jantman/gitpython_issue_301 -fbc413c164739a7e248442a8231b2e1b1af9c6eb not-for-merge branch 'testcommit2220' of github.com:jantman/gitpython_issue_301 -82cd20db1a352223bfa1543bf2305e6eaa7eaaaa not-for-merge branch 'testcommit2221' of github.com:jantman/gitpython_issue_301 -48a3ffcc99825ec9412d7b43eeca255b9981b092 not-for-merge branch 'testcommit2222' of github.com:jantman/gitpython_issue_301 -0fdb6cea083ce96d14dad8b8eaea7d5dcea6aa7a not-for-merge branch 'testcommit2223' of github.com:jantman/gitpython_issue_301 -623d6d7e38f40a36d094ffc44e0df2fd616aa69e not-for-merge branch 'testcommit2224' of github.com:jantman/gitpython_issue_301 -598c30e45fa2c332f1306ff3733c589de384f305 not-for-merge branch 'testcommit2225' of github.com:jantman/gitpython_issue_301 -ec697727cbe4c75aa0fe70fa71656d29024b1c3b not-for-merge branch 'testcommit2226' of github.com:jantman/gitpython_issue_301 -36f409ed8d4a5cff2ff7a4bbde2798c908a0c70d not-for-merge branch 'testcommit2227' of github.com:jantman/gitpython_issue_301 -3d05e0efdee0de23c0136c1eb321053960f746a6 not-for-merge branch 'testcommit2228' of github.com:jantman/gitpython_issue_301 -8aa4de111709b2a93058afea30d036bd67d0a8f0 not-for-merge branch 'testcommit2229' of github.com:jantman/gitpython_issue_301 -525f1379468b47a79ac422de820b1f8bafc5e87d not-for-merge branch 'testcommit223' of github.com:jantman/gitpython_issue_301 -63d5af6d702fd76c649c885231d6de0edba888be not-for-merge branch 'testcommit2230' of github.com:jantman/gitpython_issue_301 -91a61b345f72529f9a025b5335e301a7163a9981 not-for-merge branch 'testcommit2231' of github.com:jantman/gitpython_issue_301 -a2ed4d2b6ada7067316d3442657afae89233d8cb not-for-merge branch 'testcommit2232' of github.com:jantman/gitpython_issue_301 -1d371185c7e1acbca2ae14fc606d5290bca28303 not-for-merge branch 'testcommit2233' of github.com:jantman/gitpython_issue_301 -f5aca6b9721384e83da90850626cae2d261f8167 not-for-merge branch 'testcommit2234' of github.com:jantman/gitpython_issue_301 -693b3298b86605af185df590bd34ba7b385644b5 not-for-merge branch 'testcommit2235' of github.com:jantman/gitpython_issue_301 -536c53e19e6c3fb6f64efe06bfdf26ea3cdfba07 not-for-merge branch 'testcommit2236' of github.com:jantman/gitpython_issue_301 -13a0d94c55a8c294a2f5495b7637587ec733d086 not-for-merge branch 'testcommit2237' of github.com:jantman/gitpython_issue_301 -7afb771fb8baf679650653c30953c4f05d2be33e not-for-merge branch 'testcommit2238' of github.com:jantman/gitpython_issue_301 -67e8f4a64cf0f9942161a919b2c9787f30430320 not-for-merge branch 'testcommit2239' of github.com:jantman/gitpython_issue_301 -16961ce037d729e645a5601f436b584ebe86d1a4 not-for-merge branch 'testcommit224' of github.com:jantman/gitpython_issue_301 -203e6d95e7cc7c2874a31a2d037a54250280211c not-for-merge branch 'testcommit2240' of github.com:jantman/gitpython_issue_301 -b83fd6f0f127fb83809531de58ffe04f4a94d7a5 not-for-merge branch 'testcommit2241' of github.com:jantman/gitpython_issue_301 -8a1f91ed08cd3c1f8627618c294c7db61b4f7718 not-for-merge branch 'testcommit2242' of github.com:jantman/gitpython_issue_301 -46968390713fba3ce6242dbdc90ab6ac1f60462b not-for-merge branch 'testcommit2243' of github.com:jantman/gitpython_issue_301 -b5afe9f9f9aeeda73b59990763cad367d36f900d not-for-merge branch 'testcommit2244' of github.com:jantman/gitpython_issue_301 -6dd7d9cda19a06ded0dd98b8fb46b51aa39fb239 not-for-merge branch 'testcommit2245' of github.com:jantman/gitpython_issue_301 -cc6fbb5dc9e69a2a0e743ab6b3db9fb7762e8a6d not-for-merge branch 'testcommit2246' of github.com:jantman/gitpython_issue_301 -d32bcfb824c91286118136f4ce26ec5c458516fa not-for-merge branch 'testcommit2247' of github.com:jantman/gitpython_issue_301 -7d43a4b562c16c060c42ed95fbf0c3caedaad0d5 not-for-merge branch 'testcommit2248' of github.com:jantman/gitpython_issue_301 -0d038b495c0a95015dc799fdc7f8283454dbc4b2 not-for-merge branch 'testcommit2249' of github.com:jantman/gitpython_issue_301 -19aeadbbf556fff248f135b727f8c3c48f051c79 not-for-merge branch 'testcommit225' of github.com:jantman/gitpython_issue_301 -d8143d2c7f8849ec8c1618ad447a5b2f1a9cceff not-for-merge branch 'testcommit2250' of github.com:jantman/gitpython_issue_301 -b23db930b57b8207589aa3c955a7c2776c8714a5 not-for-merge branch 'testcommit2251' of github.com:jantman/gitpython_issue_301 -2e407d03f3993fbe1bf97ba9e4d63329e8c24c66 not-for-merge branch 'testcommit2252' of github.com:jantman/gitpython_issue_301 -e00457cd73115cdb6fb7ee8370a546c64b47cfc8 not-for-merge branch 'testcommit2253' of github.com:jantman/gitpython_issue_301 -2f4abe92aa35150fed35f0b35f7a5a4f27baecd8 not-for-merge branch 'testcommit2254' of github.com:jantman/gitpython_issue_301 -3b2c1efcd3927f6b432a4675c2529deece0c7471 not-for-merge branch 'testcommit2255' of github.com:jantman/gitpython_issue_301 -070959c65deb79a2183bb44da621332d6dde2a15 not-for-merge branch 'testcommit2256' of github.com:jantman/gitpython_issue_301 -5ac1afbfa03d8c167eac46ed47fbf02ae613f299 not-for-merge branch 'testcommit2257' of github.com:jantman/gitpython_issue_301 -91d638383ebff94f84486bd5630092c3c043e7b7 not-for-merge branch 'testcommit2258' of github.com:jantman/gitpython_issue_301 -14377e4c619735b378cb4a84fc1f5ad55957b740 not-for-merge branch 'testcommit2259' of github.com:jantman/gitpython_issue_301 -3fd150078f346fc14188ef1fd6e305097a27bef4 not-for-merge branch 'testcommit226' of github.com:jantman/gitpython_issue_301 -8986391f2c89c2f8e6de4eabac675648b4ee371a not-for-merge branch 'testcommit2260' of github.com:jantman/gitpython_issue_301 -ea5f554317f5bdf1122592a0bc463ca7bdc38037 not-for-merge branch 'testcommit2261' of github.com:jantman/gitpython_issue_301 -31ed0e04c72dd8faf0b3f7bc72ca5e4d9a41aaa5 not-for-merge branch 'testcommit2262' of github.com:jantman/gitpython_issue_301 -f1321d8d0d1d3a61e90f6e2a6babc96bacd7d665 not-for-merge branch 'testcommit2263' of github.com:jantman/gitpython_issue_301 -69506f13e7bfcc5e16adbd93283b35c63d68d6d1 not-for-merge branch 'testcommit2264' of github.com:jantman/gitpython_issue_301 -dd1233e7e67f68b96eb7d5de8cf8c0d9a16ca271 not-for-merge branch 'testcommit2265' of github.com:jantman/gitpython_issue_301 -02516d71a9b7047b875815b1173d499b3f42d18c not-for-merge branch 'testcommit2266' of github.com:jantman/gitpython_issue_301 -7ddc1871919fccc70ce08276d5bd20e2367ec845 not-for-merge branch 'testcommit2267' of github.com:jantman/gitpython_issue_301 -38d028cc6ad46d9d23960e33d94751347cf9323c not-for-merge branch 'testcommit2268' of github.com:jantman/gitpython_issue_301 -ba115859631eec2a68ad328f3659cc00605a0507 not-for-merge branch 'testcommit2269' of github.com:jantman/gitpython_issue_301 -a9e8089c3fb84af1e4b5d60aaeed338bb2a0cda1 not-for-merge branch 'testcommit227' of github.com:jantman/gitpython_issue_301 -eee2631a02043693b18187139d21a6f546d9f1b9 not-for-merge branch 'testcommit2270' of github.com:jantman/gitpython_issue_301 -e2b2b640d0ffe0b7aff3e83c668027a1fcd056d8 not-for-merge branch 'testcommit2271' of github.com:jantman/gitpython_issue_301 -582dfba4b8ca45d476dbd459afe95b87cab21999 not-for-merge branch 'testcommit2272' of github.com:jantman/gitpython_issue_301 -259d28354683c5ee95264e32152e5f70a138e56a not-for-merge branch 'testcommit2273' of github.com:jantman/gitpython_issue_301 -cd8e6ef35b97732cba92d146b35856a578c36bfc not-for-merge branch 'testcommit2274' of github.com:jantman/gitpython_issue_301 -0f8ef7609911a4d80a9b0baac3930ff30c923a2e not-for-merge branch 'testcommit2275' of github.com:jantman/gitpython_issue_301 -fd032ddfc3607a1c1cf474b73d50631d6da4b3a8 not-for-merge branch 'testcommit2276' of github.com:jantman/gitpython_issue_301 -52469f16a3b159b0a95c3530feff98a88d8c9ad5 not-for-merge branch 'testcommit2277' of github.com:jantman/gitpython_issue_301 -b6a56b4ccd3702935e59b631ae16cec50a66debf not-for-merge branch 'testcommit2278' of github.com:jantman/gitpython_issue_301 -f67640bc3fa2d30ee0c52900f20709d01139fbee not-for-merge branch 'testcommit2279' of github.com:jantman/gitpython_issue_301 -87b81d1c54d4341afe2a51e59c34ceb3137c4e6d not-for-merge branch 'testcommit228' of github.com:jantman/gitpython_issue_301 -02441c114f74b36b63ce278cb98f13f57713e546 not-for-merge branch 'testcommit2280' of github.com:jantman/gitpython_issue_301 -e5fcb7de2f3c7b31cec4b82dba086d86770f24b0 not-for-merge branch 'testcommit2281' of github.com:jantman/gitpython_issue_301 -26cfa99ca037033ff00791e54ac626f8ac129fb8 not-for-merge branch 'testcommit2282' of github.com:jantman/gitpython_issue_301 -c6f391c0b6ef699826a0837bd95e05d258f019ab not-for-merge branch 'testcommit2283' of github.com:jantman/gitpython_issue_301 -7b62226e6afb48fef801c24f3a945299a4732733 not-for-merge branch 'testcommit2284' of github.com:jantman/gitpython_issue_301 -6481951a29e494e6b3aedd6002a30b557a978803 not-for-merge branch 'testcommit2285' of github.com:jantman/gitpython_issue_301 -a83807061d53a51b54ba9d72925b85f89935d915 not-for-merge branch 'testcommit2286' of github.com:jantman/gitpython_issue_301 -762dac7005bf7c022bddf31efed439f4d0151d1d not-for-merge branch 'testcommit2287' of github.com:jantman/gitpython_issue_301 -664899277df979d3fe2465972ad830eeef6f5280 not-for-merge branch 'testcommit2288' of github.com:jantman/gitpython_issue_301 -98d3c60127ec7eaca903799739e079f3e48c5b4d not-for-merge branch 'testcommit2289' of github.com:jantman/gitpython_issue_301 -27e0b7bd5d316f5908b9faadf2dbc2f0a9379e8d not-for-merge branch 'testcommit229' of github.com:jantman/gitpython_issue_301 -65a2d58c4d22620bd54070abdb4eb050cb3f2d40 not-for-merge branch 'testcommit2290' of github.com:jantman/gitpython_issue_301 -cab8d562021768c1a3f4930487a8282a78483dc1 not-for-merge branch 'testcommit2291' of github.com:jantman/gitpython_issue_301 -8bcf51cc08da5543ed33d9d3b786421c1289f618 not-for-merge branch 'testcommit2292' of github.com:jantman/gitpython_issue_301 -81879f95b4ab593d9a6a53a4650c38394c903fc1 not-for-merge branch 'testcommit2293' of github.com:jantman/gitpython_issue_301 -9f4ffa8852c33d89c7a057b0e734b0dc245f0345 not-for-merge branch 'testcommit2294' of github.com:jantman/gitpython_issue_301 -37849d2e00ece080dbcc338f93cfa1821266f8d9 not-for-merge branch 'testcommit2295' of github.com:jantman/gitpython_issue_301 -2e1830f2b0d743b94501874f7b73a09460694d00 not-for-merge branch 'testcommit2296' of github.com:jantman/gitpython_issue_301 -20174f17f11225c03819bd8db3132f7bdd226171 not-for-merge branch 'testcommit2297' of github.com:jantman/gitpython_issue_301 -2bbdea142765dad2081a0d208758395ee20a322c not-for-merge branch 'testcommit2298' of github.com:jantman/gitpython_issue_301 -6abf0b05e61decf3777ea6da620ca17e0e7592ec not-for-merge branch 'testcommit2299' of github.com:jantman/gitpython_issue_301 -0fe57e4da5f19feef9f841b2a16771d636af8038 not-for-merge branch 'testcommit23' of github.com:jantman/gitpython_issue_301 -f2bd30b9371cb80e7149350df5e43d5740de3be1 not-for-merge branch 'testcommit230' of github.com:jantman/gitpython_issue_301 -d1426db02ecbc28d6e4c1488649be5e2e0dfc23d not-for-merge branch 'testcommit2300' of github.com:jantman/gitpython_issue_301 -33e22ba8f61501357f22ada1863cc5965c1e52db not-for-merge branch 'testcommit2301' of github.com:jantman/gitpython_issue_301 -4dbe4d5597aebc99f731713df7046b3106c04d28 not-for-merge branch 'testcommit2302' of github.com:jantman/gitpython_issue_301 -5be4523391053b13f1b77eef0a1d20c2423be876 not-for-merge branch 'testcommit2303' of github.com:jantman/gitpython_issue_301 -f10ae0b4b2049ddd8dda2b6b140096a8be8b4c6f not-for-merge branch 'testcommit2304' of github.com:jantman/gitpython_issue_301 -aea1d74f0b532826d1dc549f53aa77e281a65d23 not-for-merge branch 'testcommit2305' of github.com:jantman/gitpython_issue_301 -1b2696c3c4cdb8ab0c8a3b5961140b16e7fe7189 not-for-merge branch 'testcommit2306' of github.com:jantman/gitpython_issue_301 -6e77716d257be115c5756acbda12fa848b35f7a4 not-for-merge branch 'testcommit2307' of github.com:jantman/gitpython_issue_301 -f429a080d99621b2fa65b9c2babc66fb80cb88c1 not-for-merge branch 'testcommit2308' of github.com:jantman/gitpython_issue_301 -924c1496b39f8d7794efb09fc8a231f801a2e716 not-for-merge branch 'testcommit2309' of github.com:jantman/gitpython_issue_301 -da9244bde255bb4ee6e3ba3bac53a8bd4987ed45 not-for-merge branch 'testcommit231' of github.com:jantman/gitpython_issue_301 -2292f7c848cf882dd59e37da952df03dba959976 not-for-merge branch 'testcommit2310' of github.com:jantman/gitpython_issue_301 -627e7be35594175911614667d76691018f0b7384 not-for-merge branch 'testcommit2311' of github.com:jantman/gitpython_issue_301 -1eaf28bc61ea826b1ad9d149edefdefbd9ee7fca not-for-merge branch 'testcommit2312' of github.com:jantman/gitpython_issue_301 -561c2626ca54af77ef2ad9bf5dae5fa9e249f814 not-for-merge branch 'testcommit2313' of github.com:jantman/gitpython_issue_301 -80ebfba4250317fe524a9ba77e0277ee310b5266 not-for-merge branch 'testcommit2314' of github.com:jantman/gitpython_issue_301 -adf7dea28e7d9175394ef64817aee56c288e56f4 not-for-merge branch 'testcommit2315' of github.com:jantman/gitpython_issue_301 -8711ee8bab3029466c6ab4f917b40efac7dfd3e8 not-for-merge branch 'testcommit2316' of github.com:jantman/gitpython_issue_301 -36e299fbc300ff0b70940961cba7a506345e2c4c not-for-merge branch 'testcommit2317' of github.com:jantman/gitpython_issue_301 -fb45e86af26cce21408494fc30c40575e924e89a not-for-merge branch 'testcommit2318' of github.com:jantman/gitpython_issue_301 -ff4a3dc6b40ad04a5f8da4ad6815fdb97f16e9e9 not-for-merge branch 'testcommit2319' of github.com:jantman/gitpython_issue_301 -5e6084d1393da07d80d7fdacd0259ff884edaa7f not-for-merge branch 'testcommit232' of github.com:jantman/gitpython_issue_301 -e0bc54c8b33a8ed7fe39189f073f506f30b95c4e not-for-merge branch 'testcommit2320' of github.com:jantman/gitpython_issue_301 -e831cac5838d33993e2dd7233b1d955e96f46c90 not-for-merge branch 'testcommit2321' of github.com:jantman/gitpython_issue_301 -376f8bc59102e5e5c3b8d74e250d43010b21bfbe not-for-merge branch 'testcommit2322' of github.com:jantman/gitpython_issue_301 -059ab4297af3991d2cf215f455589eaeb458ce84 not-for-merge branch 'testcommit2323' of github.com:jantman/gitpython_issue_301 -baf8ac74e559a718281e2062f215fb60043de83c not-for-merge branch 'testcommit2324' of github.com:jantman/gitpython_issue_301 -78cc716c9e1ee4fdb8f33b0bac574275bfb46876 not-for-merge branch 'testcommit2325' of github.com:jantman/gitpython_issue_301 -ffb60495241c1f28537758e60bb02ac87686886e not-for-merge branch 'testcommit2326' of github.com:jantman/gitpython_issue_301 -6923f9cc0e4508a2d8be28f62be04b0bce795e9c not-for-merge branch 'testcommit2327' of github.com:jantman/gitpython_issue_301 -72d361c6a437be7b86844fbdec19133993b2ca7c not-for-merge branch 'testcommit2328' of github.com:jantman/gitpython_issue_301 -226dd68bc54c953f64b1944964897eeab5e36747 not-for-merge branch 'testcommit2329' of github.com:jantman/gitpython_issue_301 -8779414ab495735092104a4f2bbc02e4b0101cdc not-for-merge branch 'testcommit233' of github.com:jantman/gitpython_issue_301 -1f0f268263b9eb3b80713758421d88e9b92e3f4e not-for-merge branch 'testcommit2330' of github.com:jantman/gitpython_issue_301 -e46db99708fc5decd05db56ceedf845c3efa94e7 not-for-merge branch 'testcommit2331' of github.com:jantman/gitpython_issue_301 -778ce4cc6cd730e39438427520de285ffa207f1b not-for-merge branch 'testcommit2332' of github.com:jantman/gitpython_issue_301 -f152342389ad4eef1bf91121af1129309c1e014d not-for-merge branch 'testcommit2333' of github.com:jantman/gitpython_issue_301 -23ecd57f178bf24c18743b827729d752fd24a977 not-for-merge branch 'testcommit2334' of github.com:jantman/gitpython_issue_301 -048c88c1d8475e420775b3228772c5e38dff3c5f not-for-merge branch 'testcommit2335' of github.com:jantman/gitpython_issue_301 -f6a96d81f5c9ceeaaae98328cb6e9ee6f6778389 not-for-merge branch 'testcommit2336' of github.com:jantman/gitpython_issue_301 -42a41d352322b56b283d221202be1029f9a0fd77 not-for-merge branch 'testcommit2337' of github.com:jantman/gitpython_issue_301 -5a3cc6499728ba879a77b84ead9091479f4334dd not-for-merge branch 'testcommit2338' of github.com:jantman/gitpython_issue_301 -721718838d5cc8e4d76f383f3b61bea5cb4c752b not-for-merge branch 'testcommit2339' of github.com:jantman/gitpython_issue_301 -a259452c051820c3faf31eb311eabcf23adac7b5 not-for-merge branch 'testcommit234' of github.com:jantman/gitpython_issue_301 -53c4da3cfe6ce02dc93f4205a8d2072a1e7e91f2 not-for-merge branch 'testcommit2340' of github.com:jantman/gitpython_issue_301 -32d05aec002cba39b6b39e6ff331ccb614b77417 not-for-merge branch 'testcommit2341' of github.com:jantman/gitpython_issue_301 -4fa83d07775a0ab5ff2eacef7c529729a217c588 not-for-merge branch 'testcommit2342' of github.com:jantman/gitpython_issue_301 -52150e498c4f207e160a2ca7707c5533e9add502 not-for-merge branch 'testcommit2343' of github.com:jantman/gitpython_issue_301 -617c1868be2219e99444905ed0a9273d7d7beaeb not-for-merge branch 'testcommit2344' of github.com:jantman/gitpython_issue_301 -7c4b00fe848b6b61bb59b6d4606d80a1a445df58 not-for-merge branch 'testcommit2345' of github.com:jantman/gitpython_issue_301 -09f4f1765dd99c92053cb362cfced686a1ccf40b not-for-merge branch 'testcommit2346' of github.com:jantman/gitpython_issue_301 -0dc1cbc52512a3887aec94a7587321772cfc32d0 not-for-merge branch 'testcommit2347' of github.com:jantman/gitpython_issue_301 -57654560c0f2efe10cc6d1b7135d8d5286edbe5f not-for-merge branch 'testcommit2348' of github.com:jantman/gitpython_issue_301 -95b1fc51566c08fe619592f96df778abb4bb5a30 not-for-merge branch 'testcommit2349' of github.com:jantman/gitpython_issue_301 -28e2e39d8469c8052ed658af7b48ae62e67a97fb not-for-merge branch 'testcommit235' of github.com:jantman/gitpython_issue_301 -2024e4d5f6a22d7c278cd23dd2a5e3f826b71206 not-for-merge branch 'testcommit2350' of github.com:jantman/gitpython_issue_301 -64f918c87e1dcf23c11dc643748391c991a83f4e not-for-merge branch 'testcommit2351' of github.com:jantman/gitpython_issue_301 -ad6864f9d42d1de5f442dc5c1c532265f23594eb not-for-merge branch 'testcommit2352' of github.com:jantman/gitpython_issue_301 -66a248b9a261bbd2d28bebc239e8c5a208ffddab not-for-merge branch 'testcommit2353' of github.com:jantman/gitpython_issue_301 -ed2fb5de7500a3497e5108ff09261ef1168aec29 not-for-merge branch 'testcommit2354' of github.com:jantman/gitpython_issue_301 -e10160318492d3f1c74cf95e601edd6f9addf02a not-for-merge branch 'testcommit2355' of github.com:jantman/gitpython_issue_301 -35422657a2f4939e66bca2f78e827f1a20c0e6ca not-for-merge branch 'testcommit2356' of github.com:jantman/gitpython_issue_301 -4ec6bc3b224265a670b825bc766503d1e875dda5 not-for-merge branch 'testcommit2357' of github.com:jantman/gitpython_issue_301 -988ab730ca6f0f30fd87976b3c2f4800cc695c34 not-for-merge branch 'testcommit2358' of github.com:jantman/gitpython_issue_301 -f11991e5f3825647fccf5a0a1995056a61e2ad91 not-for-merge branch 'testcommit2359' of github.com:jantman/gitpython_issue_301 -6ae4a6f60f4cd116d821578d3ff194710e67e475 not-for-merge branch 'testcommit236' of github.com:jantman/gitpython_issue_301 -407a35181363d4d8274ac62766c0eabc81549825 not-for-merge branch 'testcommit2360' of github.com:jantman/gitpython_issue_301 -b6b7c0f11864d87a164a7c20984691796aaf1be9 not-for-merge branch 'testcommit2361' of github.com:jantman/gitpython_issue_301 -29ae536227f7318c1e2592fb6dcbf2726c0de5e8 not-for-merge branch 'testcommit2362' of github.com:jantman/gitpython_issue_301 -4ee0c17b2a64c3f9dc39dded191fe80f429be935 not-for-merge branch 'testcommit2363' of github.com:jantman/gitpython_issue_301 -7efe265e8fd283d9b38eed2207c1835f5bbf092b not-for-merge branch 'testcommit2364' of github.com:jantman/gitpython_issue_301 -09163df544adf906da100b7af19b6900b442ff60 not-for-merge branch 'testcommit2365' of github.com:jantman/gitpython_issue_301 -7c0d70c8ed5f3bd96c0dfd7efabf49d89a4d4845 not-for-merge branch 'testcommit2366' of github.com:jantman/gitpython_issue_301 -fc11ea6fc4f551aeb0340eeab93b32ca471aacc9 not-for-merge branch 'testcommit2367' of github.com:jantman/gitpython_issue_301 -1ca123892afa748526569f07881ff490843a7a65 not-for-merge branch 'testcommit2368' of github.com:jantman/gitpython_issue_301 -75a798cbea6a95b5ab85df638f09f538ffb4fb89 not-for-merge branch 'testcommit2369' of github.com:jantman/gitpython_issue_301 -7239ebcf436f0599f72269668dbe47d95c9a8b59 not-for-merge branch 'testcommit237' of github.com:jantman/gitpython_issue_301 -910115a40a24864fad19a9519e24dd34cb3fbeb5 not-for-merge branch 'testcommit2370' of github.com:jantman/gitpython_issue_301 -9a5de3e3be0efa89309d48b6ba4ff2612a97c15f not-for-merge branch 'testcommit2371' of github.com:jantman/gitpython_issue_301 -45dd7b9cee58faa19179a3ff29702d65c5663660 not-for-merge branch 'testcommit2372' of github.com:jantman/gitpython_issue_301 -4b8c55c0f9fc8447a98b17723d007a7f0582bcf8 not-for-merge branch 'testcommit2373' of github.com:jantman/gitpython_issue_301 -f0fc0c611cef7d3e02df897e9d64c76180a8d780 not-for-merge branch 'testcommit2374' of github.com:jantman/gitpython_issue_301 -55cc258eea8e1b8cc655349b088a6f77d0a39d35 not-for-merge branch 'testcommit2375' of github.com:jantman/gitpython_issue_301 -4575d57bd7f40d2c6d95a5c132013334fb1e0e24 not-for-merge branch 'testcommit2376' of github.com:jantman/gitpython_issue_301 -c6d3d91320352fa45920f37c4d818a29d291f580 not-for-merge branch 'testcommit2377' of github.com:jantman/gitpython_issue_301 -78f893af9737cbaf8684432e2fb765c893f3bb5a not-for-merge branch 'testcommit2378' of github.com:jantman/gitpython_issue_301 -cb7b64cbdfa4e9c151d9d4fb0e6d66a48b4f215a not-for-merge branch 'testcommit2379' of github.com:jantman/gitpython_issue_301 -8bb584df2d90ab6a6ba528f87da785f976aff951 not-for-merge branch 'testcommit238' of github.com:jantman/gitpython_issue_301 -47911636da6831da595483bbdff207f0c538ae7d not-for-merge branch 'testcommit2380' of github.com:jantman/gitpython_issue_301 -71cb4ac1d7528ffed3b5f0ff0d44060b8b582c13 not-for-merge branch 'testcommit2381' of github.com:jantman/gitpython_issue_301 -327bc749c4d7230594ecd1503310ee35b93c9eb4 not-for-merge branch 'testcommit2382' of github.com:jantman/gitpython_issue_301 -2735a2c7ed6cda41b21c790221513f879338448a not-for-merge branch 'testcommit2383' of github.com:jantman/gitpython_issue_301 -1fae50a37e65e010de5c10ecdb6c68b15489016a not-for-merge branch 'testcommit2384' of github.com:jantman/gitpython_issue_301 -3caf3663260c7043df279bde9366cbe4759d5522 not-for-merge branch 'testcommit2385' of github.com:jantman/gitpython_issue_301 -479ebb2583aca3e52c1970b62b8e6288fbcfe91e not-for-merge branch 'testcommit2386' of github.com:jantman/gitpython_issue_301 -cec1951f472ffd9978700feb8ec9898b86b29e86 not-for-merge branch 'testcommit2387' of github.com:jantman/gitpython_issue_301 -d4eefd5da01f3b7ee3d4089021b21e263da35abc not-for-merge branch 'testcommit2388' of github.com:jantman/gitpython_issue_301 -d739805a3b0add73aa9eae5f0a7426f9a152e6a5 not-for-merge branch 'testcommit2389' of github.com:jantman/gitpython_issue_301 -f4c87added742d3317bc1d02258a6c21838b737f not-for-merge branch 'testcommit239' of github.com:jantman/gitpython_issue_301 -f70e1f7cf9b83baed530e211464e369253a63a41 not-for-merge branch 'testcommit2390' of github.com:jantman/gitpython_issue_301 -e2adaa45776273cca5c930fd709bb1c895eb671c not-for-merge branch 'testcommit2391' of github.com:jantman/gitpython_issue_301 -364045967b74f9157ef9e06bd082befaa2f44cb5 not-for-merge branch 'testcommit2392' of github.com:jantman/gitpython_issue_301 -ca394b781920b959ace80098bc5c93efa765b361 not-for-merge branch 'testcommit2393' of github.com:jantman/gitpython_issue_301 -bd299622ce49ab2dd15c584de706984c2b61c21c not-for-merge branch 'testcommit2394' of github.com:jantman/gitpython_issue_301 -218a9ec3edb64488ec380fe4cda5951635b82d40 not-for-merge branch 'testcommit2395' of github.com:jantman/gitpython_issue_301 -0264f83198904a32f22604e8719b31b0cafe4556 not-for-merge branch 'testcommit2396' of github.com:jantman/gitpython_issue_301 -14aa73f6dfba1325fce39d2187f4c5c8dd35d2e6 not-for-merge branch 'testcommit2397' of github.com:jantman/gitpython_issue_301 -6a529f95b491069e09969118a0498e5de8c3acef not-for-merge branch 'testcommit2398' of github.com:jantman/gitpython_issue_301 -8ac0f4139f265c149c90b82952d9c4dae063c378 not-for-merge branch 'testcommit2399' of github.com:jantman/gitpython_issue_301 -b4d14118c8216eaf0206c1e92a82d21638ac3289 not-for-merge branch 'testcommit24' of github.com:jantman/gitpython_issue_301 -965715bd555173f06e3e880d675f05ff96042d69 not-for-merge branch 'testcommit240' of github.com:jantman/gitpython_issue_301 -b9c20db245f2b7a0f8191e2e22b48846e10001a7 not-for-merge branch 'testcommit2400' of github.com:jantman/gitpython_issue_301 -24c61898b4d67ecc700d41ab4e65564559bf022e not-for-merge branch 'testcommit2401' of github.com:jantman/gitpython_issue_301 -44eecabed6eb2d32a2acce0f4ea73a2a5e9200f1 not-for-merge branch 'testcommit2402' of github.com:jantman/gitpython_issue_301 -a137725293bc9725151ddc8aedb732c55a284961 not-for-merge branch 'testcommit2403' of github.com:jantman/gitpython_issue_301 -286b2678fca2d36525c6c8360ada172605196c24 not-for-merge branch 'testcommit2404' of github.com:jantman/gitpython_issue_301 -bddfe3e3ff6ed510a38ee0db41e9dca436a08108 not-for-merge branch 'testcommit2405' of github.com:jantman/gitpython_issue_301 -4cd9b9e436e1b13c6e28d89ecc8c67da48b21497 not-for-merge branch 'testcommit2406' of github.com:jantman/gitpython_issue_301 -2215efb01737dc8ab47161a9e0eb305fd376f107 not-for-merge branch 'testcommit2407' of github.com:jantman/gitpython_issue_301 -29e970c5ca417af9dc3aca63aefb0aef2de07e7f not-for-merge branch 'testcommit2408' of github.com:jantman/gitpython_issue_301 -3bc21777a3b3bf0cf8b5431adfcb6740e8d23ac6 not-for-merge branch 'testcommit2409' of github.com:jantman/gitpython_issue_301 -9c2a9c05314edce9b3d124c0d6c165ee8e5a13ec not-for-merge branch 'testcommit241' of github.com:jantman/gitpython_issue_301 -b2b874a22460571b6ec9840d7b7014aa3e982570 not-for-merge branch 'testcommit2410' of github.com:jantman/gitpython_issue_301 -b7744beff988a44a685003a75304dc42c814d344 not-for-merge branch 'testcommit2411' of github.com:jantman/gitpython_issue_301 -cb943af9d0a52c7fa6dbedab55d1f363c6d2b413 not-for-merge branch 'testcommit2412' of github.com:jantman/gitpython_issue_301 -5307367bba8f69d6684e9a4ffb41f243a9ebebb2 not-for-merge branch 'testcommit2413' of github.com:jantman/gitpython_issue_301 -f8a2457bf625b53d5ba7647a5d79fec26ae6b3c0 not-for-merge branch 'testcommit2414' of github.com:jantman/gitpython_issue_301 -9ff7efd18383834bf3d1246344b3965d5ad42d6c not-for-merge branch 'testcommit2415' of github.com:jantman/gitpython_issue_301 -f766d03deaa52e516e46f4826baffaeb88ae964f not-for-merge branch 'testcommit2416' of github.com:jantman/gitpython_issue_301 -8e5d51e85abbb9ea15589e0c678771d965bc2905 not-for-merge branch 'testcommit2417' of github.com:jantman/gitpython_issue_301 -0aec4ee825bfe3c4093d8db393576788cf612a4e not-for-merge branch 'testcommit2418' of github.com:jantman/gitpython_issue_301 -b21e3a187d872804f1cae76fae015322ee2aae2a not-for-merge branch 'testcommit2419' of github.com:jantman/gitpython_issue_301 -b1e5015368b731dc9595ce09f026c47da27e2a38 not-for-merge branch 'testcommit242' of github.com:jantman/gitpython_issue_301 -7160977fc9bce9543b2df45b7113ebf95d38c77b not-for-merge branch 'testcommit2420' of github.com:jantman/gitpython_issue_301 -eb54221f4ae7c3c19057d3d48b22115b0039f414 not-for-merge branch 'testcommit2421' of github.com:jantman/gitpython_issue_301 -9aac3c05842419cf32be269da09c08fce25dcbb5 not-for-merge branch 'testcommit2422' of github.com:jantman/gitpython_issue_301 -e5fc7ca540e12718ba84f7357953e13c38c45c60 not-for-merge branch 'testcommit2423' of github.com:jantman/gitpython_issue_301 -23e05f9aea9f4defba3123c7b654e7c6b78198be not-for-merge branch 'testcommit2424' of github.com:jantman/gitpython_issue_301 -56305aab985d88e99714e5aab841a25b4a5c119c not-for-merge branch 'testcommit2425' of github.com:jantman/gitpython_issue_301 -5c617aeb3435f322b191c172df5cb4750efa7b23 not-for-merge branch 'testcommit2426' of github.com:jantman/gitpython_issue_301 -27601a41b8cd732bc64977889cf224b51083a730 not-for-merge branch 'testcommit2427' of github.com:jantman/gitpython_issue_301 -42cdf67527c5e82388954dc2e4f5470eb6a043ac not-for-merge branch 'testcommit2428' of github.com:jantman/gitpython_issue_301 -3dccf168418e1a0dcddbfb8bb56a21a5f4abf0f7 not-for-merge branch 'testcommit2429' of github.com:jantman/gitpython_issue_301 -662ef4ad9f101cf742eff68a9a7af8701fe39034 not-for-merge branch 'testcommit243' of github.com:jantman/gitpython_issue_301 -cd733cdf51224e3cb163839b34c13c1ba14ff01c not-for-merge branch 'testcommit2430' of github.com:jantman/gitpython_issue_301 -756e873f8f0091f3396bc7ca79d595cb60114f76 not-for-merge branch 'testcommit2431' of github.com:jantman/gitpython_issue_301 -7a8dded69bac5eb00440b2ff9c96ecdbe809f67d not-for-merge branch 'testcommit2432' of github.com:jantman/gitpython_issue_301 -38de30b4cecb5d52937e6b18d69f4bcad3e8e25c not-for-merge branch 'testcommit2433' of github.com:jantman/gitpython_issue_301 -8299dc56d1fe1299c050786489b76592f643ec83 not-for-merge branch 'testcommit2434' of github.com:jantman/gitpython_issue_301 -7a0a1ca0f38def3782956c10bb49b4ceab85d157 not-for-merge branch 'testcommit2435' of github.com:jantman/gitpython_issue_301 -6416b4fcc302ba8c2f94310acbf3693adf86df1c not-for-merge branch 'testcommit2436' of github.com:jantman/gitpython_issue_301 -4e8e603caac7e6ddd4e703a6025727d224b5f41f not-for-merge branch 'testcommit2437' of github.com:jantman/gitpython_issue_301 -f09f9909ec5349346a05248f32c70b7654b6e590 not-for-merge branch 'testcommit2438' of github.com:jantman/gitpython_issue_301 -64611e2c7af7e83b01738ba7cebc4ffa0d2017bc not-for-merge branch 'testcommit2439' of github.com:jantman/gitpython_issue_301 -883337c976df16fd6cdb5229921b0f6f84dbfb4c not-for-merge branch 'testcommit244' of github.com:jantman/gitpython_issue_301 -27d18962404b8aa222c9d3c4357d134161bbcaa2 not-for-merge branch 'testcommit2440' of github.com:jantman/gitpython_issue_301 -ea288d352db1d7eaa1c8d00289c6a0bdda1bcc76 not-for-merge branch 'testcommit2441' of github.com:jantman/gitpython_issue_301 -73986aa79af74fc72ede132010397ff819f62c1c not-for-merge branch 'testcommit2442' of github.com:jantman/gitpython_issue_301 -d67afc83b0608854804f7a49da2ddcfc4efbc941 not-for-merge branch 'testcommit2443' of github.com:jantman/gitpython_issue_301 -1fa31c4205aa139ae8b3e751dee734b13f84f301 not-for-merge branch 'testcommit2444' of github.com:jantman/gitpython_issue_301 -972c33b3f51db5849143a4e5ccc4b2e1393e2c27 not-for-merge branch 'testcommit2445' of github.com:jantman/gitpython_issue_301 -23b88e677b51d57ca4a886508570f208d86e9dae not-for-merge branch 'testcommit2446' of github.com:jantman/gitpython_issue_301 -22daf2e983ba9ba119a996b4d9b30e72986c866d not-for-merge branch 'testcommit2447' of github.com:jantman/gitpython_issue_301 -98b2e4e6fe211f51f4b874b6e0ab3c166dcf8409 not-for-merge branch 'testcommit2448' of github.com:jantman/gitpython_issue_301 -48a440515d5b05120fd7ff5a8229b69883c31c55 not-for-merge branch 'testcommit2449' of github.com:jantman/gitpython_issue_301 -e5d8cfe4b41d26fcf4140d1c7492f5d82c56e78e not-for-merge branch 'testcommit245' of github.com:jantman/gitpython_issue_301 -ba2281218b20f708d7ad19c4bd5af24620b8dec8 not-for-merge branch 'testcommit2450' of github.com:jantman/gitpython_issue_301 -63156b30b41c8431b6af2ebfe221f1a301d64433 not-for-merge branch 'testcommit2451' of github.com:jantman/gitpython_issue_301 -1f6a4f8fca81cf72c08f749a753147487582c24f not-for-merge branch 'testcommit2452' of github.com:jantman/gitpython_issue_301 -2cebb78eaeb9b91832c0512063e74f0bb13c6470 not-for-merge branch 'testcommit2453' of github.com:jantman/gitpython_issue_301 -a35cf782cd3c1b2133f9603d41d3f5d838490720 not-for-merge branch 'testcommit2454' of github.com:jantman/gitpython_issue_301 -2a628386f39d921671b662335bcdce1564dcfbb2 not-for-merge branch 'testcommit2455' of github.com:jantman/gitpython_issue_301 -6477371c396b500b13c5faec7c870b82158fad3b not-for-merge branch 'testcommit2456' of github.com:jantman/gitpython_issue_301 -6cd874e1ab26af23779ef185d850ee8af9fdce4e not-for-merge branch 'testcommit2457' of github.com:jantman/gitpython_issue_301 -6cb426bd96fa4806a684713cafe3d687829203b4 not-for-merge branch 'testcommit2458' of github.com:jantman/gitpython_issue_301 -1efc72c0298cabe19de93600ffda106e3bf13a4e not-for-merge branch 'testcommit2459' of github.com:jantman/gitpython_issue_301 -1d4b1ef1c940bb3bab1b02eedbb92da3604808e4 not-for-merge branch 'testcommit246' of github.com:jantman/gitpython_issue_301 -fab1e8f9ec9de577a7287c77803df1218b41ab78 not-for-merge branch 'testcommit2460' of github.com:jantman/gitpython_issue_301 -1c4a67cbfd46701c3f9c0003f77f16e2ad509987 not-for-merge branch 'testcommit2461' of github.com:jantman/gitpython_issue_301 -03a4c137c42cf631221067a2d06e1614047d5b2d not-for-merge branch 'testcommit2462' of github.com:jantman/gitpython_issue_301 -760bee2374f630049ba0e2be91f7d30bdc35def2 not-for-merge branch 'testcommit2463' of github.com:jantman/gitpython_issue_301 -411130ce4abafdde62e65d13a9b73040ce5f6992 not-for-merge branch 'testcommit2464' of github.com:jantman/gitpython_issue_301 -9809dda92b35c05ce19745dcf50909786e79d446 not-for-merge branch 'testcommit2465' of github.com:jantman/gitpython_issue_301 -07e38d233ca974dcefd941072367759ace0c56d2 not-for-merge branch 'testcommit2466' of github.com:jantman/gitpython_issue_301 -b302017f225a5e47328d5e70a18fd4974a3af5ae not-for-merge branch 'testcommit2467' of github.com:jantman/gitpython_issue_301 -02549af281231180983872841b31f9f49d2c68b5 not-for-merge branch 'testcommit2468' of github.com:jantman/gitpython_issue_301 -991e168ded96390212d294f217fdcc4d0a6e6083 not-for-merge branch 'testcommit2469' of github.com:jantman/gitpython_issue_301 -b88fb990f009c56eef157ae5cdc477a0683f482d not-for-merge branch 'testcommit247' of github.com:jantman/gitpython_issue_301 -f2448ce092ec2ad3855b94facdeea9dfa52a53c7 not-for-merge branch 'testcommit2470' of github.com:jantman/gitpython_issue_301 -c249f489360bfac4fb81bdb78bdd356ec67f32a3 not-for-merge branch 'testcommit2471' of github.com:jantman/gitpython_issue_301 -db55205a7cfc73e6d74724b7fefd6eed44a3cd2b not-for-merge branch 'testcommit2472' of github.com:jantman/gitpython_issue_301 -40c4197fd8ed2ac4de16b5cec4d3a47786e6f7a3 not-for-merge branch 'testcommit2473' of github.com:jantman/gitpython_issue_301 -6201845ec1a44978d048d80c73852c93ad336bc6 not-for-merge branch 'testcommit2474' of github.com:jantman/gitpython_issue_301 -3d0566940de40dde5190ec3b61adb16ea9bf288c not-for-merge branch 'testcommit2475' of github.com:jantman/gitpython_issue_301 -551eea23140f5d0ce217d9b4f9cecb7e3a2cca14 not-for-merge branch 'testcommit2476' of github.com:jantman/gitpython_issue_301 -5a289451475676fa60a7bae5615a438a8b6fee1d not-for-merge branch 'testcommit2477' of github.com:jantman/gitpython_issue_301 -483522410fa62ab90a9c9565f6c5ee53951debf4 not-for-merge branch 'testcommit2478' of github.com:jantman/gitpython_issue_301 -b551623a6bc97b819ba00457b6c9e58ec53bfe2d not-for-merge branch 'testcommit2479' of github.com:jantman/gitpython_issue_301 -a3bab4cca99cd3f70cf4d8f26a7f31a604a73790 not-for-merge branch 'testcommit248' of github.com:jantman/gitpython_issue_301 -2d85780aaab6111fd914527f10cc2b21b79b10fe not-for-merge branch 'testcommit2480' of github.com:jantman/gitpython_issue_301 -d9bad33d717697f384ac845568bc4660c0fa17f2 not-for-merge branch 'testcommit2481' of github.com:jantman/gitpython_issue_301 -8e3c245be7c2f0ebfc25007d55d1084efa831457 not-for-merge branch 'testcommit2482' of github.com:jantman/gitpython_issue_301 -fa0a870b42a806fd15a6a22a1d19250bede168f6 not-for-merge branch 'testcommit2483' of github.com:jantman/gitpython_issue_301 -495904b9d5e6c534526ff2943e938a962d519098 not-for-merge branch 'testcommit2484' of github.com:jantman/gitpython_issue_301 -7bf6fc5692c576d918131a59e5b21c3ba761c4b1 not-for-merge branch 'testcommit2485' of github.com:jantman/gitpython_issue_301 -73a58778157d8f5bf547e15ed37bf6ef04d6b3d4 not-for-merge branch 'testcommit2486' of github.com:jantman/gitpython_issue_301 -5f5cda3d2d41f3dffd518e709844dd32a8c9ebaa not-for-merge branch 'testcommit2487' of github.com:jantman/gitpython_issue_301 -1bcbd2ee03bdd4ed3dee14801cfd7d447ab5893f not-for-merge branch 'testcommit2488' of github.com:jantman/gitpython_issue_301 -71bbb9703780bc1168efd6ad80792b72e29368d0 not-for-merge branch 'testcommit2489' of github.com:jantman/gitpython_issue_301 -1a82f3c2f9b29614cf62762a8f34ea71533b5024 not-for-merge branch 'testcommit249' of github.com:jantman/gitpython_issue_301 -65c7e457923624025c8ec8db959eb1d6bf574227 not-for-merge branch 'testcommit2490' of github.com:jantman/gitpython_issue_301 -554fff3a56baed029d9e5c700ab04694cf0d903f not-for-merge branch 'testcommit2491' of github.com:jantman/gitpython_issue_301 -1f8e7643e8eaaeac85402ffcbdba04d7ac87e9fc not-for-merge branch 'testcommit2492' of github.com:jantman/gitpython_issue_301 -c595c602818bfe85bf7f0bbf8b7642d6c46ca107 not-for-merge branch 'testcommit2493' of github.com:jantman/gitpython_issue_301 -fd5ca5d1b23476b7d4b19787117981ef50981971 not-for-merge branch 'testcommit2494' of github.com:jantman/gitpython_issue_301 -94ffe7293aba50d644cf7e4ce291c02065530f24 not-for-merge branch 'testcommit2495' of github.com:jantman/gitpython_issue_301 -204d77290958e8a63f51b4b712c4e096de875ede not-for-merge branch 'testcommit2496' of github.com:jantman/gitpython_issue_301 -0ced74e2d818799241d509437481d326cb2e6a29 not-for-merge branch 'testcommit2497' of github.com:jantman/gitpython_issue_301 -becb9b183a16b28f9635f9010c9e4f6ca6d1f40d not-for-merge branch 'testcommit2498' of github.com:jantman/gitpython_issue_301 -10c6365d8c5aaf192f7b74fa64052a95425dd5b8 not-for-merge branch 'testcommit2499' of github.com:jantman/gitpython_issue_301 -36ecc67ce3ad378c357403dccc885e564fd1fb6c not-for-merge branch 'testcommit25' of github.com:jantman/gitpython_issue_301 -7f65c6e89bb4d25127a11b13ab01a26d7b5917d0 not-for-merge branch 'testcommit250' of github.com:jantman/gitpython_issue_301 -9f8207cea9f14613b0da78aad6315ab7366729e9 not-for-merge branch 'testcommit2500' of github.com:jantman/gitpython_issue_301 -6fb9649faa6bdbb71e77f1f82937c3c1a26a1e0f not-for-merge branch 'testcommit2501' of github.com:jantman/gitpython_issue_301 -9af73df381eab5ef131300ce0ae4dffe2209eef5 not-for-merge branch 'testcommit2502' of github.com:jantman/gitpython_issue_301 -88433e2dcbe32d379b0282e9629170b384a27ef6 not-for-merge branch 'testcommit2503' of github.com:jantman/gitpython_issue_301 -b3d3457f4d86a74d100baace5e2a1fd21a93a8af not-for-merge branch 'testcommit2504' of github.com:jantman/gitpython_issue_301 -e50d10b6a87ae30d15b0507e950de03d0f9c089b not-for-merge branch 'testcommit2505' of github.com:jantman/gitpython_issue_301 -7b22683150ba8f8ff4c4da2f07c8b1a36d51f582 not-for-merge branch 'testcommit2506' of github.com:jantman/gitpython_issue_301 -634341785be8c1cd80aea9ea546925586163f9ff not-for-merge branch 'testcommit2507' of github.com:jantman/gitpython_issue_301 -2f921695dd1023b845fa53a8fea7862c6ffa3ab0 not-for-merge branch 'testcommit2508' of github.com:jantman/gitpython_issue_301 -3ecbb8310c8ac3d44f4e6db90fe6feff89ce32e8 not-for-merge branch 'testcommit2509' of github.com:jantman/gitpython_issue_301 -8fe658a85456807f4d679e187feb6e19a34177fb not-for-merge branch 'testcommit251' of github.com:jantman/gitpython_issue_301 -4a81015742b8e6cfd0c1688a5149d6dbf1ad8fab not-for-merge branch 'testcommit2510' of github.com:jantman/gitpython_issue_301 -b49afa22e3445c286d393a648c7008899e357f16 not-for-merge branch 'testcommit2511' of github.com:jantman/gitpython_issue_301 -9ab15838a207fcce6794a5732e1a41225695f3e4 not-for-merge branch 'testcommit2512' of github.com:jantman/gitpython_issue_301 -a8d28cd2dd6b43071d789c2086ea44c9d509f839 not-for-merge branch 'testcommit2513' of github.com:jantman/gitpython_issue_301 -65a8f327d1d0f21180e0a06a7b97ce5e92e11187 not-for-merge branch 'testcommit2514' of github.com:jantman/gitpython_issue_301 -eb1ce859412acd84ed8fd095b949e9a52148fe26 not-for-merge branch 'testcommit2515' of github.com:jantman/gitpython_issue_301 -32cb05cd13b01cb7f3e28e3aab6d0ea37152ccc9 not-for-merge branch 'testcommit2516' of github.com:jantman/gitpython_issue_301 -65a7462c7fb6c0efb3ae55dd60c2a75d24b17699 not-for-merge branch 'testcommit2517' of github.com:jantman/gitpython_issue_301 -346cbbcedec7f318aeb73c2f7680d2fb9b873256 not-for-merge branch 'testcommit2518' of github.com:jantman/gitpython_issue_301 -84695003efbf10ce8633329c02e1e27f2bae8ed3 not-for-merge branch 'testcommit2519' of github.com:jantman/gitpython_issue_301 -4ebf7167852e460bac157425ddfc6050eedcb6e8 not-for-merge branch 'testcommit252' of github.com:jantman/gitpython_issue_301 -57671b1f416f664424d890035879304bdbe93db5 not-for-merge branch 'testcommit2520' of github.com:jantman/gitpython_issue_301 -9116784214dd975a277b77edccfb00a155b9a2de not-for-merge branch 'testcommit2521' of github.com:jantman/gitpython_issue_301 -9227a8820d142544c889039090535c91f3a5f619 not-for-merge branch 'testcommit2522' of github.com:jantman/gitpython_issue_301 -a84e4d38fda2edc1210c725d45c2f4f332fb53b9 not-for-merge branch 'testcommit2523' of github.com:jantman/gitpython_issue_301 -fd731b4deccfdadf58337edcc5b5a351335fbdab not-for-merge branch 'testcommit2524' of github.com:jantman/gitpython_issue_301 -a5cef96aa401362360a7f05b416ad5fc1292dce6 not-for-merge branch 'testcommit2525' of github.com:jantman/gitpython_issue_301 -744f1b1eddc435bf75d0a69db682ff77982979b0 not-for-merge branch 'testcommit2526' of github.com:jantman/gitpython_issue_301 -4fd6e2ce11f7a8da63a8103e8f4b63ba904a41fd not-for-merge branch 'testcommit2527' of github.com:jantman/gitpython_issue_301 -ef5dc38b06a23882b4f2f1234fa68ec009327147 not-for-merge branch 'testcommit2528' of github.com:jantman/gitpython_issue_301 -1e5f1adf9c665e8fc2b4e89a0c2f343632e32c87 not-for-merge branch 'testcommit2529' of github.com:jantman/gitpython_issue_301 -81b0668d40dd32901d0dce29b6238d43b0a4b248 not-for-merge branch 'testcommit253' of github.com:jantman/gitpython_issue_301 -63bc745cb3bcda41533aafc82fd10c478258fa82 not-for-merge branch 'testcommit2530' of github.com:jantman/gitpython_issue_301 -06d3fcced50ad8c923549df83f92981cfe868b55 not-for-merge branch 'testcommit2531' of github.com:jantman/gitpython_issue_301 -ca1102f5a01c64685f5d6da535859371f7cd6b2b not-for-merge branch 'testcommit2532' of github.com:jantman/gitpython_issue_301 -5dc38224517b22506ac2a92fda2a47261067de32 not-for-merge branch 'testcommit2533' of github.com:jantman/gitpython_issue_301 -2ca31df99804169b9bcd9ce7faad3a080082124c not-for-merge branch 'testcommit2534' of github.com:jantman/gitpython_issue_301 -ca0a03d079cbba77894fe3e1768e5aec075614ce not-for-merge branch 'testcommit2535' of github.com:jantman/gitpython_issue_301 -6371392995425b3c03379c914d80352996313a1a not-for-merge branch 'testcommit2536' of github.com:jantman/gitpython_issue_301 -275d584bd35615078958d6a5f1e53835fa455519 not-for-merge branch 'testcommit2537' of github.com:jantman/gitpython_issue_301 -3abb1cb869f1159a113d1f4de5751fcefdab5cda not-for-merge branch 'testcommit2538' of github.com:jantman/gitpython_issue_301 -a6209f5516a12ba99c2da26ca4b89ef9c2a4919b not-for-merge branch 'testcommit2539' of github.com:jantman/gitpython_issue_301 -e6539bbf318dda8404b4d68000867952d9ba91db not-for-merge branch 'testcommit254' of github.com:jantman/gitpython_issue_301 -890c959e619477790cf915387ed47cd400bcf22d not-for-merge branch 'testcommit2540' of github.com:jantman/gitpython_issue_301 -ce992bd6b6ed109059771cea2f4975b5ef2d4a26 not-for-merge branch 'testcommit2541' of github.com:jantman/gitpython_issue_301 -14b13f5d38a4dc198cf4f364d8bc359e6806b384 not-for-merge branch 'testcommit2542' of github.com:jantman/gitpython_issue_301 -fd96be8a9ceca346fb83ea263fabe11a10eca49b not-for-merge branch 'testcommit2543' of github.com:jantman/gitpython_issue_301 -f6627807b966d3054ed81f2d5b4849083a962b58 not-for-merge branch 'testcommit2544' of github.com:jantman/gitpython_issue_301 -fcc60eba4d5802993c0de4112483afc19f3b4d30 not-for-merge branch 'testcommit2545' of github.com:jantman/gitpython_issue_301 -11968e5fb02505919beba80ea0d012f03a6867f2 not-for-merge branch 'testcommit2546' of github.com:jantman/gitpython_issue_301 -d0f6adfd67f5dbfd920fb8e0edbb13b7934b2dac not-for-merge branch 'testcommit2547' of github.com:jantman/gitpython_issue_301 -ad814aba0f84b171ce3f9abd080ffe9d81345dd5 not-for-merge branch 'testcommit2548' of github.com:jantman/gitpython_issue_301 -3afcfbd695e9427b3decbe7f77a9a33762defa7a not-for-merge branch 'testcommit2549' of github.com:jantman/gitpython_issue_301 -ee500b47ce450e00868565eb8dbcf1980c66a9c0 not-for-merge branch 'testcommit255' of github.com:jantman/gitpython_issue_301 -035cfd14aef1277f96468207c7199c48ec4edf35 not-for-merge branch 'testcommit2550' of github.com:jantman/gitpython_issue_301 -a422e114c5183308d221922ca6b4bc47d2d1c819 not-for-merge branch 'testcommit2551' of github.com:jantman/gitpython_issue_301 -d0a2e77af2ae0dbf87e5f91efdb85b3ae53c1904 not-for-merge branch 'testcommit2552' of github.com:jantman/gitpython_issue_301 -ae5b919b143b7cfb9013b6fe4d114a92ac31f531 not-for-merge branch 'testcommit2553' of github.com:jantman/gitpython_issue_301 -627dbe84369e211b103e64a475a052f8bedcb395 not-for-merge branch 'testcommit2554' of github.com:jantman/gitpython_issue_301 -ece723468f0eb8bf8be44d3af49412c0706ee264 not-for-merge branch 'testcommit2555' of github.com:jantman/gitpython_issue_301 -490cdf3db2c73dae209b22bae9fa6a2d650a07b3 not-for-merge branch 'testcommit2556' of github.com:jantman/gitpython_issue_301 -c5bdf8ce253384786be95c2b506433dde480eef1 not-for-merge branch 'testcommit2557' of github.com:jantman/gitpython_issue_301 -70b62327f2da14897232140a0414ff790ccd383f not-for-merge branch 'testcommit2558' of github.com:jantman/gitpython_issue_301 -690c04d4f72e3ed2c88c3739bdc726aff369755e not-for-merge branch 'testcommit2559' of github.com:jantman/gitpython_issue_301 -ac347911c82ee30b6b683e2dcc34ffdb3d83970b not-for-merge branch 'testcommit256' of github.com:jantman/gitpython_issue_301 -833751778abacd85f0ca20526e2ac6680ffce9ef not-for-merge branch 'testcommit2560' of github.com:jantman/gitpython_issue_301 -dbcfb87e2703c587a7e6b42ca61dbc1915123e9d not-for-merge branch 'testcommit2561' of github.com:jantman/gitpython_issue_301 -2b49b68cd46e14a58523ff8fcfebca4bd358744f not-for-merge branch 'testcommit2562' of github.com:jantman/gitpython_issue_301 -63e773e12bdb20f2d7f8f9ade7184cda6d583891 not-for-merge branch 'testcommit2563' of github.com:jantman/gitpython_issue_301 -9665011c0245b109d61b1643e5849cf98f10ac64 not-for-merge branch 'testcommit2564' of github.com:jantman/gitpython_issue_301 -3e790f24528c7cdee0faa872563dfebefb9bb7a1 not-for-merge branch 'testcommit2565' of github.com:jantman/gitpython_issue_301 -5dc843d1defb4c016b8d75e26ed131651a73494c not-for-merge branch 'testcommit2566' of github.com:jantman/gitpython_issue_301 -7cba31d62d15a7887aefa476c196b7f6ebda0993 not-for-merge branch 'testcommit2567' of github.com:jantman/gitpython_issue_301 -d94d0a851cfa7383c894b99ab1c59caffa4fceec not-for-merge branch 'testcommit2568' of github.com:jantman/gitpython_issue_301 -2274abbfe6f3ac9827f76ede449eca0f41fa5b8f not-for-merge branch 'testcommit2569' of github.com:jantman/gitpython_issue_301 -8b6264a409bd63a17ce91cfbd096ce69c584358e not-for-merge branch 'testcommit257' of github.com:jantman/gitpython_issue_301 -cdff398579d9fc1042de9d5705b8b141bb7fc240 not-for-merge branch 'testcommit2570' of github.com:jantman/gitpython_issue_301 -524f03f602dd78249faf1257a3bbf2da0898f903 not-for-merge branch 'testcommit2571' of github.com:jantman/gitpython_issue_301 -b47f5cdc1c7fb1a55e5a1df96d69966e2594b59b not-for-merge branch 'testcommit2572' of github.com:jantman/gitpython_issue_301 -2bf626dbb6f1c2c4f42c9ca07851387a9138ea91 not-for-merge branch 'testcommit2573' of github.com:jantman/gitpython_issue_301 -a3b0350cea18e9d2a977822cd58b5c459d22955b not-for-merge branch 'testcommit2574' of github.com:jantman/gitpython_issue_301 -5a6f7df368e95cd5bd4b5d2729dfd90f304237d1 not-for-merge branch 'testcommit2575' of github.com:jantman/gitpython_issue_301 -b26e88546d6c8642e34067507aaab9e55db21043 not-for-merge branch 'testcommit2576' of github.com:jantman/gitpython_issue_301 -f24360465b4dac88c2c94760fb6477f3dc705420 not-for-merge branch 'testcommit2577' of github.com:jantman/gitpython_issue_301 -fce23dc01e8a71d968d2602b83c879c9125f51bb not-for-merge branch 'testcommit2578' of github.com:jantman/gitpython_issue_301 -b9c72e74d9a02685735cdf5527ee7b08179bb945 not-for-merge branch 'testcommit2579' of github.com:jantman/gitpython_issue_301 -56100e094ea6e31e21ce89d6cf3be7ae9b2cb0e9 not-for-merge branch 'testcommit258' of github.com:jantman/gitpython_issue_301 -d3db6f82904a0d2ed6698437d8d046a31169de7f not-for-merge branch 'testcommit2580' of github.com:jantman/gitpython_issue_301 -22827d5ed6e9c8da94125360feb1231d238d2755 not-for-merge branch 'testcommit2581' of github.com:jantman/gitpython_issue_301 -a140a5fa20249fd9e76b493c559dbfe78336b792 not-for-merge branch 'testcommit2582' of github.com:jantman/gitpython_issue_301 -6ae718b96b85a5f7b48048d3d3d856c4a17023e8 not-for-merge branch 'testcommit2583' of github.com:jantman/gitpython_issue_301 -e01fade251ff4ad844f0c8ddaf31e0ae3df5ee16 not-for-merge branch 'testcommit2584' of github.com:jantman/gitpython_issue_301 -cbfdd98197022fe04f72004edeabe1c6b2fa2ce4 not-for-merge branch 'testcommit2585' of github.com:jantman/gitpython_issue_301 -f361df761b4117d09ded74f93dbd944adaa1f5a6 not-for-merge branch 'testcommit2586' of github.com:jantman/gitpython_issue_301 -68abb9be9ec33357b8ccc941332367eb1d22a552 not-for-merge branch 'testcommit2587' of github.com:jantman/gitpython_issue_301 -0f84dca8d20f18ed7fff1914f51e59d2ad1c77bc not-for-merge branch 'testcommit2588' of github.com:jantman/gitpython_issue_301 -ed14e4a52da8d77c12eb2c86feae1c8f96cc2071 not-for-merge branch 'testcommit2589' of github.com:jantman/gitpython_issue_301 -3faa66220ebbcc659a61b2cfebbc05a355a172d3 not-for-merge branch 'testcommit259' of github.com:jantman/gitpython_issue_301 -e26cdd365bc52a6c608a0ef75044691c7031fe90 not-for-merge branch 'testcommit2590' of github.com:jantman/gitpython_issue_301 -31c2122189840c61bb68fdb24b4623110901bc7f not-for-merge branch 'testcommit2591' of github.com:jantman/gitpython_issue_301 -85a9243cd378c0b543354675f5d91c78931eb82b not-for-merge branch 'testcommit2592' of github.com:jantman/gitpython_issue_301 -8a4936ca60a231aeeef8d4c976d2de6753e0cb50 not-for-merge branch 'testcommit2593' of github.com:jantman/gitpython_issue_301 -4697d87c3c3a72d74014284e0313afdac8896df1 not-for-merge branch 'testcommit2594' of github.com:jantman/gitpython_issue_301 -77727bc9e2ebe482df031b55dd4b5947e711f94e not-for-merge branch 'testcommit2595' of github.com:jantman/gitpython_issue_301 -47abd91b828c63b5af658dbec82defe3de7c2e4b not-for-merge branch 'testcommit2596' of github.com:jantman/gitpython_issue_301 -8fb879a957412f521cff23a96d1156703d7977b4 not-for-merge branch 'testcommit2597' of github.com:jantman/gitpython_issue_301 -2506f3999ed65736cc421bc323e5d73d91fa8910 not-for-merge branch 'testcommit2598' of github.com:jantman/gitpython_issue_301 -10b242460292fc9e7d6c8faac9f3b151ac0d63b9 not-for-merge branch 'testcommit2599' of github.com:jantman/gitpython_issue_301 -e070e1850fc3fcc175d5757b384c286274788d42 not-for-merge branch 'testcommit26' of github.com:jantman/gitpython_issue_301 -9e48be2702026120c6c15f27c450955dfc55b786 not-for-merge branch 'testcommit260' of github.com:jantman/gitpython_issue_301 -bfdef405841687d9dec80839993589af8bbb56f1 not-for-merge branch 'testcommit2600' of github.com:jantman/gitpython_issue_301 -51454689316a7913c18899369e353940e9c51da3 not-for-merge branch 'testcommit2601' of github.com:jantman/gitpython_issue_301 -ce0b8bb4aefd1c372d1b51e7da42021e7c4d12a0 not-for-merge branch 'testcommit2602' of github.com:jantman/gitpython_issue_301 -77445f7154035c094c16c6c448a35a33e7d221d6 not-for-merge branch 'testcommit2603' of github.com:jantman/gitpython_issue_301 -53fa5db3d131949deeb2471032913e123500442e not-for-merge branch 'testcommit2604' of github.com:jantman/gitpython_issue_301 -57f9ab589cbc23d753909287fb1a6c0546e3fdc9 not-for-merge branch 'testcommit2605' of github.com:jantman/gitpython_issue_301 -8305ade3aa6c3c7b400140d876a704b58da497ad not-for-merge branch 'testcommit2606' of github.com:jantman/gitpython_issue_301 -95f11943781299259b7185d46ad30df29f476648 not-for-merge branch 'testcommit2607' of github.com:jantman/gitpython_issue_301 -d340663049f70d3ea9dd225a3c535db8998c2a82 not-for-merge branch 'testcommit2608' of github.com:jantman/gitpython_issue_301 -d8bb27acda39727d74160e787a2333d803339761 not-for-merge branch 'testcommit2609' of github.com:jantman/gitpython_issue_301 -b244352a169e7d3e6eb4d6cf84511adf8e0d1d24 not-for-merge branch 'testcommit261' of github.com:jantman/gitpython_issue_301 -ce096555cdeb7f1e49e5f2855d5895e1ab379ab8 not-for-merge branch 'testcommit2610' of github.com:jantman/gitpython_issue_301 -2b5f64057c3c43bcf86dc506e49465e3eaf02dfc not-for-merge branch 'testcommit2611' of github.com:jantman/gitpython_issue_301 -884d6baa8267feb83e6b53c08b9cfe39287ddce4 not-for-merge branch 'testcommit2612' of github.com:jantman/gitpython_issue_301 -a4cb1c752e962c7c01719350c5ed53279225e6af not-for-merge branch 'testcommit2613' of github.com:jantman/gitpython_issue_301 -2275030b6492cee03472aac3576d58c67e943b3c not-for-merge branch 'testcommit2614' of github.com:jantman/gitpython_issue_301 -f039e98fd25f6d94fd97af1ea7c84f08adfbb992 not-for-merge branch 'testcommit2615' of github.com:jantman/gitpython_issue_301 -b359040761bad8dfe3a8fb65c56929215e75e1fa not-for-merge branch 'testcommit2616' of github.com:jantman/gitpython_issue_301 -ae0a8ccc7c3c32aabf7ebc1e20d8e14009cc66b1 not-for-merge branch 'testcommit2617' of github.com:jantman/gitpython_issue_301 -28c50ab0ddbc598d909955a89e44a73b675d191a not-for-merge branch 'testcommit2618' of github.com:jantman/gitpython_issue_301 -4e2c29f54f4b2265021926db02d8adef3c998aeb not-for-merge branch 'testcommit2619' of github.com:jantman/gitpython_issue_301 -1853984c561cde1995de6a13fda117647b0df0ad not-for-merge branch 'testcommit262' of github.com:jantman/gitpython_issue_301 -054826341269f6d9acac7d6045b99ffe37d7f352 not-for-merge branch 'testcommit2620' of github.com:jantman/gitpython_issue_301 -5d9b8bca889841339b564958d3f321f7c0162ba8 not-for-merge branch 'testcommit2621' of github.com:jantman/gitpython_issue_301 -037c615dbbf2c91e46beb62807434d8c32e01085 not-for-merge branch 'testcommit2622' of github.com:jantman/gitpython_issue_301 -c9d0e2884f1f9e557906486abb03a9ec5827a60a not-for-merge branch 'testcommit2623' of github.com:jantman/gitpython_issue_301 -56cdce8414532a9b304cc115da989a1984fef217 not-for-merge branch 'testcommit2624' of github.com:jantman/gitpython_issue_301 -b2b9f37f721ac3f955fca0b8e02a18a978ec73ad not-for-merge branch 'testcommit2625' of github.com:jantman/gitpython_issue_301 -17fe9ebac333c4c0b8c5eb609d65eba6d09459fb not-for-merge branch 'testcommit2626' of github.com:jantman/gitpython_issue_301 -ed516f1be4d0315920f670363b4dc0bb686a876d not-for-merge branch 'testcommit2627' of github.com:jantman/gitpython_issue_301 -00ef43b34ff69c9372888302bf1d27fcf74f9e04 not-for-merge branch 'testcommit2628' of github.com:jantman/gitpython_issue_301 -d6a29e39a1a33ea0a9f635ec4a482f66e3422e17 not-for-merge branch 'testcommit2629' of github.com:jantman/gitpython_issue_301 -b5568616d8e8b8e5e98b58fbeffde260a0b971f0 not-for-merge branch 'testcommit263' of github.com:jantman/gitpython_issue_301 -568304a0a1afa31b1d62ceef7c78873dd0e27d65 not-for-merge branch 'testcommit2630' of github.com:jantman/gitpython_issue_301 -88b9bf3db6efa520697ce71d47b493aa6da2149e not-for-merge branch 'testcommit2631' of github.com:jantman/gitpython_issue_301 -fef9167ecc90bea079adbc2875adc2ad25c8acb4 not-for-merge branch 'testcommit2632' of github.com:jantman/gitpython_issue_301 -638062826e001daf99077de32979f5447bdbd058 not-for-merge branch 'testcommit2633' of github.com:jantman/gitpython_issue_301 -dee4e1340478abd383bc231d6142ca7608d72ee6 not-for-merge branch 'testcommit2634' of github.com:jantman/gitpython_issue_301 -de1acf1124466fefc0420169697022d98b513eee not-for-merge branch 'testcommit2635' of github.com:jantman/gitpython_issue_301 -17f41e91d74673490151cee7c2618d7a53527412 not-for-merge branch 'testcommit2636' of github.com:jantman/gitpython_issue_301 -2be39a4a4673f529f9df0bd61ee64ac0d016e1ef not-for-merge branch 'testcommit2637' of github.com:jantman/gitpython_issue_301 -15a59660970c5efab7e456ae85bbbe914621581b not-for-merge branch 'testcommit2638' of github.com:jantman/gitpython_issue_301 -24b3100e41a4aa2a84a13991a2d44c9e81656465 not-for-merge branch 'testcommit2639' of github.com:jantman/gitpython_issue_301 -87fa504cb4b61e84902a80507ae9a32668fbc508 not-for-merge branch 'testcommit264' of github.com:jantman/gitpython_issue_301 -a4d891608c6cbb5b540c8f6114c144767a580262 not-for-merge branch 'testcommit2640' of github.com:jantman/gitpython_issue_301 -8280d94ac09e0670ca42b6ebcc2ba0dc868a6ea3 not-for-merge branch 'testcommit2641' of github.com:jantman/gitpython_issue_301 -0ad0d09aa10569f3f386c8253aedde617cd38a88 not-for-merge branch 'testcommit2642' of github.com:jantman/gitpython_issue_301 -3351157e7b78404a88462a171f3f6d9e7c07f927 not-for-merge branch 'testcommit2643' of github.com:jantman/gitpython_issue_301 -79a10805c3d42c900f45d462680e5f7682802cf6 not-for-merge branch 'testcommit2644' of github.com:jantman/gitpython_issue_301 -2c82599eab154662f64759486591fdb5d165fc4e not-for-merge branch 'testcommit2645' of github.com:jantman/gitpython_issue_301 -6e664103fc185bced7e715653c218463746f7bc9 not-for-merge branch 'testcommit2646' of github.com:jantman/gitpython_issue_301 -2a4d144dcb3d6f7215b3b53fdd7c6607499e22d8 not-for-merge branch 'testcommit2647' of github.com:jantman/gitpython_issue_301 -7ed08181cf870cc1f37414083a3b94c04181db51 not-for-merge branch 'testcommit2648' of github.com:jantman/gitpython_issue_301 -23e910e2918a2dbbb8bba55803b5c323b800718e not-for-merge branch 'testcommit2649' of github.com:jantman/gitpython_issue_301 -6bc9791debf3ac39b8c2805379364740041510ec not-for-merge branch 'testcommit265' of github.com:jantman/gitpython_issue_301 -c048ab1a6a2b4d2b6e95f54d7b3a4ea3092a3ff1 not-for-merge branch 'testcommit2650' of github.com:jantman/gitpython_issue_301 -ed1a1c89a6ff45dcdf837667404d1aabcb9ce9ae not-for-merge branch 'testcommit2651' of github.com:jantman/gitpython_issue_301 -4ea1acf690fb01309e729dccf00be42203961b7e not-for-merge branch 'testcommit2652' of github.com:jantman/gitpython_issue_301 -ce5ced01e8796e263e0a7a6f3f95ddf10fdcbd2e not-for-merge branch 'testcommit2653' of github.com:jantman/gitpython_issue_301 -dca4ad36be287199fa292b43cd7256fa39bacf25 not-for-merge branch 'testcommit2654' of github.com:jantman/gitpython_issue_301 -024ee6ddf8ae0d22a29afa13c8d5d8944668fb62 not-for-merge branch 'testcommit2655' of github.com:jantman/gitpython_issue_301 -6e441f6bc1200309dcdb0f7bbe25ce61d78dffc7 not-for-merge branch 'testcommit2656' of github.com:jantman/gitpython_issue_301 -ccbbe854f51c484e36177e5c33160212eb6d95b0 not-for-merge branch 'testcommit2657' of github.com:jantman/gitpython_issue_301 -9a99077e28b8f0d0a33f5165223c992d347d4127 not-for-merge branch 'testcommit2658' of github.com:jantman/gitpython_issue_301 -1518873b7a5f4fd5c79fa47d1d7d8163292ba00d not-for-merge branch 'testcommit2659' of github.com:jantman/gitpython_issue_301 -70f6cb5d1d6ddadac08c3202a322ca934584cf12 not-for-merge branch 'testcommit266' of github.com:jantman/gitpython_issue_301 -74a61ef4d19710e7fcd3dd658cd04436c2ac54bf not-for-merge branch 'testcommit2660' of github.com:jantman/gitpython_issue_301 -3e6a49c01c5edb83fd17ee4247fab66febf1f465 not-for-merge branch 'testcommit2661' of github.com:jantman/gitpython_issue_301 -0db04deeb40ac6bb776406deef343e458c28382c not-for-merge branch 'testcommit2662' of github.com:jantman/gitpython_issue_301 -ba1a8a085e5357b8913c1ee8814ef73217bd2001 not-for-merge branch 'testcommit2663' of github.com:jantman/gitpython_issue_301 -76c72bd5f4d143a694b89c338be792508edca632 not-for-merge branch 'testcommit2664' of github.com:jantman/gitpython_issue_301 -206339f0b44eff1df783ab459c72358341051d04 not-for-merge branch 'testcommit2665' of github.com:jantman/gitpython_issue_301 -9e8915b78f3215edf061b4642baded0ee26ab6b4 not-for-merge branch 'testcommit2666' of github.com:jantman/gitpython_issue_301 -c38daa95e16a2581f499d8ef38146283c42778b1 not-for-merge branch 'testcommit2667' of github.com:jantman/gitpython_issue_301 -66262cc757d815fa93cdc4c85060c690b4aadb8d not-for-merge branch 'testcommit2668' of github.com:jantman/gitpython_issue_301 -b309f8a6a67c0732c81efe23108112b89bad438f not-for-merge branch 'testcommit2669' of github.com:jantman/gitpython_issue_301 -ef005bc403b9317cfef380ea66ee4375e17040e8 not-for-merge branch 'testcommit267' of github.com:jantman/gitpython_issue_301 -86288859c62d1573f4fcf01d1f86bec40a7027cd not-for-merge branch 'testcommit2670' of github.com:jantman/gitpython_issue_301 -129570286e1629420e82015fc327520499755b3c not-for-merge branch 'testcommit2671' of github.com:jantman/gitpython_issue_301 -93a888381f65fa720388683e78ac0d1af7d5a117 not-for-merge branch 'testcommit2672' of github.com:jantman/gitpython_issue_301 -2215fe716627591511e34372d13b4c13c675a24a not-for-merge branch 'testcommit2673' of github.com:jantman/gitpython_issue_301 -5c03fe6ca8062972977d72ab7ebbd62e544f4271 not-for-merge branch 'testcommit2674' of github.com:jantman/gitpython_issue_301 -2eee715e5b304db3dd7b49213e57f4477f340c18 not-for-merge branch 'testcommit2675' of github.com:jantman/gitpython_issue_301 -f426a68d464edbbb0fcd098e69c1c8c2a52fafef not-for-merge branch 'testcommit2676' of github.com:jantman/gitpython_issue_301 -5ff37210ae00cbfb8aeaa3384ac1fce563e11498 not-for-merge branch 'testcommit2677' of github.com:jantman/gitpython_issue_301 -6fd5b2cbeae2f59fbcaf05dc93b0448924062e9b not-for-merge branch 'testcommit2678' of github.com:jantman/gitpython_issue_301 -e348ac03144c8d6943783235734e4302ece8cc6b not-for-merge branch 'testcommit2679' of github.com:jantman/gitpython_issue_301 -300c7978ef457b7fccb43d14ab1c93a3e4ccd881 not-for-merge branch 'testcommit268' of github.com:jantman/gitpython_issue_301 -cdc29b2d2c8a4dc193bc7d9975988d8527d41cdc not-for-merge branch 'testcommit2680' of github.com:jantman/gitpython_issue_301 -be3b63eca38e70fe48f36489aab93264ceb80c1b not-for-merge branch 'testcommit2681' of github.com:jantman/gitpython_issue_301 -51c7867a1771079e47424d9cc17611bae322584c not-for-merge branch 'testcommit2682' of github.com:jantman/gitpython_issue_301 -7b12453557681ade6898dd507d4e727afa618d77 not-for-merge branch 'testcommit2683' of github.com:jantman/gitpython_issue_301 -84a48e91705171ac379aca84c346da76f326d6cf not-for-merge branch 'testcommit2684' of github.com:jantman/gitpython_issue_301 -bdcf7a3e1acd3e33f3fcc08227907f2cb7359b3f not-for-merge branch 'testcommit2685' of github.com:jantman/gitpython_issue_301 -9538298ca2365a3f9736de6a93ea6a4bdab8defe not-for-merge branch 'testcommit2686' of github.com:jantman/gitpython_issue_301 -63560c686703299cf694bc673a941730c2bf40bd not-for-merge branch 'testcommit2687' of github.com:jantman/gitpython_issue_301 -e24c4ef040ed699e342156091719feb8a33dfed0 not-for-merge branch 'testcommit2688' of github.com:jantman/gitpython_issue_301 -fa7b2a71864006f9e8c64d53759e16bbfbca88a8 not-for-merge branch 'testcommit2689' of github.com:jantman/gitpython_issue_301 -9af1fab67eaa3b9a9ea108e1d4786cff78befb8a not-for-merge branch 'testcommit269' of github.com:jantman/gitpython_issue_301 -74e96964a8e3d2f5a3f9524d1167ce487a02796b not-for-merge branch 'testcommit2690' of github.com:jantman/gitpython_issue_301 -92f47c6638ee730d064c8cb409eca606b1ca5929 not-for-merge branch 'testcommit2691' of github.com:jantman/gitpython_issue_301 -bb8afeefbbf9294955d21fd08f862141cef0b656 not-for-merge branch 'testcommit2692' of github.com:jantman/gitpython_issue_301 -c7159e9c424273b30873f629524eae5bb8ce6301 not-for-merge branch 'testcommit2693' of github.com:jantman/gitpython_issue_301 -d0fccb4e8662379c41109af466e2404e7fb39b7d not-for-merge branch 'testcommit2694' of github.com:jantman/gitpython_issue_301 -c24d1498e8077e75a26999e3af6156bdb04b724b not-for-merge branch 'testcommit2695' of github.com:jantman/gitpython_issue_301 -a75d80e85917af7b88218c368eb202ba9400d918 not-for-merge branch 'testcommit2696' of github.com:jantman/gitpython_issue_301 -abdf2a7afe654bcac049fa46a4f74eca98fade56 not-for-merge branch 'testcommit2697' of github.com:jantman/gitpython_issue_301 -bbccfc7270f0f3431a3297bc304afd8cbfcb2d97 not-for-merge branch 'testcommit2698' of github.com:jantman/gitpython_issue_301 -fb6428efd505078c6e7b926d570a80f6f3a47113 not-for-merge branch 'testcommit2699' of github.com:jantman/gitpython_issue_301 -86444c4cebc67617880a05d97e464db7ca38c546 not-for-merge branch 'testcommit27' of github.com:jantman/gitpython_issue_301 -bdc60eee03be3b64f7cacaecc4ddf610d90f9dd9 not-for-merge branch 'testcommit270' of github.com:jantman/gitpython_issue_301 -de26f83c4efd759d47a4ad1e346720886f5ddc16 not-for-merge branch 'testcommit2700' of github.com:jantman/gitpython_issue_301 -016235c16e3b2fef12b060a0bac6162230b5443b not-for-merge branch 'testcommit2701' of github.com:jantman/gitpython_issue_301 -a8bc665e709be9ded447734fbc1fcdbf58973b36 not-for-merge branch 'testcommit2702' of github.com:jantman/gitpython_issue_301 -58664702dcb2ec5b154b4bcb866df6e880300526 not-for-merge branch 'testcommit2703' of github.com:jantman/gitpython_issue_301 -a443eb109afd8f3bfe759f1df120a364768c10e5 not-for-merge branch 'testcommit2704' of github.com:jantman/gitpython_issue_301 -dd1de412d01042f2890882b232a66fcf8f90ad2f not-for-merge branch 'testcommit2705' of github.com:jantman/gitpython_issue_301 -d931a521881b9ad881f7772d1747d3a04568cb3b not-for-merge branch 'testcommit2706' of github.com:jantman/gitpython_issue_301 -86e7796fd585d1c5b147f9c67d72495c7b267ebc not-for-merge branch 'testcommit2707' of github.com:jantman/gitpython_issue_301 -db7e7eb3277462bba1a8207279b59668e05607f8 not-for-merge branch 'testcommit2708' of github.com:jantman/gitpython_issue_301 -4cb3443760ee6a81e567e1bd9a0f76f798fbbb1c not-for-merge branch 'testcommit2709' of github.com:jantman/gitpython_issue_301 -7742b508e1d883a747d9ee94105cac74ea79e4ec not-for-merge branch 'testcommit271' of github.com:jantman/gitpython_issue_301 -0de6121a63f96569022c290424382bb3e5cc2b4a not-for-merge branch 'testcommit2710' of github.com:jantman/gitpython_issue_301 -d7a9df3fef684f3ce429bdd6c995a1785dca8982 not-for-merge branch 'testcommit2711' of github.com:jantman/gitpython_issue_301 -ec57dda0858c96bdea0bab3921492cf534c1fc36 not-for-merge branch 'testcommit2712' of github.com:jantman/gitpython_issue_301 -5bacc377869bb9ef27ab75d504627bc40a8aeab6 not-for-merge branch 'testcommit2713' of github.com:jantman/gitpython_issue_301 -f5818ec3c7fe1ea6df085b70aa65e7573a2b88f4 not-for-merge branch 'testcommit2714' of github.com:jantman/gitpython_issue_301 -a478f10013a5f41e0e34407091f78cce8f1b3cc5 not-for-merge branch 'testcommit2715' of github.com:jantman/gitpython_issue_301 -07803d7fa36152de3581a51a5f83693226075561 not-for-merge branch 'testcommit2716' of github.com:jantman/gitpython_issue_301 -283f5f7f8f5665a2b7de5d1031ee79cd3d11ff4c not-for-merge branch 'testcommit2717' of github.com:jantman/gitpython_issue_301 -e8f2143a073a38d778098dd1a1daf01df9c0ead5 not-for-merge branch 'testcommit2718' of github.com:jantman/gitpython_issue_301 -0f112673877298bd3bd605114ad8c1b2cf43dc7a not-for-merge branch 'testcommit2719' of github.com:jantman/gitpython_issue_301 -035812528689be89881b8ec09e21737c7955995d not-for-merge branch 'testcommit272' of github.com:jantman/gitpython_issue_301 -e3149e6672d27980097dea1245199656b6176faa not-for-merge branch 'testcommit2720' of github.com:jantman/gitpython_issue_301 -2fb5c6d8aebe7fe6328163f40bae46a9854d85c1 not-for-merge branch 'testcommit2721' of github.com:jantman/gitpython_issue_301 -b7456b3ae93086407e552cadc415eda203c24358 not-for-merge branch 'testcommit2722' of github.com:jantman/gitpython_issue_301 -4e42c57ee519d14f7ec027dffe2be48bdbc7daac not-for-merge branch 'testcommit2723' of github.com:jantman/gitpython_issue_301 -927845166fc8e31757cfa1c9c4249ebb31a522a4 not-for-merge branch 'testcommit2724' of github.com:jantman/gitpython_issue_301 -e68a346325aa25becc92f9b9a10db604a48d8881 not-for-merge branch 'testcommit2725' of github.com:jantman/gitpython_issue_301 -609b151484bd05209fb1ef8c946b729c12d4f56c not-for-merge branch 'testcommit2726' of github.com:jantman/gitpython_issue_301 -c534af6312aed0f6d8cb5285824aa2eda4caf09a not-for-merge branch 'testcommit2727' of github.com:jantman/gitpython_issue_301 -c661785bbbc1c7eaed3d4e11a659fb8b20910423 not-for-merge branch 'testcommit2728' of github.com:jantman/gitpython_issue_301 -1e1ffafff1120407cafa9d4cdef0bd2ee0961f9a not-for-merge branch 'testcommit2729' of github.com:jantman/gitpython_issue_301 -ec5db5ba7bf31c8fed3e077fc4e4428e55bd937b not-for-merge branch 'testcommit273' of github.com:jantman/gitpython_issue_301 -a516a24619e590a89e54a0866050d1443490b447 not-for-merge branch 'testcommit2730' of github.com:jantman/gitpython_issue_301 -6219988603450d46d50fd59a6ed21500212f312d not-for-merge branch 'testcommit2731' of github.com:jantman/gitpython_issue_301 -89a06adc73c37228f217c238e70898df46ce27b9 not-for-merge branch 'testcommit2732' of github.com:jantman/gitpython_issue_301 -155e19bdecedc58f2ca66ac38a8631b225a1e68d not-for-merge branch 'testcommit2733' of github.com:jantman/gitpython_issue_301 -3a8b1a870e538c0317f03df5ed818f79b47a262f not-for-merge branch 'testcommit2734' of github.com:jantman/gitpython_issue_301 -c0dab4e6717c07af103823d7646b0e1f3b263ec5 not-for-merge branch 'testcommit2735' of github.com:jantman/gitpython_issue_301 -b0f635202391d9fec2ad7136e7d098329c67c68d not-for-merge branch 'testcommit2736' of github.com:jantman/gitpython_issue_301 -1373da2e4254b55791746c2159c5e6da5753a793 not-for-merge branch 'testcommit2737' of github.com:jantman/gitpython_issue_301 -909d20a90a555d603e4f1cfb752adc47a6278cf7 not-for-merge branch 'testcommit2738' of github.com:jantman/gitpython_issue_301 -4d49e4a988b4aef58e6d3a822829ed1083866941 not-for-merge branch 'testcommit2739' of github.com:jantman/gitpython_issue_301 -8b8788798939ef345f6ad148732befd1de9ab2d2 not-for-merge branch 'testcommit274' of github.com:jantman/gitpython_issue_301 -a547eb02b189c22c391b88a640e91fda0a2087bb not-for-merge branch 'testcommit2740' of github.com:jantman/gitpython_issue_301 -ac280a16a4670388dd00014cfdabcf54e6fabaf3 not-for-merge branch 'testcommit2741' of github.com:jantman/gitpython_issue_301 -27992a11520a0fdef876683a22092b32d4251421 not-for-merge branch 'testcommit2742' of github.com:jantman/gitpython_issue_301 -6cefc7759c71a19a82d39b9cf472ce96a7481c3a not-for-merge branch 'testcommit2743' of github.com:jantman/gitpython_issue_301 -b7f30ab3c5d43499d50b2ee584ddec438cdf09c0 not-for-merge branch 'testcommit2744' of github.com:jantman/gitpython_issue_301 -023f9a33118b8a0a8f463519aa206641f0ad2ec1 not-for-merge branch 'testcommit2745' of github.com:jantman/gitpython_issue_301 -2db9231127b08684799009d64d329e675f599e66 not-for-merge branch 'testcommit2746' of github.com:jantman/gitpython_issue_301 -3dd1ecc41233793f087029fc3357d461b86e7ceb not-for-merge branch 'testcommit2747' of github.com:jantman/gitpython_issue_301 -873dd50bab8c3f3cba8e84b8110544f01c7d6902 not-for-merge branch 'testcommit2748' of github.com:jantman/gitpython_issue_301 -956d1e251cec402289af0bf7e180741298c923ab not-for-merge branch 'testcommit2749' of github.com:jantman/gitpython_issue_301 -477d03bc58fa8c59b03462f44fc10fd987a74054 not-for-merge branch 'testcommit275' of github.com:jantman/gitpython_issue_301 -f2b70c7e86776cfa22a58b244273504a11efd5b0 not-for-merge branch 'testcommit2750' of github.com:jantman/gitpython_issue_301 -925b538be48bd1edaa56bcf19f05956f0f6316ea not-for-merge branch 'testcommit2751' of github.com:jantman/gitpython_issue_301 -f412bad2aaee04a094c36b85ebeb7b5ab3eb991d not-for-merge branch 'testcommit2752' of github.com:jantman/gitpython_issue_301 -c7587fcc8f1eb94cab32acd40de77547369d704b not-for-merge branch 'testcommit2753' of github.com:jantman/gitpython_issue_301 -c89b3d790ce8c437607087567662fa763fcc311c not-for-merge branch 'testcommit2754' of github.com:jantman/gitpython_issue_301 -c83ae4b35822e78fe1be4631cee0608b664a292f not-for-merge branch 'testcommit2755' of github.com:jantman/gitpython_issue_301 -f00e1c7858ec32818e89f2d38657bf6c0a516eb7 not-for-merge branch 'testcommit2756' of github.com:jantman/gitpython_issue_301 -087ed30400590e1daad14505a1404c96de62f961 not-for-merge branch 'testcommit2757' of github.com:jantman/gitpython_issue_301 -06cb5d1b0ae16206b1003ded7db4e72e2fed95b2 not-for-merge branch 'testcommit2758' of github.com:jantman/gitpython_issue_301 -66a79aa83488a1cd179bdc2e0fc5371074e6a0fe not-for-merge branch 'testcommit2759' of github.com:jantman/gitpython_issue_301 -8df0be89ec1439e3a516d2ca645d33e97caa2689 not-for-merge branch 'testcommit276' of github.com:jantman/gitpython_issue_301 -5b90ea29f31d9bc5b270e05058bdbaa5b6ba9150 not-for-merge branch 'testcommit2760' of github.com:jantman/gitpython_issue_301 -ad9984635ee7e17c1b1c4d9de3e7e367a8a3e861 not-for-merge branch 'testcommit2761' of github.com:jantman/gitpython_issue_301 -f010a2da6865e00079778b3cfe805e46ba60861b not-for-merge branch 'testcommit2762' of github.com:jantman/gitpython_issue_301 -421b6b8dbfb7839eecae249860138ab71c95a850 not-for-merge branch 'testcommit2763' of github.com:jantman/gitpython_issue_301 -6cf0b6323bc07b85884a65d1d57ca05d3d9ba9e2 not-for-merge branch 'testcommit2764' of github.com:jantman/gitpython_issue_301 -583dbe12667f76f42af7bea0b5b20d3111a9f954 not-for-merge branch 'testcommit2765' of github.com:jantman/gitpython_issue_301 -5400094de2a040f58add91b4a95f35130d411dfe not-for-merge branch 'testcommit2766' of github.com:jantman/gitpython_issue_301 -10881284f090720529dedff6fffb2734c54b4c90 not-for-merge branch 'testcommit2767' of github.com:jantman/gitpython_issue_301 -0964c71aaaf0a65258d0f3933fbe570e6b4fb7de not-for-merge branch 'testcommit2768' of github.com:jantman/gitpython_issue_301 -a6889b94b9e1119824ac1956907487a5136ea430 not-for-merge branch 'testcommit2769' of github.com:jantman/gitpython_issue_301 -0e258afeb12f7fa6b5cd57cd94e27bdc1b51845d not-for-merge branch 'testcommit277' of github.com:jantman/gitpython_issue_301 -897d82cfccd7da726b95dffc511fc0d2a77248d6 not-for-merge branch 'testcommit2770' of github.com:jantman/gitpython_issue_301 -204658991b5b32471a98c984150160f0180b66d0 not-for-merge branch 'testcommit2771' of github.com:jantman/gitpython_issue_301 -e65bf4f95303bf1f47b0e62a8fca0d0fcda832b0 not-for-merge branch 'testcommit2772' of github.com:jantman/gitpython_issue_301 -1b9d8323fe0358b796fa1f3561617123111672ff not-for-merge branch 'testcommit2773' of github.com:jantman/gitpython_issue_301 -e50473a5f64b865ab34a693bb5e257bd1592d26a not-for-merge branch 'testcommit2774' of github.com:jantman/gitpython_issue_301 -e2579b9a36080c8e292f1034ec74b6aec5e46aa5 not-for-merge branch 'testcommit2775' of github.com:jantman/gitpython_issue_301 -16fe622481f729172e1cb7704e561727e480654c not-for-merge branch 'testcommit2776' of github.com:jantman/gitpython_issue_301 -9c280129dbbf0b7e5f4019caa555d6cf3a4007ef not-for-merge branch 'testcommit2777' of github.com:jantman/gitpython_issue_301 -1795991e54abd633ca64594400f330eea2e2a27c not-for-merge branch 'testcommit2778' of github.com:jantman/gitpython_issue_301 -72a215758e23ab980c89b97011cc5b5e6b10a19c not-for-merge branch 'testcommit2779' of github.com:jantman/gitpython_issue_301 -67fd7727b4369f200f2eeeb50450c11221582537 not-for-merge branch 'testcommit278' of github.com:jantman/gitpython_issue_301 -02716c9cfec93f1f08a4c0bfeaf1aff58083212b not-for-merge branch 'testcommit2780' of github.com:jantman/gitpython_issue_301 -70676f8847aeb07923edfb21b2dfb5eade2e2b6f not-for-merge branch 'testcommit2781' of github.com:jantman/gitpython_issue_301 -803364d253a90b4a8170fce874608e82e8385910 not-for-merge branch 'testcommit2782' of github.com:jantman/gitpython_issue_301 -b1ca2933b2138feb9b61d5d75b339831570b30f2 not-for-merge branch 'testcommit2783' of github.com:jantman/gitpython_issue_301 -af05f0faa36baaac6dd47b3072c58400cde5f224 not-for-merge branch 'testcommit2784' of github.com:jantman/gitpython_issue_301 -ac0a7f21f0b23fef9660e75aa999b82637e18b84 not-for-merge branch 'testcommit2785' of github.com:jantman/gitpython_issue_301 -02393139cb60d1704928338e3100e8c13d2328a4 not-for-merge branch 'testcommit2786' of github.com:jantman/gitpython_issue_301 -7316fd058fe6eb44fc327d3789d7099424bf25dd not-for-merge branch 'testcommit2787' of github.com:jantman/gitpython_issue_301 -469632325ebf3d08d7446a0e66883f84988686c8 not-for-merge branch 'testcommit2788' of github.com:jantman/gitpython_issue_301 -9fa2adc9160008673283c5434cc1d741de1e94e2 not-for-merge branch 'testcommit2789' of github.com:jantman/gitpython_issue_301 -cc60365a311424117593f615fd3aeb22d8205c5c not-for-merge branch 'testcommit279' of github.com:jantman/gitpython_issue_301 -214513b925a30204902d04169b821fe9a180534e not-for-merge branch 'testcommit2790' of github.com:jantman/gitpython_issue_301 -c8db2a432d55148404dad501de4748d0dce02959 not-for-merge branch 'testcommit2791' of github.com:jantman/gitpython_issue_301 -d0bd4211a76785bee781b9dd01529fac1f6301cb not-for-merge branch 'testcommit2792' of github.com:jantman/gitpython_issue_301 -54fdf6337efc7fd52c991691950f6e031afdb6c7 not-for-merge branch 'testcommit2793' of github.com:jantman/gitpython_issue_301 -9165edda237827b716ad1ecf6d346939b1104d80 not-for-merge branch 'testcommit2794' of github.com:jantman/gitpython_issue_301 -757377d84877e476f0637ab7a08f3862923d335a not-for-merge branch 'testcommit2795' of github.com:jantman/gitpython_issue_301 -0da9eb322ffefb66e35eb0af4dddaa7d43133666 not-for-merge branch 'testcommit2796' of github.com:jantman/gitpython_issue_301 -0581b81f81a4b9f6c7eee9011b7841d666131b27 not-for-merge branch 'testcommit2797' of github.com:jantman/gitpython_issue_301 -4c77cd3af6303d4e2d0ec6fc18958cbbd40beb2f not-for-merge branch 'testcommit2798' of github.com:jantman/gitpython_issue_301 -ff8de229133309d6afafc3d06bfa1ab2d2568168 not-for-merge branch 'testcommit2799' of github.com:jantman/gitpython_issue_301 -ac487289a5508d904dda5de4b2340469e866627c not-for-merge branch 'testcommit28' of github.com:jantman/gitpython_issue_301 -5bbe390a67502cc508b405490ca3007c8a3bab96 not-for-merge branch 'testcommit280' of github.com:jantman/gitpython_issue_301 -fd8e9a39a438f7a06475fe4adc801781db0b20d5 not-for-merge branch 'testcommit2800' of github.com:jantman/gitpython_issue_301 -a1c2e86465d6faac7b9544c588ff8f8f6f081758 not-for-merge branch 'testcommit2801' of github.com:jantman/gitpython_issue_301 -a38f94d87d261dfe6ec5411a3cc25e99e144a147 not-for-merge branch 'testcommit2802' of github.com:jantman/gitpython_issue_301 -2659c6ae1147254044797821d4a53e8d5b869a01 not-for-merge branch 'testcommit2803' of github.com:jantman/gitpython_issue_301 -bed4d7147ffaf84aeb0e302b0f2319756838f5fd not-for-merge branch 'testcommit2804' of github.com:jantman/gitpython_issue_301 -084c13f0d1a6d1d5dfdb7bb51807b6fe030772ca not-for-merge branch 'testcommit2805' of github.com:jantman/gitpython_issue_301 -c552623708d02901c5179e0a175c5f7be1586ed7 not-for-merge branch 'testcommit2806' of github.com:jantman/gitpython_issue_301 -9f738d021a38717a4d5e4ca979231fcea5c04c0d not-for-merge branch 'testcommit2807' of github.com:jantman/gitpython_issue_301 -47dd034e5ce727d7a167e405b52f1bb8212a693f not-for-merge branch 'testcommit2808' of github.com:jantman/gitpython_issue_301 -57f633c9b4ad4aeb0dbb54a18ec664499359af88 not-for-merge branch 'testcommit2809' of github.com:jantman/gitpython_issue_301 -ceea04a47f441c8c6d5d8e7f7cee1c8e082994cf not-for-merge branch 'testcommit281' of github.com:jantman/gitpython_issue_301 -dfcd67c70f5aee8ba896a49ee834974b4374e07e not-for-merge branch 'testcommit2810' of github.com:jantman/gitpython_issue_301 -f8a27a4b63fc44101789f6191c38d71f3a9a8402 not-for-merge branch 'testcommit2811' of github.com:jantman/gitpython_issue_301 -a947df6f494ac57c03410ac4f227a947a918951c not-for-merge branch 'testcommit2812' of github.com:jantman/gitpython_issue_301 -98c97d1cdb1e759be79579e48c2a277f37dad5a2 not-for-merge branch 'testcommit2813' of github.com:jantman/gitpython_issue_301 -88e7b9ca6b698d8ee3473bd4990349cdae5a0028 not-for-merge branch 'testcommit2814' of github.com:jantman/gitpython_issue_301 -3a3f5ed3cd30319ce9bb067674c40bd713e6280f not-for-merge branch 'testcommit2815' of github.com:jantman/gitpython_issue_301 -f27cd7d4386f4b75df4972b86ce81e767a4061a6 not-for-merge branch 'testcommit2816' of github.com:jantman/gitpython_issue_301 -9b4d0352f135fdceda3ff49dfcdd82795c0eb6e6 not-for-merge branch 'testcommit2817' of github.com:jantman/gitpython_issue_301 -e168108728ca92d06e4d05b56e371ee4f5683463 not-for-merge branch 'testcommit2818' of github.com:jantman/gitpython_issue_301 -ea4903e182d7915f8ed7276169608de7810b0c50 not-for-merge branch 'testcommit2819' of github.com:jantman/gitpython_issue_301 -dafa72ad2f875a258f7af83c42f8140bad0f7d74 not-for-merge branch 'testcommit282' of github.com:jantman/gitpython_issue_301 -3bb0edf31d30a47aa8eed04a86ca7b3cb7cc41ee not-for-merge branch 'testcommit2820' of github.com:jantman/gitpython_issue_301 -fda67e2fe38848b5de5c8d455ffea646a3d2a39a not-for-merge branch 'testcommit2821' of github.com:jantman/gitpython_issue_301 -628d25311a7bd83f152b59899a07f73ad7dca2c3 not-for-merge branch 'testcommit2822' of github.com:jantman/gitpython_issue_301 -68983f508954e0239e8b2f90ae5709bdb9d188fb not-for-merge branch 'testcommit2823' of github.com:jantman/gitpython_issue_301 -3a2a9c0bae785899637ff4f348e45e13b658e1a5 not-for-merge branch 'testcommit2824' of github.com:jantman/gitpython_issue_301 -269723ed7f27d60891f63ec518597577022ae377 not-for-merge branch 'testcommit2825' of github.com:jantman/gitpython_issue_301 -c298f7918dbab068e7cbd3b1330e1134c02306da not-for-merge branch 'testcommit2826' of github.com:jantman/gitpython_issue_301 -b3c60a0f0132b77ba51f637e6abe199a702d0447 not-for-merge branch 'testcommit2827' of github.com:jantman/gitpython_issue_301 -ca3963f474bcd248106d47c7d3b78233466c85a9 not-for-merge branch 'testcommit2828' of github.com:jantman/gitpython_issue_301 -ad6f8527271c6e96f48e28a9009adced69c01a4b not-for-merge branch 'testcommit2829' of github.com:jantman/gitpython_issue_301 -622b626d0714a2a94d8e2e119bcc052976887e8b not-for-merge branch 'testcommit283' of github.com:jantman/gitpython_issue_301 -8a12df8988d15378c586cc4577af90bebcefd06f not-for-merge branch 'testcommit2830' of github.com:jantman/gitpython_issue_301 -3ede9bb472dd3732b0ed3b081782986da0130964 not-for-merge branch 'testcommit2831' of github.com:jantman/gitpython_issue_301 -33672258d1dd731513d08cccc0e0ee7cf19f2346 not-for-merge branch 'testcommit2832' of github.com:jantman/gitpython_issue_301 -482f30671610f776f2180f59583ae638abf6f401 not-for-merge branch 'testcommit2833' of github.com:jantman/gitpython_issue_301 -40f02ac1c274ca7976338a935baee735cdf29620 not-for-merge branch 'testcommit2834' of github.com:jantman/gitpython_issue_301 -ae7f18a9fb2d2b0f6f882c890838ca8f30fb61ad not-for-merge branch 'testcommit2835' of github.com:jantman/gitpython_issue_301 -27d41a004c6c9498a8968055c63e1d5bdf2de2b5 not-for-merge branch 'testcommit2836' of github.com:jantman/gitpython_issue_301 -68b6410688f18411c29a4098dddd4eed6c738ddd not-for-merge branch 'testcommit2837' of github.com:jantman/gitpython_issue_301 -7f410b0f4b96c8a01f2ca8cf08ba18333d53a9ba not-for-merge branch 'testcommit2838' of github.com:jantman/gitpython_issue_301 -917d3e52e9989da8f8744355497df273add0895b not-for-merge branch 'testcommit2839' of github.com:jantman/gitpython_issue_301 -b484f30f09c92a1e320a008c535206724baaed48 not-for-merge branch 'testcommit284' of github.com:jantman/gitpython_issue_301 -6e06949a3d9a9aab247abb210dc307a8d2d6f40a not-for-merge branch 'testcommit2840' of github.com:jantman/gitpython_issue_301 -ab0b8f65183595171e23b3e38a0d8e67584938f3 not-for-merge branch 'testcommit2841' of github.com:jantman/gitpython_issue_301 -37af590319369a8bd9f95d1401fa0ee7fcdab202 not-for-merge branch 'testcommit2842' of github.com:jantman/gitpython_issue_301 -b74bd0f49f33e968f04070b3f61c6548c783f923 not-for-merge branch 'testcommit2843' of github.com:jantman/gitpython_issue_301 -e0a2e0b9767393cd14225d5bfa15eaac2273a032 not-for-merge branch 'testcommit2844' of github.com:jantman/gitpython_issue_301 -bed0c832d9bb1844e120054954f58735d3c50276 not-for-merge branch 'testcommit2845' of github.com:jantman/gitpython_issue_301 -e15b6ee7c80701a89a9cb8fc185c54c974f4505a not-for-merge branch 'testcommit2846' of github.com:jantman/gitpython_issue_301 -32828f07ce2dbea52d79829e055084a9b9611168 not-for-merge branch 'testcommit2847' of github.com:jantman/gitpython_issue_301 -3a995e58c1912783f9aaece7239d62e32c0f1c19 not-for-merge branch 'testcommit2848' of github.com:jantman/gitpython_issue_301 -a345b752f0cc947574402db6dc3e8884f605a210 not-for-merge branch 'testcommit2849' of github.com:jantman/gitpython_issue_301 -3c103af086db7fb74afaec94552fabbf21804524 not-for-merge branch 'testcommit285' of github.com:jantman/gitpython_issue_301 -7d0b1886f53e9d24b21bee6c8a38503f2a2d3ea9 not-for-merge branch 'testcommit2850' of github.com:jantman/gitpython_issue_301 -6ad5c1e2adae6f4a3890820f5b2ad3888b3e058e not-for-merge branch 'testcommit2851' of github.com:jantman/gitpython_issue_301 -900146a079d65fde506e5e3b7a66263098122f93 not-for-merge branch 'testcommit2852' of github.com:jantman/gitpython_issue_301 -ef629c25fd85612ea2c76f753aeb86a79b333a88 not-for-merge branch 'testcommit2853' of github.com:jantman/gitpython_issue_301 -0df22f4a33372214ef7963be483e85584bcc6ded not-for-merge branch 'testcommit2854' of github.com:jantman/gitpython_issue_301 -4db5d31321e5ba6d2dfb86908315f99c345c00cb not-for-merge branch 'testcommit2855' of github.com:jantman/gitpython_issue_301 -343cfe3f3882a7549e9899e0ec454feec29a9d4e not-for-merge branch 'testcommit2856' of github.com:jantman/gitpython_issue_301 -2e944c2af6041eb9e9b33a2d0969a32db95a334e not-for-merge branch 'testcommit2857' of github.com:jantman/gitpython_issue_301 -60a1ec72b04d0b60043af211d93c91ed48d09b8d not-for-merge branch 'testcommit2858' of github.com:jantman/gitpython_issue_301 -7304503cef189fecffbb02dde90338d5f6ad93da not-for-merge branch 'testcommit2859' of github.com:jantman/gitpython_issue_301 -c9384375bb2d2871f74744c4977163816b6450d5 not-for-merge branch 'testcommit286' of github.com:jantman/gitpython_issue_301 -3fa7ef58ead134e17834c7f1b3562f2a0a0fe878 not-for-merge branch 'testcommit2860' of github.com:jantman/gitpython_issue_301 -b30345cb9027b2c40f4e65d3ca47a16293800947 not-for-merge branch 'testcommit2861' of github.com:jantman/gitpython_issue_301 -6011bae92ec840e6ab5a29f1d8c48552d9ce2d6e not-for-merge branch 'testcommit2862' of github.com:jantman/gitpython_issue_301 -15b34d89d00c600df73691eee3b8d4cd816bd12b not-for-merge branch 'testcommit2863' of github.com:jantman/gitpython_issue_301 -674034cf8ab7faeca34f80b1fec36ef720792f97 not-for-merge branch 'testcommit2864' of github.com:jantman/gitpython_issue_301 -8d42442fd5c9d642cebcd998d0807c6382478c81 not-for-merge branch 'testcommit2865' of github.com:jantman/gitpython_issue_301 -9a0c0d5a4eea720cd5b61ad7462ed8b0d83eb1b2 not-for-merge branch 'testcommit2866' of github.com:jantman/gitpython_issue_301 -4a533b4cf48340c5c710c71cdda1e93dc2a8c10f not-for-merge branch 'testcommit2867' of github.com:jantman/gitpython_issue_301 -09cb947106e850ad6c3b7eb031748cc189f17ce3 not-for-merge branch 'testcommit2868' of github.com:jantman/gitpython_issue_301 -b15752e5e49ff9d89ad656b4da5dd41ea3af00a9 not-for-merge branch 'testcommit2869' of github.com:jantman/gitpython_issue_301 -3747ad166e7dac24d174af1de9118a98d17601f3 not-for-merge branch 'testcommit287' of github.com:jantman/gitpython_issue_301 -ed29d7f32123a398242d38c1eed148e66db431c8 not-for-merge branch 'testcommit2870' of github.com:jantman/gitpython_issue_301 -87b084adfb447371deab02c91edebdf79054874e not-for-merge branch 'testcommit2871' of github.com:jantman/gitpython_issue_301 -7f05fa54821e0a57da951400df41125d448ff037 not-for-merge branch 'testcommit2872' of github.com:jantman/gitpython_issue_301 -466af9206d347fe2dfc5a1fa9105a52a07987a5a not-for-merge branch 'testcommit2873' of github.com:jantman/gitpython_issue_301 -4692bb889b2ba3cda3ad679e579ca2cb75a735da not-for-merge branch 'testcommit2874' of github.com:jantman/gitpython_issue_301 -5331c826921a162831b5d9ca31cdbeb9f39dba8a not-for-merge branch 'testcommit2875' of github.com:jantman/gitpython_issue_301 -0c8a45501a40a4c8093f8eaeb99d94ce86148f3e not-for-merge branch 'testcommit2876' of github.com:jantman/gitpython_issue_301 -297971f48158e36843075e079316e5ed09d9a7a6 not-for-merge branch 'testcommit2877' of github.com:jantman/gitpython_issue_301 -aaa6ce4320523cbc43a956223c3a155433e4b4fa not-for-merge branch 'testcommit2878' of github.com:jantman/gitpython_issue_301 -6bba2b29b8e68d3000d92629cd9d9b96269c8dde not-for-merge branch 'testcommit2879' of github.com:jantman/gitpython_issue_301 -ca6a252bfed0319fe92e8e975a0223b1dd5bcf99 not-for-merge branch 'testcommit288' of github.com:jantman/gitpython_issue_301 -02c8ea7be9206ae07da5456114c947275b6660c4 not-for-merge branch 'testcommit2880' of github.com:jantman/gitpython_issue_301 -0ba86126d3c78f7d0fb60bdf848a3bf9cada6120 not-for-merge branch 'testcommit2881' of github.com:jantman/gitpython_issue_301 -48c11f09d3fd249e73b08865137ed7324fec8466 not-for-merge branch 'testcommit2882' of github.com:jantman/gitpython_issue_301 -18568b8bd04369d9521ca53a0383a9012362b5d1 not-for-merge branch 'testcommit2883' of github.com:jantman/gitpython_issue_301 -e041337dd1dd87005a0d37ab1b1872daece98a62 not-for-merge branch 'testcommit2884' of github.com:jantman/gitpython_issue_301 -83b39cbd328f77066289c0c36d89853f49e8425d not-for-merge branch 'testcommit2885' of github.com:jantman/gitpython_issue_301 -7e90eb75ac079c885c0abac5c7d75fcc47cff6d3 not-for-merge branch 'testcommit2886' of github.com:jantman/gitpython_issue_301 -a1a7ecd2be754616ef84d593302f0fd09ee55b69 not-for-merge branch 'testcommit2887' of github.com:jantman/gitpython_issue_301 -5abdcbef7aeb73a88ad11b599f3008634246d556 not-for-merge branch 'testcommit2888' of github.com:jantman/gitpython_issue_301 -0bbae08c46ee0f15d1155306f6cfd61b2174f171 not-for-merge branch 'testcommit2889' of github.com:jantman/gitpython_issue_301 -21ef1f0cb44604673582d5e0663a988ee7468a00 not-for-merge branch 'testcommit289' of github.com:jantman/gitpython_issue_301 -f15cc9c806b362a2c21bb837007fd94be1e3584c not-for-merge branch 'testcommit2890' of github.com:jantman/gitpython_issue_301 -d3cdeec77dbd1eb4d0a5b1373e98b7419a1e8259 not-for-merge branch 'testcommit2891' of github.com:jantman/gitpython_issue_301 -4e02181459903e9e6d8e22eb51b80df1fc2ae783 not-for-merge branch 'testcommit2892' of github.com:jantman/gitpython_issue_301 -e13f8ae70937c4da439fe77835de7aa944aed172 not-for-merge branch 'testcommit2893' of github.com:jantman/gitpython_issue_301 -cb0681da02959190104499bba48da7f11ec5b38a not-for-merge branch 'testcommit2894' of github.com:jantman/gitpython_issue_301 -b4bbebaf8af5dfc9871e205bcdbe73a6f0253319 not-for-merge branch 'testcommit2895' of github.com:jantman/gitpython_issue_301 -afa1646cdef2004aa8d555ddba9020c67d5c3628 not-for-merge branch 'testcommit2896' of github.com:jantman/gitpython_issue_301 -ce0a95687ad9bb048a4e235ffa87325341fd9576 not-for-merge branch 'testcommit2897' of github.com:jantman/gitpython_issue_301 -c0703465282cecf9c7c9ec88de9897a46096c783 not-for-merge branch 'testcommit2898' of github.com:jantman/gitpython_issue_301 -62934bbbe1a7df6965e7d788a0cc302b386338f0 not-for-merge branch 'testcommit2899' of github.com:jantman/gitpython_issue_301 -ccc0c35ea5f4542d987bcb6674851c7d5e65f305 not-for-merge branch 'testcommit29' of github.com:jantman/gitpython_issue_301 -1382bfdc94bc2f4997bd3a6b7b88ec7d27f8687f not-for-merge branch 'testcommit290' of github.com:jantman/gitpython_issue_301 -c08dc997a702a5422d3e7cd9f908c65a6cfda2ed not-for-merge branch 'testcommit2900' of github.com:jantman/gitpython_issue_301 -0ff54628f7d5edf593b2e953d50122ce1ed9308c not-for-merge branch 'testcommit2901' of github.com:jantman/gitpython_issue_301 -520d3e5f6e2591939eac5ee49f3ee73325eb52e6 not-for-merge branch 'testcommit2902' of github.com:jantman/gitpython_issue_301 -8d78f0bd1b133424c0fdbe70b6f858cc652f3436 not-for-merge branch 'testcommit2903' of github.com:jantman/gitpython_issue_301 -0715c2ed051b27907a9f6a46717ad69740d7b1b4 not-for-merge branch 'testcommit2904' of github.com:jantman/gitpython_issue_301 -580733c810691a4ed33bd32cca33c37c055e2397 not-for-merge branch 'testcommit2905' of github.com:jantman/gitpython_issue_301 -daa1c9acce05bfdda83ac18f921f105fd351df09 not-for-merge branch 'testcommit2906' of github.com:jantman/gitpython_issue_301 -2d4e6d0eea0bd497d83ab9e097c998445490d5f5 not-for-merge branch 'testcommit2907' of github.com:jantman/gitpython_issue_301 -3c6291c874d509f7cd43f60282f86a8914237acb not-for-merge branch 'testcommit2908' of github.com:jantman/gitpython_issue_301 -fc26c1bca0bc8c19289e3271ad39b73357396132 not-for-merge branch 'testcommit2909' of github.com:jantman/gitpython_issue_301 -d835f7de8ff055a9728eea14f9c375b44a86dbaf not-for-merge branch 'testcommit291' of github.com:jantman/gitpython_issue_301 -77c48739fb3b67370f9aec52d59eb29a72d1d3b3 not-for-merge branch 'testcommit2910' of github.com:jantman/gitpython_issue_301 -a0055e5cb2462980dd510811c7776a4a292ef02d not-for-merge branch 'testcommit2911' of github.com:jantman/gitpython_issue_301 -8673a8e73c3e566b8f3151e68e268d9f94ba6d3d not-for-merge branch 'testcommit2912' of github.com:jantman/gitpython_issue_301 -1ed8f63a00d8fc2444d403e58fff649b78b96ce5 not-for-merge branch 'testcommit2913' of github.com:jantman/gitpython_issue_301 -b81c15f3b300abe7ca6405ed322a7f01b462b2b4 not-for-merge branch 'testcommit2914' of github.com:jantman/gitpython_issue_301 -f5cf70a1d7a7992167a14d5014c1bd92878704cc not-for-merge branch 'testcommit2915' of github.com:jantman/gitpython_issue_301 -fc45bb13086a345f707f9eb30b5cd6ae8f90f7e4 not-for-merge branch 'testcommit2916' of github.com:jantman/gitpython_issue_301 -ea2f299ad6c61dfcaa833275bcfd002364981d1d not-for-merge branch 'testcommit2917' of github.com:jantman/gitpython_issue_301 -ac1b8138ecc96ae5019e7a6c3fd1b7aa974d9f9d not-for-merge branch 'testcommit2918' of github.com:jantman/gitpython_issue_301 -65dc2912a9285c0d91dc465ff71181639816204d not-for-merge branch 'testcommit2919' of github.com:jantman/gitpython_issue_301 -6cc730bcd56a4e847085e8cd83f3ff639836aadd not-for-merge branch 'testcommit292' of github.com:jantman/gitpython_issue_301 -3e07cfea837a25e73901febc2ed9841a32969a39 not-for-merge branch 'testcommit2920' of github.com:jantman/gitpython_issue_301 -9326f9b6dfce0f159893d3779b6c0c704f9dd4bb not-for-merge branch 'testcommit2921' of github.com:jantman/gitpython_issue_301 -d36bf8189245a5feb948550df1d8598202620209 not-for-merge branch 'testcommit2922' of github.com:jantman/gitpython_issue_301 -d86d7c1b97684340363882706a1fd08bd6fbeca5 not-for-merge branch 'testcommit2923' of github.com:jantman/gitpython_issue_301 -7b47063e07380a5834ead0970c5ffca5f6156613 not-for-merge branch 'testcommit2924' of github.com:jantman/gitpython_issue_301 -67a6f03902b9b936143a0255244b6f72ea966c29 not-for-merge branch 'testcommit2925' of github.com:jantman/gitpython_issue_301 -667c739b09f3ff099462bbad74c1bc9d20686be1 not-for-merge branch 'testcommit2926' of github.com:jantman/gitpython_issue_301 -15c18b4e7d91fbb22a52e0166b6bbbd8fe253dc2 not-for-merge branch 'testcommit2927' of github.com:jantman/gitpython_issue_301 -32ded4ff465798576b5d1f5bc8b1a55b7fd36a60 not-for-merge branch 'testcommit2928' of github.com:jantman/gitpython_issue_301 -89feb483c3a9c5fc485c00bdcdf006d5c4bb2675 not-for-merge branch 'testcommit2929' of github.com:jantman/gitpython_issue_301 -f814acd6f91c60bd72e481f8f501533a1c4cbbf3 not-for-merge branch 'testcommit293' of github.com:jantman/gitpython_issue_301 -aa201cb305498658bea583a4136ab402cbae788e not-for-merge branch 'testcommit2930' of github.com:jantman/gitpython_issue_301 -955a556baa34a4a29169c594d044726f5d4621f3 not-for-merge branch 'testcommit2931' of github.com:jantman/gitpython_issue_301 -839b7ef257046f3cf6c450e116b37f57e9b8aa2b not-for-merge branch 'testcommit2932' of github.com:jantman/gitpython_issue_301 -1cf7e05544e7ba2d4c2e1634bf2fa1c75bcedd08 not-for-merge branch 'testcommit2933' of github.com:jantman/gitpython_issue_301 -08300d00c28fed43aa12a143c682388fe98e1005 not-for-merge branch 'testcommit2934' of github.com:jantman/gitpython_issue_301 -69073155283d786f3b3bc04c6387bbaf09be8998 not-for-merge branch 'testcommit2935' of github.com:jantman/gitpython_issue_301 -d124d0be158563f7af88ce853df0d8536a8e3fda not-for-merge branch 'testcommit2936' of github.com:jantman/gitpython_issue_301 -3dfe5dae560fe84429b016e9dd8caf92161d09d9 not-for-merge branch 'testcommit2937' of github.com:jantman/gitpython_issue_301 -c454cfef0849c05665e2a563acc661717a4f512f not-for-merge branch 'testcommit2938' of github.com:jantman/gitpython_issue_301 -088064dfd953e953a52825743bf28614bc9d99f4 not-for-merge branch 'testcommit2939' of github.com:jantman/gitpython_issue_301 -90d5b105d0627e338bbab6928f6c9239ebdd6b85 not-for-merge branch 'testcommit294' of github.com:jantman/gitpython_issue_301 -336e66de13b7885006e5b1f9ad7defeaf894c425 not-for-merge branch 'testcommit2940' of github.com:jantman/gitpython_issue_301 -2b14903dc1b925e2daa419d1dbbca7e9da4adc01 not-for-merge branch 'testcommit2941' of github.com:jantman/gitpython_issue_301 -ac30937dfa64b4cb66170031e82a5d3ee4f4c56a not-for-merge branch 'testcommit2942' of github.com:jantman/gitpython_issue_301 -65ba353eb4b2c7d7de1eafaf9bc49903b4b4ddb2 not-for-merge branch 'testcommit2943' of github.com:jantman/gitpython_issue_301 -9d575797fb4fe7688bfa5e6f29697a1f71db63f3 not-for-merge branch 'testcommit2944' of github.com:jantman/gitpython_issue_301 -74115216c6a03e51300579237ace8918dc490861 not-for-merge branch 'testcommit2945' of github.com:jantman/gitpython_issue_301 -4ed279f01c6e13c9937cded9bc45712bd36240a3 not-for-merge branch 'testcommit2946' of github.com:jantman/gitpython_issue_301 -c6ae9e758a63143e556ef99c3bb5be4afb532eea not-for-merge branch 'testcommit2947' of github.com:jantman/gitpython_issue_301 -5bc54714ac5d5da2982589c0facf9e4d7ce8c7ce not-for-merge branch 'testcommit2948' of github.com:jantman/gitpython_issue_301 -c732544420f82ad3166d576674d879db94abbc72 not-for-merge branch 'testcommit2949' of github.com:jantman/gitpython_issue_301 -146ecdd033d0658898cdeb8e3534964c607cea6a not-for-merge branch 'testcommit295' of github.com:jantman/gitpython_issue_301 -6997de62aa74fc36a75109f32d7a7e530bcb4031 not-for-merge branch 'testcommit2950' of github.com:jantman/gitpython_issue_301 -723edd683bc522c2b80bb93f4587e9e600594fcf not-for-merge branch 'testcommit2951' of github.com:jantman/gitpython_issue_301 -c6ea77395baa2fd79eea946bcb9066f5ff7b7de3 not-for-merge branch 'testcommit2952' of github.com:jantman/gitpython_issue_301 -3183ac0352181dc5c276730c1a416d14404dd0d6 not-for-merge branch 'testcommit2953' of github.com:jantman/gitpython_issue_301 -c80f19a8bd071723f73c56ea1c644a55ef81adc8 not-for-merge branch 'testcommit2954' of github.com:jantman/gitpython_issue_301 -7d67399cdcf0874614398847519b944242b44520 not-for-merge branch 'testcommit2955' of github.com:jantman/gitpython_issue_301 -023891c1089f948e777fffc0b0cad5260bdccd6a not-for-merge branch 'testcommit2956' of github.com:jantman/gitpython_issue_301 -5f9b08545b63f4dc369a296a8cba74e49b3323cc not-for-merge branch 'testcommit2957' of github.com:jantman/gitpython_issue_301 -c847e290b84fb5607198bc5c209e6491a59a8063 not-for-merge branch 'testcommit2958' of github.com:jantman/gitpython_issue_301 -a1e959cd27581f548d0dc3825162737fe665e7e0 not-for-merge branch 'testcommit2959' of github.com:jantman/gitpython_issue_301 -91b4f81d958d90a2aac3ea03acddae55a1baa142 not-for-merge branch 'testcommit296' of github.com:jantman/gitpython_issue_301 -ceccf2a4c9e8f399a01be3a2a2c3ba9f87a41757 not-for-merge branch 'testcommit2960' of github.com:jantman/gitpython_issue_301 -b7d5b802e0fcef66fad34a35d1ddc41761124e61 not-for-merge branch 'testcommit2961' of github.com:jantman/gitpython_issue_301 -c99ab8a6a8067a2d8629aed0907f23035fbdc0ac not-for-merge branch 'testcommit2962' of github.com:jantman/gitpython_issue_301 -0dc3dc141867bed7fc08d077ce2dfdef9055b3fe not-for-merge branch 'testcommit2963' of github.com:jantman/gitpython_issue_301 -b0dc1ec5d589aeb408c709c22b865226a9b350d4 not-for-merge branch 'testcommit2964' of github.com:jantman/gitpython_issue_301 -77d4c860027af2dfd3b9724b01fc5bf0cf7dbbdd not-for-merge branch 'testcommit2965' of github.com:jantman/gitpython_issue_301 -51f38c55b58c5b87faa314fa9aa63a6c5112fd41 not-for-merge branch 'testcommit2966' of github.com:jantman/gitpython_issue_301 -b77d8ed4748e62e6bff33b30a8411fd7c936daa9 not-for-merge branch 'testcommit2967' of github.com:jantman/gitpython_issue_301 -793fcc60c4f1422ad8a7121bb99a50de29c37516 not-for-merge branch 'testcommit2968' of github.com:jantman/gitpython_issue_301 -acd242bd3f6258853dfb3b487a8f2146b769ece1 not-for-merge branch 'testcommit2969' of github.com:jantman/gitpython_issue_301 -68b253d1f623bd00e2cd2aa2dcff105b517a7b2f not-for-merge branch 'testcommit297' of github.com:jantman/gitpython_issue_301 -92c71e5f43348db1e58f645f9e9d1d47c2cebcaf not-for-merge branch 'testcommit2970' of github.com:jantman/gitpython_issue_301 -61d376aa1e72e701afa1fa7365f843a14dc603f9 not-for-merge branch 'testcommit2971' of github.com:jantman/gitpython_issue_301 -4fb1c613910ab248888cee907efd6f239195f48a not-for-merge branch 'testcommit2972' of github.com:jantman/gitpython_issue_301 -407614a023967b69891aae180b9224b853374f9d not-for-merge branch 'testcommit2973' of github.com:jantman/gitpython_issue_301 -86275582a81f35e52c9c9008b722ed2db0a5a729 not-for-merge branch 'testcommit2974' of github.com:jantman/gitpython_issue_301 -8251064b4d9219fbecb77c4f5397756f54cf7640 not-for-merge branch 'testcommit2975' of github.com:jantman/gitpython_issue_301 -af892e741565266001392b4b59028fd373c0a657 not-for-merge branch 'testcommit2976' of github.com:jantman/gitpython_issue_301 -b0c70367426caf88f78c1d9d734e8a56c23b4b44 not-for-merge branch 'testcommit2977' of github.com:jantman/gitpython_issue_301 -ae9465a5ae6643151c024768158fd573b3cbaf0c not-for-merge branch 'testcommit2978' of github.com:jantman/gitpython_issue_301 -d1f02dd102cea976cab9d76f53dd5c955b7bfebf not-for-merge branch 'testcommit2979' of github.com:jantman/gitpython_issue_301 -fc38290e57a95c75510bfddf2ae354c5640d7b53 not-for-merge branch 'testcommit298' of github.com:jantman/gitpython_issue_301 -9b2bc9ca92235483509186a709f1e34b20a4d2e7 not-for-merge branch 'testcommit2980' of github.com:jantman/gitpython_issue_301 -5cfea9ec5535e612c30c50697defdee666928892 not-for-merge branch 'testcommit2981' of github.com:jantman/gitpython_issue_301 -b4adf20285dc78ee2a03c2e8afa00f9d45751487 not-for-merge branch 'testcommit2982' of github.com:jantman/gitpython_issue_301 -188f99fcdc5d9fe8f31114e7ffab5bf3739da8d2 not-for-merge branch 'testcommit2983' of github.com:jantman/gitpython_issue_301 -b00880e63c61fbe617d7129d46ce809cc36d525b not-for-merge branch 'testcommit2984' of github.com:jantman/gitpython_issue_301 -4f60b9d57734ca5491f9d9109af2e47f1e3aa2f3 not-for-merge branch 'testcommit2985' of github.com:jantman/gitpython_issue_301 -f76f3c51641c72f5e5597fa29ce2ebefac99efe7 not-for-merge branch 'testcommit2986' of github.com:jantman/gitpython_issue_301 -f758ad50fd438409a0f0a07ff4d2ce552dc3b826 not-for-merge branch 'testcommit2987' of github.com:jantman/gitpython_issue_301 -44f68aa84a4c85b65559bce6fab3f2926c28b205 not-for-merge branch 'testcommit2988' of github.com:jantman/gitpython_issue_301 -68f59ad059603046e9ec5336d774fda2b73916aa not-for-merge branch 'testcommit2989' of github.com:jantman/gitpython_issue_301 -c7c20305653769c48f003197c38775bc6b372f0d not-for-merge branch 'testcommit299' of github.com:jantman/gitpython_issue_301 -2b0743a4ea1153ba67f76ffe541f557c9e04afa7 not-for-merge branch 'testcommit2990' of github.com:jantman/gitpython_issue_301 -e349dba503b710f462fc2d9af6adb844b0f78e8d not-for-merge branch 'testcommit2991' of github.com:jantman/gitpython_issue_301 -6b1f3c1c53716762d2fe9c8f5f17dd1da64b0c47 not-for-merge branch 'testcommit2992' of github.com:jantman/gitpython_issue_301 -fee6432ba53aba731a5537dee264ba02a7cd6236 not-for-merge branch 'testcommit2993' of github.com:jantman/gitpython_issue_301 -3c3a87f5c24affa518b77c835db6b50d7b78707f not-for-merge branch 'testcommit2994' of github.com:jantman/gitpython_issue_301 -72b847946939fe54c70e307944f1d3131596e07b not-for-merge branch 'testcommit2995' of github.com:jantman/gitpython_issue_301 -83c985631b203c4cab4eb86eb02144f43f3ddca4 not-for-merge branch 'testcommit2996' of github.com:jantman/gitpython_issue_301 -066dc4b1c8478848a2519cc664f1e24efc99eecd not-for-merge branch 'testcommit2997' of github.com:jantman/gitpython_issue_301 -2d76b3c07bc5bfd10068806fdfcc3a0c688bbb9a not-for-merge branch 'testcommit2998' of github.com:jantman/gitpython_issue_301 -9cada7bc8e294a78956b9ce3d13b720a2bb2d681 not-for-merge branch 'testcommit2999' of github.com:jantman/gitpython_issue_301 -e4cee9486bf22b4859e667511db86e00c711f139 not-for-merge branch 'testcommit3' of github.com:jantman/gitpython_issue_301 -dbcbcf7b94817f83d5aa24759f5366ea9bf280e9 not-for-merge branch 'testcommit30' of github.com:jantman/gitpython_issue_301 -0b14f6d87462c7f7762f7dcee17f828b07d6450b not-for-merge branch 'testcommit300' of github.com:jantman/gitpython_issue_301 -469992971ccae0d0e3d25abcdba39f62b932922e not-for-merge branch 'testcommit3000' of github.com:jantman/gitpython_issue_301 -3c6301e69de26c23307eaf76deaaf768d8f3467c not-for-merge branch 'testcommit3001' of github.com:jantman/gitpython_issue_301 -dcbc6013dfe8c3620095f082c911f1a712046b95 not-for-merge branch 'testcommit3002' of github.com:jantman/gitpython_issue_301 -daa81eb841f8ac34b5de5ef1122b4b9958efc32c not-for-merge branch 'testcommit3003' of github.com:jantman/gitpython_issue_301 -18a62ffe2d69d5b9620ce02d1cd46dd442f91dc3 not-for-merge branch 'testcommit3004' of github.com:jantman/gitpython_issue_301 -25d42d3ec5a4cc6f6bf9d59c0efba007cd6d234b not-for-merge branch 'testcommit3005' of github.com:jantman/gitpython_issue_301 -67bcaa13423e7ada3af23c2eaad0eeac4aff243b not-for-merge branch 'testcommit3006' of github.com:jantman/gitpython_issue_301 -8bb5acfa51c384bd6da05654c10ef0c1629daa3f not-for-merge branch 'testcommit3007' of github.com:jantman/gitpython_issue_301 -79d3394c66f51e7a36f02e40d31e80f11d405a39 not-for-merge branch 'testcommit3008' of github.com:jantman/gitpython_issue_301 -5e4c4da1e0523bccd8ce50a42bca025befc60035 not-for-merge branch 'testcommit3009' of github.com:jantman/gitpython_issue_301 -e956ec20cf565ffe133e203fc0fe28e2dabc2b81 not-for-merge branch 'testcommit301' of github.com:jantman/gitpython_issue_301 -4c674bf124dc14c4082c5a85ba2fde84632ecc21 not-for-merge branch 'testcommit3010' of github.com:jantman/gitpython_issue_301 -be03731a1d63f7328abc0c8c44e4b6bd07dd358c not-for-merge branch 'testcommit3011' of github.com:jantman/gitpython_issue_301 -ca30de394fbeb0e7531c75e12f374f30336e959c not-for-merge branch 'testcommit3012' of github.com:jantman/gitpython_issue_301 -2adbe4020d60644d11ac2c287f63f595653c7ce1 not-for-merge branch 'testcommit3013' of github.com:jantman/gitpython_issue_301 -563494f581e2734926119dabb05bd02d7b0fc488 not-for-merge branch 'testcommit3014' of github.com:jantman/gitpython_issue_301 -4561515162910827429e26dff72bf31d789cc056 not-for-merge branch 'testcommit3015' of github.com:jantman/gitpython_issue_301 -6299ce3c3e16d00b78c12ae51003f5575da3a587 not-for-merge branch 'testcommit3016' of github.com:jantman/gitpython_issue_301 -fa49c090caa610d6818d17bb2b691f6bdf7e6191 not-for-merge branch 'testcommit3017' of github.com:jantman/gitpython_issue_301 -7395b02ad92ca3fe30991ca949c73fd3ff5324b8 not-for-merge branch 'testcommit3018' of github.com:jantman/gitpython_issue_301 -9cae3ee8ac8a452f0d034b761de85ae275c94342 not-for-merge branch 'testcommit3019' of github.com:jantman/gitpython_issue_301 -a5bac65752d2ea09b4aec4a53916031e0df02a5f not-for-merge branch 'testcommit302' of github.com:jantman/gitpython_issue_301 -477c757618750aca3bb78de6209ec9c2f10dd977 not-for-merge branch 'testcommit3020' of github.com:jantman/gitpython_issue_301 -1f04bdd3d4934549219abcb74c5ae16321c2e379 not-for-merge branch 'testcommit3021' of github.com:jantman/gitpython_issue_301 -fb842b05b791a00fbbf1c2a1c810ab7504e81393 not-for-merge branch 'testcommit3022' of github.com:jantman/gitpython_issue_301 -4cd11d72bb3037e84df29408b33e42b5c2fee957 not-for-merge branch 'testcommit3023' of github.com:jantman/gitpython_issue_301 -58293fa3e700bb70eefc9363aac970264b469d91 not-for-merge branch 'testcommit3024' of github.com:jantman/gitpython_issue_301 -6f428c26432e64f96e2477efc8011083c4364229 not-for-merge branch 'testcommit3025' of github.com:jantman/gitpython_issue_301 -9b4aa01cefbe909cfa5342fd79f0cb395fdc3732 not-for-merge branch 'testcommit3026' of github.com:jantman/gitpython_issue_301 -7005fa1a3fa4dfa782553ab14bc3bcffff9c56df not-for-merge branch 'testcommit3027' of github.com:jantman/gitpython_issue_301 -bf9e4d85ee2f56dd7ef27e6143e845b785b6618b not-for-merge branch 'testcommit3028' of github.com:jantman/gitpython_issue_301 -45d168af42f0ed636050ee8f692e868961de6826 not-for-merge branch 'testcommit3029' of github.com:jantman/gitpython_issue_301 -1f3e973d3a67b4447e88bdaa226a9d86efd2843b not-for-merge branch 'testcommit303' of github.com:jantman/gitpython_issue_301 -186860071e3470cf69460d6402a218088a8093c0 not-for-merge branch 'testcommit3030' of github.com:jantman/gitpython_issue_301 -62b7698ae336cb97d6cb0738ee5b0a709a4ad07b not-for-merge branch 'testcommit3031' of github.com:jantman/gitpython_issue_301 -01d430de1d69d12e931134baf5bb9548f32d6cd5 not-for-merge branch 'testcommit3032' of github.com:jantman/gitpython_issue_301 -41233661f67acbfe2f148536ea1125d103fc208a not-for-merge branch 'testcommit3033' of github.com:jantman/gitpython_issue_301 -5669e6dc8e1ab17442ebc7b2186dd859996a2e31 not-for-merge branch 'testcommit3034' of github.com:jantman/gitpython_issue_301 -d9f2d60beba5fba8a9310bbb67522e92c37b468d not-for-merge branch 'testcommit3035' of github.com:jantman/gitpython_issue_301 -99c303d2e56375382b13a93b961af664a3b820a9 not-for-merge branch 'testcommit3036' of github.com:jantman/gitpython_issue_301 -800e70fc7a677c61b57fd802a361cad08afc12fd not-for-merge branch 'testcommit3037' of github.com:jantman/gitpython_issue_301 -f75c16aeddc5073657490c13e61f6faf5f581f25 not-for-merge branch 'testcommit3038' of github.com:jantman/gitpython_issue_301 -ad943dd467147d40bf1df47e38c088806950a659 not-for-merge branch 'testcommit3039' of github.com:jantman/gitpython_issue_301 -45b4862bd4febaba654cf50c8a230b83f542c0f3 not-for-merge branch 'testcommit304' of github.com:jantman/gitpython_issue_301 -3a8608b91d032305abd134bb21d612c3d8aaa4be not-for-merge branch 'testcommit3040' of github.com:jantman/gitpython_issue_301 -9f16520155c87bef70e97768b1923e78d419472a not-for-merge branch 'testcommit3041' of github.com:jantman/gitpython_issue_301 -13b232c36eb2f99b8cf33ae8051cfe6e895f4e3f not-for-merge branch 'testcommit3042' of github.com:jantman/gitpython_issue_301 -030fbaa9a0a8cadacb2f0f5ea4f175d46325bf61 not-for-merge branch 'testcommit3043' of github.com:jantman/gitpython_issue_301 -65a11e2928b23964215c1bd9536471f4390daf62 not-for-merge branch 'testcommit3044' of github.com:jantman/gitpython_issue_301 -87918a3c9d4c47544a85ec9f68223c34b3586e19 not-for-merge branch 'testcommit3045' of github.com:jantman/gitpython_issue_301 -afca50e8307f3289c1cb796bae5307f8ddf08d06 not-for-merge branch 'testcommit3046' of github.com:jantman/gitpython_issue_301 -5228c57194a6eb2be9d4d84ba3f39636d1184101 not-for-merge branch 'testcommit3047' of github.com:jantman/gitpython_issue_301 -508fd41879344e12ef8e143097a73d5678b1a278 not-for-merge branch 'testcommit3048' of github.com:jantman/gitpython_issue_301 -376a347f87572bfaf7dd673a4189612bacaa9494 not-for-merge branch 'testcommit3049' of github.com:jantman/gitpython_issue_301 -5f203ab3a2323d6a465c73248bfe5b908f5c056f not-for-merge branch 'testcommit305' of github.com:jantman/gitpython_issue_301 -5bf3e183c4b4b6167a7b104a6a6fb31605ef0cb7 not-for-merge branch 'testcommit3050' of github.com:jantman/gitpython_issue_301 -962825f7c91cc25ebd27394653e48fa855921256 not-for-merge branch 'testcommit3051' of github.com:jantman/gitpython_issue_301 -b27c09d7a09676c25d5f5cae0dd171c2ccf7622c not-for-merge branch 'testcommit3052' of github.com:jantman/gitpython_issue_301 -aab6a2a4377864550855bdd639dae8a5c52fa717 not-for-merge branch 'testcommit3053' of github.com:jantman/gitpython_issue_301 -44d6c16157e42f293b0a69b8a5941c81fb267082 not-for-merge branch 'testcommit3054' of github.com:jantman/gitpython_issue_301 -9e8bb2ae67064c95ea37dd63e2bd9be8a8150e27 not-for-merge branch 'testcommit3055' of github.com:jantman/gitpython_issue_301 -18997866b093f734233a38049635402298847d7d not-for-merge branch 'testcommit3056' of github.com:jantman/gitpython_issue_301 -8474ef14f9a88cce7b1c2a0866ba2fe10e83404c not-for-merge branch 'testcommit3057' of github.com:jantman/gitpython_issue_301 -c4507863a62a4b708bf1fd535fc50011f3de8a4f not-for-merge branch 'testcommit3058' of github.com:jantman/gitpython_issue_301 -e5ba02eae339b890d37c7323c7ac1c2f9801726a not-for-merge branch 'testcommit3059' of github.com:jantman/gitpython_issue_301 -f1c04f6206adcc49ac80406cf581fd5b49fbcd76 not-for-merge branch 'testcommit306' of github.com:jantman/gitpython_issue_301 -659f32739f88ff65bda3bac5b296c743d08ed140 not-for-merge branch 'testcommit3060' of github.com:jantman/gitpython_issue_301 -86e677e2db9fbe0bcaa83931892cac0e2dc51472 not-for-merge branch 'testcommit3061' of github.com:jantman/gitpython_issue_301 -643f424501c37369cb0ee2360e1a03096ebe5e0d not-for-merge branch 'testcommit3062' of github.com:jantman/gitpython_issue_301 -6ceed51db69910f0e380d94bba7d9cf2591c4b85 not-for-merge branch 'testcommit3063' of github.com:jantman/gitpython_issue_301 -1e72a2238daf237404b33697f6543f7cd062fcc1 not-for-merge branch 'testcommit3064' of github.com:jantman/gitpython_issue_301 -bd70a284a16bd4c53e34aa4c8f90d75c76fb564f not-for-merge branch 'testcommit3065' of github.com:jantman/gitpython_issue_301 -4722e54013e65377a28cf9919a3356c38bb96c3a not-for-merge branch 'testcommit3066' of github.com:jantman/gitpython_issue_301 -397e46f7d27f3e9944440d81cb6c883f597ef95b not-for-merge branch 'testcommit3067' of github.com:jantman/gitpython_issue_301 -27548fe41e35df65e77e7e6faa318e20d823fd7f not-for-merge branch 'testcommit3068' of github.com:jantman/gitpython_issue_301 -eca823d28ad93642c720acdd8c5f7bed96164c89 not-for-merge branch 'testcommit3069' of github.com:jantman/gitpython_issue_301 -b5ec269973a2bffd96ef3937d60e7b1a983c3dc8 not-for-merge branch 'testcommit307' of github.com:jantman/gitpython_issue_301 -edee647a005f99eeff6c2105c2a784074094a41d not-for-merge branch 'testcommit3070' of github.com:jantman/gitpython_issue_301 -7ca5bec9c741b01114936f5deb4ad7aa9bb432a0 not-for-merge branch 'testcommit3071' of github.com:jantman/gitpython_issue_301 -cfcf8ba80f40b32e2d8ba720653b2d9aa0b79588 not-for-merge branch 'testcommit3072' of github.com:jantman/gitpython_issue_301 -d4077ae770847e80ac9a7c4bd6afccabaeb5189a not-for-merge branch 'testcommit3073' of github.com:jantman/gitpython_issue_301 -ecd1ff3fa0160f88ef4abc899e8de0301b565a52 not-for-merge branch 'testcommit3074' of github.com:jantman/gitpython_issue_301 -5b9e6e36823188fee3dfcff8d73ae763ea50689d not-for-merge branch 'testcommit3075' of github.com:jantman/gitpython_issue_301 -bfb8a68ffd302b1c6850520386356e9b87407ce1 not-for-merge branch 'testcommit3076' of github.com:jantman/gitpython_issue_301 -26bcd09fad349b226d226ea45bd679791990869d not-for-merge branch 'testcommit3077' of github.com:jantman/gitpython_issue_301 -e7b17d85d57ef952230e08ed10b3f31153d528e6 not-for-merge branch 'testcommit3078' of github.com:jantman/gitpython_issue_301 -6956a52f6a1518e158fc73bbc04d6554cc7e6c7a not-for-merge branch 'testcommit3079' of github.com:jantman/gitpython_issue_301 -82220f2bac391b9c25c8fe21d1f584f328d6a601 not-for-merge branch 'testcommit308' of github.com:jantman/gitpython_issue_301 -10989c2734f5843318cbb8b29a5949a51492ba39 not-for-merge branch 'testcommit3080' of github.com:jantman/gitpython_issue_301 -ec56c090752aa98b9fd9f4b5802729ec3ffd0626 not-for-merge branch 'testcommit3081' of github.com:jantman/gitpython_issue_301 -0549c1cd5b8ba7c28d3a3d6dac81a84ed5085fbd not-for-merge branch 'testcommit3082' of github.com:jantman/gitpython_issue_301 -13b3fb97fdfa15ac745676d1fe4cd343c88f6b86 not-for-merge branch 'testcommit3083' of github.com:jantman/gitpython_issue_301 -20a9cd5de43270a3f47d7f67a3b9617a70f7525a not-for-merge branch 'testcommit3084' of github.com:jantman/gitpython_issue_301 -567e3422b2a50faa132e6c55c7d60087120e69b8 not-for-merge branch 'testcommit3085' of github.com:jantman/gitpython_issue_301 -01d7e7c3460894d4a306defc77a18c2a9a7eee18 not-for-merge branch 'testcommit3086' of github.com:jantman/gitpython_issue_301 -9b5c78deafb0062bd83b33852ec0956453b061f9 not-for-merge branch 'testcommit3087' of github.com:jantman/gitpython_issue_301 -b43a9fb97a4f5c7664a6e370c683ce4ed1f89c7f not-for-merge branch 'testcommit3088' of github.com:jantman/gitpython_issue_301 -e3286a24f44cc00fccaae801ba311879e587a9a5 not-for-merge branch 'testcommit3089' of github.com:jantman/gitpython_issue_301 -0c5f76c8757a4a782765aa7aff6ce3851e16422b not-for-merge branch 'testcommit309' of github.com:jantman/gitpython_issue_301 -97696d289ed6a78cab23e3add293e595114124e0 not-for-merge branch 'testcommit3090' of github.com:jantman/gitpython_issue_301 -48f1524918bd8a901a3abf04a636f4033a8a3469 not-for-merge branch 'testcommit3091' of github.com:jantman/gitpython_issue_301 -f55ea4dcc471ee1951e6b26ec6638748daedd3d8 not-for-merge branch 'testcommit3092' of github.com:jantman/gitpython_issue_301 -731662a23a16ee155733f46a61b64db824abed9d not-for-merge branch 'testcommit3093' of github.com:jantman/gitpython_issue_301 -50655deed02283d0e3d680009087eb042ce03f4e not-for-merge branch 'testcommit3094' of github.com:jantman/gitpython_issue_301 -135ffcd74b6c3deada8cb724947447fc65d190db not-for-merge branch 'testcommit3095' of github.com:jantman/gitpython_issue_301 -0a8e15bec4f24dcdfddb2b91c9ec3310098f61db not-for-merge branch 'testcommit3096' of github.com:jantman/gitpython_issue_301 -b8d8ed3883ef8243496b4e534105687536643a65 not-for-merge branch 'testcommit3097' of github.com:jantman/gitpython_issue_301 -f69ca845b226c693f39f43404591470b60c0ae86 not-for-merge branch 'testcommit3098' of github.com:jantman/gitpython_issue_301 -0bb52b22b9502e69f6715e4755a041bfe71e6351 not-for-merge branch 'testcommit3099' of github.com:jantman/gitpython_issue_301 -b7aa295ca3d57ab6864f78dc25cac503139edb77 not-for-merge branch 'testcommit31' of github.com:jantman/gitpython_issue_301 -31760b9035fc3098b80f29a30c18832e34bb8470 not-for-merge branch 'testcommit310' of github.com:jantman/gitpython_issue_301 -66aefe6da4c091f820dc285ffb7c55270c9f70e6 not-for-merge branch 'testcommit3100' of github.com:jantman/gitpython_issue_301 -bb298ceb6a2f6d2e94c52443cebcc4aecaa0d1e7 not-for-merge branch 'testcommit3101' of github.com:jantman/gitpython_issue_301 -f24570edf796111e761a7cf220536c583fbdcc4d not-for-merge branch 'testcommit3102' of github.com:jantman/gitpython_issue_301 -d43c0b36a3fd9d3100d534bf3f15686f3060cda2 not-for-merge branch 'testcommit3103' of github.com:jantman/gitpython_issue_301 -c0c0b599f72e88a7e43e8df0635e62787087b844 not-for-merge branch 'testcommit3104' of github.com:jantman/gitpython_issue_301 -193e92aca2d12f4b6dd7509675a40d80449129e1 not-for-merge branch 'testcommit3105' of github.com:jantman/gitpython_issue_301 -5a5dba60d054162e9f697093fc0827885f7321ee not-for-merge branch 'testcommit3106' of github.com:jantman/gitpython_issue_301 -6ab09c475ea7de06d312a38a0cadc18febe1f25a not-for-merge branch 'testcommit3107' of github.com:jantman/gitpython_issue_301 -61d0a13af1dadf6dcb93e7a32fc2f754c82b9c6f not-for-merge branch 'testcommit3108' of github.com:jantman/gitpython_issue_301 -9e591bd78c6e4a82122fc44026eeba03d545a76c not-for-merge branch 'testcommit3109' of github.com:jantman/gitpython_issue_301 -4cb4e1853561f8d6d4933eb2e19c17aa6890f00f not-for-merge branch 'testcommit311' of github.com:jantman/gitpython_issue_301 -d9f920210bd04f677cbfc9360fb80cf74efc027b not-for-merge branch 'testcommit3110' of github.com:jantman/gitpython_issue_301 -f68bbbfef1733cd862b0f6223a62e7b4c71c6176 not-for-merge branch 'testcommit3111' of github.com:jantman/gitpython_issue_301 -3f6d77bf52d5f748d82c956726be68eab00dcdcc not-for-merge branch 'testcommit3112' of github.com:jantman/gitpython_issue_301 -36f6bcd97dbab81f6d9f6efc00d152252969bc0a not-for-merge branch 'testcommit3113' of github.com:jantman/gitpython_issue_301 -6238d3310878473e8660a035e2e44290867f527f not-for-merge branch 'testcommit3114' of github.com:jantman/gitpython_issue_301 -6ab1d7107225030b2402d0d7b9b8262a559dc156 not-for-merge branch 'testcommit3115' of github.com:jantman/gitpython_issue_301 -32d03c829e431bed049795054126b4fa63aa3180 not-for-merge branch 'testcommit3116' of github.com:jantman/gitpython_issue_301 -eed4c18ab3e6b156a261d3eb4e4333b4e051c1e9 not-for-merge branch 'testcommit3117' of github.com:jantman/gitpython_issue_301 -6bc87b3d39d8861dfa107f350e49d583ef921ea1 not-for-merge branch 'testcommit3118' of github.com:jantman/gitpython_issue_301 -c9ff6c217bc48a406287b8e6f8c089d1a353bf06 not-for-merge branch 'testcommit3119' of github.com:jantman/gitpython_issue_301 -f8fbdb568acb8726a97a581635b8b4437a5a8496 not-for-merge branch 'testcommit312' of github.com:jantman/gitpython_issue_301 -1ad3edae963d8d7b5829da0de75db85a34f93b71 not-for-merge branch 'testcommit3120' of github.com:jantman/gitpython_issue_301 -d68b71d2768b40f4037b2a0ec66d7b909bd0d83b not-for-merge branch 'testcommit3121' of github.com:jantman/gitpython_issue_301 -507b5bbe23a8db25e34d6f2453963453e76fc039 not-for-merge branch 'testcommit3122' of github.com:jantman/gitpython_issue_301 -073d01c464da61c8e79848ef3bdfb0820619cf56 not-for-merge branch 'testcommit3123' of github.com:jantman/gitpython_issue_301 -e938095d843eb2e6b9148398576e04774cc1b4ca not-for-merge branch 'testcommit3124' of github.com:jantman/gitpython_issue_301 -9349027b9cc4754541adf5af7ac2faac522a6e19 not-for-merge branch 'testcommit3125' of github.com:jantman/gitpython_issue_301 -fef764ed1fe695e4bce3f3c280ba6485778cb6ec not-for-merge branch 'testcommit3126' of github.com:jantman/gitpython_issue_301 -45d29b5f1183a27db430e4a2cfafa8503156e5e1 not-for-merge branch 'testcommit3127' of github.com:jantman/gitpython_issue_301 -693e55c8db4eb6e3a24359f98091cb921594c7f3 not-for-merge branch 'testcommit3128' of github.com:jantman/gitpython_issue_301 -eaf04ef00009d7fe60eff92afa6cf8768ab56e05 not-for-merge branch 'testcommit3129' of github.com:jantman/gitpython_issue_301 -8fe4b5dd9c4ad052e0e4cae1cfbc9252c31497ae not-for-merge branch 'testcommit313' of github.com:jantman/gitpython_issue_301 -c515794201b46a0d49548fb5b4d767d4d7c941e2 not-for-merge branch 'testcommit3130' of github.com:jantman/gitpython_issue_301 -0365650552245dc6d125f9fcb1c0280220625708 not-for-merge branch 'testcommit3131' of github.com:jantman/gitpython_issue_301 -9adec0acca004907c68b8ed2bc00ab3bbe116f69 not-for-merge branch 'testcommit3132' of github.com:jantman/gitpython_issue_301 -9f55d8029e573dc95854498bb9a77c12c470404b not-for-merge branch 'testcommit3133' of github.com:jantman/gitpython_issue_301 -2ab9eb7e11f2d64bbd933e291e39b3da4b968626 not-for-merge branch 'testcommit3134' of github.com:jantman/gitpython_issue_301 -c9997da50a421af4ed993eb98fbef14f46ac215c not-for-merge branch 'testcommit3135' of github.com:jantman/gitpython_issue_301 -c6e12495e260997dde3492d67519e2bb5f0e6b40 not-for-merge branch 'testcommit3136' of github.com:jantman/gitpython_issue_301 -d2aca33e23e72a24bd5d0cdcdf04071a42df6382 not-for-merge branch 'testcommit3137' of github.com:jantman/gitpython_issue_301 -a3659d50c92b28f84b1bc4779e2d2ec5b02d2543 not-for-merge branch 'testcommit3138' of github.com:jantman/gitpython_issue_301 -bc1a34b079b6b2b77c8875953e4a70cfe5954812 not-for-merge branch 'testcommit3139' of github.com:jantman/gitpython_issue_301 -396282103d037fdad4e519be5aa489137ee9d8d1 not-for-merge branch 'testcommit314' of github.com:jantman/gitpython_issue_301 -5dceca8a4821e705646a20782ff98f7addc24410 not-for-merge branch 'testcommit3140' of github.com:jantman/gitpython_issue_301 -791a558362b7f59ba004c646f3a3957eb5e7e412 not-for-merge branch 'testcommit3141' of github.com:jantman/gitpython_issue_301 -c574de3f70655ca22f49230b8a5bcd2d34760422 not-for-merge branch 'testcommit3142' of github.com:jantman/gitpython_issue_301 -f377d2e0cf12cba5aa62d7e81713a9660e1d5ad1 not-for-merge branch 'testcommit3143' of github.com:jantman/gitpython_issue_301 -ee2588bdf5c00ada17186cfdec3965282895ebee not-for-merge branch 'testcommit3144' of github.com:jantman/gitpython_issue_301 -ce9c2f87beb5b9c321c5cbcf2d2d25924e776c36 not-for-merge branch 'testcommit3145' of github.com:jantman/gitpython_issue_301 -8af8af863fae0fe56f2dbc9f734bc5dcb0b43612 not-for-merge branch 'testcommit3146' of github.com:jantman/gitpython_issue_301 -8a818027cd88e75ee4dfc37be13c3a3d42a26adf not-for-merge branch 'testcommit3147' of github.com:jantman/gitpython_issue_301 -f883c8b50d31b66e79d504077a4ccdbf503b9c1d not-for-merge branch 'testcommit3148' of github.com:jantman/gitpython_issue_301 -119f296794e4761d32747c35eebb80a4fbe08db5 not-for-merge branch 'testcommit3149' of github.com:jantman/gitpython_issue_301 -ed9d9e76b68a020db3d32d8663660c940b679d12 not-for-merge branch 'testcommit315' of github.com:jantman/gitpython_issue_301 -0f9599a2ec0dcb5477f4f72a5791af17c4dc0121 not-for-merge branch 'testcommit3150' of github.com:jantman/gitpython_issue_301 -592604690d6819e4e12d198a910400106f12215e not-for-merge branch 'testcommit3151' of github.com:jantman/gitpython_issue_301 -d8ef81e2596b04436a907995c463c31a78bd59f5 not-for-merge branch 'testcommit3152' of github.com:jantman/gitpython_issue_301 -b0704862da0fa6dd25afcdc59677f6d63ab00d80 not-for-merge branch 'testcommit3153' of github.com:jantman/gitpython_issue_301 -f67dcaad0dc437ddbce1e7eac846529a77662f67 not-for-merge branch 'testcommit3154' of github.com:jantman/gitpython_issue_301 -e79517ef3e1304eaeb7a2b141bf80ee012861ac8 not-for-merge branch 'testcommit3155' of github.com:jantman/gitpython_issue_301 -364df92f30f457a3c021c20c183b3ec8fb473340 not-for-merge branch 'testcommit3156' of github.com:jantman/gitpython_issue_301 -9d9050ccb96b1f256232a08a0ed7dc734cf4c86a not-for-merge branch 'testcommit3157' of github.com:jantman/gitpython_issue_301 -f305c2ff672311d658a10c66a08a7e3d659262ea not-for-merge branch 'testcommit3158' of github.com:jantman/gitpython_issue_301 -bbfbb0e4ed7493cbe8b672a64d9f29061e57e1d7 not-for-merge branch 'testcommit3159' of github.com:jantman/gitpython_issue_301 -ae925c1a638331ffe711a2c9b99b0ae7d4ba52e8 not-for-merge branch 'testcommit316' of github.com:jantman/gitpython_issue_301 -72dfafa2178f51220b4103b2159ee767b6f650e3 not-for-merge branch 'testcommit3160' of github.com:jantman/gitpython_issue_301 -75bf5eb2f1797a89ebd4345115815b0016a56cc9 not-for-merge branch 'testcommit3161' of github.com:jantman/gitpython_issue_301 -eff2bf51e40a626e4b3881b2f0f8ae96b4cfe5c3 not-for-merge branch 'testcommit3162' of github.com:jantman/gitpython_issue_301 -a91cda3decbbd1bf34a7cc379ee1f009182c893e not-for-merge branch 'testcommit3163' of github.com:jantman/gitpython_issue_301 -ab74957e1a2c8cc3ed3d1a715bba51b64af6cde2 not-for-merge branch 'testcommit3164' of github.com:jantman/gitpython_issue_301 -e93ecae2182ee8f54245fad37b0f45b631839dc8 not-for-merge branch 'testcommit3165' of github.com:jantman/gitpython_issue_301 -c52b71c4ca77d3ec8b65fc916d3d1d993d8c6153 not-for-merge branch 'testcommit3166' of github.com:jantman/gitpython_issue_301 -ecaee1b6a4bc3dbee318d7c03687af4a618989fa not-for-merge branch 'testcommit3167' of github.com:jantman/gitpython_issue_301 -5b5d9107a19487bf7c06c0295e9e6ae6ada92c0a not-for-merge branch 'testcommit3168' of github.com:jantman/gitpython_issue_301 -d116bdc5260977ba8f66a5e01c428929f6decc19 not-for-merge branch 'testcommit3169' of github.com:jantman/gitpython_issue_301 -1f523bcc78615916a35514cc72664112021c7a24 not-for-merge branch 'testcommit317' of github.com:jantman/gitpython_issue_301 -3e501978a09f12f49d928e89e91166f2e2f2d07e not-for-merge branch 'testcommit3170' of github.com:jantman/gitpython_issue_301 -e766b2a2b82eadf2f29091b4d1869e1dd8b73d31 not-for-merge branch 'testcommit3171' of github.com:jantman/gitpython_issue_301 -4487811ac3c0b1f104776bf0ac07d57a7b87d64a not-for-merge branch 'testcommit3172' of github.com:jantman/gitpython_issue_301 -9c3a7c9feff96d9ac3e46456212275d6669c39b5 not-for-merge branch 'testcommit3173' of github.com:jantman/gitpython_issue_301 -e3741fbdc9e01f6b15bd7eafc4a2bcb47b3c837a not-for-merge branch 'testcommit3174' of github.com:jantman/gitpython_issue_301 -c6a31ef52181e736a07551e3107b9f65a2666c1a not-for-merge branch 'testcommit3175' of github.com:jantman/gitpython_issue_301 -90f57889a1719cd82a31e4588fc3980b3b70f9ad not-for-merge branch 'testcommit3176' of github.com:jantman/gitpython_issue_301 -d39d7349b1e3304a1c554cd147a3889e71ea3e35 not-for-merge branch 'testcommit3177' of github.com:jantman/gitpython_issue_301 -03a94c74ecdb30c6b1576f364bd7697c4e30b5fe not-for-merge branch 'testcommit3178' of github.com:jantman/gitpython_issue_301 -5e1300d415aa96c38211ccf18aae61085e352397 not-for-merge branch 'testcommit3179' of github.com:jantman/gitpython_issue_301 -3e0b17c8c0032dd65fac1e08a505fc0d467a038c not-for-merge branch 'testcommit318' of github.com:jantman/gitpython_issue_301 -4df76718d03595c9844f3102b494758af5f7a27a not-for-merge branch 'testcommit3180' of github.com:jantman/gitpython_issue_301 -e02232903046e11bd5bd92340efc34c10615213e not-for-merge branch 'testcommit3181' of github.com:jantman/gitpython_issue_301 -77e189ce96553dd632d446bb6a4eafa55a12aa5a not-for-merge branch 'testcommit3182' of github.com:jantman/gitpython_issue_301 -275a7c634aa350b529fc9b8b3461ac12453d2736 not-for-merge branch 'testcommit3183' of github.com:jantman/gitpython_issue_301 -a608c2d391bb0f7711e02e55d2241a30189dc776 not-for-merge branch 'testcommit3184' of github.com:jantman/gitpython_issue_301 -425c9f6f3fe484e3a6c5caebccb45ed3fc7afdee not-for-merge branch 'testcommit3185' of github.com:jantman/gitpython_issue_301 -90f22686bd14991ecf39bab75a3e912727d0142a not-for-merge branch 'testcommit3186' of github.com:jantman/gitpython_issue_301 -c2eb084a83f31d8fd0984887d5a796388774f55e not-for-merge branch 'testcommit3187' of github.com:jantman/gitpython_issue_301 -f60533eabaa834f2ef454a8e934c3bbe93869c00 not-for-merge branch 'testcommit3188' of github.com:jantman/gitpython_issue_301 -f579ad8e4e7e03aedb1d957cf4708fcb276a1ae2 not-for-merge branch 'testcommit3189' of github.com:jantman/gitpython_issue_301 -039e08e2b20a0d7a6a3d240e0cf9c8c6d18d90f8 not-for-merge branch 'testcommit319' of github.com:jantman/gitpython_issue_301 -47807ed0686b186bc74c53dfe823e832c5b1fe34 not-for-merge branch 'testcommit3190' of github.com:jantman/gitpython_issue_301 -1eed719913efec3150f1f32e7850a13015148e4c not-for-merge branch 'testcommit3191' of github.com:jantman/gitpython_issue_301 -7f7b013b8e454b59410ad7c18a2328be1a9b2843 not-for-merge branch 'testcommit3192' of github.com:jantman/gitpython_issue_301 -e2fdcbb3f5ad6891533accaa4910d6b386775dbb not-for-merge branch 'testcommit3193' of github.com:jantman/gitpython_issue_301 -4d9d2b00c964c502caa4a74b0f03333b0029e9b9 not-for-merge branch 'testcommit3194' of github.com:jantman/gitpython_issue_301 -9f803dd6ab9a26e5d9860cdb7b9b9e5abe03aa4e not-for-merge branch 'testcommit3195' of github.com:jantman/gitpython_issue_301 -f0c2555e8bfbde1e9c5ec45445e2ac852b291f24 not-for-merge branch 'testcommit3196' of github.com:jantman/gitpython_issue_301 -5dd7bbbeeed131026cfcd047001f41beba45f6e7 not-for-merge branch 'testcommit3197' of github.com:jantman/gitpython_issue_301 -84cbb686bcdb10ba3e0d3601159edbb80529aa2e not-for-merge branch 'testcommit3198' of github.com:jantman/gitpython_issue_301 -b40843d189469403d90b7c13729b704028451c9d not-for-merge branch 'testcommit3199' of github.com:jantman/gitpython_issue_301 -67a7e80511933e91d1c7e605d148d430329995c0 not-for-merge branch 'testcommit32' of github.com:jantman/gitpython_issue_301 -3ecfd3773cc5c0fbdcf5051435fd9034aa9aac83 not-for-merge branch 'testcommit320' of github.com:jantman/gitpython_issue_301 -b3caef26176b848c3e9d09136fe8d87a2a8c439d not-for-merge branch 'testcommit3200' of github.com:jantman/gitpython_issue_301 -f6560af1bc09356b6cb62e93ddb54e0e19f91027 not-for-merge branch 'testcommit3201' of github.com:jantman/gitpython_issue_301 -cda9efa2da61f3fb0342c2fc40504c770bb9e1cc not-for-merge branch 'testcommit3202' of github.com:jantman/gitpython_issue_301 -31f9c26f9dbc6d9430c997a5f34547b0f1f4b039 not-for-merge branch 'testcommit3203' of github.com:jantman/gitpython_issue_301 -b6e9ea946d1d8c2ce7963ff253db91305d94c605 not-for-merge branch 'testcommit3204' of github.com:jantman/gitpython_issue_301 -59b918068cb34e8764a3c8b9c0037944722c804d not-for-merge branch 'testcommit3205' of github.com:jantman/gitpython_issue_301 -1f2f13e0077551439af604313186e8d22c0df588 not-for-merge branch 'testcommit3206' of github.com:jantman/gitpython_issue_301 -e109f58006d3e5523dd5cf71e8d86505db3274ea not-for-merge branch 'testcommit3207' of github.com:jantman/gitpython_issue_301 -28294a5c69078bdccf0fad8ca6b7fd3c39a04773 not-for-merge branch 'testcommit3208' of github.com:jantman/gitpython_issue_301 -867f36a18c5629577866b1bc2a8244a5e23fc108 not-for-merge branch 'testcommit3209' of github.com:jantman/gitpython_issue_301 -1f1c7bb1f6c6916c90caa8f7a9fd33db7ce808bb not-for-merge branch 'testcommit321' of github.com:jantman/gitpython_issue_301 -7eeb65d0af5f62b2efc3bb089cdb79dddf228342 not-for-merge branch 'testcommit3210' of github.com:jantman/gitpython_issue_301 -03df7945451de60bd595ebfc4eda912882a0caae not-for-merge branch 'testcommit3211' of github.com:jantman/gitpython_issue_301 -5bdaac2e8209ac19ab48a4273fe6b95993478d9f not-for-merge branch 'testcommit3212' of github.com:jantman/gitpython_issue_301 -612e677ac0cc872b6f514179e563bb7f0080a131 not-for-merge branch 'testcommit3213' of github.com:jantman/gitpython_issue_301 -a0b944ab0feca1498712c7b450adb8d7b4c8c859 not-for-merge branch 'testcommit3214' of github.com:jantman/gitpython_issue_301 -c183c3aebcbfc6672045c942bdedd7665c6841dd not-for-merge branch 'testcommit3215' of github.com:jantman/gitpython_issue_301 -dc0ea2ad6e6754e54facc6ce7f07a3f765d9fbd8 not-for-merge branch 'testcommit3216' of github.com:jantman/gitpython_issue_301 -b9494ad40695fc3e0b5ee853042e4699fcd3cd23 not-for-merge branch 'testcommit3217' of github.com:jantman/gitpython_issue_301 -0b1fd4da2f4793a3e28fd345d472d67947c70f43 not-for-merge branch 'testcommit3218' of github.com:jantman/gitpython_issue_301 -8927f99a3d0ca4fb88f2e875436119ad5413c3e7 not-for-merge branch 'testcommit3219' of github.com:jantman/gitpython_issue_301 -d10e132919280fcdf48c62593460861031ab8c99 not-for-merge branch 'testcommit322' of github.com:jantman/gitpython_issue_301 -dc9c808aeb634c1ea885b451b202a5711e892f3f not-for-merge branch 'testcommit3220' of github.com:jantman/gitpython_issue_301 -e5778e4d9d0fdcc6a41c8c601e82e76b68211ee3 not-for-merge branch 'testcommit3221' of github.com:jantman/gitpython_issue_301 -e2021abf719fe651d2fecaf96c4bf801c6d55ad5 not-for-merge branch 'testcommit3222' of github.com:jantman/gitpython_issue_301 -7f7a4daee49d0baf077bec63ef2e9fcb1fd48425 not-for-merge branch 'testcommit3223' of github.com:jantman/gitpython_issue_301 -d4516d40be38b2326860edc9cbeaad609947b0e8 not-for-merge branch 'testcommit3224' of github.com:jantman/gitpython_issue_301 -effa895baa2f8b9641b9a0e904f407dd47678261 not-for-merge branch 'testcommit3225' of github.com:jantman/gitpython_issue_301 -b1998f7115b771156dede32cc6497de5a03204b3 not-for-merge branch 'testcommit3226' of github.com:jantman/gitpython_issue_301 -1537cc72ea1d301a0adbb9d87776c71ab05b6459 not-for-merge branch 'testcommit3227' of github.com:jantman/gitpython_issue_301 -0ee2e347e262675e86eb79a06cad82d72eee5bfa not-for-merge branch 'testcommit3228' of github.com:jantman/gitpython_issue_301 -76ef9520bffae40bd7c71d60dd215f260de9173e not-for-merge branch 'testcommit3229' of github.com:jantman/gitpython_issue_301 -776dee42ff792a033f0dba962df1f0cdce6985ca not-for-merge branch 'testcommit323' of github.com:jantman/gitpython_issue_301 -4afe8e11f2d35c6529ce3158faf1c14fe01ea968 not-for-merge branch 'testcommit3230' of github.com:jantman/gitpython_issue_301 -41c6c1dac91e84fce84b48f521b1f7a1ef24fdd4 not-for-merge branch 'testcommit3231' of github.com:jantman/gitpython_issue_301 -06337339fdef80c49fd96e2a4597c039d478264f not-for-merge branch 'testcommit3232' of github.com:jantman/gitpython_issue_301 -8450e5988e2b9c8fbee512db64d10dde38a03f6a not-for-merge branch 'testcommit3233' of github.com:jantman/gitpython_issue_301 -10b0cd35b2f954eb865d06007e3458f2d57b0bec not-for-merge branch 'testcommit3234' of github.com:jantman/gitpython_issue_301 -42dadf787d9691ccbb76651abaca92682ad8a546 not-for-merge branch 'testcommit3235' of github.com:jantman/gitpython_issue_301 -4b8f3cbae967245614d062c4fbac1c752bc36cdb not-for-merge branch 'testcommit3236' of github.com:jantman/gitpython_issue_301 -5cf5bf0af30129883220af107a9c317024f6d0fc not-for-merge branch 'testcommit3237' of github.com:jantman/gitpython_issue_301 -d612a01b30ca0d49d0a23787132fd5ebb0ac9d66 not-for-merge branch 'testcommit3238' of github.com:jantman/gitpython_issue_301 -7b1099ec96f7f77ee0ead7263c3bdaf6329ced04 not-for-merge branch 'testcommit3239' of github.com:jantman/gitpython_issue_301 -0608d22ef75fec628ab594a7f2528dfaeb8fa200 not-for-merge branch 'testcommit324' of github.com:jantman/gitpython_issue_301 -1ca12453387594d89cbf93568198e4ad83b2bb25 not-for-merge branch 'testcommit3240' of github.com:jantman/gitpython_issue_301 -455e5af5394a1c5a994dd088f847c61c9e85a8a3 not-for-merge branch 'testcommit3241' of github.com:jantman/gitpython_issue_301 -c96e9d25665e4d82773117e2ec73416704a2b172 not-for-merge branch 'testcommit3242' of github.com:jantman/gitpython_issue_301 -71b8def7858375e9784b5058b06cdee2a5afd3a5 not-for-merge branch 'testcommit3243' of github.com:jantman/gitpython_issue_301 -a1616b3c277737b4221d42b6f0eebaaba3a413b2 not-for-merge branch 'testcommit3244' of github.com:jantman/gitpython_issue_301 -ab8d732bef012568e6ba88765b9b7c5d9bfd044d not-for-merge branch 'testcommit3245' of github.com:jantman/gitpython_issue_301 -c4531d927d3f8ff1c93cbef43edb12144f5319e1 not-for-merge branch 'testcommit3246' of github.com:jantman/gitpython_issue_301 -5dcbf05dbed71edb03fc88504a9a389acc167628 not-for-merge branch 'testcommit3247' of github.com:jantman/gitpython_issue_301 -1e1e8fa7e12d4a65778917fa776bf31d6c172a32 not-for-merge branch 'testcommit3248' of github.com:jantman/gitpython_issue_301 -d44cf24d2c8f8d6df5e86dcaa08294223f665fc3 not-for-merge branch 'testcommit3249' of github.com:jantman/gitpython_issue_301 -67727507c300ff9fd434801b92952637bc2ae0c2 not-for-merge branch 'testcommit325' of github.com:jantman/gitpython_issue_301 -6950fdedcbf67ae771c923fac264b0032ccbb39d not-for-merge branch 'testcommit3250' of github.com:jantman/gitpython_issue_301 -797dc97294bc132e9a7700228e2afb60721f2927 not-for-merge branch 'testcommit3251' of github.com:jantman/gitpython_issue_301 -e59d2fa4aaf74c69946894eca02299a794427d9e not-for-merge branch 'testcommit3252' of github.com:jantman/gitpython_issue_301 -6767cd851cb484c779e2491bbdb7d4f9f71f4a93 not-for-merge branch 'testcommit3253' of github.com:jantman/gitpython_issue_301 -7e2607136a5e177716c835bc2093e7673ce12e80 not-for-merge branch 'testcommit3254' of github.com:jantman/gitpython_issue_301 -fc79de06daf5b1f760f50b61d186b3a7ec1f7aaf not-for-merge branch 'testcommit3255' of github.com:jantman/gitpython_issue_301 -d6dfb47b0cd2028de1c7287fabbce1161d03c1d2 not-for-merge branch 'testcommit3256' of github.com:jantman/gitpython_issue_301 -929350753647c43000cf87bb4d2d74ca60b02e38 not-for-merge branch 'testcommit3257' of github.com:jantman/gitpython_issue_301 -4ad7285a2dca21e136a2261775d54acc55ade8af not-for-merge branch 'testcommit3258' of github.com:jantman/gitpython_issue_301 -9efe673fb4c6470ce354b412819f988ba6bc371d not-for-merge branch 'testcommit3259' of github.com:jantman/gitpython_issue_301 -5ae0e294868d63bd32009b4682b72f8ef4a4b132 not-for-merge branch 'testcommit326' of github.com:jantman/gitpython_issue_301 -56a870e0b039d681b91e19a5c89095efa5272eb6 not-for-merge branch 'testcommit3260' of github.com:jantman/gitpython_issue_301 -c69b67208e8a288fa49298aa78cd296027d43e7b not-for-merge branch 'testcommit3261' of github.com:jantman/gitpython_issue_301 -33a20d5c51c15384d99ab714ef3fe2eaaa277134 not-for-merge branch 'testcommit3262' of github.com:jantman/gitpython_issue_301 -df70f74a288839df1e7a8f38c40e03965c759962 not-for-merge branch 'testcommit3263' of github.com:jantman/gitpython_issue_301 -4b3be6cf273358a9d4e18924fce986fa749d360e not-for-merge branch 'testcommit3264' of github.com:jantman/gitpython_issue_301 -b0853536a3dd5e604485cfd5f0d5dc13f553d215 not-for-merge branch 'testcommit3265' of github.com:jantman/gitpython_issue_301 -f71e87e4e39e0a7a35b7df661040ef2fff301d9c not-for-merge branch 'testcommit3266' of github.com:jantman/gitpython_issue_301 -da30095199650da647f47bb0b24c03de9e750850 not-for-merge branch 'testcommit3267' of github.com:jantman/gitpython_issue_301 -f4d0ed569cb9a042bbcb545bb4b3b6b9a28c5407 not-for-merge branch 'testcommit3268' of github.com:jantman/gitpython_issue_301 -1048c0d69eb5e7e7d0bdd966853b59146cd20de2 not-for-merge branch 'testcommit3269' of github.com:jantman/gitpython_issue_301 -96888d9d793609ff180a131fb12a027f97d97701 not-for-merge branch 'testcommit327' of github.com:jantman/gitpython_issue_301 -f641995b2a08f1e8955b15c77f3be76c077d4041 not-for-merge branch 'testcommit3270' of github.com:jantman/gitpython_issue_301 -04359ca5ecb19f950e9cc12f74deb43d7b6ead9e not-for-merge branch 'testcommit3271' of github.com:jantman/gitpython_issue_301 -72a5ab0d4d62fa20a04f3344d8df80ea33f13299 not-for-merge branch 'testcommit3272' of github.com:jantman/gitpython_issue_301 -46d0adc2499a7f3f567876fff74bbb2c7dbc5542 not-for-merge branch 'testcommit3273' of github.com:jantman/gitpython_issue_301 -e22d06931baff749c13514ff7227083fd735274e not-for-merge branch 'testcommit3274' of github.com:jantman/gitpython_issue_301 -6ea93b0544b800c8229de9d2daf3283c47163293 not-for-merge branch 'testcommit3275' of github.com:jantman/gitpython_issue_301 -626fc1422b478741a8204bca342c85bc0e4e404c not-for-merge branch 'testcommit3276' of github.com:jantman/gitpython_issue_301 -51713e7dab526f02f9b905f53c2fda95e195a868 not-for-merge branch 'testcommit3277' of github.com:jantman/gitpython_issue_301 -a020cbf33508798d865e7fa0855b54dd0dc57940 not-for-merge branch 'testcommit3278' of github.com:jantman/gitpython_issue_301 -145723d2a48d66b00620acc2c72434ab15f6d809 not-for-merge branch 'testcommit3279' of github.com:jantman/gitpython_issue_301 -7f57c39071554b60cf9da8615fb5079e49fce6d7 not-for-merge branch 'testcommit328' of github.com:jantman/gitpython_issue_301 -a9d16bad28d046382a5ea95019cd7d835be7c0eb not-for-merge branch 'testcommit3280' of github.com:jantman/gitpython_issue_301 -af1c3373c22aa937c7216e976324a16510374979 not-for-merge branch 'testcommit3281' of github.com:jantman/gitpython_issue_301 -d2c96c3c043e288ba0a5d9b40b684b5af4dcc069 not-for-merge branch 'testcommit3282' of github.com:jantman/gitpython_issue_301 -3fba0839769023c841d10f8a0ebb256ceccfa4ce not-for-merge branch 'testcommit3283' of github.com:jantman/gitpython_issue_301 -4aa99df62af5075bfdefa9b21df4a7b31cadf549 not-for-merge branch 'testcommit3284' of github.com:jantman/gitpython_issue_301 -593b926ce669858687305890e5705f55ded91030 not-for-merge branch 'testcommit3285' of github.com:jantman/gitpython_issue_301 -8eda75c3e84572a28be4f2f929549e2a9b469dbb not-for-merge branch 'testcommit3286' of github.com:jantman/gitpython_issue_301 -8aae2f41cd68feebfb72cd74da8ac0f085521396 not-for-merge branch 'testcommit3287' of github.com:jantman/gitpython_issue_301 -8be8e798c7b5ca4faa898a22540302f4e72536d7 not-for-merge branch 'testcommit3288' of github.com:jantman/gitpython_issue_301 -a49ed9c232fa00ec0807b0ac6c3f5bcc7b7a4b23 not-for-merge branch 'testcommit3289' of github.com:jantman/gitpython_issue_301 -77c4bb3ba7e76502898a9b3ab1ed88196edfd94e not-for-merge branch 'testcommit329' of github.com:jantman/gitpython_issue_301 -844a08808c86fbe2e81e90eb5cb54b6c82ffe25c not-for-merge branch 'testcommit3290' of github.com:jantman/gitpython_issue_301 -952b8d889474770b8b455a8044e56e873c144308 not-for-merge branch 'testcommit3291' of github.com:jantman/gitpython_issue_301 -2ffce0ad6bf485081cce51671db0339d55102bf7 not-for-merge branch 'testcommit3292' of github.com:jantman/gitpython_issue_301 -2419b315faf28f85be09193098560e8e5230dbcf not-for-merge branch 'testcommit3293' of github.com:jantman/gitpython_issue_301 -0e48ce79788ea5a6e00e7ed416b7c635c041d931 not-for-merge branch 'testcommit3294' of github.com:jantman/gitpython_issue_301 -df947b14bff373b4a30e5d6df97f8e7535d1776e not-for-merge branch 'testcommit3295' of github.com:jantman/gitpython_issue_301 -f3999c1c55dd1c5ecf33ba19e91d9a3b8e537973 not-for-merge branch 'testcommit3296' of github.com:jantman/gitpython_issue_301 -867929b2f6a5684399dacc471160f12d5d0ad4e6 not-for-merge branch 'testcommit3297' of github.com:jantman/gitpython_issue_301 -2e6e1b52810e6d10d0d4544ff64cf6fc65527d67 not-for-merge branch 'testcommit3298' of github.com:jantman/gitpython_issue_301 -ceaed6fcda89a11de67dc199afc922e2123d91b4 not-for-merge branch 'testcommit3299' of github.com:jantman/gitpython_issue_301 -b606e6388257425e1b2cdbb9564b4bbf482509c5 not-for-merge branch 'testcommit33' of github.com:jantman/gitpython_issue_301 -19580969d7d584783a74fa88c5c676c0cecba99a not-for-merge branch 'testcommit330' of github.com:jantman/gitpython_issue_301 -8c9b8c05bb5c0211c73c7bb8ca0fe1a5ade80169 not-for-merge branch 'testcommit3300' of github.com:jantman/gitpython_issue_301 -a242d715bce62cdb145895c9d5eae56512da2f80 not-for-merge branch 'testcommit3301' of github.com:jantman/gitpython_issue_301 -3509074311ceffc1f956713c6c9ee9a27949a1b0 not-for-merge branch 'testcommit3302' of github.com:jantman/gitpython_issue_301 -ba11ac5b0368e44a3e7e55b9c33598b28b5f7f7f not-for-merge branch 'testcommit3303' of github.com:jantman/gitpython_issue_301 -20458319a9b87474d66a31f667bf76e089917060 not-for-merge branch 'testcommit3304' of github.com:jantman/gitpython_issue_301 -70ea655b94dd1c6d39fc90a81ddcdc76485fc3b4 not-for-merge branch 'testcommit3305' of github.com:jantman/gitpython_issue_301 -55d8b2f782c1a10f314c2af5ccaf975f7eecde76 not-for-merge branch 'testcommit3306' of github.com:jantman/gitpython_issue_301 -a4dd253f67f3f9a36370da094c775e19ff784e92 not-for-merge branch 'testcommit3307' of github.com:jantman/gitpython_issue_301 -31a5e48d89b42597522c0fe27200b9a99275b640 not-for-merge branch 'testcommit3308' of github.com:jantman/gitpython_issue_301 -5e0ac7942db0d0d09cd2591d9ced7ac5044a3919 not-for-merge branch 'testcommit3309' of github.com:jantman/gitpython_issue_301 -a9d4134d9f50a1f7a7d7be925b819b6a2c8971ec not-for-merge branch 'testcommit331' of github.com:jantman/gitpython_issue_301 -5c8a9b4e0fa3dedb28a291f60f7b38dcd7ed66b6 not-for-merge branch 'testcommit3310' of github.com:jantman/gitpython_issue_301 -36bb1cb9046c6b76b890093c2244f6a91e8d23c3 not-for-merge branch 'testcommit3311' of github.com:jantman/gitpython_issue_301 -91810190fa163aa1b21b63dc2396ea55cf69b7a0 not-for-merge branch 'testcommit3312' of github.com:jantman/gitpython_issue_301 -986f6a24a837d98e84701429fd5a4d83956575cb not-for-merge branch 'testcommit3313' of github.com:jantman/gitpython_issue_301 -e52637b386dcee608b076fca97573d918183b3fd not-for-merge branch 'testcommit3314' of github.com:jantman/gitpython_issue_301 -f138b7809521cf9d64c7c0542adf3797f1cc8054 not-for-merge branch 'testcommit3315' of github.com:jantman/gitpython_issue_301 -ac7d8631567db9ca16b4aeca4bc345f610d45a2b not-for-merge branch 'testcommit3316' of github.com:jantman/gitpython_issue_301 -e2980145baed2200ddc1b599fc872995c59cbb05 not-for-merge branch 'testcommit3317' of github.com:jantman/gitpython_issue_301 -62f39a280ec4833cdc2e5cae8d24568cc4093eb1 not-for-merge branch 'testcommit3318' of github.com:jantman/gitpython_issue_301 -7c6f8d06b83bb1ffc80bb2508fd666dfd66ee2c5 not-for-merge branch 'testcommit3319' of github.com:jantman/gitpython_issue_301 -3d8648ce5f49b70a9c12e6be2e4c60cfcb75b057 not-for-merge branch 'testcommit332' of github.com:jantman/gitpython_issue_301 -946482e320278b065520711f8eeb940b069de44f not-for-merge branch 'testcommit3320' of github.com:jantman/gitpython_issue_301 -9294586a50aeedde770548653893972f7c805876 not-for-merge branch 'testcommit3321' of github.com:jantman/gitpython_issue_301 -1aba242a003088dd227afb74b82aed226bf9d26e not-for-merge branch 'testcommit3322' of github.com:jantman/gitpython_issue_301 -94aacd8ef48fcef25b90996937e46789a3dad2ce not-for-merge branch 'testcommit3323' of github.com:jantman/gitpython_issue_301 -825ab29c69a261a9c489478a396d387f9e8c3710 not-for-merge branch 'testcommit3324' of github.com:jantman/gitpython_issue_301 -9a6412c075cb48eef05a91f986ba8d51badbe42e not-for-merge branch 'testcommit3325' of github.com:jantman/gitpython_issue_301 -55762348856e4a4a66a633c08741603efc0dde3d not-for-merge branch 'testcommit3326' of github.com:jantman/gitpython_issue_301 -2be3069f58f6a5226baac4e5c9a091531ede8eac not-for-merge branch 'testcommit3327' of github.com:jantman/gitpython_issue_301 -1cc0930dceccc43dc51f5aac86d77369c6b62282 not-for-merge branch 'testcommit3328' of github.com:jantman/gitpython_issue_301 -039c7dbdda87bffdcad46ddbcde46e3908897f28 not-for-merge branch 'testcommit3329' of github.com:jantman/gitpython_issue_301 -6ceed68e94402cbe03e44a64e23b5b1f7acc4dc7 not-for-merge branch 'testcommit333' of github.com:jantman/gitpython_issue_301 -4213278301388bc0936bb72acdd433b17a4df60a not-for-merge branch 'testcommit3330' of github.com:jantman/gitpython_issue_301 -bb73dce2283d75d232f5882018d4fc0f90022f0f not-for-merge branch 'testcommit3331' of github.com:jantman/gitpython_issue_301 -9b725dd358f75df945b80a42474907fc19722024 not-for-merge branch 'testcommit3332' of github.com:jantman/gitpython_issue_301 -15e14bf1ffae08b1ffe64f36e2d46631f4690eb7 not-for-merge branch 'testcommit3333' of github.com:jantman/gitpython_issue_301 -8b5a12689adaeb5f2dd6b00fb70a3bfe5f8c0844 not-for-merge branch 'testcommit3334' of github.com:jantman/gitpython_issue_301 -ce611933cdf5ec62f00ce4baad38fc09961e8b9f not-for-merge branch 'testcommit3335' of github.com:jantman/gitpython_issue_301 -81d8dc8b548705cc0f3606a84fdf14a0dac63128 not-for-merge branch 'testcommit3336' of github.com:jantman/gitpython_issue_301 -b20684df50c703290c75a21b324d2efac1558814 not-for-merge branch 'testcommit3337' of github.com:jantman/gitpython_issue_301 -70ea09fb20c0fd6c6d6941285a5c156b159c0824 not-for-merge branch 'testcommit3338' of github.com:jantman/gitpython_issue_301 -154333cadcfe91e20d000ef8b4bd1c97ac8bcfe2 not-for-merge branch 'testcommit3339' of github.com:jantman/gitpython_issue_301 -ab6bfc48b9ed488da6461b5cd8b04b997da74b95 not-for-merge branch 'testcommit334' of github.com:jantman/gitpython_issue_301 -28d7870c610f6c2c2145497709522bc654393fe6 not-for-merge branch 'testcommit3340' of github.com:jantman/gitpython_issue_301 -d3841bee6760ed1696b236b47191caf3b4e8b344 not-for-merge branch 'testcommit3341' of github.com:jantman/gitpython_issue_301 -3cc9d0288790905f41b57139c2bbfffa64d97e44 not-for-merge branch 'testcommit3342' of github.com:jantman/gitpython_issue_301 -8fbccb2d7ecd7e11ccf342fea8e27de777b0a903 not-for-merge branch 'testcommit3343' of github.com:jantman/gitpython_issue_301 -4a5f0672ec9648b98833e91cdc8725a275ac6661 not-for-merge branch 'testcommit3344' of github.com:jantman/gitpython_issue_301 -ffb3634f7fa1e1e2e9c562b18be8865ab7f03139 not-for-merge branch 'testcommit3345' of github.com:jantman/gitpython_issue_301 -d91132b0ae947f7fae525a7e637054bef0024cd0 not-for-merge branch 'testcommit3346' of github.com:jantman/gitpython_issue_301 -6e7eba060ee5ab899d193f04889623cc0eff30cf not-for-merge branch 'testcommit3347' of github.com:jantman/gitpython_issue_301 -8e1992ca02f4f68968d2c4947fb4917ee721652c not-for-merge branch 'testcommit3348' of github.com:jantman/gitpython_issue_301 -925b5d68c0ec38ad65baaf90bbff53f0582b4e80 not-for-merge branch 'testcommit3349' of github.com:jantman/gitpython_issue_301 -434abe11e0936987ce440355dc6324a08cf4d104 not-for-merge branch 'testcommit335' of github.com:jantman/gitpython_issue_301 -cb31cf3528f4c946cb7977779fc06d2a6a3629c8 not-for-merge branch 'testcommit3350' of github.com:jantman/gitpython_issue_301 -7a51cd000169534975d03d5c49e2a487a98dde0b not-for-merge branch 'testcommit3351' of github.com:jantman/gitpython_issue_301 -dfa6520df0f4d15150d6f9ffa1dca38e7a6aeba7 not-for-merge branch 'testcommit3352' of github.com:jantman/gitpython_issue_301 -e04d102dcbee3526a603df8ab95906e554ab522f not-for-merge branch 'testcommit3353' of github.com:jantman/gitpython_issue_301 -c76a4c228b3c178dc270e945cde1ae89809f8c55 not-for-merge branch 'testcommit3354' of github.com:jantman/gitpython_issue_301 -2af949d68c0738594a438c037b84b1c2035142fd not-for-merge branch 'testcommit3355' of github.com:jantman/gitpython_issue_301 -2c10394e344dd4e48e1d600775725a6346253363 not-for-merge branch 'testcommit3356' of github.com:jantman/gitpython_issue_301 -a974dd0d10b67f978f0857ae4b328769c099754e not-for-merge branch 'testcommit3357' of github.com:jantman/gitpython_issue_301 -bcecf7ff289e1800db0dc3c332a64010b6978881 not-for-merge branch 'testcommit3358' of github.com:jantman/gitpython_issue_301 -0bce5bef637a161e93af097fe2703f494a6f813f not-for-merge branch 'testcommit3359' of github.com:jantman/gitpython_issue_301 -f1d5468a0e1d643ba6be89c72b13227e991d9e10 not-for-merge branch 'testcommit336' of github.com:jantman/gitpython_issue_301 -0b5074d1e238d6aff8ccbbbaee36bf2046885a29 not-for-merge branch 'testcommit3360' of github.com:jantman/gitpython_issue_301 -9cef3996c623f5454dc7fb9c5593766d681184bd not-for-merge branch 'testcommit3361' of github.com:jantman/gitpython_issue_301 -c0b9561d6025f6600b2fdb20e970a03fd8b0d7cb not-for-merge branch 'testcommit3362' of github.com:jantman/gitpython_issue_301 -b48c5f0157d9c11cc6b6683d7330029737036749 not-for-merge branch 'testcommit3363' of github.com:jantman/gitpython_issue_301 -0be69ca5f50d1986c8d182feef4f79b705ede481 not-for-merge branch 'testcommit3364' of github.com:jantman/gitpython_issue_301 -c6c20ec3c7bfca20d52aab382d7e7b177b7b93c5 not-for-merge branch 'testcommit3365' of github.com:jantman/gitpython_issue_301 -de77e6ca89c05e2ab0bdb3d2492d55c20cd3f2b7 not-for-merge branch 'testcommit3366' of github.com:jantman/gitpython_issue_301 -05d83fb014b7299a0ba2f0447d885f1129aa022b not-for-merge branch 'testcommit3367' of github.com:jantman/gitpython_issue_301 -8e22cffe3cb99b7c63afa9d1a60e785f85be634b not-for-merge branch 'testcommit3368' of github.com:jantman/gitpython_issue_301 -ba4d02428db5811112907a82a4eebca65be2fb17 not-for-merge branch 'testcommit3369' of github.com:jantman/gitpython_issue_301 -2d439c55c4c22d826686181fcbd938baf70092e4 not-for-merge branch 'testcommit337' of github.com:jantman/gitpython_issue_301 -747039611c0041bf04248e8dc8f3ec23137026fb not-for-merge branch 'testcommit3370' of github.com:jantman/gitpython_issue_301 -5f5e4eb055c477e3ba5c0c5da9c0fa1f46f5a016 not-for-merge branch 'testcommit3371' of github.com:jantman/gitpython_issue_301 -b826cf9dd50dd4bbadf895d64aecaa49aecfa8e7 not-for-merge branch 'testcommit3372' of github.com:jantman/gitpython_issue_301 -9488b06d0640e71332b5dadd5a237362a59d7e39 not-for-merge branch 'testcommit3373' of github.com:jantman/gitpython_issue_301 -2d2d1d6a467f0ac53296575f0f2243db1308ab43 not-for-merge branch 'testcommit3374' of github.com:jantman/gitpython_issue_301 -8580b605fdf472e80686491ade9213e7b6a625de not-for-merge branch 'testcommit3375' of github.com:jantman/gitpython_issue_301 -dcea3b0069f0e242db0b578628cdadd2629e5876 not-for-merge branch 'testcommit3376' of github.com:jantman/gitpython_issue_301 -6537e6bc8a1436a1a71ff7a4ddf8968a921eadde not-for-merge branch 'testcommit3377' of github.com:jantman/gitpython_issue_301 -83cfb0d38b3ab7cca1c22bd583267015647fe135 not-for-merge branch 'testcommit3378' of github.com:jantman/gitpython_issue_301 -d8d0ac9c4a1e65c15a263fb39dcfdc983f36dab2 not-for-merge branch 'testcommit3379' of github.com:jantman/gitpython_issue_301 -57005aea40208410c66df59fe9306dae0f6eb8e5 not-for-merge branch 'testcommit338' of github.com:jantman/gitpython_issue_301 -7fbe6ebab09acbda2d91cf80be657c7b11640c20 not-for-merge branch 'testcommit3380' of github.com:jantman/gitpython_issue_301 -853fdb2adfa55da166965c42f006c007c776a618 not-for-merge branch 'testcommit3381' of github.com:jantman/gitpython_issue_301 -77214fc5e42b2619decde7a47a9861c15964865b not-for-merge branch 'testcommit3382' of github.com:jantman/gitpython_issue_301 -59b7efdd7923aab63b2643531416ba9d241ca174 not-for-merge branch 'testcommit3383' of github.com:jantman/gitpython_issue_301 -011a81621798696da93d7a940567db67ff1131a4 not-for-merge branch 'testcommit3384' of github.com:jantman/gitpython_issue_301 -d5f8ab0bcca99ce74444fb7f5d0dd0a6cc77f3df not-for-merge branch 'testcommit3385' of github.com:jantman/gitpython_issue_301 -72bccd4eaa5a43665edca88ff7c275e27b49cfd5 not-for-merge branch 'testcommit3386' of github.com:jantman/gitpython_issue_301 -67ea152da6a589f5e1c508162825a24fe06f07a5 not-for-merge branch 'testcommit3387' of github.com:jantman/gitpython_issue_301 -c2f2b9a19ec3b6cac5441aa5e26524bb0afb4b24 not-for-merge branch 'testcommit3388' of github.com:jantman/gitpython_issue_301 -c945f8bb77b727ef2fd8d79c4932c9f7c1fe64c5 not-for-merge branch 'testcommit3389' of github.com:jantman/gitpython_issue_301 -b0f2cd0f6012d9b14eeb4a3b4959ac8e9d9e433e not-for-merge branch 'testcommit339' of github.com:jantman/gitpython_issue_301 -06c11f8dbfb7668b406eddba432587ec58bf4c89 not-for-merge branch 'testcommit3390' of github.com:jantman/gitpython_issue_301 -4de93bf7ca8a0fa7009403dfc5e861e1ed172f99 not-for-merge branch 'testcommit3391' of github.com:jantman/gitpython_issue_301 -cc22bbe59708d87597ca6013ec74348937352225 not-for-merge branch 'testcommit3392' of github.com:jantman/gitpython_issue_301 -b7dfd3d3eb9f9d73528cfb0bfc9581f6637d609b not-for-merge branch 'testcommit3393' of github.com:jantman/gitpython_issue_301 -4d41e0c56c4432e5bfd55219e6fbee5a6097507b not-for-merge branch 'testcommit3394' of github.com:jantman/gitpython_issue_301 -79b2c50ad9b99d1ccc36a5f25c68f8ffd5294514 not-for-merge branch 'testcommit3395' of github.com:jantman/gitpython_issue_301 -ef6d2d6cbbb5cb4f684a770fe5346f67d16c7484 not-for-merge branch 'testcommit3396' of github.com:jantman/gitpython_issue_301 -34edadf4847c1d0a41f32baad2b01f9d25f3c6d7 not-for-merge branch 'testcommit3397' of github.com:jantman/gitpython_issue_301 -0462689329222656c97e15a87dd92708d1157765 not-for-merge branch 'testcommit3398' of github.com:jantman/gitpython_issue_301 -998cbec7f04fbc33e2dcd7b0ebbed1c632fa1af9 not-for-merge branch 'testcommit3399' of github.com:jantman/gitpython_issue_301 -fa391b6aea1cd11d71a77c0e30b6fa52b74fcbba not-for-merge branch 'testcommit34' of github.com:jantman/gitpython_issue_301 -97f003d39df2ee02070fed09b02977cea61f3886 not-for-merge branch 'testcommit340' of github.com:jantman/gitpython_issue_301 -2791a05cb53972c73aa0f9e22aa19c5ecbf2850b not-for-merge branch 'testcommit3400' of github.com:jantman/gitpython_issue_301 -843a0d0c2289481780ebc1c46f55d0458e1f1ed4 not-for-merge branch 'testcommit3401' of github.com:jantman/gitpython_issue_301 -b3a8f90be64d7fad685469f6105b8514f400f965 not-for-merge branch 'testcommit3402' of github.com:jantman/gitpython_issue_301 -e9461779adc6d842192f523be3fd448ff8658ef0 not-for-merge branch 'testcommit3403' of github.com:jantman/gitpython_issue_301 -6b35a64d5faaabbeb6ad4e777bff13086347bc75 not-for-merge branch 'testcommit3404' of github.com:jantman/gitpython_issue_301 -fac007c21a114c0edf50d3b07155c69ebc7dc8ac not-for-merge branch 'testcommit3405' of github.com:jantman/gitpython_issue_301 -5ae82dbc5460838f9963a0560f11e503d409c156 not-for-merge branch 'testcommit3406' of github.com:jantman/gitpython_issue_301 -a451d1a379978f0099b114002dabe2df9d2cd238 not-for-merge branch 'testcommit3407' of github.com:jantman/gitpython_issue_301 -c28feb1e0742c0e1d5057a7de5fa294cad0f3315 not-for-merge branch 'testcommit3408' of github.com:jantman/gitpython_issue_301 -3be92caf3be3ea94695b71d44b62352b1b71fb22 not-for-merge branch 'testcommit3409' of github.com:jantman/gitpython_issue_301 -b8bca81fbbb92e13d9229f7203721ccf1cf6a3e5 not-for-merge branch 'testcommit341' of github.com:jantman/gitpython_issue_301 -0bee4cb69df1b686192fb5679b25d8eff2ae5f7f not-for-merge branch 'testcommit3410' of github.com:jantman/gitpython_issue_301 -b5beb53b21c008d5ab0018dd0e794337190e706a not-for-merge branch 'testcommit3411' of github.com:jantman/gitpython_issue_301 -9ef57a524c00fa4967a55a99c77240607968fb2d not-for-merge branch 'testcommit3412' of github.com:jantman/gitpython_issue_301 -e347c421e5f9ab7cf7a623eec2f8d18e456f7a62 not-for-merge branch 'testcommit3413' of github.com:jantman/gitpython_issue_301 -3b3d71282323712ef2f154bc6e0d05b83ce6923f not-for-merge branch 'testcommit3414' of github.com:jantman/gitpython_issue_301 -746cbc7753a923f31657817ac3789228bf872418 not-for-merge branch 'testcommit3415' of github.com:jantman/gitpython_issue_301 -3b9dd7a3965310d1cbc4d264223880b6a3191f6c not-for-merge branch 'testcommit3416' of github.com:jantman/gitpython_issue_301 -a74afd35f1263f4afe05e5fbdc85fe98fc7a79a8 not-for-merge branch 'testcommit3417' of github.com:jantman/gitpython_issue_301 -3df24b48b31fa187114dd70b5bfccc5daee8c1d4 not-for-merge branch 'testcommit3418' of github.com:jantman/gitpython_issue_301 -6438dbd340bd8fb38bfb366b37d42edf7968dfe0 not-for-merge branch 'testcommit3419' of github.com:jantman/gitpython_issue_301 -d64fec53cb5ecf98922655d99951dc66bdad16dc not-for-merge branch 'testcommit342' of github.com:jantman/gitpython_issue_301 -d0461058eaadaa3b78009589af4b6d1fde9e47fc not-for-merge branch 'testcommit3420' of github.com:jantman/gitpython_issue_301 -b68955077a0da44f25f8278a7265f980f53d05aa not-for-merge branch 'testcommit3421' of github.com:jantman/gitpython_issue_301 -5d0504ea9db4406b698ff8dbb9501b8c528ca503 not-for-merge branch 'testcommit3422' of github.com:jantman/gitpython_issue_301 -158aca170ed308f13597b201585a929bbe941050 not-for-merge branch 'testcommit3423' of github.com:jantman/gitpython_issue_301 -9f25164eae86e2fd6503f170dbe565f2aa10faa8 not-for-merge branch 'testcommit3424' of github.com:jantman/gitpython_issue_301 -8076cac738e8ee62a5b91aa3167681872b8567f5 not-for-merge branch 'testcommit3425' of github.com:jantman/gitpython_issue_301 -f853aa650a5b892b937adb40ecec4af510e4dbd9 not-for-merge branch 'testcommit3426' of github.com:jantman/gitpython_issue_301 -5ef91b23926bab823fb8e7a03434d67f950f1ded not-for-merge branch 'testcommit3427' of github.com:jantman/gitpython_issue_301 -55c2866bbf9c7f931bf7759f260800bf51bd56ca not-for-merge branch 'testcommit3428' of github.com:jantman/gitpython_issue_301 -688a109516e9f5cd91baea1bfea953900865185b not-for-merge branch 'testcommit3429' of github.com:jantman/gitpython_issue_301 -4ed449ee5d10398fe17f1bd3d3f85defbed38d59 not-for-merge branch 'testcommit343' of github.com:jantman/gitpython_issue_301 -7cf4ae4fb14a8405de93e8242e6c0dcabde99d44 not-for-merge branch 'testcommit3430' of github.com:jantman/gitpython_issue_301 -0f894f8294c2da571c163ce99db83f5b7304b6ff not-for-merge branch 'testcommit3431' of github.com:jantman/gitpython_issue_301 -0f502eab9ebc54b81426e7dd64e6ecec7ee3e7cd not-for-merge branch 'testcommit3432' of github.com:jantman/gitpython_issue_301 -b1c60aad57f85c182c97d0b0eb4fda1c4aa248aa not-for-merge branch 'testcommit3433' of github.com:jantman/gitpython_issue_301 -0c93b5b502add319e3c95b29cd9f3bd1f794d1ce not-for-merge branch 'testcommit3434' of github.com:jantman/gitpython_issue_301 -fbf492146d79c8ce03ba2bc383ea00c538f2c0d5 not-for-merge branch 'testcommit3435' of github.com:jantman/gitpython_issue_301 -703ab63cdd9f3e7c49a1128b5455b470a78994ce not-for-merge branch 'testcommit3436' of github.com:jantman/gitpython_issue_301 -ab52f85abbb192f7f9769491693f6d9c45a3b9f6 not-for-merge branch 'testcommit3437' of github.com:jantman/gitpython_issue_301 -5237e2e4673b1acb6ed703202f31582d22412a11 not-for-merge branch 'testcommit3438' of github.com:jantman/gitpython_issue_301 -f7b823ff6b581462f1b344a73069359bbd8b25e5 not-for-merge branch 'testcommit3439' of github.com:jantman/gitpython_issue_301 -1f03c0694248b34d12e5e6d69bfcfbd4845fdfd6 not-for-merge branch 'testcommit344' of github.com:jantman/gitpython_issue_301 -a8f6141dd239d02d4beae605a202398f1cd70492 not-for-merge branch 'testcommit3440' of github.com:jantman/gitpython_issue_301 -385c325a6d704def0585018013f13c8f650e95ad not-for-merge branch 'testcommit3441' of github.com:jantman/gitpython_issue_301 -c6726342266cdf7b380e13892c3e1bd7655ddb0d not-for-merge branch 'testcommit3442' of github.com:jantman/gitpython_issue_301 -6cb1e00a6053c6c8c17d4fcbf2fc1c1693fe6d30 not-for-merge branch 'testcommit3443' of github.com:jantman/gitpython_issue_301 -484a0b2b2d6dce16747a05ceb859a4fca7b521ce not-for-merge branch 'testcommit3444' of github.com:jantman/gitpython_issue_301 -d5dc0f235d3ad6a88b751f0da86017806ee255a5 not-for-merge branch 'testcommit3445' of github.com:jantman/gitpython_issue_301 -5dbf63d32c6beb7b38b32b925201ab8527b03418 not-for-merge branch 'testcommit3446' of github.com:jantman/gitpython_issue_301 -6b28def3de118e15d14d0943f617a84a026a137b not-for-merge branch 'testcommit3447' of github.com:jantman/gitpython_issue_301 -6489ad5b9a9c681ecc8c62c46cd0b8a331d47027 not-for-merge branch 'testcommit3448' of github.com:jantman/gitpython_issue_301 -67640817a7b89e35579b08a179e401db33452f6a not-for-merge branch 'testcommit3449' of github.com:jantman/gitpython_issue_301 -d3a0b3d489f6c1ff7a94c53d1715c184d8996a8b not-for-merge branch 'testcommit345' of github.com:jantman/gitpython_issue_301 -fcb2b5541b19891ba474c8c6f5e935a9b62a9002 not-for-merge branch 'testcommit3450' of github.com:jantman/gitpython_issue_301 -f62907a580fb0ac7c7cd9828f0c7e941999a29e7 not-for-merge branch 'testcommit3451' of github.com:jantman/gitpython_issue_301 -b2f69e2c9ea5ec8324442760eda25a7266ed97e7 not-for-merge branch 'testcommit3452' of github.com:jantman/gitpython_issue_301 -6034f14e4687c46bc9b1a30ded493d7bacc7dadd not-for-merge branch 'testcommit3453' of github.com:jantman/gitpython_issue_301 -2db35b6fafda5ef30b548eb7d289d58f86cae0bd not-for-merge branch 'testcommit3454' of github.com:jantman/gitpython_issue_301 -cdf8078bd5330b387400db4e6d1fd6107cbe5dac not-for-merge branch 'testcommit3455' of github.com:jantman/gitpython_issue_301 -08fbd0f723c850b32e7b223ac0443c2b6e8be2bc not-for-merge branch 'testcommit3456' of github.com:jantman/gitpython_issue_301 -7ad45d4d2d2b285024cff6401d04d98da1fcb8d2 not-for-merge branch 'testcommit3457' of github.com:jantman/gitpython_issue_301 -56557fde01a928159b9770f90b926d013943d4eb not-for-merge branch 'testcommit3458' of github.com:jantman/gitpython_issue_301 -ddffb641c0b9658f724c441ac0df513b0169ba13 not-for-merge branch 'testcommit3459' of github.com:jantman/gitpython_issue_301 -631da8acae5866f6e3b89fe93e8b76b6c08604c2 not-for-merge branch 'testcommit346' of github.com:jantman/gitpython_issue_301 -c823a563b8d6c416cf0afb3ef42b944c8d6273c3 not-for-merge branch 'testcommit3460' of github.com:jantman/gitpython_issue_301 -6f091766af383c9605f526497b330dfca3e05913 not-for-merge branch 'testcommit3461' of github.com:jantman/gitpython_issue_301 -d26efed758a860cf54d36b61542d2722c23c3b8f not-for-merge branch 'testcommit3462' of github.com:jantman/gitpython_issue_301 -1ec65a1e7fed2d9ab7573416ab103f0ae3c6b919 not-for-merge branch 'testcommit3463' of github.com:jantman/gitpython_issue_301 -70b73e9cdb060d0bed9e454b42edba816f7271c0 not-for-merge branch 'testcommit3464' of github.com:jantman/gitpython_issue_301 -25ab7e388a6e5719a13382fab11f211932c53848 not-for-merge branch 'testcommit3465' of github.com:jantman/gitpython_issue_301 -bf26f1783b8cde40110729def5c9a4d31dc0932c not-for-merge branch 'testcommit3466' of github.com:jantman/gitpython_issue_301 -6bad86cb8dc119d801957cad71289cdd7462f7a6 not-for-merge branch 'testcommit3467' of github.com:jantman/gitpython_issue_301 -95df4264212b46e3d987e7ea043ce4aea453a0cc not-for-merge branch 'testcommit3468' of github.com:jantman/gitpython_issue_301 -da501c449073fea4f196839d9c38f93dd96439b1 not-for-merge branch 'testcommit3469' of github.com:jantman/gitpython_issue_301 -3fc1e2d1419ee7137f0a909f728e3c8b89045fbb not-for-merge branch 'testcommit347' of github.com:jantman/gitpython_issue_301 -57b844d9637cecf7adc14cfce93fc792cab14216 not-for-merge branch 'testcommit3470' of github.com:jantman/gitpython_issue_301 -9c375dc219edecda376f30b01158783a5739d65b not-for-merge branch 'testcommit3471' of github.com:jantman/gitpython_issue_301 -57e22e6e408f74b3ae1a14a16b411821bebb8de7 not-for-merge branch 'testcommit3472' of github.com:jantman/gitpython_issue_301 -e6c0495e2c0956fa5c8f57793bfa0b69f1622352 not-for-merge branch 'testcommit3473' of github.com:jantman/gitpython_issue_301 -1863058c4529b1f84f8ee806a1ddcbd234be0040 not-for-merge branch 'testcommit3474' of github.com:jantman/gitpython_issue_301 -f2583decabf7848abc622306062baad1e7179c78 not-for-merge branch 'testcommit3475' of github.com:jantman/gitpython_issue_301 -00454eb51b614bcb7afe2408aee22a73c2f3e749 not-for-merge branch 'testcommit3476' of github.com:jantman/gitpython_issue_301 -be00589e21fe7ff8249faf65a313141d40f33893 not-for-merge branch 'testcommit3477' of github.com:jantman/gitpython_issue_301 -fa79d444fa173109f14c2fe25e731491768eed6b not-for-merge branch 'testcommit3478' of github.com:jantman/gitpython_issue_301 -b88a29ec867a166d4976d0b3705e5c1ca4399ca0 not-for-merge branch 'testcommit3479' of github.com:jantman/gitpython_issue_301 -3ba2f4b9d05c69fca7c387032ca63fb054fd1bd6 not-for-merge branch 'testcommit348' of github.com:jantman/gitpython_issue_301 -ee0ed69085d7b10ea4ad9fc7e7f5b583dc5f2e4c not-for-merge branch 'testcommit3480' of github.com:jantman/gitpython_issue_301 -3fcefa715674bc64fb36bd46675e8121fb135db3 not-for-merge branch 'testcommit3481' of github.com:jantman/gitpython_issue_301 -614cb228b296231bf60d58c519019765530d0271 not-for-merge branch 'testcommit3482' of github.com:jantman/gitpython_issue_301 -9cf4c7aeb3f83d1202294967208c55f9ea6af044 not-for-merge branch 'testcommit3483' of github.com:jantman/gitpython_issue_301 -fa65c6bba6c8a05e84ac3951e1aac4e72e5fa016 not-for-merge branch 'testcommit3484' of github.com:jantman/gitpython_issue_301 -e745e02b111d49f74471fce73f243bbbf52dd1c6 not-for-merge branch 'testcommit3485' of github.com:jantman/gitpython_issue_301 -ea7cd5a3cf4334c2289196795890a14398e0477e not-for-merge branch 'testcommit3486' of github.com:jantman/gitpython_issue_301 -2d1f242553e19906dff767220122e8e9e5941763 not-for-merge branch 'testcommit3487' of github.com:jantman/gitpython_issue_301 -b53e599df2dc5cda61f8d4e1af351db3cb75d811 not-for-merge branch 'testcommit3488' of github.com:jantman/gitpython_issue_301 -f0c42010514060dbe25194ddbc1c0a3644d76cc4 not-for-merge branch 'testcommit3489' of github.com:jantman/gitpython_issue_301 -88735d17b4989726ef49e90cbed6f22977dcadcc not-for-merge branch 'testcommit349' of github.com:jantman/gitpython_issue_301 -3cf6b5612b4f1dc5ccafa09082c20168695bc3a2 not-for-merge branch 'testcommit3490' of github.com:jantman/gitpython_issue_301 -42616fd47140bd61d6246cd1debfc24b679a321c not-for-merge branch 'testcommit3491' of github.com:jantman/gitpython_issue_301 -a30568dd9c59ec0545997b7625ccd868bab07e66 not-for-merge branch 'testcommit3492' of github.com:jantman/gitpython_issue_301 -f0f1f6456c400daf2d475b6d813562b88ffe3ff1 not-for-merge branch 'testcommit3493' of github.com:jantman/gitpython_issue_301 -3b0af110283f73fe1448768351d3267c05bf76cb not-for-merge branch 'testcommit3494' of github.com:jantman/gitpython_issue_301 -7eeb7e5cbbe0615c5971328f03330bf9738bb1d0 not-for-merge branch 'testcommit3495' of github.com:jantman/gitpython_issue_301 -edd4dd54930378ea6c37ff503dc7efad30086168 not-for-merge branch 'testcommit3496' of github.com:jantman/gitpython_issue_301 -eeffe1007d813ce84269647a2a8ca367f8068a6f not-for-merge branch 'testcommit3497' of github.com:jantman/gitpython_issue_301 -3f7e1c6313b132f272409974fca1f7ef111e5446 not-for-merge branch 'testcommit3498' of github.com:jantman/gitpython_issue_301 -c1a3da32691b85021afc85d9cd69cde91fbcf82d not-for-merge branch 'testcommit3499' of github.com:jantman/gitpython_issue_301 -2681351a6497e85d8f2faadc826f9c358c3e633e not-for-merge branch 'testcommit35' of github.com:jantman/gitpython_issue_301 -45faf96948c2f556bd8fae5df9115cb630dd1515 not-for-merge branch 'testcommit350' of github.com:jantman/gitpython_issue_301 -079c9a08bafbc4822f2b1561bb06d194529b936f not-for-merge branch 'testcommit3500' of github.com:jantman/gitpython_issue_301 -d746f5b0e2a7f18b1e192759c879450c984a5092 not-for-merge branch 'testcommit3501' of github.com:jantman/gitpython_issue_301 -b3e4de99100c120fead11d5b33a6b9ba301c85ab not-for-merge branch 'testcommit3502' of github.com:jantman/gitpython_issue_301 -47532933369d97709fb3c2e1ba18dcd56e3c62bc not-for-merge branch 'testcommit3503' of github.com:jantman/gitpython_issue_301 -1a6570f4b197f9869a96a18eeba066b7ef8a6654 not-for-merge branch 'testcommit3504' of github.com:jantman/gitpython_issue_301 -35bffeef6f9aa1f40d5c1faf88351758bd512cef not-for-merge branch 'testcommit3505' of github.com:jantman/gitpython_issue_301 -7980882c0c609ef038aa58be3b99ba4eb2d2c58c not-for-merge branch 'testcommit3506' of github.com:jantman/gitpython_issue_301 -7ac26c5ebd47326a347d5d01d9362747d00d5043 not-for-merge branch 'testcommit3507' of github.com:jantman/gitpython_issue_301 -0c9456cd2b773aa005e6119aff2947144c0781c5 not-for-merge branch 'testcommit3508' of github.com:jantman/gitpython_issue_301 -92424f64313cafa5e9e62bb04ba76c53dec756ff not-for-merge branch 'testcommit3509' of github.com:jantman/gitpython_issue_301 -51048d8afebb5d3508845596972ff9eee4999598 not-for-merge branch 'testcommit351' of github.com:jantman/gitpython_issue_301 -8b6b28ed471800a9f32c009cd4cfb9bc7f75073b not-for-merge branch 'testcommit3510' of github.com:jantman/gitpython_issue_301 -b9b7739fb90dbbfa00aa8a55c3846c3e2dfd069c not-for-merge branch 'testcommit3511' of github.com:jantman/gitpython_issue_301 -49e0b1f8408dcc2597f63cbb37b87d51b4db208d not-for-merge branch 'testcommit3512' of github.com:jantman/gitpython_issue_301 -5d479a69e5efcb9656745a5fa63e0feb194dc15d not-for-merge branch 'testcommit3513' of github.com:jantman/gitpython_issue_301 -df00298ae610a7b7efc82490b272ba3732cf157d not-for-merge branch 'testcommit3514' of github.com:jantman/gitpython_issue_301 -c6c509fba53095de43d48a5693c63b7390f44fb8 not-for-merge branch 'testcommit3515' of github.com:jantman/gitpython_issue_301 -73cfb7086291fa3be981aefd35ea67ddbe54d992 not-for-merge branch 'testcommit3516' of github.com:jantman/gitpython_issue_301 -479587c484bbcbbdf9833ef4ce4ec67d6dc65196 not-for-merge branch 'testcommit3517' of github.com:jantman/gitpython_issue_301 -4d65b2edd3841bbde7a455e76e60a1c85be48f77 not-for-merge branch 'testcommit3518' of github.com:jantman/gitpython_issue_301 -6526cde0de53de4cc5bc7df1f0e2e2ff2768b2c5 not-for-merge branch 'testcommit3519' of github.com:jantman/gitpython_issue_301 -e7b2ccfa40700cf4983a7d77d3a3cc447b431e8c not-for-merge branch 'testcommit352' of github.com:jantman/gitpython_issue_301 -b8bc685dd7cb2d5665f936043e3b7dd8f4d44ebb not-for-merge branch 'testcommit3520' of github.com:jantman/gitpython_issue_301 -23645cd4ce9f5a03a5ce733bf051e068e0c38eb4 not-for-merge branch 'testcommit3521' of github.com:jantman/gitpython_issue_301 -05b1fcc8e4d4a2f0a3d3ed2abef9edbd53796aa3 not-for-merge branch 'testcommit3522' of github.com:jantman/gitpython_issue_301 -df021eae381fa907e27aefb45257810496759ffc not-for-merge branch 'testcommit3523' of github.com:jantman/gitpython_issue_301 -54c8232e239919db025ee6b0d550055c9a2fe80d not-for-merge branch 'testcommit3524' of github.com:jantman/gitpython_issue_301 -275afaee7ce6a1645c2ca932c7bfd625b6fa4898 not-for-merge branch 'testcommit3525' of github.com:jantman/gitpython_issue_301 -61139fcd9b64ae9324188543824c7ec215b87f46 not-for-merge branch 'testcommit3526' of github.com:jantman/gitpython_issue_301 -95c1acf27cb92da36c8075ae099ad553b9cbf86d not-for-merge branch 'testcommit3527' of github.com:jantman/gitpython_issue_301 -2d8d625ae3a4c5a10c99fde1a49d6e2964f91009 not-for-merge branch 'testcommit3528' of github.com:jantman/gitpython_issue_301 -82e31be5f491bbc74e3b3825bbbc89cfd124d495 not-for-merge branch 'testcommit3529' of github.com:jantman/gitpython_issue_301 -725966a241e87f8328c2fa925eaf957a68dfc0e0 not-for-merge branch 'testcommit353' of github.com:jantman/gitpython_issue_301 -5d498b3d2ee20dd3a3ed342a30062f9aa0997055 not-for-merge branch 'testcommit3530' of github.com:jantman/gitpython_issue_301 -19b747c9be38c337fee1ee2585760434e624122a not-for-merge branch 'testcommit3531' of github.com:jantman/gitpython_issue_301 -eb013b79ff2a1569d8930f567b8e1377693ec65d not-for-merge branch 'testcommit3532' of github.com:jantman/gitpython_issue_301 -7f8b935d4978c052c910323cf2547781d8648e86 not-for-merge branch 'testcommit3533' of github.com:jantman/gitpython_issue_301 -ffeb2ec90095a218c19e7def99f4b78dcd116855 not-for-merge branch 'testcommit3534' of github.com:jantman/gitpython_issue_301 -f10048ce7b8afba418ee6ef9a93a02978d04d74c not-for-merge branch 'testcommit3535' of github.com:jantman/gitpython_issue_301 -baf270f4d916c6621b46021b2339b252fbdc96fb not-for-merge branch 'testcommit3536' of github.com:jantman/gitpython_issue_301 -0243d417c97a09636502eecda822bc931594af0d not-for-merge branch 'testcommit3537' of github.com:jantman/gitpython_issue_301 -31f133e50801705780dcbe0f8a863cf3029dbc1d not-for-merge branch 'testcommit3538' of github.com:jantman/gitpython_issue_301 -7d964cf9ab0412f51e866ca0f651da8f4618bb76 not-for-merge branch 'testcommit3539' of github.com:jantman/gitpython_issue_301 -1f56b7629b97f3da517bb1e5c75b74575da6992c not-for-merge branch 'testcommit354' of github.com:jantman/gitpython_issue_301 -64edeefeb1e61f9cea681aa4b183bb668deddc91 not-for-merge branch 'testcommit3540' of github.com:jantman/gitpython_issue_301 -82b26f277093bfbee3ecf77a0172741e65d1222c not-for-merge branch 'testcommit3541' of github.com:jantman/gitpython_issue_301 -04b9fc14688b04a63e71973b162eee495ee3e00a not-for-merge branch 'testcommit3542' of github.com:jantman/gitpython_issue_301 -1d1c0e284c4edeb6aa56bc385133bba660997899 not-for-merge branch 'testcommit3543' of github.com:jantman/gitpython_issue_301 -5f049e0207d0044a009dd4deb5720288edb8ab1d not-for-merge branch 'testcommit3544' of github.com:jantman/gitpython_issue_301 -40d72345b53b52e29af2901b7c3d37fb4a3a590e not-for-merge branch 'testcommit3545' of github.com:jantman/gitpython_issue_301 -0a6333776e18cce42fb15ea3780c9a1695905b8d not-for-merge branch 'testcommit3546' of github.com:jantman/gitpython_issue_301 -c38cbf54637540047cd8c9f1446fe68a76e8c6b5 not-for-merge branch 'testcommit3547' of github.com:jantman/gitpython_issue_301 -8bdd62c3f2a7cd12af7ef4c61d90eaf5109c415e not-for-merge branch 'testcommit3548' of github.com:jantman/gitpython_issue_301 -532b7053c7efe8c24e3cbb136d58a4eea7f5a25c not-for-merge branch 'testcommit3549' of github.com:jantman/gitpython_issue_301 -0a84bb17a563a2c507b14ccd3f243e4ff5bc5d13 not-for-merge branch 'testcommit355' of github.com:jantman/gitpython_issue_301 -7a11ec6604f61432aa55d1d885d7b08928277892 not-for-merge branch 'testcommit3550' of github.com:jantman/gitpython_issue_301 -9cf349c5488ac038205cb13fbf4bb2f4e3f474d6 not-for-merge branch 'testcommit3551' of github.com:jantman/gitpython_issue_301 -8858fd89e1e935cd894ab04f3e444e3ac27fa032 not-for-merge branch 'testcommit3552' of github.com:jantman/gitpython_issue_301 -05e5000a9eb7a7d0bc7584c6139f44eb5ada763b not-for-merge branch 'testcommit3553' of github.com:jantman/gitpython_issue_301 -ced3669c88984a8bf739f92dc2256654504be5ae not-for-merge branch 'testcommit3554' of github.com:jantman/gitpython_issue_301 -352c2c98b551f4bc11237b0bf46bf69f4514741f not-for-merge branch 'testcommit3555' of github.com:jantman/gitpython_issue_301 -aec581b02c582f40009891fa3e9df8a9b0de0d40 not-for-merge branch 'testcommit3556' of github.com:jantman/gitpython_issue_301 -7ad82f13ae3bad1d72a15246bcc3f576f142d8c1 not-for-merge branch 'testcommit3557' of github.com:jantman/gitpython_issue_301 -676b2ed5d545fb1e808ff86de32b20db4ce4a603 not-for-merge branch 'testcommit3558' of github.com:jantman/gitpython_issue_301 -d83d8b930677a2135f8a4e7ccd2106d9dd3149c4 not-for-merge branch 'testcommit3559' of github.com:jantman/gitpython_issue_301 -86c324fa6465a5e313a749859ff644f44701eec5 not-for-merge branch 'testcommit356' of github.com:jantman/gitpython_issue_301 -cfb89d42cf00b55d061d8037009591cb9fba7a26 not-for-merge branch 'testcommit3560' of github.com:jantman/gitpython_issue_301 -9cfadfee26e98c17a05a27817ae387698133a9f7 not-for-merge branch 'testcommit3561' of github.com:jantman/gitpython_issue_301 -cea8d3b7b23aaa4a311ddbc0a364cd314874332d not-for-merge branch 'testcommit3562' of github.com:jantman/gitpython_issue_301 -2a813ae608c43d32fb252ea6158c5d9e497811a2 not-for-merge branch 'testcommit3563' of github.com:jantman/gitpython_issue_301 -d3818e94bd6f27bf56c9397627d3c0a02654eb22 not-for-merge branch 'testcommit3564' of github.com:jantman/gitpython_issue_301 -643916b72d27d6be35e603147453bb4a5d0b0b01 not-for-merge branch 'testcommit3565' of github.com:jantman/gitpython_issue_301 -2e5a2da210d8abce34a5434b8c91debe9a6747db not-for-merge branch 'testcommit3566' of github.com:jantman/gitpython_issue_301 -e1e433a3de58cefd9c224ff7087180114c76529d not-for-merge branch 'testcommit3567' of github.com:jantman/gitpython_issue_301 -656b4ec04e932aba08bf02e39228b036bb9c44f5 not-for-merge branch 'testcommit3568' of github.com:jantman/gitpython_issue_301 -21156cc5345ef750c887373ccd3e11ba7c6bd7e2 not-for-merge branch 'testcommit3569' of github.com:jantman/gitpython_issue_301 -edfe6f21906e94f6aff3724e591367a150547e20 not-for-merge branch 'testcommit357' of github.com:jantman/gitpython_issue_301 -ccad2b0b944476f6361aa64f0087472b19ff1e91 not-for-merge branch 'testcommit3570' of github.com:jantman/gitpython_issue_301 -2625f1f5e7abe957ac8aaa4204b08d1c7a7a74c1 not-for-merge branch 'testcommit3571' of github.com:jantman/gitpython_issue_301 -1edebb9f39f2669a287aa2eae14d114cb0c507ac not-for-merge branch 'testcommit3572' of github.com:jantman/gitpython_issue_301 -9f1dfe442887ed1a390cad1797603d4a20f9a0f6 not-for-merge branch 'testcommit3573' of github.com:jantman/gitpython_issue_301 -0e673a904a1e4023cad5db412863538914c60b9a not-for-merge branch 'testcommit3574' of github.com:jantman/gitpython_issue_301 -b87bf111a69c54b3ce3a2bcb7f6e451cdabedd7f not-for-merge branch 'testcommit3575' of github.com:jantman/gitpython_issue_301 -48b627a3b6d1a6f8bb5a0f3cfaec7f2c887b8cf5 not-for-merge branch 'testcommit3576' of github.com:jantman/gitpython_issue_301 -7510719110d335b6902fbf5bdc80faf1a590cadb not-for-merge branch 'testcommit3577' of github.com:jantman/gitpython_issue_301 -9b629e8744d9dcdaef93b8c6747033e2526cb281 not-for-merge branch 'testcommit3578' of github.com:jantman/gitpython_issue_301 -6157835f6626affb326916331d0eb7f8adc1daca not-for-merge branch 'testcommit3579' of github.com:jantman/gitpython_issue_301 -0933e24600b075433d01e1dd081c05016700a3fd not-for-merge branch 'testcommit358' of github.com:jantman/gitpython_issue_301 -cc3ce4fccc43fb969b469a8551281dfcd781c47f not-for-merge branch 'testcommit3580' of github.com:jantman/gitpython_issue_301 -cd1e5538a28cdda20e163c2a5cea60b2c250d88e not-for-merge branch 'testcommit3581' of github.com:jantman/gitpython_issue_301 -deda6832e0afe4e09d2c310978e0325d6b3f8656 not-for-merge branch 'testcommit3582' of github.com:jantman/gitpython_issue_301 -37460240a1b5dc8867b54e5d5ace138a81b3bcee not-for-merge branch 'testcommit3583' of github.com:jantman/gitpython_issue_301 -de18d5071881b6fcf48409bf40874db34b226932 not-for-merge branch 'testcommit3584' of github.com:jantman/gitpython_issue_301 -b71e1079226649d17665471357f574a99283aaf1 not-for-merge branch 'testcommit3585' of github.com:jantman/gitpython_issue_301 -88b43c7193907134990d04c2f1b204b7d1535ea0 not-for-merge branch 'testcommit3586' of github.com:jantman/gitpython_issue_301 -4261a25302e6cc9bc0a9ab479e75d188a3339e37 not-for-merge branch 'testcommit3587' of github.com:jantman/gitpython_issue_301 -0979268db531c72d1ac298866cf0c72077057f50 not-for-merge branch 'testcommit3588' of github.com:jantman/gitpython_issue_301 -a63ffac9a2fe4d182189e92f555a95a7e5458371 not-for-merge branch 'testcommit3589' of github.com:jantman/gitpython_issue_301 -44b6a28984b033683982e631de358e0a857de306 not-for-merge branch 'testcommit359' of github.com:jantman/gitpython_issue_301 -060825cb161860aeedd0dcefa54f900ed8eb7996 not-for-merge branch 'testcommit3590' of github.com:jantman/gitpython_issue_301 -1b900ef2eb82608ba5fed81ee0ed7e6ba3ef60f9 not-for-merge branch 'testcommit3591' of github.com:jantman/gitpython_issue_301 -c33f58930f18e7936f77192ccb19806a9abed48f not-for-merge branch 'testcommit3592' of github.com:jantman/gitpython_issue_301 -e952a5e62390527d184eb20b72302b4a36c39695 not-for-merge branch 'testcommit3593' of github.com:jantman/gitpython_issue_301 -fa1af6faac05be6754d2631a029ae465f4a7052d not-for-merge branch 'testcommit3594' of github.com:jantman/gitpython_issue_301 -3a16a16863d9e70eb851ad5174ec59508e12c2ae not-for-merge branch 'testcommit3595' of github.com:jantman/gitpython_issue_301 -8a7a46dcb515bd7295567b12f23258d09e0483dc not-for-merge branch 'testcommit3596' of github.com:jantman/gitpython_issue_301 -030fa5c2bbf2c636372363939570e5a357c87904 not-for-merge branch 'testcommit3597' of github.com:jantman/gitpython_issue_301 -eb257c4ccd519ad40eca759a75da75c6ca547e7f not-for-merge branch 'testcommit3598' of github.com:jantman/gitpython_issue_301 -67725828ee516d2944803ea883cfb737389abb41 not-for-merge branch 'testcommit3599' of github.com:jantman/gitpython_issue_301 -b1828c2292198fbacf5ee9696d8fcbeba2efbdef not-for-merge branch 'testcommit36' of github.com:jantman/gitpython_issue_301 -35f9d975487700f9044543783c1613341d295705 not-for-merge branch 'testcommit360' of github.com:jantman/gitpython_issue_301 -f06ff26b5e98e9e3ee9240fd246f1006c4b494e1 not-for-merge branch 'testcommit3600' of github.com:jantman/gitpython_issue_301 -6fe748cbf0863ee5734e78bd39b395bbd6684d55 not-for-merge branch 'testcommit3601' of github.com:jantman/gitpython_issue_301 -7e72c200fec5344e540e90d082b1aa0badcdef55 not-for-merge branch 'testcommit3602' of github.com:jantman/gitpython_issue_301 -b4e23ea2e6774bc06f7eda9fa8addfcbfa014a9d not-for-merge branch 'testcommit3603' of github.com:jantman/gitpython_issue_301 -21ee6d0fb39d53a00288693206f64c025019293b not-for-merge branch 'testcommit3604' of github.com:jantman/gitpython_issue_301 -de04f3c17d79eebe8f10f711afe8913893c57c94 not-for-merge branch 'testcommit3605' of github.com:jantman/gitpython_issue_301 -15ae0183d12a59a3da9f897b96483a868c9d9646 not-for-merge branch 'testcommit3606' of github.com:jantman/gitpython_issue_301 -c6d740b5dd09b65c9d3add0f05c46d9a049c9608 not-for-merge branch 'testcommit3607' of github.com:jantman/gitpython_issue_301 -bdf3466ef48c80844a50a550c028a5eca6b7b50f not-for-merge branch 'testcommit3608' of github.com:jantman/gitpython_issue_301 -fdd1856b6e4767b11933f95998db798607314937 not-for-merge branch 'testcommit3609' of github.com:jantman/gitpython_issue_301 -a49c446d598eea3e6e3d687cbb94c3721ef7cc27 not-for-merge branch 'testcommit361' of github.com:jantman/gitpython_issue_301 -8b839f329ec77e577445cbac5f5a600d18056260 not-for-merge branch 'testcommit3610' of github.com:jantman/gitpython_issue_301 -877e53012e1f3ab5d989ced3f4a68128f68d141c not-for-merge branch 'testcommit3611' of github.com:jantman/gitpython_issue_301 -f12981e71c9289ad54db65f3d6d57caa314801d6 not-for-merge branch 'testcommit3612' of github.com:jantman/gitpython_issue_301 -601638053961894c3ab000b8ad376e6e745d3ff8 not-for-merge branch 'testcommit3613' of github.com:jantman/gitpython_issue_301 -a890b051cf08e348dbd673e317d11d9ab7adc6fc not-for-merge branch 'testcommit3614' of github.com:jantman/gitpython_issue_301 -4cefc95fc69b4a1e99161bf8b4e194deb7c0a85d not-for-merge branch 'testcommit3615' of github.com:jantman/gitpython_issue_301 -1c11c9eea081e4da2ee78e531923a8adc9dbed41 not-for-merge branch 'testcommit3616' of github.com:jantman/gitpython_issue_301 -40904c2867dbc6f0ca9656000e3abb3b4a3136ae not-for-merge branch 'testcommit3617' of github.com:jantman/gitpython_issue_301 -e557668bd3749b20a14987480751bf3d21bc7072 not-for-merge branch 'testcommit3618' of github.com:jantman/gitpython_issue_301 -ff19c0af73b1ee3089d41ff32443de76c6e00263 not-for-merge branch 'testcommit3619' of github.com:jantman/gitpython_issue_301 -c12fd60dad9a1153aee6090b528063aa56043d8e not-for-merge branch 'testcommit362' of github.com:jantman/gitpython_issue_301 -9adb97a071edb1757d3de32687b0aca72f5bb824 not-for-merge branch 'testcommit3620' of github.com:jantman/gitpython_issue_301 -c6df58af2413e0a56d85d8f5d990e2239e517bea not-for-merge branch 'testcommit3621' of github.com:jantman/gitpython_issue_301 -0563586588ddc02c1afb5b56777479fe9a7ef737 not-for-merge branch 'testcommit3622' of github.com:jantman/gitpython_issue_301 -9b1344f872ccdf24704263b9e5f984c39cd582be not-for-merge branch 'testcommit3623' of github.com:jantman/gitpython_issue_301 -be2c66a1c154c790057a25df6cd049208a68e1c1 not-for-merge branch 'testcommit3624' of github.com:jantman/gitpython_issue_301 -ac916630785af8e3cdbf0216b3f48d0a0e3c3e86 not-for-merge branch 'testcommit3625' of github.com:jantman/gitpython_issue_301 -ecb8f6f3074f4ab830d6924cd9baa715c36d2b77 not-for-merge branch 'testcommit3626' of github.com:jantman/gitpython_issue_301 -7965b02dd3e03e0b05863623c64a33a7f6afccb1 not-for-merge branch 'testcommit3627' of github.com:jantman/gitpython_issue_301 -7b12d1340a6408f93d1516c3912f96ceb86d4dff not-for-merge branch 'testcommit3628' of github.com:jantman/gitpython_issue_301 -d180592b5efa4a13e6e24f535249f07d53938821 not-for-merge branch 'testcommit3629' of github.com:jantman/gitpython_issue_301 -d0220065a28f1aebfb0b4aa24164cd16d81c06bb not-for-merge branch 'testcommit363' of github.com:jantman/gitpython_issue_301 -08cc273bf9b6033319eb1fb849a9dc7708477318 not-for-merge branch 'testcommit3630' of github.com:jantman/gitpython_issue_301 -10dcd7614c7f7d9f35e06761c69ef7a1eaa4b2a1 not-for-merge branch 'testcommit3631' of github.com:jantman/gitpython_issue_301 -a381f55491d07973302bc48407fa8af085759a4b not-for-merge branch 'testcommit3632' of github.com:jantman/gitpython_issue_301 -0d5da25cd7c507b9657bdc06699e50dce4467823 not-for-merge branch 'testcommit3633' of github.com:jantman/gitpython_issue_301 -8c67f5648625b0add9b3bd817293735a20afeb0c not-for-merge branch 'testcommit3634' of github.com:jantman/gitpython_issue_301 -b689c9e9274f711c2c8c07eac12f2627423dcd8f not-for-merge branch 'testcommit3635' of github.com:jantman/gitpython_issue_301 -d6e6be2cf115ecbbb6a0f48b0a9161f6a1d91840 not-for-merge branch 'testcommit3636' of github.com:jantman/gitpython_issue_301 -bb0c955e03343c0517e750f057d7f52611f12930 not-for-merge branch 'testcommit3637' of github.com:jantman/gitpython_issue_301 -8f52a5d40d89038eb1d3ed3381ad5324781e33db not-for-merge branch 'testcommit3638' of github.com:jantman/gitpython_issue_301 -81bffc1f4c39002bdcc1640a03c8f65a055937cf not-for-merge branch 'testcommit3639' of github.com:jantman/gitpython_issue_301 -538f3455fd516a96775c4728857808c6b8f835d0 not-for-merge branch 'testcommit364' of github.com:jantman/gitpython_issue_301 -2949a2678ddb7591f74a207a725a68a5b7564f11 not-for-merge branch 'testcommit3640' of github.com:jantman/gitpython_issue_301 -4438047f49d4de722513ba455ffb4032e5acd3a7 not-for-merge branch 'testcommit3641' of github.com:jantman/gitpython_issue_301 -16ffc53d5dc7c416a46bbbfb9616f514e39e1a24 not-for-merge branch 'testcommit3642' of github.com:jantman/gitpython_issue_301 -7a160ce5c0bd99b2f3f2a5703311e628a3f76bef not-for-merge branch 'testcommit3643' of github.com:jantman/gitpython_issue_301 -f5bfdae62d92a9a5385f518684648bd4e70575b1 not-for-merge branch 'testcommit3644' of github.com:jantman/gitpython_issue_301 -5d04a56a5e29b6421a38388a6e212530e29f62c5 not-for-merge branch 'testcommit3645' of github.com:jantman/gitpython_issue_301 -00aaf03a9add10dd8e105a5ae9bc54b5a82da71c not-for-merge branch 'testcommit3646' of github.com:jantman/gitpython_issue_301 -e93b80a98261625a3352241575f9bc09801e3b1c not-for-merge branch 'testcommit3647' of github.com:jantman/gitpython_issue_301 -356c0833f31e5e187bbae4ee80955f0a12e07af9 not-for-merge branch 'testcommit3648' of github.com:jantman/gitpython_issue_301 -db2cd37c006abb6bed58373dfd362dfc8c10c49b not-for-merge branch 'testcommit3649' of github.com:jantman/gitpython_issue_301 -a486982ff8fe37a3afc543a6a7c5fd1c1b239901 not-for-merge branch 'testcommit365' of github.com:jantman/gitpython_issue_301 -680681a4e8e7300cb351b1ef773c132b6d0bbe9c not-for-merge branch 'testcommit3650' of github.com:jantman/gitpython_issue_301 -b3fcccdd5b31c85ffd74b57f8207ea519bba19df not-for-merge branch 'testcommit3651' of github.com:jantman/gitpython_issue_301 -bbd705a1c914c799275c52f3409c41e3e47b9300 not-for-merge branch 'testcommit3652' of github.com:jantman/gitpython_issue_301 -f850343db43892eaeec7ddc2c94fa8cfa949919b not-for-merge branch 'testcommit3653' of github.com:jantman/gitpython_issue_301 -51078c2fd0dd38cabc7ee0b5be47a22bf8305ea9 not-for-merge branch 'testcommit3654' of github.com:jantman/gitpython_issue_301 -117754fe706ae3f9ab794fc599991578eb8d8223 not-for-merge branch 'testcommit3655' of github.com:jantman/gitpython_issue_301 -644e0ae7d99c92895d180c01a29749785b4d7bab not-for-merge branch 'testcommit3656' of github.com:jantman/gitpython_issue_301 -99c9d566f913c4f55326aa4e9289bb5c22218281 not-for-merge branch 'testcommit3657' of github.com:jantman/gitpython_issue_301 -59a0ba06dd0018bfcd14f8d5a4d21d7b7c418f6c not-for-merge branch 'testcommit3658' of github.com:jantman/gitpython_issue_301 -33277dd1b2558fcdc37479e3d34dc8963c7cb1ab not-for-merge branch 'testcommit3659' of github.com:jantman/gitpython_issue_301 -7432f9d61979014ec2e09fd0ab8eb8dd023d9f8a not-for-merge branch 'testcommit366' of github.com:jantman/gitpython_issue_301 -328b450df81b0b9a7fb6a364e80c536fe200bcfe not-for-merge branch 'testcommit3660' of github.com:jantman/gitpython_issue_301 -d104cd59a095c7a6b123836d3ed0cde7cfa47637 not-for-merge branch 'testcommit3661' of github.com:jantman/gitpython_issue_301 -40cb8853ce37f6c1cffc7a3cc20a8003987725aa not-for-merge branch 'testcommit3662' of github.com:jantman/gitpython_issue_301 -c3a2d09d4dc320dcfff3e32e9bcff5aafc03a26b not-for-merge branch 'testcommit3663' of github.com:jantman/gitpython_issue_301 -dd7c9b098599ff3e6bcccbf7641d1379bc4dc4db not-for-merge branch 'testcommit3664' of github.com:jantman/gitpython_issue_301 -5b8cfddcf528e8f3586a1adf71eb39f5e8d29788 not-for-merge branch 'testcommit3665' of github.com:jantman/gitpython_issue_301 -ba2c13ac2613dab9619b305756329d1db82a1047 not-for-merge branch 'testcommit3666' of github.com:jantman/gitpython_issue_301 -d508086d9736fe478ba2b5b1650ff83de046cb91 not-for-merge branch 'testcommit3667' of github.com:jantman/gitpython_issue_301 -1f361cf4089609e649a884dfd8dadd60575257c3 not-for-merge branch 'testcommit3668' of github.com:jantman/gitpython_issue_301 -a95b32942c5b0d039bda4d9453815a7ec7b1c99e not-for-merge branch 'testcommit3669' of github.com:jantman/gitpython_issue_301 -7d0eed69ff9e3b572f52adafbc5efed5b0bd275f not-for-merge branch 'testcommit367' of github.com:jantman/gitpython_issue_301 -57c54de45db2d2b6b0c9683671c482b5912796b4 not-for-merge branch 'testcommit3670' of github.com:jantman/gitpython_issue_301 -b40e3740c74fde7ffb3b36faa8eef712ac8856b3 not-for-merge branch 'testcommit3671' of github.com:jantman/gitpython_issue_301 -d90791526672f62a0fb7fc6c24529986fdc9b8de not-for-merge branch 'testcommit3672' of github.com:jantman/gitpython_issue_301 -5428fd7f5de26b061b0d4dcf408790e92f05cbe4 not-for-merge branch 'testcommit3673' of github.com:jantman/gitpython_issue_301 -8513463044740b1b424891fe48926a515d46ceae not-for-merge branch 'testcommit3674' of github.com:jantman/gitpython_issue_301 -42354bdcfa1c85a94bf9533e18434abc4e7cebb4 not-for-merge branch 'testcommit3675' of github.com:jantman/gitpython_issue_301 -da9a5e479f5e070e98a4a6845d55d6266b11c966 not-for-merge branch 'testcommit3676' of github.com:jantman/gitpython_issue_301 -195b3acfded78e655e56d5c50d3278f130fc688b not-for-merge branch 'testcommit3677' of github.com:jantman/gitpython_issue_301 -6733d0b31dce892525b732cbcb4ea77d25fa5d8d not-for-merge branch 'testcommit3678' of github.com:jantman/gitpython_issue_301 -58bd0b8e83706d3eea82646a8d23e3464a0377b9 not-for-merge branch 'testcommit3679' of github.com:jantman/gitpython_issue_301 -b5a5f552c24c3f6f5483cbd5c02fc27fa7fc8ffe not-for-merge branch 'testcommit368' of github.com:jantman/gitpython_issue_301 -722d93bed2c837ca80e2385feff8fbd302812bd0 not-for-merge branch 'testcommit3680' of github.com:jantman/gitpython_issue_301 -1e9df8d40ea44e727126f2870ecfaef569ffd593 not-for-merge branch 'testcommit3681' of github.com:jantman/gitpython_issue_301 -dfe6c3b0740c39721aaca89fe59b9b9458378728 not-for-merge branch 'testcommit3682' of github.com:jantman/gitpython_issue_301 -c8f26df5001f4015d5c107fcb4be0eb114168dd3 not-for-merge branch 'testcommit3683' of github.com:jantman/gitpython_issue_301 -2e4a10543be540cdd94eef7bac2195b21e93e00e not-for-merge branch 'testcommit3684' of github.com:jantman/gitpython_issue_301 -a79a9b273d08ef13212006af56e613783bbe2fa9 not-for-merge branch 'testcommit3685' of github.com:jantman/gitpython_issue_301 -9fc1847ca374405230f3b3de5cd7eeeca4389994 not-for-merge branch 'testcommit3686' of github.com:jantman/gitpython_issue_301 -83d283bba596b5d5708d3391d13710546e690d0a not-for-merge branch 'testcommit3687' of github.com:jantman/gitpython_issue_301 -d2e574f213cc3a79ecded38b749af3bf9e4ec443 not-for-merge branch 'testcommit3688' of github.com:jantman/gitpython_issue_301 -2504731901e264e47e7b8676f9c50fc33040a199 not-for-merge branch 'testcommit3689' of github.com:jantman/gitpython_issue_301 -b6d59342e61a9561471f7a517522d844a5c33fb9 not-for-merge branch 'testcommit369' of github.com:jantman/gitpython_issue_301 -33ffc5ca77c217b70f69940c2b9d86381a56679e not-for-merge branch 'testcommit3690' of github.com:jantman/gitpython_issue_301 -f453cd51d13276356ec9f36ed671b26a527b10a0 not-for-merge branch 'testcommit3691' of github.com:jantman/gitpython_issue_301 -40e04ec976c8b72860a524be8af5a8c71fd39005 not-for-merge branch 'testcommit3692' of github.com:jantman/gitpython_issue_301 -5eaa603fca328eb84e60367e32098450037c12ec not-for-merge branch 'testcommit3693' of github.com:jantman/gitpython_issue_301 -19f4ddce06d0254890b779ade9683592924f4481 not-for-merge branch 'testcommit3694' of github.com:jantman/gitpython_issue_301 -18cf34ccbd56a9d23240854a45e632dc3209ddce not-for-merge branch 'testcommit3695' of github.com:jantman/gitpython_issue_301 -f85bbdf9674ca9d03a5143ba2e6c1a53d4063828 not-for-merge branch 'testcommit3696' of github.com:jantman/gitpython_issue_301 -94a55dce4d1c751fff0c8473bad25f16ddb5c401 not-for-merge branch 'testcommit3697' of github.com:jantman/gitpython_issue_301 -961fea91a1c087a7672679587fb88fc62f70839d not-for-merge branch 'testcommit3698' of github.com:jantman/gitpython_issue_301 -4a371b8a4beb44be2d624f7657624369dec9a564 not-for-merge branch 'testcommit3699' of github.com:jantman/gitpython_issue_301 -84cf693df85140b9995a7ef4dcd0025b6a0966eb not-for-merge branch 'testcommit37' of github.com:jantman/gitpython_issue_301 -5634b6241568604d07e69d3f9819aada1871d1c0 not-for-merge branch 'testcommit370' of github.com:jantman/gitpython_issue_301 -0df99eb7a5c466923431bef2e9a85b6789c26267 not-for-merge branch 'testcommit3700' of github.com:jantman/gitpython_issue_301 -385ec758edf80ca1672e7c1b9a7b5454708d6014 not-for-merge branch 'testcommit3701' of github.com:jantman/gitpython_issue_301 -fee29312572d8c65feffd38df2867a30e31af021 not-for-merge branch 'testcommit3702' of github.com:jantman/gitpython_issue_301 -a5ef9d38ad173d1d387614a394a4e4612aa0100a not-for-merge branch 'testcommit3703' of github.com:jantman/gitpython_issue_301 -c343f44a1bca5edefadd3a4a5bf732c73a7e9dad not-for-merge branch 'testcommit3704' of github.com:jantman/gitpython_issue_301 -89ac1d8ac6678d93df7b11037c5449c32951a148 not-for-merge branch 'testcommit3705' of github.com:jantman/gitpython_issue_301 -55f47fccc0139a556fb62d4752e6b8dedabe5d8d not-for-merge branch 'testcommit3706' of github.com:jantman/gitpython_issue_301 -166726730f21f50d667c79563438f33497400c16 not-for-merge branch 'testcommit3707' of github.com:jantman/gitpython_issue_301 -4dabcd5c2e9562ca8821484f9fe7c31a3bedc9ed not-for-merge branch 'testcommit3708' of github.com:jantman/gitpython_issue_301 -d357d86dbbae30896091b9e39239e149b38807f6 not-for-merge branch 'testcommit3709' of github.com:jantman/gitpython_issue_301 -48332b59eb97e6a9ab7a0599fb0815b5f4379424 not-for-merge branch 'testcommit371' of github.com:jantman/gitpython_issue_301 -2d7dcdd1cff833ab78e73a975095b0de30845909 not-for-merge branch 'testcommit3710' of github.com:jantman/gitpython_issue_301 -59597cbc75cb1ebf4718a1dbfb79d61586e2bb63 not-for-merge branch 'testcommit3711' of github.com:jantman/gitpython_issue_301 -79c06c896f151e6096ec7a6839e224ca7be030c7 not-for-merge branch 'testcommit3712' of github.com:jantman/gitpython_issue_301 -7a5b1c78e30c131dc900044226164598eb35658c not-for-merge branch 'testcommit3713' of github.com:jantman/gitpython_issue_301 -529837f7014af8d1f1a7574e046a4a0c08426ad7 not-for-merge branch 'testcommit3714' of github.com:jantman/gitpython_issue_301 -40bd5ae509535405bb2670738c61f30dbd056703 not-for-merge branch 'testcommit3715' of github.com:jantman/gitpython_issue_301 -150327841b948e62c35002df78053db10ae3b279 not-for-merge branch 'testcommit3716' of github.com:jantman/gitpython_issue_301 -e8298f955fc49e46d093b44bcb3f4c0fb588f900 not-for-merge branch 'testcommit3717' of github.com:jantman/gitpython_issue_301 -37cf15d4ea7d5e4b0bde1945c1e94856015b691d not-for-merge branch 'testcommit3718' of github.com:jantman/gitpython_issue_301 -e3e5c3a5be73688cebf0d6ddbe7e63088778af69 not-for-merge branch 'testcommit3719' of github.com:jantman/gitpython_issue_301 -460b740007fda9e79b4c8ee6f467bb3a90aadd44 not-for-merge branch 'testcommit372' of github.com:jantman/gitpython_issue_301 -7169f7c499ace2edf0424e6d4e30e0be260676ce not-for-merge branch 'testcommit3720' of github.com:jantman/gitpython_issue_301 -301b7995fce02eb3419f0b8478db775aab6ca2bb not-for-merge branch 'testcommit3721' of github.com:jantman/gitpython_issue_301 -e3d17fc2e9315b2ecbe69bcc79721441f8c05a09 not-for-merge branch 'testcommit3722' of github.com:jantman/gitpython_issue_301 -2d64cadbaae3428574b0dc5d7a17c32a3743ef90 not-for-merge branch 'testcommit3723' of github.com:jantman/gitpython_issue_301 -c5e09e4e23473a1810d97230ddcf79c883e9a5ec not-for-merge branch 'testcommit3724' of github.com:jantman/gitpython_issue_301 -1f3fcf22bee04fdc46f0470710400e2816e8da40 not-for-merge branch 'testcommit3725' of github.com:jantman/gitpython_issue_301 -74f61e5a338c927b7937cfd11d73cf6ef535ef82 not-for-merge branch 'testcommit3726' of github.com:jantman/gitpython_issue_301 -ce1911ea14de453523afaf16426e093d9f0f1012 not-for-merge branch 'testcommit3727' of github.com:jantman/gitpython_issue_301 -efd0b1b90b5fbee34d7a12847840ed1615981c87 not-for-merge branch 'testcommit3728' of github.com:jantman/gitpython_issue_301 -14308a11e50b3c4b531ea95bba870ecc1a9207a3 not-for-merge branch 'testcommit3729' of github.com:jantman/gitpython_issue_301 -105925a695c4c46a16c972eb9542d287bb4d0edf not-for-merge branch 'testcommit373' of github.com:jantman/gitpython_issue_301 -36a052a201cdc598b0f104d5ab5185d021f55ba4 not-for-merge branch 'testcommit3730' of github.com:jantman/gitpython_issue_301 -28bcdf1a995ed6f3af4c535755cc533b23da2848 not-for-merge branch 'testcommit3731' of github.com:jantman/gitpython_issue_301 -1c19589ae7b55045ee1a485eabb25596a7348201 not-for-merge branch 'testcommit3732' of github.com:jantman/gitpython_issue_301 -9d602178d91e81e0765d108e2eaf608eafa47fd7 not-for-merge branch 'testcommit3733' of github.com:jantman/gitpython_issue_301 -3337218caf58e44ff79b59cbb2b10fd888fea85f not-for-merge branch 'testcommit3734' of github.com:jantman/gitpython_issue_301 -bf75b85382bb3f616e51b37692cb63fc17660e42 not-for-merge branch 'testcommit3735' of github.com:jantman/gitpython_issue_301 -cbdcf7ae23ca0443c93476dd11d68f9a25419078 not-for-merge branch 'testcommit3736' of github.com:jantman/gitpython_issue_301 -3c1f16e2d3c41ca949c469a12d63a15d8021f21c not-for-merge branch 'testcommit3737' of github.com:jantman/gitpython_issue_301 -5243bf2c85bf90c04c7bb0f3563c2f4ddf48d372 not-for-merge branch 'testcommit3738' of github.com:jantman/gitpython_issue_301 -fdbe09ddddb8ff7459bcd1bd3c9fe6de2b89cd3d not-for-merge branch 'testcommit3739' of github.com:jantman/gitpython_issue_301 -6cd9164dac28e9d91a35de6596059646a256a1d2 not-for-merge branch 'testcommit374' of github.com:jantman/gitpython_issue_301 -1c8ade731eb3b1af3f9b5e52ceba07f9b28c4f77 not-for-merge branch 'testcommit3740' of github.com:jantman/gitpython_issue_301 -fa9b03711f3dae738ad57cf7e483a7759ec543d3 not-for-merge branch 'testcommit3741' of github.com:jantman/gitpython_issue_301 -258ef452453aba216529436260b3b5041a8a40e7 not-for-merge branch 'testcommit3742' of github.com:jantman/gitpython_issue_301 -ff4411e29c48fe458660e13452c71192d6308be5 not-for-merge branch 'testcommit3743' of github.com:jantman/gitpython_issue_301 -8d4e91b49f86eec66be8ed8f9f767fcf8605af6a not-for-merge branch 'testcommit3744' of github.com:jantman/gitpython_issue_301 -d0c99291e24413b39144857f08b53f9d2babb22b not-for-merge branch 'testcommit3745' of github.com:jantman/gitpython_issue_301 -9d87c3b91e005b00d9879d218e5a278d4a5a664b not-for-merge branch 'testcommit3746' of github.com:jantman/gitpython_issue_301 -b77a80fa8b238553dcabc68c37441be2a06b0892 not-for-merge branch 'testcommit3747' of github.com:jantman/gitpython_issue_301 -3e3adf97fd586889bf699c276f4bc69939920fab not-for-merge branch 'testcommit3748' of github.com:jantman/gitpython_issue_301 -7e8a1f0d13f6592b665089bdccba57a23968b473 not-for-merge branch 'testcommit3749' of github.com:jantman/gitpython_issue_301 -32c28c9307d461f306a5bc347e9f6007a313cbda not-for-merge branch 'testcommit375' of github.com:jantman/gitpython_issue_301 -189876b73171469da69ae384c3fab8e9a9e213fd not-for-merge branch 'testcommit3750' of github.com:jantman/gitpython_issue_301 -ea926e25f58cfbd9aac57faf67b8b0697ab5b4d8 not-for-merge branch 'testcommit3751' of github.com:jantman/gitpython_issue_301 -eec23601cd00390bb0bdb373193997419d3b8a20 not-for-merge branch 'testcommit3752' of github.com:jantman/gitpython_issue_301 -5c2fabd4c8fee812868423576f9b4107d6f72667 not-for-merge branch 'testcommit3753' of github.com:jantman/gitpython_issue_301 -fff1328e8f94712d7f83eea38a11d1988549075e not-for-merge branch 'testcommit3754' of github.com:jantman/gitpython_issue_301 -b46c499f4f3d836e0a1076d9be1524a8ad42197d not-for-merge branch 'testcommit3755' of github.com:jantman/gitpython_issue_301 -16900b99e91c583a38281bd8b591c6a110083dde not-for-merge branch 'testcommit3756' of github.com:jantman/gitpython_issue_301 -3c1be1fa184cec4d279a7944f3f0e43dc7ab2cd3 not-for-merge branch 'testcommit3757' of github.com:jantman/gitpython_issue_301 -6627362097795d139f35e1a18c9c81415ee45708 not-for-merge branch 'testcommit3758' of github.com:jantman/gitpython_issue_301 -9ed80bd571844c7769d35e0d03d76d10c27afb91 not-for-merge branch 'testcommit3759' of github.com:jantman/gitpython_issue_301 -0e96a2e347c8000bebe359e2d899e6d65c22eaf2 not-for-merge branch 'testcommit376' of github.com:jantman/gitpython_issue_301 -bf3a5527eaf501be8d22823c962ab8488096f5c9 not-for-merge branch 'testcommit3760' of github.com:jantman/gitpython_issue_301 -a2dd7e507ceee863a17650dba14e81591f241256 not-for-merge branch 'testcommit3761' of github.com:jantman/gitpython_issue_301 -401c96d4f88c3c3d313a83b83812a075dae4e6ed not-for-merge branch 'testcommit3762' of github.com:jantman/gitpython_issue_301 -cb16192c01799867f4b5722792ea9b550c333e78 not-for-merge branch 'testcommit3763' of github.com:jantman/gitpython_issue_301 -7779cd8745fb65001e3451a92fa0e3f995e08c4e not-for-merge branch 'testcommit3764' of github.com:jantman/gitpython_issue_301 -18ec9e744441ba2ef95d26827bbc48e4075f895f not-for-merge branch 'testcommit3765' of github.com:jantman/gitpython_issue_301 -43b44d1526e107baf6991bd4c5df659955497b95 not-for-merge branch 'testcommit3766' of github.com:jantman/gitpython_issue_301 -82d8019954f52fe140f0df1c0d7650e5351afe82 not-for-merge branch 'testcommit3767' of github.com:jantman/gitpython_issue_301 -80f3713a6bf62e49396dd01d3dc718e14e3c8c8f not-for-merge branch 'testcommit3768' of github.com:jantman/gitpython_issue_301 -b91d66cd8bcb857f0d2b535058ec1c38ed0c5f99 not-for-merge branch 'testcommit3769' of github.com:jantman/gitpython_issue_301 -7c53eacbf1fe3e8f71125298c4fe0d51e29cc117 not-for-merge branch 'testcommit377' of github.com:jantman/gitpython_issue_301 -71ee5c946db99170a6eb47d61502e5445db48dc0 not-for-merge branch 'testcommit3770' of github.com:jantman/gitpython_issue_301 -5ccdd83fea8e4d9626e1e9792bfb45426294f572 not-for-merge branch 'testcommit3771' of github.com:jantman/gitpython_issue_301 -38fe9679a780f8c888086f4a0419b0438ab8134e not-for-merge branch 'testcommit3772' of github.com:jantman/gitpython_issue_301 -ffdefd911ecdb5bd98144dcb91823f3f054f7f89 not-for-merge branch 'testcommit3773' of github.com:jantman/gitpython_issue_301 -a37276edba09027af6be007e4309b7f3a29dd4bc not-for-merge branch 'testcommit3774' of github.com:jantman/gitpython_issue_301 -5e03148f270ae958aa6c0aee8b02d863de8dc54d not-for-merge branch 'testcommit3775' of github.com:jantman/gitpython_issue_301 -05bebbc4cdb70a9ef6c2cca69e2b5b4412ef74f6 not-for-merge branch 'testcommit3776' of github.com:jantman/gitpython_issue_301 -3433f81a6733c1ac5ac8c4fd29efa6d128dceafa not-for-merge branch 'testcommit3777' of github.com:jantman/gitpython_issue_301 -63a6b07c84748be55502c5c63df44a9f01521d6d not-for-merge branch 'testcommit3778' of github.com:jantman/gitpython_issue_301 -6e73296b7a7bbdfb5cf1e606ed10e90d265ad944 not-for-merge branch 'testcommit3779' of github.com:jantman/gitpython_issue_301 -9d3dcf23a80d7cb3cdcd2450e9e1a702c3617010 not-for-merge branch 'testcommit378' of github.com:jantman/gitpython_issue_301 -bb9fc5f291d692687e489e7b3eb7920073a6f1e8 not-for-merge branch 'testcommit3780' of github.com:jantman/gitpython_issue_301 -924b7057b2ee1b94dd1aee8fcc9bca52a925452e not-for-merge branch 'testcommit3781' of github.com:jantman/gitpython_issue_301 -0cc3f3f78e95f629f8dbc47dd01eb6939fef9ba4 not-for-merge branch 'testcommit3782' of github.com:jantman/gitpython_issue_301 -ca20f6bf09bded40228dd1f0ad173584e077d06e not-for-merge branch 'testcommit3783' of github.com:jantman/gitpython_issue_301 -8b7623cf94c54e0917a3e57e255a5cb0de83c27b not-for-merge branch 'testcommit3784' of github.com:jantman/gitpython_issue_301 -c18a530563a3386fd08b718c625ae976a694efe5 not-for-merge branch 'testcommit3785' of github.com:jantman/gitpython_issue_301 -575f0b7580df270c83f2c88931d4a8386f22842c not-for-merge branch 'testcommit3786' of github.com:jantman/gitpython_issue_301 -3e0308aa5e9d4c6d3b1108af37417740fac79edc not-for-merge branch 'testcommit3787' of github.com:jantman/gitpython_issue_301 -34c2caf8dd84bde1e7ae809d0e9460d9245fcb66 not-for-merge branch 'testcommit3788' of github.com:jantman/gitpython_issue_301 -40e0d4fce0790920e12a297aa075933727756731 not-for-merge branch 'testcommit3789' of github.com:jantman/gitpython_issue_301 -706b80f418435f084e8f584437362ec23ea572a8 not-for-merge branch 'testcommit379' of github.com:jantman/gitpython_issue_301 -706b0891e82263af37f5ca15efaa2d616bcc4042 not-for-merge branch 'testcommit3790' of github.com:jantman/gitpython_issue_301 -3f1a699ba616c8a2ff9eba0cdeb472b754252378 not-for-merge branch 'testcommit3791' of github.com:jantman/gitpython_issue_301 -3ec24b18bd8b2c815981dec74661df7b9c630dae not-for-merge branch 'testcommit3792' of github.com:jantman/gitpython_issue_301 -d2a8812d7f4cf3e096c9ac6e5ac5b0d6873517f5 not-for-merge branch 'testcommit3793' of github.com:jantman/gitpython_issue_301 -7fd364daa7daa312f4895dd4c813dc53c542720f not-for-merge branch 'testcommit3794' of github.com:jantman/gitpython_issue_301 -3805a7d3b2be42f7b560497aa163c130fd87111a not-for-merge branch 'testcommit3795' of github.com:jantman/gitpython_issue_301 -607d13348c4a6de0800c9f42ce17597409b95f5d not-for-merge branch 'testcommit3796' of github.com:jantman/gitpython_issue_301 -f1a1a01f3171c91d7bc4f08d16b23e31b068f30a not-for-merge branch 'testcommit3797' of github.com:jantman/gitpython_issue_301 -88f66c8acd7b7375ad5a94e22b5432f3a3a5700d not-for-merge branch 'testcommit3798' of github.com:jantman/gitpython_issue_301 -30763f806977f180d177583bfa915601b3844ad7 not-for-merge branch 'testcommit3799' of github.com:jantman/gitpython_issue_301 -3ca64d0af1860daf6521e4979152c421b0aa07f0 not-for-merge branch 'testcommit38' of github.com:jantman/gitpython_issue_301 -2cf4f3e7ff08e1a3b278964bced79674fe975c6c not-for-merge branch 'testcommit380' of github.com:jantman/gitpython_issue_301 -6f739e78b80b89d1c821a23642dfb1b384dfa28f not-for-merge branch 'testcommit3800' of github.com:jantman/gitpython_issue_301 -2993811abcfb2b8a6a4d788b8cbafb6dcb1ba6b8 not-for-merge branch 'testcommit3801' of github.com:jantman/gitpython_issue_301 -63eba19d3cff22913eb2e13be082177adf7c76e8 not-for-merge branch 'testcommit3802' of github.com:jantman/gitpython_issue_301 -6c5ad825fbdf8d425d499b8b6c0638e2e3033241 not-for-merge branch 'testcommit3803' of github.com:jantman/gitpython_issue_301 -13f313def805f5056c1c2896f4a31774524efcf8 not-for-merge branch 'testcommit3804' of github.com:jantman/gitpython_issue_301 -cb1dec33eddfd87857f3521af42e76f2adb21ce7 not-for-merge branch 'testcommit3805' of github.com:jantman/gitpython_issue_301 -21708fb301b7b56de000e70d16312bc50875868f not-for-merge branch 'testcommit3806' of github.com:jantman/gitpython_issue_301 -0c30e5fdee7d056c5bf2fe34eb99c16ad05aee43 not-for-merge branch 'testcommit3807' of github.com:jantman/gitpython_issue_301 -8ce19621f43a3ca2035ccea7da08e6f145aed48f not-for-merge branch 'testcommit3808' of github.com:jantman/gitpython_issue_301 -b19bc2253aac320d26abe4f069498ede1677851a not-for-merge branch 'testcommit3809' of github.com:jantman/gitpython_issue_301 -9958996cc7bc188182537832207753191dc55b35 not-for-merge branch 'testcommit381' of github.com:jantman/gitpython_issue_301 -e1961cb76986ad2d66ddeee4ccafcbd5744dacdd not-for-merge branch 'testcommit3810' of github.com:jantman/gitpython_issue_301 -6b20f72db42faf481c2ec72611818b3a3ccd397f not-for-merge branch 'testcommit3811' of github.com:jantman/gitpython_issue_301 -054d0994a246596bc02eae642894d959acfc4ae0 not-for-merge branch 'testcommit3812' of github.com:jantman/gitpython_issue_301 -32e8e41d6a4bb1f13b21ce4778be8bc005b20d45 not-for-merge branch 'testcommit3813' of github.com:jantman/gitpython_issue_301 -93540b157eac325a80caca54a5b6917ffee2ef92 not-for-merge branch 'testcommit3814' of github.com:jantman/gitpython_issue_301 -23223cab4ca7f72b6ccf871f8c50e90aa9bd1ab4 not-for-merge branch 'testcommit3815' of github.com:jantman/gitpython_issue_301 -45c6a3c1a9a9b7b74e496006fc42dcdf1bb80a1a not-for-merge branch 'testcommit3816' of github.com:jantman/gitpython_issue_301 -39aab84f8fa9e40bf5c8e1194461276e7bdef74a not-for-merge branch 'testcommit3817' of github.com:jantman/gitpython_issue_301 -a3eb9624fa7ea387fa8f768580280ec4db49542a not-for-merge branch 'testcommit3818' of github.com:jantman/gitpython_issue_301 -f19b3d1628cb0bf60efc4bd09b582f8edb073c31 not-for-merge branch 'testcommit3819' of github.com:jantman/gitpython_issue_301 -14ebe187a39457cc6dfc28fd95eaa7192a1cf128 not-for-merge branch 'testcommit382' of github.com:jantman/gitpython_issue_301 -52d6739a9c48f357feaf67b142f285dfdb1dd7cf not-for-merge branch 'testcommit3820' of github.com:jantman/gitpython_issue_301 -7fed48fde489385c02d16536533dcf177c0667a6 not-for-merge branch 'testcommit3821' of github.com:jantman/gitpython_issue_301 -ca7cc5e525682d8119bf12613072532bf8c51dae not-for-merge branch 'testcommit3822' of github.com:jantman/gitpython_issue_301 -2d51e42cdbd61bedc18f198939fe2e61d51b4c29 not-for-merge branch 'testcommit3823' of github.com:jantman/gitpython_issue_301 -7a6ddd2c192ca92540fac56f75f422af94ca489d not-for-merge branch 'testcommit3824' of github.com:jantman/gitpython_issue_301 -6713c2f4f80cee18686e2f46e1509664f10816ca not-for-merge branch 'testcommit3825' of github.com:jantman/gitpython_issue_301 -928b589b6bf7d47eb8b6c7d028980c21506e09ac not-for-merge branch 'testcommit3826' of github.com:jantman/gitpython_issue_301 -95bcb0bb8e3d93b52eb6e711b845021c8bae6ac0 not-for-merge branch 'testcommit3827' of github.com:jantman/gitpython_issue_301 -b957f8c6e4bf6f4cb93bedac7e924a503da3f8a0 not-for-merge branch 'testcommit3828' of github.com:jantman/gitpython_issue_301 -2a454eca03556db8b00cae971340b4185309ac31 not-for-merge branch 'testcommit3829' of github.com:jantman/gitpython_issue_301 -032474cd9eeffd8ed82d2465f0286669a3d6f872 not-for-merge branch 'testcommit383' of github.com:jantman/gitpython_issue_301 -c68ef9aafd5c5445745dca8b5d815758cd22cf72 not-for-merge branch 'testcommit3830' of github.com:jantman/gitpython_issue_301 -ca8c33f3abf4cace0d923e7d9b0d4f8bd24ed29f not-for-merge branch 'testcommit3831' of github.com:jantman/gitpython_issue_301 -ee11eaf0e11ce364dd78d1720ed12ef0c684fb55 not-for-merge branch 'testcommit3832' of github.com:jantman/gitpython_issue_301 -12a7538464b0ad95fc7aa939e1cdaff64fb653be not-for-merge branch 'testcommit3833' of github.com:jantman/gitpython_issue_301 -9e6556d29d11c3639e1c10c36bfba7a6a3a1f332 not-for-merge branch 'testcommit3834' of github.com:jantman/gitpython_issue_301 -a8f079c17a39f54752fb0978bf8e8cd563bf868d not-for-merge branch 'testcommit3835' of github.com:jantman/gitpython_issue_301 -87cfbbc949d9eab05967fd0f287fb71b0b2bd173 not-for-merge branch 'testcommit3836' of github.com:jantman/gitpython_issue_301 -c6931a691804ce8ca2580ef1d7f9d3c39b770656 not-for-merge branch 'testcommit3837' of github.com:jantman/gitpython_issue_301 -c864971c1f961db1d8d3e96d7ecde6b56281029e not-for-merge branch 'testcommit3838' of github.com:jantman/gitpython_issue_301 -010095debd48ce111734c952edfa1ac895ec0a05 not-for-merge branch 'testcommit3839' of github.com:jantman/gitpython_issue_301 -8f4c19558c08996bf71396ba5d193116e43c0638 not-for-merge branch 'testcommit384' of github.com:jantman/gitpython_issue_301 -24e33eff4e399ba2b465537d81b898ed54be6ef8 not-for-merge branch 'testcommit3840' of github.com:jantman/gitpython_issue_301 -40f54390ab75777f8c8576c43c7b2e5faca9323f not-for-merge branch 'testcommit3841' of github.com:jantman/gitpython_issue_301 -f93b097537c69a977ce3a920822e8e8a2a38f928 not-for-merge branch 'testcommit3842' of github.com:jantman/gitpython_issue_301 -f57e54bd7f06796bc3346d58833cb0efae3c9444 not-for-merge branch 'testcommit3843' of github.com:jantman/gitpython_issue_301 -355a85fa99c12c19d4895ae52af07a2e0b6109de not-for-merge branch 'testcommit3844' of github.com:jantman/gitpython_issue_301 -aaa405a1d071331782ed75a07bb7dc7d98e9377d not-for-merge branch 'testcommit3845' of github.com:jantman/gitpython_issue_301 -a48f96458c7030f8c2ecc2075243f3d9f86bcad0 not-for-merge branch 'testcommit3846' of github.com:jantman/gitpython_issue_301 -b4360b92fcd9965c89ac2efdf7d6ab446f3f28b6 not-for-merge branch 'testcommit3847' of github.com:jantman/gitpython_issue_301 -40f1014dc73f5a42f1173f8a7bc3b255ccf21e6c not-for-merge branch 'testcommit3848' of github.com:jantman/gitpython_issue_301 -0f501f3ee090db5ecb64c1200724e726c9b75c5b not-for-merge branch 'testcommit3849' of github.com:jantman/gitpython_issue_301 -1f50d6e82b30bfa67a8d87675d384c201fe8f41c not-for-merge branch 'testcommit385' of github.com:jantman/gitpython_issue_301 -4b85db2b2ff2b98bf204b572edf9b2c1b59adac6 not-for-merge branch 'testcommit3850' of github.com:jantman/gitpython_issue_301 -67089fceb4db61f48aeffe837f8792c0d3320e44 not-for-merge branch 'testcommit3851' of github.com:jantman/gitpython_issue_301 -9212eb1201bf77bf87cd2a657b1bab32f3f517ee not-for-merge branch 'testcommit3852' of github.com:jantman/gitpython_issue_301 -bacfb9a04cfe0b04144b70c54645cad3dc2f07ef not-for-merge branch 'testcommit3853' of github.com:jantman/gitpython_issue_301 -476b34fef7432a4d12748ad2d411a8fac100b10c not-for-merge branch 'testcommit3854' of github.com:jantman/gitpython_issue_301 -de68fc5e2a9fa6d80995342a13188fce84e28566 not-for-merge branch 'testcommit3855' of github.com:jantman/gitpython_issue_301 -0a726b742da9a7ec004ca9ed891206d996864b14 not-for-merge branch 'testcommit3856' of github.com:jantman/gitpython_issue_301 -c4b78fb4ebed19e6d5cccc21a00fad32e00271dc not-for-merge branch 'testcommit3857' of github.com:jantman/gitpython_issue_301 -73b6f8af40b0a25c3fbe9830c7a8261bbfcebc6b not-for-merge branch 'testcommit3858' of github.com:jantman/gitpython_issue_301 -3dbfc94194f9df4af4674f8fe7b452c42daeca39 not-for-merge branch 'testcommit3859' of github.com:jantman/gitpython_issue_301 -5f8c59f98c5e541ffe46c839142c66074187f14c not-for-merge branch 'testcommit386' of github.com:jantman/gitpython_issue_301 -c99f86547a5839ae556026c543ed53697ee41b72 not-for-merge branch 'testcommit3860' of github.com:jantman/gitpython_issue_301 -874c6591a4d68cfaca6e71f4731cdab6cc354239 not-for-merge branch 'testcommit3861' of github.com:jantman/gitpython_issue_301 -fc4ae29205cddcd51482abf808bc92983a033015 not-for-merge branch 'testcommit3862' of github.com:jantman/gitpython_issue_301 -a4417d61b3242550549569f2b5addad5dea912e0 not-for-merge branch 'testcommit3863' of github.com:jantman/gitpython_issue_301 -52d8629d93dff8d2527487e47ca876b278e6c3bf not-for-merge branch 'testcommit3864' of github.com:jantman/gitpython_issue_301 -795d582fb85c12f143135f61294501012381bae6 not-for-merge branch 'testcommit3865' of github.com:jantman/gitpython_issue_301 -801f849b5d8f5bd1178563f45dcfd7829ca4c659 not-for-merge branch 'testcommit3866' of github.com:jantman/gitpython_issue_301 -eaf24aa62ffcaa1b09041f3cfb52b860d6f381e9 not-for-merge branch 'testcommit3867' of github.com:jantman/gitpython_issue_301 -56be15fdaa7672ddb89776c5e41a57c69a6ac750 not-for-merge branch 'testcommit3868' of github.com:jantman/gitpython_issue_301 -f9bc4f70ead35cca010561da2042f5e71ba593d3 not-for-merge branch 'testcommit3869' of github.com:jantman/gitpython_issue_301 -61978735cc5a13a085295e7d61255a98d2ad4f80 not-for-merge branch 'testcommit387' of github.com:jantman/gitpython_issue_301 -17e69ca51366140da637dac4dd4dc11bc2055a43 not-for-merge branch 'testcommit3870' of github.com:jantman/gitpython_issue_301 -66c85ae6413c1e4442cee3f92c10571ba25d8cfb not-for-merge branch 'testcommit3871' of github.com:jantman/gitpython_issue_301 -bde44bfcfe6cf769e3c1aed53af272c814e32602 not-for-merge branch 'testcommit3872' of github.com:jantman/gitpython_issue_301 -47d5eab7ca2637b6ef751ab8c6e346279497edb8 not-for-merge branch 'testcommit3873' of github.com:jantman/gitpython_issue_301 -ec3109f76df91b18e14c5d8f35dc98997dc3f9b4 not-for-merge branch 'testcommit3874' of github.com:jantman/gitpython_issue_301 -8597c1bd8404f10d3208606ed6959e14facfcbfa not-for-merge branch 'testcommit3875' of github.com:jantman/gitpython_issue_301 -0bc83cb4d547b8ec5a53f4df7731f3bfb7c842cd not-for-merge branch 'testcommit3876' of github.com:jantman/gitpython_issue_301 -0fabfca9fda0ea0d386e77febfc1dc8afcd6b073 not-for-merge branch 'testcommit3877' of github.com:jantman/gitpython_issue_301 -e0fe27e86f331163c013653e6713ea5773f11ce7 not-for-merge branch 'testcommit3878' of github.com:jantman/gitpython_issue_301 -c86d6ae3d37f05c0b12decafc8d78124b80329af not-for-merge branch 'testcommit3879' of github.com:jantman/gitpython_issue_301 -59a48ae14b7e116c8080b0da2477616595ec7ff9 not-for-merge branch 'testcommit388' of github.com:jantman/gitpython_issue_301 -973ac3d2feb69f093a0b0fc2c46cd0bfdebcb27d not-for-merge branch 'testcommit3880' of github.com:jantman/gitpython_issue_301 -6c85300334780cda8433fc05029bd42829d9565a not-for-merge branch 'testcommit3881' of github.com:jantman/gitpython_issue_301 -bd8ac18a8a8dd192dfd79b69d091fd8d0baccbe1 not-for-merge branch 'testcommit3882' of github.com:jantman/gitpython_issue_301 -1db52912dbb8969b2d683973572c8fe889a09ae4 not-for-merge branch 'testcommit3883' of github.com:jantman/gitpython_issue_301 -2488fcd98f60e137a517b17c158febc2b218b6d9 not-for-merge branch 'testcommit3884' of github.com:jantman/gitpython_issue_301 -6a008841b2663989f88462f4cd380b937ecf9c3d not-for-merge branch 'testcommit3885' of github.com:jantman/gitpython_issue_301 -c3df063f6aca1ce970d214a119dd43032240dbdc not-for-merge branch 'testcommit3886' of github.com:jantman/gitpython_issue_301 -f0c5a30075365ccf2c8d8cea3154b6eec20d312e not-for-merge branch 'testcommit3887' of github.com:jantman/gitpython_issue_301 -481dbe650d118f39ee12851d869b1d4267e18acd not-for-merge branch 'testcommit3888' of github.com:jantman/gitpython_issue_301 -c75899d799a89aa8c2e57198a11eb403e99e8723 not-for-merge branch 'testcommit3889' of github.com:jantman/gitpython_issue_301 -47236e7d14ae6d44c4fbc4ef9db53d1f425e3e00 not-for-merge branch 'testcommit389' of github.com:jantman/gitpython_issue_301 -c1de52ce86c058411bee6c935c29617c2c1ea85f not-for-merge branch 'testcommit3890' of github.com:jantman/gitpython_issue_301 -e052a0acd5f69553e11b412c09a86c1b1417fa53 not-for-merge branch 'testcommit3891' of github.com:jantman/gitpython_issue_301 -10efe2e6093685f272e15d10f888a3168c41bb8c not-for-merge branch 'testcommit3892' of github.com:jantman/gitpython_issue_301 -e247f10d9d5991ab02e451395de8f7211fdcad7a not-for-merge branch 'testcommit3893' of github.com:jantman/gitpython_issue_301 -39b78b0a16a5c0ae4cac55fe66d1c15d31d393b4 not-for-merge branch 'testcommit3894' of github.com:jantman/gitpython_issue_301 -7634768feb1804de498c41fc3488438a40a45d8f not-for-merge branch 'testcommit3895' of github.com:jantman/gitpython_issue_301 -577e26732d73a0f49785e133aed5df9f97d2c9dd not-for-merge branch 'testcommit3896' of github.com:jantman/gitpython_issue_301 -c9b3d530435bd772b4c9b50348da4dae52e48fb9 not-for-merge branch 'testcommit3897' of github.com:jantman/gitpython_issue_301 -8f62c5c8b6802f1baace842ddb6eb7051f2bc98e not-for-merge branch 'testcommit3898' of github.com:jantman/gitpython_issue_301 -85e2bd9253c1b770590e12de6348efeac83a3d00 not-for-merge branch 'testcommit3899' of github.com:jantman/gitpython_issue_301 -ae4e5dbc32debf78df0206db8f52d15464c8f745 not-for-merge branch 'testcommit39' of github.com:jantman/gitpython_issue_301 -c20b5618f3138a65d792ede4ebe5fd0d936b8efe not-for-merge branch 'testcommit390' of github.com:jantman/gitpython_issue_301 -9de05fca620f1448b84ed7a460255c89787ebecc not-for-merge branch 'testcommit3900' of github.com:jantman/gitpython_issue_301 -31830de5122d1f5dab0b4217e907ad2538bea8a7 not-for-merge branch 'testcommit3901' of github.com:jantman/gitpython_issue_301 -58aa1aca5b6ee2af76f67368eda51ed8ef99a622 not-for-merge branch 'testcommit3902' of github.com:jantman/gitpython_issue_301 -caae2c1add527091145bd98da94f35a795fd005f not-for-merge branch 'testcommit3903' of github.com:jantman/gitpython_issue_301 -6b9ee22c20949f83dc0ce57b2c7f8006f86cd0bb not-for-merge branch 'testcommit3904' of github.com:jantman/gitpython_issue_301 -e5c309035697ba9f26646e0ff86964a82b51cb00 not-for-merge branch 'testcommit3905' of github.com:jantman/gitpython_issue_301 -ee468a566795e437314400664e373bd4a257d302 not-for-merge branch 'testcommit3906' of github.com:jantman/gitpython_issue_301 -432f5cc64166b3e08ca6447e177f6917ffd31248 not-for-merge branch 'testcommit3907' of github.com:jantman/gitpython_issue_301 -8fd89909b8e9cc76085588627e418e6cf14a2d2a not-for-merge branch 'testcommit3908' of github.com:jantman/gitpython_issue_301 -19f82031991f16c78d88d40eaf95eaf1a24d203d not-for-merge branch 'testcommit3909' of github.com:jantman/gitpython_issue_301 -a52f3d75f0db5fbb0b8ccd0a2cfed4912fef924a not-for-merge branch 'testcommit391' of github.com:jantman/gitpython_issue_301 -19c191e54a0a61c4a36c7c72aaada2d59c5130bd not-for-merge branch 'testcommit3910' of github.com:jantman/gitpython_issue_301 -af944c5630a1ae99ce2249a161104943fa7fb99b not-for-merge branch 'testcommit3911' of github.com:jantman/gitpython_issue_301 -8f4aee6f0f9e7b993a11dabe2c65790a59d366d2 not-for-merge branch 'testcommit3912' of github.com:jantman/gitpython_issue_301 -b5f0492ef7cb877d123b962f85eed4597e67db8e not-for-merge branch 'testcommit3913' of github.com:jantman/gitpython_issue_301 -d05ed14b900312dc83c7e045af8497361184ff7a not-for-merge branch 'testcommit3914' of github.com:jantman/gitpython_issue_301 -b43a96f581dbeacb9d96128939253ed88c450984 not-for-merge branch 'testcommit3915' of github.com:jantman/gitpython_issue_301 -af4a4fc6f65c8a6f5b6eb333591143bd78f163e0 not-for-merge branch 'testcommit3916' of github.com:jantman/gitpython_issue_301 -81ba33a17651da3c661d809324d586e094a8b9b1 not-for-merge branch 'testcommit3917' of github.com:jantman/gitpython_issue_301 -b85a4a23bc4c28303cd5682cc112d75f3d87f607 not-for-merge branch 'testcommit3918' of github.com:jantman/gitpython_issue_301 -9c95076aef310382ff41827f1464c0636b5a1ba9 not-for-merge branch 'testcommit3919' of github.com:jantman/gitpython_issue_301 -575852e533be5fcb9d28a3a1fb5e358ba7fa0176 not-for-merge branch 'testcommit392' of github.com:jantman/gitpython_issue_301 -490047e6885fce07ef7c821a1b57d78b5b0c3c62 not-for-merge branch 'testcommit3920' of github.com:jantman/gitpython_issue_301 -c269dceb110a63552de99cd1c8e54fe4ce3a018b not-for-merge branch 'testcommit3921' of github.com:jantman/gitpython_issue_301 -97e83fbb4b2a28317bc399b6ac812883d80c7aef not-for-merge branch 'testcommit3922' of github.com:jantman/gitpython_issue_301 -a5b660dc2029dd716f865a055659ad97353294b4 not-for-merge branch 'testcommit3923' of github.com:jantman/gitpython_issue_301 -a4d3b8e3164d3da3f3fa997cc7d421230ead8392 not-for-merge branch 'testcommit3924' of github.com:jantman/gitpython_issue_301 -ca2e5c8f02a95ef9cf52ef0a9769421d6b332435 not-for-merge branch 'testcommit3925' of github.com:jantman/gitpython_issue_301 -3a6b7b9bdc8706963e6991f83aac55e0d1b36aea not-for-merge branch 'testcommit3926' of github.com:jantman/gitpython_issue_301 -c03543c9ceddbfda1c6df4085c9b9ce1fd2ac784 not-for-merge branch 'testcommit3927' of github.com:jantman/gitpython_issue_301 -3ae95906f301e06d57a4335f294acabc46473436 not-for-merge branch 'testcommit3928' of github.com:jantman/gitpython_issue_301 -cf26748ecb963deaf0b216860db4099547484723 not-for-merge branch 'testcommit3929' of github.com:jantman/gitpython_issue_301 -c1ed414955bb0fcb0756c63e986aa1b49477f9ed not-for-merge branch 'testcommit393' of github.com:jantman/gitpython_issue_301 -82fff8d60219b4853b316c84232a50ad381deffe not-for-merge branch 'testcommit3930' of github.com:jantman/gitpython_issue_301 -25d6987a8a4da6b5deabe297123c8fa7fa610572 not-for-merge branch 'testcommit3931' of github.com:jantman/gitpython_issue_301 -0089ee8a1067b293456f5e35aa8e47097e290376 not-for-merge branch 'testcommit3932' of github.com:jantman/gitpython_issue_301 -dedc65439ca2cb52898d3c14afc666171a1a03af not-for-merge branch 'testcommit3933' of github.com:jantman/gitpython_issue_301 -a6db19fc66b736370a7d61f236435255af22c82e not-for-merge branch 'testcommit3934' of github.com:jantman/gitpython_issue_301 -3fb6ae79fbe4e642818f80b27004c838036ad1ed not-for-merge branch 'testcommit3935' of github.com:jantman/gitpython_issue_301 -2a1bc1f05f220461c1f6153ecfdf352978978569 not-for-merge branch 'testcommit3936' of github.com:jantman/gitpython_issue_301 -812f1c62b4e623ea073bd89c9cdcafd9385b6c3b not-for-merge branch 'testcommit3937' of github.com:jantman/gitpython_issue_301 -ae762f6f3a6e0b05005b4c3567dfd88cab81eb0e not-for-merge branch 'testcommit3938' of github.com:jantman/gitpython_issue_301 -2f38a3ce46a3e19e05c2b7950bace89ebe03298d not-for-merge branch 'testcommit3939' of github.com:jantman/gitpython_issue_301 -43eb9dcda46bfafa70501c69c9e7b0fbd368fda7 not-for-merge branch 'testcommit394' of github.com:jantman/gitpython_issue_301 -5bc21149b222627f2fa05a871e325a9f5b3cd9fd not-for-merge branch 'testcommit3940' of github.com:jantman/gitpython_issue_301 -217f80b9511a361bf07f0d108d745bf6b725475c not-for-merge branch 'testcommit3941' of github.com:jantman/gitpython_issue_301 -fbdbd51e2c00acd28271b1546063436c6d2b1249 not-for-merge branch 'testcommit3942' of github.com:jantman/gitpython_issue_301 -88492ddd36cdc0ac1bfe9ef7b63e3caf4b29fe5a not-for-merge branch 'testcommit3943' of github.com:jantman/gitpython_issue_301 -178747bc40e5e432ca98c3edb2e20bb15b7f043b not-for-merge branch 'testcommit3944' of github.com:jantman/gitpython_issue_301 -6f3c5b26a051220d90e10a7b58f030213d2bb2dd not-for-merge branch 'testcommit3945' of github.com:jantman/gitpython_issue_301 -e2bffffff64411c2529c8397da8e593ff6bf834b not-for-merge branch 'testcommit3946' of github.com:jantman/gitpython_issue_301 -f29b87f309dc471a3438d8c011f54473d2f45edb not-for-merge branch 'testcommit3947' of github.com:jantman/gitpython_issue_301 -32d072fb2d85814484a1e223e71876debc111178 not-for-merge branch 'testcommit3948' of github.com:jantman/gitpython_issue_301 -13e455f8e0a8e3f2b8cbd44d73922cef86973421 not-for-merge branch 'testcommit3949' of github.com:jantman/gitpython_issue_301 -e4b34245d67b9eb6f9217478bab4d1d92c1d9df2 not-for-merge branch 'testcommit395' of github.com:jantman/gitpython_issue_301 -23ea6f454d71b34836e99736df567310495a5de2 not-for-merge branch 'testcommit3950' of github.com:jantman/gitpython_issue_301 -cc432fc87c155335c19d09a67bdd9165f6edfa87 not-for-merge branch 'testcommit3951' of github.com:jantman/gitpython_issue_301 -ff70aa4c8aa63a72de2b3fc1e92b9087ac9ac514 not-for-merge branch 'testcommit3952' of github.com:jantman/gitpython_issue_301 -b2e76d965d61397ae2b3f3ccb6b3fc0571d01bb4 not-for-merge branch 'testcommit3953' of github.com:jantman/gitpython_issue_301 -7532a90ad0732713c88cf2b966c1c11b9d8f2ba4 not-for-merge branch 'testcommit3954' of github.com:jantman/gitpython_issue_301 -68cea90b78fa81c749af1918ba924717aefa2646 not-for-merge branch 'testcommit3955' of github.com:jantman/gitpython_issue_301 -72beb00653155a83df4edb3eb3862479fd438595 not-for-merge branch 'testcommit3956' of github.com:jantman/gitpython_issue_301 -34c3ffa21c620f35a597fb2b4f9518244b0b8e5a not-for-merge branch 'testcommit3957' of github.com:jantman/gitpython_issue_301 -8582437515e93151ce6720b7ea29ae300cbc4cf5 not-for-merge branch 'testcommit3958' of github.com:jantman/gitpython_issue_301 -7d535dd2bde187727dbc8eaacae7c761c7af470f not-for-merge branch 'testcommit3959' of github.com:jantman/gitpython_issue_301 -bc0d42c3092a64fbbc5ce32caa81647d70c20cb4 not-for-merge branch 'testcommit396' of github.com:jantman/gitpython_issue_301 -534cf384f669e31ba7f9096a8bb6ec420f8136ff not-for-merge branch 'testcommit3960' of github.com:jantman/gitpython_issue_301 -fa4a9bf037332a4f008166287f3da05d971154ca not-for-merge branch 'testcommit3961' of github.com:jantman/gitpython_issue_301 -c7e1fe9a4b894d71a60473cfa04f557c8383eab8 not-for-merge branch 'testcommit3962' of github.com:jantman/gitpython_issue_301 -b1c1e6335791defeab18021e8661093cf326e7fd not-for-merge branch 'testcommit3963' of github.com:jantman/gitpython_issue_301 -49d42154c2a1375d17eadef801e98e59829bf5c0 not-for-merge branch 'testcommit3964' of github.com:jantman/gitpython_issue_301 -c84e8b83cbb1913dfafa1456fd3e23ffb9b5ba14 not-for-merge branch 'testcommit3965' of github.com:jantman/gitpython_issue_301 -f1fa9558d014e3a1548ff62d9d3d494becdc3a44 not-for-merge branch 'testcommit3966' of github.com:jantman/gitpython_issue_301 -77ca3dff38ebe8062eee6faa595ac2ecfc0b035f not-for-merge branch 'testcommit3967' of github.com:jantman/gitpython_issue_301 -ff856b5506c50535f115c72346c1fba1d19fec47 not-for-merge branch 'testcommit3968' of github.com:jantman/gitpython_issue_301 -ee88a97ab293a58994ec2ac89e993104041df1a8 not-for-merge branch 'testcommit3969' of github.com:jantman/gitpython_issue_301 -876612dd370bea75d1943a6a739b9ffee178d838 not-for-merge branch 'testcommit397' of github.com:jantman/gitpython_issue_301 -261f2a9f0dcf870e06d225d061c0292c27b84a26 not-for-merge branch 'testcommit3970' of github.com:jantman/gitpython_issue_301 -62ee01070a967cbca5281123ed683e9b0b658dab not-for-merge branch 'testcommit3971' of github.com:jantman/gitpython_issue_301 -a82934cbc6b58d6c8b20ca6799be683b76820375 not-for-merge branch 'testcommit3972' of github.com:jantman/gitpython_issue_301 -0c379e1d14aa6877e725642e1736ddb3d10ef4dc not-for-merge branch 'testcommit3973' of github.com:jantman/gitpython_issue_301 -782f11870e125bdea8ed6caf09cc1cd9abb87502 not-for-merge branch 'testcommit3974' of github.com:jantman/gitpython_issue_301 -2d53f9b7fb6575cae61e12a7903d489d845e68ec not-for-merge branch 'testcommit3975' of github.com:jantman/gitpython_issue_301 -d283cecf24f99da4b256cfe7ed88f17c3b1a4a46 not-for-merge branch 'testcommit3976' of github.com:jantman/gitpython_issue_301 -e6734afe8c81a6e0809f7b01ff64625dea7fbdc7 not-for-merge branch 'testcommit3977' of github.com:jantman/gitpython_issue_301 -83e5d2061f3cd84fb9c0a4b231cfe61c30b92fad not-for-merge branch 'testcommit3978' of github.com:jantman/gitpython_issue_301 -1c73e98917df4fab77954699eed0b4be776abb7b not-for-merge branch 'testcommit3979' of github.com:jantman/gitpython_issue_301 -5fa08cb503349586a195155aa475d5ec80efd483 not-for-merge branch 'testcommit398' of github.com:jantman/gitpython_issue_301 -ef8c527035ec9e33ee5ba57657163999ec13eac8 not-for-merge branch 'testcommit3980' of github.com:jantman/gitpython_issue_301 -6b13196ac6155308d6e21633f21ac3da99b3d0fb not-for-merge branch 'testcommit3981' of github.com:jantman/gitpython_issue_301 -88b81d922ec0a4ccb3ead64c8d0b29f079e6a7a3 not-for-merge branch 'testcommit3982' of github.com:jantman/gitpython_issue_301 -cc18ba44027b1114631ce115f686ae0f969804e9 not-for-merge branch 'testcommit3983' of github.com:jantman/gitpython_issue_301 -187d32a59ecc039110528449122d5809800c432c not-for-merge branch 'testcommit3984' of github.com:jantman/gitpython_issue_301 -a9654e8caaf29bc5c0bb5d26d1f2812af6e6c968 not-for-merge branch 'testcommit3985' of github.com:jantman/gitpython_issue_301 -5b3ecadd90fefb523dd8013f198ae560f72d0059 not-for-merge branch 'testcommit3986' of github.com:jantman/gitpython_issue_301 -c662ba860c1b51225553ded9022ee04f80aedd62 not-for-merge branch 'testcommit3987' of github.com:jantman/gitpython_issue_301 -be2f735ddcbf91a3924d55413a0ae29016d3228d not-for-merge branch 'testcommit3988' of github.com:jantman/gitpython_issue_301 -392aa250616fcc992c0bd9ee15e4250e63b07f77 not-for-merge branch 'testcommit3989' of github.com:jantman/gitpython_issue_301 -3827cbdbfd6830b7739150bee9128d83d68aa01d not-for-merge branch 'testcommit399' of github.com:jantman/gitpython_issue_301 -550a61339fd437486766e706c5fe04714f0fce34 not-for-merge branch 'testcommit3990' of github.com:jantman/gitpython_issue_301 -6bc63f3a76a47e336750cb38cccce71ca40a0401 not-for-merge branch 'testcommit3991' of github.com:jantman/gitpython_issue_301 -c797e5ed80f575cc221978020fe812c1c8acc91b not-for-merge branch 'testcommit3992' of github.com:jantman/gitpython_issue_301 -96054ce74df3dc430338cb94c26e7d244fbe6e34 not-for-merge branch 'testcommit3993' of github.com:jantman/gitpython_issue_301 -a291f78b8b373e249aa47abc528a42dfd5fcedf1 not-for-merge branch 'testcommit3994' of github.com:jantman/gitpython_issue_301 -99b9567903c2b71e2e76443860363286f23b30e3 not-for-merge branch 'testcommit3995' of github.com:jantman/gitpython_issue_301 -6f3b47d29dd7167613e590833998bfc547b8a9e4 not-for-merge branch 'testcommit3996' of github.com:jantman/gitpython_issue_301 -c7c6bbadca5655c92a1826a367eaf52ebbdb22aa not-for-merge branch 'testcommit3997' of github.com:jantman/gitpython_issue_301 -efe37e0e58a455ac6dcbca3de86bc2d3f27e1356 not-for-merge branch 'testcommit3998' of github.com:jantman/gitpython_issue_301 -dac06c4f56c9cd01052afe06cfd091ac4916cd62 not-for-merge branch 'testcommit3999' of github.com:jantman/gitpython_issue_301 -c56dda9a31bce0ce44ae875c6ad74af667e459b6 not-for-merge branch 'testcommit4' of github.com:jantman/gitpython_issue_301 -cd19da4bc14cdae6b77a7dbba787a6d2f065b0b0 not-for-merge branch 'testcommit40' of github.com:jantman/gitpython_issue_301 -7abb93dae4104614991985b7d2aef8e54d836147 not-for-merge branch 'testcommit400' of github.com:jantman/gitpython_issue_301 -a3057349cb84f2c3341c8f67e92e7052be0c52e3 not-for-merge branch 'testcommit4000' of github.com:jantman/gitpython_issue_301 -5358762b1ab961cb0398e4a9274d4424b6a10f3a not-for-merge branch 'testcommit4001' of github.com:jantman/gitpython_issue_301 -de0f23b36622345d70001b86f649f08bca6120b9 not-for-merge branch 'testcommit4002' of github.com:jantman/gitpython_issue_301 -79536cee3c4853dd28eff9a0eb9df8e2e69aa978 not-for-merge branch 'testcommit4003' of github.com:jantman/gitpython_issue_301 -348c092e43e6917093a3c5eb244589e30a0748dc not-for-merge branch 'testcommit4004' of github.com:jantman/gitpython_issue_301 -2a18319059144dac173a41028c9702099ab63ba9 not-for-merge branch 'testcommit4005' of github.com:jantman/gitpython_issue_301 -a20c3c9528b17084fe7d626aefe37bbcd9937a1d not-for-merge branch 'testcommit4006' of github.com:jantman/gitpython_issue_301 -f70b4170dc18f96640b761b6ea9446ac37740bbd not-for-merge branch 'testcommit4007' of github.com:jantman/gitpython_issue_301 -2f122f8dc735349b6e26ebc5ab4e809e3f00f73a not-for-merge branch 'testcommit4008' of github.com:jantman/gitpython_issue_301 -33918c425a06438d60e18939c88cb643b6d04d8a not-for-merge branch 'testcommit4009' of github.com:jantman/gitpython_issue_301 -927357356994d3125ac1e12886fe2631dd90f67b not-for-merge branch 'testcommit401' of github.com:jantman/gitpython_issue_301 -cd841ae3cf7d087c3759e657d0d5449738f27ded not-for-merge branch 'testcommit4010' of github.com:jantman/gitpython_issue_301 -10fe8b899896f6b924d1cbe90566f8dfac337cbd not-for-merge branch 'testcommit4011' of github.com:jantman/gitpython_issue_301 -05f77736b3cd428695c60124e1c289a3a4946255 not-for-merge branch 'testcommit4012' of github.com:jantman/gitpython_issue_301 -6f267ccd7c5a93bfb31412597102e6caf89678cf not-for-merge branch 'testcommit4013' of github.com:jantman/gitpython_issue_301 -8b92238d1f138827eb327da6a2516d50e704bd40 not-for-merge branch 'testcommit4014' of github.com:jantman/gitpython_issue_301 -246841451517c0abe79966f7a42ea9ab8b17eff9 not-for-merge branch 'testcommit4015' of github.com:jantman/gitpython_issue_301 -687270d6451fb71008167bb488e6768965ac3380 not-for-merge branch 'testcommit4016' of github.com:jantman/gitpython_issue_301 -3d119d07682eddfdcab617490db33e81fcec4bce not-for-merge branch 'testcommit4017' of github.com:jantman/gitpython_issue_301 -b313749ee7d1558b99264f69f0ccbbc2199606fa not-for-merge branch 'testcommit4018' of github.com:jantman/gitpython_issue_301 -db4015b9928b1b7dd5f503c35f891769d441cd47 not-for-merge branch 'testcommit4019' of github.com:jantman/gitpython_issue_301 -c7e1fbc3d44ead19ec235908ed8ac47471b233ed not-for-merge branch 'testcommit402' of github.com:jantman/gitpython_issue_301 -6bedb5576b0131c7186d33ac1bee197021daa5db not-for-merge branch 'testcommit4020' of github.com:jantman/gitpython_issue_301 -5b1b591cd7167b9a51a2f40da8fc3aaa06e40a56 not-for-merge branch 'testcommit4021' of github.com:jantman/gitpython_issue_301 -f3f98a8fdcf6a316255302b577d4d7846e0ec18f not-for-merge branch 'testcommit4022' of github.com:jantman/gitpython_issue_301 -8da4a37941fc057d795791b4ae589f01fc01bbaf not-for-merge branch 'testcommit4023' of github.com:jantman/gitpython_issue_301 -7e540d9e2434dfdc9dd8d109703d8d7b3163906d not-for-merge branch 'testcommit4024' of github.com:jantman/gitpython_issue_301 -de06085b5ef53091166e2437c99de8c108c4c4b1 not-for-merge branch 'testcommit4025' of github.com:jantman/gitpython_issue_301 -5e54e4db2051564e1b0626a1b5461f217b6939e8 not-for-merge branch 'testcommit4026' of github.com:jantman/gitpython_issue_301 -77d5c8fbea8cecf44a12cde9b29755c683d8454b not-for-merge branch 'testcommit4027' of github.com:jantman/gitpython_issue_301 -c228eeae6ba7dd12f9a9d7fc7c88ea24ca2664f7 not-for-merge branch 'testcommit4028' of github.com:jantman/gitpython_issue_301 -e07cbe543fa0cb2af596f20846f051650f4eeec2 not-for-merge branch 'testcommit4029' of github.com:jantman/gitpython_issue_301 -5d958ec88e74dfe9d2bfef4c88f0b0937c12b786 not-for-merge branch 'testcommit403' of github.com:jantman/gitpython_issue_301 -c0d19655a36c81b44fcda654790e9a2a375339ef not-for-merge branch 'testcommit4030' of github.com:jantman/gitpython_issue_301 -330b75d8f7913e5a6878c619dc4a95aecf6a5ae5 not-for-merge branch 'testcommit4031' of github.com:jantman/gitpython_issue_301 -9d03c61d8f812d62d0074efb2b20b8815024b1c2 not-for-merge branch 'testcommit4032' of github.com:jantman/gitpython_issue_301 -1b836213c97df34c5d26a1c5fc3e8d6aaa323ada not-for-merge branch 'testcommit4033' of github.com:jantman/gitpython_issue_301 -52262971afa1c0cae172eb1bff8a47ec911e469c not-for-merge branch 'testcommit4034' of github.com:jantman/gitpython_issue_301 -c44e48906b25a14c1187b0b7723f795783fafed0 not-for-merge branch 'testcommit4035' of github.com:jantman/gitpython_issue_301 -7842c2ace69308d7d74713f4ebc2a6b46a9fce4d not-for-merge branch 'testcommit4036' of github.com:jantman/gitpython_issue_301 -532d701491c84febbb793b5547a52a6c72be7602 not-for-merge branch 'testcommit4037' of github.com:jantman/gitpython_issue_301 -ce21b5885df28065a0417d23b34ad477020e407f not-for-merge branch 'testcommit4038' of github.com:jantman/gitpython_issue_301 -3927e886289d6a72aa25e992f4eddc4318c676e5 not-for-merge branch 'testcommit4039' of github.com:jantman/gitpython_issue_301 -cbd04044fe1d588f8d61126745d410b81e32b9fb not-for-merge branch 'testcommit404' of github.com:jantman/gitpython_issue_301 -a0fa8b6ddd23659efe72d13c8a5ee4013d4397c7 not-for-merge branch 'testcommit4040' of github.com:jantman/gitpython_issue_301 -ba0eab61c334efeae93d258dc7ac6a2d5ca3a133 not-for-merge branch 'testcommit4041' of github.com:jantman/gitpython_issue_301 -a0cc10b6e2fb3ae452d430c398f72f8229082efb not-for-merge branch 'testcommit4042' of github.com:jantman/gitpython_issue_301 -087089b004fd9b83778da1ded72721be43eae911 not-for-merge branch 'testcommit4043' of github.com:jantman/gitpython_issue_301 -94a527fc009b5b5999f483fee61312712c3dbb25 not-for-merge branch 'testcommit4044' of github.com:jantman/gitpython_issue_301 -2db7da14d9cc0ba84d4b78d559a3db76e312213b not-for-merge branch 'testcommit4045' of github.com:jantman/gitpython_issue_301 -92dd8c1419d56d1ed224ac103242b0027d9b4356 not-for-merge branch 'testcommit4046' of github.com:jantman/gitpython_issue_301 -9fb3f08d7ad6712b2d651793bb350600c70368a2 not-for-merge branch 'testcommit4047' of github.com:jantman/gitpython_issue_301 -3aa6a483a589a9acdc3d47aa6486b415e9a69c10 not-for-merge branch 'testcommit4048' of github.com:jantman/gitpython_issue_301 -fa45581b164ce0e74623bbfb70ecc5dd81fd49c2 not-for-merge branch 'testcommit4049' of github.com:jantman/gitpython_issue_301 -7aedf8e4427db7ec44b57eb2fc0f434fe4a13cd6 not-for-merge branch 'testcommit405' of github.com:jantman/gitpython_issue_301 -09cb9142c378309dec91dfad0c9cdd09af70f543 not-for-merge branch 'testcommit4050' of github.com:jantman/gitpython_issue_301 -3404dc645d9a88d31a54653fc38bad29b4d86944 not-for-merge branch 'testcommit4051' of github.com:jantman/gitpython_issue_301 -f905990221e897bc3ca10a32725a0459315bbaaa not-for-merge branch 'testcommit4052' of github.com:jantman/gitpython_issue_301 -fb811172515a2450d659abeca7df66dfd12992c7 not-for-merge branch 'testcommit4053' of github.com:jantman/gitpython_issue_301 -ff51970eb5375a563186f066f996afdd274ba2ea not-for-merge branch 'testcommit4054' of github.com:jantman/gitpython_issue_301 -8afb80ae78462c69e95a63ad516c378626f0dd21 not-for-merge branch 'testcommit4055' of github.com:jantman/gitpython_issue_301 -db014d419614efa2d5d450e2eb2808a5323101bd not-for-merge branch 'testcommit4056' of github.com:jantman/gitpython_issue_301 -9baca685a34ba36450b2367b9b478ec933dd41f9 not-for-merge branch 'testcommit4057' of github.com:jantman/gitpython_issue_301 -42d5da9ea17416dd47a7d70c3f16a853638b4502 not-for-merge branch 'testcommit4058' of github.com:jantman/gitpython_issue_301 -39bcf12a3ba9dc1f27986ef48b7c98c98923c256 not-for-merge branch 'testcommit4059' of github.com:jantman/gitpython_issue_301 -8509c5938858a35c0da64cb2822f34bb9320769e not-for-merge branch 'testcommit406' of github.com:jantman/gitpython_issue_301 -e88cf4316029e6fa15cb9e34ad41c6ab6c29209a not-for-merge branch 'testcommit4060' of github.com:jantman/gitpython_issue_301 -593e2b8677f1fd16099579283f44b7f46902bbdd not-for-merge branch 'testcommit4061' of github.com:jantman/gitpython_issue_301 -ce4855b2af0d078e077a2d4ab8f31d82b2dc44d8 not-for-merge branch 'testcommit4062' of github.com:jantman/gitpython_issue_301 -c8f1c1b94d6075ef9c6a1fb9a9565b1652fd3c41 not-for-merge branch 'testcommit4063' of github.com:jantman/gitpython_issue_301 -4c54915e6970303ac15fddf4237097286f242ace not-for-merge branch 'testcommit4064' of github.com:jantman/gitpython_issue_301 -3c26a7cce755928ff9e6c605d3b9d8596b7e2aa0 not-for-merge branch 'testcommit4065' of github.com:jantman/gitpython_issue_301 -fc015a34249a5c40548e0d494690a1d743f7ddc8 not-for-merge branch 'testcommit4066' of github.com:jantman/gitpython_issue_301 -f6f9e29e636eacc0f84654498761cde7e40d6d10 not-for-merge branch 'testcommit4067' of github.com:jantman/gitpython_issue_301 -593f3d7d01994f0bdb915ef173e7c0672bfa7149 not-for-merge branch 'testcommit4068' of github.com:jantman/gitpython_issue_301 -e6c1b2533e620be24b622b5f072bc58d9667421a not-for-merge branch 'testcommit4069' of github.com:jantman/gitpython_issue_301 -c3e134eb0e6412c29c8986f3db9a3007c9e904f4 not-for-merge branch 'testcommit407' of github.com:jantman/gitpython_issue_301 -3e865da172caa19dacadec4d1c1ee3cf6379252b not-for-merge branch 'testcommit4070' of github.com:jantman/gitpython_issue_301 -fc8ec56bfada622bd65f15976e68a7df27600b17 not-for-merge branch 'testcommit4071' of github.com:jantman/gitpython_issue_301 -dc2c7f3a1156b816caa095385203fb052522977b not-for-merge branch 'testcommit4072' of github.com:jantman/gitpython_issue_301 -59235cd36e311961707ce294af8b38d52439f53c not-for-merge branch 'testcommit4073' of github.com:jantman/gitpython_issue_301 -75a9dd00c3c1067a8fc73b4bdd889153a24b116d not-for-merge branch 'testcommit4074' of github.com:jantman/gitpython_issue_301 -0155d00d60165e6ace1f7fd482ba27732203aae0 not-for-merge branch 'testcommit4075' of github.com:jantman/gitpython_issue_301 -0c859cacd8decae0adde1bad6cb5eff4e854f950 not-for-merge branch 'testcommit4076' of github.com:jantman/gitpython_issue_301 -a3c0c245314d977cd62878f5cd17cd51826032fa not-for-merge branch 'testcommit4077' of github.com:jantman/gitpython_issue_301 -8f982d3828cbd0982301a7f5162b87676374b429 not-for-merge branch 'testcommit4078' of github.com:jantman/gitpython_issue_301 -9adb13cb65439327f4387d8324446d24900e0ce0 not-for-merge branch 'testcommit4079' of github.com:jantman/gitpython_issue_301 -e8c830c965e1333d23c673d8871a551438033248 not-for-merge branch 'testcommit408' of github.com:jantman/gitpython_issue_301 -e33e7bb720053eb08923e24c94bc9e6d93117601 not-for-merge branch 'testcommit4080' of github.com:jantman/gitpython_issue_301 -0fd0321fa5644ee42e369096288bc320532d5828 not-for-merge branch 'testcommit4081' of github.com:jantman/gitpython_issue_301 -862c7246f818e9cf9454b7df8b245b9c02d96a36 not-for-merge branch 'testcommit4082' of github.com:jantman/gitpython_issue_301 -579be41154adcd76772ccd77a787c70543f511ba not-for-merge branch 'testcommit4083' of github.com:jantman/gitpython_issue_301 -83ee0280bf19603ba7a00b5fba3543aeedd29e2d not-for-merge branch 'testcommit4084' of github.com:jantman/gitpython_issue_301 -dbeb510475029d96f4a2c738c0cd82753d7050d4 not-for-merge branch 'testcommit4085' of github.com:jantman/gitpython_issue_301 -a2ab57cc28a7ec71c8dcd5810dc5f531f0f9ff66 not-for-merge branch 'testcommit4086' of github.com:jantman/gitpython_issue_301 -ee506c723ea7dd65dc484bffdc90421ca0382d4c not-for-merge branch 'testcommit4087' of github.com:jantman/gitpython_issue_301 -ab29a0c7ce83daa6921652c64536113a3aab5b1b not-for-merge branch 'testcommit4088' of github.com:jantman/gitpython_issue_301 -7e1eea2c9ff30af51a4cbcda63f76f35de690d22 not-for-merge branch 'testcommit4089' of github.com:jantman/gitpython_issue_301 -f521958f95fb32d3fb11bb5d0a12b99f42e5a61a not-for-merge branch 'testcommit409' of github.com:jantman/gitpython_issue_301 -18015a187cbd0c4f97d963327d8c985d18c4d041 not-for-merge branch 'testcommit4090' of github.com:jantman/gitpython_issue_301 -007a67f9cbd35fdd5c249c2097fb3453a84f7839 not-for-merge branch 'testcommit4091' of github.com:jantman/gitpython_issue_301 -c2fa57e0ae22c237037085b0ed9eb38987bbfb28 not-for-merge branch 'testcommit4092' of github.com:jantman/gitpython_issue_301 -c67e8a803d00c7f7f4fa8554cb07174dec90bf30 not-for-merge branch 'testcommit4093' of github.com:jantman/gitpython_issue_301 -5907c0458adc0f42b92f64d636366df9c46c955f not-for-merge branch 'testcommit4094' of github.com:jantman/gitpython_issue_301 -732004269dad18459ab93c47ac6a1a74f6eb1da9 not-for-merge branch 'testcommit4095' of github.com:jantman/gitpython_issue_301 -4825afe0d5571f4097082e6db13e9700646b73d7 not-for-merge branch 'testcommit4096' of github.com:jantman/gitpython_issue_301 -69f46865894fd6aa551be5ab6b365c53525c7913 not-for-merge branch 'testcommit4097' of github.com:jantman/gitpython_issue_301 -817444367567e1e3fab26005cf4e867bddc7ada5 not-for-merge branch 'testcommit4098' of github.com:jantman/gitpython_issue_301 -070716d2e8774db20b50e372f288a60e63593d8f not-for-merge branch 'testcommit4099' of github.com:jantman/gitpython_issue_301 -89edc0eebe6f59e088db308d483bbb9e5a565437 not-for-merge branch 'testcommit41' of github.com:jantman/gitpython_issue_301 -1da72c8959746d417c2418c9e99b4c2196feef90 not-for-merge branch 'testcommit410' of github.com:jantman/gitpython_issue_301 -818baafdd71fceda5a715bd85738c5d75071283d not-for-merge branch 'testcommit4100' of github.com:jantman/gitpython_issue_301 -eb6459871bd448752ca35033b907f7d3535e239c not-for-merge branch 'testcommit4101' of github.com:jantman/gitpython_issue_301 -d2c56ca5c14b9bdb0c8ce6f580beb7a02b541903 not-for-merge branch 'testcommit4102' of github.com:jantman/gitpython_issue_301 -a6b12e7cc4344f4301a3f4466ae25a982cbd0ec2 not-for-merge branch 'testcommit4103' of github.com:jantman/gitpython_issue_301 -1e5219ebf4782a5fcf70a18416dfc65cd9c154c0 not-for-merge branch 'testcommit4104' of github.com:jantman/gitpython_issue_301 -0b8e42a3e17ce1f2678f6beab93441dafd799ee6 not-for-merge branch 'testcommit4105' of github.com:jantman/gitpython_issue_301 -8733ae3bdd8e56df7edc80a60101bed66a2761aa not-for-merge branch 'testcommit4106' of github.com:jantman/gitpython_issue_301 -660910e42f1340d71a23bdf66618d5d949a83301 not-for-merge branch 'testcommit4107' of github.com:jantman/gitpython_issue_301 -2f83a8e851dc10370d5ae7e69f6ec4237919f91a not-for-merge branch 'testcommit4108' of github.com:jantman/gitpython_issue_301 -3009ac844a124e04562e301d584cdc73b229df3f not-for-merge branch 'testcommit4109' of github.com:jantman/gitpython_issue_301 -2f7fef1b3362b1fbbb7abae932397f47e212da84 not-for-merge branch 'testcommit411' of github.com:jantman/gitpython_issue_301 -ceb469b927b162691381b74947e7b4612b0963c1 not-for-merge branch 'testcommit4110' of github.com:jantman/gitpython_issue_301 -403281e781f89d5c6097b968a78a63f465ccad1d not-for-merge branch 'testcommit4111' of github.com:jantman/gitpython_issue_301 -6ff326b87b2fd0000fd81cd8f7057e62a79cf9a5 not-for-merge branch 'testcommit4112' of github.com:jantman/gitpython_issue_301 -71ba0e5736c7779c03470939af3585bfd773dcc1 not-for-merge branch 'testcommit4113' of github.com:jantman/gitpython_issue_301 -b5b81f5c311b4b500f63b507bd9cc9355573988b not-for-merge branch 'testcommit4114' of github.com:jantman/gitpython_issue_301 -0ff98aeb88a477c7a1ec227d0115617339b171e3 not-for-merge branch 'testcommit4115' of github.com:jantman/gitpython_issue_301 -5756ac1e1783a34c0937c2fd83e2cc87cb88294b not-for-merge branch 'testcommit4116' of github.com:jantman/gitpython_issue_301 -a82fe6ef0c179e6fe15e03cad16511da5935c90d not-for-merge branch 'testcommit4117' of github.com:jantman/gitpython_issue_301 -ca0ef2aa22ab9dd0f86a87bdf4161c2eaa6583d9 not-for-merge branch 'testcommit4118' of github.com:jantman/gitpython_issue_301 -62c6eaf594bb251a5a87af34209c7f91b0590317 not-for-merge branch 'testcommit4119' of github.com:jantman/gitpython_issue_301 -5c1c2349679962ab3090f9b92d520e825c59a98f not-for-merge branch 'testcommit412' of github.com:jantman/gitpython_issue_301 -037e40cb0438b32ab3edbafb77cf50142ecd3c7a not-for-merge branch 'testcommit4120' of github.com:jantman/gitpython_issue_301 -3584ac42f83e4c531e8f1269a1cf80a70ccd88c7 not-for-merge branch 'testcommit4121' of github.com:jantman/gitpython_issue_301 -243930bd7c93661a57e70777cb8e939df3605435 not-for-merge branch 'testcommit4122' of github.com:jantman/gitpython_issue_301 -9b33f39769700d0fa6d7bb2fde7641f6de192569 not-for-merge branch 'testcommit4123' of github.com:jantman/gitpython_issue_301 -420dd4eb61f9dca8ac8d131664264d48832b7b44 not-for-merge branch 'testcommit4124' of github.com:jantman/gitpython_issue_301 -46f6813377e5dbcf7db21eaf82e8d77191db3340 not-for-merge branch 'testcommit4125' of github.com:jantman/gitpython_issue_301 -ebb254499e982b693c132550c96730d6d0351ab2 not-for-merge branch 'testcommit4126' of github.com:jantman/gitpython_issue_301 -4328f01bb8aaa872c566906ada956c4ee4f4f67d not-for-merge branch 'testcommit4127' of github.com:jantman/gitpython_issue_301 -0c385b6ed2eae12177b6e6720ccf308f712e51ac not-for-merge branch 'testcommit4128' of github.com:jantman/gitpython_issue_301 -bd4f028fc05551e3db377e74607b474823d2c11c not-for-merge branch 'testcommit4129' of github.com:jantman/gitpython_issue_301 -7af96f153306a47598be8147871beecbc1713adf not-for-merge branch 'testcommit413' of github.com:jantman/gitpython_issue_301 -321de3324b896a960db8dc4c6f3cc9316049f3c9 not-for-merge branch 'testcommit4130' of github.com:jantman/gitpython_issue_301 -2ea831a41f424d48a36b4187f4895ccc7f743268 not-for-merge branch 'testcommit4131' of github.com:jantman/gitpython_issue_301 -ee517fd07202141a033f0fdc408c1248a7e60edf not-for-merge branch 'testcommit4132' of github.com:jantman/gitpython_issue_301 -6b0696087264a7cae50e347b448662d644423d48 not-for-merge branch 'testcommit4133' of github.com:jantman/gitpython_issue_301 -fb739d50f566c06ac3a8f575619f994e196ca11b not-for-merge branch 'testcommit4134' of github.com:jantman/gitpython_issue_301 -68537fa01cb57a0231068e3aaa5425fb05e7970d not-for-merge branch 'testcommit4135' of github.com:jantman/gitpython_issue_301 -cb977df44b3e5d453b503480fe3593dffae53120 not-for-merge branch 'testcommit4136' of github.com:jantman/gitpython_issue_301 -6afaf7c4a5d80b914af403dac535346f7a26b4f7 not-for-merge branch 'testcommit4137' of github.com:jantman/gitpython_issue_301 -4a2e96e635d0f5d24bffa54f4b478a8f6253bb8e not-for-merge branch 'testcommit4138' of github.com:jantman/gitpython_issue_301 -eec09e14b29f953fb69d76cf9284c913ea39cf5a not-for-merge branch 'testcommit4139' of github.com:jantman/gitpython_issue_301 -526dfba10b04b3206b4e358a9bac0042022371a3 not-for-merge branch 'testcommit414' of github.com:jantman/gitpython_issue_301 -cf1d48f68aa31104c95ceef661298bdede029dfa not-for-merge branch 'testcommit4140' of github.com:jantman/gitpython_issue_301 -2842eb07b2648b32f83668e2ac308fd19ef5007a not-for-merge branch 'testcommit4141' of github.com:jantman/gitpython_issue_301 -43edf7a48f0fe52dddd282f1f7e6c31ffd82c90d not-for-merge branch 'testcommit4142' of github.com:jantman/gitpython_issue_301 -0314295173356554bbfd2ed009dcb762136e2a07 not-for-merge branch 'testcommit4143' of github.com:jantman/gitpython_issue_301 -3fb38bfca15dd806e978432e37fc0625117ae642 not-for-merge branch 'testcommit4144' of github.com:jantman/gitpython_issue_301 -2e9b25d502914c3f571c642eb870ebd639934391 not-for-merge branch 'testcommit4145' of github.com:jantman/gitpython_issue_301 -92f06134085ee62c40392f7087beefd9b5c4e770 not-for-merge branch 'testcommit4146' of github.com:jantman/gitpython_issue_301 -d486d094cf5cad4931ce81c04fd843c8e56d9786 not-for-merge branch 'testcommit4147' of github.com:jantman/gitpython_issue_301 -00f0dceadbbb627bed8914c00d2bf079fe93351b not-for-merge branch 'testcommit4148' of github.com:jantman/gitpython_issue_301 -e703419af085e56c27f5d17c55661eb1ce3af5e0 not-for-merge branch 'testcommit4149' of github.com:jantman/gitpython_issue_301 -6d00dd33b3b7e767d4a9ff2794e276a05af0a1e2 not-for-merge branch 'testcommit415' of github.com:jantman/gitpython_issue_301 -6365e1653fb25ea02119cea6afad7d7dfbab9d58 not-for-merge branch 'testcommit4150' of github.com:jantman/gitpython_issue_301 -312982ed2307c9d0dc0280b095c68b6bf2f6a3a1 not-for-merge branch 'testcommit4151' of github.com:jantman/gitpython_issue_301 -1dfb00a038f173a535e4f498d4e0142d6a904cba not-for-merge branch 'testcommit4152' of github.com:jantman/gitpython_issue_301 -641f245ded192ca856806ad107316d8762005503 not-for-merge branch 'testcommit4153' of github.com:jantman/gitpython_issue_301 -8297eef8a17bed20b5eb4b874825410c1e33b0fe not-for-merge branch 'testcommit4154' of github.com:jantman/gitpython_issue_301 -811445b71050da518ce1b7d0316b30aa4124bde8 not-for-merge branch 'testcommit4155' of github.com:jantman/gitpython_issue_301 -596554f0231e6760fb0ad42540ab39abaa8eb910 not-for-merge branch 'testcommit4156' of github.com:jantman/gitpython_issue_301 -d8caf2ef1ff98f9a4e4a17af1bd21c1c7c11ad4d not-for-merge branch 'testcommit4157' of github.com:jantman/gitpython_issue_301 -e192684c93e934005574520c4d97d54cd9250874 not-for-merge branch 'testcommit4158' of github.com:jantman/gitpython_issue_301 -a569b7f0872d92d7e8d05aceac8a6455316b82ee not-for-merge branch 'testcommit4159' of github.com:jantman/gitpython_issue_301 -ede0f4bc17837284577159b2b30e039f3319133c not-for-merge branch 'testcommit416' of github.com:jantman/gitpython_issue_301 -dd1ac341efc0b2276a493ce8237f1a9551b9a45b not-for-merge branch 'testcommit4160' of github.com:jantman/gitpython_issue_301 -1fb5bea252847c08f8883c7c98ff55f138145e2a not-for-merge branch 'testcommit4161' of github.com:jantman/gitpython_issue_301 -d2244531e6297f9d69509cdee990d9edda1cd86c not-for-merge branch 'testcommit4162' of github.com:jantman/gitpython_issue_301 -6aebd8879e240e3eeeaed220f4d4a9fadb3d65d2 not-for-merge branch 'testcommit4163' of github.com:jantman/gitpython_issue_301 -1869ad9a3e6186c8b0e432be052cb1f615ed2749 not-for-merge branch 'testcommit4164' of github.com:jantman/gitpython_issue_301 -ab7d63be56fd70f9a97b87ac9c73d85183dacd85 not-for-merge branch 'testcommit4165' of github.com:jantman/gitpython_issue_301 -a63feee9af10ebf68b55a53bd49eeb9acc910d36 not-for-merge branch 'testcommit4166' of github.com:jantman/gitpython_issue_301 -0fb84e138dcc7854069aeaeb51de43a6be7d3977 not-for-merge branch 'testcommit4167' of github.com:jantman/gitpython_issue_301 -58be66059ddb9bcdb0d9723273c5a258dc89bb6a not-for-merge branch 'testcommit4168' of github.com:jantman/gitpython_issue_301 -8d7546be5c1935adf397b9c9b04dbf61e9060d6c not-for-merge branch 'testcommit4169' of github.com:jantman/gitpython_issue_301 -d595e73a3aa8380a47af94552c932c8c8f3241e5 not-for-merge branch 'testcommit417' of github.com:jantman/gitpython_issue_301 -a01209e29512f650662034a527ed481dbfb589e5 not-for-merge branch 'testcommit4170' of github.com:jantman/gitpython_issue_301 -46b36368f40ec0d24799f2d1387e33afcd09af31 not-for-merge branch 'testcommit4171' of github.com:jantman/gitpython_issue_301 -5f4088ef962bd5975c506c64689f4acc6c9a6c63 not-for-merge branch 'testcommit4172' of github.com:jantman/gitpython_issue_301 -853d14a472b7b956f2b96f7d146476a435bba36d not-for-merge branch 'testcommit4173' of github.com:jantman/gitpython_issue_301 -f1ef3acf046598deded8dec1b7577e6c9da78f46 not-for-merge branch 'testcommit4174' of github.com:jantman/gitpython_issue_301 -4b1bde66ab03b07a8a7ee5cc78a9620fdb179be0 not-for-merge branch 'testcommit4175' of github.com:jantman/gitpython_issue_301 -7ce80e49cc97ca221f9544182f7658fd2a35f383 not-for-merge branch 'testcommit4176' of github.com:jantman/gitpython_issue_301 -164003f9d136a6315ccdea77a84d635d0a39b3db not-for-merge branch 'testcommit4177' of github.com:jantman/gitpython_issue_301 -cf67e8485f4e69478c97febe3afd743320033e6e not-for-merge branch 'testcommit4178' of github.com:jantman/gitpython_issue_301 -7541e852756c8f1d9f15f42fa2ad5f2a010e836d not-for-merge branch 'testcommit4179' of github.com:jantman/gitpython_issue_301 -db2cfd26a3b56087b3dbeabfcec0fb3ead96a040 not-for-merge branch 'testcommit418' of github.com:jantman/gitpython_issue_301 -0913d611edc71036484b07c6d5b645b18f3a792f not-for-merge branch 'testcommit4180' of github.com:jantman/gitpython_issue_301 -830af02c4013de4dacd58cbd06f5bdcb74395ce9 not-for-merge branch 'testcommit4181' of github.com:jantman/gitpython_issue_301 -b9d0b88500abc81a0168da29957f193a6df887b2 not-for-merge branch 'testcommit4182' of github.com:jantman/gitpython_issue_301 -ea8af9727d554f6cfe19bb38afad42372a06700b not-for-merge branch 'testcommit4183' of github.com:jantman/gitpython_issue_301 -a0a6bb4cd9cae3e72234f2c977827023b309944b not-for-merge branch 'testcommit4184' of github.com:jantman/gitpython_issue_301 -3be1bb96bc19c7d7d2416fd34dfb2a8aef6db225 not-for-merge branch 'testcommit4185' of github.com:jantman/gitpython_issue_301 -f9ec5ec40e1925c34dc8881c30433ada21c3b2e9 not-for-merge branch 'testcommit4186' of github.com:jantman/gitpython_issue_301 -9822bb09c1c7cb2047e97cecd65cd4f27e826b72 not-for-merge branch 'testcommit4187' of github.com:jantman/gitpython_issue_301 -d2497a02fd99276e6aa78a41d9f2165bf34da7a4 not-for-merge branch 'testcommit4188' of github.com:jantman/gitpython_issue_301 -7109eda66c159e4ed00d6837cdef43048966b8d9 not-for-merge branch 'testcommit4189' of github.com:jantman/gitpython_issue_301 -be6a4c9d66ca1671da35ae0d7ab49d66b31f6e89 not-for-merge branch 'testcommit419' of github.com:jantman/gitpython_issue_301 -ac8bfbb04ed89a85027f608f3fe1e566db959892 not-for-merge branch 'testcommit4190' of github.com:jantman/gitpython_issue_301 -c79bfd51a9c3a15e31f773ef87df159707bd38a3 not-for-merge branch 'testcommit4191' of github.com:jantman/gitpython_issue_301 -37e9a93fa771ef8b8afb6322a8c1fdd3c177a4f5 not-for-merge branch 'testcommit4192' of github.com:jantman/gitpython_issue_301 -f9b09c97b68ed34e520da6dd61a6a26bfe9541c4 not-for-merge branch 'testcommit4193' of github.com:jantman/gitpython_issue_301 -8a6427ce29a8ff7768d3e8c74fa8119b8e43cef9 not-for-merge branch 'testcommit4194' of github.com:jantman/gitpython_issue_301 -a92d1ce80a0c73f13347733d5e892e3c624b2a23 not-for-merge branch 'testcommit4195' of github.com:jantman/gitpython_issue_301 -d621088f8e0d8bda4c9e1fc3da18f3cdbbd66111 not-for-merge branch 'testcommit4196' of github.com:jantman/gitpython_issue_301 -43dfe20ee61bc5752f6e58132696074a6e196db2 not-for-merge branch 'testcommit4197' of github.com:jantman/gitpython_issue_301 -88b37a4a6d56af13b327eac18521ba5442588cbb not-for-merge branch 'testcommit4198' of github.com:jantman/gitpython_issue_301 -baa0963bac8363684d2fa788d7f95b001ef8fd07 not-for-merge branch 'testcommit4199' of github.com:jantman/gitpython_issue_301 -b6cb8b5f76b5f4216c1b8003797a5f777f6f22f4 not-for-merge branch 'testcommit42' of github.com:jantman/gitpython_issue_301 -13a3c9b587f3d835e234e4850d7aaa0ad49fec68 not-for-merge branch 'testcommit420' of github.com:jantman/gitpython_issue_301 -2a0b7a5d3ac6662a9635a3e2b83cc57469384a7f not-for-merge branch 'testcommit4200' of github.com:jantman/gitpython_issue_301 -4702d99bc49b1837942d6e70491f7f6d6f2c47bc not-for-merge branch 'testcommit4201' of github.com:jantman/gitpython_issue_301 -f498b770fbd87982f8db3d3d9c8df0ffd31ad750 not-for-merge branch 'testcommit4202' of github.com:jantman/gitpython_issue_301 -60fc41cfeb9a4be3077658927d54802822d2a553 not-for-merge branch 'testcommit4203' of github.com:jantman/gitpython_issue_301 -724f09f803de62e291194e2390034e144fe4c33d not-for-merge branch 'testcommit4204' of github.com:jantman/gitpython_issue_301 -a97cd718f1a62de320e2905dd9ad10db5b7ebb82 not-for-merge branch 'testcommit4205' of github.com:jantman/gitpython_issue_301 -7407f315d3f648f7410321be7bc3afd3f331dafe not-for-merge branch 'testcommit4206' of github.com:jantman/gitpython_issue_301 -eecb3f22f2cb4946c4762dedd1187df9e75c988b not-for-merge branch 'testcommit4207' of github.com:jantman/gitpython_issue_301 -b47e81cc6216e90a76f78fffcad62f0ae1cf9328 not-for-merge branch 'testcommit4208' of github.com:jantman/gitpython_issue_301 -638eb215cf6acc59fc0132d7686a30f160f2b2a1 not-for-merge branch 'testcommit4209' of github.com:jantman/gitpython_issue_301 -d8b39b4a531163e1b49b6fc6b0de2f117145ed94 not-for-merge branch 'testcommit421' of github.com:jantman/gitpython_issue_301 -618f72bf6dd7f64a428d0939127baf5c9f4dee66 not-for-merge branch 'testcommit4210' of github.com:jantman/gitpython_issue_301 -4fab3c9110a80783a315ae6499a88847331a9088 not-for-merge branch 'testcommit4211' of github.com:jantman/gitpython_issue_301 -a18b0fd70c96ee55fb6f221f60f80a23b53a447b not-for-merge branch 'testcommit4212' of github.com:jantman/gitpython_issue_301 -e343952e29681a4f719a2a96aeb0edeee16dd239 not-for-merge branch 'testcommit4213' of github.com:jantman/gitpython_issue_301 -3f88c66ef96c337a995e2c528cd0fb71e5b054ee not-for-merge branch 'testcommit4214' of github.com:jantman/gitpython_issue_301 -3d2547fb9d22ec3c93b08eb24cceb5c1e9532bbf not-for-merge branch 'testcommit4215' of github.com:jantman/gitpython_issue_301 -7cff183d464b8fa4b47d15b68ccddbadb205f4ff not-for-merge branch 'testcommit4216' of github.com:jantman/gitpython_issue_301 -f93347955813839e6bed7c3ce8b0c11ba6bb5e3e not-for-merge branch 'testcommit4217' of github.com:jantman/gitpython_issue_301 -897f1766cec3671e7aa9605f0bc135836ca5f7d9 not-for-merge branch 'testcommit4218' of github.com:jantman/gitpython_issue_301 -39cac3dd60890a9662c9de24ebe20d3252f603b2 not-for-merge branch 'testcommit4219' of github.com:jantman/gitpython_issue_301 -2f2447ea9dcdb7a457c858283138c71ac23835b0 not-for-merge branch 'testcommit422' of github.com:jantman/gitpython_issue_301 -e5e8c78b3257c591a79420dec599200a44efc6fb not-for-merge branch 'testcommit4220' of github.com:jantman/gitpython_issue_301 -44e9c45405095e4aeedbc2ee2c074010783aa3da not-for-merge branch 'testcommit4221' of github.com:jantman/gitpython_issue_301 -9950ac280ccd680de190963397643861151c1003 not-for-merge branch 'testcommit4222' of github.com:jantman/gitpython_issue_301 -bd780278e3c192a0778eb15bc2314ab814a7ab9c not-for-merge branch 'testcommit4223' of github.com:jantman/gitpython_issue_301 -87b24fbc9d785acdfe906fe0557ff6f29a505d9e not-for-merge branch 'testcommit4224' of github.com:jantman/gitpython_issue_301 -ec1568c0f58745f226d19d91e0b3d4fa05285f37 not-for-merge branch 'testcommit4225' of github.com:jantman/gitpython_issue_301 -cb7cdec01ac52ffceeb374ce52337a48533824f5 not-for-merge branch 'testcommit4226' of github.com:jantman/gitpython_issue_301 -451f49c5876c0ef1a8c33618df4914fa4f61e67d not-for-merge branch 'testcommit4227' of github.com:jantman/gitpython_issue_301 -b39a2a7261821ba8833592131e1b3e07c9c86505 not-for-merge branch 'testcommit4228' of github.com:jantman/gitpython_issue_301 -75e0054cd2cfec9a2df7fdd48e560ac73029f71a not-for-merge branch 'testcommit4229' of github.com:jantman/gitpython_issue_301 -ea2aa5d80589d7cbf4dd2e8771cfe7390ed35a25 not-for-merge branch 'testcommit423' of github.com:jantman/gitpython_issue_301 -c15af982dfe3ae42eb3165be8ba34c5d3263535c not-for-merge branch 'testcommit4230' of github.com:jantman/gitpython_issue_301 -4f71bf5bb31383eb7be0fcb890a456df7ca97778 not-for-merge branch 'testcommit4231' of github.com:jantman/gitpython_issue_301 -fd9c2b8efd831bfe902ce24e8e1d6fa8c4d5fb6f not-for-merge branch 'testcommit4232' of github.com:jantman/gitpython_issue_301 -d7827dc0d42b082cb2c0e294eea4b42af57b8d5a not-for-merge branch 'testcommit4233' of github.com:jantman/gitpython_issue_301 -7f5a6cfb4c77bfb044978ce9b078ef4cb3342538 not-for-merge branch 'testcommit4234' of github.com:jantman/gitpython_issue_301 -c91bbb91791b5c37511d8e787a198814cc07c752 not-for-merge branch 'testcommit4235' of github.com:jantman/gitpython_issue_301 -5207bd77a894c1d3a24e6a6a2240af466644e976 not-for-merge branch 'testcommit4236' of github.com:jantman/gitpython_issue_301 -dc63c8af81665db5ed0d2f6ee7f6073b611ac37f not-for-merge branch 'testcommit4237' of github.com:jantman/gitpython_issue_301 -460bf9fb9b7468abe2def99efd16ac8905d7b4fe not-for-merge branch 'testcommit4238' of github.com:jantman/gitpython_issue_301 -0b37fb22cfa0bc3f31b6a3a05561cd3a369b4e0f not-for-merge branch 'testcommit4239' of github.com:jantman/gitpython_issue_301 -514f54afd508cc6d44d9994b76f220965b17c435 not-for-merge branch 'testcommit424' of github.com:jantman/gitpython_issue_301 -9d0c8f23cb283490a5eb010fde833074d8334da1 not-for-merge branch 'testcommit4240' of github.com:jantman/gitpython_issue_301 -eb70f44b7dfbafc635e01c4973067d9c6c4b06ac not-for-merge branch 'testcommit4241' of github.com:jantman/gitpython_issue_301 -2af3db4c11cde93e22baf140824e07ce5ddc0b37 not-for-merge branch 'testcommit4242' of github.com:jantman/gitpython_issue_301 -bc711556ec35c98de58cfabfbecc7731f0dccab9 not-for-merge branch 'testcommit4243' of github.com:jantman/gitpython_issue_301 -3527cc5f58665930d0437042fde5b8da7d722037 not-for-merge branch 'testcommit4244' of github.com:jantman/gitpython_issue_301 -cf0f8ac1856241fed1384d7e4a04051d2b4fab34 not-for-merge branch 'testcommit4245' of github.com:jantman/gitpython_issue_301 -ecc1bca08f3df927e6195e7719a7809c0af47347 not-for-merge branch 'testcommit4246' of github.com:jantman/gitpython_issue_301 -13c13036ab466217746a36a579031e18757ece2c not-for-merge branch 'testcommit4247' of github.com:jantman/gitpython_issue_301 -37b161a6f900deb8f74d67c8e83d8ac21f0e50c3 not-for-merge branch 'testcommit4248' of github.com:jantman/gitpython_issue_301 -7d778bdb49de4001b01bbab9792465962cb904a7 not-for-merge branch 'testcommit4249' of github.com:jantman/gitpython_issue_301 -f6b253f01493dae4a7e18a7b9a19f1ac34da3ebe not-for-merge branch 'testcommit425' of github.com:jantman/gitpython_issue_301 -b4155ec9e6ad378fc676d579a7105f7d0746624f not-for-merge branch 'testcommit4250' of github.com:jantman/gitpython_issue_301 -09c8cce5e82883d3334cfa38b23d0b97092b061a not-for-merge branch 'testcommit4251' of github.com:jantman/gitpython_issue_301 -af7d268e1568ab553c22013e5ad759c9abc927e5 not-for-merge branch 'testcommit4252' of github.com:jantman/gitpython_issue_301 -801a6c961f9107e92aade3b0e6d209711e63182d not-for-merge branch 'testcommit4253' of github.com:jantman/gitpython_issue_301 -0e13e63de3f9facb70968019db226b91827a3ad1 not-for-merge branch 'testcommit4254' of github.com:jantman/gitpython_issue_301 -11813546595917ddb6ec471662ec24c3962cb0bc not-for-merge branch 'testcommit4255' of github.com:jantman/gitpython_issue_301 -4253fa09c192cd00ca19514faceff1414b7268d7 not-for-merge branch 'testcommit4256' of github.com:jantman/gitpython_issue_301 -83e83cd37ed1eb3473b256ed1311bc709c064dc0 not-for-merge branch 'testcommit4257' of github.com:jantman/gitpython_issue_301 -906912f2bc4438e6bf20edd1d9f002b82f7a0040 not-for-merge branch 'testcommit4258' of github.com:jantman/gitpython_issue_301 -4cb5f6cc38e91a02d52779886e55a731f9fc7779 not-for-merge branch 'testcommit4259' of github.com:jantman/gitpython_issue_301 -b467e3148530a349c31f1e39c1083184a9f44089 not-for-merge branch 'testcommit426' of github.com:jantman/gitpython_issue_301 -670fb528e483588876e5f5095ab0988cc27c7349 not-for-merge branch 'testcommit4260' of github.com:jantman/gitpython_issue_301 -133150487f899adecb4f0ad35b099bea01d6ca30 not-for-merge branch 'testcommit4261' of github.com:jantman/gitpython_issue_301 -b95d4c28a71b54917f6742ff6ff6607765035687 not-for-merge branch 'testcommit4262' of github.com:jantman/gitpython_issue_301 -5faf1e02d778d626d96eddbd55ddd7143a3a9487 not-for-merge branch 'testcommit4263' of github.com:jantman/gitpython_issue_301 -787f40e92001fdd3c10da1dffdab1fc90b34d3cd not-for-merge branch 'testcommit4264' of github.com:jantman/gitpython_issue_301 -6366e0de36ca1246bfeb10fed5add7988cd252e8 not-for-merge branch 'testcommit4265' of github.com:jantman/gitpython_issue_301 -488e8fc2920368456314b0d3c23693a7ab0ef593 not-for-merge branch 'testcommit4266' of github.com:jantman/gitpython_issue_301 -7d1546852a98d66ad956a7b0ae20a78fed70a7a9 not-for-merge branch 'testcommit4267' of github.com:jantman/gitpython_issue_301 -915bb5133921b81c0d4d0f9b568aeb1c28667e15 not-for-merge branch 'testcommit4268' of github.com:jantman/gitpython_issue_301 -83d4cc2f1847da2e7d1f1916cb38e933a12e0c7a not-for-merge branch 'testcommit4269' of github.com:jantman/gitpython_issue_301 -d3afc29d37eec727e05f030418d759f5df728f41 not-for-merge branch 'testcommit427' of github.com:jantman/gitpython_issue_301 -5ebcf6641150cdd72e1d716df40a567bd5d609d2 not-for-merge branch 'testcommit4270' of github.com:jantman/gitpython_issue_301 -7cf692bc8d08e33f4eb87dcc00101f7fee58b650 not-for-merge branch 'testcommit4271' of github.com:jantman/gitpython_issue_301 -f4644fa779aa4feaf7cd17416ee5742d5d4c95d3 not-for-merge branch 'testcommit4272' of github.com:jantman/gitpython_issue_301 -244a48ac5246dbc7f64ac5b8c5705cd5d4727969 not-for-merge branch 'testcommit4273' of github.com:jantman/gitpython_issue_301 -f873f13a19f53d05c0b9a7996a71f52801a731d5 not-for-merge branch 'testcommit4274' of github.com:jantman/gitpython_issue_301 -638a7bb29eace7ea589d1a1b81fde76b60807119 not-for-merge branch 'testcommit4275' of github.com:jantman/gitpython_issue_301 -6bd419b8d460f9bda284e8a55a6ec419113153f1 not-for-merge branch 'testcommit4276' of github.com:jantman/gitpython_issue_301 -4d0a66a4fb0bfc79f86e4cc946a6202f12475cae not-for-merge branch 'testcommit4277' of github.com:jantman/gitpython_issue_301 -8a9b5c6fe777832dec3bd0299b39fe3174c38f75 not-for-merge branch 'testcommit4278' of github.com:jantman/gitpython_issue_301 -dfb9732e0c317c63e6b2fb2172f1bb731060c0ac not-for-merge branch 'testcommit4279' of github.com:jantman/gitpython_issue_301 -45153ac1921c2cc6384c28f66e08ceae0b082825 not-for-merge branch 'testcommit428' of github.com:jantman/gitpython_issue_301 -39a79dd43adb1af47d3ef6594be92f8cdc950f9a not-for-merge branch 'testcommit4280' of github.com:jantman/gitpython_issue_301 -19888fdaac686fb3533830bfc107b8a7863dda7f not-for-merge branch 'testcommit4281' of github.com:jantman/gitpython_issue_301 -3ed3f6be8b6d5558c57e04d12d694b498217aa4d not-for-merge branch 'testcommit4282' of github.com:jantman/gitpython_issue_301 -e4fac5fb397c001944725271a2e185c61e6b5698 not-for-merge branch 'testcommit4283' of github.com:jantman/gitpython_issue_301 -46557475efe2c0047ed1ae346632fc0a3304e3b4 not-for-merge branch 'testcommit4284' of github.com:jantman/gitpython_issue_301 -6f937b095019e8ccabc6e570fea3e512f6ccd0d4 not-for-merge branch 'testcommit4285' of github.com:jantman/gitpython_issue_301 -4b8c62325362460b94756e77eb0260a397a8b940 not-for-merge branch 'testcommit4286' of github.com:jantman/gitpython_issue_301 -fd4a54de5a0c28ce7193a4f611f6a82edae91da6 not-for-merge branch 'testcommit4287' of github.com:jantman/gitpython_issue_301 -5a97284694047ebb82153a61474330a6ed24bdb9 not-for-merge branch 'testcommit4288' of github.com:jantman/gitpython_issue_301 -2b1953ed026320b3e309c844ddd8ed34589d5cbc not-for-merge branch 'testcommit4289' of github.com:jantman/gitpython_issue_301 -d43166c7fe98ebc6e5a06b2dd0798cfb80ff1320 not-for-merge branch 'testcommit429' of github.com:jantman/gitpython_issue_301 -d396b3864db4ac28bbe5db225ec7d1fc4aed78e2 not-for-merge branch 'testcommit4290' of github.com:jantman/gitpython_issue_301 -af1ae6ba8e34b928b8d1d19fb459be5fb8832c44 not-for-merge branch 'testcommit4291' of github.com:jantman/gitpython_issue_301 -9571e2313caa879a37f597ea06955047d733d27d not-for-merge branch 'testcommit4292' of github.com:jantman/gitpython_issue_301 -0007688ec91d82aeab50c7b0b1623bdba762b45f not-for-merge branch 'testcommit4293' of github.com:jantman/gitpython_issue_301 -5d4b155f1fc2ba79b863603c77774b9d61d86b7a not-for-merge branch 'testcommit4294' of github.com:jantman/gitpython_issue_301 -23e4df6d94e2fce57301ca9fc2f6f464ac931a90 not-for-merge branch 'testcommit4295' of github.com:jantman/gitpython_issue_301 -af1e06f054364dede59d1ddda943d4648b9d3f84 not-for-merge branch 'testcommit4296' of github.com:jantman/gitpython_issue_301 -5d44f064ddd8959f582d7169a20f4f55dbbb98ec not-for-merge branch 'testcommit4297' of github.com:jantman/gitpython_issue_301 -5bb5a0c61af6ab4d571b6cab8ea48825d420c802 not-for-merge branch 'testcommit4298' of github.com:jantman/gitpython_issue_301 -f91ee50b35eacb5c084d3458e7b513bff418b74f not-for-merge branch 'testcommit4299' of github.com:jantman/gitpython_issue_301 -aee496009399b41fcf7e1c06e23e7428d72bf8b1 not-for-merge branch 'testcommit43' of github.com:jantman/gitpython_issue_301 -fbb14a0dfe679388d88b53ff11bc6a5195ffc7ff not-for-merge branch 'testcommit430' of github.com:jantman/gitpython_issue_301 -5574f8d6aae042f65aa89b44b5aae443e3b13d7e not-for-merge branch 'testcommit4300' of github.com:jantman/gitpython_issue_301 -311e193e27e89ed7e48f6d2a896866d400e89aa9 not-for-merge branch 'testcommit4301' of github.com:jantman/gitpython_issue_301 -4d100a242fc1dc369ef37eaba0a79a6e988acbc2 not-for-merge branch 'testcommit4302' of github.com:jantman/gitpython_issue_301 -d9c74c740d4dea1c3662fb11b2004007d1e155c5 not-for-merge branch 'testcommit4303' of github.com:jantman/gitpython_issue_301 -d442b2fa124546577e1e4e362cd62005162b83c1 not-for-merge branch 'testcommit4304' of github.com:jantman/gitpython_issue_301 -42efd0e74d02ff60bcc3d5ac80bb441690838948 not-for-merge branch 'testcommit4305' of github.com:jantman/gitpython_issue_301 -2cf16b9a8df342729c360db70ad668cee3d2b2e8 not-for-merge branch 'testcommit4306' of github.com:jantman/gitpython_issue_301 -7aa561fcfcad82962abfda5f7f32d8aff3e49958 not-for-merge branch 'testcommit4307' of github.com:jantman/gitpython_issue_301 -5bbfd4b2da074cd1c28ed8c55630a234ba05ccb6 not-for-merge branch 'testcommit4308' of github.com:jantman/gitpython_issue_301 -00b9cde7e621882412a6ed4deb783ee1719768e8 not-for-merge branch 'testcommit4309' of github.com:jantman/gitpython_issue_301 -6a51a03c3c6113f90d727070ef5c9cce2c90221f not-for-merge branch 'testcommit431' of github.com:jantman/gitpython_issue_301 -084c13331da4dcdba5a20adf7d7d51cc7abd675f not-for-merge branch 'testcommit4310' of github.com:jantman/gitpython_issue_301 -1285f1eef383907b7e8729aab82a1b30c3577ec2 not-for-merge branch 'testcommit4311' of github.com:jantman/gitpython_issue_301 -c1b639f92fbecf6eaacc25fb2c544c50caacc016 not-for-merge branch 'testcommit4312' of github.com:jantman/gitpython_issue_301 -3cd2333b30030eb7e674bd2c88d51c8c419b7f99 not-for-merge branch 'testcommit4313' of github.com:jantman/gitpython_issue_301 -8c40b8b280486bcc8e8b6a761806ac6c1a85bcab not-for-merge branch 'testcommit4314' of github.com:jantman/gitpython_issue_301 -94b640968873e6c6433b271f0c8f276bafae93ff not-for-merge branch 'testcommit4315' of github.com:jantman/gitpython_issue_301 -e21f029326a80242371eec95163e9ad7389f0a14 not-for-merge branch 'testcommit4316' of github.com:jantman/gitpython_issue_301 -5267fcf9ca98941bce280f43e3890f566cc53ae2 not-for-merge branch 'testcommit4317' of github.com:jantman/gitpython_issue_301 -1033147e853e29e467915bdaa91630aa2807ddc1 not-for-merge branch 'testcommit4318' of github.com:jantman/gitpython_issue_301 -4c232fb47a84fa77547014d5d7c6439ad2e5d537 not-for-merge branch 'testcommit4319' of github.com:jantman/gitpython_issue_301 -716fcdd31ff64ee6a0d3080f019beca4ba02a559 not-for-merge branch 'testcommit432' of github.com:jantman/gitpython_issue_301 -340ff849d6f7ad8d0d17018d6410c2ea6c8c8c44 not-for-merge branch 'testcommit4320' of github.com:jantman/gitpython_issue_301 -a96eba39fed5157187b4365243dff532335141a8 not-for-merge branch 'testcommit4321' of github.com:jantman/gitpython_issue_301 -f32af58119d33b096b22e6dbf4c4f392b5843021 not-for-merge branch 'testcommit4322' of github.com:jantman/gitpython_issue_301 -6ba460bc97271a490a39714f1d23a1f3a55cb2d1 not-for-merge branch 'testcommit4323' of github.com:jantman/gitpython_issue_301 -8e8b113f286c699c5e4f75c7272c5fea3669edef not-for-merge branch 'testcommit4324' of github.com:jantman/gitpython_issue_301 -80ef449a1fd98337750b51b618309cf0a128af22 not-for-merge branch 'testcommit4325' of github.com:jantman/gitpython_issue_301 -1d7d9393fd083b671c6afdd09554404f08da4fc0 not-for-merge branch 'testcommit4326' of github.com:jantman/gitpython_issue_301 -2cefa36b723cd374f14a7968c7bd7519f6f685e5 not-for-merge branch 'testcommit4327' of github.com:jantman/gitpython_issue_301 -a845546422b5e07d6411eed48764f9986797fa25 not-for-merge branch 'testcommit4328' of github.com:jantman/gitpython_issue_301 -5d646f97b92d675b8db5942204cba5f999d9130e not-for-merge branch 'testcommit4329' of github.com:jantman/gitpython_issue_301 -7acce46981c83905be9a4e02072b94a5f9965ffe not-for-merge branch 'testcommit433' of github.com:jantman/gitpython_issue_301 -5a69a0ab676c43814aca644c426cb8c97e08c039 not-for-merge branch 'testcommit4330' of github.com:jantman/gitpython_issue_301 -140a6cc8091088e45b6bc0ff07410694f8109068 not-for-merge branch 'testcommit4331' of github.com:jantman/gitpython_issue_301 -c23497f125871beeb4364b8d3a952c8446f5c9de not-for-merge branch 'testcommit4332' of github.com:jantman/gitpython_issue_301 -196e3140aa43c403e2e424bcd3787629618b2e39 not-for-merge branch 'testcommit4333' of github.com:jantman/gitpython_issue_301 -9d20fcdcd129ead7536fc5adebc3828476f86869 not-for-merge branch 'testcommit4334' of github.com:jantman/gitpython_issue_301 -80fe85f82cf7481307df110469856ec6a533231a not-for-merge branch 'testcommit4335' of github.com:jantman/gitpython_issue_301 -4a8e5cca86282ec160126703f4b0045b55214b0c not-for-merge branch 'testcommit4336' of github.com:jantman/gitpython_issue_301 -9575599c2d6da5466019d21e908be8ec55cc624d not-for-merge branch 'testcommit4337' of github.com:jantman/gitpython_issue_301 -b34746e71459701dff9574d9072a57bf2b46ca04 not-for-merge branch 'testcommit4338' of github.com:jantman/gitpython_issue_301 -9e2faf3d687bf3ec22df0c04665665f6edda3f4b not-for-merge branch 'testcommit4339' of github.com:jantman/gitpython_issue_301 -c4a9e6979f47f6d268f3f505ea5c914e2a84d10f not-for-merge branch 'testcommit434' of github.com:jantman/gitpython_issue_301 -7be80ed5327fedd97b4a4fb51f970ae269ef6ebb not-for-merge branch 'testcommit4340' of github.com:jantman/gitpython_issue_301 -9ee7ecea5f4c3107efdced8d341f7ce11e959c34 not-for-merge branch 'testcommit4341' of github.com:jantman/gitpython_issue_301 -3b6e0f8cd15f86a511fc8c4111e97510612eb646 not-for-merge branch 'testcommit4342' of github.com:jantman/gitpython_issue_301 -86688a4cb5cadb5de0c3f53572818220c474a1c9 not-for-merge branch 'testcommit4343' of github.com:jantman/gitpython_issue_301 -fe85fe4ab93d870a17010d6f7d9371cf5ec4c70c not-for-merge branch 'testcommit4344' of github.com:jantman/gitpython_issue_301 -14ffd6b22cf32d80a03f4b1ea648d7546d6ad9c4 not-for-merge branch 'testcommit4345' of github.com:jantman/gitpython_issue_301 -4ddc76d18c0a6de9028661955b3039b6b2f5a7ec not-for-merge branch 'testcommit4346' of github.com:jantman/gitpython_issue_301 -c27586b8fb98dba6859c50424b2a8c0a7223afaa not-for-merge branch 'testcommit4347' of github.com:jantman/gitpython_issue_301 -2a764cc8b1e0040b312d139af119d0594c7c54a9 not-for-merge branch 'testcommit4348' of github.com:jantman/gitpython_issue_301 -ff0cf325cc1215288ed97526c0bfb0fd68ade2f5 not-for-merge branch 'testcommit4349' of github.com:jantman/gitpython_issue_301 -ac4c812ffe9996619c618f8a15d324a363bd08f3 not-for-merge branch 'testcommit435' of github.com:jantman/gitpython_issue_301 -aaaad074a77b9843bac1d26997a304e01755a5cc not-for-merge branch 'testcommit4350' of github.com:jantman/gitpython_issue_301 -3c0e8571390b792f1c413230682b658387e3a17c not-for-merge branch 'testcommit4351' of github.com:jantman/gitpython_issue_301 -1427509de62262be2cbf9546751fdb43d5de79d6 not-for-merge branch 'testcommit4352' of github.com:jantman/gitpython_issue_301 -81d04229225937033ca6453746ce93d7ca5e3ce8 not-for-merge branch 'testcommit4353' of github.com:jantman/gitpython_issue_301 -0275ef86bf06e5238a4bbc17999cc6bb45e0038c not-for-merge branch 'testcommit4354' of github.com:jantman/gitpython_issue_301 -0986f3e6ace68680900ff3148df98ed79dcaebb6 not-for-merge branch 'testcommit4355' of github.com:jantman/gitpython_issue_301 -2a0b383b56ef331fb6970dceafc09e2d0780371c not-for-merge branch 'testcommit4356' of github.com:jantman/gitpython_issue_301 -1d7cb408b21e24969af8b5481ccbdb13a012d9a8 not-for-merge branch 'testcommit4357' of github.com:jantman/gitpython_issue_301 -91db31e6ac4fb113770476646f055e0d8b22aade not-for-merge branch 'testcommit4358' of github.com:jantman/gitpython_issue_301 -3995fd3cad983a3ef009c52b314025a782eb81c2 not-for-merge branch 'testcommit4359' of github.com:jantman/gitpython_issue_301 -ba14a452724d50421bd8583a492f6d90dc1e5a19 not-for-merge branch 'testcommit436' of github.com:jantman/gitpython_issue_301 -ac6c18660e37d361166e2d280a3151cf94d45fa3 not-for-merge branch 'testcommit4360' of github.com:jantman/gitpython_issue_301 -b9caf03fb75f35934204dcc0882a0e2b049a782e not-for-merge branch 'testcommit4361' of github.com:jantman/gitpython_issue_301 -0d107d024ca1373dc9f79af78580a4bd7945493b not-for-merge branch 'testcommit4362' of github.com:jantman/gitpython_issue_301 -ca24929e0cc31c95bb56f53caebdff1f2ed1e006 not-for-merge branch 'testcommit4363' of github.com:jantman/gitpython_issue_301 -7c9db9f4ff79d5df0b7a23da5876333e6d89818e not-for-merge branch 'testcommit4364' of github.com:jantman/gitpython_issue_301 -1eb94c645731c79c1ae4a4860035499214ede558 not-for-merge branch 'testcommit4365' of github.com:jantman/gitpython_issue_301 -2a5941a4d01730d4b7c9dc4aff3341b9e0be9d75 not-for-merge branch 'testcommit4366' of github.com:jantman/gitpython_issue_301 -12b07f1e22b39615516df67706385dbcc892a81f not-for-merge branch 'testcommit4367' of github.com:jantman/gitpython_issue_301 -6fe46856866fee5d1635800a8c2fc6d7f77da3ee not-for-merge branch 'testcommit4368' of github.com:jantman/gitpython_issue_301 -a37d2576244e0373bfc079feb8250f6f48022889 not-for-merge branch 'testcommit4369' of github.com:jantman/gitpython_issue_301 -f08eb2fe67d845661c162a1314b1e971dc958aea not-for-merge branch 'testcommit437' of github.com:jantman/gitpython_issue_301 -013fccb95a5292e5187d71ec7f3955e066c61380 not-for-merge branch 'testcommit4370' of github.com:jantman/gitpython_issue_301 -26589907f89b42ea589d4c235b623f49129bcbe2 not-for-merge branch 'testcommit4371' of github.com:jantman/gitpython_issue_301 -3a260bcaca46f71af634e74f56d01675a5d1c234 not-for-merge branch 'testcommit4372' of github.com:jantman/gitpython_issue_301 -6631205619df6c4945f4ef6fee309bc4f08d6dd0 not-for-merge branch 'testcommit4373' of github.com:jantman/gitpython_issue_301 -30cce39b0fc954e160b4cf1786a3a0ffa1b4617a not-for-merge branch 'testcommit4374' of github.com:jantman/gitpython_issue_301 -3c9b98640cfb0fe2559ae1da633f24d1f9a3752a not-for-merge branch 'testcommit4375' of github.com:jantman/gitpython_issue_301 -109259958a79146928d24246b85f82584977591a not-for-merge branch 'testcommit4376' of github.com:jantman/gitpython_issue_301 -edc6ece880a4a6ba5371e86e654a90bd70e9814b not-for-merge branch 'testcommit4377' of github.com:jantman/gitpython_issue_301 -896b9318cce73a5d4b9ea224a5f07789ff0e2be1 not-for-merge branch 'testcommit4378' of github.com:jantman/gitpython_issue_301 -80ae702e5bbe02eb6f6c7d145ae45280e3805905 not-for-merge branch 'testcommit4379' of github.com:jantman/gitpython_issue_301 -c6fcb9d00eb6eca0ad31407ffcf7894cd2c66908 not-for-merge branch 'testcommit438' of github.com:jantman/gitpython_issue_301 -2a8434dd5638b40d6aa9afeb5e8050be71b5f2a9 not-for-merge branch 'testcommit4380' of github.com:jantman/gitpython_issue_301 -33cdc26326e82563fcccc0635bd32c0a9060ac29 not-for-merge branch 'testcommit4381' of github.com:jantman/gitpython_issue_301 -6462df3856f4381080d97952bdc304ba4afc6573 not-for-merge branch 'testcommit4382' of github.com:jantman/gitpython_issue_301 -1f35196cf44caa4defebd1ac22c1e11253937253 not-for-merge branch 'testcommit4383' of github.com:jantman/gitpython_issue_301 -3dd85de6ac0840858fa1938a682c48fe2d79e93a not-for-merge branch 'testcommit4384' of github.com:jantman/gitpython_issue_301 -78f3ffdf5843761f0b9d91327659458e5ade1992 not-for-merge branch 'testcommit4385' of github.com:jantman/gitpython_issue_301 -255aab25276304702809cae1805991b3448b43a7 not-for-merge branch 'testcommit4386' of github.com:jantman/gitpython_issue_301 -d3133c9a226cca1193dcf58a0b560abcae22b12f not-for-merge branch 'testcommit4387' of github.com:jantman/gitpython_issue_301 -3e1829471df059580c6bb730abd76bdc8e7a66a9 not-for-merge branch 'testcommit4388' of github.com:jantman/gitpython_issue_301 -8914187181985887f6af95a07c74e9282ffdfa38 not-for-merge branch 'testcommit4389' of github.com:jantman/gitpython_issue_301 -f1a2cdaa81973020bad670e9e074d99f88dae293 not-for-merge branch 'testcommit439' of github.com:jantman/gitpython_issue_301 -c464e22cd642e69f63335cf17b9e4cbb6f379db6 not-for-merge branch 'testcommit4390' of github.com:jantman/gitpython_issue_301 -ec5898ad0e01985584914442c3869515ac612ad4 not-for-merge branch 'testcommit4391' of github.com:jantman/gitpython_issue_301 -16181dde49d85141b925a2a2c1e96b70dcea7833 not-for-merge branch 'testcommit4392' of github.com:jantman/gitpython_issue_301 -ca873166546896a14cb250d3815792e54921ec36 not-for-merge branch 'testcommit4393' of github.com:jantman/gitpython_issue_301 -b81fdbf0fbb0d00fc56f910424fc715f610933ce not-for-merge branch 'testcommit4394' of github.com:jantman/gitpython_issue_301 -96c0f27ebaf556208d47d8d059313625ea63175e not-for-merge branch 'testcommit4395' of github.com:jantman/gitpython_issue_301 -ee829021546fd484df753fed86f4adc309fb5293 not-for-merge branch 'testcommit4396' of github.com:jantman/gitpython_issue_301 -02c6f35c3fac8174cb77c70f4989f26e4ce360bb not-for-merge branch 'testcommit4397' of github.com:jantman/gitpython_issue_301 -5ca4479b3504ed523ae86766c355bdcbd1e73fa5 not-for-merge branch 'testcommit4398' of github.com:jantman/gitpython_issue_301 -8e7c8f8b3df7b7ea6c0ec44003c4a2ed6e4085d9 not-for-merge branch 'testcommit4399' of github.com:jantman/gitpython_issue_301 -61e37ba82dace3e06fd6955d565320d7b7f0bffd not-for-merge branch 'testcommit44' of github.com:jantman/gitpython_issue_301 -ac0846b3621936b2deb501254b84d58a77bd4bed not-for-merge branch 'testcommit440' of github.com:jantman/gitpython_issue_301 -64f401c38437344366ce90d633463930cff59c0a not-for-merge branch 'testcommit4400' of github.com:jantman/gitpython_issue_301 -dcc71a253d0c93467835cb9a5675924f19eb6ca7 not-for-merge branch 'testcommit4401' of github.com:jantman/gitpython_issue_301 -afe23e0a87bb85c1e577b8ad0df21ec74ba7f7e6 not-for-merge branch 'testcommit4402' of github.com:jantman/gitpython_issue_301 -a47754516d6b3ebfeb5d5b6b330db5dad7e71eec not-for-merge branch 'testcommit4403' of github.com:jantman/gitpython_issue_301 -770231eaffe884522f76ceddb517bcfa3b93223a not-for-merge branch 'testcommit4404' of github.com:jantman/gitpython_issue_301 -cfe72d6068a5b2157fdfc329756690605145cdae not-for-merge branch 'testcommit4405' of github.com:jantman/gitpython_issue_301 -332825d341c1989de09b5d1648cadd4ae076df08 not-for-merge branch 'testcommit4406' of github.com:jantman/gitpython_issue_301 -1d6f81356dba07b88f7a825590c1bc38cb51993f not-for-merge branch 'testcommit4407' of github.com:jantman/gitpython_issue_301 -3c225b6b84959095a167236d1f42705407b310fb not-for-merge branch 'testcommit4408' of github.com:jantman/gitpython_issue_301 -484243986b1a36da9b34fe66b1a70fd7b3b26f3c not-for-merge branch 'testcommit4409' of github.com:jantman/gitpython_issue_301 -a6360ff76a0e638213eb7e57f94468f671f3578e not-for-merge branch 'testcommit441' of github.com:jantman/gitpython_issue_301 -24be8c59047cee11835b3b0372ba1fd2c2669415 not-for-merge branch 'testcommit4410' of github.com:jantman/gitpython_issue_301 -ed8a54e70e5934d7f06dbaa0a9ada6e77b349459 not-for-merge branch 'testcommit4411' of github.com:jantman/gitpython_issue_301 -1668f330c9128acfff41b0271d79fe1b5f847b3b not-for-merge branch 'testcommit4412' of github.com:jantman/gitpython_issue_301 -08a2f3271b022c4af7bdacdd42440cf3e0c29cac not-for-merge branch 'testcommit4413' of github.com:jantman/gitpython_issue_301 -68687eb014b224870e49d3deab980d8607724bdd not-for-merge branch 'testcommit4414' of github.com:jantman/gitpython_issue_301 -a39ef3389c23b40fed33bd4872019d52cccb1d59 not-for-merge branch 'testcommit4415' of github.com:jantman/gitpython_issue_301 -09e631ddaa77f5f9cf91764fd8b8f3d640d1729b not-for-merge branch 'testcommit4416' of github.com:jantman/gitpython_issue_301 -ce62f947315d2f3174e12f1aed1e25d35cb7919b not-for-merge branch 'testcommit4417' of github.com:jantman/gitpython_issue_301 -9341886a65ceee4c4f88f4c0c6e252081b846c30 not-for-merge branch 'testcommit4418' of github.com:jantman/gitpython_issue_301 -5539763dd7e43d0724ebb5890297c9e7c322567c not-for-merge branch 'testcommit4419' of github.com:jantman/gitpython_issue_301 -7561910a85173068b87b0a43ceba0fdf02eb90bc not-for-merge branch 'testcommit442' of github.com:jantman/gitpython_issue_301 -1f9559092cf0b892eb222fb8c36561c75beefac0 not-for-merge branch 'testcommit4420' of github.com:jantman/gitpython_issue_301 -893ae6d4d2da5dd871ff876c7149b2bddd315c80 not-for-merge branch 'testcommit4421' of github.com:jantman/gitpython_issue_301 -2153a31962cd246e2f463d29426dbb3301357fbd not-for-merge branch 'testcommit4422' of github.com:jantman/gitpython_issue_301 -e7f3f423b9a50b96e6b88b738907db880dcb27b1 not-for-merge branch 'testcommit4423' of github.com:jantman/gitpython_issue_301 -871b22c4b71aa3fc2a5448eec97fb976e908f88d not-for-merge branch 'testcommit4424' of github.com:jantman/gitpython_issue_301 -9b210ea69c932e67fdb6212e3f7528398741cd49 not-for-merge branch 'testcommit4425' of github.com:jantman/gitpython_issue_301 -4b495f5ee1ca9968bc74da9d08e1a22de89c68dc not-for-merge branch 'testcommit4426' of github.com:jantman/gitpython_issue_301 -530bc6695a545b3e9355b947cbc0e48ab58c20b5 not-for-merge branch 'testcommit4427' of github.com:jantman/gitpython_issue_301 -b2aa31baeb93a6e9e8f6de5e816a7e334e9f62f2 not-for-merge branch 'testcommit4428' of github.com:jantman/gitpython_issue_301 -e21a5ff906445a7ac2485d3dafa1deee2f6d2814 not-for-merge branch 'testcommit4429' of github.com:jantman/gitpython_issue_301 -e62ff9a21f8febc8e7c36623c37a9d82aa813dd5 not-for-merge branch 'testcommit443' of github.com:jantman/gitpython_issue_301 -c836b6bb65f3f45c14e826e646f643cc9d43b568 not-for-merge branch 'testcommit4430' of github.com:jantman/gitpython_issue_301 -458d237e6a358c9e95f17542053587cfdb66cead not-for-merge branch 'testcommit4431' of github.com:jantman/gitpython_issue_301 -d3e3fb4abbcf775e294e1e98b362d429fa29aa6a not-for-merge branch 'testcommit4432' of github.com:jantman/gitpython_issue_301 -75b1ffd55f5164875b399401f651903bc9d13aec not-for-merge branch 'testcommit4433' of github.com:jantman/gitpython_issue_301 -7fbd039c91fec3fcdf6abd414c483d1baf48454c not-for-merge branch 'testcommit4434' of github.com:jantman/gitpython_issue_301 -a46e7171fbf392718ffa3c1b2c746028e64e87c1 not-for-merge branch 'testcommit4435' of github.com:jantman/gitpython_issue_301 -9ec6b49b6fd2328416da8f029f6badb081ef5ab6 not-for-merge branch 'testcommit4436' of github.com:jantman/gitpython_issue_301 -1689e53776ef3ff7dc3edc08cc6f80bb9a88c2a9 not-for-merge branch 'testcommit4437' of github.com:jantman/gitpython_issue_301 -a8f1aeffb5eaab7ee1008dda703483c6dff1d596 not-for-merge branch 'testcommit4438' of github.com:jantman/gitpython_issue_301 -8ccfd9fd8f15f18f3400052ae3402a2a9c282390 not-for-merge branch 'testcommit4439' of github.com:jantman/gitpython_issue_301 -f0f4bc5484f18e5446c3002b04e1787f640f30fb not-for-merge branch 'testcommit444' of github.com:jantman/gitpython_issue_301 -f12ef9484a30d195e64aca50bfa1bbabae10d091 not-for-merge branch 'testcommit4440' of github.com:jantman/gitpython_issue_301 -d18082d8c786d0f236109da7aa43815a8400f1e6 not-for-merge branch 'testcommit4441' of github.com:jantman/gitpython_issue_301 -4ab1a01d9e2e0978e74bc2a00ee7ed8fe5631804 not-for-merge branch 'testcommit4442' of github.com:jantman/gitpython_issue_301 -98edc5f7a2ccccab98d76549ab08b801609a2c82 not-for-merge branch 'testcommit4443' of github.com:jantman/gitpython_issue_301 -1e045fe0aee479ebc1e5a103fad10d776d59e559 not-for-merge branch 'testcommit4444' of github.com:jantman/gitpython_issue_301 -ba6bc2f9dde70963dfb74c11e7565672e7626393 not-for-merge branch 'testcommit4445' of github.com:jantman/gitpython_issue_301 -98120678f20d151723cb8e3db4429a6028032271 not-for-merge branch 'testcommit4446' of github.com:jantman/gitpython_issue_301 -4a2a9fd1f76c2943d4f0c795d3db9d3ef1e38d89 not-for-merge branch 'testcommit4447' of github.com:jantman/gitpython_issue_301 -3416fff2b5b699b74ef23cf72626c29aae59047d not-for-merge branch 'testcommit4448' of github.com:jantman/gitpython_issue_301 -1b419908b30c8a82ea93f3ac53442d0f27b9efc1 not-for-merge branch 'testcommit4449' of github.com:jantman/gitpython_issue_301 -a34eb83be21492ee1ffc8153a690b645156165c9 not-for-merge branch 'testcommit445' of github.com:jantman/gitpython_issue_301 -73eef8ce8eb2af79070f74fb01e1cc15f7929882 not-for-merge branch 'testcommit4450' of github.com:jantman/gitpython_issue_301 -982c42dc1bb75a868026dda616b7163ac5e54e61 not-for-merge branch 'testcommit4451' of github.com:jantman/gitpython_issue_301 -b11684754a2bc5540dc0fe2496ec74b5bb07235f not-for-merge branch 'testcommit4452' of github.com:jantman/gitpython_issue_301 -b154db37a86c58cd0a355a025b9d9ddfac98426c not-for-merge branch 'testcommit4453' of github.com:jantman/gitpython_issue_301 -2c6be12d4b6e7d994da2dcfd4ea9597363915344 not-for-merge branch 'testcommit4454' of github.com:jantman/gitpython_issue_301 -e8e16d16c300517ddf4714f6e9d1e6a3b5124ab5 not-for-merge branch 'testcommit4455' of github.com:jantman/gitpython_issue_301 -fcb3f88fd07cbbc12e9820ae5012d38bb2898793 not-for-merge branch 'testcommit4456' of github.com:jantman/gitpython_issue_301 -61f31eed4accf13a5bc21858845430a0d417fc00 not-for-merge branch 'testcommit4457' of github.com:jantman/gitpython_issue_301 -462a613b283fe200696f0f284fbfbd8370b7a459 not-for-merge branch 'testcommit4458' of github.com:jantman/gitpython_issue_301 -03780087024c83f19feac587647f2566482fc2a2 not-for-merge branch 'testcommit4459' of github.com:jantman/gitpython_issue_301 -768215b32b7163c4343e34d9b6c978d63155a26c not-for-merge branch 'testcommit446' of github.com:jantman/gitpython_issue_301 -d0f4e69c91790ae29f0de53973696f6e7ed8db48 not-for-merge branch 'testcommit4460' of github.com:jantman/gitpython_issue_301 -bb0df0b91ea17ea42873863c058be67c75e8fcde not-for-merge branch 'testcommit4461' of github.com:jantman/gitpython_issue_301 -21e38139f7b2c06892fea46c8529cf45286f1599 not-for-merge branch 'testcommit4462' of github.com:jantman/gitpython_issue_301 -daff25936287589a073acf0f3de1b687a0932114 not-for-merge branch 'testcommit4463' of github.com:jantman/gitpython_issue_301 -6e6c405bf77b314ea583231b68f444fc2f534517 not-for-merge branch 'testcommit4464' of github.com:jantman/gitpython_issue_301 -85b8d05eeae916db8cd9582a1b032455fec03e35 not-for-merge branch 'testcommit4465' of github.com:jantman/gitpython_issue_301 -2f5eef0d36cc9ea3880f8a8236ef918d6f296c2f not-for-merge branch 'testcommit4466' of github.com:jantman/gitpython_issue_301 -9b8ae1970a6c317c41aaa78fda79ed23fd9cc203 not-for-merge branch 'testcommit4467' of github.com:jantman/gitpython_issue_301 -49995dc5340ef5781d9b75cb9097c3ee19795719 not-for-merge branch 'testcommit4468' of github.com:jantman/gitpython_issue_301 -57dbb470ee19b3bb3503895aa89232d10ae0cb68 not-for-merge branch 'testcommit4469' of github.com:jantman/gitpython_issue_301 -02fa51a6d230ea29d732f63d7b0e8e7080e3c30f not-for-merge branch 'testcommit447' of github.com:jantman/gitpython_issue_301 -4c86fe4cdb7e264e8d33795a25eb394f927226b5 not-for-merge branch 'testcommit4470' of github.com:jantman/gitpython_issue_301 -dc74b4bd2e6b31e2bbf437ec66de1df4d04213ca not-for-merge branch 'testcommit4471' of github.com:jantman/gitpython_issue_301 -1e2b75991f30fe1e1907911539ec4eb0a90aa1df not-for-merge branch 'testcommit4472' of github.com:jantman/gitpython_issue_301 -a143f8242e6ed914cfacd69f6e18220415441f4f not-for-merge branch 'testcommit4473' of github.com:jantman/gitpython_issue_301 -9f6f9911481c401e2c704c5f27c4d18599d3ca88 not-for-merge branch 'testcommit4474' of github.com:jantman/gitpython_issue_301 -0306951a22d3497d6f3b55b30f87aa00cc596ea1 not-for-merge branch 'testcommit4475' of github.com:jantman/gitpython_issue_301 -baec83a9320d29835ebb8259ddd84ef59db3192f not-for-merge branch 'testcommit4476' of github.com:jantman/gitpython_issue_301 -2c060e3144b4abd8605ce6937ea5032ee841766a not-for-merge branch 'testcommit4477' of github.com:jantman/gitpython_issue_301 -d0e70c49b21a171946c5df1174b6566cd0f77834 not-for-merge branch 'testcommit4478' of github.com:jantman/gitpython_issue_301 -d487020cd608c540f538195e9393b91d53315cc1 not-for-merge branch 'testcommit4479' of github.com:jantman/gitpython_issue_301 -6f77230d110cd29367df21c7064034b33006641c not-for-merge branch 'testcommit448' of github.com:jantman/gitpython_issue_301 -1503804d1e69a3473875f27c10bc7e6669489037 not-for-merge branch 'testcommit4480' of github.com:jantman/gitpython_issue_301 -71911d9630dc1848eb8844346d32a269e1fd5d5b not-for-merge branch 'testcommit4481' of github.com:jantman/gitpython_issue_301 -3bf448cf7c218b44895847fcaeaad6b4df33609a not-for-merge branch 'testcommit4482' of github.com:jantman/gitpython_issue_301 -2308f6ec739fe826175c1cc269159ac33cb5029f not-for-merge branch 'testcommit4483' of github.com:jantman/gitpython_issue_301 -28009d32dffa5ad9d9af19d89b303afa79d6bb80 not-for-merge branch 'testcommit4484' of github.com:jantman/gitpython_issue_301 -3f19b0036c8d41113cee002d79cd93c61ea5c969 not-for-merge branch 'testcommit4485' of github.com:jantman/gitpython_issue_301 -e7b450bfa04bcabff4f4ef22dba6534ac8a9d1c6 not-for-merge branch 'testcommit4486' of github.com:jantman/gitpython_issue_301 -03d5834085e5deaa4de5afceec0ef74b2faf6f39 not-for-merge branch 'testcommit4487' of github.com:jantman/gitpython_issue_301 -79e9f953062681b33f6f69fa8d1a3afa524b0a5a not-for-merge branch 'testcommit4488' of github.com:jantman/gitpython_issue_301 -3896f0c0d347f1ca1a937603e0eb0cc5c0e8a9ed not-for-merge branch 'testcommit4489' of github.com:jantman/gitpython_issue_301 -3222a4c8f8d9ab978999a7de5e0e09fdbf3f141a not-for-merge branch 'testcommit449' of github.com:jantman/gitpython_issue_301 -b0393cc09a70998eeeee181133cc0e4aca0f6a4d not-for-merge branch 'testcommit4490' of github.com:jantman/gitpython_issue_301 -0f5c74884edc556ee8e3f300b452907af7333cb3 not-for-merge branch 'testcommit4491' of github.com:jantman/gitpython_issue_301 -49c1040d3a42dde7c755a11778ff38559fa2ab2d not-for-merge branch 'testcommit4492' of github.com:jantman/gitpython_issue_301 -477f10dad8797c1ddc3c48976a81bdc4615a7d5e not-for-merge branch 'testcommit4493' of github.com:jantman/gitpython_issue_301 -36034c8b63628e9c6c2101eb91c0378a5685e452 not-for-merge branch 'testcommit4494' of github.com:jantman/gitpython_issue_301 -5ebd99d12cb446c9d61e64253f1f7c6b7a166350 not-for-merge branch 'testcommit4495' of github.com:jantman/gitpython_issue_301 -86a150364f84db72113605bfa0e9319c052c61a8 not-for-merge branch 'testcommit4496' of github.com:jantman/gitpython_issue_301 -86f6f708ca4c0d4dc1f1daeb43426ac93bbc1b74 not-for-merge branch 'testcommit4497' of github.com:jantman/gitpython_issue_301 -055ac45823ce0bbf19f5da24ae0be52b053c36c7 not-for-merge branch 'testcommit4498' of github.com:jantman/gitpython_issue_301 -3a89e01bd7fc18dc5aa2fcdd5409a10f5853de7c not-for-merge branch 'testcommit4499' of github.com:jantman/gitpython_issue_301 -73dd7c0be1b914fcc1fec86eab6d9d3661496b52 not-for-merge branch 'testcommit45' of github.com:jantman/gitpython_issue_301 -0dd2ed6e4f7042cb99969943f3fc63c8ffe355df not-for-merge branch 'testcommit450' of github.com:jantman/gitpython_issue_301 -79dc09f7654487182d87ce9fd74d3fc3cbe0a3b4 not-for-merge branch 'testcommit4500' of github.com:jantman/gitpython_issue_301 -ec508966ee5a8435db3211379d0eda604bedd838 not-for-merge branch 'testcommit4501' of github.com:jantman/gitpython_issue_301 -5efc0c275d7847bddf817d017fe06fad1972fc21 not-for-merge branch 'testcommit4502' of github.com:jantman/gitpython_issue_301 -a203d127007a8021d98af21750b7b37a479b608a not-for-merge branch 'testcommit4503' of github.com:jantman/gitpython_issue_301 -9edb480c70c0c526257b6a5861dda12cf73d92ae not-for-merge branch 'testcommit4504' of github.com:jantman/gitpython_issue_301 -c6ab6b8e9d51821243892c82fc5ae83676ce8a1e not-for-merge branch 'testcommit4505' of github.com:jantman/gitpython_issue_301 -ee148bebdc788f3727775f2098c020db768cb8df not-for-merge branch 'testcommit4506' of github.com:jantman/gitpython_issue_301 -3e2eef1ab2115e4702a0933922b55622fb9dc7f2 not-for-merge branch 'testcommit4507' of github.com:jantman/gitpython_issue_301 -4fc2bed22b256ed3c89f4f2ecdd446ed4eb3681a not-for-merge branch 'testcommit4508' of github.com:jantman/gitpython_issue_301 -85288ec637fdfac2eac0fa14dafdfeffcc555b57 not-for-merge branch 'testcommit4509' of github.com:jantman/gitpython_issue_301 -f15c44a3e0418d1744bc55a6792643260aadf3a7 not-for-merge branch 'testcommit451' of github.com:jantman/gitpython_issue_301 -8dcf1124e3300f7e97e980641854773925dc0219 not-for-merge branch 'testcommit4510' of github.com:jantman/gitpython_issue_301 -2f43512b0403bb6a0115c8908dbf512c71543a4e not-for-merge branch 'testcommit4511' of github.com:jantman/gitpython_issue_301 -fa2fecf87ce4be361218efc9671299ef7687ea1d not-for-merge branch 'testcommit4512' of github.com:jantman/gitpython_issue_301 -a750ad93641a4742a0df1d5597d1a72d32b71c05 not-for-merge branch 'testcommit4513' of github.com:jantman/gitpython_issue_301 -5b608b684095d75ab10f8051e849469b8ca8f282 not-for-merge branch 'testcommit4514' of github.com:jantman/gitpython_issue_301 -9a2be8e670f476f2d91209e313ba552de651750e not-for-merge branch 'testcommit4515' of github.com:jantman/gitpython_issue_301 -8773f0b671ec549ccf022b3a2b1075549915708b not-for-merge branch 'testcommit4516' of github.com:jantman/gitpython_issue_301 -e03a1827c81ae92f5e081f4b896b52ef8f2c9d38 not-for-merge branch 'testcommit4517' of github.com:jantman/gitpython_issue_301 -1d024712934b464114855de554872c021c56baf5 not-for-merge branch 'testcommit4518' of github.com:jantman/gitpython_issue_301 -6181e5c6057522f68341a29d726f6ac3258cf391 not-for-merge branch 'testcommit4519' of github.com:jantman/gitpython_issue_301 -947c9bcb935560939037df1493ee96ce894fae47 not-for-merge branch 'testcommit452' of github.com:jantman/gitpython_issue_301 -e7be7a00f9d1ffab4febc685d9ae60940c4fc4b5 not-for-merge branch 'testcommit4520' of github.com:jantman/gitpython_issue_301 -3125fbb7d5662be9120ab0653e3fd19fa55ab705 not-for-merge branch 'testcommit4521' of github.com:jantman/gitpython_issue_301 -c5f03834b74d182dac89e53e93e55f4925a2e56e not-for-merge branch 'testcommit4522' of github.com:jantman/gitpython_issue_301 -05bab73860d1f40b74686b51a12fafaf9ff9a7c3 not-for-merge branch 'testcommit4523' of github.com:jantman/gitpython_issue_301 -3c07d9481fc17b11d2eecb23140f392192410f30 not-for-merge branch 'testcommit4524' of github.com:jantman/gitpython_issue_301 -cf386756f6e6a912e1b270ab2eea2f65b817c193 not-for-merge branch 'testcommit4525' of github.com:jantman/gitpython_issue_301 -edb3c66fa31b2d52c1f7cc1548729ec0b2fb36f7 not-for-merge branch 'testcommit4526' of github.com:jantman/gitpython_issue_301 -015af3d1742d6b6f7ab9e118eb8241fbcd098a56 not-for-merge branch 'testcommit4527' of github.com:jantman/gitpython_issue_301 -33a895ef5706a4f4a139693170a9d06654ab6278 not-for-merge branch 'testcommit4528' of github.com:jantman/gitpython_issue_301 -46dbd3d1a9a47fea7b43991a2353d4b089074c19 not-for-merge branch 'testcommit4529' of github.com:jantman/gitpython_issue_301 -8e554f9ca9f25d44597cf9be595f781d52e22a51 not-for-merge branch 'testcommit453' of github.com:jantman/gitpython_issue_301 -9b57c5f9dc4b3a01b70f34838952eaff1d841ce1 not-for-merge branch 'testcommit4530' of github.com:jantman/gitpython_issue_301 -5e4179a3114e2556d9f2c83f764b388704129e6c not-for-merge branch 'testcommit4531' of github.com:jantman/gitpython_issue_301 -d1505343d306477cbcff2a20d4c2569124042ea0 not-for-merge branch 'testcommit4532' of github.com:jantman/gitpython_issue_301 -fd0246b85893780efaee1451f540073926c41779 not-for-merge branch 'testcommit4533' of github.com:jantman/gitpython_issue_301 -b3e38a6f777429304cfe0a4f53f48d5cf20b4525 not-for-merge branch 'testcommit4534' of github.com:jantman/gitpython_issue_301 -4eb3f9ea8d486a41ba4e2c59b71e927633ab5954 not-for-merge branch 'testcommit4535' of github.com:jantman/gitpython_issue_301 -2a61c1c5be59251c47a2d1c02390a43a64c32b97 not-for-merge branch 'testcommit4536' of github.com:jantman/gitpython_issue_301 -d7642896082db75c2b78e815a42ceb59634e11f8 not-for-merge branch 'testcommit4537' of github.com:jantman/gitpython_issue_301 -d2e22e5bc831880e9d56391b976836d838101873 not-for-merge branch 'testcommit4538' of github.com:jantman/gitpython_issue_301 -254b857833f15e0cce02904b99b06f16a2b3bffe not-for-merge branch 'testcommit4539' of github.com:jantman/gitpython_issue_301 -e1e0f6b7cfd6ca2891a0e524093a6e36ada4458d not-for-merge branch 'testcommit454' of github.com:jantman/gitpython_issue_301 -ed58d54ccd60b00f76fa01206f7c2c2db08fc2f9 not-for-merge branch 'testcommit4540' of github.com:jantman/gitpython_issue_301 -f2c7613bae807dcfa0faae73837a7ce1b2e7f74d not-for-merge branch 'testcommit4541' of github.com:jantman/gitpython_issue_301 -85e7b06216123d9efdab7b007e305a917991c461 not-for-merge branch 'testcommit4542' of github.com:jantman/gitpython_issue_301 -b2e6b7d1467beea3f0f02444c67a2861e4bcc250 not-for-merge branch 'testcommit4543' of github.com:jantman/gitpython_issue_301 -c5ceffb5a02c96a88a28e4b58725d073050fadc9 not-for-merge branch 'testcommit4544' of github.com:jantman/gitpython_issue_301 -585a914a77aa81c20ab850b9071b49ca24cc7c59 not-for-merge branch 'testcommit4545' of github.com:jantman/gitpython_issue_301 -0ab26a9d9b51f4cef10bf8affc0e91bb8a88d28d not-for-merge branch 'testcommit4546' of github.com:jantman/gitpython_issue_301 -9a91661d2e4c02765d21d0bae39fcb8029d92a8b not-for-merge branch 'testcommit4547' of github.com:jantman/gitpython_issue_301 -bbea72e6a0f174da8534fd5b0aa612307118d01d not-for-merge branch 'testcommit4548' of github.com:jantman/gitpython_issue_301 -7925ff5c67bdf510f871efc58eae3ad80d75d3d7 not-for-merge branch 'testcommit4549' of github.com:jantman/gitpython_issue_301 -e66324b144117c07de31ca252ec4f4902bd09c7f not-for-merge branch 'testcommit455' of github.com:jantman/gitpython_issue_301 -658c07808fa2edf10c8e93702d5a0588cf1d4767 not-for-merge branch 'testcommit4550' of github.com:jantman/gitpython_issue_301 -d9ca8a905849cdd61616d3ed373777c926185fb0 not-for-merge branch 'testcommit4551' of github.com:jantman/gitpython_issue_301 -bb25773f5062d5dd17419e0f02ea74f0c83e0479 not-for-merge branch 'testcommit4552' of github.com:jantman/gitpython_issue_301 -8f56cc1cc518f7026cbe34deb0228728d08b80a9 not-for-merge branch 'testcommit4553' of github.com:jantman/gitpython_issue_301 -c7806b2de98b595e59f4aeb9e429e07ed4ef4e61 not-for-merge branch 'testcommit4554' of github.com:jantman/gitpython_issue_301 -80a1a3a8805612523b98aba5d25678741f147f25 not-for-merge branch 'testcommit4555' of github.com:jantman/gitpython_issue_301 -28db2ce0f0fd6e9002cc1606ec90ec4b2c55c5f4 not-for-merge branch 'testcommit4556' of github.com:jantman/gitpython_issue_301 -2550a758a9fc6d8ca89d2b5918c390ed1fe95eb8 not-for-merge branch 'testcommit4557' of github.com:jantman/gitpython_issue_301 -826ec403a9e26eabca86eb5b3d90ebd74ecedaad not-for-merge branch 'testcommit4558' of github.com:jantman/gitpython_issue_301 -9ca9666f4039f2c909b78de70b4feac1904c2c2c not-for-merge branch 'testcommit4559' of github.com:jantman/gitpython_issue_301 -09fd9a92ac2b8b59b2f75717d6da22bcb7d67a40 not-for-merge branch 'testcommit456' of github.com:jantman/gitpython_issue_301 -8fe70d8e0395b8e1fac013d554a782991631c44e not-for-merge branch 'testcommit4560' of github.com:jantman/gitpython_issue_301 -97cb59feb11716ad8f9239c4c1db4f3c32f13ca1 not-for-merge branch 'testcommit4561' of github.com:jantman/gitpython_issue_301 -59e0e36d11460a3e25a0f085d273dc59f511df73 not-for-merge branch 'testcommit4562' of github.com:jantman/gitpython_issue_301 -bb3d5e5f5aaba9c05a390ba2d14e7e3dbdb62c89 not-for-merge branch 'testcommit4563' of github.com:jantman/gitpython_issue_301 -aad38e56c6329d6dcfacf22b5c6e0c266899987f not-for-merge branch 'testcommit4564' of github.com:jantman/gitpython_issue_301 -342120a1e9a3446dbe93dee6b46e6c5b115c526e not-for-merge branch 'testcommit4565' of github.com:jantman/gitpython_issue_301 -421eaf0c35080528c97abf311e35dbcaf1b165a9 not-for-merge branch 'testcommit4566' of github.com:jantman/gitpython_issue_301 -8c63ecca5ade238663651a51fc1c43306688b3ab not-for-merge branch 'testcommit4567' of github.com:jantman/gitpython_issue_301 -dc46349cc84b3ebd134352f4e3d085a1245d05eb not-for-merge branch 'testcommit4568' of github.com:jantman/gitpython_issue_301 -aa08a455b7a47d61cad950533824f064893f47be not-for-merge branch 'testcommit4569' of github.com:jantman/gitpython_issue_301 -07423e7709e140650c1a23026dc4b4f20fd8d078 not-for-merge branch 'testcommit457' of github.com:jantman/gitpython_issue_301 -2dc237eb34d2cb0e0f29b8da3d7297ccb48e423e not-for-merge branch 'testcommit4570' of github.com:jantman/gitpython_issue_301 -8288dc53e107c7dee222be3c734f3883d72d2321 not-for-merge branch 'testcommit4571' of github.com:jantman/gitpython_issue_301 -16ea2f5ef9949386c98a7815adf4b0c08455eccb not-for-merge branch 'testcommit4572' of github.com:jantman/gitpython_issue_301 -9c2fc0ccaafb7a1ac3f855b17aa4c9b81b35a0bf not-for-merge branch 'testcommit4573' of github.com:jantman/gitpython_issue_301 -6f18ee22e63de15763cb1cf2fc1b11e5581fbf73 not-for-merge branch 'testcommit4574' of github.com:jantman/gitpython_issue_301 -e8d9da2f024a9f18b4d261e1e762132c29743e01 not-for-merge branch 'testcommit4575' of github.com:jantman/gitpython_issue_301 -8ab57172f2b0cb97e83cd5555a5b5f934d6d580c not-for-merge branch 'testcommit4576' of github.com:jantman/gitpython_issue_301 -94399b3537a44845f708eb24dea1e37c9eee7422 not-for-merge branch 'testcommit4577' of github.com:jantman/gitpython_issue_301 -53c5edab5e0fe7678d08fa224b45c0d64f850235 not-for-merge branch 'testcommit4578' of github.com:jantman/gitpython_issue_301 -b47847671db4eb9544b0387ba5378a8eb45c7c86 not-for-merge branch 'testcommit4579' of github.com:jantman/gitpython_issue_301 -d6fb5d084f31733672154e0be548a252a9ff5cf3 not-for-merge branch 'testcommit458' of github.com:jantman/gitpython_issue_301 -64b84cafc9e1cbefe401c1c5c55ef5a01f5a2a09 not-for-merge branch 'testcommit4580' of github.com:jantman/gitpython_issue_301 -0f9939a4240781b0bf1a8aed9ddde11d372bb075 not-for-merge branch 'testcommit4581' of github.com:jantman/gitpython_issue_301 -482dbd80e6afcad9cec9489fd0cb2e7ad609befa not-for-merge branch 'testcommit4582' of github.com:jantman/gitpython_issue_301 -c09358a8d384d6bb46759acbb061f1f04fe8a68e not-for-merge branch 'testcommit4583' of github.com:jantman/gitpython_issue_301 -a5c8b8fdd504de510dc674e06f5babd81f2196b8 not-for-merge branch 'testcommit4584' of github.com:jantman/gitpython_issue_301 -c42825ca1895a6d3d63d9ed71c8a1f7d8831249e not-for-merge branch 'testcommit4585' of github.com:jantman/gitpython_issue_301 -c885aae0ac42ef4538434c4f698c0f04f534af81 not-for-merge branch 'testcommit4586' of github.com:jantman/gitpython_issue_301 -3db631415e34655ba7437418adccb67cc1cfa482 not-for-merge branch 'testcommit4587' of github.com:jantman/gitpython_issue_301 -9142491a2bb51be30d87d23ad53b9ff6e0633d01 not-for-merge branch 'testcommit4588' of github.com:jantman/gitpython_issue_301 -3d6b3516ab5fe4db7f20ba7133299c870bbbf790 not-for-merge branch 'testcommit4589' of github.com:jantman/gitpython_issue_301 -f14ff148b122843d1ec9ed81be35f4e734257fbd not-for-merge branch 'testcommit459' of github.com:jantman/gitpython_issue_301 -9b3c24a55f6b0afddd3cfe1d0b015b4eac8e242f not-for-merge branch 'testcommit4590' of github.com:jantman/gitpython_issue_301 -0090ead916e6006415c88ffe94ef6c79e8e8f992 not-for-merge branch 'testcommit4591' of github.com:jantman/gitpython_issue_301 -b3579a45da072243e35c8e493086aaf23a8f38c4 not-for-merge branch 'testcommit4592' of github.com:jantman/gitpython_issue_301 -322c404ef226424b0df71176b2d61d852c0906e7 not-for-merge branch 'testcommit4593' of github.com:jantman/gitpython_issue_301 -4488862722bd3ec9c617d7597413fc80704d423c not-for-merge branch 'testcommit4594' of github.com:jantman/gitpython_issue_301 -b1f13540579d513d418822949125421f7dd47021 not-for-merge branch 'testcommit4595' of github.com:jantman/gitpython_issue_301 -a0f0dfbcfa1f3ce3b8bc686c169acfe76a0d38f5 not-for-merge branch 'testcommit4596' of github.com:jantman/gitpython_issue_301 -c4067b52d28097684b6197f8ff71020b82d1a515 not-for-merge branch 'testcommit4597' of github.com:jantman/gitpython_issue_301 -66bef0adb706a07a534a49bb03cb3ff511443377 not-for-merge branch 'testcommit4598' of github.com:jantman/gitpython_issue_301 -e57d4a503cbc7897dc94bcf33c636d89b3f8d96b not-for-merge branch 'testcommit4599' of github.com:jantman/gitpython_issue_301 -4408a6549f07b6bc1d45c560da49ad17e9f57f91 not-for-merge branch 'testcommit46' of github.com:jantman/gitpython_issue_301 -782574411f2628bb41a2453901680843a9324e96 not-for-merge branch 'testcommit460' of github.com:jantman/gitpython_issue_301 -cd449510541e85c8cd7976d65cafb8fb253e0599 not-for-merge branch 'testcommit4600' of github.com:jantman/gitpython_issue_301 -8c7e1fb83c0ed6a23ed0b64e5d0185a80f799426 not-for-merge branch 'testcommit4601' of github.com:jantman/gitpython_issue_301 -5b0821036d347e9db57a4655ce4b80834f1d81ce not-for-merge branch 'testcommit4602' of github.com:jantman/gitpython_issue_301 -ac586d1aef846495bf99b34b88acefab2928fad2 not-for-merge branch 'testcommit4603' of github.com:jantman/gitpython_issue_301 -d899eb9e15dfede86fe3d3d4f5fffc6a98ce7273 not-for-merge branch 'testcommit4604' of github.com:jantman/gitpython_issue_301 -77efa7284a52f3c09a3bec279deff8e8dc712699 not-for-merge branch 'testcommit4605' of github.com:jantman/gitpython_issue_301 -95e9948127295f773864614a6f1869f63e10ffa6 not-for-merge branch 'testcommit4606' of github.com:jantman/gitpython_issue_301 -30923c7e41efe7b8342276ef591509d30c5d33a8 not-for-merge branch 'testcommit4607' of github.com:jantman/gitpython_issue_301 -8644d4c0f68ccd48c0e24ca5a4cf1de16ee6047e not-for-merge branch 'testcommit4608' of github.com:jantman/gitpython_issue_301 -349d2f5dd306cbfa2744d27ae579c5baee7dfda7 not-for-merge branch 'testcommit4609' of github.com:jantman/gitpython_issue_301 -faa26ba9c589d8c57a4900091e54a76efec88537 not-for-merge branch 'testcommit461' of github.com:jantman/gitpython_issue_301 -ec9d76a1f90761bcb43703f1fb6fc0e89c292f03 not-for-merge branch 'testcommit4610' of github.com:jantman/gitpython_issue_301 -c810d1f864579409f206ecd90b84c5c313b2d8aa not-for-merge branch 'testcommit4611' of github.com:jantman/gitpython_issue_301 -d050d02597816b16f4bd3ea51d783f8e253bb2d6 not-for-merge branch 'testcommit4612' of github.com:jantman/gitpython_issue_301 -ee147213b836f1a394c0dcd10231473604770b18 not-for-merge branch 'testcommit4613' of github.com:jantman/gitpython_issue_301 -d2d6443ec55a9c7331f6315671dec8c1d1038a4e not-for-merge branch 'testcommit4614' of github.com:jantman/gitpython_issue_301 -6bc6cd0f52e719a9915ba15dde58e40fc100c261 not-for-merge branch 'testcommit4615' of github.com:jantman/gitpython_issue_301 -c8299c09c063734f127925ab5ea37e92a68824cc not-for-merge branch 'testcommit4616' of github.com:jantman/gitpython_issue_301 -fb650bdfb2324c5d8c33a782e26be5bf3f709f7d not-for-merge branch 'testcommit4617' of github.com:jantman/gitpython_issue_301 -9e0f2197f6cd9f8392167b4fff072f76d445df89 not-for-merge branch 'testcommit4618' of github.com:jantman/gitpython_issue_301 -5e15710d098fee81c9a658bab19c7ccc4f2c4d5e not-for-merge branch 'testcommit4619' of github.com:jantman/gitpython_issue_301 -c722679c7049071d42f504e5e4de3c27565fddc5 not-for-merge branch 'testcommit462' of github.com:jantman/gitpython_issue_301 -0b06eeba1f2a5b8643e341f957d9bc57034049be not-for-merge branch 'testcommit4620' of github.com:jantman/gitpython_issue_301 -4770c53b3d2b686720f1dd589b35a9b496a53d91 not-for-merge branch 'testcommit4621' of github.com:jantman/gitpython_issue_301 -bd1d514c0c62c63ada3e6dd65435042999c7ef06 not-for-merge branch 'testcommit4622' of github.com:jantman/gitpython_issue_301 -32b3b15e0265ec7233f4714f414158d9ea18e34f not-for-merge branch 'testcommit4623' of github.com:jantman/gitpython_issue_301 -2bef3f5bb54a231aecf4578ae5866d2b74202b54 not-for-merge branch 'testcommit4624' of github.com:jantman/gitpython_issue_301 -8d687bbc847a234d3586853091c506fe0c159fbc not-for-merge branch 'testcommit4625' of github.com:jantman/gitpython_issue_301 -2ac3c99a2d0d07607266061392af37326e2dda1e not-for-merge branch 'testcommit4626' of github.com:jantman/gitpython_issue_301 -82bfca714b7ac30c6d3b64ff17fc2b1e38e0507f not-for-merge branch 'testcommit4627' of github.com:jantman/gitpython_issue_301 -1c81a7f9b5710f0b87987b59396661ef30eaf9ac not-for-merge branch 'testcommit4628' of github.com:jantman/gitpython_issue_301 -9038af1f6a7afbc81e7637ba16c4eb01f39e43de not-for-merge branch 'testcommit4629' of github.com:jantman/gitpython_issue_301 -da36800203252ff61e5da0101a6f70c3e5003581 not-for-merge branch 'testcommit463' of github.com:jantman/gitpython_issue_301 -7270cf515a5bc4c3540b2be7369c4e9cbbb0cd48 not-for-merge branch 'testcommit4630' of github.com:jantman/gitpython_issue_301 -26c0c348572c0fc190d83c9479d450f02ab064b0 not-for-merge branch 'testcommit4631' of github.com:jantman/gitpython_issue_301 -eb532de11df9b49f0eb9a96fc847726bcc9bff9f not-for-merge branch 'testcommit4632' of github.com:jantman/gitpython_issue_301 -61a72ded48e60e73bd14e5bcf73a636e4f58edbd not-for-merge branch 'testcommit4633' of github.com:jantman/gitpython_issue_301 -affef25c9b909aea4922443d7bb701dcd35e5640 not-for-merge branch 'testcommit4634' of github.com:jantman/gitpython_issue_301 -3189d8f0527f2671297e9790742736cec364ab69 not-for-merge branch 'testcommit4635' of github.com:jantman/gitpython_issue_301 -ab1475133bcde1635b85034ff08738a83e5caf24 not-for-merge branch 'testcommit4636' of github.com:jantman/gitpython_issue_301 -e76dbf4776d130b3fa2d6d02ea964464c9ddc463 not-for-merge branch 'testcommit4637' of github.com:jantman/gitpython_issue_301 -b20a84157df3ff49e6c1bbe9a853be04073f76ce not-for-merge branch 'testcommit4638' of github.com:jantman/gitpython_issue_301 -0af0fa844c9101d88679134253e525154ce6aabc not-for-merge branch 'testcommit4639' of github.com:jantman/gitpython_issue_301 -bd31695a8840d6e4d8f7214b20d9e0e42ad64def not-for-merge branch 'testcommit464' of github.com:jantman/gitpython_issue_301 -8a989a6e8f497edc4bcb4ab26d2c24b825b3d290 not-for-merge branch 'testcommit4640' of github.com:jantman/gitpython_issue_301 -c6af30e0aa864b535c2ce58206f8b66abbdce65c not-for-merge branch 'testcommit4641' of github.com:jantman/gitpython_issue_301 -10f3979d4f995e20281f747f24ef0a10184e7fe6 not-for-merge branch 'testcommit4642' of github.com:jantman/gitpython_issue_301 -87f9eeac20879c623c09ed6fe3aa83d85d3fa469 not-for-merge branch 'testcommit4643' of github.com:jantman/gitpython_issue_301 -72fecebf9deb4204e261b9735e993fcba99a3856 not-for-merge branch 'testcommit4644' of github.com:jantman/gitpython_issue_301 -bf353ef455b3f6c0ce6d0520f58081d745a3dd6e not-for-merge branch 'testcommit4645' of github.com:jantman/gitpython_issue_301 -31b5910264489a5e18d9c1e16b1e43fec64ef83e not-for-merge branch 'testcommit4646' of github.com:jantman/gitpython_issue_301 -a121373ebc8c96dd09ebb7e1a19ccf147e8d6665 not-for-merge branch 'testcommit4647' of github.com:jantman/gitpython_issue_301 -45a6793496f41c6ae5c7bf6d3aac03a85c95345e not-for-merge branch 'testcommit4648' of github.com:jantman/gitpython_issue_301 -75385fbaef8a4a7d7dc70f47c32a833a5faa62c2 not-for-merge branch 'testcommit4649' of github.com:jantman/gitpython_issue_301 -d0ece462b4caa4411d28f56b47e8b06a2bb59cde not-for-merge branch 'testcommit465' of github.com:jantman/gitpython_issue_301 -a3660e37bd31043060c5edd91089df7efa5e6a35 not-for-merge branch 'testcommit4650' of github.com:jantman/gitpython_issue_301 -42cb9586c8193038d8c4fe1094586ed1d2cb4d38 not-for-merge branch 'testcommit4651' of github.com:jantman/gitpython_issue_301 -d6383d73d8041a5c63c623d3a54c1dd1722d8725 not-for-merge branch 'testcommit4652' of github.com:jantman/gitpython_issue_301 -60c1aa5e56afa1350ba5083f5a3042653cba2efd not-for-merge branch 'testcommit4653' of github.com:jantman/gitpython_issue_301 -0c63743c061e6b6dce14ed65fb035f58adc9f9e8 not-for-merge branch 'testcommit4654' of github.com:jantman/gitpython_issue_301 -60387f4f50d4f4a0b8295fadcc8224a1cd8c4aa2 not-for-merge branch 'testcommit4655' of github.com:jantman/gitpython_issue_301 -9359a45bf9e1a4a224e10138c3299ddd032d9831 not-for-merge branch 'testcommit4656' of github.com:jantman/gitpython_issue_301 -244124a7c26d3a9575718cc6da32664e2e02bcd4 not-for-merge branch 'testcommit4657' of github.com:jantman/gitpython_issue_301 -864fae9ff556b50fda76cbfb5a8569451c62c005 not-for-merge branch 'testcommit4658' of github.com:jantman/gitpython_issue_301 -1c340884744433f70a209238680144dac061468c not-for-merge branch 'testcommit4659' of github.com:jantman/gitpython_issue_301 -de6884046384439ce66bd8b57973e59fd2070d32 not-for-merge branch 'testcommit466' of github.com:jantman/gitpython_issue_301 -2a7223b4d667e726688e01f5cd3c04dcbb3e53c8 not-for-merge branch 'testcommit4660' of github.com:jantman/gitpython_issue_301 -89f7dde7fce1654248c848df1a3c21f966d279ee not-for-merge branch 'testcommit4661' of github.com:jantman/gitpython_issue_301 -eeb0d5d5f6c4403d4961aaed0ce67cc91d22c9ef not-for-merge branch 'testcommit4662' of github.com:jantman/gitpython_issue_301 -0818ece5d463717408a2336b4e8eafcf8ee30087 not-for-merge branch 'testcommit4663' of github.com:jantman/gitpython_issue_301 -66cce34cb7e3955fba12ca63bf45954acc06beae not-for-merge branch 'testcommit4664' of github.com:jantman/gitpython_issue_301 -38dd9e96b48909c4c65e7c51eb437ed333e096a6 not-for-merge branch 'testcommit4665' of github.com:jantman/gitpython_issue_301 -49fcaf8ea1893e25006443cc7387f77e9970a465 not-for-merge branch 'testcommit4666' of github.com:jantman/gitpython_issue_301 -12961e069a5d9f9cc119b23772c65eb98f037987 not-for-merge branch 'testcommit4667' of github.com:jantman/gitpython_issue_301 -61c216acfabccc37ef9f16ba9c25e574114203c9 not-for-merge branch 'testcommit4668' of github.com:jantman/gitpython_issue_301 -e6045ad2ce553da4d2fea96ed6b289e125229c1e not-for-merge branch 'testcommit4669' of github.com:jantman/gitpython_issue_301 -3465e9b44795690978f1559f7421a71a34e82ec2 not-for-merge branch 'testcommit467' of github.com:jantman/gitpython_issue_301 -bf009e13c27e4ee9e39e3eeb6bf23fde6a94b08e not-for-merge branch 'testcommit4670' of github.com:jantman/gitpython_issue_301 -ed864fde0c96eb1ac7758454a35bb57f93896b7e not-for-merge branch 'testcommit4671' of github.com:jantman/gitpython_issue_301 -451fc4c454b548a772ecbce0b005efe1b4baf8e3 not-for-merge branch 'testcommit4672' of github.com:jantman/gitpython_issue_301 -85f7dfa269218ba5259302bea38141d5d66e268d not-for-merge branch 'testcommit4673' of github.com:jantman/gitpython_issue_301 -ad633520a88294e873f81c31ece4df085f479ea2 not-for-merge branch 'testcommit4674' of github.com:jantman/gitpython_issue_301 -80e2b2231f9982f230b6559ab0d20ff01b2ee28d not-for-merge branch 'testcommit4675' of github.com:jantman/gitpython_issue_301 -5e19eda57e362462f6d2caa617114f74c1d4ea50 not-for-merge branch 'testcommit4676' of github.com:jantman/gitpython_issue_301 -b71444a5fe5fdb0c9513cf8898994795ccd5e377 not-for-merge branch 'testcommit4677' of github.com:jantman/gitpython_issue_301 -b2f76d1348824629b925e6d02b2149c4fcb6efb6 not-for-merge branch 'testcommit4678' of github.com:jantman/gitpython_issue_301 -febc2ef270a1c571565ea51068db9216c43ebf43 not-for-merge branch 'testcommit4679' of github.com:jantman/gitpython_issue_301 -b27e44cc67a424b8fcfcbcf99aa1e53a4b7989b6 not-for-merge branch 'testcommit468' of github.com:jantman/gitpython_issue_301 -0aaabf343ecc78088f1cbbf48c5b505bae3c94e7 not-for-merge branch 'testcommit4680' of github.com:jantman/gitpython_issue_301 -f2a9518221de0b8292f9de3bda5c9efaa4fd73b9 not-for-merge branch 'testcommit4681' of github.com:jantman/gitpython_issue_301 -38145f651bb7b6eaea7ed91c60b923ff29d3f86d not-for-merge branch 'testcommit4682' of github.com:jantman/gitpython_issue_301 -59f7ae03055b58f3c3b514cab4fca50741970a6c not-for-merge branch 'testcommit4683' of github.com:jantman/gitpython_issue_301 -d340798e0d7829afe7318e764d9cb00271994693 not-for-merge branch 'testcommit4684' of github.com:jantman/gitpython_issue_301 -2bea460597e9213b4c8ac404eb44402a592ee647 not-for-merge branch 'testcommit4685' of github.com:jantman/gitpython_issue_301 -79ea94aef265ad475a3a1d65e19c414667a273b9 not-for-merge branch 'testcommit4686' of github.com:jantman/gitpython_issue_301 -9cb166ae857224045a9efa518d6898d963a96d74 not-for-merge branch 'testcommit4687' of github.com:jantman/gitpython_issue_301 -296732f4fde007fe3cf22a050d140560dc90291c not-for-merge branch 'testcommit4688' of github.com:jantman/gitpython_issue_301 -daab1842fccb375b7131a243c17b28ed174b3887 not-for-merge branch 'testcommit4689' of github.com:jantman/gitpython_issue_301 -f7b92f16e07c7fb2d7fd3753d7a2de062f5ce481 not-for-merge branch 'testcommit469' of github.com:jantman/gitpython_issue_301 -89c8f14615bc119fc4a75dd68fa1773317776da9 not-for-merge branch 'testcommit4690' of github.com:jantman/gitpython_issue_301 -47b3025258d8f7a623b8fb6174f77dec795a2863 not-for-merge branch 'testcommit4691' of github.com:jantman/gitpython_issue_301 -44447fb702b81b966de9aa2e95b24986f3282dd0 not-for-merge branch 'testcommit4692' of github.com:jantman/gitpython_issue_301 -2f7b08b3d42c0dc91996b6efb9066e6a7bdef7c7 not-for-merge branch 'testcommit4693' of github.com:jantman/gitpython_issue_301 -06899198123eef21db579a79b2c0f269728876dc not-for-merge branch 'testcommit4694' of github.com:jantman/gitpython_issue_301 -424b202bac168d24c6cf69e5003a7d93d37c7333 not-for-merge branch 'testcommit4695' of github.com:jantman/gitpython_issue_301 -ef7fb0252a4f7884338e0b2a71de483cd2690e0b not-for-merge branch 'testcommit4696' of github.com:jantman/gitpython_issue_301 -ec8917df84a02b6eac2cbdb7c23a37bbac2ea669 not-for-merge branch 'testcommit4697' of github.com:jantman/gitpython_issue_301 -07824ed70edda4a87850f042ad729a3da1a04856 not-for-merge branch 'testcommit4698' of github.com:jantman/gitpython_issue_301 -272180c45556c46468fc0bba7dc4cda67707d9e1 not-for-merge branch 'testcommit4699' of github.com:jantman/gitpython_issue_301 -a96b1e88b11c2af67e2e62dcb37e375cd8061da6 not-for-merge branch 'testcommit47' of github.com:jantman/gitpython_issue_301 -4b5f4081febcce059a7224eaa1d818ecee4dbb2d not-for-merge branch 'testcommit470' of github.com:jantman/gitpython_issue_301 -3ee300791ab3256c5c6340252b4f347570b78637 not-for-merge branch 'testcommit4700' of github.com:jantman/gitpython_issue_301 -da60c0e47e78806ffc93597df96b4aedef8ca7ba not-for-merge branch 'testcommit4701' of github.com:jantman/gitpython_issue_301 -98cf757142564087bd538c84912ec089eef09a0b not-for-merge branch 'testcommit4702' of github.com:jantman/gitpython_issue_301 -fb36375ddf1743b4668a4eb14387e0a9ab698842 not-for-merge branch 'testcommit4703' of github.com:jantman/gitpython_issue_301 -a7ec52ca63f42c30deccb00c6585a7f44021536c not-for-merge branch 'testcommit4704' of github.com:jantman/gitpython_issue_301 -efa8fa75318191832949065a754e96c79f9f2ddf not-for-merge branch 'testcommit4705' of github.com:jantman/gitpython_issue_301 -656074d3587cb08c61c4976d10d13c7bc698dde0 not-for-merge branch 'testcommit4706' of github.com:jantman/gitpython_issue_301 -7631e155ebe75f7f356f1aa123623d11bec4a235 not-for-merge branch 'testcommit4707' of github.com:jantman/gitpython_issue_301 -9a9541589878253c55a3c0f322d736a400ee2417 not-for-merge branch 'testcommit4708' of github.com:jantman/gitpython_issue_301 -bf9a1b59414fe5352b273844a9a9e2e5c9047f02 not-for-merge branch 'testcommit4709' of github.com:jantman/gitpython_issue_301 -0b57494572f1ba3d77a1ed467abcdaf6d7996469 not-for-merge branch 'testcommit471' of github.com:jantman/gitpython_issue_301 -9fbae1120c6a5284b8d5c36cd792e53a9bcf64eb not-for-merge branch 'testcommit4710' of github.com:jantman/gitpython_issue_301 -b2c147e9c41853bb862a3a34b3175f1bebf79dfe not-for-merge branch 'testcommit4711' of github.com:jantman/gitpython_issue_301 -25e56b40f5f1001e4dcff44be1377e850bf26cf7 not-for-merge branch 'testcommit4712' of github.com:jantman/gitpython_issue_301 -1268d28c4d6959fbd7c4d7ac6a9ce4e4aaa51076 not-for-merge branch 'testcommit4713' of github.com:jantman/gitpython_issue_301 -5cc5af2fb72044e4502896f5d1b4643a76b34314 not-for-merge branch 'testcommit4714' of github.com:jantman/gitpython_issue_301 -4c9aae9857e38652c972c61779fd26a793db615b not-for-merge branch 'testcommit4715' of github.com:jantman/gitpython_issue_301 -7e0a2d3844b64fdb6538cdf77112e3864861a389 not-for-merge branch 'testcommit4716' of github.com:jantman/gitpython_issue_301 -c0b56ec06503f88a5536a76813f2a8002920de76 not-for-merge branch 'testcommit4717' of github.com:jantman/gitpython_issue_301 -fa349fb4eedc8fe83b212bc50a6cde0ac60dfdf1 not-for-merge branch 'testcommit4718' of github.com:jantman/gitpython_issue_301 -8b89383ed3342e1868a8f15468323556f896b0a5 not-for-merge branch 'testcommit4719' of github.com:jantman/gitpython_issue_301 -57e4f05db54fbbcd1c37dad3ab7c6fda4e28ada4 not-for-merge branch 'testcommit472' of github.com:jantman/gitpython_issue_301 -47baa17d9fdf816cca446906ac6b4ec5bcb810d5 not-for-merge branch 'testcommit4720' of github.com:jantman/gitpython_issue_301 -ef69fd4b86df724bb605b1ce5da3fbef0253e131 not-for-merge branch 'testcommit4721' of github.com:jantman/gitpython_issue_301 -f1add743ee1a3e4ffc5dd4160532fa999c474cdb not-for-merge branch 'testcommit4722' of github.com:jantman/gitpython_issue_301 -1abbbace215189b65786d68e7be908894e79f4d9 not-for-merge branch 'testcommit4723' of github.com:jantman/gitpython_issue_301 -4b583f0793a66358172535514980f507f4b3c101 not-for-merge branch 'testcommit4724' of github.com:jantman/gitpython_issue_301 -01cc8110edda20b344ceb5f0bb14b91f4a67b86d not-for-merge branch 'testcommit4725' of github.com:jantman/gitpython_issue_301 -650118d2905e90bff7f12b9483102136d1a11314 not-for-merge branch 'testcommit4726' of github.com:jantman/gitpython_issue_301 -9876c400fddf34e6d63cb79f63f1cdcde682fa7c not-for-merge branch 'testcommit4727' of github.com:jantman/gitpython_issue_301 -adbf0e2652278a2c5327f8bfcdd82053ab7898ff not-for-merge branch 'testcommit4728' of github.com:jantman/gitpython_issue_301 -0f1b5aa64f3b4f8236750501d52e08c9152d3140 not-for-merge branch 'testcommit4729' of github.com:jantman/gitpython_issue_301 -c5fdd38e3ba69c6339edcff67fc0f35c9c6c8229 not-for-merge branch 'testcommit473' of github.com:jantman/gitpython_issue_301 -a461aaef1e126939d88af1e2ad6568aefa6a5ff8 not-for-merge branch 'testcommit4730' of github.com:jantman/gitpython_issue_301 -f7f1bc6411c66f79dea26d79f79ea6da3ba0d289 not-for-merge branch 'testcommit4731' of github.com:jantman/gitpython_issue_301 -17f0489db85bb2e7a6a279c99ed0162b4f092c5d not-for-merge branch 'testcommit4732' of github.com:jantman/gitpython_issue_301 -b93bd99dc9cd848d747b7ef8d08114422a781b66 not-for-merge branch 'testcommit4733' of github.com:jantman/gitpython_issue_301 -bdb81e21b4ffb025fc258bdff60f33bf60775163 not-for-merge branch 'testcommit4734' of github.com:jantman/gitpython_issue_301 -fdf820206d700a7c2f3533be337dd1450d3b2ae5 not-for-merge branch 'testcommit4735' of github.com:jantman/gitpython_issue_301 -d0516245e042d435ade211d3038623160e4dce6e not-for-merge branch 'testcommit4736' of github.com:jantman/gitpython_issue_301 -5da00cd8aa59bde795892f8273527ff53e255b04 not-for-merge branch 'testcommit4737' of github.com:jantman/gitpython_issue_301 -3a581973ccbca62cd93a6dc5ddb41cf6e0afaaca not-for-merge branch 'testcommit4738' of github.com:jantman/gitpython_issue_301 -30062baab4c3184b8410664fd0366665f9b23f66 not-for-merge branch 'testcommit4739' of github.com:jantman/gitpython_issue_301 -cb90b672c33fc034a4b6c1ba574a94a3c5c0d8c7 not-for-merge branch 'testcommit474' of github.com:jantman/gitpython_issue_301 -367ee76c8836f8ef6f5da5b039e2ccbcdd671d92 not-for-merge branch 'testcommit4740' of github.com:jantman/gitpython_issue_301 -caaafcac3305d9bd2ff6af98791b724b6e95c048 not-for-merge branch 'testcommit4741' of github.com:jantman/gitpython_issue_301 -009ff4492544b991f46550de7a59fbed92019ff4 not-for-merge branch 'testcommit4742' of github.com:jantman/gitpython_issue_301 -8c4c340d4dc7df5ccdf6002b9bc5582db6a240ce not-for-merge branch 'testcommit4743' of github.com:jantman/gitpython_issue_301 -d550ecc2fb82c75e61a42c429237bfd30497e04f not-for-merge branch 'testcommit4744' of github.com:jantman/gitpython_issue_301 -bdfcf93190280e5ba874a39f5eba8fe7d70dcd30 not-for-merge branch 'testcommit4745' of github.com:jantman/gitpython_issue_301 -c4030e1d7b10c4a194493fc4001c02214f401df4 not-for-merge branch 'testcommit4746' of github.com:jantman/gitpython_issue_301 -b1b8a74e7223423bdccbf7240c46d246a5b94707 not-for-merge branch 'testcommit4747' of github.com:jantman/gitpython_issue_301 -7dcdf2507b09496ccd1e6deab9593ecbd54dbcbb not-for-merge branch 'testcommit4748' of github.com:jantman/gitpython_issue_301 -681c0432d22d1af1d9339ebe8a7452820a725b26 not-for-merge branch 'testcommit4749' of github.com:jantman/gitpython_issue_301 -b5737cad7c154b5dc3e63a673f18bd5f36248a8c not-for-merge branch 'testcommit475' of github.com:jantman/gitpython_issue_301 -7e55d9a01f26b536014c7bf6bff32eced4cbc4b5 not-for-merge branch 'testcommit4750' of github.com:jantman/gitpython_issue_301 -57a5a899e81a2aeee5a674fa7b25ab1294e65aa6 not-for-merge branch 'testcommit4751' of github.com:jantman/gitpython_issue_301 -b8ec3f8871a61a3b9b2d209e06270f8ad18658eb not-for-merge branch 'testcommit4752' of github.com:jantman/gitpython_issue_301 -039e57e0809fb429aee18e8ce95167b535ee4053 not-for-merge branch 'testcommit4753' of github.com:jantman/gitpython_issue_301 -ff31f45c8470f99bdf4558d56ad5f977c5579e19 not-for-merge branch 'testcommit4754' of github.com:jantman/gitpython_issue_301 -2cdb3f1ce30a4beeb31a67e1b572bd75aba86a15 not-for-merge branch 'testcommit4755' of github.com:jantman/gitpython_issue_301 -9340574a8286af190322394261d343859c3b9413 not-for-merge branch 'testcommit4756' of github.com:jantman/gitpython_issue_301 -7cc16b46721ea783155f6ad0e2605de5f9fec53c not-for-merge branch 'testcommit4757' of github.com:jantman/gitpython_issue_301 -a28ce7eb446c78b0ac07826b9fbb72e36455c226 not-for-merge branch 'testcommit4758' of github.com:jantman/gitpython_issue_301 -e0d3b75affc218ab68a28c0b14f751134f57db54 not-for-merge branch 'testcommit4759' of github.com:jantman/gitpython_issue_301 -c72b3e087c56a82b2dc6fabe742d7e5bccfce31e not-for-merge branch 'testcommit476' of github.com:jantman/gitpython_issue_301 -f70ad114725aa0eee24804c8498821f4217dd73c not-for-merge branch 'testcommit4760' of github.com:jantman/gitpython_issue_301 -55767fcb78e91d770228492c390eb375e4452181 not-for-merge branch 'testcommit4761' of github.com:jantman/gitpython_issue_301 -caeaaee3e1c0d207898bc2407449dc3bff1bc566 not-for-merge branch 'testcommit4762' of github.com:jantman/gitpython_issue_301 -1a7077fcf2ead60494ee48d8cda8704243cddb52 not-for-merge branch 'testcommit4763' of github.com:jantman/gitpython_issue_301 -a78a6a78a1f362b43d485a5cf51cd5414babc179 not-for-merge branch 'testcommit4764' of github.com:jantman/gitpython_issue_301 -74055d80d474a67b3e683c857fa83b9c1d46172b not-for-merge branch 'testcommit4765' of github.com:jantman/gitpython_issue_301 -3ced591cfbd6b174da051309a52b6d4febf5be50 not-for-merge branch 'testcommit4766' of github.com:jantman/gitpython_issue_301 -703c1df1e6bd58f126335b72feff8ac4e9009f05 not-for-merge branch 'testcommit4767' of github.com:jantman/gitpython_issue_301 -c81a5b76f1d6d57555a51fdeb2da22802df7c30f not-for-merge branch 'testcommit4768' of github.com:jantman/gitpython_issue_301 -9ef553a342ddc71bd9f02ac9c66fc9e645c009a0 not-for-merge branch 'testcommit4769' of github.com:jantman/gitpython_issue_301 -b4d006109bb472e591c75f3b2d0c841605c84ec0 not-for-merge branch 'testcommit477' of github.com:jantman/gitpython_issue_301 -d6fb5bb083d2a27d92063861d66611bf9c31a932 not-for-merge branch 'testcommit4770' of github.com:jantman/gitpython_issue_301 -989ee14f5df38347c9e6758af74e4e945d1c36c8 not-for-merge branch 'testcommit4771' of github.com:jantman/gitpython_issue_301 -df0f5f54f021b36d5660e12fb3f6dd4b6bd3b658 not-for-merge branch 'testcommit4772' of github.com:jantman/gitpython_issue_301 -450738f1cb07a13deef9bcc477390a790efbf7f9 not-for-merge branch 'testcommit4773' of github.com:jantman/gitpython_issue_301 -6364fe5716435df242947f874ff7ef364c270e5d not-for-merge branch 'testcommit4774' of github.com:jantman/gitpython_issue_301 -9c4b655f023e394f8caa6e227d9e202adf1eb2d7 not-for-merge branch 'testcommit4775' of github.com:jantman/gitpython_issue_301 -4f5b46c5dafcbe2c252626d1cf3d5392f1d7f340 not-for-merge branch 'testcommit4776' of github.com:jantman/gitpython_issue_301 -13f1a86587dd48d1ddc9f8bf584b1be292c00965 not-for-merge branch 'testcommit4777' of github.com:jantman/gitpython_issue_301 -59984f06106897542d6553b5d923f9a6ff43dac4 not-for-merge branch 'testcommit4778' of github.com:jantman/gitpython_issue_301 -b6f54bfe2ccf8f253fff6bdf0724cd614623eb9a not-for-merge branch 'testcommit4779' of github.com:jantman/gitpython_issue_301 -0a98fa71a74d51baddcb510252781ef511db7fb2 not-for-merge branch 'testcommit478' of github.com:jantman/gitpython_issue_301 -ceafcfe0f41ca1f1e6488a4e958d39cf2cc4a123 not-for-merge branch 'testcommit4780' of github.com:jantman/gitpython_issue_301 -91c874733d4ea294a17e649faef7fa9af97ec8f1 not-for-merge branch 'testcommit4781' of github.com:jantman/gitpython_issue_301 -d87d4ea406c402656b073b2ddfebf2f108e44e8a not-for-merge branch 'testcommit4782' of github.com:jantman/gitpython_issue_301 -7f2b7476f912fe9d9c6af171dac55f43ab2b397e not-for-merge branch 'testcommit4783' of github.com:jantman/gitpython_issue_301 -dee931d3645e482b98b7c68516c368d58d964e2c not-for-merge branch 'testcommit4784' of github.com:jantman/gitpython_issue_301 -64dd7dfe23166c9a076611b415c930b404c10dd4 not-for-merge branch 'testcommit4785' of github.com:jantman/gitpython_issue_301 -464c257d5f609648955fc8bd0073a67abf88fa6f not-for-merge branch 'testcommit4786' of github.com:jantman/gitpython_issue_301 -e0e9548becf04661a6df870e06471c5171a9873c not-for-merge branch 'testcommit4787' of github.com:jantman/gitpython_issue_301 -de70ce3b10e2b85a1bddbeb54be192a4bcf7a083 not-for-merge branch 'testcommit4788' of github.com:jantman/gitpython_issue_301 -cd12173c1d60544d4c5f48321a6c73f178efd346 not-for-merge branch 'testcommit4789' of github.com:jantman/gitpython_issue_301 -f3c706707e8a4093d448d948338bb47c18884352 not-for-merge branch 'testcommit479' of github.com:jantman/gitpython_issue_301 -4eafb6bbbd03cf9c86c340134bab24f48c61584b not-for-merge branch 'testcommit4790' of github.com:jantman/gitpython_issue_301 -aa6d45c63dee95ad50cb6eab4acad58efe686f82 not-for-merge branch 'testcommit4791' of github.com:jantman/gitpython_issue_301 -89439da78b3358ca7481edafed3a78a666bc925c not-for-merge branch 'testcommit4792' of github.com:jantman/gitpython_issue_301 -fbdf551c0353bd998607c87b3742b2b8fde3f23c not-for-merge branch 'testcommit4793' of github.com:jantman/gitpython_issue_301 -9b1e3da2d5400ab8cee41b1fedadc66606212ffc not-for-merge branch 'testcommit4794' of github.com:jantman/gitpython_issue_301 -818b8717be3f6f737ded2a3c812af33c07399e3b not-for-merge branch 'testcommit4795' of github.com:jantman/gitpython_issue_301 -b5be4374c35cbf2064d35afda06350825fe192e1 not-for-merge branch 'testcommit4796' of github.com:jantman/gitpython_issue_301 -b3f0a68e7d8e111a9941f346fb9b20064a0968f8 not-for-merge branch 'testcommit4797' of github.com:jantman/gitpython_issue_301 -499b056d1e978ebd37f81992a06fcf825d29d2d4 not-for-merge branch 'testcommit4798' of github.com:jantman/gitpython_issue_301 -26763fb6ac7648b952d9eaaa904e0849c3dcd21f not-for-merge branch 'testcommit4799' of github.com:jantman/gitpython_issue_301 -200b93bf3e1739198c0a643d21ffa9ec90171d74 not-for-merge branch 'testcommit48' of github.com:jantman/gitpython_issue_301 -adadd5c09f650d34468764da909b8fc21a493c4d not-for-merge branch 'testcommit480' of github.com:jantman/gitpython_issue_301 -2c1b1d4fecf87b50aaf2d2d1e83000fcf96cd6b2 not-for-merge branch 'testcommit4800' of github.com:jantman/gitpython_issue_301 -7396157ed5f9fbb3913b817a23ca41dc729df8d2 not-for-merge branch 'testcommit4801' of github.com:jantman/gitpython_issue_301 -5646a232b8c5a3cdbf47e7ec1eacd9d8fdae989d not-for-merge branch 'testcommit4802' of github.com:jantman/gitpython_issue_301 -47e107bb03079718c0cffaa62b6c3354a3d2cff6 not-for-merge branch 'testcommit4803' of github.com:jantman/gitpython_issue_301 -8a8e4d1e1c845bbb7cd9d8d21604f51404728eec not-for-merge branch 'testcommit4804' of github.com:jantman/gitpython_issue_301 -486c2a3a72c74dd06cd08c8f20acda06bd9d7909 not-for-merge branch 'testcommit4805' of github.com:jantman/gitpython_issue_301 -c75a2b9b8f52f198712202abc5364234d9eed365 not-for-merge branch 'testcommit4806' of github.com:jantman/gitpython_issue_301 -a80d0c0548d10b6989808a9b40dc800c88486abc not-for-merge branch 'testcommit4807' of github.com:jantman/gitpython_issue_301 -9c80ba3f1f1e52c029bff29cb96401bd575eb015 not-for-merge branch 'testcommit4808' of github.com:jantman/gitpython_issue_301 -78623aedb95842e441c46570e33c85ccda50c56b not-for-merge branch 'testcommit4809' of github.com:jantman/gitpython_issue_301 -c537e917ffad17cf62f79bff77dd8de7aea74d17 not-for-merge branch 'testcommit481' of github.com:jantman/gitpython_issue_301 -3ef5388cea576d59ec3d3806455d98cdcaba75f1 not-for-merge branch 'testcommit4810' of github.com:jantman/gitpython_issue_301 -921cb0104254c6bbeb6d1222a3d98dcbad0921a3 not-for-merge branch 'testcommit4811' of github.com:jantman/gitpython_issue_301 -e826256813339835a2fd7817dd7ebb551674a8bf not-for-merge branch 'testcommit4812' of github.com:jantman/gitpython_issue_301 -2245305b6e787ae1421d3a9fe7adb8f0cfe68851 not-for-merge branch 'testcommit4813' of github.com:jantman/gitpython_issue_301 -b5800727b17dad948826f23c8d3d240ab4a6c707 not-for-merge branch 'testcommit4814' of github.com:jantman/gitpython_issue_301 -e3d954c768058aea363067d4aa5040d696ab0e67 not-for-merge branch 'testcommit4815' of github.com:jantman/gitpython_issue_301 -0348043e0e0a66e3d587fc7af204ca3ffa0989a5 not-for-merge branch 'testcommit4816' of github.com:jantman/gitpython_issue_301 -a7b6bacfd8e540961db384e66b3fdfc66f69ef27 not-for-merge branch 'testcommit4817' of github.com:jantman/gitpython_issue_301 -cb8be592ef228f279241d585ad65055e91dafa0f not-for-merge branch 'testcommit4818' of github.com:jantman/gitpython_issue_301 -2cdc84a696ace92eb37975c3c17aade732cc4bc9 not-for-merge branch 'testcommit4819' of github.com:jantman/gitpython_issue_301 -8019e1daa505af7bbd67ef954439e43f435f9949 not-for-merge branch 'testcommit482' of github.com:jantman/gitpython_issue_301 -ad54168be9509eabbec3c5c88c27c6f90e03a040 not-for-merge branch 'testcommit4820' of github.com:jantman/gitpython_issue_301 -b1915b8a48ad72cdc3d056f88d4df3d9662da702 not-for-merge branch 'testcommit4821' of github.com:jantman/gitpython_issue_301 -21eacb67a9f6b2d5e2be162ba8c13eaf8fa9cef3 not-for-merge branch 'testcommit4822' of github.com:jantman/gitpython_issue_301 -538aa6a4932df946d8314baa898c7bc43fc790e0 not-for-merge branch 'testcommit4823' of github.com:jantman/gitpython_issue_301 -36e843c017c01d88fdeeff2985f3aa8dc760de08 not-for-merge branch 'testcommit4824' of github.com:jantman/gitpython_issue_301 -cc3956673b7a9e74ac134d93f6a8d7749313a7a5 not-for-merge branch 'testcommit4825' of github.com:jantman/gitpython_issue_301 -0effbe4e45f04fcd1f4362b1a1bc87469888af9f not-for-merge branch 'testcommit4826' of github.com:jantman/gitpython_issue_301 -8d64fed50308450a8d5547317197a92782fc4367 not-for-merge branch 'testcommit4827' of github.com:jantman/gitpython_issue_301 -d67b7db4f4d6a8bb90f77fe6c8fd82b19ba77da8 not-for-merge branch 'testcommit4828' of github.com:jantman/gitpython_issue_301 -2fe18c487147cbc37e298e26ea9e1320c1cf5a50 not-for-merge branch 'testcommit4829' of github.com:jantman/gitpython_issue_301 -0c9f5fca72838c6e9e8871872684549932fcc663 not-for-merge branch 'testcommit483' of github.com:jantman/gitpython_issue_301 -ee5a3293882850fbecbe9c4236968f6d1904d6e9 not-for-merge branch 'testcommit4830' of github.com:jantman/gitpython_issue_301 -b7b3cb1d16bc7d7493ffc461210156cade6ef96c not-for-merge branch 'testcommit4831' of github.com:jantman/gitpython_issue_301 -1f4760a0f761cfa3661478799e1ee6e79bf782ab not-for-merge branch 'testcommit4832' of github.com:jantman/gitpython_issue_301 -6a5a19408308f1d3e429cb001fab8c231c94ba63 not-for-merge branch 'testcommit4833' of github.com:jantman/gitpython_issue_301 -3a0ce9008d177d20ea62ad59a7b75714bfa28777 not-for-merge branch 'testcommit4834' of github.com:jantman/gitpython_issue_301 -418970ab8f74f513f3dce5d89aec062ff7a2ff4d not-for-merge branch 'testcommit4835' of github.com:jantman/gitpython_issue_301 -81da625ee9b021e0f861f00bc18b325dd3e26346 not-for-merge branch 'testcommit4836' of github.com:jantman/gitpython_issue_301 -e6d6a495dc34a2ffcf01956ca366a69abe4947f6 not-for-merge branch 'testcommit4837' of github.com:jantman/gitpython_issue_301 -68a03f82fb18ebc338c02b82bb3ef4d3631311c6 not-for-merge branch 'testcommit4838' of github.com:jantman/gitpython_issue_301 -d99051e83311ff60dee3ec6223d4d5836b5c1ceb not-for-merge branch 'testcommit4839' of github.com:jantman/gitpython_issue_301 -1718a4e5492c1ce3b6d68d4b7844cdaff2abfe0c not-for-merge branch 'testcommit484' of github.com:jantman/gitpython_issue_301 -8efcfcd1e8275909b3735a2e5f259ad507aa7c6d not-for-merge branch 'testcommit4840' of github.com:jantman/gitpython_issue_301 -57ff33b7649440420c07dfd1a42dfd32895801ce not-for-merge branch 'testcommit4841' of github.com:jantman/gitpython_issue_301 -389780c26d584a69e1e12b72593cad0cccf1a15d not-for-merge branch 'testcommit4842' of github.com:jantman/gitpython_issue_301 -67ac6b5ca5f689382faaf1f098ad886609bbea70 not-for-merge branch 'testcommit4843' of github.com:jantman/gitpython_issue_301 -0d571b3d912555b057f348d588544edca1446ab6 not-for-merge branch 'testcommit4844' of github.com:jantman/gitpython_issue_301 -ae6ab622df2beebd3263c40a9d1c81a28704b7bb not-for-merge branch 'testcommit4845' of github.com:jantman/gitpython_issue_301 -d7dcf0f24cafc23cda14dfc1331c06964e90dabd not-for-merge branch 'testcommit4846' of github.com:jantman/gitpython_issue_301 -3840a8113886deb33d7ec2e516d08477aba24b55 not-for-merge branch 'testcommit4847' of github.com:jantman/gitpython_issue_301 -400ac52de92299328a9beedf8c37b4fdd0a6bad7 not-for-merge branch 'testcommit4848' of github.com:jantman/gitpython_issue_301 -885af1be7be1af252832db73fa905942feb9099a not-for-merge branch 'testcommit4849' of github.com:jantman/gitpython_issue_301 -58799889a4c4976941d26813a3c995e42157d667 not-for-merge branch 'testcommit485' of github.com:jantman/gitpython_issue_301 -549a624495c164dd9801be4b5e86c5258c70ced0 not-for-merge branch 'testcommit4850' of github.com:jantman/gitpython_issue_301 -cc8b49809f4be6ca20f6650148bfcf4e7d167253 not-for-merge branch 'testcommit4851' of github.com:jantman/gitpython_issue_301 -897eea43202254e365495480c28ac7d95b3b11aa not-for-merge branch 'testcommit4852' of github.com:jantman/gitpython_issue_301 -230a0e7aa3b8f0af4f413179588721566f531e6d not-for-merge branch 'testcommit4853' of github.com:jantman/gitpython_issue_301 -b511ca98acc98036355678f0454b449d10aebfa0 not-for-merge branch 'testcommit4854' of github.com:jantman/gitpython_issue_301 -459b41cdfb4fe9e166c474a847324f11e87b260c not-for-merge branch 'testcommit4855' of github.com:jantman/gitpython_issue_301 -c9ce9b41f7c4a3a05ade72e1d4e6b8e05f107c07 not-for-merge branch 'testcommit4856' of github.com:jantman/gitpython_issue_301 -15b33f0962f2074a7a1f5f82d3e57fe855719ce4 not-for-merge branch 'testcommit4857' of github.com:jantman/gitpython_issue_301 -53b43d6b4fa1156c6f925f3a002f6b14721d17fc not-for-merge branch 'testcommit4858' of github.com:jantman/gitpython_issue_301 -36ac41452fc09093acb685f78387a345392a17f4 not-for-merge branch 'testcommit4859' of github.com:jantman/gitpython_issue_301 -a6e9790bca8c8ac8c34bca4b917c31ea5cfc550c not-for-merge branch 'testcommit486' of github.com:jantman/gitpython_issue_301 -f0fefd42d41fb2c566c0691bd66ff41eff2802bd not-for-merge branch 'testcommit4860' of github.com:jantman/gitpython_issue_301 -e45c32e1a5da64f03b2bd0037622a184700058f2 not-for-merge branch 'testcommit4861' of github.com:jantman/gitpython_issue_301 -a367d5c803f294bf928284408e7d9827c87fdda8 not-for-merge branch 'testcommit4862' of github.com:jantman/gitpython_issue_301 -a821ebd7105c7de61630064ffa4bcbde0065dd3d not-for-merge branch 'testcommit4863' of github.com:jantman/gitpython_issue_301 -cb2b479dd5d3acd07872c4c17ebfcc262f3ef5a8 not-for-merge branch 'testcommit4864' of github.com:jantman/gitpython_issue_301 -99673500cac034ea224d4ac0d4313c25ede78854 not-for-merge branch 'testcommit4865' of github.com:jantman/gitpython_issue_301 -f58e27a10d7fa1584a898fdad49d23b0ab8cfe6d not-for-merge branch 'testcommit4866' of github.com:jantman/gitpython_issue_301 -dfb894a6b797808708203b75572d4af0ca2ca6fd not-for-merge branch 'testcommit4867' of github.com:jantman/gitpython_issue_301 -fc648d5aaf550c2edc2c5297f35abb1be53541d0 not-for-merge branch 'testcommit4868' of github.com:jantman/gitpython_issue_301 -83d4458b27eaa159ccb1e947516cd921908ba0dc not-for-merge branch 'testcommit4869' of github.com:jantman/gitpython_issue_301 -5b1af6038b9684cb8aaa894a8694c5a078ac3026 not-for-merge branch 'testcommit487' of github.com:jantman/gitpython_issue_301 -4351d6a34c69578342e4cbff2550bf581ed3df92 not-for-merge branch 'testcommit4870' of github.com:jantman/gitpython_issue_301 -dbe97c72fc6b972d9d9a4824b02ed911f179ad07 not-for-merge branch 'testcommit4871' of github.com:jantman/gitpython_issue_301 -59c4d3fa8e3e2f790b1836d29f12d7a4e6619502 not-for-merge branch 'testcommit4872' of github.com:jantman/gitpython_issue_301 -78ca87f036905814bc155ea78dad3f90e7025d67 not-for-merge branch 'testcommit4873' of github.com:jantman/gitpython_issue_301 -941741f88d67e2223bd2a1b458271878af065a3e not-for-merge branch 'testcommit4874' of github.com:jantman/gitpython_issue_301 -27e38b8839df81b51a684c46b85e936634420e46 not-for-merge branch 'testcommit4875' of github.com:jantman/gitpython_issue_301 -cfb7361cd6f5c01fccd6d10919741cf6503259ca not-for-merge branch 'testcommit4876' of github.com:jantman/gitpython_issue_301 -bcd78e07e37ae0bad26d301af787e4ae05ed5e02 not-for-merge branch 'testcommit4877' of github.com:jantman/gitpython_issue_301 -74268e975c348732f1578401f30913639b29176c not-for-merge branch 'testcommit4878' of github.com:jantman/gitpython_issue_301 -2e709e84f9cb01f189d1c11e21b14fb9c238abde not-for-merge branch 'testcommit4879' of github.com:jantman/gitpython_issue_301 -22d447e21b635be73ce65ea89213ee2a14305fcd not-for-merge branch 'testcommit488' of github.com:jantman/gitpython_issue_301 -217d13bbcaf4f922dd8e7f8c5efeb1521cca60e8 not-for-merge branch 'testcommit4880' of github.com:jantman/gitpython_issue_301 -73845341832815776dda3af4e50203b2c70aff61 not-for-merge branch 'testcommit4881' of github.com:jantman/gitpython_issue_301 -37843af2396839217856fa86739bce9fe2a1189c not-for-merge branch 'testcommit4882' of github.com:jantman/gitpython_issue_301 -cbf36da6cb52d7105691fc24c49b6c787ec0d8a1 not-for-merge branch 'testcommit4883' of github.com:jantman/gitpython_issue_301 -67fad606b36bf297c9e8c4713c360296d5f6481a not-for-merge branch 'testcommit4884' of github.com:jantman/gitpython_issue_301 -0f6aa2f595dc20b5df6f1430bc80380b16c8e4fe not-for-merge branch 'testcommit4885' of github.com:jantman/gitpython_issue_301 -2052c4a6eb32b78589bd5ac5a9ab1d9f11a6d6ef not-for-merge branch 'testcommit4886' of github.com:jantman/gitpython_issue_301 -f3de71cbd3740e2cdd051612dd37c480c5b7a963 not-for-merge branch 'testcommit4887' of github.com:jantman/gitpython_issue_301 -3d0115a1c2c6eb2541a559c13ee1fe26329868a8 not-for-merge branch 'testcommit4888' of github.com:jantman/gitpython_issue_301 -5877cfa2631cb5f904c9ef6edd4bdcbad6d88926 not-for-merge branch 'testcommit4889' of github.com:jantman/gitpython_issue_301 -6abe493a3a217b737ccc1f736ecda10970a500ca not-for-merge branch 'testcommit489' of github.com:jantman/gitpython_issue_301 -79ff0d0f6515e86dfc6a56f4b69fefe8bdbd38ab not-for-merge branch 'testcommit4890' of github.com:jantman/gitpython_issue_301 -3e80331b0b9db3a68c27f3a39049c37a1d52a6ec not-for-merge branch 'testcommit4891' of github.com:jantman/gitpython_issue_301 -97b84b21639efa5b35774d7e29e8e74155c71b0d not-for-merge branch 'testcommit4892' of github.com:jantman/gitpython_issue_301 -881a573148d1d94fa26b5eb25712784f8d3303f5 not-for-merge branch 'testcommit4893' of github.com:jantman/gitpython_issue_301 -4c9274d49966a9e86eb41a08742669151d9fefcf not-for-merge branch 'testcommit4894' of github.com:jantman/gitpython_issue_301 -87a7e344afe99ff34b85c71181329dc27a0d7832 not-for-merge branch 'testcommit4895' of github.com:jantman/gitpython_issue_301 -1470f6be4490d07647887f7bb75c82d71d027099 not-for-merge branch 'testcommit4896' of github.com:jantman/gitpython_issue_301 -23fad48425144e68c6bdfcc2ecc46ab456ae79fa not-for-merge branch 'testcommit4897' of github.com:jantman/gitpython_issue_301 -6ed3cd5f43f57751f9d05916a888e3077bc21266 not-for-merge branch 'testcommit4898' of github.com:jantman/gitpython_issue_301 -f9f104267a5a3d39f72a8619dc1542329dfb17d3 not-for-merge branch 'testcommit4899' of github.com:jantman/gitpython_issue_301 -510985b3b3736e6a7aa936d7df07593fff9d81fd not-for-merge branch 'testcommit49' of github.com:jantman/gitpython_issue_301 -b62a7ede2089094e8d70fda99926914216f961ce not-for-merge branch 'testcommit490' of github.com:jantman/gitpython_issue_301 -b0c90df5719181b894964f67b1fd154d7f476338 not-for-merge branch 'testcommit4900' of github.com:jantman/gitpython_issue_301 -8f911ad4e49577bbe144de655eab517407d16af6 not-for-merge branch 'testcommit4901' of github.com:jantman/gitpython_issue_301 -f8dcf44b3aedf81229c77218de6c35fa84285a95 not-for-merge branch 'testcommit4902' of github.com:jantman/gitpython_issue_301 -02cd7055c67b2f497c731e99ed0e410ea6ecaf88 not-for-merge branch 'testcommit4903' of github.com:jantman/gitpython_issue_301 -4eb23a530cf38f5bf30b65b049b6f7e1dd2033be not-for-merge branch 'testcommit4904' of github.com:jantman/gitpython_issue_301 -12a5c2302ce9d0bdec0f2bd1b4ffab4446ec7989 not-for-merge branch 'testcommit4905' of github.com:jantman/gitpython_issue_301 -e5c023dbde8fd11c5cda079e13035b1c32c8172e not-for-merge branch 'testcommit4906' of github.com:jantman/gitpython_issue_301 -c64de60a6362eb58b6effe036b75cd5fc80cb29e not-for-merge branch 'testcommit4907' of github.com:jantman/gitpython_issue_301 -47d393f16644c887effc011f1637235bf3a3819f not-for-merge branch 'testcommit4908' of github.com:jantman/gitpython_issue_301 -cde42e18fc0b7854348eaec06dc8d41e2597950d not-for-merge branch 'testcommit4909' of github.com:jantman/gitpython_issue_301 -7470b36ca9a524dcec6419b2e18796afe004fbb7 not-for-merge branch 'testcommit491' of github.com:jantman/gitpython_issue_301 -505a03c18ceb3436ecb2c1c524c78862f624c5c2 not-for-merge branch 'testcommit4910' of github.com:jantman/gitpython_issue_301 -edb075b9b53bdcb9b2cbcf53bc145fa21397875a not-for-merge branch 'testcommit4911' of github.com:jantman/gitpython_issue_301 -64e2cb11ee2a2bbf32c8a254e3e24eaf6547e1c1 not-for-merge branch 'testcommit4912' of github.com:jantman/gitpython_issue_301 -4cafee368fb00cd5a7e16861bb38d472caa2092d not-for-merge branch 'testcommit4913' of github.com:jantman/gitpython_issue_301 -bc63bdf115ae89edf0c53eb07300ed5386c91df9 not-for-merge branch 'testcommit4914' of github.com:jantman/gitpython_issue_301 -01edede31d3e2aa6435169a4ab5469ef5f829674 not-for-merge branch 'testcommit4915' of github.com:jantman/gitpython_issue_301 -1e289687c17dc72840499d7deab12c13c20b1e75 not-for-merge branch 'testcommit4916' of github.com:jantman/gitpython_issue_301 -09b3ce01787c63313cb557cc27bbd71d108c7f74 not-for-merge branch 'testcommit4917' of github.com:jantman/gitpython_issue_301 -4341625b504b8e93a156d4845e430074fe744e85 not-for-merge branch 'testcommit4918' of github.com:jantman/gitpython_issue_301 -a08ca860031c33a0a63912295ab40f4f82d98dd7 not-for-merge branch 'testcommit4919' of github.com:jantman/gitpython_issue_301 -bf4d928c94c62b6b8519c9a40bd32a9e629fa3a8 not-for-merge branch 'testcommit492' of github.com:jantman/gitpython_issue_301 -3ebcfd4634d4ed735b9328a192665d6d49fdd4db not-for-merge branch 'testcommit4920' of github.com:jantman/gitpython_issue_301 -08dd7f6b68635be0c84d6c52a20bcd0ef926c98d not-for-merge branch 'testcommit4921' of github.com:jantman/gitpython_issue_301 -f9515f6b4f521e8e1b56bd742b9c983b543ca9b7 not-for-merge branch 'testcommit4922' of github.com:jantman/gitpython_issue_301 -ef15057d82e6c53b4cd8ad1c8c503537aba98a17 not-for-merge branch 'testcommit4923' of github.com:jantman/gitpython_issue_301 -30942a7d1b72fcf82af83a7a4bace86a254d7028 not-for-merge branch 'testcommit4924' of github.com:jantman/gitpython_issue_301 -2dd9f9c9b24a8e4108e26a78aacd00b8ddca81ee not-for-merge branch 'testcommit4925' of github.com:jantman/gitpython_issue_301 -81ccacd1977d04ae7fad875c880a2f573c38fe39 not-for-merge branch 'testcommit4926' of github.com:jantman/gitpython_issue_301 -22af7cbf1a22a682ed1ed873a606b551f7e178ad not-for-merge branch 'testcommit4927' of github.com:jantman/gitpython_issue_301 -38df393b8ea7f866715de2e7b7cbc5f3764b1e12 not-for-merge branch 'testcommit4928' of github.com:jantman/gitpython_issue_301 -76ffa8b708a880151f8963008fe7adb3b8706c8f not-for-merge branch 'testcommit4929' of github.com:jantman/gitpython_issue_301 -b1921c9a6ab3459cce4da6f14eca55fb8be49b85 not-for-merge branch 'testcommit493' of github.com:jantman/gitpython_issue_301 -9941d21519390af85dc48fba4487457f2ee0fdd5 not-for-merge branch 'testcommit4930' of github.com:jantman/gitpython_issue_301 -dbe3693634c4774007c4938d947e1d38908de0f3 not-for-merge branch 'testcommit4931' of github.com:jantman/gitpython_issue_301 -3c62b047e45d8199841c7a79fd4b6d93e79ed5b1 not-for-merge branch 'testcommit4932' of github.com:jantman/gitpython_issue_301 -d55ea1ef07eddf7685979bf18a79f2d343fea7be not-for-merge branch 'testcommit4933' of github.com:jantman/gitpython_issue_301 -a80b3e2917f7c65e62c56abd2efbd9d9be178430 not-for-merge branch 'testcommit4934' of github.com:jantman/gitpython_issue_301 -1d920f054f6beff2af672d7f8cdc55505330db63 not-for-merge branch 'testcommit4935' of github.com:jantman/gitpython_issue_301 -20fb10bd60a9686bb0abffbf8f66d04fea0ad507 not-for-merge branch 'testcommit4936' of github.com:jantman/gitpython_issue_301 -fcb7919ba53f4ad1f324ee4f1be04f67e3e46e10 not-for-merge branch 'testcommit4937' of github.com:jantman/gitpython_issue_301 -f0e86927244e12669680f385531a2bc304a59518 not-for-merge branch 'testcommit4938' of github.com:jantman/gitpython_issue_301 -75896e016ad72b90b24f961ef1985012c8ad8762 not-for-merge branch 'testcommit4939' of github.com:jantman/gitpython_issue_301 -390507d7e39eee72b5f2b2101ef2d967b42f075f not-for-merge branch 'testcommit494' of github.com:jantman/gitpython_issue_301 -7ee2850f04ef65362d847863be485e8c20545762 not-for-merge branch 'testcommit4940' of github.com:jantman/gitpython_issue_301 -b7df9ebd0c9d6c1ad87230cb40cfd7304ef0ded1 not-for-merge branch 'testcommit4941' of github.com:jantman/gitpython_issue_301 -9878c4c3fb20944ac0d1ae5f96602877e2b4d08e not-for-merge branch 'testcommit4942' of github.com:jantman/gitpython_issue_301 -3424a1f5b5882870bcd6f71e49c3cb27e18784b0 not-for-merge branch 'testcommit4943' of github.com:jantman/gitpython_issue_301 -b4d4c5ddf380e01cc9feb30b0647eb6fbd6cfccb not-for-merge branch 'testcommit4944' of github.com:jantman/gitpython_issue_301 -cf4fe699dc4b659ddc9d35f834098c38b3334cd8 not-for-merge branch 'testcommit4945' of github.com:jantman/gitpython_issue_301 -08e09d0c2f08bf046503b14f4226c829996f3135 not-for-merge branch 'testcommit4946' of github.com:jantman/gitpython_issue_301 -7b1d18fe6627a0f9bb90773c1ecd1e4f64ba6064 not-for-merge branch 'testcommit4947' of github.com:jantman/gitpython_issue_301 -c1d6e6a442ed1fc304be05d7480c01fb446b7603 not-for-merge branch 'testcommit4948' of github.com:jantman/gitpython_issue_301 -cb6fdbad7108957255ca8bc5e162802256d65b73 not-for-merge branch 'testcommit4949' of github.com:jantman/gitpython_issue_301 -74141456452fe752112ac1d66c25cc89e5f2b082 not-for-merge branch 'testcommit495' of github.com:jantman/gitpython_issue_301 -41921333290e8ae60fd848ca3529a129a253809a not-for-merge branch 'testcommit4950' of github.com:jantman/gitpython_issue_301 -a485519d33d2d3b7a424c110b840e1b0f3aa8e56 not-for-merge branch 'testcommit4951' of github.com:jantman/gitpython_issue_301 -c5799d2d7d33331d9ec876c0964ededc709732b6 not-for-merge branch 'testcommit4952' of github.com:jantman/gitpython_issue_301 -aec9836dfd342122e9a0717adda03cf3f2fa4b8b not-for-merge branch 'testcommit4953' of github.com:jantman/gitpython_issue_301 -e9a21002eea37fc3f98002e86ccc40caeb5d4dce not-for-merge branch 'testcommit4954' of github.com:jantman/gitpython_issue_301 -1aa4c09befb791462efe82b481a18b3f5eefb116 not-for-merge branch 'testcommit4955' of github.com:jantman/gitpython_issue_301 -dffe42675a59129b633495a46845c931bf7a7ccf not-for-merge branch 'testcommit4956' of github.com:jantman/gitpython_issue_301 -7c14bfd07f747f60b3fc9870bd7ef3037d012d5d not-for-merge branch 'testcommit4957' of github.com:jantman/gitpython_issue_301 -7a7504d112cc70b71b9167a084ddd068a7648e3e not-for-merge branch 'testcommit4958' of github.com:jantman/gitpython_issue_301 -e3933682182c315a2c813c56d28f555d1730f8c5 not-for-merge branch 'testcommit4959' of github.com:jantman/gitpython_issue_301 -f0c5eaf14ba0a996da7a61c2af2b12727095249f not-for-merge branch 'testcommit496' of github.com:jantman/gitpython_issue_301 -d8d4eb198ec22bfcd0553f90199e67ee41079a53 not-for-merge branch 'testcommit4960' of github.com:jantman/gitpython_issue_301 -9ced83c7c64c19c9a44f9af3b1411cdac9a497cf not-for-merge branch 'testcommit4961' of github.com:jantman/gitpython_issue_301 -e5ad44e062e68856fc5a503abe5da0acee56bda5 not-for-merge branch 'testcommit4962' of github.com:jantman/gitpython_issue_301 -8c5f593cc20b060a0685c181f6d64b3dd8049671 not-for-merge branch 'testcommit4963' of github.com:jantman/gitpython_issue_301 -e8ed0f7c052a83e342ab881e082d09e0f892d0d0 not-for-merge branch 'testcommit4964' of github.com:jantman/gitpython_issue_301 -0309f8820c5e0d23684452fa6f760bd4845d4592 not-for-merge branch 'testcommit4965' of github.com:jantman/gitpython_issue_301 -625a9e136da4ef4129b7ee87e648687628f4106a not-for-merge branch 'testcommit4966' of github.com:jantman/gitpython_issue_301 -a7bef094d0e7d74052135daea1389c21845f04c9 not-for-merge branch 'testcommit4967' of github.com:jantman/gitpython_issue_301 -b8109f706c5111d956df68e00a5bb278fed7c0e4 not-for-merge branch 'testcommit4968' of github.com:jantman/gitpython_issue_301 -2f9f9e14818f891b4dda4d7c74753fb4bcebc31a not-for-merge branch 'testcommit4969' of github.com:jantman/gitpython_issue_301 -2d9f0516c5518662fb5371918b46cf0802b3f8f1 not-for-merge branch 'testcommit497' of github.com:jantman/gitpython_issue_301 -49171969b21cff5d9736e1e381e06725ecd7ffc0 not-for-merge branch 'testcommit4970' of github.com:jantman/gitpython_issue_301 -f3b7d8a1bb36be7a57cfea02836c7b0438453c23 not-for-merge branch 'testcommit4971' of github.com:jantman/gitpython_issue_301 -c9ca82918218a667a129ebe6b7c82ab8b6768957 not-for-merge branch 'testcommit4972' of github.com:jantman/gitpython_issue_301 -fce87465dfa60cbda3467c72280142e3431569d1 not-for-merge branch 'testcommit4973' of github.com:jantman/gitpython_issue_301 -1361add13ade248c688421fb21ee93e7349f0f57 not-for-merge branch 'testcommit4974' of github.com:jantman/gitpython_issue_301 -a525eb62e3fb0f5b02d02d9c5e08aa985e3ec4a4 not-for-merge branch 'testcommit4975' of github.com:jantman/gitpython_issue_301 -5c96c2ad6b52efb59dd67e31364a3ee7cdc6bc8b not-for-merge branch 'testcommit4976' of github.com:jantman/gitpython_issue_301 -8c6db17d2fb4375d474831eb64dd0f9077f7e4cd not-for-merge branch 'testcommit4977' of github.com:jantman/gitpython_issue_301 -768352aab53ad82ca18bc447f260e7a91653d871 not-for-merge branch 'testcommit4978' of github.com:jantman/gitpython_issue_301 -8de9bb7e988981e107b5b7e5705531ea0ad874ea not-for-merge branch 'testcommit4979' of github.com:jantman/gitpython_issue_301 -d82cacaaa7bbdc05b5a469f64807304c828f52b8 not-for-merge branch 'testcommit498' of github.com:jantman/gitpython_issue_301 -6bdb3a36ad45177343c22a40a258a8a3d4caf2bf not-for-merge branch 'testcommit4980' of github.com:jantman/gitpython_issue_301 -e88a90335164f81f77146852a6f6826bc39ca673 not-for-merge branch 'testcommit4981' of github.com:jantman/gitpython_issue_301 -fcc4b30a5cd6a021214ff077f050d497a628cace not-for-merge branch 'testcommit4982' of github.com:jantman/gitpython_issue_301 -1aee91c37e5c6ee5d459c59098195b9934d91d56 not-for-merge branch 'testcommit4983' of github.com:jantman/gitpython_issue_301 -91de3b74af2bbccd42fda1761321e74308daeb2d not-for-merge branch 'testcommit4984' of github.com:jantman/gitpython_issue_301 -c265f38a5a77c17cb6987d3cb391a549e5c470a1 not-for-merge branch 'testcommit4985' of github.com:jantman/gitpython_issue_301 -ba257d81a3e7c073ac07eceab83ce5e7360c0236 not-for-merge branch 'testcommit4986' of github.com:jantman/gitpython_issue_301 -7bacc8b4763735478b5924850182d2762956110f not-for-merge branch 'testcommit4987' of github.com:jantman/gitpython_issue_301 -403850a4dc94c3e5686817f02c6e5310930da393 not-for-merge branch 'testcommit4988' of github.com:jantman/gitpython_issue_301 -15675dfe8634132555b65115c507839e6f63630f not-for-merge branch 'testcommit4989' of github.com:jantman/gitpython_issue_301 -8ab258f6673859db350c50a183397e2e7813658a not-for-merge branch 'testcommit499' of github.com:jantman/gitpython_issue_301 -8f88e38717432f523424e6e26b53f91284514c77 not-for-merge branch 'testcommit4990' of github.com:jantman/gitpython_issue_301 -33e71cec8ab3feeb54ac6965f89b46d2e5b7fde6 not-for-merge branch 'testcommit4991' of github.com:jantman/gitpython_issue_301 -ac8323730e106c430c3d2f654cdefe985ccf5120 not-for-merge branch 'testcommit4992' of github.com:jantman/gitpython_issue_301 -d11cd1b1d61b266559a564f214beee53216dfeac not-for-merge branch 'testcommit4993' of github.com:jantman/gitpython_issue_301 -7f36afe04c62053ed4538287a15191a9835e7a6b not-for-merge branch 'testcommit4994' of github.com:jantman/gitpython_issue_301 -439080bc1fefd57c6f0482119c6cc50ad661039b not-for-merge branch 'testcommit4995' of github.com:jantman/gitpython_issue_301 -5ef621199ec49bd83a6e92785fb003e771c13fa3 not-for-merge branch 'testcommit4996' of github.com:jantman/gitpython_issue_301 -253ae37f21d634ce195ea9732fb8297589842343 not-for-merge branch 'testcommit4997' of github.com:jantman/gitpython_issue_301 -cad2b6270c8f1581eed475980ef507c1c13c56a4 not-for-merge branch 'testcommit4998' of github.com:jantman/gitpython_issue_301 -ffdc41e0afb01d52b3852b0e852eaa2b1714f4d0 not-for-merge branch 'testcommit4999' of github.com:jantman/gitpython_issue_301 -0af5eb0bf5e860a073289c639e38da341d34f3a1 not-for-merge branch 'testcommit5' of github.com:jantman/gitpython_issue_301 -1fb8e354a8f17b5560d571dbec3d2d04630e5db1 not-for-merge branch 'testcommit50' of github.com:jantman/gitpython_issue_301 -fd22aff054f025dc2d08c6a7007c82f3f693a8f2 not-for-merge branch 'testcommit500' of github.com:jantman/gitpython_issue_301 -04636ad640661ce6da5fe153c8ae6ca3813e6426 not-for-merge branch 'testcommit5000' of github.com:jantman/gitpython_issue_301 -3929eee257dd1ce763a485f6bd4196f1fcd8b4e7 not-for-merge branch 'testcommit501' of github.com:jantman/gitpython_issue_301 -0c7b386757f4bcee9015f155303a05bc6096649f not-for-merge branch 'testcommit502' of github.com:jantman/gitpython_issue_301 -cff890adce4a8093d07cd7b42460e9ef4df4eda9 not-for-merge branch 'testcommit503' of github.com:jantman/gitpython_issue_301 -a634d5bc948136bafe7fc03675c32d05bf146572 not-for-merge branch 'testcommit504' of github.com:jantman/gitpython_issue_301 -48a4c5c26662ed94020aeb235da3e6af7b22599f not-for-merge branch 'testcommit505' of github.com:jantman/gitpython_issue_301 -42296adaafec37ddb1c14e836d620df8d2572518 not-for-merge branch 'testcommit506' of github.com:jantman/gitpython_issue_301 -f5e40a173c9f079d03835876a643912452b4c018 not-for-merge branch 'testcommit507' of github.com:jantman/gitpython_issue_301 -b6ccf0b2f15b95166e2b7437bee335a9aa12c892 not-for-merge branch 'testcommit508' of github.com:jantman/gitpython_issue_301 -9ca0c55f8634e4a6819b9c0a8b10cea828fc5fa8 not-for-merge branch 'testcommit509' of github.com:jantman/gitpython_issue_301 -fc903beeec26eaabd0d28193e63129513bc9b1ef not-for-merge branch 'testcommit51' of github.com:jantman/gitpython_issue_301 -549bc6ad6187fccb869d0a6168e372d77b3c696e not-for-merge branch 'testcommit510' of github.com:jantman/gitpython_issue_301 -7dc4bf2f183fc345eccf61ca3e050f986eea0094 not-for-merge branch 'testcommit511' of github.com:jantman/gitpython_issue_301 -92dc359a7c15710db9c6307ed108cfd25b5800c2 not-for-merge branch 'testcommit512' of github.com:jantman/gitpython_issue_301 -608862086a7900b0fad50d0e45ad97f87678d931 not-for-merge branch 'testcommit513' of github.com:jantman/gitpython_issue_301 -da45b6f208df454874278564dd2853d1d090b9b4 not-for-merge branch 'testcommit514' of github.com:jantman/gitpython_issue_301 -efd4a8e69a5c96e76bec21183badc484df531d75 not-for-merge branch 'testcommit515' of github.com:jantman/gitpython_issue_301 -290ac4347c0620f9b1bdc13af9bec52c4b9bce92 not-for-merge branch 'testcommit516' of github.com:jantman/gitpython_issue_301 -a3e1468127ebf8d3f76a9be87bfb690a39e50d33 not-for-merge branch 'testcommit517' of github.com:jantman/gitpython_issue_301 -d24f5b78937f500b6fd700ff1a95da9abe80e1b2 not-for-merge branch 'testcommit518' of github.com:jantman/gitpython_issue_301 -4f68836e2cf25f0b7268e2456470f20f13f11ce0 not-for-merge branch 'testcommit519' of github.com:jantman/gitpython_issue_301 -c6c5525727411cc9d78a0c2f4eaa242a1eaff6a6 not-for-merge branch 'testcommit52' of github.com:jantman/gitpython_issue_301 -a16823103b345e75fd2b925d5c88998964301464 not-for-merge branch 'testcommit520' of github.com:jantman/gitpython_issue_301 -4e9bad0fbd35ec4ee5b0cb43b295d7f47a4e2fad not-for-merge branch 'testcommit521' of github.com:jantman/gitpython_issue_301 -1b8e4e40e281111fff8fa688dde16c9b21fccb79 not-for-merge branch 'testcommit522' of github.com:jantman/gitpython_issue_301 -faa559598c05e004bc8c14ce340f1f0943d65798 not-for-merge branch 'testcommit523' of github.com:jantman/gitpython_issue_301 -1a09317cb738b86360b10ebfc42bbdcba466836b not-for-merge branch 'testcommit524' of github.com:jantman/gitpython_issue_301 -ccbb2cae977d819f4ee64c428eb23e1aa3c98e03 not-for-merge branch 'testcommit525' of github.com:jantman/gitpython_issue_301 -4aeb01401bcc82f1c6e13ec41f8bcf1868de4985 not-for-merge branch 'testcommit526' of github.com:jantman/gitpython_issue_301 -232e5c35ba73a63ef3f323e0306a27081c05043e not-for-merge branch 'testcommit527' of github.com:jantman/gitpython_issue_301 -c113f691326df97ccb2a96c1e9e21495e26adf83 not-for-merge branch 'testcommit528' of github.com:jantman/gitpython_issue_301 -95815a91bba0b0150c2861018d415006b77ad3ab not-for-merge branch 'testcommit529' of github.com:jantman/gitpython_issue_301 -8c5f53ec252f99eab16c4dc16573ea86e2b000bc not-for-merge branch 'testcommit53' of github.com:jantman/gitpython_issue_301 -40b05a4150f165baf5556e2a1f017306c1da68fc not-for-merge branch 'testcommit530' of github.com:jantman/gitpython_issue_301 -842a153e392ac2d58d24d965610560d85f05ca88 not-for-merge branch 'testcommit531' of github.com:jantman/gitpython_issue_301 -98bf19f982d19ad49f93141c940a75ac931888b9 not-for-merge branch 'testcommit532' of github.com:jantman/gitpython_issue_301 -1b3ba5d70b3b3c8a8fd263903ab349715bbd083f not-for-merge branch 'testcommit533' of github.com:jantman/gitpython_issue_301 -2e4e1150cb18211efb7f7552e7c098c3753b4df3 not-for-merge branch 'testcommit534' of github.com:jantman/gitpython_issue_301 -109fa8326711aa79eae84794450757926f007318 not-for-merge branch 'testcommit535' of github.com:jantman/gitpython_issue_301 -83fe1411a6672c06019b22e8e50b792c2735812f not-for-merge branch 'testcommit536' of github.com:jantman/gitpython_issue_301 -da93f0e7fdc10602ef1d7fed03212b30fc6e25d3 not-for-merge branch 'testcommit537' of github.com:jantman/gitpython_issue_301 -b853d2d294410257a1984e3e89113b0e96e6e276 not-for-merge branch 'testcommit538' of github.com:jantman/gitpython_issue_301 -18144d3fdd17179a114bdbcff740c2aa2e72fb20 not-for-merge branch 'testcommit539' of github.com:jantman/gitpython_issue_301 -aeddcc2e051bcfe91963177f4c47dedea3d5659e not-for-merge branch 'testcommit54' of github.com:jantman/gitpython_issue_301 -d3d23bb86d17a6c2c1128df796a110f6ebdaea7c not-for-merge branch 'testcommit540' of github.com:jantman/gitpython_issue_301 -d051497d104640e63aed0227d1fe354506e14b7d not-for-merge branch 'testcommit541' of github.com:jantman/gitpython_issue_301 -0a54721efde832ec7f63fb6afd7afe82abd909ef not-for-merge branch 'testcommit542' of github.com:jantman/gitpython_issue_301 -c87152b239b6753efb165bf3457b81578790d561 not-for-merge branch 'testcommit543' of github.com:jantman/gitpython_issue_301 -7c51b7a83e795fdee8f3bd2b954d46787d7ed51a not-for-merge branch 'testcommit544' of github.com:jantman/gitpython_issue_301 -5ec95a8439bdf6cec8cbcdb3a9e19f899e6f669e not-for-merge branch 'testcommit545' of github.com:jantman/gitpython_issue_301 -40ddbd74f4d0247f923d28c459d0b007ed3cd116 not-for-merge branch 'testcommit546' of github.com:jantman/gitpython_issue_301 -5012509bc27d70ff08efbf290adeba9e5d799846 not-for-merge branch 'testcommit547' of github.com:jantman/gitpython_issue_301 -cb2f62728416f722c48a2d90345a92b394ac4131 not-for-merge branch 'testcommit548' of github.com:jantman/gitpython_issue_301 -ccf0eb3000490a6dab1bb461e49ce482104a9e26 not-for-merge branch 'testcommit549' of github.com:jantman/gitpython_issue_301 -4725bb980022f82f23029db5401951c067962d38 not-for-merge branch 'testcommit55' of github.com:jantman/gitpython_issue_301 -758ba44750649e5635935190e5a66ffdf6a6466f not-for-merge branch 'testcommit550' of github.com:jantman/gitpython_issue_301 -25e56c767e903f2d78ba010cc6ff92c6685d3276 not-for-merge branch 'testcommit551' of github.com:jantman/gitpython_issue_301 -250e57aeb90507b7077c4df6f703dfdadcf0eae3 not-for-merge branch 'testcommit552' of github.com:jantman/gitpython_issue_301 -24ce7c0bdb3fbe6d574c252ed90b17805f461550 not-for-merge branch 'testcommit553' of github.com:jantman/gitpython_issue_301 -52e70454ccc5d47d414348b1b356ebf5cf3757b2 not-for-merge branch 'testcommit554' of github.com:jantman/gitpython_issue_301 -060a2f2ab23ac4d65d4e8e23f5ca02e84b17ce99 not-for-merge branch 'testcommit555' of github.com:jantman/gitpython_issue_301 -623d550c93b4cd6b3f483ab69526a44616d5c675 not-for-merge branch 'testcommit556' of github.com:jantman/gitpython_issue_301 -0c73d52d2b28045f1bcc06a5ab9be45541b44b15 not-for-merge branch 'testcommit557' of github.com:jantman/gitpython_issue_301 -123daf9efaadb9f7a0bc5f2e22aa9800770ab217 not-for-merge branch 'testcommit558' of github.com:jantman/gitpython_issue_301 -c5c00a688df74021314e19844000093524330d03 not-for-merge branch 'testcommit559' of github.com:jantman/gitpython_issue_301 -a6769943f94459a85e67f6cfcaec1ac8bf5a455f not-for-merge branch 'testcommit56' of github.com:jantman/gitpython_issue_301 -a4d3c9a10b734479e5da1be86eff73a8efaf3b64 not-for-merge branch 'testcommit560' of github.com:jantman/gitpython_issue_301 -4e40e25f4f34d2d4dc7dc6ca154329a77119c23c not-for-merge branch 'testcommit561' of github.com:jantman/gitpython_issue_301 -f7074b88b054d426427da675bd5aa4ae2c7af74e not-for-merge branch 'testcommit562' of github.com:jantman/gitpython_issue_301 -21eec875be8bbdc0d6580e1e6d62a73c6a838694 not-for-merge branch 'testcommit563' of github.com:jantman/gitpython_issue_301 -2c8870d58f91ab55e0a1ded8af0303d841bceb60 not-for-merge branch 'testcommit564' of github.com:jantman/gitpython_issue_301 -c6828df5350f4683cc4060bf88906ee747460572 not-for-merge branch 'testcommit565' of github.com:jantman/gitpython_issue_301 -e1d3ca6b3e34875379dcde10598f2e474e11c213 not-for-merge branch 'testcommit566' of github.com:jantman/gitpython_issue_301 -1b44f6c01bc673ddf75aad6cf494f206944063f9 not-for-merge branch 'testcommit567' of github.com:jantman/gitpython_issue_301 -8019000a9c47371d46d738e07a012185676095f8 not-for-merge branch 'testcommit568' of github.com:jantman/gitpython_issue_301 -b75883f1ac14a15a19c846206fb8d02fa7e56c10 not-for-merge branch 'testcommit569' of github.com:jantman/gitpython_issue_301 -bd19a09754f2f3d4383422ae6ec6a6ad37437075 not-for-merge branch 'testcommit57' of github.com:jantman/gitpython_issue_301 -6c7dbe56d550cda42700a13c31a611b469931f3d not-for-merge branch 'testcommit570' of github.com:jantman/gitpython_issue_301 -47710b30158fe92980cb7bab9a603bc70502038e not-for-merge branch 'testcommit571' of github.com:jantman/gitpython_issue_301 -5de460892123d71d3b90b651c1c006ed545f72ea not-for-merge branch 'testcommit572' of github.com:jantman/gitpython_issue_301 -d04e1a23adc2591cef631222414e391734f162d2 not-for-merge branch 'testcommit573' of github.com:jantman/gitpython_issue_301 -c0fc4cf010f30d6c55875899129271883b804d7d not-for-merge branch 'testcommit574' of github.com:jantman/gitpython_issue_301 -6f7c42dad686367fa3cb4ea55f072e7f458d6c3f not-for-merge branch 'testcommit575' of github.com:jantman/gitpython_issue_301 -71c10a37c8331dbf8479d4cd6780f317f2567077 not-for-merge branch 'testcommit576' of github.com:jantman/gitpython_issue_301 -c27aa71279121c759585e8b6f19763feb134c25d not-for-merge branch 'testcommit577' of github.com:jantman/gitpython_issue_301 -dd1e95096c1ce19ca691de1bad5c551d05ee38ec not-for-merge branch 'testcommit578' of github.com:jantman/gitpython_issue_301 -c89a18e0ed67404d1128312f15e17338b0fdb6e5 not-for-merge branch 'testcommit579' of github.com:jantman/gitpython_issue_301 -951b8e3c1341b3a9c677409e3684bfe8ed71f816 not-for-merge branch 'testcommit58' of github.com:jantman/gitpython_issue_301 -5941df890fa59eac905a98cc06d17c812bb44a0c not-for-merge branch 'testcommit580' of github.com:jantman/gitpython_issue_301 -ad2c03d96c4952fab9d26241d8c24f3978130ee3 not-for-merge branch 'testcommit581' of github.com:jantman/gitpython_issue_301 -e4d7916d7aaef1dd5ad86b2f245fb5c4d709c1e1 not-for-merge branch 'testcommit582' of github.com:jantman/gitpython_issue_301 -95cf818ecdd5c1381169e5cd3c1b309693d24224 not-for-merge branch 'testcommit583' of github.com:jantman/gitpython_issue_301 -4deaad8fcb2504357b8239e8c36171255f4ddf13 not-for-merge branch 'testcommit584' of github.com:jantman/gitpython_issue_301 -2bf5962f48db8f1ac36aea8fc94eaf5134002ce9 not-for-merge branch 'testcommit585' of github.com:jantman/gitpython_issue_301 -567e6acedaf03e56c22e0fb15081fc9a86cff0c0 not-for-merge branch 'testcommit586' of github.com:jantman/gitpython_issue_301 -617f2fde588298dd568e858df3bda07d33889eee not-for-merge branch 'testcommit587' of github.com:jantman/gitpython_issue_301 -beab9210ce11a58172a1a6bd306cd31b95f9392a not-for-merge branch 'testcommit588' of github.com:jantman/gitpython_issue_301 -17cd07f2c17cebe35a490f38cf2cbc464099e9a1 not-for-merge branch 'testcommit589' of github.com:jantman/gitpython_issue_301 -3939908522f2ce7f5c6f295feb9160abbdaac2f7 not-for-merge branch 'testcommit59' of github.com:jantman/gitpython_issue_301 -61cc799b25a43c468f70bec3453b521eb013fc42 not-for-merge branch 'testcommit590' of github.com:jantman/gitpython_issue_301 -234800550ccbf53ebf72295e618cfd712b6e9186 not-for-merge branch 'testcommit591' of github.com:jantman/gitpython_issue_301 -46e8f8ed3c390fd78ab07cc9122c666c9f216eeb not-for-merge branch 'testcommit592' of github.com:jantman/gitpython_issue_301 -ed359344f0bde25ec903e0f15b6e9acb4ec3f676 not-for-merge branch 'testcommit593' of github.com:jantman/gitpython_issue_301 -c9ff6b3cce45b56b71510fa3e8ccd3ca88105739 not-for-merge branch 'testcommit594' of github.com:jantman/gitpython_issue_301 -bf57554e2e5f19761452bf25dc921cfed6adc3f5 not-for-merge branch 'testcommit595' of github.com:jantman/gitpython_issue_301 -d3aa5ae79085a2074b65e8fa90a5cc3dcea7453b not-for-merge branch 'testcommit596' of github.com:jantman/gitpython_issue_301 -7ca1dbca8bc643ed05ce31c226e900b8cc6df07f not-for-merge branch 'testcommit597' of github.com:jantman/gitpython_issue_301 -53ec767fa2b8d6dff7456dae62199923463b12b5 not-for-merge branch 'testcommit598' of github.com:jantman/gitpython_issue_301 -3b2a0ae920980ba80a9e0d6cb5d8b64ca566f7dc not-for-merge branch 'testcommit599' of github.com:jantman/gitpython_issue_301 -d88d5a5641ba9aaa29fa6f68a7e79840c3cbcc21 not-for-merge branch 'testcommit6' of github.com:jantman/gitpython_issue_301 -be014996a807dbaef480e269d6002e2ec00a9cd5 not-for-merge branch 'testcommit60' of github.com:jantman/gitpython_issue_301 -3dc27b539fa5f61430263ef3a5f97f5969f91f55 not-for-merge branch 'testcommit600' of github.com:jantman/gitpython_issue_301 -1fa2c894edd2b43a808f84c07aad6fa39840d986 not-for-merge branch 'testcommit601' of github.com:jantman/gitpython_issue_301 -2749624397bedbda9211c568a506438a2f73193b not-for-merge branch 'testcommit602' of github.com:jantman/gitpython_issue_301 -7f6608453db4220a304a522a37d9d4d08cad9319 not-for-merge branch 'testcommit603' of github.com:jantman/gitpython_issue_301 -60ee9dee153d6bc368fe4026bb1feb4cad1a083d not-for-merge branch 'testcommit604' of github.com:jantman/gitpython_issue_301 -341746654511f70dcb4198e55fb05b46de0b7739 not-for-merge branch 'testcommit605' of github.com:jantman/gitpython_issue_301 -4c9f8b40a4fe348313a9043635dec6e582d91f8d not-for-merge branch 'testcommit606' of github.com:jantman/gitpython_issue_301 -5e32b8056cb3c43bcc22eab931d2fd5dd25ba77f not-for-merge branch 'testcommit607' of github.com:jantman/gitpython_issue_301 -adf7c5c59ee4707f4e07592515a5efc81235a993 not-for-merge branch 'testcommit608' of github.com:jantman/gitpython_issue_301 -e7abbb6422f8a77c923b831a905d7729c0e475ef not-for-merge branch 'testcommit609' of github.com:jantman/gitpython_issue_301 -d35c8c7f4a7dd024fc4913b71e7b5b4a68cd23d3 not-for-merge branch 'testcommit61' of github.com:jantman/gitpython_issue_301 -4681d67a662852099961aecb8a56048c7485a111 not-for-merge branch 'testcommit610' of github.com:jantman/gitpython_issue_301 -31cd3cf16d09a0473b01dfabbb1982455509dc6d not-for-merge branch 'testcommit611' of github.com:jantman/gitpython_issue_301 -09d035efaebd1f36048f809a0d3e1541db0c191b not-for-merge branch 'testcommit612' of github.com:jantman/gitpython_issue_301 -cf2f3b18354a4da3c088a0be5fb150c94fd990ea not-for-merge branch 'testcommit613' of github.com:jantman/gitpython_issue_301 -b2003fac21f253ae879ed5561901ee883244feee not-for-merge branch 'testcommit614' of github.com:jantman/gitpython_issue_301 -21483f4244fec57ce9a5561efa23a34711ccfd10 not-for-merge branch 'testcommit615' of github.com:jantman/gitpython_issue_301 -e5c61f4a40f8ce4175364d67b7454007fe40f503 not-for-merge branch 'testcommit616' of github.com:jantman/gitpython_issue_301 -8f9964dfc0eb87e5bfc0c37e1ba64ed647c7adf0 not-for-merge branch 'testcommit617' of github.com:jantman/gitpython_issue_301 -0704a6e6787b35f1642f4d03f4f92ea963e6ae62 not-for-merge branch 'testcommit618' of github.com:jantman/gitpython_issue_301 -66d3d0db7781fe3a6d639edccac31aed08b18d18 not-for-merge branch 'testcommit619' of github.com:jantman/gitpython_issue_301 -18c4b2f8087520dea0c5a22729a6f7646699d75a not-for-merge branch 'testcommit62' of github.com:jantman/gitpython_issue_301 -ed7370db8f1003834aeccc722323e869937980ac not-for-merge branch 'testcommit620' of github.com:jantman/gitpython_issue_301 -eb2b560fa659f4f9a3f46460f7e0b8ca71576540 not-for-merge branch 'testcommit621' of github.com:jantman/gitpython_issue_301 -2317a512aaf6c8945c9dea3f88ca2d6ffb47aec4 not-for-merge branch 'testcommit622' of github.com:jantman/gitpython_issue_301 -8f1bece9607d3b94e96a1bc317551a89624823a4 not-for-merge branch 'testcommit623' of github.com:jantman/gitpython_issue_301 -23c5512563c9ea51e56885e7df9b3db6dd6e3f93 not-for-merge branch 'testcommit624' of github.com:jantman/gitpython_issue_301 -3f4ec629251a4493e59d809235beaf35a58609fb not-for-merge branch 'testcommit625' of github.com:jantman/gitpython_issue_301 -76a29790150998b64c36cc8a06d8c6a82239ec3f not-for-merge branch 'testcommit626' of github.com:jantman/gitpython_issue_301 -6ba7be2aa94a15e9b0b6e89ccf83d2e38a6b4265 not-for-merge branch 'testcommit627' of github.com:jantman/gitpython_issue_301 -2950b40b01bca45e525806a19b01c51e433ca61f not-for-merge branch 'testcommit628' of github.com:jantman/gitpython_issue_301 -198076834d0423635272d993985e49c8328aab29 not-for-merge branch 'testcommit629' of github.com:jantman/gitpython_issue_301 -da8138f8b88d4bf592b773d9169ff4ffc6e19cb2 not-for-merge branch 'testcommit63' of github.com:jantman/gitpython_issue_301 -73afcc153425d72a4c5ca3068b3e9ad3f2fd7b3c not-for-merge branch 'testcommit630' of github.com:jantman/gitpython_issue_301 -745827af54538ba1786b5d96872e975d1eeea5d7 not-for-merge branch 'testcommit631' of github.com:jantman/gitpython_issue_301 -e760bb7a85cbeac419da6e8fd1d5fecbd72bfbd7 not-for-merge branch 'testcommit632' of github.com:jantman/gitpython_issue_301 -12140acfea48e1288e9b6b07b1e06aec54006a4c not-for-merge branch 'testcommit633' of github.com:jantman/gitpython_issue_301 -df63decdbf3d197f22c5a6d4a2eabd8343861d60 not-for-merge branch 'testcommit634' of github.com:jantman/gitpython_issue_301 -11161362a5a6f3a4b5c7b5850c1ebcb8a8b844a0 not-for-merge branch 'testcommit635' of github.com:jantman/gitpython_issue_301 -51b76aae8bdaff7b013526ed245a2455ae5afdd7 not-for-merge branch 'testcommit636' of github.com:jantman/gitpython_issue_301 -8f6e916b4aebd572664d344b48424f514a16fde1 not-for-merge branch 'testcommit637' of github.com:jantman/gitpython_issue_301 -845122213c72d4ac4ca50363910c77081adccae5 not-for-merge branch 'testcommit638' of github.com:jantman/gitpython_issue_301 -8522f13257f677aebff24918a12e35a78e6a8de6 not-for-merge branch 'testcommit639' of github.com:jantman/gitpython_issue_301 -627cb75498069aa04b046935f6ce4b4a230e861d not-for-merge branch 'testcommit64' of github.com:jantman/gitpython_issue_301 -fbed06c60a496fe8167565e36f20f95c11b4da5a not-for-merge branch 'testcommit640' of github.com:jantman/gitpython_issue_301 -a64a21adab51312f4536d840401aa5a34c7cb432 not-for-merge branch 'testcommit641' of github.com:jantman/gitpython_issue_301 -2f48a0befc146eb65271b56d119db00feea56091 not-for-merge branch 'testcommit642' of github.com:jantman/gitpython_issue_301 -43f2d6f1fffbd20bbee16f5a3136efa0d060006c not-for-merge branch 'testcommit643' of github.com:jantman/gitpython_issue_301 -3cb0cbed1c1b12d7ffb0bd3a96f6f55872c831c3 not-for-merge branch 'testcommit644' of github.com:jantman/gitpython_issue_301 -72d15075581fb8ff95b0a21c223d9cae0b20e6ac not-for-merge branch 'testcommit645' of github.com:jantman/gitpython_issue_301 -ea8cb8da43561a36e162dbf0364f94b668825001 not-for-merge branch 'testcommit646' of github.com:jantman/gitpython_issue_301 -f28edddeaac007fdaa892aeceeb3c9f92a8b9859 not-for-merge branch 'testcommit647' of github.com:jantman/gitpython_issue_301 -1d7e581deed1f8ded19f71ebd7a81f7188483ebc not-for-merge branch 'testcommit648' of github.com:jantman/gitpython_issue_301 -5f421574215196b83f3aef58cce5325b1f88a23f not-for-merge branch 'testcommit649' of github.com:jantman/gitpython_issue_301 -76be05ba476e01d87dff2c3b3bbb22048e88abda not-for-merge branch 'testcommit65' of github.com:jantman/gitpython_issue_301 -e78d00a7f2c723c5115d648de340e41bf81bc5a8 not-for-merge branch 'testcommit650' of github.com:jantman/gitpython_issue_301 -1bd51dad748edd6449f49340612cfea775e07b36 not-for-merge branch 'testcommit651' of github.com:jantman/gitpython_issue_301 -8b9980a10f5f645c2b66e0638d3ddf4573e9ff04 not-for-merge branch 'testcommit652' of github.com:jantman/gitpython_issue_301 -88c77092a2742f4d94c02459b67c25cf39002d33 not-for-merge branch 'testcommit653' of github.com:jantman/gitpython_issue_301 -069f6767a2a2f2813b251a32d453d9f51c49c069 not-for-merge branch 'testcommit654' of github.com:jantman/gitpython_issue_301 -78be5eb31dee9f005f6196dc41a47d3cabd36cbd not-for-merge branch 'testcommit655' of github.com:jantman/gitpython_issue_301 -1ca94cac14eb3fcaa4c5aa5de00f6177f28f380a not-for-merge branch 'testcommit656' of github.com:jantman/gitpython_issue_301 -2c5a049a6b315780e9eb8cdb66742ee2f7e94ef3 not-for-merge branch 'testcommit657' of github.com:jantman/gitpython_issue_301 -df4b83ae3ddad319885558ade8153dfcca16b654 not-for-merge branch 'testcommit658' of github.com:jantman/gitpython_issue_301 -7aea97890fc97816f8ef9d234f0550ac294039e8 not-for-merge branch 'testcommit659' of github.com:jantman/gitpython_issue_301 -5c277d39a90efc5b4afaff12a1a57ef8e89b5d78 not-for-merge branch 'testcommit66' of github.com:jantman/gitpython_issue_301 -884e1c2130e34f53823d984adc12487b3f4888ee not-for-merge branch 'testcommit660' of github.com:jantman/gitpython_issue_301 -a9ee4cdd0dcd526dea8a1d53784e906b54509c84 not-for-merge branch 'testcommit661' of github.com:jantman/gitpython_issue_301 -b993dea4c36e6218fedb96991565d36b7214571d not-for-merge branch 'testcommit662' of github.com:jantman/gitpython_issue_301 -cac00eabd9979648c70ecf7971b7a9bdadaa1fbd not-for-merge branch 'testcommit663' of github.com:jantman/gitpython_issue_301 -bfe55c6d8410a108d67788d755f31ddfe08c0d73 not-for-merge branch 'testcommit664' of github.com:jantman/gitpython_issue_301 -f99661586eca2d8cf805b56e0be9650995250139 not-for-merge branch 'testcommit665' of github.com:jantman/gitpython_issue_301 -ea7e7f8fcea34f7f57cebefe192d1ae5c6960bc7 not-for-merge branch 'testcommit666' of github.com:jantman/gitpython_issue_301 -f0ef48f1a3723343854d54938be3404cdcd37a2b not-for-merge branch 'testcommit667' of github.com:jantman/gitpython_issue_301 -74fe8c675f43584cdb506926e6530eb58884cc14 not-for-merge branch 'testcommit668' of github.com:jantman/gitpython_issue_301 -ac574023ec5831f15f164e7c7815f21dd7a27358 not-for-merge branch 'testcommit669' of github.com:jantman/gitpython_issue_301 -8fb42784c9e8dbc0b2cdd94e6398e26a8f6c6f36 not-for-merge branch 'testcommit67' of github.com:jantman/gitpython_issue_301 -ad1501d79d27e570d900caaaf0709d61ae90b1ec not-for-merge branch 'testcommit670' of github.com:jantman/gitpython_issue_301 -326bd1cb5a9a166884d019ef04ffc7bed1a87a6b not-for-merge branch 'testcommit671' of github.com:jantman/gitpython_issue_301 -78f0552f7b777372751670642cd25ae9de91ee89 not-for-merge branch 'testcommit672' of github.com:jantman/gitpython_issue_301 -cfcd7c668f194678141a58ae436dfd8dc9f2b256 not-for-merge branch 'testcommit673' of github.com:jantman/gitpython_issue_301 -e6c8ff319dcdaf62f3d8018d3a6cb4cc4725035b not-for-merge branch 'testcommit674' of github.com:jantman/gitpython_issue_301 -c16b0d9209c8ca377e779015cbe9586dc5320e41 not-for-merge branch 'testcommit675' of github.com:jantman/gitpython_issue_301 -98fc552e8e2903b6c6d653d5eec5a0e574341448 not-for-merge branch 'testcommit676' of github.com:jantman/gitpython_issue_301 -16338f5805d7aed669526daab276f2e6e8c223fb not-for-merge branch 'testcommit677' of github.com:jantman/gitpython_issue_301 -dbb5253584ed1e15d2c66c0678543cce677d0ec3 not-for-merge branch 'testcommit678' of github.com:jantman/gitpython_issue_301 -3e63c8410712516148820233d33213bcea8e0ddb not-for-merge branch 'testcommit679' of github.com:jantman/gitpython_issue_301 -31f5481a21aafa64fbdcbecd340b68dc71d1ac74 not-for-merge branch 'testcommit68' of github.com:jantman/gitpython_issue_301 -a4713b2b5df4ba141e8c47c76a17bd581efe5373 not-for-merge branch 'testcommit680' of github.com:jantman/gitpython_issue_301 -6d15215387c6414ce441b897d8259f10cbd697a6 not-for-merge branch 'testcommit681' of github.com:jantman/gitpython_issue_301 -dad0e5c7f4d03a5379722a1778f23814ea8c081a not-for-merge branch 'testcommit682' of github.com:jantman/gitpython_issue_301 -05849c2a5baf4c5feae6783e5f01970ead6848ce not-for-merge branch 'testcommit683' of github.com:jantman/gitpython_issue_301 -c077a04458b1866ddde6145ffed6134ab9c29835 not-for-merge branch 'testcommit684' of github.com:jantman/gitpython_issue_301 -bafc54e5b9f1e76400f36997cedf3b1821128f71 not-for-merge branch 'testcommit685' of github.com:jantman/gitpython_issue_301 -1bd29c18d689fd51b67f0fd05972b59eb20e365c not-for-merge branch 'testcommit686' of github.com:jantman/gitpython_issue_301 -072573094d2a6c680d3a30b413a2d0efb4642b5a not-for-merge branch 'testcommit687' of github.com:jantman/gitpython_issue_301 -3e96284863d4dbf5f3c8b7131a094421fc51401d not-for-merge branch 'testcommit688' of github.com:jantman/gitpython_issue_301 -eac126d52b81365b66affd7fc9a34bbf45999113 not-for-merge branch 'testcommit689' of github.com:jantman/gitpython_issue_301 -51e19904d1cd3626b601b476c131ceb94d50fb4f not-for-merge branch 'testcommit69' of github.com:jantman/gitpython_issue_301 -96106803bb7bd6871975333d466e9e0dbc7c3045 not-for-merge branch 'testcommit690' of github.com:jantman/gitpython_issue_301 -8853692d533f739dbb55eb84246808e49f9169f1 not-for-merge branch 'testcommit691' of github.com:jantman/gitpython_issue_301 -e1190f7fdf6bb90ee5fe5a22ffcb2401efc45384 not-for-merge branch 'testcommit692' of github.com:jantman/gitpython_issue_301 -16b364efd801bd7185c61152e568c2227debb59d not-for-merge branch 'testcommit693' of github.com:jantman/gitpython_issue_301 -82fb07032592eb5e733db9d8460b990b0827873c not-for-merge branch 'testcommit694' of github.com:jantman/gitpython_issue_301 -04bbdc81ac25a5c6f3cf72ec772a15623a44b079 not-for-merge branch 'testcommit695' of github.com:jantman/gitpython_issue_301 -1c05bbbcf7571ec72897b1b4c023563c5b5e7e9a not-for-merge branch 'testcommit696' of github.com:jantman/gitpython_issue_301 -a7d383f01a4f0d1e0db8a72b30a4e09ca6eeb1ff not-for-merge branch 'testcommit697' of github.com:jantman/gitpython_issue_301 -f7c40dea2fa82c4fd7b1828886ad483c39537035 not-for-merge branch 'testcommit698' of github.com:jantman/gitpython_issue_301 -cdeb9507884b51bd3d2a1e62233bf5646ed7955e not-for-merge branch 'testcommit699' of github.com:jantman/gitpython_issue_301 -7183b4adb38d53d300d2fc415ff60b3aaf551a1a not-for-merge branch 'testcommit7' of github.com:jantman/gitpython_issue_301 -73bc7a9757a4487556e16aa997905dcf19fc3a6f not-for-merge branch 'testcommit70' of github.com:jantman/gitpython_issue_301 -1899686e3007b533f5d4d6a8c4dff48e17f7f0f3 not-for-merge branch 'testcommit700' of github.com:jantman/gitpython_issue_301 -e192639756e885dd519f421f24c9c90b3b9ac0bb not-for-merge branch 'testcommit701' of github.com:jantman/gitpython_issue_301 -9fa971b4a7280068b0bf6e83d5358f6a055cfb02 not-for-merge branch 'testcommit702' of github.com:jantman/gitpython_issue_301 -0ad2a758f289227ecbbe7d600c866a2f2e8a62ef not-for-merge branch 'testcommit703' of github.com:jantman/gitpython_issue_301 -c15718e655ef80b75ebd7f79a5a2b3f2a46824f6 not-for-merge branch 'testcommit704' of github.com:jantman/gitpython_issue_301 -b061bf5f0866a35a97230b5e33ed255cd07d2555 not-for-merge branch 'testcommit705' of github.com:jantman/gitpython_issue_301 -89a7ae7d960b83c8368eb16866ddd50208f2759a not-for-merge branch 'testcommit706' of github.com:jantman/gitpython_issue_301 -430da8812bf3b75970bfaa145a88d262a610476f not-for-merge branch 'testcommit707' of github.com:jantman/gitpython_issue_301 -c5e9864885520d4fd30d9bb2fb3230a72e5ab47a not-for-merge branch 'testcommit708' of github.com:jantman/gitpython_issue_301 -5ccb0ca0351a099e5aa85d0bbfffc5fb72f90b8c not-for-merge branch 'testcommit709' of github.com:jantman/gitpython_issue_301 -a887655df93951efdd3c087f655700eccaffa878 not-for-merge branch 'testcommit71' of github.com:jantman/gitpython_issue_301 -2fc32162cae9ba6984771d6ca640f5ad212d217e not-for-merge branch 'testcommit710' of github.com:jantman/gitpython_issue_301 -7ed10d2777cd37d93995314415b1f0e7a79bc2a6 not-for-merge branch 'testcommit711' of github.com:jantman/gitpython_issue_301 -cac7985c11aca6b76b609f3c5f46301248f69f3d not-for-merge branch 'testcommit712' of github.com:jantman/gitpython_issue_301 -ff775531dd249139228634be0fc50d235646dbe1 not-for-merge branch 'testcommit713' of github.com:jantman/gitpython_issue_301 -46fb240f08a0ebd80838621b919cce9869ba7ed8 not-for-merge branch 'testcommit714' of github.com:jantman/gitpython_issue_301 -c6045e3a04d0fecfb0ec370cbff08e42a2e52019 not-for-merge branch 'testcommit715' of github.com:jantman/gitpython_issue_301 -1fc76560fb2ee848a04e651d7bd6177c78f55395 not-for-merge branch 'testcommit716' of github.com:jantman/gitpython_issue_301 -6ec0bf73c3cbe10ed01b533e373b4939abacfee4 not-for-merge branch 'testcommit717' of github.com:jantman/gitpython_issue_301 -7457e8d1710d76639bbd4924d8977769aacc715d not-for-merge branch 'testcommit718' of github.com:jantman/gitpython_issue_301 -5626b0c7ac4c2406cc5cd8558baa4d43e505f881 not-for-merge branch 'testcommit719' of github.com:jantman/gitpython_issue_301 -9581970f260c3beb3cf2a218ddacc19bd9c0390f not-for-merge branch 'testcommit72' of github.com:jantman/gitpython_issue_301 -8896e8b56495bb6ed1bb8b0bbd21e57c55594ff1 not-for-merge branch 'testcommit720' of github.com:jantman/gitpython_issue_301 -0e7a84a5fb26a272c2155246949d24bcb9868b3d not-for-merge branch 'testcommit721' of github.com:jantman/gitpython_issue_301 -e338b95228b8195f4233406ddd2bc1cd3e4e1afa not-for-merge branch 'testcommit722' of github.com:jantman/gitpython_issue_301 -c0cdb916ead450e7736760fee86c92017eb70cf5 not-for-merge branch 'testcommit723' of github.com:jantman/gitpython_issue_301 -f74e172e0b48b4cc541abae153c3b0f81d11255e not-for-merge branch 'testcommit724' of github.com:jantman/gitpython_issue_301 -81f9cb544c58c521ef48822ebe4423268ebd3206 not-for-merge branch 'testcommit725' of github.com:jantman/gitpython_issue_301 -e15d7403a1a8a21c5b0775911a34c699f016ea52 not-for-merge branch 'testcommit726' of github.com:jantman/gitpython_issue_301 -454255b72d236615c44c8559784615ce5424c812 not-for-merge branch 'testcommit727' of github.com:jantman/gitpython_issue_301 -dac1421221409c0a47492c70a26d8e3d0f75c7e7 not-for-merge branch 'testcommit728' of github.com:jantman/gitpython_issue_301 -877b64fe21a916a7606e8d1276ccc8e2f69b6bde not-for-merge branch 'testcommit729' of github.com:jantman/gitpython_issue_301 -b8b1f22a0d63663b231d5adcf4e02def22e3719a not-for-merge branch 'testcommit73' of github.com:jantman/gitpython_issue_301 -2a1ef0e1957d32330af5115dea9b2266c556da69 not-for-merge branch 'testcommit730' of github.com:jantman/gitpython_issue_301 -3f02d23fb10197ce8dda09f759b79df5e4db3066 not-for-merge branch 'testcommit731' of github.com:jantman/gitpython_issue_301 -e190b285fa5852979953d17a8d410edfa494cc95 not-for-merge branch 'testcommit732' of github.com:jantman/gitpython_issue_301 -8ea77f78ebc4aa91df342ca471b51483a2809b0f not-for-merge branch 'testcommit733' of github.com:jantman/gitpython_issue_301 -d4ea610e186420d3b11b04d908881e30db54aa6e not-for-merge branch 'testcommit734' of github.com:jantman/gitpython_issue_301 -b1e9e6fd118ab60888da33cd86691a039bba3505 not-for-merge branch 'testcommit735' of github.com:jantman/gitpython_issue_301 -987400bab6475050e037229dc28567025ed41ea7 not-for-merge branch 'testcommit736' of github.com:jantman/gitpython_issue_301 -92da208017666e4fb16786d685693783840a2dc8 not-for-merge branch 'testcommit737' of github.com:jantman/gitpython_issue_301 -6a41b5aceaa643f771acf64f1d33e961226bae58 not-for-merge branch 'testcommit738' of github.com:jantman/gitpython_issue_301 -b394bc10d2b7f259aa33d8d8c052c9baa774e613 not-for-merge branch 'testcommit739' of github.com:jantman/gitpython_issue_301 -ce9e8f662287854b9a7191f230500acbc4cf411f not-for-merge branch 'testcommit74' of github.com:jantman/gitpython_issue_301 -89f34de2e420d6a4f65f19dd7c4cf525fba8a07e not-for-merge branch 'testcommit740' of github.com:jantman/gitpython_issue_301 -1850e93bafbe7379151bd180722d694a00d29998 not-for-merge branch 'testcommit741' of github.com:jantman/gitpython_issue_301 -19a5ca727c5e984c79cf36d3592bc143f06014b2 not-for-merge branch 'testcommit742' of github.com:jantman/gitpython_issue_301 -0c9210cea676be08d70dcfd712ba77f103ccf236 not-for-merge branch 'testcommit743' of github.com:jantman/gitpython_issue_301 -886d51b78354d463b2038bc71d9a3f0f973d7d5d not-for-merge branch 'testcommit744' of github.com:jantman/gitpython_issue_301 -59f956bf63b56eeaf4597b71893922967b28ed77 not-for-merge branch 'testcommit745' of github.com:jantman/gitpython_issue_301 -8ba24dee716331408b522a6363bba35e2e584491 not-for-merge branch 'testcommit746' of github.com:jantman/gitpython_issue_301 -26cdee6d11218df8cd489d3fe78a3320a705b3cf not-for-merge branch 'testcommit747' of github.com:jantman/gitpython_issue_301 -bdc94910d8bf361169c940505df3f38d03546efd not-for-merge branch 'testcommit748' of github.com:jantman/gitpython_issue_301 -3ed09f579117f7871ff72d8a618b7ae54e2da511 not-for-merge branch 'testcommit749' of github.com:jantman/gitpython_issue_301 -1f099be01f56caa337d1424e8f7c724ab14efcea not-for-merge branch 'testcommit75' of github.com:jantman/gitpython_issue_301 -5cd06ba8a8eb085ae5ebb6cc2022f2c27ffcc451 not-for-merge branch 'testcommit750' of github.com:jantman/gitpython_issue_301 -f4845edc84bd0e6e5fc51dde1e1826abf2b37d39 not-for-merge branch 'testcommit751' of github.com:jantman/gitpython_issue_301 -4158a930e8ef5043f7469e54aefab0b4cb1be11d not-for-merge branch 'testcommit752' of github.com:jantman/gitpython_issue_301 -793c1fb7ada7ab9d1a6f7757484d96e0877c8e73 not-for-merge branch 'testcommit753' of github.com:jantman/gitpython_issue_301 -31d307ab37d6d1a85f236c74d1abb563c4846114 not-for-merge branch 'testcommit754' of github.com:jantman/gitpython_issue_301 -dd8e37e681a66199a3fdba9895b044f6fe9c752c not-for-merge branch 'testcommit755' of github.com:jantman/gitpython_issue_301 -7e899a31ebe3c9e5c8a94c4576ae9086e695c5e2 not-for-merge branch 'testcommit756' of github.com:jantman/gitpython_issue_301 -a517467124458d1b873cf3ce4d81651c66fa8467 not-for-merge branch 'testcommit757' of github.com:jantman/gitpython_issue_301 -7480231aced2a51b29d90194208301384bc927a2 not-for-merge branch 'testcommit758' of github.com:jantman/gitpython_issue_301 -d642e1a83702107fd1d53b3e31d61e259f782b9d not-for-merge branch 'testcommit759' of github.com:jantman/gitpython_issue_301 -a96ae9402cd6e07d6aed4181b1d1b196d963f4a5 not-for-merge branch 'testcommit76' of github.com:jantman/gitpython_issue_301 -166979d272fb143b2106005e44d1325937d7e48e not-for-merge branch 'testcommit760' of github.com:jantman/gitpython_issue_301 -57a2c3d640be5e40cbf99578f232e4c7bb41d7cb not-for-merge branch 'testcommit761' of github.com:jantman/gitpython_issue_301 -a19600c5700d8f804e23188ce43f557ff63032d2 not-for-merge branch 'testcommit762' of github.com:jantman/gitpython_issue_301 -2a8e7cb5947065a0a55870e91ff758ce5bdbe2c7 not-for-merge branch 'testcommit763' of github.com:jantman/gitpython_issue_301 -9fe59bb8b02a2aa0b8fe1079eb638685c90c5c74 not-for-merge branch 'testcommit764' of github.com:jantman/gitpython_issue_301 -bcad73ce970f39347ebd7943192da4714d0c1ff3 not-for-merge branch 'testcommit765' of github.com:jantman/gitpython_issue_301 -6b265e1b81e908258b386931ad1e8e81f8d45e4e not-for-merge branch 'testcommit766' of github.com:jantman/gitpython_issue_301 -c7a07cb6a4dd4c6f049b9245bc3b919c5490d923 not-for-merge branch 'testcommit767' of github.com:jantman/gitpython_issue_301 -4434db27b53b14fbf959f9e1f02fdcd36fe31a14 not-for-merge branch 'testcommit768' of github.com:jantman/gitpython_issue_301 -6b2a85d383b56f3316093d12d9906a0f6247573b not-for-merge branch 'testcommit769' of github.com:jantman/gitpython_issue_301 -c062acc5601fa599b463d642d07317e48adbfab1 not-for-merge branch 'testcommit77' of github.com:jantman/gitpython_issue_301 -f99ccbf211c5b2f2f16426a62f1bd9dbea379cbe not-for-merge branch 'testcommit770' of github.com:jantman/gitpython_issue_301 -cd67820d2f9d38394193d893a9c82096331bcb7f not-for-merge branch 'testcommit771' of github.com:jantman/gitpython_issue_301 -c91ff851021f50244909e09346fc94221e01c323 not-for-merge branch 'testcommit772' of github.com:jantman/gitpython_issue_301 -eb99193107afabab6575e95e562c1912476d9630 not-for-merge branch 'testcommit773' of github.com:jantman/gitpython_issue_301 -b748524e74a350954eecd5acd2bcd9c124b59259 not-for-merge branch 'testcommit774' of github.com:jantman/gitpython_issue_301 -e67af751060ca25134c041876c72d48e683c3b48 not-for-merge branch 'testcommit775' of github.com:jantman/gitpython_issue_301 -7dc8c9b97ed3742c788d18313c89f200e886e41f not-for-merge branch 'testcommit776' of github.com:jantman/gitpython_issue_301 -3956f65a7571d7c2f5d1e3cf29661be5ac96af07 not-for-merge branch 'testcommit777' of github.com:jantman/gitpython_issue_301 -238f4b8f9490c19675aa8f1b6ea77b880c417399 not-for-merge branch 'testcommit778' of github.com:jantman/gitpython_issue_301 -87f45209d9940b028fd878c82412404782319955 not-for-merge branch 'testcommit779' of github.com:jantman/gitpython_issue_301 -ce18d422ff680722062ea828991c46d082c2536b not-for-merge branch 'testcommit78' of github.com:jantman/gitpython_issue_301 -daec64ad43ee1cd043480cf84abfbf5abde21503 not-for-merge branch 'testcommit780' of github.com:jantman/gitpython_issue_301 -71d94edd149a1669af2f42ef57ff1c4be554a848 not-for-merge branch 'testcommit781' of github.com:jantman/gitpython_issue_301 -77af70977625b000241f3cc70b3e04632b439e0b not-for-merge branch 'testcommit782' of github.com:jantman/gitpython_issue_301 -2044acd8aaf317b212f0647ec66c396614c86048 not-for-merge branch 'testcommit783' of github.com:jantman/gitpython_issue_301 -355c7a6bb5f38fd4de427f4af5f27bd169177384 not-for-merge branch 'testcommit784' of github.com:jantman/gitpython_issue_301 -8484dc4c34524cad0c0a015ad024a739dc94d59d not-for-merge branch 'testcommit785' of github.com:jantman/gitpython_issue_301 -ac37a36346041a279f2c6a8905d7aea552d6469d not-for-merge branch 'testcommit786' of github.com:jantman/gitpython_issue_301 -bc81c331e7c0f8ad60dde277ebefd982fe67aec6 not-for-merge branch 'testcommit787' of github.com:jantman/gitpython_issue_301 -6f74eb3284e47b22a7ffb9aa996859f49b423cb3 not-for-merge branch 'testcommit788' of github.com:jantman/gitpython_issue_301 -8e89376be1e0e2fa71ab9330b6e4bbe88663b630 not-for-merge branch 'testcommit789' of github.com:jantman/gitpython_issue_301 -547d3b7654bb21c6586f818294e97a6865af7092 not-for-merge branch 'testcommit79' of github.com:jantman/gitpython_issue_301 -1f61ac5478750f5c4cb97d51a4f7379c988466a1 not-for-merge branch 'testcommit790' of github.com:jantman/gitpython_issue_301 -7522207812d15b512013dd48fe8979cbf4859441 not-for-merge branch 'testcommit791' of github.com:jantman/gitpython_issue_301 -563959a9a8afde03c9807821b0899484a7c7e714 not-for-merge branch 'testcommit792' of github.com:jantman/gitpython_issue_301 -3ea2d3492e0df6a7ca33c99f182b809d21e5a230 not-for-merge branch 'testcommit793' of github.com:jantman/gitpython_issue_301 -7288c2e0d6eb9841dda155e34bdddea94605ccff not-for-merge branch 'testcommit794' of github.com:jantman/gitpython_issue_301 -4392e67cd444b0aa57bf952e76cd5bbc8ae29841 not-for-merge branch 'testcommit795' of github.com:jantman/gitpython_issue_301 -20194f78cc6e12eb5c8635dddb872a3cf4334a4d not-for-merge branch 'testcommit796' of github.com:jantman/gitpython_issue_301 -86b3de8a0b071e13867cede0e16b65bff18cbd86 not-for-merge branch 'testcommit797' of github.com:jantman/gitpython_issue_301 -62c6cd3dce0343368d32b7a8cb070f4bb1ebd569 not-for-merge branch 'testcommit798' of github.com:jantman/gitpython_issue_301 -c26c787fe5e2e1d8783f82ace7ec064215582205 not-for-merge branch 'testcommit799' of github.com:jantman/gitpython_issue_301 -e22365ff704d8b81a68af0149bdd1a2b5ec88109 not-for-merge branch 'testcommit8' of github.com:jantman/gitpython_issue_301 -b95f2a5c8a4dc15afe7aae95c29ef283326fe5cd not-for-merge branch 'testcommit80' of github.com:jantman/gitpython_issue_301 -be583784fd6a5ab7f87f1d13117a5f1c4abd0424 not-for-merge branch 'testcommit800' of github.com:jantman/gitpython_issue_301 -337754426fef018eab4923ca29374819264adce8 not-for-merge branch 'testcommit801' of github.com:jantman/gitpython_issue_301 -3f622f9a54ada76c6a85cc76465fee1fe97d81be not-for-merge branch 'testcommit802' of github.com:jantman/gitpython_issue_301 -4cbed8c6448c7ce8fd86d0f15e382aa2c22102e6 not-for-merge branch 'testcommit803' of github.com:jantman/gitpython_issue_301 -8f823f815655a125a7e1b1850d5e3d03077fc153 not-for-merge branch 'testcommit804' of github.com:jantman/gitpython_issue_301 -abce3b56852fb86e797ba047df312cf15d59b49a not-for-merge branch 'testcommit805' of github.com:jantman/gitpython_issue_301 -086bc8be85bbc99f2f851d3a1fdc3f8367da2399 not-for-merge branch 'testcommit806' of github.com:jantman/gitpython_issue_301 -ed8a4fee7608bdb5741e697262624dae65f07f07 not-for-merge branch 'testcommit807' of github.com:jantman/gitpython_issue_301 -6ccf8903a397c9565237763b117431016d1b35ae not-for-merge branch 'testcommit808' of github.com:jantman/gitpython_issue_301 -b01316b4523997a00ebae0c309fb53d5f1b6c857 not-for-merge branch 'testcommit809' of github.com:jantman/gitpython_issue_301 -456c75d54ca7385d900765ee15db2260e15580a6 not-for-merge branch 'testcommit81' of github.com:jantman/gitpython_issue_301 -49045cb7f6345e7fb715bcbf8a010c0d8e9ea56d not-for-merge branch 'testcommit810' of github.com:jantman/gitpython_issue_301 -2bb588a62356c2b30ac2e8ce618252d905ece92b not-for-merge branch 'testcommit811' of github.com:jantman/gitpython_issue_301 -9ad36c46ffe634096d911dd3c83e2fb6f09d3bdb not-for-merge branch 'testcommit812' of github.com:jantman/gitpython_issue_301 -470f29e406e589b8fc14ae6d3a8dc4b15e01b907 not-for-merge branch 'testcommit813' of github.com:jantman/gitpython_issue_301 -2618fcdc88feda29c8b0d11ffb40889f28707a3e not-for-merge branch 'testcommit814' of github.com:jantman/gitpython_issue_301 -c8ce90a3e686bb5a5d430cbfa76ea622988e6e50 not-for-merge branch 'testcommit815' of github.com:jantman/gitpython_issue_301 -e1f2cbb958e56f8490cc02f00086420404f94335 not-for-merge branch 'testcommit816' of github.com:jantman/gitpython_issue_301 -2a1a21ca972c7cbc22e78072657f417b9370d4f6 not-for-merge branch 'testcommit817' of github.com:jantman/gitpython_issue_301 -74fee87b0abe2b2ed07da35be4c77648e34d3eda not-for-merge branch 'testcommit818' of github.com:jantman/gitpython_issue_301 -a6c6f6b64e7633729a0d819e7b78f1b58537ea07 not-for-merge branch 'testcommit819' of github.com:jantman/gitpython_issue_301 -3b84aadc6c3ee800a72c39ac1ad2c975e923ef49 not-for-merge branch 'testcommit82' of github.com:jantman/gitpython_issue_301 -73d9510a26e2d4695b85dcbecdfe4c581c88eec3 not-for-merge branch 'testcommit820' of github.com:jantman/gitpython_issue_301 -1381c18adb0f5e5a350e25b200a7654001839f69 not-for-merge branch 'testcommit821' of github.com:jantman/gitpython_issue_301 -1fe1c0b9d2d019717391d193783beb9202fec97e not-for-merge branch 'testcommit822' of github.com:jantman/gitpython_issue_301 -e9d7dcb5c2e8e8b217d1f9ffa33ab90c55ace089 not-for-merge branch 'testcommit823' of github.com:jantman/gitpython_issue_301 -70fb2bbe50f7f32f7072a0adda6c263c313c699b not-for-merge branch 'testcommit824' of github.com:jantman/gitpython_issue_301 -a3df832a7fc2e8051c2ce2ec1eb34b458518fb1e not-for-merge branch 'testcommit825' of github.com:jantman/gitpython_issue_301 -04e6a980300fc5e78a12e98366fd0c6f037f60f3 not-for-merge branch 'testcommit826' of github.com:jantman/gitpython_issue_301 -65097224fed766e9dfaafe780eee5c3bd1ad4dff not-for-merge branch 'testcommit827' of github.com:jantman/gitpython_issue_301 -bdecb866f6e154fbd267b11fa9c1ddf9ea6633cd not-for-merge branch 'testcommit828' of github.com:jantman/gitpython_issue_301 -35f974b9ba357014f155eff8968e55b8f1ec925a not-for-merge branch 'testcommit829' of github.com:jantman/gitpython_issue_301 -2196661743c6cde6466a7fe54c6765490b34833f not-for-merge branch 'testcommit83' of github.com:jantman/gitpython_issue_301 -a9d8255cb273568fa0791f94982483a9b4bb7384 not-for-merge branch 'testcommit830' of github.com:jantman/gitpython_issue_301 -7bda83dcd876a0812b9da7d056c8bfb052cbcb29 not-for-merge branch 'testcommit831' of github.com:jantman/gitpython_issue_301 -94ce61f4fe4a67d51908cb0370a8ede163b559f1 not-for-merge branch 'testcommit832' of github.com:jantman/gitpython_issue_301 -3fe76e6b8f4835ce9bf6007a1f2a8f1f106c683c not-for-merge branch 'testcommit833' of github.com:jantman/gitpython_issue_301 -45a3ecf57ada742770e94823c1dfa76d61d26516 not-for-merge branch 'testcommit834' of github.com:jantman/gitpython_issue_301 -1ce7b8d0499ab282963a3e5d2af204631da19dfd not-for-merge branch 'testcommit835' of github.com:jantman/gitpython_issue_301 -24db116f6749039117fcf900f5ba1cbc3277a527 not-for-merge branch 'testcommit836' of github.com:jantman/gitpython_issue_301 -e02accccfe173b0bb00c23825f668ab928be6562 not-for-merge branch 'testcommit837' of github.com:jantman/gitpython_issue_301 -f48fe50fb71f0c99e728c556602cfee3d4a66676 not-for-merge branch 'testcommit838' of github.com:jantman/gitpython_issue_301 -a75c6bd3394f98e391379076426b000288961ca0 not-for-merge branch 'testcommit839' of github.com:jantman/gitpython_issue_301 -dab51e9ed7240cf0e1aa1c2e41e09512e0a0212d not-for-merge branch 'testcommit84' of github.com:jantman/gitpython_issue_301 -bc69f3990de88e9332b578df8aa5e482281e445c not-for-merge branch 'testcommit840' of github.com:jantman/gitpython_issue_301 -72292f3cec24b4fc02622bdd2504b167536892da not-for-merge branch 'testcommit841' of github.com:jantman/gitpython_issue_301 -5d2c335f11cacdef97632a8857cd94236466e10b not-for-merge branch 'testcommit842' of github.com:jantman/gitpython_issue_301 -c336aaed145dbca8df378aaa87de1e375d61f31e not-for-merge branch 'testcommit843' of github.com:jantman/gitpython_issue_301 -01e5add3f9da49312bb06dea24b1ee4b309661ad not-for-merge branch 'testcommit844' of github.com:jantman/gitpython_issue_301 -dd44113da5bc3c9db5afd60e4cdf7aabf77f13b0 not-for-merge branch 'testcommit845' of github.com:jantman/gitpython_issue_301 -f9b2e9b19e6a7ca5def62baba856eb23cf1b70df not-for-merge branch 'testcommit846' of github.com:jantman/gitpython_issue_301 -c4528bab51e8e143af02d89f1be992247a55b8ac not-for-merge branch 'testcommit847' of github.com:jantman/gitpython_issue_301 -263ebf73275454133026eaef301d2edc64def3ff not-for-merge branch 'testcommit848' of github.com:jantman/gitpython_issue_301 -9f50779d0eb726452891d41a322b4746ddbf1017 not-for-merge branch 'testcommit849' of github.com:jantman/gitpython_issue_301 -857a64baf52860c4871a5c946bbba75a70f4f2c3 not-for-merge branch 'testcommit85' of github.com:jantman/gitpython_issue_301 -192837cae9a502b486030a056d26ab079303f3f2 not-for-merge branch 'testcommit850' of github.com:jantman/gitpython_issue_301 -f116298dcecef5cb1efc05b4bddbd9de4c10141b not-for-merge branch 'testcommit851' of github.com:jantman/gitpython_issue_301 -db4b905889959bc98e7eea2bdfed2283c5c1d6f9 not-for-merge branch 'testcommit852' of github.com:jantman/gitpython_issue_301 -bb74c3344b5abfaa9324ba397d7f3240fdc48f96 not-for-merge branch 'testcommit853' of github.com:jantman/gitpython_issue_301 -4643826485e09942a1899007d4c8107d2666adc3 not-for-merge branch 'testcommit854' of github.com:jantman/gitpython_issue_301 -f75f908a38b129342700b58017933ed680fe9784 not-for-merge branch 'testcommit855' of github.com:jantman/gitpython_issue_301 -4bd9edb27bb1a60058290e51b1880ac83a6e1a23 not-for-merge branch 'testcommit856' of github.com:jantman/gitpython_issue_301 -1b6ddeff4575e6dc5c921f502394d2a98b869a57 not-for-merge branch 'testcommit857' of github.com:jantman/gitpython_issue_301 -706c0624b714ba02fcbc33fbab76c8137860d59d not-for-merge branch 'testcommit858' of github.com:jantman/gitpython_issue_301 -d9126406160c2d952c8ccb15bbd220fab3943132 not-for-merge branch 'testcommit859' of github.com:jantman/gitpython_issue_301 -4371ccd5279b6caa3650aaf096ab607a6fb32d7a not-for-merge branch 'testcommit86' of github.com:jantman/gitpython_issue_301 -5c811bb95fbd3883c15ec39e078d6a4658e2ca4c not-for-merge branch 'testcommit860' of github.com:jantman/gitpython_issue_301 -b26ae7564bfa9cac13c6b505116283c1c38cf1ec not-for-merge branch 'testcommit861' of github.com:jantman/gitpython_issue_301 -d8beba9621f6930a36278b1c12b695dafbc0080e not-for-merge branch 'testcommit862' of github.com:jantman/gitpython_issue_301 -b35b1700d020dbf197ab2d059888bb904e6ac8ad not-for-merge branch 'testcommit863' of github.com:jantman/gitpython_issue_301 -8ff06252963757a07e6cc9586081691944753618 not-for-merge branch 'testcommit864' of github.com:jantman/gitpython_issue_301 -ffb11f1630667373b452ff797d7a2f97779c4fc1 not-for-merge branch 'testcommit865' of github.com:jantman/gitpython_issue_301 -85b1806fd544a139192702b24384e60e6f4763a1 not-for-merge branch 'testcommit866' of github.com:jantman/gitpython_issue_301 -2cacf0dad6331b9d03ec4b27ba444ab4f1f3020e not-for-merge branch 'testcommit867' of github.com:jantman/gitpython_issue_301 -5873103c91ffef02f7f27f08ed9408d81260db8d not-for-merge branch 'testcommit868' of github.com:jantman/gitpython_issue_301 -25cc2a2301a25f873b64c2e7050a50f1851e4e79 not-for-merge branch 'testcommit869' of github.com:jantman/gitpython_issue_301 -43fb9d702d1ea39abb68c3932e29038a281918ae not-for-merge branch 'testcommit87' of github.com:jantman/gitpython_issue_301 -3c8bc3ba3a801d0624f4a7dcbb6b02c6cf70fd9a not-for-merge branch 'testcommit870' of github.com:jantman/gitpython_issue_301 -74fec1d315e2a22f74bab34913ee32f5d81eba22 not-for-merge branch 'testcommit871' of github.com:jantman/gitpython_issue_301 -b2ec8c6d408edc78a457775d05fcd376e819878b not-for-merge branch 'testcommit872' of github.com:jantman/gitpython_issue_301 -a259dee43dbf1c837c8db4308b833de974a10e13 not-for-merge branch 'testcommit873' of github.com:jantman/gitpython_issue_301 -92357dbe4a97256110a2fc9831d159e6cb32031d not-for-merge branch 'testcommit874' of github.com:jantman/gitpython_issue_301 -6b2329d76d3a0f310dcb38a0feb10521b28618fb not-for-merge branch 'testcommit875' of github.com:jantman/gitpython_issue_301 -be0507f5e36a8a46e72d6f0562a29b64eabd4199 not-for-merge branch 'testcommit876' of github.com:jantman/gitpython_issue_301 -d4f981b78c2c17bdeaa556ee943c6772b8160a4a not-for-merge branch 'testcommit877' of github.com:jantman/gitpython_issue_301 -531885c676fd1c29d8cf8b44919cd93509819261 not-for-merge branch 'testcommit878' of github.com:jantman/gitpython_issue_301 -38dfc4b5fa08900be867481294cb16b783c31920 not-for-merge branch 'testcommit879' of github.com:jantman/gitpython_issue_301 -9b7ffdfe4ed10799c09ab6b974e7799bad4a8845 not-for-merge branch 'testcommit88' of github.com:jantman/gitpython_issue_301 -af9727f11fb5f575858232555259c26516370a52 not-for-merge branch 'testcommit880' of github.com:jantman/gitpython_issue_301 -405787bc9202686f631f7e10d92e4f10f7db5095 not-for-merge branch 'testcommit881' of github.com:jantman/gitpython_issue_301 -27b613a73fc19c8013cfae392420de3cad34b391 not-for-merge branch 'testcommit882' of github.com:jantman/gitpython_issue_301 -a7399203b425cfa5b9cb142c83702909bb757f34 not-for-merge branch 'testcommit883' of github.com:jantman/gitpython_issue_301 -6554ab095e70116f4dd7a6476690e6b5165ce37b not-for-merge branch 'testcommit884' of github.com:jantman/gitpython_issue_301 -d34363cd1553d0c97c915e201ba5140c5abd256d not-for-merge branch 'testcommit885' of github.com:jantman/gitpython_issue_301 -2f1a8817ed3066eea7bfa1045cc983fef4a1d979 not-for-merge branch 'testcommit886' of github.com:jantman/gitpython_issue_301 -92be475c2d9fbefeeac0b252527c05b1749d39eb not-for-merge branch 'testcommit887' of github.com:jantman/gitpython_issue_301 -7451f6cba84e3dbbd917724dceafbd6d2fbce922 not-for-merge branch 'testcommit888' of github.com:jantman/gitpython_issue_301 -68841ca3d6b26ed389f0fae6e50dc17ac50fe308 not-for-merge branch 'testcommit889' of github.com:jantman/gitpython_issue_301 -df7d39fd5f4f172c40fe8d66c5a99f0565dd02c4 not-for-merge branch 'testcommit89' of github.com:jantman/gitpython_issue_301 -b6064cd192e6407c23c8205aa684a33d102349f1 not-for-merge branch 'testcommit890' of github.com:jantman/gitpython_issue_301 -c5ea72773bca57f176f6a9cfa099960e55293fcd not-for-merge branch 'testcommit891' of github.com:jantman/gitpython_issue_301 -2cbd695ccafd9b6d01e30cce08e8a98e100bbbf5 not-for-merge branch 'testcommit892' of github.com:jantman/gitpython_issue_301 -c462af6ae86b081646e8ccf25b8beed6ce6b15be not-for-merge branch 'testcommit893' of github.com:jantman/gitpython_issue_301 -7efd6d02e05b290244af6ff38d5277b5909896e7 not-for-merge branch 'testcommit894' of github.com:jantman/gitpython_issue_301 -b448349d8d8ad82a3d3c358b075cab296223b13c not-for-merge branch 'testcommit895' of github.com:jantman/gitpython_issue_301 -5a19033021213cadbe74d075149eee603e03c2fe not-for-merge branch 'testcommit896' of github.com:jantman/gitpython_issue_301 -77d42dafd2a77adbe5708f0b5720cba288c67df7 not-for-merge branch 'testcommit897' of github.com:jantman/gitpython_issue_301 -14bf733e5bf6608ec9a46f00efc21c309672f5a4 not-for-merge branch 'testcommit898' of github.com:jantman/gitpython_issue_301 -c7fafa5dc37a5d7e8eeb3b0365b0ea5ca4dd59ed not-for-merge branch 'testcommit899' of github.com:jantman/gitpython_issue_301 -ddeb69069843fb15f6b10de1dc05a3c2d8d6f7b3 not-for-merge branch 'testcommit9' of github.com:jantman/gitpython_issue_301 -db1d1aef2dfbaeab03bbf79130c1d946f76d2552 not-for-merge branch 'testcommit90' of github.com:jantman/gitpython_issue_301 -8191d99d60de3b7bff3678ea8d6329288e6deb94 not-for-merge branch 'testcommit900' of github.com:jantman/gitpython_issue_301 -870799f09a1771d4e1b14ff630d7080c1c323b80 not-for-merge branch 'testcommit901' of github.com:jantman/gitpython_issue_301 -34553a2a109de7fa7c40562be791094dc38a4ea1 not-for-merge branch 'testcommit902' of github.com:jantman/gitpython_issue_301 -80686c2fa5f4e26a3b50674fd199c144d26d57e0 not-for-merge branch 'testcommit903' of github.com:jantman/gitpython_issue_301 -c03519559b29176e1f5a253b66a09deaf013dbc1 not-for-merge branch 'testcommit904' of github.com:jantman/gitpython_issue_301 -f43d67c99625ba3503dc54edbfa4839431647491 not-for-merge branch 'testcommit905' of github.com:jantman/gitpython_issue_301 -689ffc1f1af5190b6b60900ab707ba9d037605e7 not-for-merge branch 'testcommit906' of github.com:jantman/gitpython_issue_301 -3bdfe86fa164e932ccfcc40e242eaf8d594e175f not-for-merge branch 'testcommit907' of github.com:jantman/gitpython_issue_301 -2f91a021d9c53d26e0c4fea76068896ae2958618 not-for-merge branch 'testcommit908' of github.com:jantman/gitpython_issue_301 -4a32b92cc914285aed38efa28332c0767e24406f not-for-merge branch 'testcommit909' of github.com:jantman/gitpython_issue_301 -1c477dbd6b3792daf18e066b88dce2fe74b288e0 not-for-merge branch 'testcommit91' of github.com:jantman/gitpython_issue_301 -9ca271b0bb951a869329642c5c60bc44fa87407d not-for-merge branch 'testcommit910' of github.com:jantman/gitpython_issue_301 -e05b6b8e5a21a81e7e70d090dde3cdbc2a5d9e8b not-for-merge branch 'testcommit911' of github.com:jantman/gitpython_issue_301 -1da90dbd26103b7db343da16c72c8b1a4ae94fb6 not-for-merge branch 'testcommit912' of github.com:jantman/gitpython_issue_301 -72bc1782f11af5400bf22a20c760e948b2bf72ef not-for-merge branch 'testcommit913' of github.com:jantman/gitpython_issue_301 -8e9d28e51744305addbbfc53e5d7feb2903b9410 not-for-merge branch 'testcommit914' of github.com:jantman/gitpython_issue_301 -994c6eb5668504424fd7a98c28cdbef37cb9ff73 not-for-merge branch 'testcommit915' of github.com:jantman/gitpython_issue_301 -569ff3f875b87899fb713eeb1e9008ea1ca041e0 not-for-merge branch 'testcommit916' of github.com:jantman/gitpython_issue_301 -ea51b9934dae7202c9abcc92b40bd68b74a22863 not-for-merge branch 'testcommit917' of github.com:jantman/gitpython_issue_301 -e1d5c68be4b10e5053458437f764bcb3a3460f28 not-for-merge branch 'testcommit918' of github.com:jantman/gitpython_issue_301 -a82eadcce378b5c5e28c5a73df00f4ca9cc8eb49 not-for-merge branch 'testcommit919' of github.com:jantman/gitpython_issue_301 -c99c941dd47de731e839f79ad8946ab4d7fc2a01 not-for-merge branch 'testcommit92' of github.com:jantman/gitpython_issue_301 -7833a3f9b0d40c883c10e60906458e95e1158167 not-for-merge branch 'testcommit920' of github.com:jantman/gitpython_issue_301 -c1ea75e900bdc5d1e2756382c7c3acfc855ddc68 not-for-merge branch 'testcommit921' of github.com:jantman/gitpython_issue_301 -d653f8b3ba76ca15f42a535ce5ea71e36734c19c not-for-merge branch 'testcommit922' of github.com:jantman/gitpython_issue_301 -01e2567f414733b5866700e40e3cc615c104fcb4 not-for-merge branch 'testcommit923' of github.com:jantman/gitpython_issue_301 -7223e84697d7aa76e4ef610ff82047658887bd3a not-for-merge branch 'testcommit924' of github.com:jantman/gitpython_issue_301 -2edcd7a4765f35d21d69f540d54dac6689b408a5 not-for-merge branch 'testcommit925' of github.com:jantman/gitpython_issue_301 -a7292b4052beddef33922bfeb945f7288f51633f not-for-merge branch 'testcommit926' of github.com:jantman/gitpython_issue_301 -5229940e781a4b24df3fe61e566f1ed0e1e719ee not-for-merge branch 'testcommit927' of github.com:jantman/gitpython_issue_301 -1a18a9623ad47a410d70950e3216ecd6d3d51cec not-for-merge branch 'testcommit928' of github.com:jantman/gitpython_issue_301 -2a2ddee059cc26fda65b888c6020d34df4d39153 not-for-merge branch 'testcommit929' of github.com:jantman/gitpython_issue_301 -3a5d7becb833f3768d2fa89e9bc11dd55691013f not-for-merge branch 'testcommit93' of github.com:jantman/gitpython_issue_301 -9de8f439bbb5c4133151dcae86172f2f0c08dcaf not-for-merge branch 'testcommit930' of github.com:jantman/gitpython_issue_301 -03ebc2491870c9edaa736730a74989b29d59ad12 not-for-merge branch 'testcommit931' of github.com:jantman/gitpython_issue_301 -5629019959fa16374908dac26f82110939a20bd9 not-for-merge branch 'testcommit932' of github.com:jantman/gitpython_issue_301 -07c2cd8af15bb63546ff1cb00a556c00addd02cb not-for-merge branch 'testcommit933' of github.com:jantman/gitpython_issue_301 -b502a556ed01876eab05543437e4ca7f16f6313a not-for-merge branch 'testcommit934' of github.com:jantman/gitpython_issue_301 -7ad8d641cfd6eb63e5bc20c8194217b972011ffd not-for-merge branch 'testcommit935' of github.com:jantman/gitpython_issue_301 -f35d4c665a07a5f3caa665317a14df107a13e8bc not-for-merge branch 'testcommit936' of github.com:jantman/gitpython_issue_301 -18298a892629335371c8d227c10838dcd097cdc0 not-for-merge branch 'testcommit937' of github.com:jantman/gitpython_issue_301 -7a2fb16ff4676731898d30b7a5680e5f36a0db18 not-for-merge branch 'testcommit938' of github.com:jantman/gitpython_issue_301 -8bc647785d3f30333835a4fd3a2b593afd959e03 not-for-merge branch 'testcommit939' of github.com:jantman/gitpython_issue_301 -88d02da30d56f223205f17745319ad470cc5e50c not-for-merge branch 'testcommit94' of github.com:jantman/gitpython_issue_301 -9e2c28704be19a06f5e537fa1027a9d16d05580e not-for-merge branch 'testcommit940' of github.com:jantman/gitpython_issue_301 -00d80aeebdc48333a6493162cc04356286c4f137 not-for-merge branch 'testcommit941' of github.com:jantman/gitpython_issue_301 -db7a4a8abdb4da8b9391654046985aba8681f5e7 not-for-merge branch 'testcommit942' of github.com:jantman/gitpython_issue_301 -f6493cf384ec938945ab03221b6a4c033ac0140f not-for-merge branch 'testcommit943' of github.com:jantman/gitpython_issue_301 -eb15f69556fb0ef743effae07f24a5f49a6bdabd not-for-merge branch 'testcommit944' of github.com:jantman/gitpython_issue_301 -7c1bd8e8476a2d4bf6f6df3f6f938ecc74411079 not-for-merge branch 'testcommit945' of github.com:jantman/gitpython_issue_301 -dab6d7eff111c750ab78417e1fee2cd3f484704f not-for-merge branch 'testcommit946' of github.com:jantman/gitpython_issue_301 -9b5e699798aecc59fdfef25bcc300e02e516903b not-for-merge branch 'testcommit947' of github.com:jantman/gitpython_issue_301 -be15cb66adf5cc5e478871d5cf45123003d6d80c not-for-merge branch 'testcommit948' of github.com:jantman/gitpython_issue_301 -041d42e3ec17eb17d40da3584e471a4817c0ac71 not-for-merge branch 'testcommit949' of github.com:jantman/gitpython_issue_301 -42f148a4d88bd9f84bd4180e6653ee95f5d66963 not-for-merge branch 'testcommit95' of github.com:jantman/gitpython_issue_301 -85067470dc6f14ceb385f1035247a6094118d222 not-for-merge branch 'testcommit950' of github.com:jantman/gitpython_issue_301 -ec6ea31822f656d4b3c9f61ab40f14fb6a18d48f not-for-merge branch 'testcommit951' of github.com:jantman/gitpython_issue_301 -34c7638ef0f83dd28a1aea94def9632ab88f6ea3 not-for-merge branch 'testcommit952' of github.com:jantman/gitpython_issue_301 -f768494abb215923b298698fb98a946ac03e1534 not-for-merge branch 'testcommit953' of github.com:jantman/gitpython_issue_301 -8b677c09d1cd1bc9e99f0b8e1d7104b04b80ad23 not-for-merge branch 'testcommit954' of github.com:jantman/gitpython_issue_301 -fb929d38cfa371beb0f82cf389548a86ae178f3b not-for-merge branch 'testcommit955' of github.com:jantman/gitpython_issue_301 -7e8b2bf8812ac582bd4ddfc3a11f54e92beabff2 not-for-merge branch 'testcommit956' of github.com:jantman/gitpython_issue_301 -e00814adbacabcc029b68ad63a6678eaec2b18d6 not-for-merge branch 'testcommit957' of github.com:jantman/gitpython_issue_301 -c709ad362edb2660bde94c535c9801de72b9f4aa not-for-merge branch 'testcommit958' of github.com:jantman/gitpython_issue_301 -e6c560ae9dbc82ddeabc37b35f9c7e769fc1b83e not-for-merge branch 'testcommit959' of github.com:jantman/gitpython_issue_301 -7350766195eb4e0efa2cdc5395476102e89e8739 not-for-merge branch 'testcommit96' of github.com:jantman/gitpython_issue_301 -1da965408f9cfbd2b0b33c70cc25ffae984cd5e6 not-for-merge branch 'testcommit960' of github.com:jantman/gitpython_issue_301 -1c6f8f8ddebc8fcfd609161fdc2857bc2df8d6c5 not-for-merge branch 'testcommit961' of github.com:jantman/gitpython_issue_301 -dac5f4787fd02377109b81d33f55f3c607f08038 not-for-merge branch 'testcommit962' of github.com:jantman/gitpython_issue_301 -c5f82782b5461a0f8f1b545bd05eca99cf2ac966 not-for-merge branch 'testcommit963' of github.com:jantman/gitpython_issue_301 -01e098c0474b1b456585567a7f59a46bcdf2852d not-for-merge branch 'testcommit964' of github.com:jantman/gitpython_issue_301 -e2379f316416cf11e02149bb837d46739fd95d66 not-for-merge branch 'testcommit965' of github.com:jantman/gitpython_issue_301 -3094f713109366bd730c62b6ea9faf89886f9c5b not-for-merge branch 'testcommit966' of github.com:jantman/gitpython_issue_301 -a2bfdf2fb5a15894d0971078397213957aac07fe not-for-merge branch 'testcommit967' of github.com:jantman/gitpython_issue_301 -3a466c2d6adfec6d43e1deaa8f224333e0278be4 not-for-merge branch 'testcommit968' of github.com:jantman/gitpython_issue_301 -9c989b9d76e9030761c88b9427fc01438a88a440 not-for-merge branch 'testcommit969' of github.com:jantman/gitpython_issue_301 -59d79380ecf45464fe0144bc9f0e099e25aa1584 not-for-merge branch 'testcommit97' of github.com:jantman/gitpython_issue_301 -008ca4360db0ada336536e3b8a652a8ffac607a2 not-for-merge branch 'testcommit970' of github.com:jantman/gitpython_issue_301 -23bf63d4060155e3931722522fd021cdebebde20 not-for-merge branch 'testcommit971' of github.com:jantman/gitpython_issue_301 -e85611780ec2757972052f1451f0b74e0285fbd7 not-for-merge branch 'testcommit972' of github.com:jantman/gitpython_issue_301 -fca57448b3409828758880d3182fb75a053b4a9b not-for-merge branch 'testcommit973' of github.com:jantman/gitpython_issue_301 -bfe65a58f4a65632c73cbe9f5546b0b41ec0d8f1 not-for-merge branch 'testcommit974' of github.com:jantman/gitpython_issue_301 -c6bcf9deb2e6eff1dc28bd2e8a0a2fccc9fa1bc3 not-for-merge branch 'testcommit975' of github.com:jantman/gitpython_issue_301 -02a2cd795746b89516269b01431ce796cfe06c40 not-for-merge branch 'testcommit976' of github.com:jantman/gitpython_issue_301 -8b18d2b77f8366c9bcdbb2caaa0040ef8b9b2931 not-for-merge branch 'testcommit977' of github.com:jantman/gitpython_issue_301 -ae908980739b37067ee02a348b313c0a3323eb5f not-for-merge branch 'testcommit978' of github.com:jantman/gitpython_issue_301 -cf7cc673d8d782e1bf3d16fc97483863a5bb5365 not-for-merge branch 'testcommit979' of github.com:jantman/gitpython_issue_301 -b0a2585798ac2ddce9402b4ce691e74835eb720b not-for-merge branch 'testcommit98' of github.com:jantman/gitpython_issue_301 -a978fc0409b6de22b8b6370096d3b90ac068192d not-for-merge branch 'testcommit980' of github.com:jantman/gitpython_issue_301 -db73a55c656fb27edf3bb185d651e1afc434a4de not-for-merge branch 'testcommit981' of github.com:jantman/gitpython_issue_301 -869e3005fcf1a31c8610bd9519aa2835d746cc52 not-for-merge branch 'testcommit982' of github.com:jantman/gitpython_issue_301 -91b2dc537d6b6b1db9b8732cce7de1e8fcb5e8d9 not-for-merge branch 'testcommit983' of github.com:jantman/gitpython_issue_301 -a6daa63e5d654891e0f349d7a2bf25b2a8a3d5ed not-for-merge branch 'testcommit984' of github.com:jantman/gitpython_issue_301 -362f670649c92e62320f7c93f8ebad6aad53e37d not-for-merge branch 'testcommit985' of github.com:jantman/gitpython_issue_301 -82a11e9226bdd02d3f25b83c1016ebe112a760b9 not-for-merge branch 'testcommit986' of github.com:jantman/gitpython_issue_301 -8213be4548925d305f1603c4ad383d54fe10a301 not-for-merge branch 'testcommit987' of github.com:jantman/gitpython_issue_301 -05ce60b3d5d7c6bfbc1e4c586ef45d24ee280d7e not-for-merge branch 'testcommit988' of github.com:jantman/gitpython_issue_301 -3b4fa29aec584fa83d99f4b05a3bd40863c41a42 not-for-merge branch 'testcommit989' of github.com:jantman/gitpython_issue_301 -69f46edc5faeadf15648f991790bd1cc6d40a7ad not-for-merge branch 'testcommit99' of github.com:jantman/gitpython_issue_301 -e0534a599e72daa8d934d99477ee4d80af670ac7 not-for-merge branch 'testcommit990' of github.com:jantman/gitpython_issue_301 -446fb5e2501d498c0b49ba3a0fc2e44a0c7cdc6e not-for-merge branch 'testcommit991' of github.com:jantman/gitpython_issue_301 -138eadf0395e5d53303c871932575211b2a81ca0 not-for-merge branch 'testcommit992' of github.com:jantman/gitpython_issue_301 -cf5652cce3d15e8dd1f108c306e0873c47b92760 not-for-merge branch 'testcommit993' of github.com:jantman/gitpython_issue_301 -e1fc3bf4a22a3cb484fb17a8a672fe0ce7d844e3 not-for-merge branch 'testcommit994' of github.com:jantman/gitpython_issue_301 -97d24159a5aeed8b1a3c5c25c4517fad4e1ca987 not-for-merge branch 'testcommit995' of github.com:jantman/gitpython_issue_301 -90ab5f7a82fb9c539b3e319db2ebb8adc9fb01f5 not-for-merge branch 'testcommit996' of github.com:jantman/gitpython_issue_301 -5dd4efeb4aa45c18d76648b3958869e2c799c4be not-for-merge branch 'testcommit997' of github.com:jantman/gitpython_issue_301 -5f48d52c7bcf27e7e48f3655022794169fe2d5b0 not-for-merge branch 'testcommit998' of github.com:jantman/gitpython_issue_301 -fe62b52ad79d032f6275227cb74782ff952e30f8 not-for-merge branch 'testcommit999' of github.com:jantman/gitpython_issue_301 diff --git a/git/test/test_git.py b/git/test/test_git.py index f7442257c..b1ffa0804 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -207,17 +207,15 @@ def test_environment(self, rw_dir): # end if select.poll exists def test_dispatch_lines(self): - for path, line_count in ((fixture_path('issue-301_stderr'), 5002), - (fixture_path('issue-301_FETCH_HEAD'), 5001)): - count = [0] - def counter(line): - count[0] += 1 - - fd = os.open(path, os.O_RDONLY) - buf_list = [b''] - lines_parsed = _deplete_buffer(fd, counter, buf_list) - os.close(fd) - - assert lines_parsed == line_count - assert count[0] == line_count - # end for each file to read + line_count = 5002 + count = [0] + def counter(line): + count[0] += 1 + + fd = os.open(fixture_path('issue-301_stderr'), os.O_RDONLY) + buf_list = [b''] + lines_parsed = _deplete_buffer(fd, counter, buf_list) + os.close(fd) + + assert lines_parsed == line_count + assert count[0] == line_count From 369e564174bfdd592d64a027bebc3f3f41ee8f11 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 15:37:29 +0200 Subject: [PATCH 0229/2790] fix(cmd): don't open stdout when fetching This allows us to use the main thread to parse stderr to get progress, and resolve assertion failures hopefully once and for all. Relates to #301 --- git/cmd.py | 155 ++++++++++++++++------------------ git/remote.py | 9 +- git/test/fixtures/cat_file.py | 5 ++ git/test/test_git.py | 32 ++++--- 4 files changed, 105 insertions(+), 96 deletions(-) create mode 100644 git/test/fixtures/cat_file.py diff --git a/git/cmd.py b/git/cmd.py index ec916d8aa..31865d090 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -41,7 +41,7 @@ execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', 'with_exceptions', 'as_process', 'stdout_as_string', - 'output_stream') + 'output_stream', 'with_stdout') log = logging.getLogger('git.cmd') log.addHandler(logging.NullHandler()) @@ -65,84 +65,6 @@ def _bchr(c): # Documentation ## @{ -def _parse_lines_from_buffer(buf): - line = b'' - bi = 0 - lb = len(buf) - while bi < lb: - char = _bchr(buf[bi]) - bi += 1 - - if char in (b'\r', b'\n') and line: - yield bi, line - line = b'' - else: - line += char - # END process parsed line - # END while file is not done reading -# end - -def _read_lines_from_fno(fno, last_buf_list): - buf = os.read(fno, mmap.PAGESIZE) - buf = last_buf_list[0] + buf - - bi = 0 - for bi, line in _parse_lines_from_buffer(buf): - yield line - # for each line to parse from the buffer - - # keep remainder - last_buf_list[0] = buf[bi:] - -def _dispatch_single_line(line, handler): - line = line.decode(defenc) - if line and handler: - try: - handler(line) - except Exception: - # Keep reading, have to pump the lines empty nontheless - log.error("Line handler exception on line: %s", line, exc_info=True) - # end - # end dispatch helper -# end single line helper - -def _dispatch_lines(fno, handler, buf_list): - lc = 0 - last_buf = buf_list[0] - while True: - for line in _read_lines_from_fno(fno, buf_list): - _dispatch_single_line(line, handler) - lc += 1 - # for each line - - if last_buf == buf_list[0]: - break - - last_buf = buf_list[0] - # end endless loop - return lc -# end - -def _deplete_buffer(fno, handler, buf_list, wg=None): - lc = 0 - while True: - line_count = _dispatch_lines(fno, handler, buf_list) - lc += line_count - if line_count == 0: - break - # end deplete buffer - - if buf_list[0]: - _dispatch_single_line(buf_list[0], handler) - lc += 1 - # end - - if wg: - wg.done() - - return lc -# end - def handle_process_output(process, stdout_handler, stderr_handler, finalizer): """Registers for notifications to lean that process output is ready to read, and dispatches lines to the respective line handlers. We are able to handle carriage returns in case progress is sent by that @@ -156,6 +78,76 @@ def handle_process_output(process, stdout_handler, stderr_handler, finalizer): fdmap = {process.stdout.fileno(): (stdout_handler, [b'']), process.stderr.fileno(): (stderr_handler, [b''])} + def _parse_lines_from_buffer(buf): + line = b'' + bi = 0 + lb = len(buf) + while bi < lb: + char = _bchr(buf[bi]) + bi += 1 + + if char in (b'\r', b'\n') and line: + yield bi, line + line = b'' + else: + line += char + # END process parsed line + # END while file is not done reading + # end + + def _read_lines_from_fno(fno, last_buf_list): + buf = os.read(fno, mmap.PAGESIZE) + buf = last_buf_list[0] + buf + + bi = 0 + for bi, line in _parse_lines_from_buffer(buf): + yield line + # for each line to parse from the buffer + + # keep remainder + last_buf_list[0] = buf[bi:] + + def _dispatch_single_line(line, handler): + line = line.decode(defenc) + if line and handler: + try: + handler(line) + except Exception: + # Keep reading, have to pump the lines empty nontheless + log.error("Line handler exception on line: %s", line, exc_info=True) + # end + # end dispatch helper + # end single line helper + + def _dispatch_lines(fno, handler, buf_list): + lc = 0 + for line in _read_lines_from_fno(fno, buf_list): + _dispatch_single_line(line, handler) + lc += 1 + # for each line + return lc + # end + + def _deplete_buffer(fno, handler, buf_list, wg=None): + lc = 0 + while True: + line_count = _dispatch_lines(fno, handler, buf_list) + lc += line_count + if line_count == 0: + break + # end deplete buffer + + if buf_list[0]: + _dispatch_single_line(buf_list[0], handler) + lc += 1 + # end + + if wg: + wg.done() + + return lc + # end + if hasattr(select, 'poll'): # poll is preferred, as select is limited to file handles up to 1024 ... . This could otherwise be # an issue for us, as it matters how many handles our own process has @@ -483,6 +475,7 @@ def execute(self, command, as_process=False, output_stream=None, stdout_as_string=True, + with_stdout=True, **subprocess_kwargs ): """Handles executing the command on the shell and consumes and returns @@ -536,6 +529,8 @@ def execute(self, command, some of the valid kwargs are already set by this method, the ones you specify may not be the same ones. + :param with_stdout: If True, default True, we open stdout on the created process + :return: * str(output) if extended_output = False (Default) * tuple(int(status), str(stdout), str(stderr)) if extended_output = True @@ -586,7 +581,7 @@ def execute(self, command, cwd=cwd, stdin=istream, stderr=PIPE, - stdout=PIPE, + stdout=with_stdout and PIPE or None, shell=self.USE_SHELL, close_fds=(os.name == 'posix'), # unsupported on windows **subprocess_kwargs diff --git a/git/remote.py b/git/remote.py index 4871ea5fc..7cb0f4f8e 100644 --- a/git/remote.py +++ b/git/remote.py @@ -550,7 +550,7 @@ def _get_fetch_info_from_stderr(self, proc, progress): progress_handler = progress.new_message_handler() - def my_progress_handler(line): + for line in proc.stderr.readlines(): for pline in progress_handler(line): if line.startswith('fatal:') or line.startswith('error:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) @@ -563,9 +563,7 @@ def my_progress_handler(line): # end for each comand code we know # end for each line progress didn't handle # end - - # We are only interested in stderr here ... - handle_process_output(proc, None, my_progress_handler, finalize_process) + finalize_process(proc) # read head information fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') @@ -651,7 +649,8 @@ def fetch(self, refspec=None, progress=None, **kwargs): else: args = [refspec] - proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, v=True, **kwargs) + proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, with_stdout=True, v=True, + **kwargs) res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() diff --git a/git/test/fixtures/cat_file.py b/git/test/fixtures/cat_file.py new file mode 100644 index 000000000..2f1b915aa --- /dev/null +++ b/git/test/fixtures/cat_file.py @@ -0,0 +1,5 @@ +import sys + +for line in open(sys.argv[1]).readlines(): + sys.stdout.write(line) + sys.stderr.write(line) diff --git a/git/test/test_git.py b/git/test/test_git.py index b1ffa0804..fe7ec9701 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -5,7 +5,9 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os +import sys import mock +import subprocess from git.test.lib import ( TestBase, @@ -22,7 +24,6 @@ GitCommandNotFound, Repo ) -from git.cmd import _deplete_buffer from gitdb.test.lib import with_rw_directory from git.compat import PY3 @@ -206,16 +207,25 @@ def test_environment(self, rw_dir): # end # end if select.poll exists - def test_dispatch_lines(self): + def test_handle_process_output(self): + from git.cmd import handle_process_output + line_count = 5002 - count = [0] - def counter(line): - count[0] += 1 + count = [None, 0, 0] + + def counter_stdout(line): + count[1] += 1 + + def counter_stderr(line): + count[2] += 1 + + proc = subprocess.Popen([sys.executable, fixture_path('cat_file.py'), str(fixture_path('issue-301_stderr'))], + stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=False) - fd = os.open(fixture_path('issue-301_stderr'), os.O_RDONLY) - buf_list = [b''] - lines_parsed = _deplete_buffer(fd, counter, buf_list) - os.close(fd) + handle_process_output(proc, counter_stdout, counter_stderr, lambda proc: proc.wait()) - assert lines_parsed == line_count - assert count[0] == line_count + assert count[1] == line_count + assert count[2] == line_count From c5a9bbef0d2d8fc5877dab55879464a13955a341 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 15:45:09 +0200 Subject: [PATCH 0230/2790] chore(travis): added test for issue 301 Related to #301 --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7aaf9f949..08eafda51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,11 +28,14 @@ install: # If we rewrite the user's config by accident, we will mess it up # and cause subsequent tests to fail - cat git/test/fixtures/.gitconfig >> ~/.gitconfig + # used later when testing for specific issue + - git clone git@github.com:gitpython-developers/gitpython_issue_301.git issue-301-repo script: # Make sure we limit open handles to see if we are leaking them - ulimit -n 96 - ulimit -n - nosetests -v --with-coverage + - '( cd issue-301-repo && PYTHONPATH=$PWD/.. ./reproduce.py )' - flake8 - cd doc && make html after_success: From 02cb16916851336fcf2778d66a6d54ee15d086d7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 16:22:19 +0200 Subject: [PATCH 0231/2790] fix(travis): assure private key has access Previously travis would fail to clone the special testing repository as SSH access requires a deploy key to be set. The latter has been configured and is now added in clear-text. This is save as it is only good for read-only access to a test repository, mis-use cannot happen that way. --- .travis.private-ssh-key-for-issue-301 | 27 +++++++++++++++++++++++++++ .travis.yml | 3 +++ 2 files changed, 30 insertions(+) create mode 100644 .travis.private-ssh-key-for-issue-301 diff --git a/.travis.private-ssh-key-for-issue-301 b/.travis.private-ssh-key-for-issue-301 new file mode 100644 index 000000000..dd9c057b9 --- /dev/null +++ b/.travis.private-ssh-key-for-issue-301 @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAu5awaLHx+F7O9gE1ac3gKztAi3OYzCS75XsUmQkjIZ+6je/3 +L+uVmtFyQ8t0PXaSF8rPBs+E35Vl1t9uz+vry7Q6bI5ClvlzaXCYHAuOqnDwrpdo +jykjKN4U0r0leDBO3rXpvjluKCGiE4pj0KgTe+xtoU4r64z7/DPQcaAmHbOFabxs +b8YZ/gHvA3vA8RA81eHWw83cw1U12dqjcE/gj6UZ0f4qj+PKQG6nfZEg6MzV71rS +wdHtCMljd4pz/3vzrCYCdl34jrzlm0lxuDbX/oMVe2OhoJAgilUQ6ieMhG0MKTr4 +Cf5LBRQGNKkuwNgj70fmsYphm3xKeehjvwxB/wIDAQABAoIBACKZkMA+0hq1ogbO +AkQZrRdMPoN6Ntywidex9AKmJMy24Xn8oOM92MJNj33hsPcFP70Ts0vWSvPSYo5X +d+Dx6vQPshcDxlSCfj8cfXHuz8mwOzR4yNhfBhUroTudl6OrhWCevRZREXhle7eO +9wotdiqNWUs/V+qCfpfuFqxelak0erSSdR4rh35uZYNBdopPiMlo8klYEDRGrH2R +LCjeOiC9pkkj7f1ylyDCjkI8hdjOnWO/QYYD7g8ZDKFwRRBm0os6d3Nj20ED7N8y +eBRBjDv6k5165MAtFmjHrO9olUh1o+2rwrYK+hVckg5uE/cv6VanRs9tRgF6TyIw +97tSeQECgYEA3yuy0aINAW+T7+3oOPuo9c6ZrBMrPTOlRJufrLS4WvV3laL/AVNt +DmKkQOjKbQI8cknlqV9CovteRT2Dj9lTZwSGmecVPijslAUmwz9s4Ucu1BR8Qckl +i470z5Fge6fdPsAYhjhqjbLUE2Lml2A/YyNnpTFSP4wXpyy6HLkT1pECgYEA1y8E +0zVlnoeHKDgpGDpmXV9YhcqtQ6Q2HC/g9oUn+jAfeYkVX8L5brUX2S4L03hYAljH +j0RJZnOZoXpN6WMRnWJkOP80Fkq5Jv6vJkghNPJ7vWtXJan4wkNr/nGQ65DvxeLJ +qIEmSe+sZHCB/W26y9bgI+ELHt4VgPuEIoGad48CgYBNza5J53UhSwUIYKjVNOdy +ytRIaWZpr9euU5MXYunizDEkue6tR6h9m2YoOwBXgLASKDEpG0zgBUKYYRm8zMeG +4s0KWsXNJfdUo3cgGryazXZF+d5YEQhF31D6DHTWp286sT3bjU+Ylv/YwmIh5Cw1 +I+K+dLN39B9K6Qz5doy0AQKBgFHlzFFSflWiwVcWYNWezHz3H+rz45Pd+NYrhtRs +g3WeQSxxdxgWTfbLp8L52nhm0iA6h+FIHSOIFc22jdao5PhgjUKAJuPhFqz3u9O3 +GiRbsaq7ItTr5wiQvpZ9xKlTZV6MXTHrzZXQSW2EwISi8bhJFM+zBBeAcPDBSV4U +s6STAoGANTuc66z/2wtZYINA2+JN1kSELL22ka8yKYWBmi0NJ7Hp+7MPKj9v71mM +Oq4zuNIYEJfQaf53xhi6BhZVWMERDKMGWqJet88BATbBIqBahHxFTiCmsP6fBH7e +AipTene7xg9mqG8qoluFdHRvzGqZFu0lZSGxtZYeU/y+U2b7lzI= +-----END RSA PRIVATE KEY----- diff --git a/.travis.yml b/.travis.yml index 08eafda51..a8f0dfeb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,9 @@ install: # and cause subsequent tests to fail - cat git/test/fixtures/.gitconfig >> ~/.gitconfig # used later when testing for specific issue + # copy the configured key into place so clone can work + # The key just has read-only access to the test-repository + - cp .travis.private-ssh-key-for-issue-301 ~/.ssh/id_rsa - git clone git@github.com:gitpython-developers/gitpython_issue_301.git issue-301-repo script: # Make sure we limit open handles to see if we are leaking them From 86ec7573a87cd8136d7d497b99594f29e17406d3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 16:26:52 +0200 Subject: [PATCH 0232/2790] fix(travis): fix permissions of private key --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a8f0dfeb0..c68a24b83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ install: # copy the configured key into place so clone can work # The key just has read-only access to the test-repository - cp .travis.private-ssh-key-for-issue-301 ~/.ssh/id_rsa + - chmod 0400 ~/.ssh/id_rsa - git clone git@github.com:gitpython-developers/gitpython_issue_301.git issue-301-repo script: # Make sure we limit open handles to see if we are leaking them From 9db24bc7a617cf93321bb60de6af2a20efd6afc1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 16:43:51 +0200 Subject: [PATCH 0233/2790] fix(cmd): work with py3 Fixed additional test which seems to have different outcomes depending on the interpreter. This just makes it work withouth attempting to find the root cause of the issue. --- git/remote.py | 1 + git/test/test_git.py | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/git/remote.py b/git/remote.py index 7cb0f4f8e..00d95b3c0 100644 --- a/git/remote.py +++ b/git/remote.py @@ -551,6 +551,7 @@ def _get_fetch_info_from_stderr(self, proc, progress): progress_handler = progress.new_message_handler() for line in proc.stderr.readlines(): + line = line.decode(defenc) for pline in progress_handler(line): if line.startswith('fatal:') or line.startswith('error:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) diff --git a/git/test/test_git.py b/git/test/test_git.py index fe7ec9701..fca00d406 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -201,8 +201,12 @@ def test_environment(self, rw_dir): try: remote.fetch() except GitCommandError as err: - assert 'ssh-origin' in str(err) - assert err.status == 128 + if sys.version_info[0] < 3: + assert 'ssh-origin' in str(err) + assert err.status == 128 + else: + assert 'FOO' in str(err) + assert err.status == 2 # end # end # end if select.poll exists From bbf04348b0c79be2103fd3aaa746685578eb12fd Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 3 Jul 2015 16:54:35 +0200 Subject: [PATCH 0234/2790] fix(travis): get py2.6 to work Seems like OSX is somewhat special here ... . --- git/test/test_git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index fca00d406..f386150f5 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -201,7 +201,7 @@ def test_environment(self, rw_dir): try: remote.fetch() except GitCommandError as err: - if sys.version_info[0] < 3: + if sys.version_info[0] < 3 and sys.platform == 'darwin': assert 'ssh-origin' in str(err) assert err.status == 128 else: From 80d43111b6bb73008683ad2f5a7c6abbab3c74ed Mon Sep 17 00:00:00 2001 From: Mihyaeru Date: Mon, 6 Jul 2015 21:00:54 +0900 Subject: [PATCH 0235/2790] fix(config): care tilde in include.path config --- git/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/git/config.py b/git/config.py index 2d9adbdd9..b5e1fbab2 100644 --- a/git/config.py +++ b/git/config.py @@ -386,6 +386,8 @@ def read(self): # We expect all paths to be normalized and absolute (and will assure that is the case) if self._has_includes(): for _, include_path in self.items('include'): + if '~' in include_path: + include_path = os.path.expanduser(include_path) if not os.path.isabs(include_path): if not close_fp: continue From 1578baf817c2526d29276067d2f23d28b6fab2b1 Mon Sep 17 00:00:00 2001 From: Mihyaeru Date: Mon, 6 Jul 2015 22:43:47 +0900 Subject: [PATCH 0236/2790] fix(config): use `str.startswith('~')` instead of `'~' in str` --- git/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/config.py b/git/config.py index b5e1fbab2..b7ddf0d22 100644 --- a/git/config.py +++ b/git/config.py @@ -386,7 +386,7 @@ def read(self): # We expect all paths to be normalized and absolute (and will assure that is the case) if self._has_includes(): for _, include_path in self.items('include'): - if '~' in include_path: + if include_path.startswith('~'): include_path = os.path.expanduser(include_path) if not os.path.isabs(include_path): if not close_fp: From 9aaaa83c44d5d23565e982a705d483c656e6c157 Mon Sep 17 00:00:00 2001 From: Tanner Netterville Date: Wed, 15 Jul 2015 10:54:00 -0500 Subject: [PATCH 0237/2790] Fix typo --- git/repo/fun.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/repo/fun.py b/git/repo/fun.py index 1d551f046..049800b93 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -121,7 +121,7 @@ def name_to_object(repo, name, return_ref=False): def deref_tag(tag): - """Recursively dereerence a tag and return the resulting object""" + """Recursively dereference a tag and return the resulting object""" while True: try: tag = tag.object From f3e78d98e06439eea1036957796f8df9f386930f Mon Sep 17 00:00:00 2001 From: Marian Wieczorek Date: Thu, 16 Jul 2015 23:44:30 +0200 Subject: [PATCH 0238/2790] Correct doc errors revA..revB → revA...revB (three instead of two dots) [base.py, line 467](https://github.com/gitpython-developers/GitPython/blob/master/git/repo/base.py#L467) rorepo is a ~~a~~ Repo instance [test_docs.py, line 21](https://github.com/gitpython-developers/GitPython/blob/master/git/test/test_docs.py#L21) closes #314 --- git/repo/base.py | 2 +- git/test/test_docs.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index 2783e2a4e..8b8f8db80 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -464,7 +464,7 @@ def iter_commits(self, rev=None, paths='', **kwargs): max_count and skip :note: to receive only commits between two named revisions, use the - "revA..revB" revision specifier + "revA...revB" revision specifier :return ``git.Commit[]``""" if rev is None: diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 5b8aa8179..985938e56 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -18,7 +18,7 @@ def test_init_repo_object(self, rw_dir): from git import Repo join = os.path.join - # rorepo is a a Repo instance pointing to the git-python repository. + # rorepo is a Repo instance pointing to the git-python repository. # For all you know, the first argument to Repo is a path to the repository # you want to work with repo = Repo(self.rorepo.working_tree_dir) From 141b78f42c7a3c1da1e5d605af3fc56aceb921ab Mon Sep 17 00:00:00 2001 From: avi Date: Fri, 17 Jul 2015 21:58:55 +0530 Subject: [PATCH 0239/2790] Added two extra paramaters for commit to take author date and commit date --- git/index/base.py | 5 +++-- git/objects/commit.py | 13 ++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/git/index/base.py b/git/index/base.py index f86968007..78120da39 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -922,7 +922,7 @@ def move(self, items, skip_errors=False, **kwargs): return out - def commit(self, message, parent_commits=None, head=True, author=None, committer=None): + def commit(self, message, parent_commits=None, head=True, author=None, committer=None, author_date=None, commit_date=None): """Commit the current default index file, creating a commit object. For more information on the arguments, see tree.commit. @@ -932,7 +932,8 @@ def commit(self, message, parent_commits=None, head=True, author=None, committer run_commit_hook('pre-commit', self) tree = self.write_tree() rval = Commit.create_from_tree(self.repo, tree, message, parent_commits, - head, author=author, committer=committer) + head, author=author, committer=committer, + author_date=author_date, commit_date=commit_date) run_commit_hook('post-commit', self) return rval diff --git a/git/objects/commit.py b/git/objects/commit.py index d301e3014..376b451d9 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -266,7 +266,8 @@ def _iter_from_process_or_stream(cls, repo, proc_or_stream): finalize_process(proc_or_stream) @classmethod - def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, author=None, committer=None): + def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, author=None, committer=None, + author_date=None, commit_date=None): """Commit the given tree, creating a commit object. :param repo: Repo object the commit should be part of @@ -288,6 +289,8 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, configuration is used to obtain this value. :param committer: The name of the committer, optional. If unset, the repository configuration is used to obtain this value. + :param author_date: The timestamp for the author field + :param commit_date: The timestamp for the committer field :return: Commit object representing the new commit @@ -327,14 +330,18 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, offset = altzone author_date_str = env.get(cls.env_author_date, '') - if author_date_str: + if author_date: + author_time, author_offset = parse_date(author_date) + elif author_date_str: author_time, author_offset = parse_date(author_date_str) else: author_time, author_offset = unix_time, offset # END set author time committer_date_str = env.get(cls.env_committer_date, '') - if committer_date_str: + if commit_date: + committer_time, committer_offset = parse_date(commit_date) + elif committer_date_str: committer_time, committer_offset = parse_date(committer_date_str) else: committer_time, committer_offset = unix_time, offset From e3068025b64bee24efc1063aba5138708737c158 Mon Sep 17 00:00:00 2001 From: avi Date: Fri, 17 Jul 2015 22:18:46 +0530 Subject: [PATCH 0240/2790] added tests for commits with dates --- git/index/base.py | 3 ++- git/test/test_index.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/git/index/base.py b/git/index/base.py index 78120da39..b955dae4e 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -922,7 +922,8 @@ def move(self, items, skip_errors=False, **kwargs): return out - def commit(self, message, parent_commits=None, head=True, author=None, committer=None, author_date=None, commit_date=None): + def commit(self, message, parent_commits=None, head=True, author=None, + committer=None, author_date=None, commit_date=None): """Commit the current default index file, creating a commit object. For more information on the arguments, see tree.commit. diff --git a/git/test/test_index.py b/git/test/test_index.py index 8c3775d2b..2fd53f656 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -470,6 +470,17 @@ def mixed_iterator(): assert cur_head.commit == commit_actor assert cur_head.log()[-1].actor == my_committer + # commit with author_date and commit_date + cur_commit = cur_head.commit + commit_message = u"commit with dates by Avinash Sajjanshetty" + + new_commit = index.commit(commit_message, author_date="2006-04-07T22:13:13", commit_date="2005-04-07T22:13:13") + assert cur_commit != new_commit + print(new_commit.authored_date, new_commit.committed_date) + assert new_commit.message == commit_message + assert new_commit.authored_date == 1144447993 + assert new_commit.committed_date == 1112911993 + # same index, no parents commit_message = "index without parents" commit_no_parents = index.commit(commit_message, parent_commits=list(), head=True) From 3438795d2af6d9639d1d6e9182ad916e73dd0c37 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 17 Jul 2015 22:09:05 +0200 Subject: [PATCH 0241/2790] typo in submodules api documentation --- git/objects/submodule/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 30201e090..610dddad7 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -431,7 +431,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress= This only works if we have a local tracking branch, which is the case if the remote repository had a master branch, or of the 'branch' option was specified for this submodule and the branch existed remotely - :param progress: UpdateProgress instance or None of no progress should be shown + :param progress: UpdateProgress instance or None if no progress should be shown :param dry_run: if True, the operation will only be simulated, but not performed. All performed operations are read-only :param force: From bdc38b83f4a6d39603dc845755df49065a19d029 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Fri, 17 Jul 2015 13:58:28 -0700 Subject: [PATCH 0242/2790] Always add '--' to git reset If a git repo has the misfortune to have a file with the name "HEAD" at the root level of the repo, git will return an error because it is unsure whether the file or ref is meant: File "/usr/local/lib/python2.7/dist-packages/git/refs/head.py", line 81, in reset self.repo.git.reset(mode, commit, add_arg, paths, **kwargs) File "/usr/local/lib/python2.7/dist-packages/git/cmd.py", line 440, in return lambda *args, **kwargs: self._call_process(name, *args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/git/cmd.py", line 834, in _call_process return self.execute(make_call(), **_kwargs) File "/usr/local/lib/python2.7/dist-packages/git/cmd.py", line 627, in execute raise GitCommandError(command, status, stderr_value) GitCommandError: 'git reset --hard HEAD' returned with exit code 128 stderr: 'fatal: ambiguous argument 'HEAD': both revision and filename Use '--' to separate filenames from revisions' Implement its suggested fix by always passing '--' as an argument to "git reset". It is fine to pass it with no file specifiers afterwords. In that case, git knows that "HEAD" is always meant as the ref. --- git/refs/head.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/git/refs/head.py b/git/refs/head.py index 18dac3497..06207e0ad 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -55,7 +55,6 @@ def reset(self, commit='HEAD', index=True, working_tree=False, :return: self""" mode = "--soft" - add_arg = None if index: mode = "--mixed" @@ -73,12 +72,8 @@ def reset(self, commit='HEAD', index=True, working_tree=False, # END working tree handling - if paths: - add_arg = "--" - # END nicely separate paths from rest - try: - self.repo.git.reset(mode, commit, add_arg, paths, **kwargs) + self.repo.git.reset(mode, commit, '--', paths, **kwargs) except GitCommandError as e: # git nowadays may use 1 as status to indicate there are still unstaged # modifications after the reset From 9c272abea2c837e4725c37f5c0467f83f3700cd5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 20 Jul 2015 08:51:41 +0200 Subject: [PATCH 0243/2790] fix(encoding): in untracked_files() and index * untracked_files could, if there were spaces in the path returned, re-rencode the previously decoded unicode string thanks to a `decode("string_escape")` call. Now re-encode into utf-8 afterwards - added test to assure this works indeed * IndexFile.add() didn't handle unicode correctly and would write broken index files. The solution was to compute the path length after encoding it into utf-8 bytes, not before ... . Closes #320 --- git/index/base.py | 4 ++-- git/index/fun.py | 3 ++- git/repo/base.py | 2 +- git/test/test_repo.py | 28 +++++++++++++++------------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/git/index/base.py b/git/index/base.py index b955dae4e..4317d46a2 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -583,7 +583,7 @@ def _store_path(self, filepath, fprogress): stream = None if S_ISLNK(st.st_mode): # in PY3, readlink is string, but we need bytes. In PY2, it's just OS encoded bytes, we assume UTF-8 - stream = BytesIO(force_bytes(os.readlink(filepath), encoding='utf-8')) + stream = BytesIO(force_bytes(os.readlink(filepath), encoding=defenc)) else: stream = open(filepath, 'rb') # END handle stream @@ -610,7 +610,7 @@ def _entries_for_paths(self, paths, path_rewriter, fprogress, entries): blob = Blob(self.repo, Blob.NULL_BIN_SHA, stat_mode_to_index_mode(os.stat(abspath).st_mode), - to_native_path_linux(gitrelative_path)) + to_native_path_linux(gitrelative_path), encoding=defenc) # TODO: variable undefined entries.append(BaseIndexEntry.from_blob(blob)) # END for each path diff --git a/git/index/fun.py b/git/index/fun.py index c1188ccbc..9ae468611 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -124,12 +124,13 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1 write(entry[4]) # ctime write(entry[5]) # mtime path = entry[3] + path = path.encode(defenc) plen = len(path) & CE_NAMEMASK # path length assert plen == len(path), "Path %s too long to fit into index" % entry[3] flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0], entry[8], entry[9], entry[10], entry[1], flags)) - write(path.encode(defenc)) + write(path) real_size = ((tell() - beginoffset + 8) & ~7) write(b"\0" * ((beginoffset + real_size) - tell())) # END for each entry diff --git a/git/repo/base.py b/git/repo/base.py index 8b8f8db80..cea88f393 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -625,7 +625,7 @@ def _get_untracked_files(self, **kwargs): filename = line[len(prefix):].rstrip('\n') # Special characters are escaped if filename[0] == filename[-1] == '"': - filename = filename[1:-1].decode('string_escape') + filename = filename[1:-1].decode('string_escape').decode(defenc) untracked_files.append(filename) finalize_process(proc) return untracked_files diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 667ede74d..9c08e2e4c 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -1,3 +1,4 @@ +#-*-coding:utf-8-*- # test_repo.py # Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors # @@ -324,17 +325,21 @@ def test_blame_complex_revision(self, git): assert len(res) == 1 assert len(res[0][1]) == 83, "Unexpected amount of parsed blame lines" - def test_untracked_files(self): - base = self.rorepo.working_tree_dir - files = (join_path_native(base, "__test_myfile"), - join_path_native(base, "__test_other_file")) - num_recently_untracked = 0 - try: + @with_rw_repo('HEAD', bare=False) + def test_untracked_files(self, rwrepo): + for (run, repo_add) in enumerate((rwrepo.index.add, rwrepo.git.add)): + base = rwrepo.working_tree_dir + files = (join_path_native(base, u"%i_test _myfile" % run), + join_path_native(base, "%i_test_other_file" % run), + join_path_native(base, u"%i__çava verböten" % run), + join_path_native(base, u"%i_çava-----verböten" % run)) + + num_recently_untracked = 0 for fpath in files: fd = open(fpath, "wb") fd.close() # END for each filename - untracked_files = self.rorepo.untracked_files + untracked_files = rwrepo.untracked_files num_recently_untracked = len(untracked_files) # assure we have all names - they are relative to the git-dir @@ -342,13 +347,10 @@ def test_untracked_files(self): for utfile in untracked_files: num_test_untracked += join_path_native(base, utfile) in files assert len(files) == num_test_untracked - finally: - for fpath in files: - if os.path.isfile(fpath): - os.remove(fpath) - # END handle files - assert len(self.rorepo.untracked_files) == (num_recently_untracked - len(files)) + repo_add(untracked_files) + assert len(rwrepo.untracked_files) == (num_recently_untracked - len(files)) + # end for each run def test_config_reader(self): reader = self.rorepo.config_reader() # all config files From 3c8a33e2c9cae8deef1770a5fce85acb2e85b5c6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 20 Jul 2015 09:19:38 +0200 Subject: [PATCH 0244/2790] fix(encoding): in `untracked_files()` I have no idea why PY3 requires such a mess of encoding/decoding statements, but let's just be happy it works. Also let's be sure I never ever write python code again ... EVER. --- git/repo/base.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index cea88f393..5be63d860 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -54,7 +54,9 @@ ) from git.compat import ( text_type, - defenc + force_text, + defenc, + PY3 ) import os @@ -625,7 +627,12 @@ def _get_untracked_files(self, **kwargs): filename = line[len(prefix):].rstrip('\n') # Special characters are escaped if filename[0] == filename[-1] == '"': - filename = filename[1:-1].decode('string_escape').decode(defenc) + filename = filename[1:-1] + if PY3: + # WHATEVER ... it's a mess, but works for me + filename = filename.encode('ascii').decode('unicode_escape').encode('latin1').decode(defenc) + else: + filename = filename.decode('string_escape').decode(defenc) untracked_files.append(filename) finalize_process(proc) return untracked_files From c1d33021feb7324e0f2f91c947468bf282f036d2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 20 Jul 2015 09:30:24 +0200 Subject: [PATCH 0245/2790] fix(index): remove invalid keyword argument It was a left-over of some prior hacking that was not removed by accident. --- git/index/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/index/base.py b/git/index/base.py index 4317d46a2..753fa4ae2 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -610,7 +610,7 @@ def _entries_for_paths(self, paths, path_rewriter, fprogress, entries): blob = Blob(self.repo, Blob.NULL_BIN_SHA, stat_mode_to_index_mode(os.stat(abspath).st_mode), - to_native_path_linux(gitrelative_path), encoding=defenc) + to_native_path_linux(gitrelative_path)) # TODO: variable undefined entries.append(BaseIndexEntry.from_blob(blob)) # END for each path From f360ecd7b2de173106c08238ec60db38ec03ee9b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 20 Jul 2015 09:57:53 +0200 Subject: [PATCH 0246/2790] fix(flake8): remove unused import I knew that flake would eventually get me, especially when least suspected. This time it's even useful, as it is a non-whitespace related issue. --- git/repo/base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/git/repo/base.py b/git/repo/base.py index 5be63d860..b04112353 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -54,7 +54,6 @@ ) from git.compat import ( text_type, - force_text, defenc, PY3 ) From 65c07d64a7b1dc85c41083c60a8082b3705154c3 Mon Sep 17 00:00:00 2001 From: Sandy Carter Date: Tue, 21 Jul 2015 11:02:24 -0400 Subject: [PATCH 0247/2790] Implement is_ancestor Wrap `git merge-base --is-ancestor` into its own function because it acts as a boolean check unlike base `git merge-base call` --- git/repo/base.py | 15 +++++++++++++++ git/test/test_repo.py | 14 ++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/git/repo/base.py b/git/repo/base.py index b04112353..16fb58e59 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -504,6 +504,21 @@ def merge_base(self, *rev, **kwargs): return res + def is_ancestor(self, ancestor_rev, rev): + """Check if a commit is an ancestor of another + + :param ancestor_rev: Rev which should be an ancestor + :param rev: Rev to test against ancestor_rev + :return: ``True``, ancestor_rev is an accestor to rev. + """ + try: + self.git.merge_base(ancestor_rev, rev, is_ancestor=True) + except GitCommandError as err: + if err.status == 1: + return False + raise + return True + def _get_daemon_export(self): filename = join(self.git_dir, self.DAEMON_EXPORT_FILE) return os.path.exists(filename) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 9c08e2e4c..bc9f3e92c 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -42,6 +42,7 @@ import sys import tempfile import shutil +import itertools from io import BytesIO @@ -765,3 +766,16 @@ def test_merge_base(self): # Test for no merge base - can't do as we have self.failUnlessRaises(GitCommandError, repo.merge_base, c1, 'ffffff') + + def test_is_ancestor(self): + repo = self.rorepo + c1 = 'f6aa8d1' + c2 = '763ef75' + self.assertTrue(repo.is_ancestor(c1, c1)) + self.assertTrue(repo.is_ancestor("master", "master")) + self.assertTrue(repo.is_ancestor(c1, c2)) + self.assertTrue(repo.is_ancestor(c1, "master")) + self.assertFalse(repo.is_ancestor(c2, c1)) + self.assertFalse(repo.is_ancestor("master", c1)) + for i, j in itertools.permutations([c1, 'ffffff', ''], r=2): + self.assertRaises(GitCommandError, repo.is_ancestor, i, j) From 6fdb6a5eac7433098cfbb33d3e18d6dbba8fa3d3 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Wed, 22 Jul 2015 09:28:42 +0200 Subject: [PATCH 0248/2790] gic {init,clone} --separate-git-dir is supported only since 1.7.5 Without this commit the update() function of a submodule does not work in CentOS 6. --- git/objects/submodule/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 610dddad7..eea091f8c 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -137,7 +137,7 @@ def _get_intermediate_items(self, item): @classmethod def _need_gitfile_submodules(cls, git): - return git.version_info[:3] >= (1, 7, 0) + return git.version_info[:3] >= (1, 7, 5) def __eq__(self, other): """Compare with another submodule""" From 58c5b993d218c0ebc3f610c2e55a14b194862e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Garc=C3=ADa=20Garz=C3=B3n?= Date: Sun, 26 Jul 2015 15:42:00 +0200 Subject: [PATCH 0249/2790] Ensure file resources are released --- git/refs/symbolic.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index d884250f7..f3799ed4e 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -88,25 +88,25 @@ def _iter_packed_refs(cls, repo): """Returns an iterator yielding pairs of sha1/path pairs (as bytes) for the corresponding refs. :note: The packed refs file will be kept open as long as we iterate""" try: - fp = open(cls._get_packed_refs_path(repo), 'rt') - for line in fp: - line = line.strip() - if not line: - continue - if line.startswith('#'): - if line.startswith('# pack-refs with:') and not line.endswith('peeled'): - raise TypeError("PackingType of packed-Refs not understood: %r" % line) - # END abort if we do not understand the packing scheme - continue - # END parse comment + with open(cls._get_packed_refs_path(repo), 'rt') as fp: + for line in fp: + line = line.strip() + if not line: + continue + if line.startswith('#'): + if line.startswith('# pack-refs with:') and not line.endswith('peeled'): + raise TypeError("PackingType of packed-Refs not understood: %r" % line) + # END abort if we do not understand the packing scheme + continue + # END parse comment - # skip dereferenced tag object entries - previous line was actual - # tag reference for it - if line[0] == '^': - continue + # skip dereferenced tag object entries - previous line was actual + # tag reference for it + if line[0] == '^': + continue - yield tuple(line.split(' ', 1)) - # END for each line + yield tuple(line.split(' ', 1)) + # END for each line except (OSError, IOError): raise StopIteration # END no packed-refs file handling From eb6beb75aaa269a1e7751d389c0826646878e5fc Mon Sep 17 00:00:00 2001 From: Ram Rachum Date: Tue, 28 Jul 2015 00:18:57 +0300 Subject: [PATCH 0250/2790] Fix bug in tutorial --- doc/source/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 7cc296d83..2533216c9 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -393,7 +393,7 @@ Use the diff framework if you want to implement git-status like functionality. * A diff between the index and the commit's tree your HEAD points to - * use ``repo.index.diff(repo.head)`` + * use ``repo.index.diff(repo.head.commit)`` * A diff between the index and the working tree From c58887a2d8554d171a7c76b03bfa919c72e918e1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 28 Jul 2015 17:51:50 +0200 Subject: [PATCH 0251/2790] don't 'log' to stderr in `RemoteProgress` There is simply no excuse to doing that. Closes #330 --- git/util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/git/util.py b/git/util.py index f0a08e799..809bcc048 100644 --- a/git/util.py +++ b/git/util.py @@ -239,7 +239,6 @@ def _parse_progress_line(self, line): # to make sure we get informed in case the process spits out new # commands at some point. self.line_dropped(sline) - sys.stderr.write("Operation name %r unknown - skipping line '%s'" % (op_name, sline)) # Note: Don't add this line to the failed lines, as we have to silently # drop it return failed_lines From 8324c4b38cf37af416833d36696577d8d35dce7f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 29 Jul 2015 15:14:41 +0200 Subject: [PATCH 0252/2790] fix(diff): mode-assertions now deal with 0 If the file was not present, the mode seen in a diff can be legally '0', which previously caused an assertion to fail for no good reason. Now the assertion tests for None instead. Closes #323 --- git/diff.py | 4 ++-- git/test/test_diff.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/git/diff.py b/git/diff.py index dc53f3f71..9059091e6 100644 --- a/git/diff.py +++ b/git/diff.py @@ -223,12 +223,12 @@ def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode, if a_blob_id is None: self.a_blob = None else: - assert self.a_mode + assert self.a_mode is not None self.a_blob = Blob(repo, hex_to_bin(a_blob_id), mode=self.a_mode, path=a_path) if b_blob_id is None: self.b_blob = None else: - assert self.b_mode + assert self.b_mode is not None self.b_blob = Blob(repo, hex_to_bin(b_blob_id), mode=self.b_mode, path=b_path) self.new_file = new_file diff --git a/git/test/test_diff.py b/git/test/test_diff.py index f2ce14471..53bb65dbd 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -4,6 +4,7 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +import os from git.test.lib import ( TestBase, @@ -14,7 +15,11 @@ ) +from gitdb.test.lib import with_rw_directory + from git import ( + Repo, + GitCommandError, Diff, DiffIndex ) @@ -37,6 +42,33 @@ def _assert_diff_format(self, diffs): # END for each diff return diffs + @with_rw_directory + def test_diff_with_staged_file(self, rw_dir): + # SETUP INDEX WITH MULTIPLE STAGES + r = Repo.init(rw_dir) + fp = os.path.join(rw_dir, 'hello.txt') + with open(fp, 'w') as fs: + fs.write("hello world") + r.git.add(fp) + r.git.commit(message="init") + + with open(fp, 'w') as fs: + fs.write("Hola Mundo") + r.git.commit(all=True, message="change on master") + + r.git.checkout('HEAD~1', b='topic') + with open(fp, 'w') as fs: + fs.write("Hallo Welt") + r.git.commit(all=True, message="change on topic branch") + + # there must be a merge-conflict + self.failUnlessRaises(GitCommandError, r.git.cherry_pick, 'master') + + # Now do the actual testing - this should just work + assert len(r.index.diff(None)) == 2 + + assert len(r.index.diff(None, create_patch=True)) == 0, "This should work, but doesn't right now ... it's OK" + def test_list_from_string_new_mode(self): output = StringProcessAdapter(fixture('diff_new_mode')) diffs = Diff._index_from_patch_format(self.rorepo, output.stdout) From 7ab12b403207bb46199f46d5aaa72d3e82a3080d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 29 Jul 2015 18:29:03 +0200 Subject: [PATCH 0253/2790] fix(index):allow adding non-unicode paths to index This issue only surfaced in python 2, in case paths containing unicode characters were not actual unicode objects. In python 3, this was never the issue. Closes #331 --- git/index/fun.py | 5 +++-- git/test/test_index.py | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/git/index/fun.py b/git/index/fun.py index 9ae468611..c1026fd62 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -41,7 +41,8 @@ from gitdb.typ import str_tree_type from git.compat import ( defenc, - force_text + force_text, + force_bytes ) S_IFGITLINK = S_IFLNK | S_IFDIR # a submodule @@ -124,7 +125,7 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1 write(entry[4]) # ctime write(entry[5]) # mtime path = entry[3] - path = path.encode(defenc) + path = force_bytes(path, encoding=defenc) plen = len(path) & CE_NAMEMASK # path length assert plen == len(path), "Path %s too long to fit into index" % entry[3] flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values diff --git a/git/test/test_index.py b/git/test/test_index.py index 2fd53f656..397885752 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -18,6 +18,7 @@ ) from git import ( IndexFile, + Repo, BlobFilter, UnmergedEntriesError, Tree, @@ -45,6 +46,7 @@ IndexEntry ) from git.index.fun import hook_path +from gitdb.test.lib import with_rw_directory class TestIndex(TestBase): @@ -780,3 +782,14 @@ def test_index_bare_add(self, rw_bare_repo): except InvalidGitRepositoryError: asserted = True assert asserted, "Adding using a filename is not correctly asserted." + + @with_rw_directory + def test_add_utf8P_path(self, rw_dir): + # NOTE: fp is not a Unicode object in python 2 (which is the source of the problem) + fp = os.path.join(rw_dir, 'ø.txt') + with open(fp, 'w') as fs: + fs.write('content of ø') + + r = Repo.init(rw_dir) + r.index.add([fp]) + r.index.commit('Added orig and prestable') From b2e4134963c971e3259137b84237d6c47964b018 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 8 Aug 2015 22:25:09 +0200 Subject: [PATCH 0254/2790] docs(README): removed coveralls link Coveralls was disabled a while ago because it would prevent merging PRs from the phone. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f87cb0efe..75fcdcb2c 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,6 @@ New BSD License. See the LICENSE file. [![Build Status](https://travis-ci.org/gitpython-developers/GitPython.svg)](https://travis-ci.org/gitpython-developers/GitPython) [![Code Climate](https://codeclimate.com/github/gitpython-developers/GitPython/badges/gpa.svg)](https://codeclimate.com/github/gitpython-developers/GitPython) -[![Coverage Status](https://coveralls.io/repos/gitpython-developers/GitPython/badge.png?branch=master)](https://coveralls.io/r/gitpython-developers/GitPython?branch=master) [![Documentation Status](https://readthedocs.org/projects/gitpython/badge/?version=stable)](https://readthedocs.org/projects/gitpython/?badge=stable) [![Issue Stats](http://www.issuestats.com/github/gitpython-developers/GitPython/badge/pr)](http://www.issuestats.com/github/gitpython-developers/GitPython) [![Issue Stats](http://www.issuestats.com/github/gitpython-developers/GitPython/badge/issue)](http://www.issuestats.com/github/gitpython-developers/GitPython) From a0acb2229e1ebb59ab343e266fc5c1cc392a974e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 8 Aug 2015 23:02:38 +0200 Subject: [PATCH 0255/2790] tests(submodule): add new submodule commits It's somewhat more complex to add new commits in submodules to the parent repository. The new test shows how to do that in a 'GitPythonic' way. Related to #335 --- git/test/test_submodule.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index cbf38c182..3d78d0672 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -661,7 +661,7 @@ def test_add_empty_repo(self, rwdir): # end for each checkout mode @with_rw_directory - def test_git_submodules(self, rwdir): + def test_git_submodules_and_add_sm_with_new_commit(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) parent.git.submodule('add', self._small_repo_url(), 'module') parent.index.commit("added submodule") @@ -686,6 +686,37 @@ def test_git_submodules(self, rwdir): sm.move(sm.path + '_moved') sm2.move(sm2.path + '_moved') + parent.index.commit("moved submodules") + + smm = sm.module() + fp = os.path.join(smm.working_tree_dir, 'empty-file') + with open(fp, 'w'): + pass + smm.git.add(fp) + smm.git.commit(m="new file added") + + # submodules are retrieved from the current commit's tree, therefore we can't really get a new submodule + # object pointing to the new submodule commit + sm_too = parent.submodules[0] + assert parent.head.commit.tree[sm.path].binsha == sm.binsha + assert sm_too.binsha == sm.binsha, "cached submodule should point to the same commit as updated one" + + added_bies = parent.index.add([sm]) # addded base-index-entries + assert len(added_bies) == 1 + parent.index.commit("add same submodule entry") + commit_sm = parent.head.commit.tree[sm.path] + assert commit_sm.binsha == added_bies[0].binsha + assert commit_sm.binsha == sm.binsha + + sm_too.binsha = sm_too.module().head.commit.binsha + added_bies = parent.index.add([sm_too]) + assert len(added_bies) == 1 + parent.index.commit("add new submodule entry") + commit_sm = parent.head.commit.tree[sm.path] + assert commit_sm.binsha == added_bies[0].binsha + assert commit_sm.binsha == sm_too.binsha + assert sm_too.binsha != sm.binsha + @with_rw_directory def test_git_submodule_compatibility(self, rwdir): parent = git.Repo.init(os.path.join(rwdir, 'parent')) From 039e265819cc6e5241907f1be30d2510bfa5ca6c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 8 Aug 2015 23:35:12 +0200 Subject: [PATCH 0256/2790] fix(tests): remove dependency on sort order Now we select the submodule by name, not by index. The latter is not deterministic. Closes #335 --- git/test/test_submodule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 3d78d0672..17ce605a4 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -697,7 +697,7 @@ def test_git_submodules_and_add_sm_with_new_commit(self, rwdir): # submodules are retrieved from the current commit's tree, therefore we can't really get a new submodule # object pointing to the new submodule commit - sm_too = parent.submodules[0] + sm_too = parent.submodules['module_moved'] assert parent.head.commit.tree[sm.path].binsha == sm.binsha assert sm_too.binsha == sm.binsha, "cached submodule should point to the same commit as updated one" From a8f7e3772f68c8e6350b9ff5ac981ba3223f2d43 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 17 Aug 2015 22:32:15 +0200 Subject: [PATCH 0257/2790] fix(commit): serialization timezone handling Previously timezones which were not divisable by 3600s would be parsed correctly, but would serialize into a full hour, rounded up. Now floating point computation is used which fixes the issue. Related to #336 --- doc/source/changes.rst | 7 +++++++ git/objects/util.py | 2 +- git/test/performance/test_commit.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index e6d7b09be..970ba1958 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,13 @@ Changelog ========= +1.0.2 - Fixes +============= + +* CRITICAL: fixed incorrect `Commit` object serialization when authored or commit date had timezones which were not + divisable by 3600 seconds. This would happen if the timezone was something like `+0530` for instance. +* A list of all additional fixes can be found `on github `_ + 1.0.1 - Fixes ============= diff --git a/git/objects/util.py b/git/objects/util.py index 567b1d5b2..8fd92a0a9 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -73,7 +73,7 @@ def utctz_to_altz(utctz): def altz_to_utctz_str(altz): """As above, but inverses the operation, returning a string that can be used in commit objects""" - utci = -1 * int((altz / 3600) * 100) + utci = -1 * int((float(altz) / 3600) * 100) utcs = str(abs(utci)) utcs = "0" * (4 - len(utcs)) + utcs prefix = (utci < 0 and '-') or '+' diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index 7d3e87c4c..b59c747ee 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -76,7 +76,7 @@ def test_commit_iteration(self): % (nc, elapsed_time, nc / elapsed_time), file=sys.stderr) def test_commit_serialization(self): - assert_commit_serialization(self.gitrwrepo, self.gitrwrepo.head, True) + assert_commit_serialization(self.gitrwrepo, '58c78e6', True) rwrepo = self.gitrwrepo make_object = rwrepo.odb.store From c8b837923d506e265ff8bb79af61c0d86e7d5b2e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 17 Aug 2015 22:39:13 +0200 Subject: [PATCH 0258/2790] fix(test_index): fix encoding I really never want to touch python again, and never deal with py2/3 unicode handling anymore. By now, it seems pretty much anything is better. Is python to be blamed for it entirely ? Probably not, but there are better alternatives. Nim ? Rust ? Ruby ? Totally --- git/test/test_index.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git/test/test_index.py b/git/test/test_index.py index 397885752..ffc4bffe1 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -787,8 +787,8 @@ def test_index_bare_add(self, rw_bare_repo): def test_add_utf8P_path(self, rw_dir): # NOTE: fp is not a Unicode object in python 2 (which is the source of the problem) fp = os.path.join(rw_dir, 'ø.txt') - with open(fp, 'w') as fs: - fs.write('content of ø') + with open(fp, 'wb') as fs: + fs.write(u'content of ø'.encode('utf-8')) r = Repo.init(rw_dir) r.index.add([fp]) From 332521ac1d94f743b06273e6a8daf91ce93aed7d Mon Sep 17 00:00:00 2001 From: Marcos Dione Date: Thu, 20 Aug 2015 00:09:26 +0200 Subject: [PATCH 0259/2790] fix(cmd): make short options with arguments become two separate arguments for the executable. --- git/cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/cmd.py b/git/cmd.py index 31865d090..3cdc68ab7 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -700,7 +700,7 @@ def custom_environment(self, **kwargs): finally: self.update_environment(**old_env) - def transform_kwargs(self, split_single_char_options=False, **kwargs): + def transform_kwargs(self, split_single_char_options=True, **kwargs): """Transforms Python style kwargs into git command line options.""" args = list() for k, v in kwargs.items(): From ec15e53439d228ec64cb260e02aeae5cc05c5b2b Mon Sep 17 00:00:00 2001 From: Marcos Dione Date: Thu, 20 Aug 2015 00:18:48 +0200 Subject: [PATCH 0260/2790] fix(test): update to changes. --- git/test/test_git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/test/test_git.py b/git/test/test_git.py index f386150f5..3e3e21e48 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -65,7 +65,7 @@ def test_it_raises_errors(self): def test_it_transforms_kwargs_into_git_command_arguments(self): assert_equal(["-s"], self.git.transform_kwargs(**{'s': True})) - assert_equal(["-s5"], self.git.transform_kwargs(**{'s': 5})) + assert_equal(["-s", "5"], self.git.transform_kwargs(**{'s': 5})) assert_equal(["--max-count"], self.git.transform_kwargs(**{'max_count': True})) assert_equal(["--max-count=5"], self.git.transform_kwargs(**{'max_count': 5})) From 6eb3af27464ffba83e3478b0a0c8b1f9ff190889 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 22 Aug 2015 16:31:31 +0200 Subject: [PATCH 0261/2790] fix(repo): use GitCmdObjectDB by default This should fix resource leaking issues once and for all. Related #304 --- doc/source/changes.rst | 3 +++ git/repo/base.py | 7 ++----- git/test/test_repo.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 970ba1958..acf681eea 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -5,6 +5,9 @@ Changelog 1.0.2 - Fixes ============= +* IMPORTANT: Changed default object database of `Repo` objects to `GitComdObjectDB`. The pure-python implementation + used previously usually fails to release its resources (i.e. file handles), which can lead to problems when working + with large repositories. * CRITICAL: fixed incorrect `Commit` object serialization when authored or commit date had timezones which were not divisable by 3600 seconds. This would happen if the timezone was something like `+0530` for instance. * A list of all additional fixes can be found `on github `_ diff --git a/git/repo/base.py b/git/repo/base.py index 16fb58e59..d5bc24d87 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -35,10 +35,7 @@ add_progress ) -from git.db import ( - GitCmdObjectDB, - GitDB -) +from git.db import GitCmdObjectDB from gitdb.util import ( join, @@ -62,7 +59,7 @@ import sys import re -DefaultDBType = GitDB +DefaultDBType = GitCmdObjectDB if sys.version_info[:2] < (2, 5): # python 2.4 compatiblity DefaultDBType = GitCmdObjectDB # END handle python 2.4 diff --git a/git/test/test_repo.py b/git/test/test_repo.py index bc9f3e92c..c95592ea9 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -657,7 +657,7 @@ def test_rev_parse(self): assert rev_parse('@{1}') != head.commit def test_repo_odbtype(self): - target_type = GitDB + target_type = GitCmdObjectDB if sys.version_info[:2] < (2, 5): target_type = GitCmdObjectDB assert isinstance(self.rorepo.odb, target_type) From e8590424997ab1d578c777fe44bf7e4173036f93 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 29 Aug 2015 16:19:52 +0200 Subject: [PATCH 0262/2790] fix(repo): fail loudly if worktrees are used As GitPython is in maintenance mode, there will be no new features. However, I believe it's good idea to explicitly state we do not support certain things if this is the case. Therefore, when worktrees are encountered, we will throw an specific exception to indicate that. The current implementation is hacky to speed up development, and increases the risk of failing due to false-positive worktree directories. Related to #344 --- git/exc.py | 4 ++++ git/repo/fun.py | 25 ++++++++++++++++--------- git/test/test_repo.py | 20 +++++++++++++++++++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/git/exc.py b/git/exc.py index f5b52374b..34382ecd5 100644 --- a/git/exc.py +++ b/git/exc.py @@ -14,6 +14,10 @@ class InvalidGitRepositoryError(Exception): """ Thrown if the given repository appears to have an invalid format. """ +class WorkTreeRepositoryUnsupported(InvalidGitRepositoryError): + """ Thrown to indicate we can't handle work tree repositories """ + + class NoSuchPathError(OSError): """ Thrown if a path could not be access by the system. """ diff --git a/git/repo/fun.py b/git/repo/fun.py index 049800b93..6b06663a0 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -4,7 +4,7 @@ from gitdb.exc import ( BadObject, - BadName + BadName, ) from git.refs import SymbolicReference from git.objects import Object @@ -16,6 +16,7 @@ hex_to_bin, bin_to_hex ) +from git.exc import WorkTreeRepositoryUnsupported from git.compat import xrange @@ -31,14 +32,20 @@ def touch(filename): def is_git_dir(d): """ This is taken from the git setup.c:is_git_directory - function.""" - if isdir(d) and \ - isdir(join(d, 'objects')) and \ - isdir(join(d, 'refs')): - headref = join(d, 'HEAD') - return isfile(headref) or \ - (os.path.islink(headref) and - os.readlink(headref).startswith('refs')) + function. + + @throws WorkTreeRepositoryUnsupported if it sees a worktree directory. It's quite hacky to do that here, + but at least clearly indicates that we don't support it. + There is the unlikely danger to throw if we see directories which just look like a worktree dir, + but are none.""" + if isdir(d): + if isdir(join(d, 'objects')) and isdir(join(d, 'refs')): + headref = join(d, 'HEAD') + return isfile(headref) or \ + (os.path.islink(headref) and + os.readlink(headref).startswith('refs')) + elif isfile(join(d, 'gitdir')) and isfile(join(d, 'commondir')) and isfile(join(d, 'gitfile')): + raise WorkTreeRepositoryUnsupported(d) return False diff --git a/git/test/test_repo.py b/git/test/test_repo.py index c95592ea9..2e44f0aad 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -33,7 +33,10 @@ ) from git.repo.fun import touch from git.util import join_path_native -from git.exc import BadObject +from git.exc import ( + BadObject, + WorkTreeRepositoryUnsupported +) from gitdb.util import bin_to_hex from git.compat import string_types from gitdb.test.lib import with_rw_directory @@ -45,6 +48,8 @@ import itertools from io import BytesIO +from nose import SkipTest + class TestRepo(TestBase): @@ -779,3 +784,16 @@ def test_is_ancestor(self): self.assertFalse(repo.is_ancestor("master", c1)) for i, j in itertools.permutations([c1, 'ffffff', ''], r=2): self.assertRaises(GitCommandError, repo.is_ancestor, i, j) + + @with_rw_directory + def test_work_tree_unsupported(self, rw_dir): + git = Git(rw_dir) + if git.version_info[:3] < (2, 5, 1): + raise SkipTest("worktree feature unsupported") + + rw_master = self.rorepo.clone(join_path_native(rw_dir, 'master_repo')) + rw_master.git.checkout('HEAD~10') + worktree_path = join_path_native(rw_dir, 'worktree_repo') + rw_master.git.worktree('add', worktree_path, 'master') + + self.failUnlessRaises(WorkTreeRepositoryUnsupported, Repo, worktree_path) From 7f8d9ca08352a28cba3b01e4340a24edc33e13e8 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 29 Aug 2015 16:25:40 +0200 Subject: [PATCH 0263/2790] fix(compat): make test work with git >= 2.5 --- git/test/test_index.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git/test/test_index.py b/git/test/test_index.py index ffc4bffe1..a928fe5e7 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -690,6 +690,9 @@ def make_paths(): index.add(files, write=True) if os.name != 'nt': hp = hook_path('pre-commit', index.repo.git_dir) + hpd = os.path.dirname(hp) + if not os.path.isdir(hpd): + os.mkdir(hpd) with open(hp, "wt") as fp: fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1") # end From 074842accb51b2a0c2c1193018d9f374ac5e948f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 6 Sep 2015 15:11:54 +0200 Subject: [PATCH 0264/2790] fix(config): ignore empty values in config file Similar to git, we now ignore options which have no value. Previously it would not handle it consistently, and throw a parsing error the first time the cache was built. Afterwards, it was fully usable though. Now we specifically check for the case of no-value options instead. Closes #349 --- git/config.py | 20 +++++++++++++------ git/test/fixtures/git_config_with_empty_value | 4 ++++ git/test/test_config.py | 7 +++++++ 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 git/test/fixtures/git_config_with_empty_value diff --git a/git/config.py b/git/config.py index b7ddf0d22..ea5e17bea 100644 --- a/git/config.py +++ b/git/config.py @@ -156,15 +156,21 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, obje #} END configuration + optvalueonly_source = r'\s*(?P