git cl split: Include dirname as part of branch names

This CL changes the way `git cl split` generates branch names during
upload. Specifically, it attempts to derive a common directory for all
the files in each CL, and includes that dirname as part of the branch
name, in addition to a hash of the files in the CL. This makes it a bit
easier to guess what's in a branch, given its name.

Since the hash is still included, branch names should remain unique.
Finding a common directory should be deterministic, so we can still rely
on branches having the same name if the script is re-run with the same
splitting.

Bug: 389069356
Change-Id: I70490258755f13962f3db5c835619caa24176af9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6243377
Commit-Queue: Devon Loehr <dloehr@google.com>
Reviewed-by: Josip Sokcevic <sokcevic@chromium.org>
This commit is contained in:
Devon Loehr
2025-02-07 09:47:10 -08:00
committed by LUCI CQ
parent 5a3c9438e6
commit ff733a6496
2 changed files with 26 additions and 4 deletions

View File

@@ -99,14 +99,35 @@ def EnsureInGitRepository():
git.run('rev-parse')
def CreateBranchForOneCL(prefix, files, upstream):
def CreateBranchName(prefix: str, files: List[Tuple[str, str]]) -> str:
"""
Given a sub-CL as a list of (action, file) pairs, create a unique and
deterministic branch name for it.
The name has the format <prefix>_<dirname>_<hash(files)>_split.
"""
file_names = [file for _, file in files]
if len(file_names) == 1:
# Only one file, just use its directory as the common path
common_path = os.path.dirname(file_names[0])
else:
common_path = os.path.commonpath(file_names)
if not common_path:
# Files have nothing in common at all. Unlikely but possible.
common_path = "None"
# Replace path delimiter with underscore in common_path.
common_path = common_path.replace(os.path.sep, '_')
return f"{prefix}_{HashList(files):020}_{common_path}_split"
def CreateBranchForOneCL(prefix: str, files: List[Tuple[str, str]],
upstream: str) -> bool:
"""Creates a branch named |prefix| + "_" + |hash(files)| + "_split".
Return false if the branch already exists. |upstream| is used as upstream
for the created branch.
"""
existing_branches = set(git.branches(use_limit=False))
branch_name = f'{prefix}_{HashList(files)}_split'
branch_name = CreateBranchName(prefix, files)
if branch_name in existing_branches:
return False
git.run('checkout', '-t', upstream, '-b', branch_name)