Загрузите определенный тег с помощью Git

1941

Я пытаюсь выяснить, как я могу загрузить определенный тег репозитория Git - это одна версия позади текущей версии.

На веб-странице git я увидел тег для предыдущей версии, в котором имя объекта было длинным шестнадцатеричным числом.

Но название версии " Tagged release 1.1.5" согласно сайту.

Я попробовал команду как это (с измененными именами):

git clone http://git.abc.net/git/abc.git my_abc

И я кое-что получил - каталог, куча подкаталогов и т. Д.

Если это весь репозиторий, как мне найти нужную версию? Если нет, как я могу скачать эту конкретную версию?

Джек БеНимбл
источник
11
Я работаю на совершенно ином репо, чем на производстве, поэтому мой продукт не знал никаких тегов, когда я пытался использовать git checkout. Решением было использовать «git pull --tags», а затем использовать git checkout.
Предприятие Архитектор
11
"git fetch --tags" тоже работает
Джон Эрк
16
Чтобы избежать клонирования всего хранилища и последующего переключения на тег, вы можете сделать это напрямую clone -b "Tagged release 1.1.5" http://git.abc.net/git/abs.git my_abc. Это будет работать только в том случае, если у вас нет ветки с таким же именем, конечно (в зависимости от вашей методологии это может никогда не произойти).
RedGlyph
3
@ RedGlyph Спасибо, я попробую. Иначе мы можем сделать это. git checkout -b new-branch tag-name, Теперь клонируйте вашу новую ветку. Когда мы захотим, мы можем удалить новую ветку.
Калидасан

Ответы:

2871
$ git clone

даст вам весь репозиторий.

После клонирования вы можете перечислить теги с помощью, $ git tag -lа затем извлечь конкретный тег:

$ git checkout tags/<tag_name>

Более того, извлеките и создайте ветку (в противном случае вы попадете на ветку, названную в честь номера версии тега):

$ git checkout tags/<tag_name> -b <branch_name>
Besen
источник
15
Ага. Git отличается от Subversion в этом отношении. Тег svn в основном копирует файлы в новую папку, так что вы можете svn извлекать определенную группу файлов, тогда как теги git - это просто указатели на определенные ревизии.
DBR
5
Что если у вас есть ветка и тег с одинаковым именем? Если вы просто говорите «git checkout <name>», это говорит: «предупреждение: refname '<name>' неоднозначно. Переключено на ветку« <name> »» - как вы скажете ему вместо этого переключаться на тег?
MatrixFrog
54
при оформлении заказа и, как упоминал Дерек, репо переходит в состояние «отстраненная голова». вместо этого добавьте -bфлаг, указывающий git, чтобы создать новую ветку, и укажите имя ветви:git checkout <tag_name> -b <branch_name>
hellatan
22
@hellatan Вы должны делать это только тогда, когда вы действительно хотите создать ветку, но в большинстве случаев это не так. Работа в состоянии «отстраненная голова» не причинит вам вреда и, скорее всего, именно то, что вы хотите, если вы просто хотите проверить историю мерзавцев.
Machineghost
4
В git-версии 1.8.3.5и новее она --branch <tag ref>должна позволять вам загружать репозиторий, начиная с вашего <tag ref>как репозитория HEAD; в сочетании с --depth 1будет делать поверхностную проверку тегов. См stackoverflow.com/a/21699307/1695680
ThorSummoner
410
git clone --branch my_abc http://git.abc.net/git/abc.git

Клонируем репо и оставим вас на интересующем вас теге.

Документация для 1.8.0 состояний git clone .

--branch может также взять теги и отсоединить HEAD при этом коммите в результирующем репозитории.

Toni
источник
7
Это работает (по крайней мере, сейчас) для тегов, хотя в конечном итоге вы находитесь в отключенном состоянии HEAD.
mxcl
72
К вашему сведению: также укажите, --depth 1чтобы не загружать любые текущие коммиты.
Acumenus
4
Это действительно не работает с тегами. Только ветки. Редактировать: похоже, что только более новые версии Git поддерживает это.
lzap
Мы также можем отредактировать .git / config (или каким-то образом настроить его), чтобы сделать поверхностный клон из двух или более тегов, если это потребуется, обновить неглубокий клон до полного клона и т. Д.
Сэм Уоткинс,
Вы также можете указать нужную ветку вместе с тегом. Например, git clone --branch my_abc http://git.abc.net/git/abc.git -b qualityкачество - это название отрасли, которую мы хотим.
Хазимдикенли
180

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

