web-dev-qa-db-ja.com

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

これは私が望むものではありません。

67
davr

リポジトリ全体のクローンを作成する必要がありますが、これにはすべてのファイルが含まれます。 --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として保存すると、git sparse foo/ bar/を実行してfooおよびbarディレクトリのみを「チェックアウト」するか、git sparse '*'を実行できます。すべてを取り戻す。

26
richq

短い答えはノーです。 Gitはすべてのファイルを単一のユニットとして認識します。

リポジトリを論理的なチャンクに分解することをお勧めします。 Perl、画像、およびドキュメント用の別の1つ。 uberリポジトリスタイルを維持する必要がある場合は、 Submodules で構成されるリポジトリを作成できます。

16
John K

richqの答えは近かったが、一歩逃した。スパースチェックアウトを明示的に有効にする必要があります。

git config core.sparsecheckout true

このブログ投稿には、明確に概説されているすべての手順が含まれています。

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

7
PhilYoussef

なぜこれをしたいのかを詳しく説明することなく、シンボリックリンク/ショートカットで問題を(おそらく)簡単に解決できます。

質問に答えるために-いいえ、そして意味のある理由で。リポジトリの全履歴は、「スパースチェックアウト」でもダウンロードされます。なぜこれが必要なのかを明確にするために-そうでなければ、名前を変更したファイルを追跡することは...首の痛みになるでしょう。ファイルを移動すると想像してください/repo_root/asd/file1.cppから/repo_root/fgh/file1.cpp-ダウンロードした場合のみ/repo_root/fghデルタ、file1.cppについては知りません。そのため、すべてのデルタをダウンロードする必要があります。ただし、完全なリポジトリがあります。単なるフォルダカットではなく、したがって/rero_root/fghフォルダーはリポジトリそのものではありません。チェックアウトするとき、これは重要ではないように聞こえるかもしれませんが、コミットするとき、gitはうまく動作するのに十分な知識がないかもしれません。

回避策:本当にしたい場合は、次のような方法でgit-checkoutを呼び出すスクリプトを作成できます(shシェルの場合、Windowsのバッチを作成するのは難しくありません)。

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

ここで、最初の引数はチェックアウトへのブランチ、2番目-リポジトリが現在存在するフォルダー、3番目-実際に使用するサブディレクトリ、4番目-コピー先の場所です。

警告:シェルスキルはほとんど存在しないため、テスト後に使用してください。このスクリプトの逆を再作成することは難しくありません。これは、ものをコピーして、リポジトリにコミットできるようにします。

5
Ger4ish

git filter-branch --subdirectory-filterは必要なものです。 サブディレクトリを個別のGitリポジトリに分離(移動) を参照してください。

これを行うための小さなbashスクリプトを次に示します。

これにより、最初に元のリポジトリの作業用コピーが作成され、次にサブディレクトリfilterを使用してブランチをフィルター処理し、必要なものを取得します。

#!/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動作します。

3
weynhamz

あなたは三つ編みを試すことができます-それはパスに一致させながらリモートを追跡します。 https://github.com/evilchelu/braid/wiki

2
Antoine Toulme

あなたがしようとしているのは、ファイルが別の場所に配置されるようにディレクトリツリーの名前を変更することです。あなたがやろうとしていることは、2つの点でコード/プロジェクト管理のためのアンチテンプレートであるように見えます:モジュールの分類(Javaノード、Perlノードの下のPerl)の下のJavaビット)、開発者が視覚化する場所とは異なる場所にファイルがあるプロジェクトを持つgitは、ディレクトリの内容のハッシュを保持して変更内容を確認するため、git自体も破損します。

大名レイデル

0
Daemeon