一、实现效果
1、通过python获取路径下所有文件的svn状态
2、通过python对svn进行“提交、删除、锁、解锁、删除等操作”
3、通过svn打开小乌龟界面
二、完整代码
""" SVN状态对照表 """ class FileState: Normal = 0 # 000000 正常在svn管理下的最新的文件 RemoteLocked = 1 # 000001 云端锁定态 LocalLocked = 2 # 000010 本地锁定态 Locked = 3 # 000011 已锁定 state and Locked == True LocalMod = 4 # 000100 本地有修改需提交 RemoteMod = 8 # 001000 远程有修改需要更新 Conflicked = 12 # 001100 冲突 state and Conflicked == Conflicked UnVersioned = 16 # 010000 未提交到库 Error = 32 # 100000 错误状态
""" 具体实现逻辑 """ # -*- coding: utf-8 -*- import os import pprint import subprocess import time from threading import Thread from xmltodict import parse as xmlParse def _doSvnCommandSync(args): startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE p = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo, shell=True ) rst, err = p.communicate() try: rst = str(rst, 'utf-8') except: rst = str(rst, 'gbk', errors="-ignore") try: err = str(err, 'utf-8') except: err = str(err, 'gbk', errors="-ignore") return rst, err def svnCommitNoUnlockSync(path, comment=""): rst, err = _doSvnCommandSync("svn commit " + path + " -m \"" + comment + "\"" + " --no-unlock") return rst, err def svnCommitSync(path, comment=""): rst, err = _doSvnCommandSync("svn commit " + path + " -m \"" + comment + "\"") return rst, err def _svnStatusSync(path): rst, err = _doSvnCommandSync("svn status " + path) if err: return None, err data = rst return data, None def svnLockSync(path): rst, err = _doSvnCommandSync("svn lock -m '哈哈哈哈哈哈' " + path) return rst, err def svnAddSync(path): data, err = _doSvnCommandSync("svn add " + path) return data, err def svnUnLockSync(path): rst, err = _doSvnCommandSync("svn unlock " + path) return rst, err def svnDeleteSync(path): return _doSvnCommandSync("svn delete " + path) def _svnStatusXMLSync(path): rst, err = _doSvnCommandSync("svn status " + path + " -u --xml") if err: return None, err data = rst data = xmlParse(data) return data, None def syncGetAllFileStatus(rootPath): data, info = _svnStatusXMLSync(rootPath) returnDict = {} lockRole = "" state = FileState.Normal if info: if data is None: state = state | FileState.UnVersioned else: state = state | FileState.Error return returnDict target = data["status"]["target"] if target and "entry" in target: iterList = [] if not isinstance(target["entry"], list): iterList.append(target["entry"]) else: iterList = target["entry"] for fileStatusItem in iterList: state = FileState.Normal filePath = fileStatusItem["@path"] wc_status = fileStatusItem["wc-status"] if "unversioned" == wc_status["@item"]: state = state | FileState.UnVersioned elif "modified" == wc_status["@item"]: state = state | FileState.LocalMod elif "repos-status" in fileStatusItem: repos_status = fileStatusItem["repos-status"] if "lock" in repos_status and "lock" not in wc_status: info = repos_status["lock"]["owner"] lockRole = info state = state | FileState.RemoteLocked elif "lock" in wc_status: info = wc_status["lock"]["owner"] lockRole = info state = state | FileState.LocalLocked elif "modified" == repos_status["@item"]: state = state | FileState.RemoteMod info = "%s is modified on remote, you need update first" % filePath if "modified" == wc_status["@item"]: state = state | FileState.LocalMod info = "%s is modified on local, you need commit first" % filePath returnDict[os.path.normcase(filePath)] = [state, info, lockRole] return returnDict def openTortoise(): pathsStr = "".join("G:\SVNCheckOut\Txt2") cmd = "TortoiseProc.exe /command:commit /path %s" % pathsStr p = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", shell=True ) # class Process(subprocess.Popen): # def register_callback(self, callback, *args, **kwargs): # Thread(target=self._poll_completion, args=(callback, args, kwargs)).start() # # def _poll_completion(self, callback, args, kwargs): # while self.poll() is None: # time.sleep(0.1) # callback(*args, **kwargs) # def openTortoise(): # pathsStr = "".join("G:\SVNCheckOut\Version1") # cmd = "TortoiseProc.exe /command:commit /path %s" % pathsStr # handle = Process(cmd) # handle.register_callback(MyPrint) # def MyPrint(): # print("~~~~~~~~~~~~~~~~~") openTortoise() data = syncGetAllFileStatus(r"G:\SVNCheckOut\Txt2") pprint.pprint(data) os.system("Pause")
三、结果展示、代码解析
1、上述代码最终会有两个输出展示
a、打开小乌龟提交界面
这里对应的其实就是 “TortoiseProc.exe /command:commit /path %s” % pathsStr" 这句命令行的运行
b、展示SVN 文件状态
我们需要查看上述 “svn状态对照表”,可以发现状态码 “2、4、16” 分别对应的就是 “本地锁定、本地有修改、未提交到库”,并且到文件夹中查看可知是一一对应的
2、代码解析
首先,我们看 “_doSvnCommandSync” 该函数的实质就是运行命令行
我们将svn的各种命令行传入上述函数 “_doSvnCommandSync”,以此构造了python内的 "提交、删除、锁、解锁 等函数"
比较特殊的是 “_svnStatusXMLSync” 这个获取svn状态的函数,因为我们是将其以xml的格式输出,因此要对其结构进行解析,“svn status " + path + " -u --xml” 这条指令能够获取 path路径下所有文件的svn状态,我们在 “syncGetAllFileStatus” 函数中对其解析便可以得到我们想要的信息,包括 锁的相关信息、提交信息、文件状态等
以上就是python实现对svn操作及信息获取的详细内容,更多关于python操作svn信息获取的资料请关注服务器之家其它相关文章!
原文链接:https://blog.csdn.net/weixin_40301728/article/details/115792763