git clone -b 'v2.0' --single-branch --depth 1 https://github.com/git/git.git

Это кажется самым быстрым способом извлечения кода из удаленного репозитория, если его интересует только самый последний код, а не полный репозиторий. Таким образом, это напоминает команду 'svn co'.

Примечание: согласно руководству по Git , пропуск --depthфлага подразумевает --single-branchпо умолчанию.

--depth

Создайте неглубокий клон с историей, усеченной до указанного количества коммитов. Подразумевает --single-branch, если --no-single-branch не дан для извлечения историй около кончиков всех ветвей. Если вы хотите поверхностно клонировать подмодули, также передайте --shallow-submodules.

Юань Хонг
источник
10
не могу поверить, что это сложно. думаю, никто не ожидает, что их код будет использоваться другими.
Бен
9
@Ben, это на самом деле самое простое решение (требуется одна команда)
Элиран Малка
3
@ Бен, почему это сложно? Это специальный сценарий использования с несколькими функциями, которые вы хотите сделать не так, как по умолчанию. Конечно, вам нужно указать это. Нормальным решением было бы оформить весь репо в распределенном vcs.
erikbwork
9
@ Бен прав. git сложен и был написан ГОДА назад Линусом, и он единственный, кто «по-настоящему» понимает, как это работает. xkcd.com/1597
RyanNerd
11
--depth nподразумевает --single-branch. Вам не нужны оба.
Нияз
98

Я не эксперт по git, но я думаю, что это должно работать:

git clone http://git.abc.net/git/abc.git
cd abc
git checkout my_abc 

ИЛИ

git clone http://git.abc.net/git/abc.git
cd abc
git checkout -b new_branch my_abc

Второй вариант устанавливает новую ветвь на основе тега, что позволяет вам избежать «отсоединенного HEAD». (руководство по git-checkout)

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

Гроссфогель
источник
4
Спасибо. Мне нужно было использовать git checkout -b b1.5.0 v1.5.0при проверке версии в ветке «gh-pages», чтобы успешно перейти на Github Pages. Этот Gist, который я написал, мог бы помочь другим: разветвлять / тегировать / подмодули ... gist.github.com/1064750
Крис Джейкоб
4
Я не думаю, что это абсолютно точно (например, для вставки в терминал), так как вы должны сначала cdвойти в систему, abc/прежде чем сможете оформить отделение
Стивен Лу,
@ StevenLu Вы правы, конечно. Я собирался использовать концепции, а не вырезать и вставить, но это может быть как можно более точным. Я добавил cd.
grossvogel
81

Вы можете использовать архив git для загрузки tar-шара для данного тега или идентификатора коммита:

git archive --format=tar --remote=[hostname]:[path to repo] [tag name] > tagged_version.tar

Вы также можете экспортировать zip-архив тега.

  1. Список тегов:

    git tag
    
    0.0.1
    0.1.0
    
  2. Экспорт тега:

    git archive -o /tmp/my-repo-0.1.0.zip --prefix=my-repo-0.1.0/ 0.1.0
    
  3. Ноты:

    • Вам не нужно указывать формат. Он будет выбран по имени выходного файла.
    • Указание префикса приведет к экспорту вашего кода в каталог (если вы добавите косую черту).
Крис Дж
источник
3
Эта команда не работает с подмодулями см stackoverflow.com/questions/1591387/...
Zitrax
3
Но архив git также удаляет управление версиями, поэтому вы не можете просто сделать еще одну проверку git, чтобы перейти к следующему тегу.
idbrii
9
Да, вы теряете контроль версий, но время, которое git-архив экономит по сравнению с git-клоном, АБСОЛЮТНО НЕВЕРОЯТНО! +1
13
Это так близко к тому, что я хочу, за исключением того, что git archiveспрашивает у меня пароль, когда все, что я хочу сделать, это загрузить из публичного репо. Как я могу заставить его использовать http вместо ssh?
Робру
1
Это терпит неудачу с fatal: Operation not supported by protocol.и Unexpected end of command streamошибок. Кроме того, он также может вернуть fatal: The remote end hung up unexpectedlyошибку.
Acumenus
52

Используйте --single-branchпереключатель (доступен с Git 1.7.10) . Синтаксис:

git clone -b <tag_name> --single-branch <repo_url> [<dest_dir>] 

Например:

git clone -b 'v1.9.5' --single-branch https://github.com/git/git.git git-1.9.5

Преимущество: Git будет получать объекты и (нужно) разрешать дельты только для указанной ветви / тега - при проверке одинакового количества файлов! В зависимости от исходного хранилища это сэкономит вам много места на диске. (Плюс, это будет намного быстрее.)

