Pobieranie określonych zmian ze zdalnego repozytorium Git

Czy Jest jakiś sposób, aby odzyskać tylko jeden konkretny commit ze zdalnego repo Git bez klonowania go na moim komputerze? Struktura zdalnego repo jest absolutnie taka sama jak moja i dlatego nie będzie żadnych konfliktów, ale nie mam pojęcia, jak to zrobić i nie chcę klonować tego ogromnego repozytorium.

Jestem nowy w git, czy jest jakiś sposób?

 166
Author: Daniel, 2013-02-14

7 answers

Począwszy od wersji Git 2.5+ (Q2 2015), pobieranie pojedynczego commita (bez klonowania pełnego repo) jest w rzeczywistości możliwe.

Zobacz commit 68ee628 by Fredrik Medley (moroten), 21 Maj 2015.
(dodany przez Junio C Hamano -- gitster -- in commit a9d3493, 01 Jun 2015)

[[55]} masz teraz nowy config (po stronie serwera)
uploadpack.allowReachableSHA1InWant

Pozwól upload-pack zaakceptować żądanie fetch, które prosi o obiekt, który jest osiągalny z każdej końcówki ref. Należy jednak pamiętać, że obliczanie osiągalności obiektów jest kosztowne obliczeniowo.
Domyślnie false.

Jeśli połączysz tę konfigurację po stronie serwera z płytkim klonem (git fetch --depth=1), możesz poprosić o pojedynczy commit (zobacz t/t5516-fetch-push.sh:

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

Możesz użyć git cat-file aby zobaczyć, że commit został pobrany:

git cat-file commit $SHA1

"git upload-pack" które służy "git fetch " można powiedzieć, aby służyć commity, które nie są na końcówka dowolnego ref, o ile są osiągalny z ref, z uploadpack.allowReachableSHA1InWant zmienna konfiguracyjna.


Pełna dokumentacja to:

upload-pack: opcjonalnie Zezwalaj na pobieranie osiągalnego sha1

Z opcją konfiguracji uploadpack.allowReachableSHA1InWant ustawioną po stronie serwera," git fetch "może wysłać żądanie z linią "want", która nazywa obiekt, który nie został reklamowany (prawdopodobnie został uzyskany poza pasmem lub ze wskaźnika podmodułu).
Tylko obiekty dostępne z końcówek gałęzi, tj. związek reklamowanych gałęzi i gałęzi ukrytych przez transfer.hideRefs, będą przetwarzane.
Należy pamiętać, że istnieje związany z tym koszt przejścia wstecz do historii, aby sprawdzić osiągalność.

Ta funkcja może być używana podczas uzyskiwania zawartości określonego commita, dla których znany jest sha1, bez konieczności klonowania całego repozytorium, zwłaszcza jeśli używane jest płytkie pobieranie .

Przydatne przypadki to np.

  • repozytoria zawierające duże pliki w historii,
  • W tym celu należy wysłać wiadomość e-mail na adres .]}
  • podczas dzielenia sha1 bez podania dokładnej gałęzi, do której należy i w Gerrit, jeśli myślisz w kategoriach commitów zamiast liczb zmian.
    (Sprawa Gerrita została już rozwiązana przez allowTipSHA1InWant, ponieważ każda zmiana Gerrita ma ref.)

[55]}Git 2.6 (Q3 2015) poprawi to model.
Zobacz commit 2bc31d1, commit cc118a6 (28 Jul 2015) by Jeff King (peff).
(dodany przez Junio C Hamano -- gitster -- in commit 824a0be, 19 Aug 2015)

refs: Wsparcie negatywne transfer.hideRefs

Jeśli ukryjesz hierarchię refów za pomocą konfiguracji transfer.hideRefs, nie ma możliwości późniejszego nadpisania tej konfiguracji, aby ją "odkryć".
Ta łatka implementuje" negatywną " kryjówkę, która powoduje, że dopasowania są natychmiast oznaczane jako nieujawnione, nawet jeśli inne dopasowanie ukryłoby je.
Dbamy o to, aby dopasowania były stosowane w odwrotnej kolejności od sposobu, w jaki są dostarczane nam przez maszynę konfiguracyjną, ponieważ pozwala to na działanie naszego zwykłego pierwszeństwa konfiguracji "ostatni wygrywa" (a wpisy w .git/config, na przykład, nadpiszą /etc/gitconfig).

