1
1
import os
2
- import shutil
3
2
import subprocess
4
3
from pathlib import Path
5
4
from urllib .parse import urlparse
24
23
from ctfcli .utils .deploy import DEPLOY_HANDLERS
25
24
from ctfcli .utils .spec import CHALLENGE_SPEC_DOCS , blank_challenge_spec
26
25
from ctfcli .utils .templates import get_template_dir
26
+ from ctfcli .utils .git import get_git_repo_head_branch
27
27
28
28
29
29
class Challenge (object ):
@@ -58,7 +58,7 @@ def add(self, repo):
58
58
# Get relative path from project root to current directory
59
59
challenge_path = Path (os .path .relpath (os .getcwd (), get_project_path ()))
60
60
61
- # Get new directory that will exist after clone
61
+ # Get new directory that will add the git subtree
62
62
base_repo_path = Path (os .path .basename (repo ).rsplit ("." , maxsplit = 1 )[0 ])
63
63
64
64
# Join targets
@@ -67,11 +67,23 @@ def add(self, repo):
67
67
68
68
config ["challenges" ][str (challenge_path )] = repo
69
69
70
+ head_branch = get_git_repo_head_branch (repo )
71
+ subprocess .call (
72
+ [
73
+ "git" ,
74
+ "subtree" ,
75
+ "add" ,
76
+ "--prefix" ,
77
+ challenge_path ,
78
+ repo ,
79
+ head_branch ,
80
+ "--squash" ,
81
+ ],
82
+ cwd = get_project_path (),
83
+ )
70
84
with open (get_config_path (), "w+" ) as f :
71
85
config .write (f )
72
86
73
- subprocess .call (["git" , "clone" , "--depth" , "1" , repo ])
74
- shutil .rmtree (str (base_repo_path / ".git" ))
75
87
elif Path (repo ).exists ():
76
88
config ["challenges" ][repo ] = repo
77
89
with open (get_config_path (), "w+" ) as f :
@@ -89,9 +101,21 @@ def restore(self, challenge=None):
89
101
if url .endswith (".git" ):
90
102
if challenge is not None and folder != challenge :
91
103
continue
92
- click .echo (f"Cloning { url } to { folder } " )
93
- subprocess .call (["git" , "clone" , "--depth" , "1" , url , folder ])
94
- shutil .rmtree (str (Path (folder ) / ".git" ))
104
+ click .echo (f"Adding git repo { url } to { folder } as subtree" )
105
+ head_branch = get_git_repo_head_branch (url )
106
+ subprocess .call (
107
+ [
108
+ "git" ,
109
+ "subtree" ,
110
+ "add" ,
111
+ "--prefix" ,
112
+ folder ,
113
+ url ,
114
+ head_branch ,
115
+ "--squash" ,
116
+ ],
117
+ cwd = get_project_path (),
118
+ )
95
119
else :
96
120
click .echo (f"Skipping { url } - { folder } " )
97
121
@@ -178,22 +202,24 @@ def update(self, challenge=None):
178
202
if challenge and challenge != folder :
179
203
continue
180
204
if url .endswith (".git" ):
181
- click .echo (f"Cloning { url } to { folder } " )
182
- subprocess .call (["git" , "init" ], cwd = folder )
183
- subprocess .call (["git" , "remote" , "add" , "origin" , url ], cwd = folder )
184
- subprocess .call (["git" , "add" , "-A" ], cwd = folder )
205
+ click .echo (f"Pulling latest { url } to { folder } " )
206
+ head_branch = get_git_repo_head_branch (url )
185
207
subprocess .call (
186
- ["git" , "commit" , "-m" , "Persist local changes (ctfcli)" ],
187
- cwd = folder ,
188
- )
189
- subprocess .call (
190
- ["git" , "pull" , "--allow-unrelated-histories" , "origin" , "master" ],
191
- cwd = folder ,
208
+ [
209
+ "git" ,
210
+ "subtree" ,
211
+ "pull" ,
212
+ "--prefix" ,
213
+ folder ,
214
+ url ,
215
+ head_branch ,
216
+ "--squash" ,
217
+ ],
218
+ cwd = get_project_path (),
192
219
)
193
220
subprocess .call (["git" , "mergetool" ], cwd = folder )
194
221
subprocess .call (["git" , "clean" , "-f" ], cwd = folder )
195
222
subprocess .call (["git" , "commit" , "--no-edit" ], cwd = folder )
196
- shutil .rmtree (str (Path (folder ) / ".git" ))
197
223
else :
198
224
click .echo (f"Skipping { url } - { folder } " )
199
225
@@ -299,3 +325,23 @@ def deploy(self, challenge, host=None):
299
325
click .secho (
300
326
f"An error occured during deployment" , fg = "red" ,
301
327
)
328
+
329
+ def push (self , challenge = None ):
330
+ config = load_config ()
331
+ challenges = dict (config ["challenges" ])
332
+ if challenge is None :
333
+ # Get relative path from project root to current directory
334
+ challenge_path = Path (os .path .relpath (os .getcwd (), get_project_path ()))
335
+ challenge = str (challenge_path )
336
+
337
+ try :
338
+ url = challenges [challenge ]
339
+ head_branch = get_git_repo_head_branch (url )
340
+ subprocess .call (
341
+ ["git" , "subtree" , "push" , "--prefix" , challenge , url , head_branch ],
342
+ cwd = get_project_path (),
343
+ )
344
+ except KeyError :
345
+ click .echo (
346
+ "Couldn't process that challenge path. Please check that the challenge is added to .ctf/config and that your path matches."
347
+ )
0 commit comments