Как вытащить конкретный каталог с помощью Git


193

У меня есть проект с git, и я просто хочу клонировать или извлечь конкретный каталог, как myproject / javascript, как это делает Subversion.
внести некоторые изменения, зафиксировать и отодвинуть снова.
Это возможно?


3
Вас может заинтересовать редкая проверка (даже если вам по-прежнему нужно извлекать все): см. stackoverflow.com/questions/2416815/…
VonC

Ответы:


205
  1. CD в ​​верхней части вашей копии репо
  2. git fetch
  3. git checkout HEAD path/to/your/dir/or/file

    • Где " path/..." в (3) начинается с каталога чуть ниже корня репо, содержащего ваш " .../file"

    • Обратите внимание, что вместо «HEAD» можно использовать хеш-код конкретного коммита, и тогда вы получите ревизию (файл) или ревизии (dir), специфичные для этого коммита.


1
Просто понял, что я неправильно понял вопрос. Вместо этого в моем ответе рассматривается, как оформить заказ на один файл, который затем можно изменить и зафиксировать.
vergueishon

Вы обратились к названию вопроса, и это достаточно хорошо. Это только спасло меня, так что, насколько я понимаю, это правильный ответ - тем более, что это был главный хит в Google для этой проблемы.
Моргон

21
Это все еще получает весь репо, хотя. Для проекта размером 2 ГБ это не экономит много времени ..
Pithikos

5
Для тех, кто читает эти комментарии и не знает, как это не отвечает на вопрос, это решение дает вам копию только одной этой папки, но это не рабочая копия, то есть вы не можете изменять и повторно возьмут на . Таким образом, как сказал @Morgon, он обращается к названию вопроса (вы МОЖЕТЕ вытащить только один каталог), но не отвечает по существу вопроса («внесите некоторые изменения, подтвердите и отодвиньте снова»).
MSB

@ StanHolodnak --не требуется, хотя. Это заставляет биты после него интерпретироваться как путь. Итак, да, если у вас есть файл с именем, --helpкоторое вы хотите оформить, потребуется префикс его с этими дефисами:git checkout HEAD -- --help
Tim Visée

105

В пустой директории:

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory

это работает, если вы хотите использовать только удаленную версию файла для замены локального файла, я думаю
Джон

это тянуть папку также, как не выгружать папку, а только вещи внутри папки?
Аль Касих

Нет необходимости в командах fetchили checkoutкомандах, мы можем просто сделать запрос remote addна получение после команды, чтобы получить всю основную ветку.
Икра.

2
Как указывает Pithkos в принятом ответе, этот ответ также загрузит ВСЕ удаленное хранилище на ваш локальный компьютер. Ответ Шингары самый ясный - нет возможности дистанционно вытащить часть репо. Однако для тех, кто не возражает против пропускной способности всей выборки и заинтересован в создании рабочей копии части локального кэша, тогда принятый ответ покажет вам, как это сделать. Но я просто хочу прояснить, что вся история репо (в сжатом формате) должна быть загружена на ваш компьютер.
Гейб Халсмер

39

После долгих поисков ответа, не найдя, не сдаваясь, пытаясь снова и так далее, я наконец-то нашел решение этой проблемы в другой SO-теме:

Как гит-тянуть все кроме одной папки

Чтобы скопировать и вставить то, что есть:

git init
git remote add -f origin <url>
git config core.sparsecheckout true
echo <dir1>/ >> .git/info/sparse-checkout
echo <dir2>/ >> .git/info/sparse-checkout
echo <dir3>/ >> .git/info/sparse-checkout
git pull origin master

Чтобы сделать то, что хочет OP (работать только с одним каталогом), просто добавьте этот каталог .git/info/sparse-checkout, выполняя шаги выше.

Большое спасибо @cforbish!