Więc możesz teraz zrobić:

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

Aby ukryć refs/secret we wszystkich repozytoriach, z wyjątkiem jednego publicznego bitu w jednym konkretnym repo.


Git 2.7 (Listopad/Grudzień 2015) ponownie się poprawi:

Zobacz commit 948bfa2, commit 00b293e (05 Nov 2015), commit 78a766a, / align = "left" / 92cab49, / align = "left" / 92cab49, commit 92cab49 (03 Nov 2015), commit 00b293e, commit 00b293e (05 lis 2015) oraz commit 92cab49, / align = "left" / 92cab49, / align = "left" / 92cab49, commit 92cab49 (03 Nov 2015) by Lukas Fleischer (lfos).
Helped-by: Eric Sunshine (sunshineco).
(dodane przez Jeff King -- peff -- in commit dbba85e, 20 Nov 2015)

config.txt: dokumentuje semantykę hideRefs z przestrzeniami nazw

W tej chwili, nie ma jasnej definicji jak transfer.hideRefs powinien zachowuje się, gdy ustawiona jest Przestrzeń nazw.
Wyjaśnij, że prefiksy hideRefs pasują do nazw usuniętych w tym przypadku. Oto jak hideRefs wzory są obecnie obsługiwane w opakowaniu odbiorczym.

HideRefs: Dodaj wsparcie dla dopasowania pełnych refów

Oprócz dopasowywania pozbawionych refów, można teraz dodać hideRefs wzorce, z którymi dopasowane jest pełne (nieopisane) ref.
Aby rozróżnić pomiędzy pasami pozbawionymi i pełnymi, te nowe wzory muszą być poprzedzone znakiem circumflex (^).

Stąd Nowa dokumentacja :

transfer.hideRefs:

Jeśli używana jest Przestrzeń nazw, prefiks przestrzeni nazw jest usuwany z każdego odniesienia, zanim zostanie dopasowany do wzorców transfer.hiderefs.
Na przykład, jeśli {[39] } jest określone w transfer.hideRefs i bieżąca przestrzeń nazw to foo, następnie refs/namespaces/foo/refs/heads/master jest pomijany w reklamach, ale refs/heads/master i refs/namespaces/bar/refs/heads/master są nadal reklamowane jako tak zwane "mieć" linie.
W celu dopasowania refów przed rozebraniem, dodaj ^ przed nazwisko sędziego. Jeśli połączysz ! i ^, ! należy określić najpierw.


R.. wspomina w komentarzach konfiguracja uploadpack.allowAnySHA1InWant, co pozwala upload-pack zaakceptować fetch żądanie, które prosi o dowolny obiekt. (Domyślnie false).

Zobacz commit f8edeaa (Nov. 2016, Git v2. 11. 1) by David" novalis " Turner (novalis):

upload-pack: opcjonalnie Zezwalaj na pobieranie dowolnego sha1

Wydaje się trochę głupie, aby zrobić reachabilty sprawdzić w przypadku, gdy zaufaj użytkownikowi, aby miał dostęp do absolutnie wszystkiego w repozytorium.

Poza tym, to jest pikantne w systemie rozproszonym -- być może jeden serwer reklamuje referenta, ale inny od tego czasu miał siłę do tego referenta, i być może dwa żądania HTTP kończą się skierowane do tych różnych serwery.

 87
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 10:50:15

Sklonujesz tylko raz, więc jeśli masz już klon Zdalnego repozytorium, wyciągnięcie z niego nie spowoduje ponownego pobrania wszystkiego. Po prostu wskaż gałąź, którą chcesz wyciągnąć lub Pobierz zmiany i sprawdź commit, który chcesz pobrać.

