SvnToGit.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. from email.policy import strict
  2. from inspect import getcomments
  3. import os
  4. from re import S
  5. import sys
  6. import json
  7. import urllib3
  8. import re
  9. DirPath = os.path.split(os.path.realpath(__file__))
  10. # DirPath = "E:\\Jenkins3Agent\\workspace\\qiuqiuTest"
  11. # 白名单
  12. whiteList = ['info','svnUpdate','status','gitPull','versionLog','diffLog','gitStatus']
  13. # DIR = sys.argv[1] # 方向
  14. GitPath = sys.argv[1] # git地址
  15. GITBRANCH = sys.argv[2] # git分支
  16. SVN_USER = sys.argv[3] # svn用户
  17. SVN_PASSWORD = sys.argv[4] # svn密码
  18. GIT_USER = sys.argv[5] # git用户
  19. GIT_PASSWORD = sys.argv[6] #git密码
  20. PUSH_STYLE = sys.argv[7] #提交方式 #true为分批提交,false为一次提交
  21. GIT_USER_TEMP = r"http://liaoyourong%40brmyx.com" #git临时用户
  22. GIT_PASSWORD_TEMP = r"z123456" #git临时密码
  23. # svn命令行
  24. SVNDiffCommand = "svn diff -r "
  25. SVNInfoCommand = "svn info >.\info"
  26. SVNLogCommand = "svn log -r "
  27. SVNUpdateToVersionCommand = "svn up -r "
  28. SVNRevertCommand = "svn revert -R *"
  29. SVNUpdateCommand = "svn update >.\svnUpdate"
  30. SVNUpdate = "svn update"
  31. SVNStatusCommand = "svn status > .\status"
  32. SVNDeleteCommand = "svn del "
  33. SVNAddOneCommand = "svn add "
  34. SVNCommitCommand = 'svn commit --username ' + SVN_USER + ' --password ' + SVN_PASSWORD + ' -m "git提交"'
  35. SVNBeforeRevision = "" #一次提交的版本迭代 前版本
  36. SVNAfterRevision = "" #一次提交的版本迭代 后版本
  37. SVNBeforeRevision_New = "" #分批提交的版本迭代 前版本
  38. SVNAfterRevision_New = "" #分批提交的版本迭代 后版本
  39. SVNVersionList = []
  40. SVNVersionLogList = []
  41. NewGitList = [] #git拉取下来,相对于svn来说是改变的文件列表
  42. # git命令行
  43. addstr = "."
  44. GitCheckoutCommand = "git checkout ."
  45. GitPullCommand = "git pull > .\gitPull"
  46. GitAddCommand = "git add "
  47. GitAddAllCommand = "git add " + addstr
  48. GitCommitCommand = 'git commit -m "'
  49. GitCommitCommandLog = 'git commit '
  50. GitPushCommand = r"git push " + GIT_USER_TEMP + ":" + GIT_PASSWORD_TEMP + "@" + GitPath + " " + GITBRANCH
  51. # 前缀函数
  52. def NormalFunc():
  53. # 路径跳转
  54. # os.chdir(listPath[0])
  55. os.chdir(DirPath[0]) #跳转
  56. # testarg = open("./testArgs",'w')
  57. # for i in range(0,len(sys.argv)):
  58. # testarg.write(sys.argv[i] + '\n')
  59. # testarg.close()
  60. # 拿到版本区间的提交信息
  61. def GetLogCommand(after,before):
  62. return SVNLogCommand + after + ":" + before + r" >.\versionLog"
  63. def GetLog():
  64. os.system(GetLogCommand(SVNBeforeRevision_New,SVNAfterRevision_New))
  65. SvnVersionLog = open("./versionLog",'r')
  66. svnLogList = SvnVersionLog.readlines()
  67. for i in range(len(svnLogList)):
  68. svnList = svnLogList[i].split('|')
  69. if(len(svnList) > 1):
  70. global SVNVersionList
  71. global SVNVersionLogList
  72. SVNVersionList.append(int(re.findall(r"\d+",svnList[0])[0]))
  73. SVNVersionLogList.append(str(svnLogList[i+2]).strip())
  74. SvnVersionLog.close()
  75. os.remove(DirPath[0] + "\\" + "versionLog")
  76. def JudgeGitClean():
  77. GitStatusCommand = "git status > .\gitStatus"
  78. os.system(GitStatusCommand)
  79. StatusLog = open("./gitStatus",'r',encoding= "utf-8")
  80. for StatusLogLine in StatusLog.readlines():
  81. if(StatusLogLine.strip().find("nothing to commit") != -1):
  82. StatusLog.close()
  83. os.remove(DirPath[0] + "\\" + "gitStatus")
  84. return True
  85. StatusLog.close()
  86. os.remove(DirPath[0] + "\\" + "gitStatus")
  87. return False
  88. def GetDiff(lastVersion,nowVersion):
  89. diffList = []
  90. svnDiff = SVNDiffCommand + str(lastVersion) + r":" + str(nowVersion) + " --summarize" + " >.\diffLog"
  91. os.system(svnDiff)
  92. diffLog = open("./diffLog",'r',encoding= "ansi")
  93. for diffLogLine in diffLog.readlines():
  94. # if(diffLogLine.find("Index:",0,7) != -1):
  95. diffList.append(diffLogLine.strip()[8:len(diffLogLine.strip())])
  96. diffLog.close()
  97. os.remove(DirPath[0] + "\\" + "diffLog")
  98. return diffList
  99. def UpdateSVNByVersion():
  100. # SVNVersionList.reverse()
  101. # SVNVersionLogList.reverse()
  102. for j in range(len(SVNVersionList)):
  103. if(j > 0):
  104. os.system(SVNUpdateToVersionCommand + str(SVNVersionList[j]))
  105. if(JudgeGitClean() ==False):
  106. diffList = GetDiff(SVNVersionList[j-1],SVNVersionList[j])
  107. for m in range(len(diffList)):
  108. if(diffList[m] in NewGitList): #如果修改列表里面,包含修改的内容,就修正改成单次提交
  109. os.system(SVNUpdate)
  110. os.system(GitAddAllCommand)
  111. changeLog = 'git commit -m "' + r"svn提交,修改列表里面,包含git修改内容,本次自动修改成单次提交,从以下提交开始:" + '"'
  112. for l in range(len(SVNVersionLogList)):
  113. if l >= j:
  114. changeLog = changeLog + ' -m "' + SVNVersionLogList[l].strip() + '"'
  115. os.system(changeLog)
  116. os.system(GitPushCommand)
  117. return
  118. add = GitAddCommand + '"' + diffList[m] + '"'
  119. os.system(add)
  120. os.system(GitCommitCommand+ r"svn版本号:" + str(SVNVersionList[j]) + r"/" + str(SVNVersionLogList[j]).strip())
  121. os.system(GitPushCommand)
  122. # print(SVNVersionLogList[j])
  123. def GetLocalVersion():
  124. os.system(SVNInfoCommand)
  125. infoLog = open("./info",'r')
  126. for infoLine in infoLog.readlines():
  127. if(infoLine.strip().find('Last Changed Rev') != -1):
  128. global SVNBeforeRevision_New
  129. SVNBeforeRevision_New = infoLine.strip()[18:len(infoLine.strip())]
  130. # if(infoLine.strip().find(r"URL: http:") != -1):
  131. # global SVNURL
  132. # SVNURL = infoLine.strip()[5:len(infoLine.strip())]
  133. infoLog.close()
  134. def GetNewVersion():
  135. os.system(SVNInfoCommand)
  136. infoLog = open("./info",'r')
  137. for infoLine in infoLog.readlines():
  138. if(infoLine.strip().find('Last Changed Rev') != -1):
  139. global SVNAfterRevision_New
  140. SVNAfterRevision_New = infoLine.strip()[18:len(infoLine.strip())]
  141. # if(infoLine.strip().find(r"URL: http:") != -1):
  142. # global SVNURL
  143. # SVNURL = infoLine.strip()[5:len(infoLine.strip())]
  144. infoLog.close()
  145. os.remove(DirPath[0] + "\\" + "info")
  146. def GetBeforeInfo():
  147. infoLog = open("./info",'r')
  148. for infoLine in infoLog.readlines():
  149. if(infoLine.strip().find('Revision') != -1):
  150. global SVNBeforeRevision
  151. SVNBeforeRevision = infoLine.strip()[10:len(infoLine.strip())]
  152. infoLog.close()
  153. def GetAfterInfo():
  154. infoLog = open("./info",'r')
  155. for infoLine in infoLog.readlines():
  156. if(infoLine.strip().find('Revision') != -1):
  157. global SVNAfterRevision
  158. SVNAfterRevision = infoLine.strip()[10:len(infoLine.strip())]
  159. infoLog.close()
  160. # svn发到git
  161. def SvnToGit():
  162. os.system(SVNRevertCommand)
  163. os.system(SVNUpdateCommand)
  164. # os.system(GitCheckoutCommand)
  165. os.system(GitPullCommand)
  166. # os.system(SVNRevertCommand)
  167. # os.system(SVNStatusCommand)
  168. # statusLog = open("./status")
  169. # for line in statusLog.readlines():
  170. # if line.strip()[0] == "?": #新增的文件: (实际上在svn已经删除的)
  171. # os.remove(DirPath + "\\" + line.strip()[8:len(line.strip())])
  172. # statusLog.close()
  173. # os.system(GitAddCommand)
  174. # os.system(GitCommitCommand)
  175. # os.system(GitPushCommand)
  176. # git发到svn
  177. def GitToSVN():
  178. os.system(SVNRevertCommand)
  179. os.system(SVNUpdateCommand)
  180. # os.system(GitCheckoutCommand)
  181. os.system(GitPullCommand)
  182. # os.system(SVNStatusCommand)
  183. # statusLog = open("./status")
  184. # for line in statusLog.readlines():
  185. # if line.strip()[0] == "!": #被删除的文件
  186. # os.system(SVNDeleteCommand + '"' + ".\\" + line.strip()[8:len(line.strip())] + '"')
  187. # elif line.strip()[0] == "?": #新增的文件:
  188. # os.system(SVNAddOneCommand + '"' + ".\\" + line.strip()[8:len(line.strip())] + '"')
  189. # os.system(SVNCommitCommand)
  190. headers = {
  191. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36', 'Accept-Charset': 'utf-8', 'Content-Type': 'application/json'}
  192. webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/eb0834e0-4d2d-4d2c-a20c-90ce9079566e"
  193. href = ""
  194. # git pull失败
  195. def notify():
  196. content = {
  197. "msg_type": "post",
  198. "content": {
  199. "post": {
  200. "zh_cn": {
  201. "title": "git和svn合并通知",
  202. "content":
  203. [
  204. [
  205. {
  206. "tag": "text",
  207. "text": "git拉取失败,有修改了相同文件: "
  208. },
  209. {
  210. "tag": "at",
  211. "user_id": "7109285249619836931"
  212. }
  213. ]
  214. ]
  215. }
  216. }
  217. }
  218. }
  219. http = urllib3.PoolManager(retries=3, timeout=10)
  220. resp = http.request(method="POST", url=webhook,
  221. headers=headers, body=json.dumps(content))
  222. # print(resp.data)
  223. # svn要删除文件,但是git修改了这个文件
  224. def AlreadySVNDel(message,allMessage):
  225. content = {
  226. "msg_type": "post",
  227. "content": {
  228. "post": {
  229. "zh_cn": {
  230. "title": "git和svn合并通知",
  231. "content":
  232. [
  233. [
  234. {
  235. "tag": "text",
  236. "text": "svn要删除文件,但是git修改了这个文件:\n "
  237. },
  238. {
  239. "tag": "text",
  240. "text": f"{message}"
  241. },
  242. {
  243. "tag": "text",
  244. "text": "\n所有svn删除的文件列表为:\n "
  245. },
  246. {
  247. "tag": "text",
  248. "text": f"{allMessage}"
  249. },
  250. {
  251. "tag": "at",
  252. "user_id": "7109285249619836931"
  253. }
  254. ]
  255. ]
  256. }
  257. }
  258. }
  259. }
  260. http = urllib3.PoolManager(retries=3, timeout=10)
  261. resp = http.request(method="POST", url=webhook,
  262. headers=headers, body=json.dumps(content))
  263. # print(resp.data)
  264. # svn和git重命名了同一个文件
  265. def Rename(message):
  266. content = {
  267. "msg_type": "post",
  268. "content": {
  269. "post": {
  270. "zh_cn": {
  271. "title": "git和svn合并通知",
  272. "content":
  273. [
  274. [
  275. {
  276. "tag": "text",
  277. "text": "svn重命名了这个文件,git也重命名了这个文件,会产生多余的文件:\n "
  278. },
  279. {
  280. "tag": "text",
  281. "text": f"{message}"
  282. },
  283. {
  284. "tag": "at",
  285. "user_id": "7109285249619836931"
  286. }
  287. ]
  288. ]
  289. }
  290. }
  291. }
  292. }
  293. http = urllib3.PoolManager(retries=3, timeout=10)
  294. resp = http.request(method="POST", url=webhook,
  295. headers=headers, body=json.dumps(content))
  296. # print(resp.data)
  297. def DelOther():
  298. os.remove(DirPath[0] + "\\" + "svnlog")
  299. os.remove(DirPath[0] + "\\" + "gitPull")
  300. os.remove(DirPath[0] + "\\" + "status")
  301. os.remove(DirPath[0] + "\\" + "svnUpdate")
  302. os.remove(DirPath[0] + "\\" + "info")
  303. # os.remove(DirPath[0] + "\\" + "versionLog")
  304. def GetAfterInfo():
  305. infoLog = open("./info",'r')
  306. for infoLine in infoLog.readlines():
  307. if(infoLine.strip().find('Revision') != -1):
  308. global SVNAfterRevision
  309. SVNAfterRevision = infoLine.strip()[10:len(infoLine.strip())]
  310. infoLog.close()
  311. # 双向发送
  312. def Both():
  313. os.system(SVNRevertCommand)
  314. os.system(SVNInfoCommand)
  315. GetBeforeInfo()
  316. GetLocalVersion()
  317. os.system(SVNUpdateCommand)
  318. os.system(SVNInfoCommand)
  319. GetAfterInfo()
  320. os.system(GitPullCommand)
  321. os.system(SVNStatusCommand)
  322. svndelList = ""
  323. svnDelTrueList = []
  324. svnLog = open("./svnUpdate",'r')
  325. for svnLine in svnLog.readlines():
  326. if svnLine.strip()[0] == "D": #被删除的文件
  327. svndelList = svndelList + svnLine + "\n"
  328. splitList = svnLine.split("\\")
  329. svnDelTrueList.append(splitList[len(splitList)-1])
  330. svnLog.close()
  331. gitLog = open("./gitPull",'r',encoding= "utf-8")
  332. gitNormal = False
  333. isRename = False
  334. for gitLine in gitLog.readlines():
  335. if len(gitLine.split('|')) > 1:
  336. gitNormal = True
  337. if(gitLine.find("rename",0,len(gitLine)-1) != -1):
  338. for i in range(0,len(svnDelTrueList)):
  339. cleanLine = gitLine.replace("\"",'')
  340. if(cleanLine.strip().find(str(svnDelTrueList[i]).strip(),0,len(cleanLine)-1) != -1):
  341. isRename = True
  342. Rename(svnDelTrueList[i])
  343. if(gitLine.find("Already",0,len(gitLine)-1) != -1):
  344. gitNormal = True
  345. break
  346. gitLog.close()
  347. if(isRename == True):
  348. print("git something wrong!!!!!!!!!!!")
  349. return
  350. if(gitNormal == False):
  351. print("git something wrong!!!!!!!!!!!")
  352. notify()
  353. return
  354. else:
  355. print("git normal ula!!!!!!!!!!!!!!!!!!!!")
  356. statusLog = open("./status")
  357. NewGitList.clear()
  358. for line in statusLog.readlines():
  359. if whiteList.count(line.strip()[8:len(line.strip())]) != 0 :
  360. continue
  361. fullName = line.strip()[8:len(line.strip())] + "@"
  362. NewGitList.append(line.strip()[8:len(line.strip())]) #存储git对于svn而言,变更的文件列表
  363. if line.strip()[0] == "!": #被删除的文件
  364. os.system(SVNDeleteCommand + '"' + ".\\" + fullName + '"')
  365. elif line.strip()[0] == "?": #新增的文件:
  366. if(svndelList.find(line.strip()[8:len(line.strip())],0,len(svndelList)-1) != -1):
  367. AlreadySVNDel(line.strip()[8:len(line.strip())],svndelList)
  368. print("git something wrong!!!!!!!!!!!")
  369. return
  370. else:
  371. os.system(SVNAddOneCommand + '"' + ".\\" + fullName + '"')
  372. statusLog.close()
  373. os.system(SVNLogCommand + SVNBeforeRevision + ':' + SVNAfterRevision + " >.\svnlog")
  374. versionLog = open("./svnlog",'r')
  375. versionLogList = versionLog.readlines()
  376. VersionMessageList = []
  377. for i in range(len(versionLogList)):
  378. svnList = versionLogList[i].split('|')
  379. if(len(svnList) > 1):
  380. logIndex = i + 2
  381. if(logIndex <= len(versionLogList) -1):
  382. message =re.findall(r"\d+",svnList[0])[0] + r":" + versionLogList[i+2].strip()
  383. else:
  384. message =re.findall(r"\d+",svnList[0])[0] + r":"
  385. VersionMessageList.append(' -m "' + message + '"')
  386. # for versionLine in versionLog.readlines():
  387. # print("versionLine:"+versionLine)
  388. # global GitCommitCommandLog
  389. # GitCommitCommandLog = GitCommitCommandLog + ' -m "' + versionLine.replace('\n','') + '"'
  390. versionLog.close()
  391. VersionMessageList.reverse()
  392. for j in range(len(VersionMessageList)-1):
  393. global GitCommitCommandLog
  394. GitCommitCommandLog = GitCommitCommandLog + VersionMessageList[j]
  395. DelOther()
  396. os.system(SVNCommitCommand)
  397. os.system(SVNUpdate)
  398. # 判断是分批提交,还是单次提交
  399. if(str(PUSH_STYLE) == "true"):
  400. GetNewVersion()
  401. GetLog()
  402. UpdateSVNByVersion()
  403. else:
  404. os.system(GitAddAllCommand)
  405. os.system(GitCommitCommandLog)
  406. os.system(GitPushCommand)
  407. # direction = {"svn发给git":SvnToGit,"git发给svn":GitToSVN,"双向更新":Both}
  408. NormalFunc()
  409. # direction.get(DIR,Both)()
  410. Both()