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

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


person bluefoot    schedule 11.03.2010    source источник
comment
вас может заинтересовать разреженная проверка (даже если вам все равно нужно получить все): см. stackoverflow.com/questions/2416815/   -  person VonC    schedule 11.03.2010


Ответы (10)


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

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

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

person vergueishon    schedule 29.10.2010
comment
Только что понял, что неправильно понял вопрос. Вместо этого мой ответ касается того, как проверить один файл, который затем можно изменить и зафиксировать. - person vergueishon; 04.02.2011
comment
Вы обратились к названию вопроса, что достаточно хорошо. Это просто спасло меня, так что, насколько мне известно, это правильный ответ, тем более, что это был лучший результат в Google по этой проблеме. - person Morgon; 01.11.2011
comment
Тем не менее, это все еще получает все репо. Для проекта размером 2 ГБ это не сэкономит много времени. - person Pithikos; 24.10.2014
comment
Для тех, кто читает эти комментарии и не знает, как это не отвечает на вопрос, это решение дает вам копию только этой одной папки, но это не рабочая копия, то есть вы не можете изменять и повторно -совершить. Итак, как сказал @Morgon, он касается заголовка вопроса (вы МОЖЕТЕ вытащить только один каталог), но не отвечает на основной вопрос (внесите некоторые изменения, зафиксируйте и снова отправьте). - person msb; 10.05.2017
comment
Однако @StanHolodnak -- не требуется. Он заставляет биты после него интерпретироваться как путь. Итак, да, если у вас есть файл с именем --help, который вы хотите извлечь, потребуется префикс с этими дефисами: git checkout HEAD -- --help - person Tim Visée; 01.12.2017

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

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory
person scottalan    schedule 04.02.2016
comment
это работает, если вы хотите использовать только удаленную версию файла для замены локального файла, я думаю - person John; 16.01.2018
comment
это также вытащить папку, как не загружать папку, а только вещи внутри папки? - person Al Kasih; 18.07.2018
comment
Нет необходимости в командах fetch или checkout, мы можем просто сделать запрос на извлечение после команды remote add, чтобы получить всю основную ветку. - person Iqra.; 15.11.2018
comment
Как указывает Питкос в принятом ответе, этот ответ также загрузит ВЕСЬ удаленный репозиторий на ваш локальный компьютер. ответ шингары самый ясный - нет возможности удаленно вытащить часть репо. Однако для тех, кто не возражает против пропускной способности ВСЕГО извлечения и заинтересован в создании рабочей копии части локального кеша, принятый ответ покажет вам, как это сделать. Но я просто хочу прояснить, что вся история репо (в сжатом формате) должна быть загружена на вашу машину. - person Gabe Halsmer; 17.10.2019

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

Как git-pull все папки, кроме одной

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

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 !

person msb    schedule 10.05.2017
comment
Я публикую это здесь в основном потому, что всякий раз, когда я пытаюсь найти в Google, как это сделать, это лучший результат, а эта тема даже близко не отображается. :( Я плохо себя чувствую при копировании, но я считаю, что это НАСТОЛЬКО лучшие практики? - person msb; 10.05.2017
comment
Это единственное чистое решение. Пробовал ответы выше. После того, как я проверил свою ветку с другими ответами, я не мог вытащить, и у меня было несколько новых файлов, которые нужно было зафиксировать. С этим решением все выглядит правильно. Но ПРИМЕЧАНИЕ. Независимо от ветки, которая была извлечена, git будет думать, что вы находитесь в master. Просто убедитесь, что вы делаете git branch --set-upstream-to=origin/<branch> правильно. - person seebiscuit; 25.06.2018

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

$ git -C <Path to directory> pull
person feralamillo    schedule 19.08.2019

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

person shingara    schedule 11.03.2010
comment
Несмотря на то, что вам нужно выбрать все, будет ли в этом случае интересно использовать разреженное рабочее дерево проверки? См. stackoverflow.com/questions/2416815/ - person VonC; 11.03.2010
comment
Просто чтобы добавить к этому, причина, по которой вы не можете вытащить только каталог, заключается в том, что git использует семантическое отслеживание данных, а не семантическое отслеживание файлов, поэтому вы можете легко перемещать код (или другие данные) в файлы и из них, не сообщая источнику система отслеживания (пока вы, конечно, не обновитесь). Из-за этого код также может беспрепятственно перемещаться в каталоги и из них, поэтому захват только одного каталога не имеет большого смысла. Надеюсь это поможет. - person OmnipotentEntity; 29.10.2010
comment
@OmnipotentEntity Извините, но ИМХО это действительно имеет смысл. Реализация не должна ограничивать использование. Git знает, что такое каталоги (по крайней мере, при создании локальной рабочей копии), поэтому нет никаких причин, по которым он не может выполнить аналогичную операцию на сервере и просто отправить соответствующий вывод. Конечно, в настоящее время это не реализовано, но это связано с отсутствием функции, а не с принципиальной невозможностью. Лично я думаю, что это довольно важная функция, но, эй, это одна из причин, по которой я избегаю git, когда это возможно. - person Basic; 24.02.2015

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

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

"И вуаля"

person fabrice belle    schedule 05.01.2012
comment
Это загружает определенный каталог файла для целей архивирования, это не извлекает копию, которую вы можете изменить и отправить обратно. - person leetNightshade; 02.02.2017
comment
Очень круто. Вероятно, это неприемлемо в качестве решения для OP, но на самом деле это то, что я искал, поскольку мне просто нужно искать содержимое большой папки в еще большем репо, которое я определенно не хочу извлекать, и я не нужно изменять/нажимать. - person Oliver; 01.04.2020

git clone --filter из git 2.19 теперь работает на GitHub (проверено 18 сентября 2020 г., git 2.25.1)

Я не уверен насчет pull/fetch, но, по крайней мере, для первоначального клона эта опция была добавлена ​​вместе с обновлением удаленного протокола, и она действительно предотвращает загрузку объектов с сервера.

Например, чтобы клонировать только объекты, необходимые для d1 этого репозитория: https://github.com/cirosantilli/test-git-partial-clone Я могу:

git clone \
  --depth 1 \
  --filter=blob:none \
  --no-checkout \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git checkout master -- d1

Я рассмотрел это более подробно по адресу: Git: как клонировать подкаталог только репозитория Git?

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

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 27.02.2019

Проверено и проверено, это работает!

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>

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

person Nnaik    schedule 28.01.2020

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

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

person Abizern    schedule 11.03.2010

Для всей этой борьбы с теоретическими путями к файлам и примерами, как я, вот реальный пример: 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

is

Sdk.Soap.js/*

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

git pull origin master
person D M    schedule 25.03.2020