GIT: оформление заказа в определенную папку


Ответы:


57

В соответствии с Do a "git export" (например, "svn export")?

Вы можете использовать git checkout-indexдля этого, это команда низкого уровня, если вы хотите экспортировать все, вы можете использовать -a,

git checkout-index -a -f --prefix=/destination/path/

Процитируем страницы руководства:

Последний "/" [в префиксе] важен. Экспортируемое имя буквально начинается с указанной строки.

Если вы хотите экспортировать определенный каталог, есть несколько уловок. Команда принимает только файлы, а не каталоги. Чтобы применить его к каталогам, используйте команду «find» и направьте вывод в git.

find dirname -print0 | git checkout-index --prefix=/path-to/dest/ -f -z --stdin

Также на страницах руководства:

Интуитивность здесь не цель. Повторяемость есть.


К сожалению, это не будет работать из чистого репозитория git, даже с установленным --prefix :-( (проверено с git 1.9.1)
apeiros

1
если вы хотите проверить ветку / фиксацию GIT_WORK_TREE=../path/to/place git checkout
чистого

4
git worktree(см. ниже) imho - это канонический ответ сегодня, и его можно добавить сюда.
geek-merlin

213

Другое решение, которое немного чище - просто укажите другое дерево работы.

Чтобы проверить все, от HEAD (не индекс) до определенного каталога:

git --work-tree=/path/to/outputdir checkout HEAD -- .

Чтобы извлечь подкаталог или файл из HEAD в конкретный каталог:

git --work-tree=/path/to/outputdir checkout HEAD -- subdirname

4
Незначительное примечание - вам действительно нужен абсолютный путь, поскольку расширение тильды оболочки не происходит, то есть --work-tree=/home/thomasg/okcopyвместо --work-tree=~/okcopy(возможно, использование относительного пути, сидя внутри того же дерева git, тоже работает, но в этом случае заключается безумие и git statusвыходы в R'lyehian)
Том Гудфеллоу

10
Он работает должным образом и со старыми коммитами (например, дает SHA вместо HEAD), однако git statusзатем показывает множество модов (предположительно потому, что индекс теперь соответствует другому каталогу, а не нетронутому нормальному рабочему дереву). git resetвернул его в хорошее состояние.
Том Гудфеллоу

2
Здесь же git statusпоказано много модов, и git resetэто не помогает. Пришлось git checkout -f HEADвосстановить состояние репо.
DUzun

11
К вашему сведению: вам нужно создать каталог самостоятельно, иначе вы получите эту ошибку:fatal: This operation must be run in a work tree
timaschew

13
Это катастрофически изменяет индекс основного рабочего дерева, что обычно плохо. Как предлагает @TomGoodfellow, этого git resetдостаточно, чтобы восстановить работоспособность основного рабочего дерева. Чтобы безопасно экспортировать подкаталоги репозитория в любой SHA1, ветвь или тег без изменения основного рабочего дерева, см . Печально известное git archiveрешение Чарльза Бейли . Точно так же, чтобы безопасно проверять несколько веток одновременно, новая git worktree addподкоманда - ваш друг.
Сесил Карри

25

Для одного файла:

git show HEAD:abspath/to/file > file.copy

2
+1 и уточнить «определенную предыдущую фиксацию» (вместо HEAD): это относится к тому, SHA1 IDчто можно легко найти с помощью gitk. Если мне нужно только «извлечь» этот файл во временное место (т.е. не возвращаться), я бы использовал showподкоманду:git show 82e54378856215ef96c5db1ff1160a741b5dcd70:MyProj/proguard/mapping.txt > myproj_mapping.txt
ef2011,

19

Вышеупомянутые решения не сработали для меня, потому что мне нужно было проверить конкретную версию дерева с тегами. cvs exportКстати, вот как это предназначено для использования. git checkout-indexне принимает аргумент тега, поскольку извлекает файлы из индекса. git checkout <tag>изменил бы индекс независимо от рабочего дерева, поэтому мне нужно было бы сбросить исходное дерево. Решение, которое сработало для меня, заключалось в клонировании репозитория. Общий клон работает довольно быстро и не занимает много места. При .gitжелании каталог можно удалить.

git clone --shared --no-checkout <repository> <destination>
cd <destination>
git checkout <tag>
rm -rf .git

Новые версии git должны поддерживать git clone --branch <tag>автоматическую проверку указанного тега:

git clone --shared --branch <tag> <repository> <destination>
rm -rf <destination>/.git

3
git --work-tree=/path/to/outputdir checkout <tag> -- .у вас не сработало?
warvariuc 03

1
Нет, это не так. Фактический файл в исходном рабочем каталоге не изменяется, но поэтапная версия теряется и заменяется версией из тега. Особенно плохо, если поэтапная версия содержала тщательно подобранный набор изменений, которые нужно было зафиксировать. Я не хочу, чтобы команда экспорта касалась моего индекса, точка.
proski

19

Если вы работаете со своей функцией и не хотите возвращаться к мастеру, вы можете запустить:

cd ./myrepo

git worktree add ../myrepo_master master

git worktree remove ../myrepo_master

Он создаст ../myrepo_masterкаталог с masterкоммитами веток, где вы сможете продолжить работу.


1
Лучший ответ - простой, и, в отличие от git --work-tree=/path/to/outputdir checkout HEAD -- .него, ничего не делает с индексом, просто копирует выбранную ветку в указанное место (с добавлением файла .git).
Роджер Дук

И как мне отменить это изменение?
Скотт П.

@ ScottP. Просто удалите myrepo_masterкаталог
itsnikolay

1
отмена этой подкоманды от worktree:git worktree remove ../myrepo_master
Martijn Dashorst

8

Ответ Адриана был «фатальным: эта операция должна выполняться в дереве работы». У нас сработало следующее.

git worktree add <new-dir> --no-checkout --detach
cd <new-dir>
git checkout <some-ref> -- <existing-dir>

Ноты:

  • --no-checkout Не извлекайте ничего в новое рабочее дерево.
  • --detach Не создавайте новую ветку для нового рабочего дерева.
  • <some-ref> работает с любым рефом, например, работает с HEAD~1 .
  • Очистка с помощью git worktree prune.

+1 за комментарии о том, как очистить - все остальные рады испортить текущее репо. только у этого нет побочных эффектов.
Эндрю Хилл

1

Дополнение к ответу @hasen . Чтобы перечислить файлы для оформления заказа , вы можете использовать git ls-filesвместо findlike:

git ls-files -z *.txt | git checkout-index --prefix=/path-to/dest/ -f -z --stdin

Спасибо за правильное использование -z! Приятно, что вы предоставляете сценарий, который не уязвим для определенных видов атак путем инъекций.
Эрике

0

Я определил псевдоним git именно для этого (до того, как нашел этот вопрос).

Это короткая функция bash, которая сохраняет текущий путь, переключается на репозиторий git, выполняет проверку и возвращается с того места, где она была запущена.

git checkдля разработки ~ / my_project_git

Это, например, приведет к извлечению ветки разработки в каталог "~ / my_project_git".

Это код псевдонима внутри ~/.gitconfig:

[alias]
    checkTo = "!f(){ [ -z \"$1\" ] && echo \"Need to specify branch.\" && \
               exit 1; [ -z \"$2\" ] && echo \"Need to specify target\
               dir\" && exit 2; cDir=\"$(pwd)\"; cd \"$2\"; \
               git checkout \"$1\"; cd \"$cDir\"; };f"

0

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

[alias]
    cot = "!TEMP=$(mktemp -d); f() { git worktree prune && git worktree add $TEMP $1 && zsh -c \"cd $TEMP; zsh\";}; f" # checkout branch in temporary directory

Использование:

git cot mybranch

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

Когда вы закончите, удалите каталог и запустите:

git worktree prune

Это также делается автоматически в псевдониме перед добавлением нового рабочего дерева.


0

Используйте, git archive branch-index | tar -x -C your-folder-on-PCчтобы клонировать ветку в другую папку. Думаю, тогда можно скопировать любой нужный вам файл

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