2013-03-06 33 views
3

我對使用git非常陌生,以前並沒有真正試圖「組織」我所從事的任何項目。然而,我最近剛購買了個人使用的開發服務器,並且我想開始組織我所有的項目並使用版本控制。git中的子模塊庫,以最大限度地減少冗餘

我已經花了近8個小時的項目組織文件研究不同的推薦方法,我意識到,這是一個非常主觀的問題。然而,我已經開發了一個系統,我認爲它可以用於任何原因,而且我有一個關於如何使用目錄結構完成特定任務的非常客觀的問題。

目前我正在尋找到一個結構類似以下內容:

src/ - All deliverables in an uncompiled form (PHP files, c source files, etc) 
data/ - Crucial but unrelated data (SQL databases, etc.) 
lib/ - Dependencies -- THIS IS WHERE MY QUESTION LIES 
docs/ - Documentation 
build/ - Scripts to aide in the build process 
test/ - Unit tests 
res/ - Not version controlled. Contains PSD files and non-diff-able stuff 
.gitignore 
README 
output.zip - Ready-to-install finished product (just unzip and go) 

正如我提到的 - 這lib/目錄在我的真正的問題旋轉。這需要包含我的項目運行所需的所有文件和程序,但這些文件和程序超出了我的項目範圍,因此我不會進行編輯。我需要這個文件夾的一些功能有:

  • 由於這些都需要我的最終產品來運行,它們必須包含在output.zip
  • 我想這個文件夾進行版本控制,使任何人誰下載我的git存儲庫將有權訪問所有依賴項
  • 如果幾個項目具有相同的依賴關係,我不想在我的服務器上有相同文件的18個冗餘副本
  • 我希望能夠拉這些來自我的其他項目的依賴關係(一個項目應該能夠作爲單獨項目的庫)

我可以通過使用虛擬目錄(符號鏈接)來避免擁有18個相同文件的冗餘副本,但是根據我的理解,git會將此符號鏈接原樣複製到存儲庫中而不復制文件。因此,如果其他人抓取我的倉庫,他們將有一個懸掛指針,沒有庫。

起初,它看起來像我能做什麼,我想用git-submodule。但從我的理解,這採取了另一個存儲庫的全部內容,並將其視爲一個子目錄。因此,如果我包括「依賴一個」我的庫文件夾會看起來像:

/lib/A/src/ 
/lib/A/data/ 
... 
/lib/A/test/ 
.gitignore 
README 
output.zip 

在腳本(PHP,Perl等),我大概可以加載使用require('lib/A/src/dependency.php')依賴的情況下,但在案件DLL或二進制文件的文件我沒有簡單的方法來從output.zip讀取輸出文件。我可以將完成的項目直接存儲在根目錄下,而不是包裝在一個漂亮的zip文件中,但是如果項目是一個網站 - 這可能意味着數百個文件混亂了我的存儲庫根目錄。

如何將另一個存儲庫作爲我自己的庫引入,在我自己的項目中輕鬆引用庫文件,將庫有意地複製到提取我的存儲庫的任何人,並防止我的開發中的相同文件的多餘副本服務器?

編輯:在谷歌搜索一段時間後,我發現this similar issue,但它只能解決PHP項目。儘管自動加載器可能允許您在PHP環境中掩蓋底層文件系統,但您如何將類似的方法應用於C++項目?還是一個Python項目?還是一個Java項目?

當我今天想到更多關於這個項目的時候,我想到了一些其他的想法,這可能需要一個新的思維方向。首先是非常深的圖書館巢穴問題。如果項目A依賴於依賴於項目C++項目B,其取決於項目d,那麼你將有一個目錄結構如下所示:

A/lib/ 
A/lib/B/ 
A/lib/B/lib/ 
A/lib/B/lib/C/ 
A/lib/B/lib/C/lib/ 
A/lib/B/lib/C/lib/D/ 

顯然,這不僅會招人煩,但以自己的方式是多餘的。

正常人在做git存儲庫時如何處理依賴關係?

回答

3

在我參與的項目中,子模塊僅適用於涉及依賴管理的某些情況,在其他情況下,此模塊由其他框架補充。大多數情況下,當我需要完整的存儲庫時,我更喜歡使用子模塊,例如我有一個公用的構建腳本,可以跨項目共享。

有側重於依賴管理在不同堆棧特定的工具 -

這些工具負責冗餘管理。

目前,我在一個.NET項目,我們有這樣的設置 -

整個使用子模塊項目共享
  1. Powershell的構建腳本。 Buildscript存儲庫包含部署我們的.NET應用程序和相應的包裝器PowerShell腳本所需的所有第三方可執行文件,以及一些用於加載約定,配置等的腳本。
  2. Nuget服務器(通過Teamcity)託管共享二進制文件的nuget包跨項目。 Nuget Package恢復功能允許將包作爲構建的一部分來獲取。
+0

