最近写一个类似博客的东西,用于存放部门的文档,为了文章能够回滚,写了个git的类用于操作本地类,如下:
脚本名称:myGit.py
import os,sys,re
import logging
logger = logging.getLogger(__name__)
from runCMD import runCmd
from django.conf import settings
GIT_DIR = settings.GIT_DIR
def write2GitWorkSpace(file,context):
'''
将文件写入到本地git的工作区间
'''
try:
with open(os.path.join(GIT_DIR,file),'w') as f:
f.write(context)
return {'code':True}
except Exception,e:
logger.error('写入到git工作区文件失败:%s' % str(e))
return {'code':False,'msg':'写入到git工作区文件失败:%s' % str(e)}
def commit2Git(file):
'''
将修改提交到git中
'''
if not os.path.exists(os.path.join(GIT_DIR,file)):
logger.error('文件不存在')
return {'code':False,'msg':'文件不存在'}
cmd = 'cd %s;git add %s && git commit -m "%s"' % (GIT_DIR,file,file)
n = runCmd(real=1)
execute = n.run(cmd)
if not execute[0]:
logger.error("在git中提交失败: %s" % execute[2])
return {'code':False,'msg':"在git中删除失败: %s" % execute[2]}
else:
logger.info("提交git成功")
return {'code':True}
def rmFileInGit(file):
'''
在git中删除文件
'''
cmd = 'cd %s;git rm %s && git commit -m "%s"' % (GIT_DIR,file,file)
n = runCmd(real=1)
execute = n.run(cmd)
if not execute[0]:
logger.error("在git中删除失败: %s" % execute[2])
return {'code':False,'msg':"在git中删除失败: %s" % execute[2]}
else:
logger.info(execute)
logger.info("在git中删除成功")
return {'code':True}
def getFileLog(file,item=0):
'''
获取指定文件的git版本控制信息
'''
if item==0:
cmd = 'cd %s;git log --pretty="[%%cd(%%cr)] %%h : %%s" -p %s' % (GIT_DIR,file)
else:
cmd = 'cd %s;git log --pretty="[%%cd(%%cr)] %%h : %%s" -%s -p %s' % (GIT_DIR,item,file)
n = runCmd(real=1)
execute = n.run(cmd)
if not execute[0]:
logger.error("执行git失败: %s" % execute[2])
return {'code':False,'msg':"在git中删除失败: %s" % execute[2]}
else:
return execute[2]
#return formatLogData(execute[2])
def formatLogData(data):
'''
对版本控制信息数据进行格式化
'''
resultData = []
#找出每个版本的开头
pat1 = re.compile(r'(?=\[.*\(.*ago\)\])')
#替换成容易辨认的统一抬头
data = pat1.sub('#----',data)
data += '#----'
#分离出每个版本
pat2 = re.compile(r'(?<=#----)(.*?)\n(?=#----)',re.S)
#提取每个版本的信息
pat3 = re.compile(r'\[(.*)\]\s(.*)\s:\s(.*)\n\ndiff.*@@\n(.*)\n',re.S)
#替换掉没用的字符串
pat4 = re.compile(r'\\ No newline at end of file\n')
#分离出每个版本,循环取出每个版本信息
for item in re.findall(pat2,data):
resultData.append(pat3.findall(pat4.sub('',item))[0])
return resultData
def getFileVersionData(file,version):
'''
获取指定文件某个版本内容
'''
logger.info("查看文件版本视图")
cmd = 'cd %s;git checkout %s -- %s' % (GIT_DIR,version,file)
logger.info(cmd)
n = runCmd(real=1)
execute = n.run(cmd)
if not execute[0]:
logger.error("在git中获取文件指定历史版本失败: %s" % execute[2])
return {'code':False,'msg':"在git中删除失败: %s" % execute[2]}
else:
with open(os.path.join(GIT_DIR,file),'r') as f:
return f.read()
def revertArticle(file,version):
'''
回滚文档到指定版本
'''
logger.info('文件开始回滚')
cmd = 'cd {DIR};git checkout {version} -- {file} && git commit -m "revert to {version}"'.format(
DIR = GIT_DIR,
version = version,
file= file)
n = runCmd(real=1)
execute = n.run(cmd)
if not execute[0]:
logger.error("在git中回滚失败: %s" % execute[2])
return {'code':False,'msg':"在git中删除失败: %s" % execute[2]}
else:
with open(os.path.join(GIT_DIR,file),'r') as f:
return f.read()
runCMD是一个执行命令的脚本,在文章http://blog.youkuaiyun.com/u011085172/article/details/78106859 点击打开链接 有,可以参考下
有了以上git的操作类,就可以尽情的调用来操作git存储文档、博客了:
创建:
gitid = uuid.uuid1()
logger.info("写入git:[%s]" % gitid)
exc_result = write2GitWorkSpace(str(gitid),requestData['article'])
if exc_result['code']:
exc_result = commit2Git(str(gitid))
if not exc_result['code']:
return JsonResponse(exc_result)
else:
return exc_result
logger.info("写入git完毕")
编辑:
logger.info("编辑文档写入git:[%s]" % gitid)
exc_result = write2GitWorkSpace(str(gitid),requestData['article'])
if exc_result['code']:
exc_result = commit2Git(str(gitid))
if not exc_result['code']:
return JsonResponse(exc_result)
else:
return JsonResponse(exc_result)
logger.info("编辑文档写入git完毕")
版本控制,获取版本记录:
gitid = fileRecord.objects.get(id=requestData['articleId']).get_gitid()
exc_result = getFileVersionData(str(gitid),requestData['version'])
if type(exc_result) == dict and exc_result.has_key('code') and not exc_result['code']:
return JsonResponse(exc_result)
版本回滚:
gitid = fileRecord.objects.get(id=requestData['articleId']).get_gitid()
exc_result = revertArticle(str(gitid),requestData['version'])
logger.info("exc_result type:"+ str(type(exc_result)))
if type(exc_result) == dict and exc_result.has_key('code') and not exc_result['code']:
return JsonResponse(exc_result)
姿势都有了,还有啥做不了呢!
样例:
版本控制也没样例: