2014年3月24日 星期一

git-svn experience sharing.

延續之前 git-svn 運作預想图我查了也試了幾個方法,發現事情並不單純,在此分享一下我嘗試過的方法,以試著歸納出最適合這种工作環境的運作方。
首先假設我已在 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 新手,所以如果有不對的地方,歡迎指正。

沒有留言:

張貼留言