Skip to content

reference: iter_item method add a parameter to return the ref's destination #624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions git/refs/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please describe what with_destination does in the doc-string? Since it is not available in the SymbolicReference, it's probably correct to put it here and make a note about this specialty in SymbolicReference.iter_items().

return cls._iter_items(repo, common_path)
return cls._iter_items(repo, common_path, with_destination)

#}END interface

Expand Down
19 changes: 15 additions & 4 deletions git/refs/symbolic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
7 changes: 7 additions & 0 deletions git/test/test_refs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down