使用 git-svn 整合 git 與 svn
git 是目前最紅的分散式 VCS 之一,我很喜歡用 git 因為他預設就有許多方便的特性如:
- git log/diff/help 都有彩色的 pager 可用,不用再自己 pipe 到 less
- git log 的格式一目了然,清晰易懂
- git bisect/format-patch/shortlog/stash… 等趁手工具一堆
- 速度快
而 git 不僅僅是 git,他分成高階的命令如 pull/commit 等,還有低階的命令可以直接操作 ref/object,因此有一些 VCS 就是建立在 git 的檔案系統上,運作起來跟 git 截然不同。
git-svn 是一個可以把 svn 當 git 用的工具,就算專案還在用 svn 也可以享受到 git 的便利。以下簡介一下 git-svn 的使用流程。
首先創造一個實驗用的 svn repository:
bob % cd /tmp/test
bob % svnadmin create hello
bob % svn co file:///tmp/test/hello hello-svn
bob % cd hello-svn
bob % svn mkdir branches tags trunk
bob % svn ci -m'Initial dir setup'
現在我們有一個傳統的 svn repository 了,加點東西進去吧:
bob % cd trunk
bob % echo "printf("hello\n");" > hello.c
bob % svn add hello.c
bob % svn ci -m'My first program :D'
bob % cd ..
bob % svn cp trunk tags/v0.1
bob % svn ci -m'tag v0.1'
這時候 Bob 已經建好他的程式 v0.1 版,Alice 知道了他的計劃也想加入,於是她用 git-svn 來取出 repository
alice % git svn clone --stdlayout file:///tmp/test/hello hello-git
Initialized empty Git repository in /tmp/test/hello-git/.git/
r1 = 80a0fc18653e8bc7d3784567b1b7024b20fd8c11 (trunk)
A hello.c
r2 = 4a80acebb6a41c208f3427498225f829950ee39e (trunk)
Found possible branch point: file:///tmp/test/hello/trunk => file:///tmp/test/hello/tags/v0.1, 1
Found branch parent: (tags/v0.1) 80a0fc18653e8bc7d3784567b1b7024b20fd8c11
Following parent with do_switch
A hello.c
Successfully followed parent
r3 = 24ca9410e9ca78ffa3bffa1c9ef574068d128935 (tags/v0.1)
Checked out HEAD:
file:///tmp/test/hello/tags/v0.1 r3
alice % git reset --hard remotes/trunk
因為是使用 stdlayout,所以 tag/branch 等會自動對應到 remote branch
alice % cd hello-git
alice % git branch -r
tags/v0.1
trunk
Alice 發現 Bob 原本的程式無法 compile,因此開始修改,改完之後用 git add -p
挑選要 commit 的部份,然後把剩下的部份 stash 起來,最後用 git svn dcommit
提交給 Bob 的 svn repository
alice % edit hello.c
alice % git add -p
alice % git commit -m'Fix everything'
alice % git stash
alice % git svn dcommit
隔了幾天,Alice 發現 Bob 有更新,因此開始做同步。同時,因為她有一個 local branch,所以在更新完 master 之後,還需要把 fancy branch 跟 master rebase。
alice % git svn fetch
M hello.c
r6 = c43134a98f43dc6507deaa7495bfcd2c906aaa30 (trunk)
alice % git svn rebase
First, rewinding head to replay your work on top of it...
Fast-forwarded master to refs/remotes/trunk.
alice % git checkout fancy
alice % git rebase master
First, rewinding head to replay your work on top of it...
Applying: Inital fancy output branch
以上就是使用 git-svn 時會用到的大部分指令,其餘的就跟操作一般 git 一樣。
各命令的詳細說明可以參考 git-svn(1)