2010-02-25 93 views
64

在Git 1.7.0中使用新的sparse checkout feature,是否可以像SVN那樣獲取子目錄的內容?我發現this example,但它保留了完整的目錄結構。想象一下,我只是想要'perl'目錄的內容,而沒有名爲'perl'的實際目錄。Git 1.7.0中的稀疏結賬?

- 編輯 -

例子:

我的Git倉庫包含以下路徑

repo/.git/ 
repo/perl/ 
repo/perl/script1.pl 
repo/perl/script2.pl 
repo/images/ 
repo/images/image1.jpg 
repo/images/image2.jpg 
repo/doc/ 
repo/doc/readme.txt 
repo/doc/help.txt 

我要的是能夠從上面的資料庫這個佈局產生:

repo/.git/ 
repo/script1.pl 
repo/script2.pl 

然而wi th目前的稀疏結帳功能,它似乎只有可能得到

repo/.git/ 
repo/perl/script1.pl 
repo/perl/script2.pl 

這不是我想要的。

+4

他們終於實現了!涼! – 2010-02-25 18:42:25

+0

爲什麼?問題是什麼?爲什麼你想要在存儲庫中有不同的目錄結構,並在本地不同?乍一看沒什麼意義。 – 2010-03-09 09:02:16

+2

@Jiri:我有一個帶有actionscript(客戶端)和PHP(服務器端)代碼的web應用程序。這些文件密切相關,所以我想把它們放在一個單獨的repo /分支中。不過,我不希望服務器上的動作源文件,只有PHP文件。 – davr 2010-03-09 21:02:40

回答

23

您仍然需要克隆整個存儲庫,它將包含所有文件。您可以使用--depth標誌僅檢索有限的歷史記錄。

一旦存儲庫被克隆,讀取樹技巧就會將存儲庫的「視圖」限制爲僅存在於.git/info/sparse-checkout文件中的那些文件或目錄。

我寫了一個快速腳本來幫助管理稀疏,因爲在那一刻實在是有點不友好:如果將該腳本保存爲git-sparse.sh到報告的路徑通過調用git --exec-path

#!/bin/sh 
echo > .git/info/sparse-checkout 
for i in "[email protected]" 
do 
    echo "$i" >> .git/info/sparse-checkout 
done 
git read-tree -m -u HEAD 

,那麼你就可以運行git sparse foo/ bar/只能「檢出」foo和bar目錄,或者git sparse '*'將所有內容都恢復回來。

+0

感謝您的幫助,但這似乎並沒有回答我的問題。查看我最新的問題以獲得澄清。 – davr 2010-02-26 22:59:45

+3

是的,稀疏只是一種過濾實際樹的方式,它不能移動文件。所以你不能做你想做的事...... – richq 2010-02-27 11:07:22

16

簡短的回答是否定的。 Git將所有文件視爲一個單元。

我推薦的是你把你的資料庫分解成邏輯塊。一個單獨的perl,圖像和文檔。如果您還需要維持卓越的回購風格,您可以創建一個由Submodules組成的回購。

5

現在,沒有陷入細節,你爲什麼要這樣做,你的問題可以(可能)通過符號鏈接/快捷方式輕鬆解決。

回答這個問題 - 沒有,並有一個有意義的理由。即使是「稀疏結賬」,也可以下載整個回購協議的歷史。爲了澄清爲什麼這是必要的 - 否則跟蹤重命名的文件將是一個痛苦的...頸部。假設您將文件/repo_root/asd/file1.cpp移動到/repo_root/fgh/file1.cpp - 現在如果您只下載了/repo_root/fgh增量,您將無法瞭解file1.cpp。所以這意味着你必須下載所有的增量。但是,你有一個完整的存儲庫;不僅僅是它的一個文件夾,因此只有/rero_root/fgh文件夾本身不是回購站。這在結帳時可能聽起來不重要,但是當您提交時,git可能不夠用,無法正常工作。

解決方法:如果你真的想,你可以創建這樣的方式調用git的結帳的腳本(對於sh shell中,批次窗口不應該很難產生):

!/bin/sh 
curDir=`pwd` 
cd $2 
git-checkout $1 
cp -R $3/* $4 
cd $curDir 

這裏的第一個參數是要簽出的分支,第二個是當前存在回購目錄的文件夾,第三個是要真正使用的子目錄,第四個是要將其複製到的位置。

警告:我的shell技能幾乎不存在,所以在測試後使用它。重新創建這個腳本的反向並不難,它會複製回來的東西,這樣它就可以致力於回購。

+0

回購的全部歷史不是問題,它不是一個大回購,而且我們有充足的磁盤空間。我想我們的特殊用例並不常見,所以git開發者從未想過要添加它。這是SVN爲我們更好地工作的很少的東西之一(git可以更好地完成99個其他的事情,這就是爲什麼我們切換,但仍然) – davr 2011-08-07 06:01:54

+0

窗口上的符號鏈接是一個噩夢 - 這是不容易處理的。 – 2013-03-20 17:50:55

+0

lulz在窗戶的傢伙 – nottinhill 2015-03-18 13:39:19

3

git filter-branch --subdirectory-filter是您需要的,請參閱Detach (move) subdirectory into separate Git repository

這是一個小bash腳本來做到這一點。

這將首先製作原始repo的工作副本,然後使用子目錄篩選器篩選分支以獲得所需內容。

#!/bin/bash 
# 
# git-subdir.sh 
# 
git clone --no-hardlinks $1 $2 

cd $2 

git filter-branch --subdirectory-filter $2 --prune-empty --tag-name-filter cat HEAD -- --all 

git reset --hard 

git remote rm origin 

refbak=$(git for-each-ref --format="%(refname)" refs/original/) 

if [ -n "$refbak" ];then 
    echo -n $refbak | xargs -n 1 git update-ref -d 
fi 

git reflog expire --expire=now --all 

git repack -ad 

git gc --aggressive --prune=now 

用於示例中的問題git-subdir.sh repo perl會起作用。

0

看來你要做的是重命名目錄樹,以便你的文件最終在不同的地方。在我看來,你要做的是在兩個計數器上爲代碼/項目管理提供一個反模板:模塊分類(Java節點下的java位,perl節點下的perl)以及在不同位置具有文件的項目從開發人員可視化他們的地方。由於git維護目錄內容的散列以查看更改的內容,因此這也會破壞git。

Daemeon Reiydelle