From e21d1b2c73a9b9d986f1d13d0e56a695df7821ca Mon Sep 17 00:00:00 2001 From: wusisu Date: Thu, 4 May 2017 10:22:23 +0800 Subject: [PATCH] reference: iter_item method add a parameter to return the ref's destination --- git/refs/reference.py | 4 ++-- git/refs/symbolic.py | 19 +++++++++++++++---- git/test/test_refs.py | 7 +++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/git/refs/reference.py b/git/refs/reference.py index 734ed8b9e..561bcc8a9 100644 --- a/git/refs/reference.py +++ b/git/refs/reference.py @@ -94,10 +94,10 @@ def name(self): return '/'.join(tokens[2:]) @classmethod - def iter_items(cls, repo, common_path=None): + def iter_items(cls, repo, common_path=None, with_destination=False): """Equivalent to SymbolicReference.iter_items, but will return non-detached references as well.""" - return cls._iter_items(repo, common_path) + return cls._iter_items(repo, common_path, with_destination) #}END interface diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 22b7c53e9..763c3e4d9 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -566,10 +566,11 @@ def rename(self, new_path, force=False): return self @classmethod - def _iter_items(cls, repo, common_path=None): + def _iter_items(cls, repo, common_path=None, with_destination=False): if common_path is None: common_path = cls._common_path_default rela_paths = set() + rela_paths_dest = {} # walk loose refs # Currently we do not follow links @@ -584,21 +585,31 @@ def _iter_items(cls, repo, common_path=None): 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) + '/', "")) + rela_path = abs_path.replace(to_native_path_linux(repo.git_dir) + '/', "") + rela_paths.add(rela_path) + if with_destination: + with open(abs_path, 'r') as fp: + dest = fp.read().strip('\n') + rela_paths_dest[rela_path] = dest # END for each file in root directory # END for each directory to walk # read packed refs - for sha, rela_path in cls._iter_packed_refs(repo): # @UnusedVariable + for dest, rela_path in cls._iter_packed_refs(repo): # @UnusedVariable if rela_path.startswith(common_path): rela_paths.add(rela_path) + if with_destination and rela_path not in rela_paths_dest: + rela_paths_dest[rela_path] = dest # END relative path matches common path # END packed refs reading # return paths in sorted order for path in sorted(rela_paths): try: - yield cls.from_path(repo, path) + if with_destination: + yield cls.from_path(repo, path), rela_paths_dest[path] if path in rela_paths_dest else None + else: + yield cls.from_path(repo, path) except ValueError: continue # END for each sorted relative refpath diff --git a/git/test/test_refs.py b/git/test/test_refs.py index f885617e8..19d5b3edb 100644 --- a/git/test/test_refs.py +++ b/git/test/test_refs.py @@ -92,6 +92,13 @@ def test_tags(self): assert len(s) == ref_count assert len(s | s) == ref_count + @with_rw_repo('HEAD') + def test_iter_item_with_destination(self, rwrepo): + for ref, dest in Reference.iter_items(rwrepo, None, True): + if not dest.startswith('ref:'): + assert len(dest) == 40 + assert ref.commit == rwrepo.commit(dest) + @with_rw_repo('HEAD', bare=False) def test_heads(self, rwrepo): for head in rwrepo.heads: