Jak mogę pobrać pliki ze zdalnego bez nadpisywania plików lokalnych?

113

Próbuję skonfigurować nowe repozytorium git do istniejącego zdalnego repozytorium.

Chcę, aby moje lokalne pliki nadpisały zdalne repozytorium, ale git mówi, że najpierw muszę pobrać te zdalne pliki i scalić je.

Czy jest jakiś sposób na ściągnięcie, ale upewnij się, że pliki lokalne nie są nadpisywane przez pilota?

Joe Isaacson
źródło

Odpowiedzi:

182

Cóż, tak i nie ...

Rozumiem, że chcesz, aby Twoje lokalne kopie „nadpisały” to, co jest w pilocie, ale, o rany, jeśli ktoś zmodyfikował pliki w zdalnym repozytorium w inny sposób, a ty po prostu ignorujesz ich zmiany i próbujesz „wymusić” twoje własne zmiany, nawet nie patrząc na możliwe konflikty, cóż, płaczę za tobą (i twoimi współpracownikami) ;-)

To powiedziawszy, jednak naprawdę łatwo jest zrobić „właściwą rzecz…”

Krok 1:

git stash

w lokalnym repozytorium. Spowoduje to zapisanie lokalnych aktualizacji w skrytce, a następnie przywrócenie zmodyfikowanych plików do stanu sprzed edycji.

Krok 2:

git pull

aby uzyskać zmodyfikowane wersje. Miejmy nadzieję, że nie otrzyma to żadnych nowych wersji plików, o które się martwisz. Jeśli tak się nie stanie, następny krok będzie przebiegał sprawnie. Jeśli to robi , to masz coś do zrobienia, a będziesz zadowolony zrobiłeś.

Krok 3:

git stash pop

Spowoduje to połączenie zmodyfikowanych wersji, które zachowałeś w kroku 1, z wersjami, które właśnie pobrałeś w kroku 2. Jeśli wszystko pójdzie gładko, wszystko będzie gotowe!

Z drugiej strony, jeśli wystąpiłyby rzeczywiste konflikty między tym, co wyciągnąłeś w kroku 2, a twoimi modyfikacjami (spowodowanymi przez kogoś innego edytującego w międzyczasie), dowiesz się i zostaniesz poproszony o ich rozwiązanie. Zrób to.

W ten sposób wszystko ułoży się znacznie lepiej - prawdopodobnie zachowa zmiany bez Twojej realnej pracy z Twojej strony, ostrzegając Cię o poważnych, poważnych problemach.

Bob Gilmore
źródło
5
dlaczego nie tylko git commitlokalne zmiany przed git pull?
Don Cheadle
10
Czasami jestem w sytuacji, w której nie chcę zatwierdzać kodu, ale chciałbym zachować go na mojej lokalnej maszynie, ten zestaw poleceń jest w tym naprawdę pomocny.
Vargan
3
Nie jest to przydatne, jeśli masz wiele plików, niektóre chcesz nadpisać, a inne nie. Czy nie ma sposobu, aby powiedzieć GIT, aby ignorował pliki podczas ściągania? Dlaczego .gitignore działa tylko do pchania, w ogóle nie rozumiem tej decyzji projektowej ...
Bobak Hashemi
25

Możesz najpierw schować lokalne zmiany, a następnie pociągnąć, a następnie wyjąć schowek.

git stash
git pull origin master
git stash pop

Wszystko, co zastępuje zmiany wprowadzone zdalnie, będzie powodować konflikty, które będziesz musiał rozwiązać ręcznie.

Ryan Bigg
źródło
4
Dokonałem już tych zmian lokalnie, więc jest napisane, że „nie ma lokalnych zmian do zapisania”
Joe Isaacson,
myślę, że to najlepsza strategia.
Jimmy Obonyo Abor
13

Więc zatwierdziłeś lokalne zmiany w swoim lokalnym repozytorium. Następnie, aby uzyskać zdalne zmiany w lokalnym repozytorium bez wprowadzania zmian w plikach lokalnych, możesz użyć git fetch. W rzeczywistości git pulljest to operacja dwuetapowa: nieniszcząca, git fetchpo której następuje git merge. Zobacz Jaka jest różnica między „git pull” a „git fetch”? więcej dyskusji.

Szczegółowy przykład:

Załóżmy, że twoje repozytorium wygląda tak (dokonałeś zmian test2:

* ed0bcb2 - (HEAD, master) test2
* 4942854 - (origin/master, origin/HEAD) first

A originrepozytorium wygląda tak (ktoś inny popełnił test1):

* 5437ca5 - (HEAD, master) test1
* 4942854 - first

W tym momencie git będzie narzekał i poprosi Cię o ściągnięcie najpierw, jeśli spróbujesz wypchnąć swoje test2do zdalnego repozytorium. Jeśli chcesz zobaczyć, czym jest test1 bez modyfikowania lokalnego repozytorium, uruchom to:

$ git fetch

Twoje lokalne repozytorium wyników wyglądałoby tak:

* ed0bcb2 - (HEAD, master) test2 
| * 5437ca5 - (origin/master, origin/HEAD) test1 
|/  
* 4942854 - first 

Teraz masz zdalne zmiany w innej gałęzi i zachowujesz nienaruszone pliki lokalne.

Więc co dalej? Możesz zrobić git merge, co da taki sam efekt, jak git pull(w połączeniu z poprzednim git fetch), lub, jak wolałbym, zrobić, git rebase origin/masteraby zastosować swoją zmianę origin/master, co daje czystszą historię.

Penghe Geng
źródło
dzięki za wyjaśnienie git pull jako dwuetapowego git fetch / git merge
cdabel