repo.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # -*- coding: utf-8 -*-
  2. """
  3. walle-web
  4. :copyright: © 2015-2019 walle-web.io
  5. :created time: 2019-02-24 10:47:53
  6. :author: wushuiyong@walle-web.io
  7. """
  8. import os
  9. import re
  10. import os.path as osp
  11. import git as PyGit
  12. from git import Repo as PyRepo
  13. class Repo:
  14. path = None
  15. def __init__(self, path=None):
  16. self.path = path
  17. def is_git_dir(self):
  18. '''
  19. 判断是否为git目录
  20. @param path:
  21. @return:
  22. '''
  23. d = self.path + '/.git'
  24. if osp.isdir(d):
  25. if osp.isdir(osp.join(d, 'objects')) and osp.isdir(osp.join(d, 'refs')):
  26. headref = osp.join(d, 'HEAD')
  27. return osp.isfile(headref) or \
  28. (osp.islink(headref) and
  29. os.readlink(headref).startswith('refs'))
  30. elif (osp.isfile(osp.join(d, 'gitdir')) and
  31. osp.isfile(osp.join(d, 'commondir')) and
  32. osp.isfile(osp.join(d, 'gitfile'))):
  33. return False
  34. return False
  35. def init(self, url):
  36. # 创建目录
  37. if not os.path.exists(self.path):
  38. os.makedirs(self.path)
  39. # git clone
  40. if self.is_git_dir():
  41. return self.pull()
  42. else:
  43. return self.clone(url)
  44. def clone(self, url):
  45. '''
  46. 检出项目
  47. @param branch:
  48. @param kwargs:
  49. @return:
  50. '''
  51. return PyRepo.clone_from(url, self.path)
  52. def pull(self):
  53. '''
  54. 更新项目
  55. @param branch:
  56. @param kwargs:
  57. @return:
  58. '''
  59. repo = PyRepo(self.path)
  60. return repo.remote().pull()
  61. def checkout_2_branch(self, branch):
  62. PyRepo(self.path).git.checkout(branch)
  63. def checkout_2_commit(self, branch, commit):
  64. '''
  65. @todo 未完成
  66. @param branch:
  67. @param commit:
  68. @return:
  69. '''
  70. PyRepo(self.path).git.checkout(branch)
  71. # PyRepo(self.path).head.set_reference(branch)
  72. # 方法有问题,只是做了reset,没有checkout
  73. PyRepo(self.path).head.set_commit(commit)
  74. def checkout_2_tag(self, tag):
  75. PyRepo(self.path).git.checkout(tag)
  76. def branches(self):
  77. '''
  78. 获取所有分支
  79. @param branch:
  80. @param kwargs:
  81. @return:
  82. '''
  83. # 去除 origin/HEAD -> 当前指向
  84. # 去除远端前缀
  85. branches = PyRepo(self.path).remote().refs
  86. # fixbug https://github.com/meolu/walle-web/issues/705
  87. return [str(branch).strip().lstrip('origin').lstrip('/') for branch in branches if
  88. not str(branch).strip().startswith('origin/HEAD')]
  89. def tags(self):
  90. '''
  91. 获取所有tag
  92. @param branch:
  93. @param kwargs:
  94. @return:
  95. '''
  96. return [str(tag) for tag in PyRepo(self.path).tags]
  97. def commits(self, branch):
  98. '''
  99. 获取分支的commits
  100. @param branch:
  101. @param kwargs:
  102. @return:
  103. '''
  104. self.checkout_2_branch(branch)
  105. commit_log = PyGit.Git(self.path).log('--pretty=%h #@_@# %an #@_@# %s', max_count=50)
  106. commit_list = commit_log.split('\n')
  107. commits = []
  108. for commit in commit_list:
  109. if not re.search('^.+ #@_@# .+ #@_@# .*$', commit):
  110. continue
  111. commit_dict = commit.split(' #@_@# ')
  112. from flask import current_app
  113. current_app.logger.info(commit_dict)
  114. commits.append({
  115. 'id': commit_dict[0],
  116. 'name': commit_dict[1],
  117. 'message': commit_dict[2],
  118. })
  119. return commits