4
4
#
5
5
6
6
import subprocess
7
- from enum import Enum
8
7
from os import PathLike , fspath
9
8
from pathlib import Path
10
9
from typing import (
11
10
Collection ,
12
11
Iterable ,
13
12
Iterator ,
14
- List ,
15
13
Optional ,
16
14
Sequence ,
17
15
Union ,
18
16
)
19
17
18
+ from pontos .enum import StrEnum
20
19
from pontos .errors import PontosError
21
20
22
21
from ._status import StatusEntry , parse_git_status
@@ -85,7 +84,7 @@ def exec_git(
85
84
raise GitError (e .returncode , e .cmd , e .output , e .stderr ) from None
86
85
87
86
88
- class MergeStrategy (Enum ):
87
+ class MergeStrategy (StrEnum ):
89
88
"""
90
89
Possible strategies for a merge
91
90
@@ -107,7 +106,7 @@ class MergeStrategy(Enum):
107
106
SUBTREE = "subtree"
108
107
109
108
110
- class ConfigScope (Enum ):
109
+ class ConfigScope (StrEnum ):
111
110
"""
112
111
Possible scopes for git settings
113
112
@@ -126,7 +125,7 @@ class ConfigScope(Enum):
126
125
WORKTREE = "worktree"
127
126
128
127
129
- class TagSort (Enum ):
128
+ class TagSort (StrEnum ):
130
129
"""
131
130
Sorting for git tags
132
131
@@ -137,6 +136,14 @@ class TagSort(Enum):
137
136
VERSION = "version:refname"
138
137
139
138
139
+ class ResetMode (StrEnum ):
140
+ SOFT = "soft"
141
+ MIXED = "mixed"
142
+ HARD = "hard"
143
+ MERGE = "merge"
144
+ KEEP = "keep"
145
+
146
+
140
147
class Git :
141
148
"""
142
149
Run git commands as subprocesses
@@ -231,7 +238,7 @@ def rebase(
231
238
if strategy == MergeStrategy .ORT_OURS :
232
239
args .extend (["--strategy" , "ort" , "-X" , "ours" ])
233
240
else :
234
- args .extend (["--strategy" , strategy . value ])
241
+ args .extend (["--strategy" , str ( strategy ) ])
235
242
236
243
if onto :
237
244
args .extend (["--onto" , onto ])
@@ -274,32 +281,43 @@ def clone(
274
281
275
282
def push (
276
283
self ,
284
+ refspec : Optional [Union [str , Iterable [str ]]] = None ,
277
285
* ,
278
286
remote : Optional [str ] = None ,
279
287
branch : Optional [str ] = None ,
280
288
follow_tags : bool = False ,
281
289
force : Optional [bool ] = None ,
290
+ delete : Optional [bool ] = None ,
282
291
) -> None :
283
292
"""
284
293
Push changes to remote repository
285
294
286
295
Args:
296
+ refspec: Refs to push
287
297
remote: Push changes to the named remote
288
- branch: Branch to push. Will only be considered in combination with
289
- a remote.
298
+ branch: Branch to push. Will only be considered in
299
+ combination with a remote. Deprecated, use refs instead .
290
300
follow_tags: Push all tags pointing to a commit included in the to
291
- be pushed branch.
301
+ be pushed branch.
292
302
force: Force push changes.
303
+ delete: Delete remote refspec
293
304
"""
294
305
args = ["push" ]
295
306
if follow_tags :
296
307
args .append ("--follow-tags" )
297
308
if force :
298
309
args .append ("--force" )
310
+ if delete :
311
+ args .append ("--delete" )
299
312
if remote :
300
313
args .append (remote )
301
314
if branch :
302
315
args .append (branch )
316
+ if refspec :
317
+ if isinstance (refspec , str ):
318
+ args .append (refspec )
319
+ else :
320
+ args .extend (refspec )
303
321
304
322
self .exec (* args )
305
323
@@ -308,7 +326,7 @@ def config(
308
326
key : str ,
309
327
value : Optional [str ] = None ,
310
328
* ,
311
- scope : Optional [ConfigScope ] = None ,
329
+ scope : Optional [Union [ ConfigScope , str ] ] = None ,
312
330
) -> str :
313
331
"""
314
332
Get and set a git config
@@ -320,7 +338,7 @@ def config(
320
338
"""
321
339
args = ["config" ]
322
340
if scope :
323
- args .append (f"--{ scope . value } " )
341
+ args .append (f"--{ scope } " )
324
342
325
343
args .append (key )
326
344
@@ -329,7 +347,7 @@ def config(
329
347
330
348
return self .exec (* args )
331
349
332
- def cherry_pick (self , commits : Union [str , List [str ]]) -> None :
350
+ def cherry_pick (self , commits : Union [str , list [str ]]) -> None :
333
351
"""
334
352
Apply changes of a commit(s) to the current branch
335
353
@@ -348,10 +366,10 @@ def cherry_pick(self, commits: Union[str, List[str]]) -> None:
348
366
def list_tags (
349
367
self ,
350
368
* ,
351
- sort : Optional [TagSort ] = None ,
369
+ sort : Optional [Union [ TagSort , str ] ] = None ,
352
370
tag_name : Optional [str ] = None ,
353
- sort_suffix : Optional [List [str ]] = None ,
354
- ) -> List [str ]:
371
+ sort_suffix : Optional [list [str ]] = None ,
372
+ ) -> list [str ]:
355
373
"""
356
374
List all available tags
357
375
@@ -370,7 +388,7 @@ def list_tags(
370
388
args .extend (["-c" , f"versionsort.suffix={ suffix } " ])
371
389
372
390
args .extend (["tag" , "-l" ])
373
- args .append (f"--sort={ sort . value } " )
391
+ args .append (f"--sort={ sort } " )
374
392
else :
375
393
args = ["tag" , "-l" ]
376
394
@@ -463,6 +481,19 @@ def tag(
463
481
464
482
self .exec (* args )
465
483
484
+ def delete_tag (
485
+ self ,
486
+ tag : str ,
487
+ ) -> None :
488
+ """
489
+ Delete a Tag
490
+
491
+ Args:
492
+ tag: Tag name to delete
493
+ """
494
+ args = ["tag" , "-d" , tag ]
495
+ self .exec (* args )
496
+
466
497
def fetch (
467
498
self ,
468
499
remote : Optional [str ] = None ,
@@ -538,7 +569,7 @@ def log(
538
569
* log_args : str ,
539
570
oneline : Optional [bool ] = None ,
540
571
format : Optional [str ] = None ,
541
- ) -> List [str ]:
572
+ ) -> list [str ]:
542
573
"""
543
574
Get log of a git repository
544
575
@@ -614,7 +645,7 @@ def rev_list(
614
645
* commit : str ,
615
646
max_parents : Optional [int ] = None ,
616
647
abbrev_commit : Optional [bool ] = False ,
617
- ) -> List [str ]:
648
+ ) -> list [str ]:
618
649
"""
619
650
Lists commit objects in reverse chronological order
620
651
@@ -693,3 +724,30 @@ def status(
693
724
694
725
output = self .exec (* args )
695
726
return parse_git_status (output )
727
+
728
+ def reset (
729
+ self ,
730
+ commit ,
731
+ * ,
732
+ mode : Union [ResetMode , str ],
733
+ ) -> None :
734
+ """
735
+ Reset the git history
736
+
737
+ Args:
738
+ commit: Git reference to reset the checked out tree to
739
+ mode: The reset mode to use
740
+
741
+ Examples:
742
+ This will "list all the commits which are reachable from foo or
743
+ bar, but not from baz".
744
+
745
+ .. code-block:: python
746
+
747
+ from pontos.git import Git, ResetMode
748
+
749
+ git = Git()
750
+ git.reset("HEAD^", mode=ResetMode.HARD)
751
+ """
752
+ args = ["reset" , f"--{ mode } " , commit ]
753
+ self .exec (* args )
0 commit comments