Получить конкретную фиксацию из удаленного репозитория Git

Есть ли способ получить только одну конкретную фиксацию из удаленного репозитория Git без клонирования его на моем ПК? Структура удаленного репо абсолютно такая же, как у меня, и, следовательно, конфликтов не будет, но я понятия не имею, как это сделать, и я не хочу клонировать этот огромный репозиторий.

Я новичок в git, есть ли способ?

Ответ 1

Начиная с Git версии 2. 5+ (2 квартал 2015 г.), получение одного коммита (без клонирования полного репо) действительно возможно.

См. Коммит 68ee628 Фредрика Медли (moroten), 21 мая 2015 г.
(Объединено Junio C Hamano - gitster - в коммите a9d3493, 01 июня 2015 г.)

Теперь у вас есть новый конфиг (на стороне сервера)

uploadpack.allowReachableSHA1InWant

Разрешить upload-pack для принятия запроса на выборку, который запрашивает объект, доступный из любой ссылки ref. Тем не менее, обратите внимание, что вычисление достижимости объекта вычислительно дорого.
По умолчанию false.

Если вы объедините эту конфигурацию на стороне сервера с мелким клоном ( git fetch --depth=1), вы можете запросить один коммит (см. t/t5516-fetch-push.sh:

git fetch --depth=1 ../testrepo/.git $SHA1

Вы можете использовать команду git cat-file чтобы увидеть, что был получен коммит:

git cat-file commit $SHA1

" git upload-pack ", который обслуживает " git fetch ", можно сказать, чтобы он обслуживал коммиты, которые не находятся на кончиках ссылок, если они доступны из ссылки, с помощью переменной конфигурации uploadpack.allowReachableSHA1InWant.


Полная документация:

upload-pack: опционально разрешить выборку доступного sha1

С uploadpack.allowReachableSHA1InWant конфигурации uploadpack.allowReachableSHA1InWant установленным на стороне сервера, " git fetch " может сделать запрос со строкой "want", которая называет объект, который не был объявлен (вероятно, был получен вне диапазона или из указателя подмодуля),
Только объекты достижимы от кончиков ветки, то есть объединение рекламируемых ветвей и ветвей, спрятанных transfer.hideRefs, будут обработаны.
Обратите внимание, что это связано с необходимостью обходить историю, чтобы проверить достижимость.

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

Например, полезные случаи

  • репозитории, содержащие большие файлы в истории,
  • получение только необходимых данных для проверки субмодуля,
  • при совместном использовании sha1, не сообщая, к какой именно ветки он принадлежит, и в Gerrit, если вместо чисел изменений вы думаете о коммитах.
    (Случай Gerrit уже был разрешен с помощью allowTipSHA1InWant поскольку каждое изменение Gerrit имеет allowTipSHA1InWant.)

Git 2.6 (3 квартал 2015 года) улучшит эту модель.
Смотрите коммит 2bc31d1, коммит cc118a6 (28 июля 2015 г.) Джеффа Кинга (peff).
(Объединено Junio C Hamano - gitster - в коммите 824a0be, 19 августа 2015 г.)

refs: поддержка отрицательного transfer.hideRefs

Если скрыть иерархию рефов с помощью transfer.hideRefs конфигурации, нет никакого способа, чтобы позже переопределить конфигурации для "UNHIDE" его.
Этот патч реализует "отрицательное" скрытие, которое заставляет совпадения немедленно помечаться как скрытые, даже если другое совпадение скрыло бы это.
Мы позаботимся о том, чтобы применить совпадения в обратном порядке по сравнению с тем, как они передаются нам механизмом конфигурации, поскольку это позволяет нашему обычному приоритету конфигурации "последний выиграл" (и записи в .git/config, например, переопределят /etc/gitconfig).

Итак, теперь вы можете сделать:

git config --system transfer.hideRefs refs/secret
git config transfer.hideRefs '!refs/secret/not-so-secret'

скрывать refs/secret во всех репо, кроме одного публичного бита в одном репо.


Git 2.7 (ноябрь/декабрь 2015) снова улучшится:

См. Коммит 948bfa2, коммит 00b293e (05 ноября 2015 г.), коммит 78a766a, коммит 92cab49, коммит 92cab49, коммит 92cab49 (03 ноя 2015 г.), коммит 00b293e, коммит 00b293e (05 ноября 2015 г.) и коммит 92cab49, коммит 92cab49, коммит 92cab49, совершить 92cab49 (3 ноября 2015 г.) Лукасом Флейшером (lfos).
Помогает: Эрик Саншайн (sunshineco).
(Объединено Джеффом Кингом - peff - in commit dbba85e, 20 ноября 2015 г.)

config.txt: документировать семантику hideRefs с пространствами имен

Прямо сейчас, нет четкого определения того, как transfer.hideRefs следует вести себя, когда пространство имен устанавливается.
Объясните, что в этом hideRefs префиксы hideRefs соответствуют hideRefs именам. Вот как шаблоны hideRefs в настоящее время обрабатываются в receive-pack.

hideRefs: добавить поддержку для сопоставления полных ссылок

В дополнение к сопоставлению разделенных hideRefs теперь можно добавить шаблоны hideRefs, с которыми сопоставляется полный (необрезанный) ref.
Чтобы различать разделенные и полные совпадения, эти новые шаблоны должны иметь префикс с кружком (^).

Отсюда новая документация:

transfer.hideRefs:

Если пространство имен используется префикс пространства имен удаляется из каждой ссылки, прежде чем он будет сопоставлен с transfer.hiderefs узорами.
Например, если refs/heads/master задаются в transfer.hideRefs и текущее пространство имен foo, то refs/namespaces/foo/refs/heads/master опускаются от рекламы, но refs/heads/master и refs/namespaces/bar/refs/heads/master по-прежнему рекламируются как так называемые строки "иметь".
Чтобы сопоставить ссылки перед удалением, добавьте ^ перед именем ссылки. Если вы объедините ! и ^ ! должен быть указан первым.


В комментариях R упоминает конфигурацию uploadpack.allowAnySHA1InWant, которая позволяет upload-pack принимать запрос на fetch который вообще запрашивает какой-либо объект. (По умолчанию false).

Смотрите коммит f8edeaa (ноябрь 2016, Git v2.11.1) Дэвида "novalis" Тернера (novalis):

upload-pack: опционально разрешить выборку любого sha1

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

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

Ответ 2

Вы только клонируете один раз, поэтому, если у вас уже есть клон удаленного репозитория, вытаскивание из него не будет загружать все снова. Просто укажите, какую ветку вы хотите потянуть, или выберите изменения и проверите фиксацию, которую хотите.

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

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


Чтобы уменьшить размер загружаемого файла, вы можете запросить Git для извлечения только объектов, связанных с определенной ветвью или фиксацией:

git fetch origin refs/heads/branch:refs/remotes/origin/branch

Это будет загружать только коммиты, содержащиеся в удаленной ветке branch (и только те, которые вы пропустите), и сохраните их в origin/branch. Затем вы можете объединить или проверить.

Вы также можете указать только фиксацию SHA1:

git fetch origin 96de5297df870:refs/remotes/origin/foo-commit

Это загрузит только фиксацию указанного SHA-1 96de5297df870 (и его предков, которые вы пропустите), и сохраните его как (несуществующую) удаленную ветвь origin/foo-commit.

Ответ 3

Я потянул за git repo:

git pull --rebase <repo> <branch>

Разрешить git вытащить весь код для ветки, а затем я отправил reset в коммит, который меня заинтересовал.

git reset --hard <commit-hash>

Надеюсь, что это поможет.

Ответ 4

Вы можете просто получить одно коммит удаленного репо с помощью

git fetch <repo> <commit>

где

  • <repo> может быть удаленным именем репо (например, origin) или даже удаленным URL-адресом репо (например, https://git.foo.com/myrepo.git)
  • <commit> может быть передан SHA1

например

git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545

после того, как вы получили фиксацию (и отсутствующие предки), вы можете просто проверить ее с помощью

git checkout FETCH_HEAD

Обратите внимание, что это приведет вас в состояние "отсоединенной головки".

Ответ 5

Вы можете просто получить удаленное репо с помощью:

git fetch <repo>

где

  • <repo> может быть удаленным именем репо (например, origin) или даже удаленным URL-адресом репо (например, https://git.foo.com/myrepo.git)

например:

git fetch https://git.foo.com/myrepo.git 

после того, как вы извлекли репозиции, вы можете объединить сделанные вами коммиты (поскольку вопрос заключается в извлечении одного коммита, а вместо слияния вы можете использовать вишневый выбор для выбора только одного коммита):

git merge <commit>
  • <commit> может быть передан SHA1

например:

git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545

или

git merge 0a071603d87e0b89738599c160583a19a6d95545

Если это последняя фиксация, которую вы хотите объединить, вы также можете использовать переменную FETCH_HEAD:

git cherry-pick (or merge) FETCH_HEAD

Ответ 6

Наконец, я нашел способ клонировать конкретную фиксацию, используя git вишневый выбор. Предполагая, что у вас нет какого-либо репозитория в локальной сети, и вы выполняете конкретную фиксацию с удаленного,

1) создать пустой репозиторий в локальном и git init

2) git удаленный добавочный источник "url-of-repository"

3) git fetch origin [это не приведет к перемещению ваших файлов в локальное рабочее пространство, если вы не объединились)

