@@ -37,7 +37,7 @@ def clone(
3737 user_params = []
3838
3939 if type == "git-svn" :
40- # just the preperation for the svn deep clone / checkout here
40+ # just the preparation for the svn deep clone / checkout here
4141 # clone will be made in update function to simplify source.py).
4242 os .makedirs (path )
4343 return
@@ -78,6 +78,38 @@ def clone(
7878 git ("clone" , "--reference-if-able" , reference , repo , normpath , * user_params )
7979
8080
81+ def create_branch_local (type , name : str , base_ref : str = "HEAD" , recreate : bool = True ):
82+ """Create a local branch.
83+
84+ :param recreate: delete and create if already exists
85+ """
86+ if type == "git-svn" :
87+ return # ignore creating branch in case of git-svn
88+
89+ assert type == "git"
90+
91+ # Check if branch exists and delete
92+ if recreate and _local_branch_exists (name ):
93+ git ("branch" , "-D" , name , _show = False )
94+
95+ # Create branch
96+ git ("branch" , name , base_ref , _show = False )
97+
98+
99+ def checkout (type , branch_name : str ):
100+ """Checkout a specific branch.
101+
102+ :param branch_name: branch name for the checkout
103+ """
104+ if type == "git-svn" :
105+ return # ignore checkout in the case of git-svn
106+
107+ assert type == "git"
108+
109+ # Checkout branch
110+ git ("checkout" , branch_name )
111+
112+
81113def is_sha (rev ):
82114 """Heuristically determine whether a revision corresponds to a commit SHA.
83115
@@ -152,7 +184,7 @@ def rebuild(type, repo): # pylint: disable=unused-argument
152184
153185 assert type == "git"
154186
155- common .show ("Rebuilding mising git repo..." , color = "message" )
187+ common .show ("Rebuilding missing git repo..." , color = "message" )
156188 git ("init" , _show = True )
157189 git ("remote" , "add" , "origin" , repo , _show = True )
158190 common .show ("Rebuilt git repo..." , color = "message" )
@@ -163,8 +195,7 @@ def changes(type, include_untracked=False, display_status=True, _show=False):
163195 status = False
164196
165197 if type == "git-svn" :
166- # ignore changes in case of git-svn
167- return status
198+ return status # ignore changes in case of git-svn
168199
169200 assert type == "git"
170201
@@ -194,6 +225,26 @@ def changes(type, include_untracked=False, display_status=True, _show=False):
194225 return status
195226
196227
228+ def am (patch , _skip = False ):
229+ """Apply a patch.
230+
231+ :param patch: the patch to be applied
232+ :param _skip: skip patch if applying fails
233+ """
234+ try :
235+ git ("am" , "--3way" , patch , _show = True )
236+ except ShellError as e :
237+ if _skip :
238+ # Check if current git am is stuck
239+ rebase_dir = git ("rev-parse" , "--git-path" , "rebase-apply" , _show = False )
240+ if rebase_dir and os .path .isdir (rebase_dir [0 ]):
241+ try :
242+ git ("am" , "--skip" , _show = True , _ignore = True )
243+ except ShellError :
244+ pass
245+ raise ShellError from e
246+
247+
197248def update (
198249 type , repo , path , * , clean = True , fetch = False , rev = None
199250): # pylint: disable=redefined-outer-name,unused-argument
@@ -241,14 +292,17 @@ def get_url(type):
241292 return git ("config" , "--get" , "remote.origin.url" , _show = False )[0 ]
242293
243294
244- def get_hash (type , _show = False ):
295+ def get_hash (type , short = False , _show = False ):
245296 """Get the current working tree's hash."""
246297 if type == "git-svn" :
247298 return "" .join (filter (str .isdigit , gitsvn ("info" , _show = _show )[4 ]))
248299
249300 assert type == "git"
250-
251- return git ("rev-parse" , "HEAD" , _show = _show , _stream = False )[0 ]
301+ args = ["rev-parse" ]
302+ if short :
303+ args .append ("--short" )
304+ args .append ("HEAD" )
305+ return git (* args , _show = _show , _stream = False )[0 ]
252306
253307
254308def get_tag ():
@@ -283,6 +337,15 @@ def get_object_rev(object_name):
283337 return commit_sha
284338
285339
340+ def _local_branch_exists (name ) -> bool :
341+ """Check if a local branch exists."""
342+ try :
343+ git ("rev-parse" , "--verify" , name , _show = False )
344+ return True
345+ except ShellError :
346+ return False
347+
348+
286349def _get_sha_from_rev (rev ):
287350 """Get a rev-parse string's hash."""
288351 if "@{" in rev :
0 commit comments