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

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

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

154
задан Varun Chitre 14 февр. '13 в 13:18
источник поделиться
9 ответов

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

Получение из нового репозитория очень дешево в полосе пропускания, так как оно будет загружать только те изменения, которые у вас нет. Подумайте в терминах 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.

89
ответ дан CharlesB 14 февр. '13 в 13:23
источник поделиться

С Git 2.5+ (Q2 2015) получение одной фиксации (без клонирования полного репо) будет действительно возможным!

См. commit 68ee628 Fredrik Medley (moroten), 21 мая 2015 года.
(слияние Junio ​​C Hamano - gitster - в commit a9d3493, 01 июня 2015 г.)

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

uploadpack.allowReachableSHA1InWant

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

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

git fetch --depth=1 ../testrepo/.git $SHA1
git cat-file commit $SHA1

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


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

upload-pack: необязательно разрешить выборку достижимой sha1

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

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

Полезными случаями являются, например,

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

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

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

Если вы спрячете иерархию ссылок refs с помощью конфигурации transfer.hideRefs, нет способа позже переопределить эту конфигурацию, чтобы "показать" ее.
Этот патч реализует "негативное" спряжение, в результате которого совпадения сразу же помечены как невидимые, даже если другое совпадение скроет его.
Мы позаботимся о том, чтобы применить спички в обратном порядке от того, как они будут переданы нам с помощью оборудования конфигурации, поскольку это позволяет нашей обычной "последней победе" работать с приоритетом конфигурации (а записи в .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 года) снова улучшится:

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

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

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

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

В дополнение к сопоставлению разделенных ссылок теперь можно добавить шаблоны hideRefs, с которыми сопоставляется полный (unstripped) 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 все еще рекламируются как так называемые "иметь" строки.
Чтобы соответствовать refs перед снятием, добавьте ^ перед имя ссылки. Если вы комбинируете ! и ^, сначала необходимо указать !.

81
ответ дан VonC 08 июня '15 в 8:22
источник поделиться

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

git pull --rebase <repo> <branch>

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

git reset --hard <commit-hash>

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

54
ответ дан Piu Sharma 03 дек. '13 в 15:43
источник поделиться

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

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

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

40
ответ дан Flow 06 июня '14 в 17:50
источник поделиться

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

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
11
ответ дан Sérgio 16 июля '15 в 20:32
источник поделиться

Наконец, я нашел способ клонировать конкретную фиксацию, используя 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

2
ответ дан surya deepak 03 янв. '17 в 7:19
источник поделиться

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

1
ответ дан Hubbitus 28 янв. '15 в 18:42
источник поделиться

Шаг 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

0
ответ дан Rahi.Shah 04 мая '17 в 17:16
источник поделиться

Пожалуйста, приложите все 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
-4
ответ дан Hien 27 окт. '15 в 6:01
источник поделиться

Другие вопросы по меткам