@@ -1031,26 +1031,29 @@ def pull(
1031
1031
def init (
1032
1032
self ,
1033
1033
* ,
1034
- template : str | None = None ,
1034
+ template : str | pathlib . Path | None = None ,
1035
1035
separate_git_dir : StrOrBytesPath | None = None ,
1036
1036
object_format : t .Literal ["sha1" , "sha256" ] | None = None ,
1037
1037
branch : str | None = None ,
1038
1038
initial_branch : str | None = None ,
1039
1039
shared : bool
1040
- | Literal [false , true , umask , group , all , world , everybody ]
1041
- | str
1040
+ | t . Literal [" false" , " true" , " umask" , " group" , " all" , " world" , " everybody" ]
1041
+ | str # Octal number string (e.g., "0660")
1042
1042
| None = None ,
1043
1043
quiet : bool | None = None ,
1044
1044
bare : bool | None = None ,
1045
+ ref_format : t .Literal ["files" , "reftable" ] | None = None ,
1046
+ default : bool | None = None ,
1045
1047
# libvcs special behavior
1046
1048
check_returncode : bool | None = None ,
1049
+ make_parents : bool = True ,
1047
1050
** kwargs : t .Any ,
1048
1051
) -> str :
1049
1052
"""Create empty repo. Wraps `git init <https://git-scm.com/docs/git-init>`_.
1050
1053
1051
1054
Parameters
1052
1055
----------
1053
- template : str, optional
1056
+ template : str | pathlib.Path , optional
1054
1057
Directory from which templates will be used. The template directory
1055
1058
contains files and directories that will be copied to the $GIT_DIR
1056
1059
after it is created. The template directory will be one of the
@@ -1084,17 +1087,27 @@ def init(
1084
1087
- umask: Use permissions specified by umask
1085
1088
- group: Make the repository group-writable
1086
1089
- all, world, everybody: Same as world, make repo readable by all users
1087
- - An octal number: Explicit mode specification (e.g., "0660")
1090
+ - An octal number string : Explicit mode specification (e.g., "0660")
1088
1091
quiet : bool, optional
1089
1092
Only print error and warning messages; all other output will be
1090
1093
suppressed. Useful for scripting.
1091
1094
bare : bool, optional
1092
1095
Create a bare repository. If GIT_DIR environment is not set, it is set
1093
1096
to the current working directory. Bare repositories have no working
1094
1097
tree and are typically used as central repositories.
1098
+ ref_format : "files" | "reftable", optional
1099
+ Specify the reference storage format. Requires git version >= 2.37.0.
1100
+ - files: Classic format with packed-refs and loose refs (default)
1101
+ - reftable: New format that is more efficient for large repositories
1102
+ default : bool, optional
1103
+ Use default permissions for directories and files. This is the same as
1104
+ running git init without any options.
1095
1105
check_returncode : bool, optional
1096
1106
If True, check the return code of the git command and raise a
1097
1107
CalledProcessError if it is non-zero.
1108
+ make_parents : bool, default: True
1109
+ If True, create the target directory if it doesn't exist. If False,
1110
+ raise an error if the directory doesn't exist.
1098
1111
1099
1112
Returns
1100
1113
-------
@@ -1105,6 +1118,10 @@ def init(
1105
1118
------
1106
1119
CalledProcessError
1107
1120
If the git command fails and check_returncode is True.
1121
+ ValueError
1122
+ If invalid parameters are provided.
1123
+ FileNotFoundError
1124
+ If make_parents is False and the target directory doesn't exist.
1108
1125
1109
1126
Examples
1110
1127
--------
@@ -1146,6 +1163,14 @@ def init(
1146
1163
>>> git.init(shared='group')
1147
1164
'Initialized empty shared Git repository in ...'
1148
1165
1166
+ Create with octal permissions:
1167
+
1168
+ >>> shared_repo = tmp_path / 'shared_octal_example'
1169
+ >>> shared_repo.mkdir()
1170
+ >>> git = Git(path=shared_repo)
1171
+ >>> git.init(shared='0660')
1172
+ 'Initialized empty shared Git repository in ...'
1173
+
1149
1174
Create with a template directory:
1150
1175
1151
1176
>>> template_repo = tmp_path / 'template_example'
@@ -1218,18 +1243,31 @@ def init(
1218
1243
shared_str .isdigit ()
1219
1244
and len (shared_str ) <= 4
1220
1245
and all (c in string .octdigits for c in shared_str )
1246
+ and int (shared_str , 8 ) <= 0o777 # Validate octal range
1221
1247
)
1222
1248
):
1223
1249
msg = (
1224
1250
f"Invalid shared value. Must be one of { valid_shared_values } "
1225
- "or an octal number"
1251
+ "or a valid octal number between 0000 and 0777 "
1226
1252
)
1227
1253
raise ValueError (msg )
1228
1254
local_flags .append (f"--shared={ shared } " )
1255
+
1229
1256
if quiet is True :
1230
1257
local_flags .append ("--quiet" )
1231
1258
if bare is True :
1232
1259
local_flags .append ("--bare" )
1260
+ if ref_format is not None :
1261
+ local_flags .append (f"--ref-format={ ref_format } " )
1262
+ if default is True :
1263
+ local_flags .append ("--default" )
1264
+
1265
+ # libvcs special behavior
1266
+ if make_parents and not self .path .exists ():
1267
+ self .path .mkdir (parents = True )
1268
+ elif not self .path .exists ():
1269
+ msg = f"Directory does not exist: { self .path } "
1270
+ raise FileNotFoundError (msg )
1233
1271
1234
1272
return self .run (
1235
1273
["init" , * local_flags , "--" , * required_flags ],
@@ -2863,7 +2901,7 @@ def set_url(
2863
2901
)
2864
2902
2865
2903
2866
- GitRemoteManagerLiteral = Literal [
2904
+ GitRemoteManagerLiteral = t . Literal [
2867
2905
"--verbose" ,
2868
2906
"add" ,
2869
2907
"rename" ,
@@ -2933,7 +2971,7 @@ def run(
2933
2971
# Pass-through to run()
2934
2972
log_in_real_time : bool = False ,
2935
2973
check_returncode : bool | None = None ,
2936
- ** kwargs : Any ,
2974
+ ** kwargs : t . Any ,
2937
2975
) -> str :
2938
2976
"""Run a command against a git repository's remotes.
2939
2977
0 commit comments