From fcc166d3a6e235933e823e82e1fcf6160a32a5d3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 8 Jun 2011 01:27:28 +0200 Subject: [PATCH] log: non-existing logs no longer throw an exception, but are ignored. Fixed critical bug which caused packed-ref files to be written with native line endings, which made git fail to parse it. I wonder why I never noticed this before, or ignored it. Unbelievable \! --- .gitmodules | 8 ++++---- git/refs/log.py | 8 +++++++- git/refs/symbolic.py | 13 ++++++++----- git/util.py | 3 +++ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.gitmodules b/.gitmodules index 83a5207ef..67cfa9b86 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "gitdb"] - path = git/ext/gitdb - url = git://github.com/gitpython-developers/gitdb.git - branch = master +[submodule "gitdb"] + path = git/ext/gitdb + url = git://github.com/gitpython-developers/gitdb.git + branch = master diff --git a/git/refs/log.py b/git/refs/log.py index f49c07fda..e94c21f03 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -129,7 +129,13 @@ def __init__(self, filepath=None): # END handle filepath def _read_from_file(self): - fmap = file_contents_ro_filepath(self._path, stream=False, allow_mmap=True) + try: + fmap = file_contents_ro_filepath(self._path, stream=False, allow_mmap=True) + except OSError: + # it is possible and allowed that the file doesn't exist ! + return + #END handle invalid log + try: self._deserialize(fmap) finally: diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index aec68750d..1c6a3bf1f 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -75,7 +75,7 @@ def _iter_packed_refs(cls, repo): """Returns an iterator yielding pairs of sha1/path pairs 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), 'r') + fp = open(cls._get_packed_refs_path(repo), 'rb') for line in fp: line = line.strip() if not line: @@ -398,7 +398,7 @@ def delete(cls, repo, path): # check packed refs pack_file_path = cls._get_packed_refs_path(repo) try: - reader = open(pack_file_path) + reader = open(pack_file_path, 'rb') except (OSError,IOError): pass # it didnt exist at all else: @@ -425,7 +425,10 @@ def delete(cls, repo, path): # write the new lines if made_change: - open(pack_file_path, 'w').writelines(new_lines) + # 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) + # END write out file # END open exception handling # END handle deletion @@ -549,7 +552,7 @@ def _iter_items(cls, repo, common_path = None): # Currently we do not follow links for root, dirs, files in os.walk(join_path_native(repo.git_dir, common_path)): if 'refs/' not in root: # skip non-refs subfolders - refs_id = [ i for i,d in enumerate(dirs) if d == 'refs' ] + refs_id = [ d for d in dirs if d == 'refs' ] if refs_id: dirs[0:] = ['refs'] # END prune non-refs folders @@ -589,7 +592,7 @@ def iter_items(cls, repo, common_path = None): :return: git.SymbolicReference[], each of them is guaranteed to be a symbolic - ref which is not detached. + ref which is not detached and pointing to a valid ref List is lexigraphically sorted The returned objects represent actual subclasses, such as Head or TagReference""" diff --git a/git/util.py b/git/util.py index 0492b63c6..00085ae00 100644 --- a/git/util.py +++ b/git/util.py @@ -47,12 +47,15 @@ def join_path(a, *p): '/' instead of possibly '\' on windows.""" path = a for b in p: + if len(b) == 0: + continue if b.startswith('/'): path += b[1:] elif path == '' or path.endswith('/'): path += b else: path += '/' + b + # END for each path token to add return path def to_native_path_windows(path):