Git_Ctrl.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. # -*- coding: <encoding name> -*-
  2. from git import Repo
  3. from os.path import split, exists
  4. import os
  5. import subprocess
  6. from time import time
  7. import random
  8. sys_seeting = dict(
  9. shell=True,
  10. stdin=subprocess.PIPE,
  11. stdout=subprocess.PIPE,
  12. stderr=subprocess.STDOUT,
  13. universal_newlines=True)
  14. git_path = 'git' # git的地址,如果配置了环境变量则不需要修改
  15. stopKey = '【操作完成】' # 存储stopKey的global变量
  16. passwd = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM' # stopKey的候选词库
  17. class git_Repo: # git的基类
  18. def __init__(self, Dic, *args, **kwargs):
  19. self.url = None
  20. try:
  21. if exists(Dic + r'/.git'): # 是否为git 仓库
  22. pass
  23. elif Dic[-4:] == '.git':
  24. Dic = Dic[:-5] # -5,得把/去掉
  25. else:
  26. raise Exception
  27. except BaseException:
  28. subprocess.Popen(
  29. f'{git_path} init',
  30. cwd=self.Repo_Dic,
  31. **sys_seeting).wait()
  32. self.Repo_Dic = Dic # 仓库地址(末尾不带/)
  33. self.repo = Repo(Dic)
  34. self.name = split(Dic)[-1]
  35. self.have_clone = True
  36. def make_stopKey(self): # 生成一个随机stopKey
  37. global stopKey, passwd
  38. code = ''
  39. for _ in range(8): # 八位随机数
  40. code += passwd[random.randint(0, len(passwd) - 1)] # 时间戳+8位随机数
  41. stopKey = (str(time()) + code).replace('.', '')
  42. return stopKey
  43. def Flie_List(self, file_list, is_file=True, pat=' '):
  44. if file_list == '.':
  45. file = '..'
  46. else:
  47. file_ = []
  48. for i in file_list:
  49. if i[:len(self.Repo_Dic)] == self.Repo_Dic:
  50. file_.append(i[len(self.Repo_Dic) + 1:]) # +1是为了去除/
  51. if not is_file:
  52. return file_
  53. file = pat.join(file_)
  54. return file
  55. def dir_list(self, all=True):
  56. listfile = []
  57. if all:
  58. listfile += [
  59. f'[当前分支] {self.repo.active_branch} 工作区{"不" if self.repo.is_dirty() else ""}干净 -> {self.name}']
  60. listfile += [f'{"[配置文件]" if i == ".git" else "[未跟踪]"if i in self.repo.untracked_files else "[已跟踪]"} {i}'
  61. for i in os.listdir(self.Repo_Dic)]
  62. return listfile
  63. def Add_File(self, file_list):
  64. file = self.Flie_List(file_list)
  65. return subprocess.Popen(
  66. f'echo 添加文件... && {git_path} add {file} && echo {self.make_stopKey()}',
  67. cwd=self.Repo_Dic,
  68. **sys_seeting)
  69. def Reset_File(self, file_list):
  70. file = self.Flie_List(file_list)
  71. return subprocess.Popen(
  72. f'echo 撤销文件... && {git_path} rm --cached {file} && echo {self.make_stopKey()}',
  73. cwd=self.Repo_Dic,
  74. **sys_seeting)
  75. def Commit_File(self, m):
  76. return subprocess.Popen(
  77. f'echo 提交文件: && {git_path} commit -m "{m}" && echo {self.make_stopKey()}',
  78. cwd=self.Repo_Dic,
  79. **sys_seeting)
  80. def Status(self): # 执行status
  81. return subprocess.Popen(
  82. f'echo 仓库状态: && {git_path} status && echo {self.make_stopKey()}',
  83. cwd=self.Repo_Dic,
  84. **sys_seeting)
  85. def Log(self, graph, pretty, abbrev): # 执行log
  86. args = ''
  87. if graph:
  88. args += ' --graph'
  89. if pretty:
  90. args += ' --pretty=oneline'
  91. if abbrev:
  92. args += ' --abbrev-commit'
  93. return subprocess.Popen(
  94. f'echo 仓库日志: && {git_path} log{args} && echo {self.make_stopKey()}',
  95. cwd=self.Repo_Dic,
  96. **sys_seeting)
  97. def refLog(self): # 执行reflog
  98. return subprocess.Popen(
  99. f'echo 操作记录: && {git_path} reflog && echo {self.make_stopKey()}',
  100. cwd=self.Repo_Dic,
  101. **sys_seeting)
  102. def Diff_File(self, MASTER='HEAD'): # 执行diff
  103. return subprocess.Popen(
  104. f'echo 文件日志: && {git_path} diff {MASTER} && echo {self.make_stopKey()}',
  105. cwd=self.Repo_Dic,
  106. **sys_seeting)
  107. def reset(self, HEAD='HEAD~1', Type=0):
  108. if Type == 0:
  109. type_ = '--mixed' # 退回到工作区
  110. elif Type == 1:
  111. type_ = '--soft' # 退回到暂存区
  112. else:
  113. type_ = '--hard' # 退回到暂存区
  114. return subprocess.Popen(
  115. f'echo 回退... && {git_path} reset {type_} {HEAD} && echo {self.make_stopKey()}',
  116. cwd=self.Repo_Dic,
  117. **sys_seeting)
  118. def checkout(self, file_list):
  119. if len(file_list) >= 1: # 多于一个文件,不用--,空格
  120. file = self.Flie_List(file_list, pat=' ')
  121. return subprocess.Popen(
  122. f'echo 丢弃修改: && {git_path} checkout {file} && echo {self.make_stopKey()}',
  123. cwd=self.Repo_Dic,
  124. **sys_seeting)
  125. elif len(file_list) == 1:
  126. return subprocess.Popen(
  127. f'echo 丢弃修改: && {git_path} checkout -- {file_list[0]} && echo {self.make_stopKey()}',
  128. cwd=self.Repo_Dic,
  129. **sys_seeting)
  130. else:
  131. return subprocess.Popen(
  132. f'echo 丢弃修改: && {git_path} checkout * && echo {self.make_stopKey()}',
  133. cwd=self.Repo_Dic,
  134. **sys_seeting)
  135. def rm(self, file_list): # 删除版本库中的文件
  136. file = self.Flie_List(file_list)
  137. return subprocess.Popen(
  138. f'echo 删除... && {git_path} rm {file}',
  139. cwd=self.Repo_Dic,
  140. **sys_seeting)
  141. def check_Branch(self): # 查看本地分支和远程分支
  142. return subprocess.Popen(
  143. f'echo 仓库分支: && {git_path} branch -a && echo 远程仓库信息: && {git_path} remote -v && '
  144. f'echo 分支详情: && {git_path} branch -vv && echo {self.make_stopKey()}',
  145. cwd=self.Repo_Dic,
  146. **sys_seeting)
  147. def new_Branch(self, branch_name, origin): # 新建分支
  148. return subprocess.Popen(
  149. f'echo 新建分支... && {git_path} branch {branch_name} {origin} && echo {self.make_stopKey()}',
  150. cwd=self.Repo_Dic,
  151. **sys_seeting)
  152. def switch_Branch(self, branch_name): # 切换分支
  153. return subprocess.Popen(
  154. f'echo 切换分支... && {git_path} switch {branch_name} && echo {self.make_stopKey()}',
  155. cwd=self.Repo_Dic,
  156. **sys_seeting)
  157. def del_Branch(self, branch_name, del_type): # 删除分支
  158. return subprocess.Popen(
  159. f'echo 删除分支... && {git_path} branch -{del_type} {branch_name} && echo {self.make_stopKey()}',
  160. cwd=self.Repo_Dic,
  161. **sys_seeting)
  162. def merge_Branch(self, branch_name, no_ff, m=''): # 合并分支
  163. if no_ff:
  164. no_ff = f' --no-ff -m "{m}"' # --no-ff前有空格
  165. else:
  166. no_ff = ''
  167. return subprocess.Popen(
  168. f'echo 合并分支... && {git_path} merge{no_ff} {branch_name} && echo {self.make_stopKey()}',
  169. cwd=self.Repo_Dic,
  170. **sys_seeting)
  171. def merge_abort(self): # 退出冲突处理
  172. return subprocess.Popen(
  173. f'echo 冲突处理退出... && {git_path} merge --abort && echo {self.make_stopKey()}',
  174. cwd=self.Repo_Dic,
  175. **sys_seeting)
  176. def Save_stash(self): # 保存工作区
  177. return subprocess.Popen(
  178. f'echo 保存工作区... && {git_path} stash && echo {self.make_stopKey()}',
  179. cwd=self.Repo_Dic,
  180. **sys_seeting)
  181. def Stash_List(self): # 工作区列表
  182. return subprocess.Popen(
  183. f'echo 工作区列表: && {git_path} stash list && echo {self.make_stopKey()}',
  184. cwd=self.Repo_Dic,
  185. **sys_seeting)
  186. def Apply_stash(self, stash_num='0'): # 恢复工作区
  187. return subprocess.Popen(
  188. f'echo 恢复工作区... && {git_path} stash apply stash@{{{stash_num}}} && echo {self.make_stopKey()}',
  189. cwd=self.Repo_Dic,
  190. **sys_seeting)
  191. def Drop_stash(self, stash_num='0'): # 删除工作区
  192. return subprocess.Popen(
  193. f'echo 删除工作区... && {git_path} stash drop stash@{{{stash_num}}} && echo {self.make_stopKey()}',
  194. cwd=self.Repo_Dic,
  195. **sys_seeting)
  196. def cherry_pick(self, commit): # 补丁
  197. return subprocess.Popen(
  198. f'echo 补丁... && {git_path} cherry-pick {commit} && echo {self.make_stopKey()}',
  199. cwd=self.Repo_Dic,
  200. **sys_seeting)
  201. def Del_remote(self, remote_name):
  202. return subprocess.Popen(
  203. f'echo 删除远程仓库... && {git_path} remote remove {remote_name} && echo {self.make_stopKey()}',
  204. cwd=self.Repo_Dic,
  205. **sys_seeting)
  206. def Add_remote(self, remote, remote_name):
  207. return subprocess.Popen(
  208. f'echo 添加远程仓库... && {git_path} remote add {remote_name} {remote} && echo {self.make_stopKey()}',
  209. cwd=self.Repo_Dic,
  210. **sys_seeting)
  211. def Bind_remote(self, local_name, remote_name):
  212. return subprocess.Popen(
  213. f'echo 分支绑定... && {git_path} branch --set-upstream-to={remote_name} {local_name} && echo {self.make_stopKey()}',
  214. cwd=self.Repo_Dic,
  215. **sys_seeting)
  216. def push_Tag(self, tag, remote_name):
  217. return subprocess.Popen(
  218. f'echo 推送标签... && {git_path} push {remote_name} {tag} && echo {self.make_stopKey()}',
  219. cwd=self.Repo_Dic,
  220. **sys_seeting)
  221. def del_tag(self, tag):
  222. return subprocess.Popen(
  223. f'echo 删除本地标签... && {git_path} tag -d {tag} && echo {self.make_stopKey()}',
  224. cwd=self.Repo_Dic,
  225. **sys_seeting)
  226. def Add_Tag(self, tag, commit, message=''):
  227. a = ' -a'
  228. if message != '':
  229. message = f' -m "{message}"' # 自带空格
  230. else:
  231. a = ''
  232. if commit != '':
  233. commit = f' {commit}' # 自带空格
  234. return subprocess.Popen(
  235. f'echo 添加标签... && {git_path} tag{a} {tag}{commit}{message} && echo {self.make_stopKey()}',
  236. cwd=self.Repo_Dic,
  237. **sys_seeting)
  238. def Tag(self, condition=''):
  239. if condition != '':
  240. condition = f' -l {condition}'
  241. return subprocess.Popen(
  242. f'echo 标签列表: && {git_path} tag{condition} && echo {self.make_stopKey()}',
  243. cwd=self.Repo_Dic,
  244. **sys_seeting)
  245. def show_new(self, condition):
  246. return subprocess.Popen(
  247. f'echo 查询结果: && {git_path} show {condition} && echo {self.make_stopKey()}',
  248. cwd=self.Repo_Dic,
  249. **sys_seeting)
  250. def Pull_Push_remote(
  251. self,
  252. Pull_Push=0,
  253. remote='',
  254. remote_branch='',
  255. local='',
  256. allow=False,
  257. u=False,
  258. f=False):
  259. # 处理逻辑
  260. # 1)remote去斜杠第一个作为主机名字
  261. # 2) 从remote分离主机名(如果没指定)
  262. # 3) 如果local为空,用HEAD填充
  263. # 4) 如果以上后,主机名仍为空,则local和分支均为空
  264. split = remote.split('/')
  265. try:
  266. remote_name = split[0] # 获取主机名 1)
  267. except BaseException:
  268. remote_name = '' # 没有主机名 1)
  269. branch_split = remote_branch.split('/')
  270. if len(branch_split) >= 2 and remote_name == '':
  271. remote_name = branch_split[0] # 2)
  272. remote_branch = '/'.join(branch_split[1:]) # 2)
  273. if local.replace(' ', '') == '':
  274. local = 'HEAD' # 3)
  275. if remote_name == '': # 4)
  276. branch = ''
  277. else:
  278. if Pull_Push == 1:
  279. # 注意,local不可以为空,也不会为空
  280. if remote_branch != '':
  281. # git push <远程主机名> <本地分支名>:<远程分支名>
  282. branch = f'{local}:{remote_branch}'
  283. else:
  284. branch = f'{local}' # 要去掉冒号
  285. else:
  286. if remote_branch != 'HEAD':
  287. # git push <远程主机名> <本地分支名>:<远程分支名>
  288. branch = f'{remote_branch}:{local}'
  289. else:
  290. branch = f'{remote_branch}'
  291. if allow:
  292. history = ' --allow-unrelated-histories'
  293. else:
  294. history = ''
  295. push_pull = {
  296. 0: "pull",
  297. 1: f"push{' -u' if u else ''}{' -f' if f else ''}"}
  298. return subprocess.Popen(
  299. f'''echo 与服务器连接... && {git_path} {push_pull.get(Pull_Push,"pull")}{history} {remote_name} {branch} && echo {self.make_stopKey()}''',
  300. cwd=self.Repo_Dic,
  301. **sys_seeting)
  302. def del_Branch_remote(self, remote, remote_branch):
  303. split = remote.split('/')
  304. try:
  305. remote_name = split[0] # 获取主机名 1)
  306. except BaseException:
  307. remote_name = '' # 没有主机名 1)
  308. branch_split = remote_branch.split('/')
  309. if len(branch_split) >= 2 and remote_name == '':
  310. remote_name = branch_split[0] # 2)
  311. remote_branch = '/'.join(branch_split[1:]) # 2)
  312. return subprocess.Popen(
  313. f'echo 删除远程分支... && {git_path} push {remote_name} :{remote_branch} && echo {self.make_stopKey()}',
  314. cwd=self.Repo_Dic,
  315. **sys_seeting)
  316. def del_Tag_remote(self, remote, tag):
  317. return subprocess.Popen(
  318. f'echo 删除远程标签... && {git_path} push {remote} :refs/tags/{tag} && echo {self.make_stopKey()}',
  319. cwd=self.Repo_Dic,
  320. **sys_seeting)
  321. def fetch(self, remote, remote_branch, local):
  322. # 处理逻辑
  323. # 1)remote去斜杠第一个作为主机名字
  324. # 2) 从remote分离主机名(如果没指定)
  325. # 3) 如果local为空,用HEAD填充
  326. # 4) 如果以上后,主机名仍为空,则local和分支均为空
  327. split = remote.split('/')
  328. try:
  329. remote_name = split[0] # 获取主机名 1)
  330. except BaseException:
  331. remote_name = '' # 没有主机名 1)
  332. branch_split = remote_branch.split('/')
  333. if len(branch_split) >= 2 and remote_name == '':
  334. remote_name = branch_split[0] # 2)
  335. remote_branch = '/'.join(branch_split[1:]) # 2)
  336. if local.replace(' ', '') == '':
  337. local = 'HEAD' # 3)
  338. if remote_name == '': # 4)
  339. branch = ''
  340. else:
  341. if remote_branch != 'HEAD':
  342. # git push <远程主机名> <本地分支名>:<远程分支名>
  343. branch = f'{remote_branch}:{local}'
  344. else:
  345. branch = f'{remote_branch}'
  346. return subprocess.Popen(
  347. f'''echo 更新远程仓库... && {git_path} fetch {remote_name} {branch} && echo {self.make_stopKey()}''',
  348. cwd=self.Repo_Dic,
  349. **sys_seeting)
  350. def Customize(self, command: str):
  351. return subprocess.Popen(command, cwd=self.Repo_Dic, **sys_seeting)
  352. def Clone(self, url):
  353. return subprocess.Popen(
  354. f'echo 克隆操作不被允许 && echo {self.make_stopKey()}',
  355. cwd=self.Repo_Dic,
  356. **sys_seeting)
  357. def make_Dir(self, dir):
  358. if len(dir) == '':
  359. return dir
  360. inside = '/'
  361. if dir[0] == '/':
  362. inside = ''
  363. return self.Repo_Dic + inside + dir
  364. def reset_File(self, hard, file_list): # 注意版本回退是:Reset_File
  365. file = self.Flie_List(file_list)
  366. return subprocess.Popen(
  367. f'''echo 回退文件... && {git_path} reset {hard} {file} && echo {self.make_stopKey()}''',
  368. cwd=self.Repo_Dic, **sys_seeting)
  369. def Branch_new(self, old_name, new_name):
  370. return subprocess.Popen(
  371. f'''echo 回退文件... && {git_path} branch -m {old_name} {new_name} && echo {self.make_stopKey()}''',
  372. cwd=self.Repo_Dic, **sys_seeting)
  373. class Clone_git(git_Repo): # Clone一个git
  374. def __init__(self, Dic, *args, **kwargs):
  375. self.Repo_Dic = Dic # 仓库地址
  376. self.url = None
  377. self.name = split(Dic)[-1]
  378. self.have_clone = False
  379. def Clone(self, url):
  380. if self.have_clone:
  381. super(Clone_git, self).Clone(url)
  382. self.have_clone = True
  383. return subprocess.Popen(
  384. f'echo 正在克隆... && {git_path} clone {url} {self.Repo_Dic}',
  385. cwd=split(
  386. self.Repo_Dic)[0],
  387. **sys_seeting)
  388. def after_Clone(self):
  389. self.repo = Repo(self.Repo_Dic)
  390. class git_Ctrol:
  391. def __init__(self):
  392. self.git_Dic = {} # 名字-文件位置
  393. self.gitType_Dic = {} # 名字-类型
  394. def Add_init(self, Dic, **kwargs):
  395. git = git_Repo(Dic)
  396. self.git_Dic[git.name] = git
  397. self.gitType_Dic[git.name] = 'init'
  398. return git.name
  399. def Clone_init(self, Dic, **kwargs):
  400. git = Clone_git(Dic)
  401. self.git_Dic[git.name] = git
  402. self.gitType_Dic[git.name] = 'clone'
  403. return git.name
  404. def get_git(self, name):
  405. return self.git_Dic[name]
  406. def get_git_Dic(self):
  407. return self.git_Dic.copy()
  408. def get_Dir(self, name):
  409. return self.get_git(name).dir_list()
  410. def add_File(self, name, dic_list):
  411. return self.get_git(name).Add_File(dic_list)
  412. def reset_File(self, name, dic_list):
  413. return self.get_git(name).Reset_File(dic_list) # 移除出去暂存区
  414. def commit_File(self, name, m):
  415. return self.get_git(name).Commit_File(m)
  416. def log(self, name, graph, pretty, abbrev):
  417. return self.get_git(name).Log(graph, pretty, abbrev)
  418. def reflog(self, name):
  419. return self.get_git(name).refLog()
  420. def status(self, name):
  421. return self.get_git(name).Status()
  422. def diff_File(self, name, MASTER):
  423. return self.get_git(name).diff(MASTER)
  424. def back_version(self, name, HEAD, Type=0):
  425. return self.get_git(name).reset(HEAD, Type) # 版本回退HEAD
  426. def back_version_file(self, name, HEAD, File_list):
  427. return self.get_git(name).reset_File(HEAD, File_list) # 文件回退
  428. def checkout_version(self, name, file):
  429. return self.get_git(name).checkout(file) # 弹出
  430. def rm(self, name, file):
  431. return self.get_git(name).rm(file)
  432. def check_Branch(self, name):
  433. return self.get_git(name).check_Branch()
  434. def new_Branch(self, name, new_branch, origin):
  435. return self.get_git(name).new_Branch(new_branch, origin)
  436. def switch_Branch(self, name, branch_name):
  437. return self.get_git(name).switch_Branch(branch_name)
  438. def Del_Branch(self, name, branch_name, type_):
  439. d = {1: 'd', 0: 'D'}.get(type_, 'd')
  440. return self.get_git(name).del_Branch(branch_name, d)
  441. def merge_Branch(self, name, branch_name, no_ff, m):
  442. return self.get_git(name).merge_Branch(branch_name, no_ff, m)
  443. def merge_abort(self, name):
  444. return self.get_git(name).merge_abort()
  445. def Save_stash(self, name):
  446. return self.get_git(name).Save_stash()
  447. def Stash_List(self, name):
  448. return self.get_git(name).Stash_List()
  449. def Apply_stash(self, name, stash_num='0'):
  450. return self.get_git(name).Apply_stash(stash_num)
  451. def Drop_stash(self, name, stash_num='0'):
  452. return self.get_git(name).Drop_stash(stash_num)
  453. def cherry_pick(self, name, commit):
  454. return self.get_git(name).cherry_pick(commit)
  455. def Del_remote(self, name, remote_name):
  456. return self.get_git(name).Del_remote(remote_name)
  457. def Add_remote(self, name, remote, remote_name):
  458. return self.get_git(name).Add_remote(remote, remote_name)
  459. def Bind_remote(self, name, local_name, remote_name):
  460. return self.get_git(name).Bind_remote(local_name, remote_name)
  461. def Pull_remote(
  462. self,
  463. name,
  464. local_name,
  465. remote_name,
  466. remote_branch,
  467. allow=False,
  468. u=False,
  469. f=False):
  470. return self.get_git(name).Pull_Push_remote(
  471. 0, remote_name, remote_branch, local_name, allow, u, False)
  472. def Push_remote(
  473. self,
  474. name,
  475. local_name,
  476. remote_name,
  477. remote_branch,
  478. allow=False,
  479. u=False,
  480. f=False):
  481. return self.get_git(name).Pull_Push_remote(
  482. 1, remote_name, remote_branch, local_name, False, u, f) # push没有allow选项
  483. def Tag(self, name, condition=''):
  484. return self.get_git(name).Tag(condition) # push没有allow选项
  485. def show_new(self, name, condition):
  486. return self.get_git(name).show_new(condition) # push没有allow选项
  487. def Add_Tag(self, name, tag, commit, message=''):
  488. return self.get_git(name).Add_Tag(
  489. tag, commit, message) # push没有allow选项
  490. def push_Tag(self, name, tag, remoto):
  491. return self.get_git(name).push_Tag(tag, remoto)
  492. def push_allTag(self, name, remoto):
  493. return self.get_git(name).push_Tag('--tags', remoto)
  494. def del_Tag_remote(self, name, remote, tag):
  495. return self.get_git(name).del_Tag_remote(remote, tag)
  496. def del_Branch_remote(self, name, remote, remote_Branch):
  497. return self.get_git(name).del_Branch_remote(remote, remote_Branch)
  498. def del_tag(self, name, tag):
  499. return self.get_git(name).del_tag(tag)
  500. def Fetch(self, name, local_name, remote_name, remote_branch):
  501. return self.get_git(name).fetch(remote_name, remote_branch, local_name)
  502. def Customize(self, name, command: str):
  503. return self.get_git(name).Customize(command)
  504. def Clone(self, name, url):
  505. return self.get_git(name).Clone(url)
  506. def After_Clone(self, name):
  507. try:
  508. return self.get_git(name).after_Clone()
  509. except BaseException:
  510. return None
  511. def make_Dir(self, name, dir):
  512. return self.get_git(name).make_Dir(dir)
  513. def Branch_new(self, name, old_name, new_name):
  514. return self.get_git(name).Branch_new(old_name, new_name)