需求场景
对于程序员来说,版本控制工具有 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" } }
|