1716

ルートに 2 つのサブディレクトリがある Git リポジトリがあります。

/finisht
/static

これがSVNにあるとき、次のよう/finishtに、ある場所で/staticチェックアウトされ、他の場所でチェックアウトされました。

svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static

Gitでこれを行う方法はありますか?

4

24 に答える 24

1682

あなたがやろうとしていることはsparse checkoutと呼ばれ、その機能は git 1.7.0 (2012 年 2 月) で追加されました。スパースクローンを実行する手順は次のとおりです。

mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>

これにより、リモートで空のリポジトリが作成され、すべてのオブジェクトがフェッチされますが、チェックアウトされません。次に、次のようにします。

git config core.sparseCheckout true

ここで、実際にチェックアウトするファイル/フォルダーを定義する必要があります。これは、それらを にリストすることによって行われます.git/info/sparse-checkout

echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout

最後になりましたが、空のレポをリモートからの状態で更新します。

git pull origin master

some/dirこれで、ファイル システムに対してファイルが「チェックアウト」されanother/sub/tree(これらのパスはまだ)、他のパスは存在しません。

拡張チュートリアルを見たいと思うかもしれませんし、おそらくsparse checkoutread-treeの公式ドキュメントを読むべきです。

関数として:

function git_sparse_clone() (
  rurl="$1" localdir="$2" && shift 2

  mkdir -p "$localdir"
  cd "$localdir"

  git init
  git remote add -f origin "$rurl"

  git config core.sparseCheckout true

  # Loops over remaining args
  for i; do
    echo "$i" >> .git/info/sparse-checkout
  done

  git pull origin master
)

使用法:

git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"

これにより、サーバーからリポジトリ全体がダウンロードされることに注意してください。チェックアウトのサイズのみが縮小されます。現時点では、1 つのディレクトリのみを複製することはできません。ただし、リポジトリの履歴が必要ない場合は、浅いクローンを作成することで、少なくとも帯域幅を節約できます。浅いクローンとスパース チェックアウトを組み合わせる方法については、以下の udondan の回答を参照してください。


git 2.25.0 (2020 年 1 月) の時点で、実験的な sparse-checkoutコマンドが git に追加されました。

git sparse-checkout init
# same as: 
# git config core.sparseCheckout true

git sparse-checkout set "A/B"
# same as:
# echo "A/B" >> .git/info/sparse-checkout

git sparse-checkout list
# same as:
# cat .git/info/sparse-checkout
于 2012-12-06T07:37:21.387 に答える
742

編集:Git 2.19の時点で、この回答に見られるように、これは最終的に可能になりました。

その答えに賛成することを検討してください。

注:Git 2.19では、クライアント側のサポートのみが実装されていますが、サーバー側のサポートはまだ欠落しているため、ローカルリポジトリのクローンを作成する場合にのみ機能します。また、GitHubなどの大規模なGitホスティング業者は、実際にはGitサーバーを使用せず、独自の実装を使用するため、Gitサーバーにサポートが表示されても、Gitホスティング事業者で機能することを自動的に意味するわけではありません。(OTOH、Gitサーバーを使用しないため、Gitサーバーに表示される前に、独自の実装でより高速に実装できます。)


いいえ、それはGitでは不可能です。

このようなものをGitに実装することはかなりの努力であり、クライアント側リポジトリの整合性が保証されなくなることを意味します。興味がある場合は、gitメーリングリストで「スパースクローン」と「スパースフェッチ」に関するディスカッションを検索してください。

一般に、Gitコミュニティのコンセンサスは、常に独立してチェックアウトされる複数のディレクトリがある場合、これらは実際には2つの異なるプロジェクトであり、2つの異なるリポジトリに存在する必要があるというものです。Gitサブモジュールを使用してそれらを接着して戻すことができます。

于 2009-03-01T18:00:23.660 に答える
189

github からファイル/フォルダーをダウンロードしたいだけの他のユーザーの場合は、次のようにします。

svn export <repo>/trunk/<folder>

例えば

svn export https://github.com/lodash/lodash.com/trunk/docs

(はい、それはここの svn です。どうやら 2016 年には、いくつかの github ファイルを単純にダウンロードするためにまだ svn が必要です)

礼儀: GitHub リポジトリから 1 つのフォルダーまたはディレクトリをダウンロードする

重要- 必ず github URL を更新し、/tree/master/'/trunk/' に置き換えてください。

bash スクリプトとして:

git-download(){
    folder=${@/tree\/master/trunk}
    folder=${folder/blob\/master/trunk}
    svn export $folder
}

注: このメソッドはフォルダーをダウンロードしますが、クローン/チェックアウトは行いません。変更をリポジトリにプッシュすることはできません。一方、これにより、スパース チェックアウトまたはシャロー チェックアウトと比較してダウンロードが小さくなります。

