Git_Ctrl.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. # -*- coding: <encoding name> -*-
  2. from git import Repo
  3. from os.path import split,exists
  4. import os
  5. import subprocess
  6. sys_seeting = dict(shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,universal_newlines=True)
  7. git_path = 'git'
  8. class git_Repo:#git的基类
  9. def __init__(self,Dic,name,*args,**kwargs):
  10. self.Repo_Dic = Dic # 仓库地址
  11. self.url = None
  12. if not exists(Dic + r'/.git'): # 是否为git 仓库
  13. subprocess.Popen(f'{git_path} init',cwd=self.Repo_Dic,**sys_seeting).wait()
  14. self.repo = Repo(Dic)
  15. self.name = name
  16. def Flie_List(self,file_list,is_file=True,pat=' '):
  17. if file_list == '.':
  18. file = '.'
  19. else:
  20. file_ = []
  21. for i in file_list:
  22. if i[:len(self.Repo_Dic)] == self.Repo_Dic:
  23. file_.append(i[len(self.Repo_Dic) + 1:]) # +1是为了去除/
  24. if not is_file:return file_
  25. file = pat.join(file_)
  26. return file
  27. def dir_list(self,all=True):
  28. listfile = []
  29. if all:
  30. listfile += [f'[当前分支] {self.repo.active_branch} 工作区{"不" if self.repo.is_dirty() else ""}干净 -> {self.name}']
  31. listfile += [f'{"[配置文件]" if i == ".git" else "[未跟踪]"if i in self.repo.untracked_files else "[已跟踪]"} {i}'
  32. for i in os.listdir(self.Repo_Dic)]
  33. return listfile
  34. def Add_File(self,file_list):
  35. file = self.Flie_List(file_list)
  36. return subprocess.Popen(f'{git_path} add {file}',cwd=self.Repo_Dic,**sys_seeting)
  37. def Commit_File(self,m):
  38. return subprocess.Popen(f'{git_path} commit -m "{m}"',cwd=self.Repo_Dic,**sys_seeting)
  39. def Status(self):#执行status
  40. return subprocess.Popen(f'{git_path} status',cwd=self.Repo_Dic,**sys_seeting)
  41. def Log(self):#执行log
  42. return subprocess.Popen(f'{git_path} log',cwd=self.Repo_Dic,**sys_seeting)
  43. def refLog(self):#执行reflog
  44. return subprocess.Popen(f'{git_path} reflog',cwd=self.Repo_Dic,**sys_seeting)
  45. def Diff_File(self,MASTER='HEAD'):#执行diff
  46. return subprocess.Popen(f'{git_path} diff {MASTER}',cwd=self.Repo_Dic,**sys_seeting)
  47. def reset(self,HEAD='HEAD~1'):
  48. return subprocess.Popen(f'{git_path} reset --hard {HEAD}',cwd=self.Repo_Dic,**sys_seeting)
  49. def checkout(self,file_list):
  50. if len(file_list) >= 1:#多于一个文件,不用--,空格
  51. file = self.Flie_List(file_list,pat=' ')
  52. return subprocess.Popen(f'{git_path} checkout {file}',cwd=self.Repo_Dic,**sys_seeting)
  53. elif len(file_list) == 1:
  54. return subprocess.Popen(f'{git_path} checkout -- {file_list[0]}', cwd=self.Repo_Dic, **sys_seeting)
  55. else:
  56. return subprocess.Popen(f'{git_path} checkout *', cwd=self.Repo_Dic, **sys_seeting)
  57. def rm(self,file_list):#删除版本库中的文件
  58. file = self.Flie_List(file_list)
  59. return subprocess.Popen(f'{git_path} rm {file}', cwd=self.Repo_Dic,**sys_seeting)
  60. def check_Branch(self):#查看本地分支和远程分支
  61. return subprocess.Popen(f'echo 仓库分支:&&{git_path} branch -a&&echo 远程仓库信息:&&{git_path} remote -v',
  62. cwd=self.Repo_Dic,**sys_seeting)
  63. def new_Branch(self,branch_name, origin):#新建分支
  64. return subprocess.Popen(f'{git_path} branch {branch_name} {origin}', cwd=self.Repo_Dic,**sys_seeting)
  65. def switch_Branch(self,branch_name):#切换分支
  66. return subprocess.Popen(f'{git_path} switch {branch_name}', cwd=self.Repo_Dic,**sys_seeting)
  67. def del_Branch(self,branch_name,del_type):#删除分支
  68. return subprocess.Popen(f'{git_path} branch -{del_type} {branch_name}', cwd=self.Repo_Dic,**sys_seeting)
  69. def merge_Branch(self,branch_name,no_ff,m=''):#合并分支
  70. if no_ff:no_ff = f' --no-ff -m "{m}"'#--no-ff前有空格
  71. else:no_ff = ''
  72. return subprocess.Popen(f'{git_path} merge{no_ff} {branch_name}', cwd=self.Repo_Dic,**sys_seeting)
  73. def merge_abort(self):#退出冲突处理
  74. return subprocess.Popen(f'{git_path} merge --abort', cwd=self.Repo_Dic,**sys_seeting)
  75. def Save_stash(self):#保存工作区
  76. return subprocess.Popen(f'{git_path} stash', cwd=self.Repo_Dic,**sys_seeting)
  77. def Stash_List(self):#保存工作区
  78. return subprocess.Popen(f'{git_path} stash list', cwd=self.Repo_Dic,**sys_seeting)
  79. def Apply_stash(self,stash_num = '0'):#保存工作区
  80. return subprocess.Popen(f'{git_path} stash apply stash@{{{stash_num}}}', cwd=self.Repo_Dic,**sys_seeting)
  81. def Drop_stash(self,stash_num = '0'):#保存工作区
  82. return subprocess.Popen(f'{git_path} stash drop stash@{{{stash_num}}}', cwd=self.Repo_Dic,**sys_seeting)
  83. def cherry_pick(self,commit):#保存工作区
  84. return subprocess.Popen(f'{git_path} cherry-pick {commit}', cwd=self.Repo_Dic,**sys_seeting)
  85. def Add_remote(self,remote,remote_name):
  86. return subprocess.Popen(f'{git_path} remote add {remote_name} {remote}', cwd=self.Repo_Dic, **sys_seeting)
  87. def Bind_remote(self,local_name,remote_name):
  88. return subprocess.Popen(f'{git_path} branch --set-upstream-to={remote_name} {local_name}', cwd=self.Repo_Dic,
  89. **sys_seeting)
  90. def Add_Tag(self,tag,commit,message=''):
  91. if message != '':
  92. message = f' -m "{message}"'#自带空格
  93. if commit != '':
  94. commit = f' {commit}'#自带空格
  95. return subprocess.Popen(f'{git_path} tag -a {tag}{commit}{message}', cwd=self.Repo_Dic,
  96. **sys_seeting)
  97. def Tag(self,condition=''):
  98. if condition != '':
  99. condition = f' -l {condition}'
  100. return subprocess.Popen(f'{git_path} tag{condition}', cwd=self.Repo_Dic,**sys_seeting)
  101. def show_new(self,condition):
  102. return subprocess.Popen(f'{git_path} show {condition}', cwd=self.Repo_Dic, **sys_seeting)
  103. def Pull_Push_remote(self,Pull_Push=0,remote='',local='',allow=False,u=False):
  104. split = remote.split('/')
  105. try:
  106. remote_name = ' '.join(split[0:2])
  107. except:
  108. remote_name = remote
  109. local = ''
  110. if allow:
  111. history = ' --allow-unrelated-histories'
  112. else:
  113. history = ''
  114. return subprocess.Popen(f'''{git_path} { {0:"pull",1:f"push{' -u' if u else ''}"}.get(Pull_Push,"pull") }{history} {remote_name} {local}''',
  115. cwd=self.Repo_Dic, **sys_seeting)
  116. class Clone_git(git_Repo):#Clone一个git
  117. def __init__(self,Dic,url,name,*args,**kwargs):
  118. super(Clone_git, self).__init__(Dic,name, *args, **kwargs)
  119. self.url = url
  120. Repo.clone_from(url=url,to_path=Dic)
  121. self.git = self.repo.git
  122. self.index = self.repo.index
  123. class git_Ctrol:
  124. def __init__(self):
  125. self.git_Dic = {}#名字-文件位置
  126. self.gitType_Dic = {}#名字-类型
  127. def Add_init(self,Dic,**kwargs):
  128. name = split(Dic)[-1]
  129. git = git_Repo(Dic,name)
  130. self.git_Dic[name] = git
  131. self.gitType_Dic[name] = 'init'
  132. def Clone_init(self,Dic,url,**kwargs):
  133. name = split(Dic)[-1]
  134. git = Clone_git(Dic,url,name)
  135. self.git_Dic[name] = git
  136. self.gitType_Dic[name] = 'clone'
  137. def get_git(self,name):
  138. return self.git_Dic[name]
  139. def get_git_Dic(self):
  140. return self.git_Dic.copy()
  141. def get_Dir(self,name):
  142. return self.get_git(name).dir_list()
  143. def add_File(self,name,dic_list):
  144. return self.get_git(name).Add_File(dic_list)
  145. def commit_File(self,name,m):
  146. return self.get_git(name).Commit_File(m)
  147. def log(self,name):
  148. return self.get_git(name).Log()
  149. def reflog(self,name):
  150. return self.get_git(name).refLog()
  151. def status(self,name):
  152. return self.get_git(name).Status()
  153. def diff_File(self,name,MASTER):
  154. return self.get_git(name).Diff_File(MASTER)
  155. def back_version(self,name,HEAD):
  156. return self.get_git(name).reset(HEAD)
  157. def checkout_version(self,name,file):
  158. return self.get_git(name).checkout(file)
  159. def rm(self,name,file):
  160. return self.get_git(name).rm(file)
  161. def check_Branch(self,name):
  162. return self.get_git(name).check_Branch()
  163. def new_Branch(self,name, new_branch, origin):
  164. return self.get_git(name).new_Branch(new_branch, origin)
  165. def switch_Branch(self,name,branch_name):
  166. return self.get_git(name).switch_Branch(branch_name)
  167. def Del_Branch(self,name,branch_name,type_):
  168. d = {1:'d',0:'D'}.get(type_,'d')
  169. return self.get_git(name).del_Branch(branch_name,d)
  170. def merge_Branch(self,name,branch_name,no_ff,m):
  171. return self.get_git(name).merge_Branch(branch_name,no_ff,m)
  172. def merge_abort(self,name):
  173. return self.get_git(name).merge_abort()
  174. def Save_stash(self,name):
  175. return self.get_git(name).Save_stash()
  176. def Stash_List(self,name):
  177. return self.get_git(name).Stash_List()
  178. def Apply_stash(self,name,stash_num='0'):
  179. return self.get_git(name).Apply_stash(stash_num)
  180. def Drop_stash(self,name,stash_num='0'):
  181. return self.get_git(name).Drop_stash(stash_num)
  182. def cherry_pick(self,name,commit):
  183. return self.get_git(name).cherry_pick(commit)
  184. def Add_remote(self,name,remote,remote_name):
  185. return self.get_git(name).Add_remote(remote,remote_name)
  186. def Bind_remote(self,name,local_name,remote_name):
  187. return self.get_git(name).Bind_remote(local_name,remote_name)
  188. def Pull_remote(self,name,local_name,remote_name,allow=False,u=False):
  189. return self.get_git(name).Pull_Push_remote(0,remote_name,local_name,allow,u)
  190. def Push_remote(self,name,local_name,remote_name,allow=False,u=False):
  191. return self.get_git(name).Pull_Push_remote(1,remote_name,local_name,False,u)#push没有allow选项
  192. def Tag(self,name, condition=''):
  193. return self.get_git(name).Tag(condition) # push没有allow选项
  194. def show_new(self,name, condition):
  195. return self.get_git(name).show_new(condition) # push没有allow选项
  196. def Add_Tag(self,name,tag,commit,message=''):
  197. return self.get_git(name).Add_Tag(tag,commit,message) # push没有allow选项