Git клонировать конкретную версию удаленного репозитория


191

Я клонировал удаленный репозиторий git около месяца назад. Удаленный репозиторий претерпел множество изменений и теперь стал нестабильным. Теперь мне нужна еще одна копия репозитория, версия, идентичная той, которую я клонировал месяц назад.

Как мне это сделать?



Ответы:


252

Вы можете «сбросить» свой репозиторий на любую фиксацию (например, 1 месяц назад).

Для этого используйте git-reset :

git clone [remote_address_here] my_repo
cd my_repo
git reset --hard [ENTER HERE THE COMMIT HASH YOU WANT]

27
Вы не упомянули об этом, но это только сбросит masterветку, которая по умолчанию проверена на клоне. Если ветвь, отличная от masterвашей основной, должна быть проверена раньшеgit reset
— Стив Фолли,

16
почему бы вам не выполнить простую проверку желаемой фиксации?
— nemoo

10
Потому что вы будете в состоянии «отключенной HEAD» после проверки на конкретную фиксацию.
— Руи Карнейро

7
@RuiCarneiro было бы лучше использовать git checkout -b new_branch hashсоздание новой ветки на основе хэша, не касаясь какой-либо другой ветки. Перемещение заголовка существующей ветки могло вызвать проблемы, когда пришло время отправить что-то на удаленный сервер.
— Лоик Фор-Лакруа

1
@YuriGhensev Если фиксация уже была отправлена ​​в удаленную ветку, вы можете сделать git pull origin [branch]иначе, ага, она потеряна.
— Руи Карнейро,

104

Вы можете просто использовать

git checkout  commithash

в этой последовательности

git clone `URLTORepository`
cd `into your cloned folder`
git checkout commithash

хеш фиксации выглядит так: "45ef55ac20ce2389c9180658fdba35f4a663d204"


9
Мне больше всего нравится этот ответ. Я думаю, что git reset --hardлучше избегать a git checkout commit-hash. A git reset --hardудаляет часть истории git, что иногда нежелательно.
— Джордан Стюарт,

8
git initне обязательно
— Лаутаро Паскявичюс

36

Используйте, git logчтобы найти ревизию, к которой вы хотите выполнить откат, и запишите хэш фиксации. После этого у вас есть 2 варианта:

  1. Если вы планируете зафиксировать что-либо после этой ревизии, я рекомендую вам оформить заказ в новую ветку:git checkout -b <new_branch_name> <hash>

  2. Если вы не планируете ничего фиксировать после этой ревизии, вы можете просто оформить заказ без ветки: git checkout <hash>- ПРИМЕЧАНИЕ. Это переведет ваш репозиторий в состояние «отсоединенной HEAD», что означает, что в настоящее время он не прикреплен к какой-либо ветке - тогда вы у меня будет дополнительная работа по слиянию новых коммитов с реальной веткой .

Пример:

$ git log
commit 89915b4cc0810a9c9e67b3706a2850c58120cf75
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:15:01 2010 -0300

    Added a custom extension.

commit 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:13:48 2010 -0300

    Missing constness.

$ git checkout 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Note: moving to '4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7'
which isn't a local branch
If you want to create a new branch from this checkout, 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 4553c14... Missing constness.

Таким образом вы не потеряете никакой информации и сможете перейти к более новой версии, когда она станет стабильной.


2
Но также не то, что вы используете отдельную голову, что нормально для операций только для чтения. Но если вы собираетесь внести изменения, начиная с этой версии, вам необходимо создать новую ветку. См. Sitaramc.github.com/concepts/detached-head.html для получения дополнительной информации.
— Руди

@ Руди: Спасибо. Это был просто пример использования. Обновлено, чтобы упомянуть об этом.
— jweyrich

Чтобы вернуться в «рабочий статус», вы можете просто указать, git checkout developгде разработка - это имя вашей ветки.
— Стив Таубер

1
@SteveTauber. Предположим, у вас есть другая работающая ветка , и перехода на эту ветку действительно достаточно.
— jweyrich

23

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

git clone -b branch_or_tag_name repo_address_or_path

2

В отличие от централизованных систем контроля версий, Git клонирует весь репозиторий, поэтому вы получаете не только текущие удаленные файлы, но и всю историю. Все это будет включать ваш локальный репозиторий.

В то время могли быть теги для обозначения конкретной версии. Если нет, вы можете создать их самостоятельно локально. Хороший способ сделать это - использовать git logили, возможно, более визуально с такими инструментами, как gitk(возможно, gitk --allчтобы увидеть все ветки и теги). Если вы можете определить хэши коммитов, которые использовались в то время, вы можете пометить их с помощью, git tag <hash>а затем проверить их в новых рабочих копиях (например, git checkout -b new_branch_name tag_nameили напрямую с помощью хеша вместо имени тега).


1

Решить это можно так:

git reset --hard sha

где shaнапример:85a108ec5d8443626c690a84bc7901195d19c446

Получить желаемый ша можно командой:

git log

1

uploadpack.allowReachableSHA1InWant

Начиная с Git 2.5.0, эту переменную конфигурации можно включить на сервере, здесь запрос функции GitHub и фиксация GitHub включают эту функцию .

Bitbucket Server включил его с версии 5.5+ .

Применение:

# Make remote with 4 commits, and local with just one.
mkdir server
cd server
git init
touch 1
git add 1
git commit -m 1
git clone ./ ../local
for i in {2..4}; do
    touch "$i"
    git add "$i"
    git commit -m "$i"
done

# Before last commit.
SHA3="$(git log --format='%H' --skip=1 -n1)"
# Last commit.
SHA4="$(git log --format='%H' -n1)"

# Failing control without feature.
cd ../local
# Does not give an error, but does not fetch either.
git fetch origin "$SHA3"
# Error.
git checkout "$SHA3"

# Enable the feature.
cd ../server
git config uploadpack.allowReachableSHA1InWant true

# Now it works.
cd ../local
git fetch origin "$SHA3"
git checkout "$SHA3"
# Error.
git checkout "$SHA4"

0

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

Если вы можете получить этот SHA1, вы можете создать там ветку / сбросить, чтобы иметь идентичный репозиторий.

Команды согласно ответу Руи


0

Наверное git resetрешит вашу проблему.

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