@@ -5548,6 +5548,40 @@ def unset_upstream(
55485548 log_in_real_time = log_in_real_time ,
55495549 )
55505550
5551+ def track (
5552+ self ,
5553+ remote_branch : str ,
5554+ * ,
5555+ # Pass-through to run()
5556+ log_in_real_time : bool = False ,
5557+ check_returncode : bool | None = None ,
5558+ ) -> str :
5559+ """Create branch tracking a remote branch.
5560+
5561+ Wraps `git branch -t <https://git-scm.com/docs/git-branch>`_.
5562+
5563+ Parameters
5564+ ----------
5565+ remote_branch :
5566+ Remote branch to track (e.g., 'origin/main').
5567+
5568+ Examples
5569+ --------
5570+ For existing branches, use set_upstream() instead.
5571+ track() is for creating new branches that track a remote:
5572+
5573+ >>> GitBranchCmd(
5574+ ... path=example_git_repo.path,
5575+ ... branch_name='tracking-branch'
5576+ ... ).track('origin/master')
5577+ "branch 'tracking-branch' set up to track 'origin/master'."
5578+ """
5579+ return self .cmd .run (
5580+ ["branch" , "-t" , self .branch_name , remote_branch ],
5581+ check_returncode = check_returncode ,
5582+ log_in_real_time = log_in_real_time ,
5583+ )
5584+
55515585
55525586class GitBranchManager :
55535587 """Run commands directly related to git branches of a git repo."""
@@ -5660,30 +5694,80 @@ def create(self, *, branch: str) -> str:
56605694 check_returncode = False ,
56615695 )
56625696
5663- def _ls (self ) -> list [str ]:
5664- """List branches.
5697+ def _ls (
5698+ self ,
5699+ * ,
5700+ local_flags : list [str ] | None = None ,
5701+ ) -> list [str ]:
5702+ """List branches (raw output).
5703+
5704+ Parameters
5705+ ----------
5706+ local_flags :
5707+ Additional flags to pass to git branch.
56655708
56665709 Examples
56675710 --------
5668- >>> GitBranchManager(path=example_git_repo.path)._ls()
5669- ['* master']
5711+ >>> branches = GitBranchManager(path=example_git_repo.path)._ls()
5712+ >>> '* master' in branches or 'master' in str(branches)
5713+ True
56705714 """
5671- return self .run (
5672- "--list" ,
5673- ).splitlines ()
5715+ flags = ["--list" ]
5716+ if local_flags :
5717+ flags .extend (local_flags )
5718+ return self .run (local_flags = flags ).splitlines ()
56745719
5675- def ls (self ) -> QueryList [GitBranchCmd ]:
5720+ def ls (
5721+ self ,
5722+ * ,
5723+ _all : bool = False ,
5724+ remotes : bool = False ,
5725+ merged : str | None = None ,
5726+ no_merged : str | None = None ,
5727+ contains : str | None = None ,
5728+ sort : str | None = None ,
5729+ ) -> QueryList [GitBranchCmd ]:
56765730 """List branches.
56775731
5732+ Parameters
5733+ ----------
5734+ _all :
5735+ List all branches (local + remote). Maps to --all.
5736+ remotes :
5737+ List remote branches only. Maps to --remotes.
5738+ merged :
5739+ Only list branches merged into specified commit.
5740+ no_merged :
5741+ Only list branches NOT merged into specified commit.
5742+ contains :
5743+ Only list branches containing specified commit.
5744+ sort :
5745+ Sort key (e.g., '-committerdate', 'refname').
5746+
56785747 Examples
56795748 --------
5680- >>> GitBranchManager(path=example_git_repo.path).ls()
5681- [<GitBranchCmd path=... branch_name=master>]
5749+ >>> branches = GitBranchManager(path=example_git_repo.path).ls()
5750+ >>> any(b.branch_name == 'master' for b in branches)
5751+ True
56825752 """
5753+ local_flags : list [str ] = []
5754+ if _all :
5755+ local_flags .append ("--all" )
5756+ if remotes :
5757+ local_flags .append ("--remotes" )
5758+ if merged is not None :
5759+ local_flags .extend (["--merged" , merged ])
5760+ if no_merged is not None :
5761+ local_flags .extend (["--no-merged" , no_merged ])
5762+ if contains is not None :
5763+ local_flags .extend (["--contains" , contains ])
5764+ if sort is not None :
5765+ local_flags .extend (["--sort" , sort ])
5766+
56835767 return QueryList (
56845768 [
56855769 GitBranchCmd (path = self .path , branch_name = branch_name .lstrip ("* " ))
5686- for branch_name in self ._ls ()
5770+ for branch_name in self ._ls (local_flags = local_flags or None )
56875771 ],
56885772 )
56895773
0 commit comments