2014年6月14日 星期六

使用git-svn解決無svn http server而上傳程式

欲在區網上做測試環境,但伺服器上svn db 沒有開svn server,只可以ssh,所以使用git-svn這個迂迴的方法上傳程式到伺服器上的svn db(因git可以走ssh)

外部ip:x.x.x.x
svn db和程式放在外部伺服器上(走file://)
內部ip:o.o.o.o
我能動的只有外部伺服器的家目錄,和ssh連線到外部ip

svn db: x.x.x.x/home/svn/my_project
live 程式:x.x.x.x/var/www
將svn db用git svn clone到自己家目錄:x.x.x.x/home/user/git-svn_test
$ git svn clone file:///home/svn/my_project git-svn_test
再用ssh將去連結自己家目錄下git-svn的專案,在內部伺服器上改程式後再push上去到外部伺服器的家目錄下

$ git remote add ssh://x.x.x.x:22/home/user/blog_workspace/git-svn_test

測試紀錄
mkdir svn_test git-svn_test git-ssh_test # svn_test是外部live程式,git-svn_test是外部ip家目錄程式(橋接用),git-ssh_test是內部ip的測試環境

$ svnadmin create /home/svn/my_project #產生測試專案

ps. 下面git-svn 是remote 的名字

git-svn 使用方法參考: http://blog.chhsu.org/2010/05/git-git-svn.html

※svn_test
$ svn checkout file:///home/svn/my_project svn_test
$ touch svn_test/index.html
$ cd svn_test/
$ svn add index.html
$ svn commit -m "svn hello world"

※git-svn_test( 在remotes/git-svn/master這branch工作 )
$ git svn clone file:///home/svn/my_project git-svn_test
$ git checkout remotes/git-svn/master  # 做這步才會使git-ssh_test push上來的資料更新內容,且在這個branch上git svn dcommit 到svn db 上
$ git svn dcommit  #推git-svn_test的內容到svn db上
$ git svn rebase # 更新檔案到svn db上最新的內容,類似svn update, git pull

※git-ssh_test(在 svn-ssh_branch 這branch工作)
$ git --bare init
$ git remote add git-svn ssh://x.x.x.x:/home/user/blog_workspace/git-svn_test # ssh://x.x.x.x:22:/home/user/blog_workspace/git-svn_test 也是錯的
$ git fetch git-svn
ssh: Could not resolve hostname x.x.x.x:: Name or service not known
fatal: The remote end hung up unexpectedly =>會出現這錯誤
$ git remote rm git-svn
正確作法:
$ git remote add git-svn ssh://x.x.x.x:22/home/user/blog_workspace/git-svn_test
$ git fetch git-svn
user@x.x.x.x's password:
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ssh://x.x.x.x:22/home/user/blog_workspace/git-svn_test
 * [new branch]      master     -> git-svn/master
$ git branch -a
  remotes/git-svn/master
$ git checkout -b svn-ssh_branch remotes/git-svn/master # 建立svn-ssh_branch
$ echo "test" >> index.html
$ git add .
$ git commit -m "git-ssh commit"
$ git push git-svn svn-ssh_branch:remotes/git-svn/master git push git-svn_remote svn-ssh_branch:master  #推內部ip的程式到外部家目錄下 => http://stackoverflow.com/questions/1519006/git-how-to-create-remote-branch
user@x.x.x.x's password:
Counting objects: 5, done.
Writing objects: 100% (3/3), 237 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://x.x.x.x:22/home/user/blog_workspace/git-svn_test
 * [new branch]      svn-ssh_branch -> remotes/git-svn/master
$ git pull git-svn remotes/git-svn/master:svn-ssh_branch git pull git-svn_remote master:svn-ssh_branch # 更新自git-svn上的程式
(不能pull試試把紀錄reset --hard到前面一點的紀錄,再pull)

錯誤:
...
 ! [remote rejected] svn-ssh_branch -> remotes/git-svn/master (branch is currently checked out)
...
http://stackoverflow.com/questions/2816369/git-push-error-remote-rejected-master-master-branch-is-currently-checked
解法:
在remote repository資料夾下這指令
$ git config --bool core.bare true
或是
http://www.cnblogs.com/abeen/archive/2010/06/17/1759496.html
这是由于git默认拒绝了push操作,需要进行设置,修改.git/config(倉庫git-svn_test的)添加如下代码:
    [receive]
    denyCurrentBranch = ignore
在初始化远程仓库时最好使用 git --bare init   而不要使用:git init
   (如果使用了git init初始化,则远程仓库的目录下,也包含work tree,当本地仓库向远程仓库push时,   如果远程仓库正在push的分支上(如果当时不在push的分支,就没有问题), 那么push后的结果不会反应在work tree上,  也即在远程仓库的目录下对应的文件还是之前的内容,必须得使用git reset --hard才能看到push后的内容. )

錯誤:
$ git svn dcommit
fatal: This operation must be run in a work tree
update-index --refresh: command returned error: 128
http://stackoverflow.com/questions/9262801/fatal-this-operation-must-be-run-in-a-work-tree
解法:
$ git config core.bare false
所以在git-svn推到svn db時需要再下這指令,git-ssh推到git-svn時要再度打開
還是出現這錯誤的話嘗試git reset --hard

結論:
svn db 有新紀錄要更新到git-ssh_test
git-svn_test$ git svn rebase
git-ssh_test$ git reset <較前面的commit_id> --hard
git-ssh_test$ git pull git-svn remotes/git-svn/master:svn-ssh_branch

更新程式從git-ssh_test到svn db
git-svn_test$ git config --bool core.bare true
git-ssh_test$ git push git-svn svn-ssh_branch:remotes/git-svn/master
git-svn_test$ git config core.bare false
git-svn_test$ git reset --hard
git-svn_test$ git svn dcommit
svn_test$ svn update


svn 遠端倉庫改網址
用$ svn info查URL版本庫根
$ svn relocate
未知命令: “relocate”
使用“svn help”得到用法。
原因:
svn版本太新 -version 1.8.9 (r1591380)
svn 1.8.6才有svn relocate,改用svn switch --relocate
http://stackoverflow.com/questions/617239/svn-switch-relocate-not-persisting
bear@s2:/home/www/dev/cakephp$ svn switch --relocate  http://svn.your_domain.com.cn:81/84/trunk http://svn.your_domain.com.cn/svn/84/trunk

我用的是git svn,要怎麼改呢?
http://stackoverflow.com/questions/268736/git-svn-whats-the-equivalent-to-svn-switch-relocate
https://git.wiki.kernel.org/index.php/GitSvnSwitch
1. Edit the svn-remote url URL in .git/config to point to the new domain name # url = http://svn.your_domain.com.cn/svn/84/trunk/www/as/cakephp
2. Run git svn fetch - This needs to fetch at least one new revision from svn! => 出現錯誤:
Authentication realm: <http://svn.your_domain:80> SVN Repositories
Password for 'bear': Can't locate Term/ReadKey.pm in @INC (you may need to install the Term::ReadKey module) (@INC contains: /usr/share/perl5/site_perl /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5/core_perl /usr/share/perl5/core_perl .) at /usr/share/perl5/vendor_perl/Git.pm line 565.
解法:安裝perl 的Term/ReadKey
# cpan
cpan[1]> install Term::ReadKey
3. Change svn-remote url back to the original url # url = http://svn.your_domain.com.cn:81/84/trunk/www/as/cakephp
4. Run git svn rebase -l to do a local rebase (with the changes that came in with the last fetch operation)
5. Change svn-remote url back to the new url # url = http://svn.your_domain.com.cn/svn/84/trunk/www/as/cakephp
6. Run git svn rebase should now work again! =>出現錯誤: Unable to determine upstream SVN information from working tree history
( git reset --hard到之前的版本仍無效)
使用其他方法:
重新git svn clone 到新的資料夾,
然後參考 "[git] 查歷史紀錄 ( git常見問題 )" 把diff檔取出來然後apply回去
git apply出現錯誤
$ git apply ~/tmp.diff
error: cannot apply binary patch to 'app/webroot/css/images/images/album-b.jpg' without full index line
error: app/webroot/css/images/images/album-b.jpg: patch does not apply
解法:
編輯diff檔,把新增的圖檔那幾行刪掉再apply
cakephp記得再把tmp權限改成777

svn relocate出現錯誤:
The repository at 'https://new-repository/newpath/folder' has uuid 'd3b83275-bf16-aa42-9467-f8a402003233', but the WC has '30e22be1-af51-d84d-ad8f-d4e8545a4735'
http://stackoverflow.com/questions/3565284/problem-trying-to-relocate-wc-to-new-repository
原因:
relocate只能在你的svn庫移動後且svn沒有任何改變才能relocate ( You can not do relocate to a new repository, you need to delete your working copy and do a clean checkout.
Relocate can only be used if a repository has been moved unchanged to a new server or the server has got a new name. )

沒有留言:

張貼留言