2014-01-27 92 views
1

我想寫一個結帳和保持更新的makefile(通用或GNU)來操作多個svn工作副本,如repo_1 ... repo_n,像這樣已使svn結帳和更新各種工作副本

對於所有回購i

  • 如果./repo_i尚不存在,svn checkout repo_i [它應該實際上是安全的假設,沒有或全部存在,但我傾向於overengineer]
  • 否則cd ./repo_i && svn update

我非常確定這應該是優雅的可以做的,這似乎是一個非常簡單的事情要,所以別人一定有這個想法在我面前;但是,我仍然無法找到任何有用的東西,並在自己構建時遇到困難。

結賬部分是確定的,在那裏我可以做

DIRS = repo1 repo2 [...] repoN 
all: $(DIRS) 
$(DIRS): 
    svn checkout http://some.svn.path/[email protected]/trunk [email protected] 

但更新位是棘手。我希望在全新結帳後防止更新(確保它不會造成傷害,但是不要只是討厭冗餘?),然後我不確定如何在回購站中「循環」而不必寫出更新規則爲每個工作副本,並使其.PHONY,然後再次可能會干擾結帳規則。我最初的想法看起來像

DIRS = repo1 repo2 [...] repoN 
update: $(DIRS) 
    cd $(make-magic) && svn update 

但這不會飛,因爲規則更新repo_i將永遠不會被觸發,如果./repo_i已經存在,並檢查是否上行較新,我需要在./repo_i運行svn update

有沒有其他人試過這個?額外的榮譽,如果你的想法和make -j和平共處,只是因爲! (在N = 4的情況下也很乏味)。

PS:這是完全獨立於實際VCS的,但它需要使用svn工作(所以任何的那些神奇的git solve --all-problems不會幫助這裏:-)

回答

3

所以要記住的第一件事是,沒有先決條件的目標,如果目標存在,則認爲它們是最新的。因此,如果您的目標repo1的規則沒有先決條件且文件系統上存在(文件或目錄),make認爲它是最新的並且不會運行配方。

第二件要記住的是,默認情況下,僅處理文件系統和時間戳。沒有辦法建立依賴於其他內容的先決關係,比如「SVN倉庫是否是最新的?」。

所以。你需要做的第一件事就是將所有的存儲庫標記爲.PHONY,這樣即使目錄存在,配方也會一直運行。其次,您需要更改配方,使其或者檢出存儲庫(如果不存在),如果存在,則會更新它。

像這樣的東西應該做你想要什麼:

DIRS = repo1 repo2 [...] repoN 

.PHONY: update $(DIRS) 
update: $(DIRS) 
$(DIRS): 
     if [ -d [email protected] ]; then \ 
      cd [email protected] && svn update; \ 
     else \ 
      svn checkout http://some.svn.path/[email protected]/trunk [email protected]; \ 
     fi 

這也適用於-j。以上要求有人明確make update。如果你想嵌入它,以便它始終運行在每一個make(我不喜歡這個我自己...),你可以把update作爲所有編譯規則(模式規則等)的訂單唯一先決條件。

+0

感謝@MadScientist,就像你說過的那樣,它像'魅力一樣,也帶有'-j'。也會+1你,因爲我認爲你的答案是清晰和全面的,但缺乏代表:( – dlw