eyecatchUp
источник
3
Кто бы ни проголосовал против / отрицает этот ответ: Пожалуйста, также оставьте комментарий с кратким объяснением понижения. (Просто спрашиваю, потому что я немного смущен. Потому что, на самом деле, это лучшее решение для данной проблемы. И если вы так не думаете, я хотел бы знать почему.) Большое спасибо.
eyecatchUp
5
Не пытайтесь понять слишком много отрицательных голосов ... ваш ответ очень хороший, их отрицательные оценки, вероятно, необоснованны ... это жизнь на SOF ..
javadba
не работал на git версии 2.22.0.windows.1
Mahesh
29

сначала получить все теги в этом конкретном пульте

git fetch <remote> 'refs/tags/*:refs/tags/*'

или просто введите

git fetch <remote>

Затем проверьте наличие тегов

git tag -l

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

git checkout tags/<tag_name>

Надеюсь, это поможет вам!

tk_
источник
зачем использовать тег git -l, он должен совпадать с тегом git?
serup 11.1018
1
@serup; git tagдобавит тег, в то время как git tag -lперечисляет доступные теги
Joost Döbken
18

Если ваши теги можно сортировать с помощью команды linux sort, используйте это:

git tag | sort -n | tail -1

например. если git tagвозвращается:

v1.0.1
v1.0.2
v1.0.5
v1.0.4

git tag | sort -n | tail -1 будет выводить:

v1.0.5

git tag | sort -n | tail -2 | head -1 будет выводить:

v1.0.4

(потому что вы попросили второй самый последний тег)

чтобы оформить заказ, сначала клонируйте репозиторий, затем введите:

git checkout v1.0.4

... или любой тег, который вам нужен.

Питер Джонсон
источник
25
Пока вы не достигнете v1.0.10, и тогда произойдут плохие вещи :)
Лоран Грегуар
10
Чтобы ваши теги были отсортированы в хронологическом порядке:git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags
Боб Г
Один вкладыш для автоматической проверки последней версии,git checkout `git tag | sort -n | tail -1`
weiji14
Вы можете использовать sort -Vвместо sort -n. Первый правильно обрабатывает версии, которые не обязательно являются числовыми, например, «1.2.3». Он также понимает, что «0.4.10» идет после «0.4.1», а не после «0.4.2», что -nдаст вам.
Матеуш Мисорный
16

Я проверил документацию git checkout , она обнаружила одну интересную вещь:

git checkout -b <new_branch_name> <start_point>, где <start_point> - это имя коммита, с которого начинается новая ветка; По умолчанию HEAD

Таким образом, мы можем упомянуть имя тега (так как тег - это не что иное, как имя коммита) как, скажем:

>> git checkout -b 1.0.2_branch 1.0.2
позже, измените некоторые файлы
>> git push --tags

PS: В Git вы не можете напрямую обновить тег (так как тег - это просто метка для коммита), вам нужно извлечь тот же тег в виде ветви, а затем зафиксировать его и затем создать отдельный тег.

Без-да
источник
1
Или, если вы не планируете вносить какие-либо изменения и хотите просто посмотреть, как выглядит код для этого тега, вы можете просто извлечь тег, не создавая ветку. Вы получите текст, объясняющий, что вы находитесь в состоянии «отсоединенная голова», и вы всегда можете создать ветку позже, если захотите.
MatrixFrog
16
git fetch <gitserver> <remotetag>:<localtag>

===================================

Я только что сделал это. Сначала я убедился, что знаю правописание имени тега.

git ls-remote --tags gitserver; : or origin, whatever your remote is called

Это дало мне список тегов на моем git-сервере на выбор. Оригинальный постер уже знал имя своего тега, поэтому этот шаг не нужен для всех. Вывод выглядел так, хотя реальный список был длиннее.

8acb6864d10caa9baf25cc1e4857371efb01f7cd    refs/tags/v5.2.2.2
f4ba9d79e3d760f1990c2117187b5010e92e1ea2    refs/tags/v5.2.3.1
8dd05466201b51fcaf4ca85897347d82fcb29518    refs/tags/Fix_109
9b5087090d9077c10ba22d99d5ce90d8a45c50a3    refs/tags/Fix_110

Я выбрал метку, которую хотел, и получил ее, и ничего больше, как указано ниже.

git fetch gitserver Fix_110

Затем я отметил это на своем локальном компьютере, присвоив этому тегу то же имя.

