在 CafeMol 项目上试用 Git-Svn
git-svn
- Bidirectional operation between a Subversion repository and Git.1
写在前面的废话
很久以前当我准备开始学习版本控制的时候, 就已经有了 git 与 github, 因此我也少走 了许多弯路。 甚至在我写博士论文的时候, 全部都用 git 来进行 $\LaTeX$ 文件的管理。 这也是我惨淡的博士求学生涯中为数不多值得回味的快乐回忆。
后来我开始了博士后阶段的工作。 在新的组里遇到的代码管理工具居然是 svn。 没有办
法, 我自己只好想其他路子来克服从 git 切换到 svn 的焦虑。 我找到一个愚蠢但有效
的路径: 首先克隆 svn 项目, 然后 git 化, 并把 .svn
等目录加到 .gitignore
列表中, 之后就可以像普通 git 一样来管理代码了。 不过在给 svn 版本贡献代码时,
却需要对照 git diff
的结果, 一条条手动加入到 svn 代码库, 然后再进行危险的
svn commit
。 有效但愚蠢。
事实上, git 本身就提供一个工具 git svn
来做我想做的事情: 周游于两种版本控制
体系之间。
## 概述 ---
这里以我操作 CafeMol 的经过为例子, 写下一些简单的 git svn
流程。
### 从 svn 服务器获取拷贝
这是第一步:
git svn clone http://server.name.net/svn/cafemol/trunk cafemol --username tan
网上有许多教程提示说可以用 -s
选项来自动获取所有的 svn 分支。 很智能, 但是未
必实用。 以我们的 CafeMol 项目为例, 该项目有许多代码贡献者, 也于是有许多的
svn 分支, 每个分支都可能仅仅只是一些测试性的代码, 根本没有必要拷贝至本地。 此
外, git svn
过于智能到连已经删除的 svn 分支也会抓取。 这会导致 git branch -a
变成又臭又长的一串红色列表。 至少爱清洁的人是不会这样做的。
### 从 svn 设置来创建 `gitignore`
很简单:
git svn show-ignore >> .git/info/exclude
### 简单的流程及命令
从服务器更新
git svn rebase
推送本地修改到服务器
git svn dcommit
看 log
git svn log | less
# or:
git log
创建本地分支
与基本的 git
命令使用方式一致:
git checkout -b develop
git add .
git commit -a
合并到 master
:
git rebase master
git checkout master
git merge develop
这里使用 rebase
而不用 merge
是考虑保持 svn log 的简单线性。
### 注意
简单来说, 每一次 git svn dcommit
都会改写 git commit
的记录。 因此每次推送
之后, 不同分支与 master 之间就会出现奇怪的分叉行为: 因为本来的共同祖先的信息被
改写了。 因此在进行这些操作时需要格外注意: 最好在每次 dcommit 之后将本地的危险
分支给删除。
感觉还是很傻!