服务端CVS本地Git的版本控制:利用git钩子自定义工作流

请以解决问题为核心,不要为了用技术而用技术。

公司各个项目有CVS、SVN、HG、Git等多版本管理工具。

但CVS确实太老了,十分不便,由于历史原因公司的部分旧代码还都是用CVS来管理,恰恰是我目前在用的- -|||。但是我们可以在本地使用Git来方便代码的管理。因为Git作为分布式版本管理系统,本身local端就是完备的。

如果是用SVN、HG等版本控制系统,有git-svn等解决方案可以不改变服务端而非常方便的在本地用git,但CVS并没有找到现成的方法…,可能确实太老了吧!

最近终于想到了个方法,利用合理的流程+Git钩子,来实现Git对CVS的操作:

 git push 时执行python脚本解析本次commit的文件,分别执行cvs update <filename>推送到服务器。

Git 钩子:自定义你的工作流

Git钩子是在 Git 仓库中特定事件发生时自动运行的脚本。它可以让你自定义 Git 内部的行为,在开发周期中的关键点触发自定义的行为,因为脚本可以完全定制,你可以用 Git 钩子来自动化或者优化你开发工作流中任意部分。

git钩子介绍及使用方法:https://github.com/geeeeeeeeek/git-recipes/blob/master/sources/Git%E9%92%A9%E5%AD%90.md

How To Use Git Hooks To Automate Development and Deployment Tasks: https://www.digitalocean.com/community/tutorials/how-to-use-git-hooks-to-automate-development-and-deployment-tasks

Hooks汇总:

Hook Name Invoked By DescriptionParameters (Number and Description)
applypatch-msg git am Can edit the commit message file and is often used to verify or actively format a patch's message to a project's standards. A non-zero exit status aborts the commit. (1) name of the file containing the proposed commit message
pre-applypatch git am This is actually called after the patch is applied, but before the changes are committed. Exiting with a non-zero status will leave the changes in an uncommitted state. Can be used to check the state of the tree before actually committing the changes. (none)
post-applypatch git am This hook is run after the patch is applied and committed. Because of this, it cannot abort the process, and is mainly used for creating notifications. (none)
pre-commit git commit This hook is called before obtaining the proposed commit message. Exiting with anything other than zero will abort the commit. It is used to check the commit itself (rather than the message). (none)
prepare-commit-msg git commit Called after receiving the default commit message, just prior to firing up the commit message editor. A non-zero exit aborts the commit. This is used to edit the message in a way that cannot be suppressed. (1 to 3) Name of the file with the commit message, the source of the commit message (messagetemplatemergesquash, or commit), and the commit SHA-1 (when operating on an existing commit).
commit-msg git commit Can be used to adjust the message after it has been edited in order to ensure conformity to a standard or to reject based on any criteria. It can abort the commit if it exits with a non-zero value. (1) The file that holds the proposed message.
post-commit git commit Called after the actual commit is made. Because of this, it cannot disrupt the commit. It is mainly used to allow notifications. (none)
pre-rebase git rebase Called when rebasing a branch. Mainly used to halt the rebase if it is not desirable. (1 or 2) The upstream from where it was forked, the branch being rebased (not set when rebasing current)
post-checkout git checkoutand git clone Run when a checkout is called after updating the worktree or after git clone. It is mainly used to verify conditions, display differences, and configure the environment if necessary. (3) Ref of the previous HEAD, ref of the new HEAD, flag indicating whether it was a branch checkout (1) or a file checkout (0)
post-merge git merge or git pull Called after a merge. Because of this, it cannot abort a merge. Can be used to save or apply permissions or other kinds of data that git does not handle. (1) Flag indicating whether the merge was a squash.
pre-push git push Called prior to a push to a remote. In addition to the parameters, additional information, separated by a space is passed in through stdin in the form of "<local ref> <local sha1> <remote ref> <remote sha1>". Parsing the input can get you additional information that you can use to check. For instance, if the local sha1 is 40 zeros long, the push is a delete and if the remote sha1 is 40 zeros, it is a new branch. This can be used to do many comparisons of the pushed ref to what is currently there. A non-zero exit status aborts the push. (2) Name of the destination remote, location of the destination remote
pre-receive git-receive-pack on the remote repo This is called on the remote repo just before updating the pushed refs. A non-zero status will abort the process. Although it receives no parameters, it is passed a string through stdin in the form of "<old-value> <new-value> <ref-name>" for each ref. (none)
update git-receive-pack on the remote repo This is run on the remote repo once for each ref being pushed instead of once for each push. A non-zero status will abort the process. This can be used to make sure all commits are only fast-forward, for instance. (3) The name of the ref being updated, the old object name, the new object name
post-receive git-receive-pack on the remote repo This is run on the remote when pushing after the all refs have been updated. It does not take parameters, but receives info through stdin in the form of "<old-value> <new-value> <ref-name>". Because it is called after the updates, it cannot abort the process. (none)
post-update git-receive-pack on the remote repo This is run only once after all of the refs have been pushed. It is similar to the post-receive hook in that regard, but does not receive the old or new values. It is used mostly to implement notifications for the pushed refs. (?) A parameter for each of the pushed refs containing its name
pre-auto-gc git gc --auto Is used to do some checks before automatically cleaning repos. (none)
post-rewrite git commit --amendgit-rebase This is called when git commands are rewriting already committed data. In addition to the parameters, it receives strings in stdin in the form of "<old-sha1> <new-sha1>". (1) Name of the command that invoked it (amend or rebase)

Workflow for Remote CVS, Local Git

 

所有命令在Git Bash中执行,和正常的git流程相比:

1、git pull 被 cvs update 替换,且最好只在master上进行。

2、每次update后需要git commit -a "syn cvs date+msg" 执行一次commit,把本次cvs更新的内容加入git版本库。

 其他完全一样,随意切换分支!记得git stash save !

 

其他注意项:

1、在本地CVS代码处初始化git库

2、填写.gitignore规则,先commit,在 git bash 中 cvs update 后整体commit作为初始版本。

3、git master分支和远端cvs master分支对应,此后master分支只处理合入,dev分支最为常用开发。

4、设置一个有效的git remote url,才能执行git push利用Hook: pre-push,使用sys.exit(1)放弃本次git push。

 

posted @ 2017-11-28 22:58  水墨禅心  阅读(244)  评论(0编辑  收藏  举报