git tag Fix_110 FETCH_HEAD

Я не хотел клонировать удаленный репозиторий, как предлагали другие люди, так как проект, над которым я работаю, большой, и я хочу развиваться в хорошей чистой среде. Я чувствую, что это ближе к первоначальным вопросам «Я пытаюсь выяснить, как загрузить A PARTICULAR TAG», чем к решению, которое предполагает клонирование всего хранилища. Я не понимаю, почему кто-то должен иметь копию исходного кода Windows NT и Windows 8.1, если он хочет взглянуть на исходный код DOS 0.1 (например).

Я также не хотел использовать CHECKOUT, как предлагали другие. Я проверил ветку и не хотел влиять на это. Мое намерение состояло в том, чтобы получить программное обеспечение, которое я хотел, чтобы я мог что-то выбрать и добавить это в свою разработку.

Вероятно, есть способ получить сам тег, а не просто копию коммита, который был помечен. Мне пришлось пометить извлеченный коммит сам. РЕДАКТИРОВАТЬ: Ах да, я нашел это сейчас.

git fetch gitserver Fix_110:Fix_110

Там, где вы видите двоеточие, это remote-name: local-name, а здесь это имена тегов. Это работает без нарушения рабочего дерева и т. Д. Просто кажется, что вы копируете данные с удаленного на локальный компьютер, чтобы у вас была собственная копия.

git fetch gitserver --dry-run Fix_110:Fix_110

с добавленной опцией --dry-run вы сможете посмотреть, что будет делать команда, если вы хотите проверить, что вы хотите. Так что я думаю, простой

git fetch gitserver remotetag:localtag

это реальный ответ.

знак равно

Отдельное примечание о тегах ... Когда я запускаю что-то новое, я обычно отмечаю пустой репозиторий после git init, так как

git rebase -i XXXXX 

требует фиксации, и возникает вопрос: «Как вы перебазируете изменения, которые включают ваше первое изменение программного обеспечения?» Поэтому, когда я начинаю работать, я делаю

git init
touch .gitignore
[then add it and commit it, and finally]
git tag EMPTY

т.е. создать коммит до моего первого реального изменения, а затем использовать позже

git rebase -i EMPTY 

если я хочу перебазировать всю свою работу, включая первое изменение .

Иван
источник
8

Отрабатывая ответ Питера Джонсона, я создал для себя симпатичный маленький псевдоним:

alias gcolt="git checkout $(git tag | sort -V | tail -1)"

ака 'Git Checkout последний тег'.

Это зависит от GNU-версии sort, которая соответствующим образом обрабатывает ситуации, подобные той, на которую указал lOranger:

v1.0.1
...
v1.0.9
v1.0.10

Если вы на Mac, brew install coreutilsа затем вместо этого вызовите gsort.

billkw
источник
6

пытаться:

git clone -b <name_of_the_tag> <repository_url> <destination>
Камил Зайц
источник
Если для хранилища существует несколько веток, то какая ветка будет клонирована?
tauseef_CuriousGuy
5

Проверка тегов

Если вы хотите просмотреть версии файлов, на которые указывает тег, вы можете выполнить git checkout, хотя это переводит ваш репозиторий в состояние «detached HEAD», что имеет некоторые неприятные побочные эффекты:

$ git checkout 2.0.0
Note: checking out '2.0.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final

$ git checkout 2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... add atlas.json and cover image

В состоянии «отсоединенный HEAD», если вы вносите изменения, а затем создаете коммит, тег останется прежним, но ваш новый коммит не будет принадлежать какой-либо ветви и будет недоступен, за исключением точного хэша коммита. Таким образом, если вам нужно внести изменения - например, вы исправляете ошибку в более старой версии - вы, как правило, захотите создать ветку:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

Если вы сделаете это и сделаете коммит, ваша ветка version2 будет немного отличаться от вашего тега v2.0.0, поскольку она будет продвигаться вперед с вашими новыми изменениями, поэтому будьте осторожны.

artamonovdev
источник
4

Я делаю это через API GitHub:

curl -H "Authorization: token %(access_token)s" -sL -o /tmp/repo.tar.gz "http://api.github.com/repos/%(organisation)s/%(repo)s/tarball/%(tag)s" ;\
tar xfz /tmp/repo.tar.gz -C /tmp/repo --strip-components=1 ; \
J0hnG4lt
источник
1
Это работает для веток и тегов, но не для главы мастера, которому нужен тег, созданный против него. Имхо довольно элегантный способ получить версию минимального размера.
J0hnG4lt