2011-04-07 126 views
5

我的項目有一個網絡文件系統上的Subversion版本庫,以及一個新的團隊想使用Git從它來訪問它,並能夠承諾,並得到更新。自動同步Subversion版本庫和一個Git倉庫

我想到的是在同一個網絡文件系統上創建Subversion版本庫的新版本git-svn,並確保兩個版本庫始終保持最新。

做到這一點的方法可能是添加一個post-commit鉤子兩個顛覆和新的Git倉庫,將每個更新其他的存儲庫。

顛覆post-commit鉤子將包括git svn rebase,和GIT中一個git svn dcommit

的問題是,我將不得不使用某種類型的鎖,以確保沒有人提交要麼庫,而其他也正在致力的,因爲他們總是要同步的任何承諾之前。這有幾個缺點,其中包括提交到Subversion或推送到Git存儲庫所需的時間(它必須等待掛鉤完成),以及某些用戶可能無法運行的事實(因爲它沒有安裝在他們的機器上),這意味着它們在提交/推送時不能更新其他存儲庫。

我該如何解決這些問題? Subversion和Git鉤子會是什麼樣子?

回答

12

這裏是我想出來的:

  1. 創建git-svn庫,如果不存在的話:

    git svn init --std-layout <svn_url> <git-svn_path> 
    

    master分支被自動創建跟蹤trunk

  2. 爲了避免名稱含糊不清與Subversion追蹤分支,使原來的Subversion分支顯示爲remotes/svn/<branch name>:去新創建git-svn庫和運行

    git config svn-remote.svn.fetch trunk:refs/remotes/svn/trunk 
    git config svn-remote.svn.branches branches/*:refs/remotes/svn/* 
    git config svn-remote.svn.tags tags/*:refs/remotes/svn/tags/* 
    
    rm .git/refs/remotes/* 
    git svn fetch 
    
  3. 爲每個Subversion的跟蹤分支Subversion的分支:

    for BRANCH in $(svn ls <svn_url>/branches/); do 
        git branch $BRANCH remotes/svn/$BRANCH 
    done 
    
  4. 確保沒有非Subversion的跟蹤分支在中央Git倉庫創建:

    # Used by hooks/update: 
    git config hooks.denyCreateBranch true 
    git config hooks.allowDeleteBranch false 
    
    cp .git/hooks/update.sample .git/hooks/update 
    chmod +x .git/hooks/update 
    
  5. 允許推到中央的Git倉庫:

    git config receive.denyCurrentBranch ignore 
    git config receive.denyNonFastForwards true 
    git config push.default current 
    

    ,並創建後收到鉤重置併發送提交到Subversion:

    cat .git/hooks/post-receive 
    
        #!/bin/sh 
    
        date >> receive.log 
        git reset --quiet --hard 
        while read LINE 
        do 
         BRANCH=${LINE##*/} 
         echo Updating $BRANCH 
         git checkout --quiet --force $BRANCH 
         git svn dcommit 
        done 2>&1 | tee -a receive.log 
        git checkout --quiet --force master 
    
    chmod +x .git/hooks/post-receive 
    

    復位是必要的,因爲否則當前分支在每次接收後都是過時的。

  6. 最後,創建鉤從Subversion獲取更新:

    cat .git/hooks/svn-rebase-all 
    
        #!/bin/sh 
    
        date >> .git/svn-rebase.log 
        git reset --quiet --hard 
        for REF in .git/refs/heads/* 
        do 
         BRANCH=${REF##*/} 
         echo Updating $BRANCH 
         git checkout --quiet --force $BRANCH 
         git svn rebase 
        done 2>&1 | tee -a .git/svn-rebase.log 
        git checkout --quiet --force master 
    
    chmod +x .git/hooks/svn-rebase-all 
    

    而且從Subversion稱它爲post-commit鉤子:

    cat <svn_path>/hooks/post-commit 
    
        cd <git_path> 
        . .git/hooks/svn-rebase-all 
    
    chmod +x <svn_path>/hooks/post-commit 
    

而不是使用一個單一的git-svn中央存儲庫,可以使用一個裸露的中央Git存儲庫和一個非中間存儲庫git-svn,如this answer。 我選擇使用一個非裸露的git-svn存儲庫,它也是中央存儲庫。

任何人都可以使用Git工作,方法是克隆<git_path>並推送到該項目,或使用Subversion簽出<svn_url>並提交。

+0

'git config hooks.denycreatebranch false' @丹尼爾你的意思是「真」嗎? – basin 2013-04-22 11:10:25

+0

@basin是的,我想是的。謝謝。 – 2013-04-22 12:57:08

4

你只有讓每個開發者更好學習直接使用git-svn。 git和SVN模型之間的阻抗失配太多,無法實現您正在尋找的功能。只有這樣才能使其工作得幾乎可靠,唯一的辦法是制定git-svn可能具有的相同類型的限制,但是可能會有更多移動部件可能中斷。在我看來,你的版本控制系統並不是你想要的部分可靠的東西。

或者只是溝SVN乾脆一路搬到混帳如果可能的話。

+1

我確實打算在某個時候將我的團隊轉移到Git上,但我認爲git-svn允許的逐步移動是一個很大的優勢。我想其他團隊將不得不完成我的git-svn克隆副本,並使用git svn dcommit和git svn rebase自己。 – 2011-04-09 14:05:19

+2

如果多個git repos使用git-svn從中央svn repo推送/拉出(我相信這是推薦的),那麼在這些git repos之間直接推/拉將會很困難。這是因爲git分支在'git svn rebase'期間被重新設置。 – 2011-05-02 20:56:51

+0

這是正確的,並且它還使未來更加難以轉換爲純粹的Git配置,因爲每個人都必須通過創建補丁並將它們應用於來自新中央Git存儲庫的新克隆存儲庫來「遷移」其Git存儲庫。 – 2011-10-03 17:24:03