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 新手,所以如果有不對的地方,歡迎指正。

2014年3月19日 星期三

git with company svn repository

Written with StackEdit.

因為一般公司都是用 SVN 作 VCS,但當你想用 git 作 local version control 的時後,該怎麼辨呢?
最近花了一點時間在研究這個工作方法 ,有點復雜,分享小弟一些心得給大家。

下面是我的預想图:
enter image description here
首先先看 SVN, 上面有兩個 branch: branch_1,branch_2 (在此我用藍色表示 source注1)
(為何不是 standard SVN layout, trunk, branchs, tags? 因為公司不一定遵守 ….)

我希望將 SVN 拉到 local git repository, 並用 remotes/branch_1, remotes/branch_2 分別指到 SVN 上的 branch_1,branch_2,然後 create local git branchs,svn-branch_1 and svn-branch_1 to track remotes/branch_1 及 remotes/branch_2。

在操作上,svn-XXX 只用來將 SVN 上的 branch 修改拉下來,不會直接在上面修改,以免在下 $git svn rebase 時出問題。因此我們還需要再另外從 svn-XXX branch 出來作修改使用。 在此例即為 git-feature1-branch_1 , git-feature1-branch_2。

(注1: 以上 naming rule 均參考Plasma’s BLOG)
(注2: 在此使用 git 指標的全名說明觀念比較清楚)

最後,我想在再把我的 git 放到另一個 remote git repository 作備份,所以需要再 create remote branch git-feature1, git-feature2 來存 git-feature1-branch_1 , git-feature1-branch_2。
(其實也可以再 create git-svn-branch_1, git-svn-branch_1 來存 svn-branch_1, svn-branch_1,這樣也可以保留 SVN 的 log.)

我也是 git 新手,所以如果有不對的地方,歡迎指正。