$ sudo aptitude install git-svn將 git-svn 獨(dú)立安裝是因?yàn)?git-svn 軟件包有著特殊的依賴,即依賴 Subversion 的 perl 語言綁定接口,Debian/Ubuntu 上由 libsvn-perl 軟件包提供。當(dāng) git-svn 正確安裝后,就可以使用 git svn 命令了。但如果在執(zhí)行 git svn --version 時(shí)遇到下面的錯(cuò)誤,則說明 Subversion 的 perl 語言綁定沒有正確安裝。
$ git svn --versionCan't locate loadable object for module SVN::_Core in @INC (@INC contains: /usr/share/perl/5.10.1 /etc/perl /usr/local/lib/perl/5.10.1 /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 .) at /usr/lib/perl5/SVN/Base.pm line 59BEGIN failed--compilation aborted at /usr/lib/perl5/SVN/Core.pm line 5.Compilation failed in require at /usr/lib/git-core/git-svn line 41.遇到上面的情況,需要檢查本機(jī)是否正確安裝了 Subversion 以及 Subversion 的 perl 語言綁定。為了便于對(duì) git-svn 的介紹和演示,我們需要有一個(gè) Subversion 版本庫,并且需要有提交權(quán)限以便演示用 Git 向 Subversion 進(jìn)行提交。最好的辦法是在本地創(chuàng)建一個(gè) Subversion 版本庫。
$ svnadmin create /path/to/svn/repos$ svn co file:///path/to/svn/repos svndemo取出版本 0$ cd svndemo$ mkdir trunk tags branches$ svn add *A branchesA tagsA trunk$ svn ci -m "initialized."增加 branches增加 tags增加 trunk提交后的版本為 1。我們?cè)傧?Subversion 開發(fā)主線 trunk 中添加些數(shù)據(jù)。
$ echo hello > trunk/README$ svn add trunk/READMEA trunk/README$ svn ci -m "hello"增加 trunk/README傳輸文件數(shù)據(jù).提交后的版本為 2。建立分支:
$ svn up$ svn cp trunk branches/demo-1.0A branches/demo-1.0$ svn ci -m "new branch: demo-1.0"增加 branches/demo-1.0提交后的版本為 3。建立里程碑:
$ svn cp -m "new tag: v1.0" trunk file:///path/to/svn/repos/tags/v1.0提交后的版本為 4。
git svn clone | v (本地Git庫) | v+-> (hack...)| || v| git add| || v| git commit| |+-----+ | vgit svn rebase | vgit svn dcommit首先用 git svn clone 命令對(duì) Subversion 進(jìn)行克隆,創(chuàng)建一個(gè)包含 git-svn 擴(kuò)展的本地 Git 庫。在下面的示例中,我們使用 Subversion 的本地協(xié)議(file://) 來訪問之前創(chuàng)立的 Subversion 示例版本庫,實(shí)際上 git-svn 可以使用任何 Subversion 可用的協(xié)議,并可以對(duì)遠(yuǎn)程版本庫進(jìn)行操作。
$ git svn clone -s file:///path/to/svn/repos git-svn-demoInitialized empty Git repository in /my/workspace/git-svn-demo/.git/r1 = 2c73d657dfc3a1ceca9d465b0b98f9e123b92bb4 (refs/remotes/trunk) A READMEr2 = 1863f91b45def159a3ed2c4c4c9428c25213f956 (refs/remotes/trunk)Found possible branch point: file:///path/to/svn/repos/trunk => file:///path/to/svn/repos/branches/demo-1.0, 2Found branch parent: (refs/remotes/demo-1.0) 1863f91b45def159a3ed2c4c4c9428c25213f956Following parent with do_switchSuccessfully followed parentr3 = 1adcd5526976fe2a796d932ff92d6c41b7eedcc4 (refs/remotes/demo-1.0)Found possible branch point: file:///path/to/svn/repos/trunk => file:///path/to/svn/repos/tags/v1.0, 2Found branch parent: (refs/remotes/tags/v1.0) 1863f91b45def159a3ed2c4c4c9428c25213f956Following parent with do_switchSuccessfully followed parentr4 = c12aa40c494b495a846e73ab5a3c787ca1ad81e9 (refs/remotes/tags/v1.0)Checked out HEAD: file:///path/to/svn/repos/trunk r2從上面的輸出我們看到,當(dāng)執(zhí)行了 git svn clone 之后,在本地工作目錄創(chuàng)建了一個(gè) Git 庫 (git-svn-demo),并將 Subversion 的每一個(gè)提交都轉(zhuǎn)換為 Git 庫中的提交。我們進(jìn)入 git-svn-demo 目錄,看看我們用 git-svn 克隆出來的版本庫。
$ cd git-svn-demo/$ git branch -a* master remotes/demo-1.0 remotes/tags/v1.0 remotes/trunk$ git logcommit 1863f91b45def159a3ed2c4c4c9428c25213f956Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Mon Nov 1 05:49:41 2010 +0000 hello git-svn-id: file:///path/to/svn/repos/trunk@2 f79726c4-f016-41bd-acd5-6c9acb7664b2commit 2c73d657dfc3a1ceca9d465b0b98f9e123b92bb4Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Mon Nov 1 05:47:03 2010 +0000 initialized. git-svn-id: file:///path/to/svn/repos/trunk@1 f79726c4-f016-41bd-acd5-6c9acb7664b2我們看到 Subversion 版本庫的分支和里程碑都被克隆出來,并保存在 refs/remotes 下的引用中。在 git log 的輸出中,我們可以看到 Subversion 的提交的確被轉(zhuǎn)換為 Git 的提交。下面我們就可以在 Git 庫中進(jìn)行修改,并在本地提交(用 git commit 命令)。
$ cat READMEhello$ echo "I am fine." >> README$ git add -u$ git commit -m "my hack 1."[master 55e5fd7] my hack 1. 1 files changed, 1 insertions(+), 0 deletions(-)$ echo "Thank you." >> README$ git add -u$ git commit -m "my hack 2."[master f1e00b5] my hack 2. 1 files changed, 1 insertions(+), 0 deletions(-)我們對(duì)工作區(qū)中的 README 文件修改了兩次,并進(jìn)行了本地的提交。我們查看這時(shí)的提交日志,會(huì)發(fā)現(xiàn)最新兩個(gè)只在本地 Subversion 版本庫的提交和之前 Subversion 中的提交的不同。區(qū)別在于最新在 Git 中的提交沒有用 git-svn-id: 標(biāo)簽標(biāo)記的行。
$ git logcommit f1e00b52209f6522dd8135d27e86370de552a7b6Author: Jiang Xin <jiangxin@ossxp.com>Date: Thu Nov 4 15:05:47 2010 +0800 my hack 2.commit 55e5fd794e6208703aa999004ec2e422b3673adeAuthor: Jiang Xin <jiangxin@ossxp.com>Date: Thu Nov 4 15:05:32 2010 +0800 my hack 1.commit 1863f91b45def159a3ed2c4c4c9428c25213f956Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Mon Nov 1 05:49:41 2010 +0000 hello git-svn-id: file:///path/to/svn/repos/trunk@2 f79726c4-f016-41bd-acd5-6c9acb7664b2commit 2c73d657dfc3a1ceca9d465b0b98f9e123b92bb4Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Mon Nov 1 05:47:03 2010 +0000 initialized. git-svn-id: file:///path/to/svn/repos/trunk@1 f79726c4-f016-41bd-acd5-6c9acb7664b2現(xiàn)在我們就可以向 Subversion 服務(wù)器推送我們的改動(dòng)了。但真實(shí)的環(huán)境中,往往在我們向服務(wù)器推送時(shí),已經(jīng)有其它用戶先于我們?cè)诜?wù)器上進(jìn)行了提交。而且往往更糟的是,先于我們的提交會(huì) 造成我們的提交沖突!我們現(xiàn)在就人為的制造一個(gè)沖突:使用 svn 命令在 Subversion 版本庫中執(zhí)行一次提交。
$ svn checkout file:///path/to/svn/repos/trunk demoA demo/README取出版本 4。$ cd demo/$ cat READMEhello$ echo "HELLO." > README$ svn commit -m "hello -> HELLO."正在發(fā)送 README傳輸文件數(shù)據(jù).提交后的版本為 5。好的,我們已經(jīng)模擬了一個(gè)用戶先于我們更改了 Subversion 版本庫?,F(xiàn)在回到我們用 git-svn 克隆的本地版本庫,執(zhí)行 git svn dcommit 操作,將我們?cè)?Git 中的提交推送的 Subversion 版本庫中。
$ git svn dcommitCommitting to file:///path/to/svn/repos/trunk ...事務(wù)過時(shí): 文件 “/trunk/README” 已經(jīng)過時(shí) at /usr/lib/git-core/git-svn line 572顯然,由于 Subversion 版本庫中包含了新的提交,導(dǎo)致我們執(zhí)行 git svn dcommit 出錯(cuò)。這時(shí)我們需執(zhí)行 git svn fetch 命令,以從 Subversion 版本庫獲取更新。
$ git svn fetch M READMEr5 = fae6dab863ed2152f71bcb2348d476d47194fdd4 (refs/remotes/trunk)15:37:08 jiangxin@hp:/my/workspace/git-svn-demo$ git st# On branch masternothing to commit (working directory clean)當(dāng)我們獲取了新的 Subversion 提交之后,我們需要執(zhí)行 git svn rebase 將我們 Git 中未推送到 Subversion 的提交通過變基(rebase)形成包含 Subversion 最新提交的線性提交。這是因?yàn)?Subversion 的提交都是線性的。
$ git svn rebaseFirst, rewinding head to replay your work on top of it...Applying: my hack 1.Using index info to reconstruct a base tree...Falling back to patching base and 3-way merge...Auto-merging READMECONFLICT (content): Merge conflict in READMEFailed to merge in the changes.Patch failed at 0001 my hack 1.When you have resolved this problem run "git rebase --continue".If you would prefer to skip this patch, instead run "git rebase --skip".To restore the original branch and stop rebasing run "git rebase --abort".rebase refs/remotes/trunk: command returned error: 1果不其然,變基時(shí)發(fā)生了沖突,這是因?yàn)?Subversion 中他人的修改和我們?cè)?Git 庫中的修改都改動(dòng)了同一個(gè)文件,并且改動(dòng)了相近的行。下面按照 git rebase 沖突解決的一般步驟進(jìn)行,直到成功完成變基操作。先編輯 README 文件,以解決沖突。
$ git status# Not currently on any branch.# Unmerged paths:# (use "git reset HEAD <file>..." to unstage)# (use "git add/rm <file>..." as appropriate to mark resolution)## both modified: README#no changes added to commit (use "git add" and/or "git commit -a")15:49:30 jiangxin@hp:/my/workspace/git-svn-demo$ vi README處于沖突狀態(tài)的 REAEME 文件內(nèi)容。
<<<<<<< HEADHELLO.=======helloI am fine.>>>>>>> my hack 1.下面是我們修改后的內(nèi)容。保存退出。
HELLO.I am fine.執(zhí)行 git add 命令解決沖突
$ git add README調(diào)用 git rebase --continue 完成變基操作。
$ git rebase --continueApplying: my hack 1.Applying: my hack 2.Using index info to reconstruct a base tree...Falling back to patching base and 3-way merge...Auto-merging README看看變基之后的 Git 庫日志:
$ git logcommit e382f2e99eca07bc3a92ece89f80a7a5457acfd8Author: Jiang Xin <jiangxin@ossxp.com>Date: Thu Nov 4 15:05:47 2010 +0800 my hack 2.commit 6e7e0c7dccf5a072404a28f06ce0c83d77988b0bAuthor: Jiang Xin <jiangxin@ossxp.com>Date: Thu Nov 4 15:05:32 2010 +0800 my hack 1.commit fae6dab863ed2152f71bcb2348d476d47194fdd4Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Thu Nov 4 07:15:58 2010 +0000 hello -> HELLO. git-svn-id: file:///path/to/svn/repos/trunk@5 f79726c4-f016-41bd-acd5-6c9acb7664b2commit 1863f91b45def159a3ed2c4c4c9428c25213f956Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Mon Nov 1 05:49:41 2010 +0000 hello git-svn-id: file:///path/to/svn/repos/trunk@2 f79726c4-f016-41bd-acd5-6c9acb7664b2commit 2c73d657dfc3a1ceca9d465b0b98f9e123b92bb4Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Mon Nov 1 05:47:03 2010 +0000 initialized. git-svn-id: file:///path/to/svn/repos/trunk@1 f79726c4-f016-41bd-acd5-6c9acb7664b2當(dāng)變基操作成功完成后,我們?cè)賵?zhí)行 git svn dcommit 向 Subversion 推送我們?cè)?Git 庫中的兩個(gè)新提交。
$ git svn dcommitCommitting to file:///path/to/svn/repos/trunk ... M READMECommitted r6 M READMEr6 = d0eb86bdfad4720e0a24edc49ec2b52e50473e83 (refs/remotes/trunk)No changes between current HEAD and refs/remotes/trunkResetting to the latest refs/remotes/trunkUnstaged changes after reset:M README M READMECommitted r7 M READMEr7 = 69f4aa56eb96230aedd7c643f65d03b618ccc9e5 (refs/remotes/trunk)No changes between current HEAD and refs/remotes/trunkResetting to the latest refs/remotes/trunk推送之后本地 Git 庫中最新的兩個(gè)提交的提交說明中也嵌入了 git-svn-id: 標(biāo)簽。這個(gè)標(biāo)簽的作用非常重要,我們?cè)谙乱还?jié)予以介紹。
$ git log -2commit 69f4aa56eb96230aedd7c643f65d03b618ccc9e5Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Thu Nov 4 07:56:38 2010 +0000 my hack 2. git-svn-id: file:///path/to/svn/repos/trunk@7 f79726c4-f016-41bd-acd5-6c9acb7664b2commit d0eb86bdfad4720e0a24edc49ec2b52e50473e83Author: jiangxin <jiangxin@f79726c4-f016-41bd-acd5-6c9acb7664b2>Date: Thu Nov 4 07:56:37 2010 +0000 my hack 1. git-svn-id: file:///path/to/svn/repos/trunk@6 f79726c4-f016-41bd-acd5-6c9acb7664b2
使用 git-svn 和 git-filter-branch 整理 SVN 版本庫 | 2014-04-24 | 0 Comments |
---|---|---|
復(fù)用 git.git 測(cè)試框架 | 2013-10-26 | 1 Comment |
墻不住的Git官網(wǎng) | 2013-03-04 | 5 Comments |
聯(lián)系客服