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.