于 2016-09-04T13:02:24.217 に答える
77

クローン元のリポジトリと対話する予定がない場合は、完全に実行しgit cloneてリポジトリを次のように書き換えることができます。

git filter-branch --subdirectory-filter <subdirectory>

このようにして、少なくとも履歴は保持されます。

于 2009-03-01T21:17:53.623 に答える
68

これははるかに簡単に見えます:

git archive --remote=<repo_url> <branch> <path> | tar xvf -
于 2014-09-10T17:03:33.467 に答える
63

Git 1.7.0 には「スパース チェックアウト」があります。git config manpageの「core.sparseCheckout」 、 git read-tree manpageの「Sparse checkout」 、 git update-index manpageの「Skip-worktree bit」を参照してください。

インターフェイスは SVN ほど便利ではありません (たとえば、最初のクローン時にスパース チェックアウトを作成する方法はありません) が、より単純なインターフェイスを構築できる基本機能が利用できるようになりました。

于 2010-05-18T21:15:04.130 に答える
40

Git だけでサブディレクトリを複製することはできませんが、以下にいくつかの回避策を示します。

フィルター ブランチ

プロジェクトのルートであったかのようにリポジトリを書き換え、trunk/public_html/( を使用して) 他のすべての履歴を破棄しfilter-branch、すでにチェックアウトされているブランチを試してください。

git filter-branch --subdirectory-filter trunk/public_html -- --all

注: は--フィルター ブランチ オプションをリビジョン オプションから分離し、--allすべてのブランチとタグを書き換えます。元のコミット時間やマージ情報を含むすべての情報は保持されます。.git/info/graftsこのコマンドは名前空間のファイルと参照を尊重refs/replace/するため、接ぎ木または置換がrefs定義されている場合、このコマンドを実行するとそれらが永続化されます。

警告!書き換えられた履歴は、すべてのオブジェクトのオブジェクト名が異なり、元の分岐に収束しません。元のブランチの上に書き換えられたブランチを簡単にプッシュして配布することはできません。完全な意味がわからない場合は、このコマンドを使用しないでください。問題を解決するために単純な単一のコミットで十分な場合は、とにかく使用しないでください。


まばらなチェックアウト

作業ディレクトリにまばらにデータを入力するスパース チェックアウトアプローチを使用した簡単な手順を次に示します。これにより、作業ディレクトリ内のどのフォルダーまたはファイルをチェックアウトする価値があるかを Git に伝えることができます。

  1. いつものようにレポジトリをクローンします (--no-checkoutオプションです):

    git clone --no-checkout git@foo/bar.git
    cd bar
    

    リポジトリがすでに複製されている場合は、この手順をスキップできます。

    ヒント: 大規模なリポジトリの場合は、浅いクローン( --depth 1) を使用して、最新のリビジョンのみまたは/および--single-branchのみをチェックアウトすることを検討してください。

  2. sparseCheckoutオプションを有効にする:

    git config core.sparseCheckout true
    
  3. スパース チェックアウト用のフォルダーを指定します (最後にスペースを入れません) :

    echo "trunk/public_html/*"> .git/info/sparse-checkout
    

    または編集します.git/info/sparse-checkout

  4. ブランチをチェックアウトします (例master):

    git checkout master
    

これで、現在のディレクトリ内のフォルダーが選択されているはずです。

代わりにディレクトリまたはフィルタリング ブランチのレベルが多すぎる場合は、シンボリック リンクを検討してください。


于 2016-03-22T23:06:20.680 に答える
2

実際にディレクトリの最新リビジョン ファイルにのみ関心がある場合は、Github を使用すると、履歴を含まない Zip ファイルとしてリポジトリをダウンロードできます。そのため、ダウンロードは非常に高速です。

于 2020-01-25T14:07:29.297 に答える
2

ここには多くの素晴らしい回答がありましたが、Windows Sever 2016 では、ディレクトリ名を引用符で囲むとうまくいかなかったことを付け加えたいと思います。ファイルは単にダウンロードされていませんでした。

それ以外の

"mydir/myfolder"

私は使用しなければならなかった

mydir/myfolder

また、単にすべてのサブディレクトリをダウンロードしたい場合は、単に使用します

git sparse-checkout set *
于 2021-04-08T13:15:33.360 に答える
1

あなたはまだ使用することができますsvn

svn export https://admin@domain.com/home/admin/repos/finisht/static static --force

サブディレクトリ" git clone" に移動し、次にgit pullこのサブディレクトリ " " に移動します。

(コミット&プッシュを意図したものではありません。)

于 2021-09-27T08:56:50.367 に答える