首先假設我已在 user home 下面弄好一個 local SVN 的環境以供測試,其架構如下:
file:///home/user/temp/svn_reporsitory
├── branches
│ ├── br1
│ │ ├── add_file
│ │ ├── br1_file
│ │ └── trunk_file
│ ├── br2
│ │ ├── add_file
│ │ ├── svn-commit.tmp
│ │ └── trunk_file
│ └── br3
│ ├── add_file
│ ├── br1_file
│ └── trunk_file
├── tags
├── test
└── trunk
├── add_file
├── svn-commit.tmp
└── trunk_file
一定有人想問,為何有些東西不是放在 branches, tags or trunks 裡面,因為我遇到的 SVN repository 就是像這樣,如之前所提,公司人員不一定遵守 standard SVN layout, 因此模擬的 case 就要作得像一點。local git 和 remote SVN 運作
假設在沒有 remote git repository backup 的需求下,用 local git 就可以了。standart SVN layout case:
就如上面的 layout 還存在 branches,tags and trunk,因此下面指令就可以將它們都抓下來$git svn clone -s file:///home/user/temp/svn_reporsitory/
接下來查看 remote branch 就可以看到連到到 remote SVN 的 branch 了。
$ git branch -r
br1
br2
br3
trunk
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[svn-remote "svn"]
url = file:///home/user/temp/svn_reporsitory
fetch = trunk:refs/remotes/trunk
branches = branches/*:refs/remotes/*
tags = tags/*:refs/remotes/tags/*
上面可以看到 .git/config 多了一個 [svn-remote "svn"]
,這是git-svn 建立的一個模擬 git remote 的section, 其中 fetch = xxx 就是你要抓的 branch,此例 trunk:refs/remotes/trunk 即表示建一個 refs/remotes/trunk 追綜 file:///home/user/temp/svn_reporsitory/trunk實際上就是讓 local git 認為有一個 remote git 叫 trunk,而 git-svn 這個 module 會利用 fetch or rebase command 將 remote SVN 的修改版本記錄抓到 local git 認為的 remote, trunk. 如此一來,就可以方便使用 normal git command.
non-standart SVN layout case 1:
就是我遇到的 cases 啦~ 我遇到的 svn layout 如下:├── branches
│ ├── br1
│ │ ├── add_file
│ │ ├── br1_file
│ │ └── trunk_file
│ ├── br2
│ │ ├── add_file
│ │ ├── svn-commit.tmp
│ │ └── trunk_file
│ ├── br3
│ │ ├── add_file
│ │ ├── br1_file
│ │ └── trunk_file
│ └── test_build
│ └── br1
│ ├── add_file
│ ├── br1_file
│ └── trunk_file
他們將實際上的 trunk 放在 branches 裡面 (ex. br1), 然後在branches 裡再多開folder 叫test_build,用以存放暫時的 build ,ex. (
$svn cp br1 test_build/br1
)。 這個 case 我就不要把整個 repository 透過
git svn clone -s url
抓下來了,因為太大。 我只想抓我要的
br1
, br2
and test_build/br1
先 create 一個 local git,然後把 .git/config 。
$git init test
$vim test/.git/config
[svn-remote "svn-rep"]
url = file:///home/user/temp/svn_reporsitory
fetch = branches/br1:refs/remotes/branches/svn-br1
fetch = branches/test_build/br1:refs/remotes/branches/test_build/svn-br1
$ git svn fetch svn-rep
....
Found possible branch point: file:///home/user/temp/svn_reporsitory/trunk => file:///home/user/temp/svn_reporsitory/branches/br1, 9
....
$ git branch -r
branches/svn-br1
branches/svn-br1@9
branches/test_build/svn-br1
這裡出現一個奇怪的 branch branches/svn-br1@9,我猜應該是因為git-svn 需要create 一個branch 來記錄目前 branch 的 parent branch.這裡可以知道更多更清楚的 git-svn 說明。
注記:
在 windows git shell 中執行時,發現第二筆的 fetch 一直都不會被抓下來 (也就是無法在
git branch -r
裡面看到),原因不明… 唯一覺得奇怪的地方在於執行 git svn -r HEAD fetch xxx
時出現了 error message如下: Couldn't find revmap for svn://xxx/xxx/trunk/xxx/xxx
上面的 xxx 並不是我在 fetch 中指定的 branch ,應該 git-svn 在找尋 parent branch 的資訊時失敗。
non-standart SVN layout case 2:
承接 case 1, 可以發現其實 section name 可以自已取的,以case 1 的例子就是 “svn-rep”,所以,其實也可以把每個 branch 的 fetch 放到不同的 section name, ex. svn-rep-br1, svn-rep-br2, svn-rep-test_build_br1.
如下例:
.git/config
[svn-remote "svn-rep-br1"]
url = file:///home/user/temp/svn_reporsitory
fetch = branches/br1:refs/remotes/branches/svn-br1
[svn-remote "svn-rep-test_build-br1"]
url = file:///home/user/temp/svn_reporsitory
fetch = branches/test_build/br1:refs/remotes/branches/svn-test_build-br1
$ git svn fetch svn-rep-test_build-br1
$ git branch -r
branches/svn-br1
branches/svn-br1@9
branches/svn-test_build-br1
$ git svn fetch svn-rep-test_build-br1
$ git branch -r
branches/svn-br1
branches/svn-br1@9
branches/svn-test_build-br1
我也是 git 新手,所以如果有不對的地方,歡迎指正。
沒有留言:
張貼留言