Назад | Перейти на главную страницу

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

У нас есть удаленное репозиторий git, которое мы обычно развертываем с помощью git push на нашем сервере разработки тогда git pull на наших действующих серверах, чтобы получить последнюю продвинутую версию репо.

Но если мы зафиксировали и выдвинули несколько исправлений (без git pull на живых серверах) как мы можем git pull это относится к более старой фиксации, которую мы хотим?

то есть что-то вроде git pull -r 3ef0dedda699f56dc1062b5dcc2c59f7ad93ede4

После того, как вы вытащили репозиторий, вы сможете:

git checkout 3ef0d...

uploadpack.allowReachableSHA1InWant

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

Сервер Bitbucket включил его с версии 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"

Если какой-то процесс на вашем живом сервере сразу обращается к только что извлеченному контенту (т.е. вы не можете работать с git checkout 3ef0d после извлечения) вам следует подумать о том, чтобы пометить версию, которую вы хотите развернуть в производственной среде, и, в частности, проверить этот тег в производственной среде, чтобы при извлечении не сразу изменился ваш рабочий каталог. В противном случае вы рискуете, что кто-то толкнет вас прямо перед вашим толчком.

Обратите внимание, что git pull git checkout my-old-commit теперь оставляет вас в состоянии ОТДЕЛЕННОЙ ГОЛОВКИ - фактически вы отправляете будущие коммиты в этот репозиторий по новому пути фиксации. Для репозитория развертывания это не является серьезной проблемой, поскольку единственными коммитами должны быть те, которые уже были правильно зафиксированы до извлечения.

Однако иногда бывает полезно проверить, что маркеры фиксации (заголовок, теги, пульты) выглядят идентично основному репо. Чтобы исправить это после оформления заказа: git reset - снова прикрепляет голову git fetch - синхронизирует маркеры для пультов [это может зависеть от версии git - по общему признанию, наша среда все еще находится на версии 1.7 ... поэтому, возможно, больше не требуется YMMV]