簡體   English   中英

在Git 1.7.0中稀疏結賬?

[英]Sparse checkout in Git 1.7.0?

使用Git 1.7.0中新的稀疏結賬功能 ,是否可以像在SVN中一樣獲取子目錄的內容? 我找到了這個例子 ,但它保留了完整的目錄結構。 想象一下,我只想要'perl'目錄的內容,而沒有名為'perl'的實際目錄。

- 編輯 -

例:

我的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

然而,使用當前的稀疏結賬功能,似乎只能獲得

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

這不是我想要的。

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

克隆存儲庫后,讀取樹技巧將存儲庫的“視圖”限制為僅包含.git/info/sparse-checkout文件中的文件或目錄。

我寫了一個快速腳本來幫助管理稀疏性,因為此刻它有點不友好:

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

如果將此腳本作為git-sparse.sh保存到通過調用git --exec-path path報告git --exec-path ,則可以運行git sparse foo/ bar/以僅“檢出”foo和bar目錄,或者git sparse '*'讓一切恢復原狀。

最簡潔的答案是不。 Git將所有文件視為一個單元。

我建議您將存儲庫分解為邏輯塊。 perl,images和docs的單獨一個。 如果您還需要維護uber repo樣式,則可以創建由子模塊組成的repo。

richq的答案很接近,但它錯過了一步。 您需要顯式啟用稀疏結帳:

git config core.sparsecheckout是的

此博客文章清楚地概述了所有步驟:

http://blog.quilitz.de/2010/03/checkout-sub-directories-in-git-sparse-checkouts/comment-page-1/#comment-3146

現在沒有詳細說明為什么要這樣做,你的問題可以(可能)通過符號鏈接/快捷方式輕松解決。

回答這個問題 - 不,並且有一個有意義的理由。 即使使用“稀疏結賬”,也可以下載回購的整個歷史記錄。 澄清為什么這是必要的 - 否則跟蹤重命名的文件將是一個痛苦的...脖子。 想象一下你將文件/repo_root/asd/file1.cpp移動到/repo_root/fgh/file1.cpp - 現在如果你只下載了/repo_root/fgh deltas,你就不會知道file1.cpp。 所以這意味着你必須下載所有的增量。 但是你有一個完整的存儲庫; 不僅僅是文件夾的剪切,因此/rero_root/fgh文件夾本身不是repo。 當你結賬時,這可能聽起來不重要,但是當你提交時,git可能不知道工作正常。

解決方法 :如果你真的想要,你可以創建一個以這種方式調用git-checkout的腳本(對於sh shell,不應該很難生成用於windows的批處理):

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

這里第一個參數是checkout的分支,第二個參數是repo當前存在的文件夾,第三個參數是你想要真正使用的子目錄,第四個參數是你想要復制的位置。

警告:我的shell技能幾乎不存在,所以在測試后使用它。 重新創建此腳本的反向並不難,復制回來的東西,以便它可以提交到repo。

git filter-branch --subdirectory-filter是你需要的,請參見Detach(move)子目錄到單獨的Git存儲庫中

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

這將首先制作原始倉庫的工作副本,然后使用子目錄過濾器過濾分支,以獲得您想要的。

#!/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將起作用。

您可以嘗試編織 - 它跟蹤遙控器,同時將它們與路徑匹配。 https://github.com/evilchelu/braid/wiki

您嘗試執行的操作似乎是重命名目錄樹,以便您的文件最終位於不同的位置。 在我看來,你要做的是一個代碼/項目管理的反模板,有兩個方面:模塊分類(java節點下的java位,perl節點下的perl),以及一個包含不同位置文件的項目從開發人員可視化的地方開始。 由於git維護目錄內容的哈希以查看更改內容,因此這也會破壞git。

Daemeon Reiydelle

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM