Як витягнути конкретний каталог за допомогою git


193

У мене є проект з git, і я просто хочу клонувати або витягувати певний каталог, як-от myproject / javascript, як це робить субверсія.
внесіть деякі зміни, введіть і знову натисніть.
Це можливо?


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, він вирішує заголовок питання (ви МОЖЕТЕ витягнути лише один dir), але не відповідає тій частині запитання ("внесіть деякі зміни, введіть і знову натисніть").
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
Як вказує Піткос у прийнятій відповіді, ця відповідь також завантажить цілий віддалений сховище на вашу локальну машину. Відповідь шингари є найбільш зрозумілою - немає можливості віддалено витягнути частину репо. Однак для тих, хто не заперечує пропускну здатність вагового вибору і зацікавлений у створенні робочої копії частини локального кешу, то прийнята відповідь показує, як це зробити. Але я просто хочу, щоб було зрозуміло, що вся історія репо (у стисненому форматі) повинна бути завантажена на вашу машину.
Гейб Халсмер

39

Шукаючи відповіді, не знаходячи, не відмовляючись, намагаючись знову і так далі, я нарешті знайшов рішення для цього в іншій темі 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

Щоб робити те, що хоче ОП (працюйте лише над одним dir), просто додайте цей один dir .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 Вибачте, але IMHO це має сенс. Реалізація не повинна обмежувати використання. Git знає, що це каталоги (принаймні, під час створення локальної робочої копії), тому немає причин, щоб він не міг виконати якусь подібну операцію на сервері, а просто надіслати відповідний вихід. Зрозуміло, це наразі не реалізовано, але це пов’язано з відсутністю функції, а не з принциповою неможливістю. Особисто я думаю, що це досить важлива особливість, але ей, це одна з причин, коли я уникаю git, коли це можливо.
Основні

10

Можливо, ця команда може бути корисною:

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

"Et voilà"


2
При цьому завантажується специфічний каталог файлів для архівації, це не тягне копію, яку ви можете змінювати та відновлювати.
leetNightshade

Дуже круто. Можливо, це не прийнятно як рішення для ОП, але це насправді те, про що я пішов, оскільки мені просто потрібно шукати вміст великої папки в ще більшому репо, я точно не хочу отримувати, і мені не потрібно змінювати / поштовх.
Олівер

7

Якщо ви хочете отримати останні зміни в каталозі, не вводячи його, ви можете зробити:

$ git -C <Path to directory> pull

4

git clone --filter від Git 2.19

Цей параметр фактично пропустить отримання серверу непотрібних об'єктів.

Я написав докладну відповідь, що пояснює поточний стан підтримки на: Як я клоную підкаталог лише у сховищі Git?

Цілком ймовірно, що все, що реалізується git cloneв цій галузі, також матиме git pullаналоги.


1

Спробував і випробував це працює!

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

Іноді просто хочеться переглянути попередні копії файлів без ригмароли проходження через diff.

У такому випадку так само просто зробити клон сховища та перевірити конкретний комітет, який вас цікавить, і подивитися підкаталог у цьому клонованому сховищі. Оскільки все локально, ви можете просто видалити цей клон, коли закінчите.


-1

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

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

Мене цікавили лише файли js Microsoft Dynamics на шляху

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/*

нарешті зробити a

git pull origin master
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.