我可以理解使用特定於語言的工具來管理冗餘的好處(比如使用'npm'作爲node.js),但是當您的某個項目依賴於另一個項目時,您會做什麼?例如,我在PHP中使用了一個身份驗證腳本,這是我在**幾個**項目中使用的。這個身份驗證腳本本身可能是一個項目,但它也是許多其他項目的依賴項。 – stevendesu 2013-03-09 16:22:34

+0

我不太熟悉php來評論,但由於它是像ruby這樣的解釋性語言,所以我可以畫出相似之處。這個問題在php http://stackoverflow.com/a/12244957/326543中討論Rubygems像功能。這可以成爲你的解決方案嗎? – 2013-03-09 16:27:54

+0

我從來沒有聽說過作曲家,並通過它聽起來像(與薩蒂斯安裝)的介紹閱讀它可以做我所需要的。聽起來像我在我之前有一個很大的學習曲線=)我會留下這個開放一段時間,看看是否有人使用目錄結構和git的一個輝煌的解決方案,但如果沒有什麼出現,那麼你一定會得到綠色的檢查。 – stevendesu 2013-03-11 03:13:57

0

你已經提出了一個普遍的問題,但也特別詢問了幾個實例。我將傾向於更一般化。簡而言之:這是一個構建系統問題,而不是版本控制系統問題。

對於Java,您可以使用幾種不同的依賴項管理/解析工具。構建系統應該瞭解如何在構建時間處獲取這些依賴項並使其可用。但是,它們是暫時的 - 你不會檢查它們是否受版本控制。此外,Maven - 例如 - 使用一個/target文件夾,這兩個文件夾都包含您的輸出(例如output.zip - 我也建議這樣做,因爲它可以使清理輸出變得更容易。如果有多個輸出文件會怎麼樣?變體呢?等等。)以及其他項目,如靜態分析輸出 - 它也使用外部目錄來本地緩存依賴關係,但這可能是短暫的,它不會在意。底線:它沒有堅持到版本控制。據我所知,這在C++中並不那麼容易。 CMake seems to support建設外部項目。我最近纔開始玩這個,看看有什麼可能,所以我不想誤導你說「它可以很容易地完成」,但有理由認爲它可以完成,問題是隻有你需要投入多少工作。因此,無論您是否調用文件夾/libs,都應該將構建對待依賴關係設置爲傳遞對象(然後使用傳遞依賴關係來祝好運)。

+0

爲了確保我的理解,您的建議不是版本控制依賴性,而是將它們放在外部文件中並通過一些智能構建腳本包含在內?如果是這樣,那麼有人會在github上(或者類似的git主機)分叉我的項目能夠訪問這些依賴關係嗎? – stevendesu 2013-03-09 02:19:15

+0

這就是普通答案可能不足的地方 - 因此,使用Java作爲示例,您可以將工件發佈到集中式存儲庫供任何人使用。他們通常將它們緩存在本地機器上,但這確實是一種優化。我對C++沒有足夠的瞭解來回答這個問題,但是我有同事告訴我,在Linux中這並不是什麼大問題,因爲分發趨勢是有一個包管理系統。 Windows是另一回事。 – 2013-03-11 15:46:02

2

雖然統一工作流程很不錯,但您必須尊重您試圖馴服的野獸。對於不同的項目你應該有不同的目錄結構。從3D動畫項目到PHP項目到C++項目,以及其中的任何地方,我發現擠壓它們以符合相同的工作流程只會增加長期工作和頭痛。大多數IDE都有一個很好的「新項目」結構,它是其他開發人員直接瞭解和理解的結構。

至於依賴性問題嘗試實現上層項目的方法: http://git-scm.com/book/en/Git-Tools-Submodules

+0

雖然它並沒有真正回答我的問題,但這是一個很好的答案。絕對是我在與git痛苦戰鬥的最後3天之後可能考慮的事情 – stevendesu 2013-03-11 03:04:38

+0

我想起了一些關於git中的超級項目的東西,可以幫助你。我已經更新了答案。 – Goran 2013-03-12 21:04:05

0

沒有嵌入庫,這是一個安全噩夢! 當您在應用程序中嵌入像libpng,libjpeg或libtiff這樣的圖像格式庫時,因爲您想使用它的圖像格式,所以您可以將應用程序打開到這些庫可能包含的任何安全漏洞,並且用戶沒有簡單的方法知道他們需要更新您的程序來解決安全問題。當您將依賴關係置於應用程序的範圍之外時,程序包管理員知道庫,並且可以在安全漏洞暴露時採取措施。

在您的項目範圍之外留下您依賴的圖書館。如果您親自開發了您在多個項目中使用的庫,請將其放入其自己的存儲庫中,並對其進行單獨發佈。

對於像操作系統(linux/bsd/solaris等)的unix,用戶可以通過軟件包管理器單獨安裝它們,如果您發佈軟件,軟件包管理器將知道您的依賴關係並安裝必要的依賴關係,應用程序,因此不需要手動操作。

對於Windows,使用單獨的捆綁過程將依賴的庫捆綁到便捷安裝程序中,該安裝程序將庫安裝到共享系統目錄而不是程序目錄。

在git中沒有任何技術手段來做你想要的而沒有大量的重複。