Pobieranie z nowego repozytorium jest bardzo tanie w przepustowości, ponieważ pobierze tylko zmiany, których nie masz. Pomyśl w kategoriach Git robi dobrą rzecz, przy minimalnym obciążeniu.

Git przechowuje wszystko w .git folderze. Commit nie może być pobierane i przechowywane w izolacji, potrzebuje wszystkich swoich przodków. Są one powiązane ze sobą .


Aby zmniejszyć rozmiar pobierania, możesz jednak poprosić git o pobranie tylko obiektów związanych z konkretną gałęzią lub zatwierdzeniem:

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

Spowoduje pobranie tylko commitów zawartych w zdalnej gałęzi branch (i tylko te, za którymi tęsknisz) i przechowuj je w origin/branch. Następnie możesz scalić lub zrealizować zamówienie.

Możesz również podać tylko commit SHA1:

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

To będzie pobierz tylko commit określonego SHA-1 96de5297df870 (i jego przodków, których brakuje) i zapisz go jako (nieistniejącą) zdalną gałąź origin/foo-commit.

 92
Author: CharlesB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-06 14:46:37

I did a pull on my Git repo:

git pull --rebase <repo> <branch>

PozwalajÄ ... c gitowi na pobranie caĹ 'ego kodu dla branch' A, a potem udaĹ 'em siÄ ™ wykonaÄ ‡ reset do commita, ktĂłry mnie zainteresowaĺ'.

git reset --hard <commit-hash>

Mam nadzieję, że to pomoże.
 58
Author: Piu Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-03 12:43:17

Możesz po prostu pobrać pojedynczy commit zdalnego repo za pomocą

git fetch <repo> <commit>

Gdzie,

  • Może to być zdalna nazwa repo (np. origin) lub nawet zdalny adres URL repo (np. https://git.foo.com/myrepo.git)
  • <commit> może być commit SHA1

Na przykład

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

Po pobraniu commita (i zaginionych przodków) możesz go po prostu sprawdzić za pomocą

git checkout FETCH_HEAD

Zauważ, że to spowoduje, że stan "odłączonej głowy".

 42
Author: Flow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-06 14:50:35

Możesz po prostu pobrać zdalny repo za pomocą:

git fetch <repo>

Gdzie,

  • W tym celu należy skontaktować się z działem obsługi klienta pod adresem .]}

Na przykład:

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

Po pobraniu repo możesz scalić commity, które chcesz (ponieważ pytanie dotyczy odzyskania jednego commita, zamiast scalić możesz użyć cherry-pick, aby wybrać tylko jeden commit):

git merge <commit>
  • <commit> może być commit SHA1

Dla przykład:

git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545

Lub

git merge 0a071603d87e0b89738599c160583a19a6d95545

Jeśli jest najnowszym zatwierdzeniem, które chcesz scalić, możesz również użyć zmiennej FETCH_HEAD:

git cherry-pick (or merge) FETCH_HEAD
 13
Author: Sérgio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 10:43:07

Myślę, że 'git ls-remote' ( http://git-scm.com/docs/git-ls-remote ) powinieneś robić, co chcesz. Bez siły.

 1
Author: Hubbitus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-28 15:42:04

W końcu znalazłem sposób, aby sklonować konkretny commit używając git cherry-pick . Zakładając, że nie masz żadnego repozytorium w lokalnym repozytorium i wyciągasz konkretny commit ze zdalnego,

1) Utwórz puste repozytorium w lokalnym i git INIT

2) Git remote add origin "url-of-repozytorium "

3) git fetch origin [spowoduje to przeniesienie plików do lokalnej przestrzeni roboczej, chyba że połączysz]

4) git cherry-pick "Enter-long-commit-hash-that-you-need "

Zrobione.W ten sposób będziesz mieć tylko pliki z tego konkretnego commita w swoim lokalnym.

Enter-long-commit-hash:

Możesz to uzyskać używając -> Git log --pretty=oneline

 1
Author: surya deepak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-03 04:19:49