Skip to content
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

Simplify nearest_branch algorithm #1167

Merged
merged 1 commit into from
Oct 24, 2019
Merged
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
57 changes: 2 additions & 55 deletions core/git_mixins/rebase.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,43 +26,6 @@ def branch_relatives(self, branch):
relatives.append(branch_name)
return relatives

def _nearest_from_relatives(self, relatives, branch):
"""
Find the nearest branch from the "branch-out nodes" of all relatives.
"""
util.debug.add_to_log('nearest_branch: filtering branches that share branch-out nodes')
diff = difflib.Differ()
max_revisions = 100
branch_commits = self.git(
"rev-list", "-{}".format(max_revisions), "--first-parent", branch).splitlines()
for relative in relatives:
util.debug.add_to_log('nearest_branch: Getting common commits with {}'.format(relative))
relative_commits = self.git("rev-list", "-{}".format(max_revisions),
"--first-parent", relative).splitlines()

# Enumerate over branch vs relative commit hashes and look for a common one
common = None
for line in diff.compare(branch_commits, relative_commits):
if not line.startswith(' '):
util.debug.add_to_log('nearest_branch: commit differs {}'.format(line))
continue
common = line.strip()
util.debug.add_to_log('nearest_branch: found common commit {}'.format(common))
break

if not common:
util.debug.add_to_log('nearest_branch: No common commit found with {}'.format(relative))
continue

# Found common "branch-out node", get reachable branches for commit
branches = self.git("branch", "--contains", common, "--merged").splitlines()
cleaned_branch_names = [b[2:].strip() for b in branches]
util.debug.add_to_log('nearest_branch: got valid branches {}'.format(cleaned_branch_names))
if relative in cleaned_branch_names:
return relative

return None

def nearest_branch(self, branch, default="master"):
"""
Find the nearest commit in current branch history that exists
Expand All @@ -79,7 +42,6 @@ def nearest_branch(self, branch, default="master"):
http://stackoverflow.com/a/17843908/484127
http://stackoverflow.com/questions/1527234
"""
start = time.time()
try:
relatives = self.branch_relatives(branch)
except GitSavvyError:
Expand All @@ -89,23 +51,8 @@ def nearest_branch(self, branch, default="master"):
util.debug.add_to_log('nearest_branch: No relatives found. '
'Possibly on a root branch!')
return default

util.debug.add_to_log('nearest_branch: found {} relatives: {}'.format(
len(relatives), relatives))

nearest = self._nearest_from_relatives(relatives, branch)

end = time.time()
util.debug.add_to_log('nearest_branch: Located nearest branch in {:.4f}'
' seconds'.format(end - start))

if not nearest:
util.debug.add_to_log('nearest_branch: No valid nearest found. '
'Possibly on a root / detached branch!')
return default

# if same as branch, return default instead
if branch == nearest:
util.debug.add_to_log('nearest_branch: Best candidate is source branch; using default')
return default
util.debug.add_to_log('nearest_branch: Found best candidate {}'.format(nearest))
return nearest
return relatives[0]