2
Я публикую это здесь в основном потому, что всякий раз, когда я пытаюсь Google, как это сделать, это лучший результат, и эта тема даже близко не отображается. :( Я чувствую себя плохо копировать-наклеивать, но я считаю , что это ТАК лучшие практики?
MSB

1
Это единственное чистое решение. Пробовал ответы выше. После того, как я проверил свою ветку с другими ответами, я не мог тянуть, и у меня было несколько новых файлов, которые нужно было зафиксировать. С этим решением все выглядит правильно. Но ПРИМЕЧАНИЕ: независимо от того, какая ветка была проверена, git будет думать, что вы в master. Просто убедитесь, что вы делаете, git branch --set-upstream-to=origin/<branch>чтобы тянуть правильно
Бисквит

12

Это невозможно. Вам нужно вытащить все хранилище или ничего.


1
Даже если вам нужно получить все, будет ли в этом случае представлять интерес рабочее дерево редких проверок? См. Stackoverflow.com/questions/2416815/…
VonC

10
Чтобы добавить это, причина, по которой вы не можете извлечь только каталог, заключается в том, что git использует семантическое отслеживание данных, а не семантическое отслеживание файлов, поэтому вы можете легко перемещать код (или другие данные) в файлы и из них, не сообщая об этом источнику. Система отслеживания (пока вы не обновите, конечно.) Из-за этого код также может плавно входить и выходить из каталогов, поэтому захват только одного каталога не имеет особого смысла. Надеюсь это поможет.
OmnipotentEntity

12
@OmnipotentEntity Извините, но ИМХО это имеет смысл. Реализация не должна ограничивать использование. Git знает, что такое каталоги (по крайней мере, при создании локальной рабочей копии), поэтому нет никаких причин, по которым он не может выполнить какую-либо аналогичную операцию на сервере и просто отправить соответствующий вывод. Конечно, это в настоящее время не реализовано, но это связано с отсутствием функции, а не принципиальной невозможностью. Лично я думаю, что это довольно важная особенность, но эй, это одна из причин, по которой я избегаю мерзавцев, когда это возможно.
Основной

10

Может быть, эта команда может быть полезна:

git archive --remote=MyRemoteGitRepo --format=tar BranchName_or_commit  path/to/your/dir/or/file > files.tar

"И вуаля"


2
Это загружает определенный каталог файла для целей архивирования, но не извлекает копию, которую можно изменить, и отодвинет назад.
leetNightshade

Очень круто. Возможно, это неприемлемо в качестве решения для ОП, но на самом деле это то, что я сделал после того, как мне просто нужно искать содержимое большой папки в еще большем репо, которое я определенно не хочу получать, и мне не нужно изменять / От себя.
Оливер

8

Если вы хотите получать последние изменения в каталоге, не вводя его, вы можете сделать:

$ git -C <Path to directory> pull

4

git clone --filter из Git 2.19

Эта опция фактически пропускает выборку ненужных объектов с сервера.

Я написал подробный ответ с объяснением текущего статуса поддержки по адресу: Как мне клонировать только подкаталог репозитория Git?

Весьма вероятно, что все, что будет реализовано git cloneв этой области, также будет иметь git pullаналоги.


2

Пробовал и проверял это работает!

mkdir <directory name> ;  //Same directory name as the one you want to pull
cd <directory name>;
git remote add origin <GIT_URL>;
git checkout -b '<branch name>';
git config core.sparsecheckout true;
echo <directory name>/ >> .git/info/sparse-checkout;
git pull origin <pull branch name>

Надеюсь, это было полезно!


0

Иногда вам просто нужно взглянуть на предыдущие копии файлов без необходимости проходить через разностные файлы.

В таком случае так же легко сделать клон репозитория и получить конкретный коммит, который вас интересует, и взглянуть на подкаталог в этом клонированном репозитории. Поскольку все локально, вы можете просто удалить этот клон, когда закончите.


-1

Для всей этой борьбы с теоретическими путями к файлам и примерами, как я сделал, вот реальный пример: Microsoft предлагает свои документы и примеры на git hub, к сожалению, они собирают все свои файлы примеров для большого количества тем в этом репозитории:

https://github.com/microsoftarchive/msdn-code-gallery-community-s-z

Меня интересовали только файлы Microsoft Dynamics js в пути

msdn-code-gallery-community-s-z/Sdk.Soap.js/

поэтому я сделал следующее

создать

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

файл в папке моих репозиториев на диске

git sparse-checkout init

в этом каталоге с помощью cmd на windows

Содержимое файла

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

является

Sdk.Soap.js/*

наконец сделать

git pull origin master
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.