需求场景
对于程序员来说,版本控制工具有 git 和 svn 可以选择,svn 由于其细致的权限管理配置,在很多公司中仍然有应用场景,但在实际项目开发中,git 由于其优越的分布式架构更受程序员的欢迎。在大多数程序开发过程中,都会推崇 git 优秀的版本控制思想。
这样就有了一个需求场景,在日常开发中想使用 git,但公司的版本控制又要求存储使用 svn。
实现步骤
整体思路步骤为:
1. 自已搭建一个 git 服务器,用于存储各个员工的 git 提交
- 这里建议使用 
gitea 来搭建,以下是 docker 的方式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | version: "3" services:     gitea-server:         image: gitea/gitea:latest         container_name: gitea         environment:             - USER_UID=1000             - USER_GID=1000         restart: always         volumes:             - ./data:/data             - /etc/timezone:/etc/timezone:ro             - /etc/localtime:/etc/localtime:ro         ports:             - 3000:3000
   | 
 
2. 在 git 的 hook 点 post-receive 中添加 git 同步 svn 的脚本逻辑
在 post-receive 的挂载点目录中默认有一个 test.sh,可以在里面修改后挂载 python 执行脚本
1 2 3 4 5 6
   | echo ${data} | while read p_commit c_commit branch; do         result=$(echo ${branch}| grep "main")         if [ "$result" != "" ];then                 python /data/git/repositories/wang_guoliang/test-git.git/hooks/post-receive.d/sync-svn.py $c_commit $p_commit         fi done
  | 
 
其主要步骤是:
- 将当次提交的内容检出到指定的缓存目录中
 
- 将缓存目录中的文件拷贝到 
git svn 目录 
- 在 
svn 目录中提交记录 
在 svn 客户端目录要向服务端提交记录,可以用 svn,也可以用 git svn,这里我们使用 git svn 来做,利用其可以指定工作目录的的特点来实现
git-svn 默认包含在 Git 的安装包中,不过在 Ubuntu 中,git-svn 是作为一个独立的 Package 需要额外安装的。
1
   | sudo apt-get install git-svn
   | 
 
以下是完整的脚本代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
   | 
 
 
  import os import sys import subprocess import json
 
  argv = sys.argv
 
  with open("/data/git-svn-config.json", 'r', encoding='UTF-8') as f:     git_svn_config = json.load(f)
 
  shell_git_tmp_dir = git_svn_config['dir']['git_svn_tmp']
  shell_git_svn_dir = git_svn_config['dir']['git_svn']
  svn_repository = git_svn_config['svn']['repository']
  shell_svn_username = git_svn_config['svn']['default_uname']
  shell_svn_password = git_svn_config['svn']['default_pwd']
 
 
  if not os.path.exists(shell_git_tmp_dir):     os.makedirs(shell_git_tmp_dir)
  if not os.path.exists(shell_git_svn_dir):     os.makedirs(shell_git_svn_dir)
  if not os.path.exists(shell_git_svn_dir + '/.git'):     git_svn_init_result = subprocess.getoutput(         'echo ' +         shell_svn_password +         ' | git svn clone ' +         svn_repository +         ' ' +         shell_git_svn_dir +         ' --username ' +         shell_svn_username)     print('git_svn_init_result: ' + git_svn_init_result)
 
 
  def add_commit(line):     lineArr = line.split(' - ')     print(lineArr)     subprocess.getoutput('rm -rf ' + shell_git_tmp_dir + '/.')     subprocess.getoutput('GIT_WORK_TREE=' + shell_git_tmp_dir + ' git checkout ' + argv[1] + ' -f ')     subprocess.getoutput('rm -rf ' + shell_git_tmp_dir + '/.git')     subprocess.getoutput('rm -rf ' + shell_git_svn_dir + '/*')     subprocess.getoutput('cp -r ' + shell_git_tmp_dir + '/. ' + shell_git_svn_dir + '/')     subprocess.getoutput('git --work-tree=' + shell_git_svn_dir + ' --git-dir=' + shell_git_svn_dir + '/.git add . ')     result_commit = subprocess.getoutput(         'git --work-tree=' +         shell_git_svn_dir +         ' --git-dir=' +         shell_git_svn_dir +         '/.git commit -m "' +         lineArr[2] +         '"')     print('svn-commit: ' + result_commit)     global shell_svn_username     shell_svn_username = lineArr[1]
 
 
  def find_svn_info(git_uname, notFound={}):     user_list = git_svn_config['user']     for i in range(0, len(user_list)):         if user_list[i]['git']['uname'] == git_uname:             return user_list[i]['svn']     return notFound
 
  def main():     global shell_svn_username     global shell_svn_password
           log_list = subprocess.getoutput('git log main --pretty=format:"%h - %an - %s" ' + argv[1] + ' ^' + argv[2])     list = log_list.splitlines()     for line in list:         add_commit(line)
           svn_user_info = find_svn_info(shell_svn_username)     if 'uname' in svn_user_info:         shell_svn_username = svn_user_info['uname']         shell_svn_password = svn_user_info['pwd']
           result_push = subprocess.getoutput(         'echo ' +         shell_svn_password +         ' | git --work-tree=' +         shell_git_svn_dir +         ' --git-dir=' +         shell_git_svn_dir +         '/.git svn dcommit --username ' +         shell_svn_username)     print('svn-push: ' + result_push)
 
  if __name__ == "__main__":     main()
 
 
  | 
 
配置文件git-svn-config.json内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
   | {     "user": [         {             "git": {                 "uname": "wgl",                 "email": "wang_guoliang@webape.net"             },             "svn": {                 "uname": "wgl",                 "pwd": "123456"             }         },         {             "git": {                 "uname": "user1",                 "email": "usr1@webape.net"             },             "svn": {                 "uname": "user1",                 "pwd": "123456"             }         },         {             "git": {                 "uname": "user2",                 "email": "usr2@webape.net"             },             "svn": {                 "uname": "user2",                 "pwd": "123456"             }         }     ],     "dir": {         "git_chk": "/tmp/test-git-check",         "git_svn_tmp": "/tmp/test-git-tmp",         "git_svn": "/tmp/test-git"     },     "svn": {         "repository": "svn://10.28.34.219/cloud-platform",         "default_uname": "user1",         "default_pwd": "123456"     } }
  | 
 
      
     
    
      
  
  
    
      
      
        
        致力于网站建设与Web开发。喜欢新事物,关注前后端动态,对新的技术有追求, 做一个优秀的web全栈工程师。