4) git cherry-pick "Введите-long-commit-hash-that-you-need"

Готово. Таким образом, вы будете иметь только файлы из этой конкретной фиксации в локальном.

Enter-долго зафиксированной-хэш:

Вы можете использовать это → git log --pretty = oneline

Ответ 7

Это работает лучше всего:

git fetch origin specific_commit
git checkout -b temp FETCH_HEAD

назовите "temp" как хотите... эта ветка может быть осиротевшей

Ответ 8

Я думаю, что git ls-remote '(http://git-scm.com/docs/git-ls-remote) должен делать то, что вы хотите. Без принудительного извлечения или натяжения.

Ответ 9

Шаг 1: выбор списка коммитов:

git log

Вы получите список, как в этом примере:

commit 7244ab27d1c3411cdb8c0111706a4f0cd1236ce1 (commit hash) Автор: aspmac Дата: Чт май 4 18:03:40 2017 +0530

Fix header in ios(In-progress).

Это последнее сообщение о фиксации

commit b586ed0f5fd6b89a73b632181774464ef1c37bd5 (commit hash) Автор: Автор Дата: ср май 3 11:44:28 2017 +0530

remove all console.

Это предыдущее сообщение фиксации

... Шаг 2: скопируйте необходимый хэш и вставьте его для проверки:

git checkout b586ed0f5fd6b89a73b632181774464ef1c37bd5

Ответ 10

Если запрошенный коммит находится в запросах на удаление удаленного репо, вы можете получить его по его ID:

# Add the remote repo path, let call it 'upstream':
git remote add upstream https://github.com/repo/ptoject.git

# checkout the pull ID, for example ID '60':
git fetch upstream pull/60/head && git checkout FETCH_HEAD

Ответ 11

Пожалуйста, приложите все upvotes к сообщению Sergio, если вам это нравится. Решение было рассмотрено в его ответе. Я думаю, что это работает, вытягивая любую фиксацию из любого репо.

Последовательность:

git init
git fetch <repo> 
git merge <commitSHA> 
git push

Вот так:

git init
git fetch https://github.com/github/octicons.git
git merge 8fc17d58e75d9711fcd7f51a158f93ce9076cb23
git push