Jak zmusić „git pull” do zastąpienia lokalnych plików?

7176

Jak wymusić zastąpienie plików lokalnych w pliku git pull?

Scenariusz jest następujący:

  • Członek zespołu modyfikuje szablony witryny, nad którą pracujemy
  • Dodają kilka obrazów do katalogu obrazów (ale zapomina dodać je pod kontrolą źródła)
  • Później wysyłają mi zdjęcia pocztą
  • Dodaję obrazy pod kontrolą źródła i wypycham je do GitHub wraz z innymi zmianami
  • Nie mogą pobierać aktualizacji z GitHub, ponieważ Git nie chce zastępować swoich plików.

To jest błąd, który otrzymuję:

błąd: nieśledzony plik drzewa roboczego „public / images / icon.gif” zostałby zastąpiony przez scalenie

Jak zmusić Gita do zastąpienia ich? Osoba jest projektantem - zwykle wszystkie konflikty rozwiązuję ręcznie, więc serwer ma najnowszą wersję, którą wystarczy zaktualizować na swoim komputerze.

Jakub Troszok
źródło
17
każdy, kto myśli, że może stracić pliki, byłem w tej pozycji i odkryłem, że bufor Sublime Text mnie uratował - jeśli nad czymś pracuję, to przypadkowo usuń wszystko, próbując rozwiązać podobny problem do tego lub używając odpowiedź na to pytanie i po otwarciu plików w Sublime (na co jest duża szansa), wtedy pliki nadal będą tam Sublime, albo tylko tam, albo w historii cofania
Toni Leigh
61
git reset --hard origin/branch_to_overwrite
Andrew Atkinson,
1
w zasadzie, wykonuj tylko pull z rozwijania po początkowej kasie -b.
wykonuj
1
Krótka odpowiedź: usuń i ponownie utwórz gałąź. 1. Usuń gałąź: git branch <branch> -D2. Zresetuj do zatwierdzenia przed konfliktem: git reset <commit> --hard3. Ponownie utwórz gałąź: git branch <branch>4. Ustaw śledzenie na serwerze: git --set-upstream-to=origin/<branch> <branch> 5. Pull: git pull`
Nino Filiu
1
Aby zmienić wszystkie zakończenia CRLF na LF, (zacznij czyścić)git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Chloe,

Odpowiedzi:

10026

Ważne: jeśli wprowadzisz jakieś zmiany lokalne, zostaną one utracone. Z --hardopcją lub bez , wszelkie lokalne zatwierdzenia, które nie zostały wypchnięte, zostaną utracone. [*]

Jeśli masz jakieś pliki, które nie są śledzone przez Git (np. Przesłane treści użytkowników), nie będzie to miało wpływu na te pliki.


Myślę, że to właściwy sposób:

git fetch --all

Następnie masz dwie opcje:

git reset --hard origin/master

LUB Jeśli jesteś w innym oddziale:

git reset --hard origin/<branch_name>

Wyjaśnienie:

git fetch pobiera najnowsze z pilota, bez próby scalania lub zmiany bazy danych.

Następnie git resetresetuje gałąź master do tego, co właśnie pobrałeś. Ta --hardopcja zmienia wszystkie pliki w drzewie roboczym, aby pasowały do ​​plików worigin/master


Utrzymuj bieżące lokalne zobowiązania

[*] : Warto zauważyć, że możliwe jest utrzymanie bieżących lokalnych zatwierdzeń poprzez utworzenie oddziału masterprzed zresetowaniem:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

Po tym wszystkie stare zmiany będą przechowywane new-branch-to-save-current-commits.

Niezatwierdzone zmiany

Niezatwierdzone zmiany zostaną jednak utracone. Pamiętaj, aby schować i popełnić wszystko, czego potrzebujesz. W tym celu możesz uruchomić następujące czynności:

git stash

A następnie, aby ponownie zastosować te niezatwierdzone zmiany:

git stash pop
RNA
źródło
14
Uważaj! Jeśli masz lokalne niepublikowane zatwierdzenia, spowoduje to usunięcie ich z twojego oddziału! To rozwiązanie utrzymuje nienaruszone pliki w repozytorium w stanie nienaruszonym, ale zastępuje wszystko inne.
Matthijs P,
479
To popularne pytanie, dlatego chciałbym wyjaśnić najważniejszy komentarz tutaj. Właśnie wykonałem polecenia zgodnie z opisem w tej odpowiedzi i nie usunęło WSZYSTKICH plików lokalnych. Tylko zdalnie śledzone pliki zostały nadpisane, a każdy plik lokalny, który tu był, pozostał niezmieniony.
Red
14
na wypadek, gdybyś git reset --hard origin/branch-name
pobierał dane
97
Biorąc pod uwagę liczbę głosów pozytywnych na to pytanie i odpowiedź, myślę, że git powinien zawierać polecenie takie jakgit pull -f
Sophivorus
7
Zatwierdzenia, które nie zostały wypchnięte przed twardym resetowaniem, można odzyskać za pomocą git reflog, które wyświetla wszystkie zatwierdzenia, także te bez podstawy. Dopóki nie wyczyścisz swojej lokalnej kopii za pomocą git gc, wtedy wszystko zostanie utracone
Koen.
933

Spróbuj tego:

git reset --hard HEAD
git pull

Powinien robić, co chcesz.

Travis Reeder
źródło
16
Zrobiłem to, a niektóre lokalne pliki, które nie były już w repozytorium, pozostały na dysku.
Piotr Owsiak
26
Nie sądzę, że to prawda. powyższe spowoduje scalenie, a nie nadpisanie, o które proszono w pytaniu: „Jak zmusić git, aby je nadpisał?” Nie mam odpowiedzi, obecnie jej szukam .. w tej chwili przełączam się do gałęzi z kodem, który chcę zachować „git checkout BranchWithCodeToKeep”, następnie „git branch -D BranchToOverwrite”, a następnie w końcu „git checkout -b BranchToOverwrite”. teraz będziesz mieć dokładny kod z BranchWithCodeToKeep w gałęzi BranchToOverwrite bez konieczności wykonywania scalania.
felbus
252
zamiast łączyć za pomocą „git pull”, spróbuj git fetch --all, a następnie „git reset --hard origin / master”
Lloyd Moore
5
tak, rozwiązanie @lloydmoore zadziałało dla mnie. Przydałoby się być odpowiedzią, a nie tylko komentarzem.
Max Williams,
2
Spowoduje to zresetowanie bieżących zmian z powrotem do ostatniego ściągnięcia zatwierdzenia gałęzi. Następnie git pull scala zmiany z najnowszego oddziału. To zrobiło dokładnie to, co chciałem. Dzięki!
Codeversed
459

OSTRZEŻENIE: git cleanusuwa wszystkie nieśledzone pliki / katalogi i nie można ich cofnąć.


Czasami po prostu clean -fnie pomaga. W przypadku nieśledzonych DIRECTORIES -d również potrzebna jest opcja:

# WARNING: this can't be undone!

git reset --hard HEAD
git clean -f -d
git pull

OSTRZEŻENIE: git cleanusuwa wszystkie nieśledzone pliki / katalogi i nie można ich cofnąć.

Najpierw rozważ użycie flagi -n( --dry-run). To pokaże, co zostanie usunięte bez faktycznego usuwania:

git clean -n -f -d

Przykładowe dane wyjściowe:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
David Avsajanishvili
źródło
33
Niesamowite ... Sprawdziłem to w moim repozytorium dotfiles ... W moim katalogu domowym. Dobrze, że tak naprawdę nie miałem tam nic ważnego ...
Lauri,
7
Myślę, że opis scenariusza wyjaśnia, że ​​tak naprawdę nie chce wyrzucić treści. Raczej to, czego chce, to przestać gadać o nadpisywaniu plików. @Lauri, to nie powinno ci się przydarzyć. Niestety wydaje się, że ludzie źle odczytali istotę opisu scenariusza - patrz moja sugestia.
Jeż
19
WRESZCIE . git clean -f -d jest przydatny, gdy make clean nie wyczyści wszystkiego.
earthmeLon
7
@crizCraig, chyba że zostaną dodane.gitignore
Bleeding Fingers
5
@earthmeLon, do tego możesz chcieć git clean -dfx. W -xignoruje .gitignore. Zazwyczaj produkty kompilacji będą w .gitignore.
Paul Draper,
384

Podobnie jak Jeż, myślę, że odpowiedzi są okropne. Ale chociaż odpowiedź Jeża może być lepsza, nie sądzę, aby była tak elegancka, jak mogłaby być. Znalazłem to, używając „pobierania” i „scalania” ze zdefiniowaną strategią. Co powinno sprawić, że lokalne zmiany zostaną zachowane, o ile nie będą to jeden z plików, które próbujesz wymusić nadpisaniem.

Najpierw wykonaj zatwierdzenie swoich zmian

 git add *
 git commit -a -m "local file server commit message"

Następnie pobierz zmiany i zastąp je, jeśli wystąpi konflikt

 git fetch origin master
 git merge -s recursive -X theirs origin/master

„-X” to nazwa opcji, a „ich” to wartość tej opcji. Zdecydujesz się użyć „ich” zmian, zamiast „swoich” zmian w przypadku konfliktu.

Richard Kersey
źródło
56
To najlepsza odpowiedź, jaką do tej pory widziałem. Nie próbowałem tego, ale w przeciwieństwie do innych odpowiedzi, nie próbuje to zniszczyć wszystkich twoich nieśledzonych plików, co jest bardzo niebezpieczne z oczywistych powodów.
huyz
5
Ditto - to zadziałało dla mnie podczas bardzo dużego scalania (żądanie ściągnięcia GitHub), w którym chciałem zaakceptować wszystko oprócz tego, co miałem. Dobra odpowiedź! W moim przypadku dwie ostatnie komendy to: 1) get fetch other-repo; 2)git merge -s recursive -X theirs other-repo/master
quux00,
2
Spowoduje to zastąpienie wszelkich konfliktów z plikami repozytoriów, a nie lokalnymi, prawda?
Nathan F.
2
Najlepsza odpowiedź. Najwyższa akceptowana odpowiedź pozostawiła mnie w moim przypadku na oderwanej głowie. Wróciłem do lokalnego oddziału głównego i pobiegłemgit merge -X theirs origin/master
petergus
2
Problem z tą (doskonałą) odpowiedzią polega na tym, że dodaje ona wszystkie lokalne pliki, które czasem mogą nie być tym, czego chcesz. Możesz po prostu dodać określone pliki, które zostały pominięte. Ale najlepsze jest to, że robi to, co powinien - dodając je lokalnie. Prawdopodobnie nie potrzebujesz strategii -X ich, ponieważ są one tym samym obrazem. W rzeczywistości proponuję odrzucić to na początku, aby dowiedzieć się, czy są jakieś anomalie i dodać je, jeśli istnieją, po sprawdzeniu, że „ich” zawsze jest właściwym wyborem. Ale jestem paranoikiem.
Bob Kerns
279

Zamiast robić:

git fetch --all
git reset --hard origin/master

Radzę wykonać następujące czynności:

git fetch origin master
git reset --hard origin/master

Nie musisz pobierać wszystkich pilotów i gałęzi, jeśli chcesz zresetować do źródła / gałęzi głównej, prawda?

Johanneke
źródło
3
Twoja odpowiedź jest dokładnie tym, czego potrzebujesz dla swojego przedstawiciela. Muszę zapytać, czy to również usuwa wszystkie nieśledzone pliki?
Nicolas De Jay
5
Tak, większość moich przedstawicieli pochodzi stąd :) Spowoduje to również usunięcie wszystkich nieśledzonych plików. Coś, o czym zapomniałem i boleśnie przypomniałem zaledwie 2 dni temu ...
Johanneke
1
Zobacz komentarze do tej drugiej odpowiedzi: stackoverflow.com/a/8888015/2151700
Johanneke
Nie usunęło to moich nieśledzonych plików; czego właściwie się spodziewałbym. Czy istnieje powód, dla którego może to być dla niektórych osób, a nie dla innych?
arichards 19.04.16
Git reset nie wpływa na nieśledzone pliki. Jeśli chcesz je również usunąć, zrób to git add .wcześniejgit reset --hard
Johanneke
131

Wygląda na to, że najlepiej jest najpierw zrobić:

git clean

Aby usunąć wszystkie nieśledzone pliki, a następnie kontynuować zwykłe git pull...

Jakub Troszok
źródło
4
Próbowałem użyć „git clean”, aby rozwiązać ten sam problem, ale to nie rozwiązało. git status mówi „Twój oddział i 'origin / master' są rozbieżne, # i mają odpowiednio 2 i 9 różnych zatwierdzeń.” a git pull mówi coś podobnego do tego, co masz powyżej.
slacy
43
git clean to raczej tępy instrument, który może wyrzucić wiele rzeczy, które możesz chcieć zatrzymać. Lepiej usunąć lub zmienić nazwę plików, na które skarży się git, dopóki ściąganie się nie powiedzie.
Neil Mayhew
2
Nie sądzę, że to ogólnie działa. Czy nie ma sposobu na zrobienie zdalnie klonowania git za pomocą wymuszonego ściągania git?
Mathtick
10
@mathick:git fetch origin && git reset --hard origin/master
Arrowmaster
3
Czy git cleannajlepsza odpowiedź tutaj? Wydaje się, że usuwanie plików niekoniecznie jest tym, czego chce OP. Poprosili o „nadpisanie lokalnych plików”, a nie usunięcie.
JohnAllen
111

Uwaga, zrobienie tego spowoduje trwałe usunięcie plików, jeśli masz jakieś wpisy katalogu / * w pliku gitignore.

Niektóre odpowiedzi wydają się okropne. Straszne w tym, co się stało z @Lauri, postępując zgodnie z sugestią Davida Avsajanishvili.

Raczej (git> v1.7.6):

git stash --include-untracked
git pull

Później możesz wyczyścić historię zapasów.

Ręcznie, jeden po drugim:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

Brutalnie, od razu:

$ git stash clear

Oczywiście, jeśli chcesz wrócić do tego, co ukryłeś:

$ git stash list
...
$ git stash apply stash@{5}
Jeż
źródło
2
Nie, nie sądzę. Przechowywanie po prostu usuwa nieproszone pliki z drogi. Powyższe powoduje także przenoszenie (ukrywanie) plików, których git nie śledzi. Zapobiega to rozkładaniu plików dodanych do pilota, które nie zostały jeszcze ściągnięte na komputer - ale które utworzyłeś (!). Wszystko bez niszczenia nieprzyzwoitej pracy. Mam nadzieję, że to ma sens?
Jeż
3
Jeśli nie masz wersji 1.7.6, możesz naśladować --include-untrackedpo prostu tymczasowo - git addcałe swoje repozytorium, a następnie natychmiast je składując.
nategood
3
Zgadzam się z Jeżem. Jeśli odpowiesz tutaj na popularne odpowiedzi, z dużym prawdopodobieństwem odkryjesz, że przypadkowo zabiłeś wiele rzeczy, których tak naprawdę nie chciałeś stracić.
Guardius
1
Miałem inne nieśledzone pliki - oprócz tego, które scalanie / ściąganie chciało zastąpić, więc to rozwiązanie działało najlepiej. git stash applyprzywrócił wszystkie moje nieśledzone pliki z wyjątkiem (słusznie) tych, które scalenie już utworzył: „już istnieje, nie ma kasy”. Działał idealnie.
BigBlueHat
2
To najczystsza odpowiedź i powinna być zaakceptowana. Aby zaoszczędzić trochę pisania można wykorzystać krótki formularz: git stash -u.
ccpizza
93

To polecenie może pomóc w odrzuceniu lokalnych zmian:

git checkout <your-branch> -f

A następnie wykonaj czyszczenie (usuwa nieśledzone pliki z działającego drzewa):

git clean -f

Jeśli chcesz usunąć nieśledzone katalogi oprócz nieśledzonych plików:

git clean -fd
Vishal
źródło
Myślę, że opis scenariusza wyjaśnia, że ​​tak naprawdę nie chce wyrzucić treści. Raczej to, czego chce, to przestać gadać o nadpisywaniu plików. Zobacz moją sugestię.
Jeż
3
Chociaż ta odpowiedź może nie pasować dokładnie do opisu, wciąż uratowała mnie przed frustracją, jaką git kręci się po powrocie karetki (zdarzenie z autocrlf false). Kiedy git resetuje --hard HEAD nie pozostawia ci „zmodyfikowanych” plików, te flagi „-f” są bardzo pomocne. Wielkie dzięki.
Kellindil
88

Zamiast łączyć się z git pull, spróbuj tego:

git fetch --all

śledzony przez:

git reset --hard origin/master.

Lloyd Moore
źródło
61

Jedyne, co działało dla mnie, to:

git reset --hard HEAD~5

Spowoduje to powrót do pięciu zatwierdzeń, a następnie z

git pull

Zauważyłem, że patrząc na to, jak cofnąć scalenie Git .

Chris BIllante
źródło
To ostatecznie działało dla mnie, ponieważ
zmuszałem
Cześć, właściwie to sztuczka, work aroundale naprawdę skuteczna. Ponieważ niektóre konflikty mogą wystąpić tylko w kilku zatwierdzeniach, cofnięcie 5 zatwierdzeń sprawi, że nie wystąpią konflikty ze zdalnym kodem.
Hoang Le
54

Problem z tymi wszystkimi rozwiązaniami polega na tym, że wszystkie są albo zbyt skomplikowane, albo, jeszcze większy problem, polega na tym, że usuwają wszystkie nieśledzone pliki z serwera WWW, czego nie chcemy, ponieważ zawsze są potrzebne pliki konfiguracyjne, które są włączone serwer, a nie repozytorium Git.

Oto najczystsze rozwiązanie, którego używamy:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • Pierwsze polecenie pobiera najnowsze dane.

  • Drugie polecenie sprawdza, czy do repozytorium są dodawane jakieś pliki i usuwa te nieśledzone pliki z lokalnego repozytorium, które mogłyby powodować konflikty.

  • Trzecie polecenie sprawdza wszystkie pliki, które zostały zmodyfikowane lokalnie.

  • Wreszcie staramy się zaktualizować do najnowszej wersji, ale tym razem bez żadnych konfliktów, ponieważ nieśledzone pliki znajdujące się w repozytorium już nie istnieją, a wszystkie lokalnie zmodyfikowane pliki są już takie same jak w repozytorium.

Strahinja Kustudic
źródło
Użycie „git merge origin / master” jako ostatniego wiersza (jak powiesz w notatce) zamiast „git pull” będzie szybsze, ponieważ już ściągnąłeś jakiekolwiek zmiany z repozytorium git.
Josh
1
Tak, oczywiście git merge origin/masterbędzie szybszy i prawdopodobnie jeszcze bezpieczniejszy. Ponieważ jeśli ktoś pchnie nowe zmiany podczas usuwania plików tego skryptu (co prawdopodobnie nie nastąpi, ale możliwe), całe ściągnięcie może się nie powieść. Jedyny powód, dla którego pulltam wprowadziłem, to fakt, że ktoś może nie pracować nad gałęzią master, ale z inną gałęzią i chciałem, aby skrypt był uniwersalny.
Strahinja Kustudic
Jeśli masz lokalnie utworzone pliki, takie jak pliki opcji, włóż je .gitignore.
Sebi
52

Najpierw wypróbuj standardowy sposób:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Ostrzeżenie : powyższe polecenia mogą spowodować utratę danych / plików tylko wtedy, gdy ich nie zatwierdzisz! Jeśli nie masz pewności, wykonaj kopię zapasową na pierwszym miejscu w całym folderze repozytorium.

Następnie pociągnij ponownie.

Jeśli powyższe nie pomoże i nie obchodzi Cię nieśledzone pliki / katalogi (wykonaj kopię zapasową na wszelki wypadek), spróbuj wykonać następujące proste kroki:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Spowoduje to USUNIĘCIE wszystkich plików git (wyłącz katalog .git/, w którym masz wszystkie zatwierdzenia) i ściągniesz je ponownie.


Dlaczego git reset HEAD --hardw niektórych przypadkach może się nie powieść?

  1. Niestandardowe reguły w .gitattributes file

    Mający eol=lf reguły w .gitattributes może spowodować, że git zmodyfikuje niektóre zmiany pliku, przekształcając zakończenia linii CRLF w LF w niektórych plikach tekstowych.

    W takim przypadku należy zatwierdzić zmiany CRLF / LF (przeglądając je git status) lub spróbować: git config core.autcrlf falsetymczasowo je zignorować.

  2. Niezgodność systemu plików

    Gdy używasz systemu plików, który nie obsługuje atrybutów uprawnień. Na przykład masz dwa repozytoria, jedno w systemie plików Linux / Mac ( ext3/ hfs+), a drugie w systemie plików opartym na FAT32 / NTFS.

    Jak zauważyłeś, istnieją dwa różne rodzaje systemów plików, więc ten, który nie obsługuje uprawnień uniksowych, zasadniczo nie może zresetować uprawnień do plików w systemie, który nie obsługuje tego rodzaju uprawnień, więc bez względu na to, jak --hardspróbujesz, git zawsze wykrywaj „zmiany”.

kenorb
źródło
47

Miałem ten sam problem. Nikt nie dał mi tego rozwiązania, ale zadziałało dla mnie.

Rozwiązałem to przez:

  1. Usuń wszystkie pliki. Zostaw tylko .gitkatalog.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Teraz działa.

John John Pichler
źródło
1
To samo tutaj. Czasami działa tylko bardzo trudne rozwiązanie, zdarza się często, że tylko resetowanie i czyszczenie w jakiś sposób nie wystarczą ...
jdehaan
41

Premia:

Mówiąc o pull / fetch / merge w poprzednich odpowiedziach, chciałbym podzielić się ciekawą i produktywną sztuczką,

git pull --rebase

To powyższe polecenie jest najbardziej użytecznym poleceniem w moim życiu Git, które pozwoliło zaoszczędzić dużo czasu.

Przed wypchnięciem nowego zatwierdzenia na serwer, wypróbuj to polecenie, a ono automatycznie zsynchronizuje najnowsze zmiany na serwerze (z funkcją pobierania + scalania) i umieści zatwierdzenie na górze w dzienniku Git. Nie musisz martwić się ręcznym ściąganiem / scalaniem.

Znajdź szczegóły w Czym zajmuje się „git pull --rebase”? .

Sazzad Hissain Khan
źródło
3
W skrócie: git pull -r.
kenorb
29

Miałem podobny problem. Musiałem to zrobić:

git reset --hard HEAD
git clean -f
git pull
Ryan
źródło
6
używaj git cleanostrożnie
nategood
29

Podsumowałem inne odpowiedzi. Możesz wykonać git pullbez błędów:

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Ostrzeżenie : ten skrypt jest bardzo wydajny, więc możesz stracić zmiany.

Robert Moon
źródło
2
Spowoduje to zastąpienie zmodyfikowanych plików (plików, które były wcześniej rejestrowane) i usunie nieśledzone pliki (pliki, które nigdy nie były rejestrowane). Właśnie tego szukałem, dzięki!
styfle
3
Podejrzewam, że trzecia linia git reset --hard HEADmoże być zbędna; moja lokalna strona resetpodręcznika (2.6.3) mówi, że w drugim wierszu git reset --hard origin/master „domyślnie HEAD we wszystkich formach”.
arichards 19.04.16
2
@arichards Myślę, że twój podejrzany ma rację, ale jeśli druga linia nie zadziała (z jakiegokolwiek powodu) trzecia linia działa dobrze, aby zresetować. To rozwiązanie nie wymaga optymalizacji. Właśnie streściłem inne odpowiedzi. To wszystko. Dziękuję za Twój komentarz. :)
Robert Moon,
28

W oparciu o moje własne podobne doświadczenia, rozwiązanie oferowane przez Strahinja Kustudic powyżej jest zdecydowanie najlepsze. Jak zauważyli inni, zwykły twardy reset usunie wszystko nieśledzone pliki, które mogą zawierać wiele rzeczy, których nie chcesz usuwać, takich jak pliki konfiguracyjne. Bezpieczniejsze jest usuwanie tylko plików, które mają zostać dodane, i w związku z tym prawdopodobnie będziesz również chciał pobrać wszystkie lokalnie zmodyfikowane pliki, które mają zostać zaktualizowane.

Mając to na uwadze, zaktualizowałem skrypt Kustudica, aby to zrobić. Naprawiłem także literówkę (brakujące w oryginale).

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull
Rolf Kaiser
źródło
Użycie „git merge origin / master” jako ostatniego wiersza (jak powiesz w notatce) zamiast „git pull” będzie szybsze, ponieważ już ściągnąłeś jakiekolwiek zmiany z repozytorium git.
Josh
Konieczne jest pobranie zmodyfikowanych plików, więc działa to 100% razy. Zaktualizowałem ten skrypt dawno temu, ale tutaj też zapomniałem. Używam go również trochę inaczej niż ty. Sprawdzam pliki, które mają dowolny rodzaj modyfikacji, nie tylko M, więc działa cały czas.
Strahinja Kustudic
24

Uważam, że istnieją dwie możliwe przyczyny konfliktu, które należy rozwiązać osobno, i o ile wiem, żadna z powyższych odpowiedzi nie dotyczy obu:

  • Pliki lokalne, które nie są śledzone, muszą zostać usunięte ręcznie (bezpieczniej) lub zgodnie z sugestią w innych odpowiedziach autorstwa git clean -f -d

  • Lokalne zatwierdzenia, które nie znajdują się w oddziale zdalnym, również muszą zostać usunięte. IMO najprostszym sposobem na osiągnięcie tego jest: git reset --hard origin/master(zamień „master” na jakąkolwiek gałąź, nad którą pracujesz, i uruchom git fetch originpierwszą)

tiho
źródło
22

Łatwiejszym sposobem byłoby:

git checkout --theirs /path/to/file.extension
git pull origin master

Spowoduje to zastąpienie lokalnego pliku plikiem w git

maximus 69
źródło
21

Wygląda na to, że większość odpowiedzi tutaj dotyczy mastergałęzi; są jednak chwile, kiedy pracuję nad tą samą gałęzią funkcji w dwóch różnych miejscach i chcę, aby podstawa w jednym była odzwierciedlona w drugim, bez dużej ilości skoków przez obręcze.

Oparty na kombinacji odpowiedzi RNA i odpowiedzi torek do podobnych pytanie , mam wymyślić ten, który działa wspaniale:

git fetch
git reset --hard @{u}

Uruchom to z oddziału, a spowoduje to zresetowanie lokalnego oddziału do wersji nadrzędnej.

Można to również dobrze umieścić w git alias ( git forcepull):

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Lub w twoim .gitconfigpliku:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Cieszyć się!

JacobEvelyn
źródło
Ta odpowiedź jest również miła, ponieważ działa niezależnie od tego, w której gałęzi jesteś!
mączka z liści
19

Miałem ten sam problem iz jakiegoś powodu nawet git clean -f -dtego nie zrobiłbym. Oto dlaczego: Z jakiegoś powodu, jeśli twój plik jest ignorowany przez Git (zakładam, że za pomocą wpisu .gitignore), nadal kłopota się nadpisaniem go późniejszym ściągnięciem , ale czysty nie usunie go, chyba że dodasz -x.

Tierlieb
źródło
19

Znam dużo łatwiejszą i mniej bolesną metodę:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

Otóż ​​to!

ddmytrenko
źródło
18

Właśnie rozwiązałem to przez:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

gdzie ostatnie polecenie podaje listę lokalnych zmian. Kontynuuj modyfikowanie gałęzi „tmp”, aż będzie to akceptowalne, a następnie ponownie połącz z master:

git checkout master && git merge tmp

Następnym razem możesz prawdopodobnie poradzić sobie z tym w bardziej przejrzysty sposób, patrząc na „gałąź git stash”, chociaż skrytka może powodować problemy w pierwszych kilku próbach, więc najpierw eksperymentuj nad niekrytycznym projektem ...

Simon B.
źródło
17

Mam dziwną sytuację, że żadna git cleanlub git resetrobót. Muszę usunąć plik powodujący konflikt, git indexużywając następującego skryptu na każdym nieśledzonym pliku:

git rm [file]

Jestem w stanie dobrze pociągnąć.

Chen Zhang
źródło
16

git fetch --all && git reset --hard origin/master && git pull

Suge
źródło
14

Pomimo pierwotnego pytania, najlepsze odpowiedzi mogą powodować problemy dla osób, które mają podobny problem, ale nie chcą stracić swoich lokalnych plików. Na przykład zobacz komentarze Al-Punk i crizCraig.

Następująca wersja zatwierdza lokalne zmiany w gałęzi tymczasowej ( tmp), sprawdza oryginalną gałąź (którą zakładam, że jest master) i łączy aktualizacje. Możesz to zrobić za pomocą stash, ale stwierdziłem, że zwykle łatwiej jest po prostu użyć metody rozgałęzienia / scalenia.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

git fetch origin master
git merge -s recursive -X theirs origin master

gdzie zakładamy, że drugie repozytorium znajduje się origin master.

Snowcrash
źródło
13

Te cztery polecenia działają dla mnie.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Aby sprawdzić / pociągnąć po wykonaniu tych poleceń

git pull origin master

Próbowałem dużo, ale w końcu udało mi się uzyskać te polecenia.

vishesh chandra
źródło
2
„git branch -D master” usuń gałąź. więc bądź ostrożny z tym. Wolę używać „git checkout origin / master -b <nowa nazwa oddziału>”, które tworzą nową gałąź o nowej nazwie i gotowe 3,4 wiersze. Zalecane jest również użycie „git clean -f”.
Chand Priyankara,
13

Po prostu zrób

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

Dzięki temu unikniesz wszystkich niepożądanych efektów ubocznych, takich jak usuwanie plików lub katalogów, które chcesz zachować itp.

użytkownik2696128
źródło
12

Zresetuj indeks i nagłówek do origin/master, ale nie resetuj działającego drzewa:

git reset origin/master

źródło
Osobiście uważam, że jest to najbardziej przydatne. Następnie utrzymuje działające drzewo, aby można było je ponownie sprawdzić. W przypadku mojego problemu usunąłem te same pliki, co podczas dodawania, więc utknąłem. Dziwne, wiem.
Jason Sebring
12

Wymagania:

  1. Śledź lokalne zmiany, aby nikt ich nie zgubił.
  2. Dopasuj lokalne repozytorium do zdalnego źródłowego repozytorium.

Rozwiązanie:

  1. Ukryj lokalne zmiany.
  2. Fetch z czysty z plików i katalogów ignorując .gitignore i twardy reset do pochodzenia .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
vezenkov
źródło