Pytanie Jak wymusić "git pull", aby nadpisać lokalne pliki?


Jak wymusić nadpisanie lokalnych plików na git pull?

Scenariusz jest następujący:

  • Członek zespołu modyfikuje szablony strony internetowej, nad którą pracujemy
  • Dodają niektóre obrazy do katalogu images (ale zapominają dodać je pod kontrolą źródła)
  • Wysyłają obrazy pocztą, później, do mnie
  • Dodaję obrazy pod kontrolą kodu źródłowego i przesyłaję je do GitHub razem z innymi zmianami
  • Nie mogą pobierać aktualizacji z GitHub, ponieważ Git nie chce nadpisywać swoich plików.

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

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge

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


5217
2017-07-14 14:58


pochodzenie


każdy czytający to, kto myśli, że może stracić pliki, znajduję się w tej pozycji i znalazłem bufor Sublime Text, który mnie uratował - jeśli pracuję nad czymś, to przypadkowo usuń wszystko, próbując rozwiązać podobny problem lub używając odpowiedź na to pytanie i otwarte pliki w Sublime (co jest sporą szansą), to pliki nadal będą tam Sublime, albo tam, albo w historii cofania - Toni Leigh
git reset --hard origin/branch_to_overwrite - Andrew Atkinson


Odpowiedzi:


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

Jeśli masz jakieś pliki, które są nie śledzone przez Git (np. przesłane treści użytkownika), pliki te nie zostaną zmienione.


Myślę, że to jest właściwa droga:

git fetch --all

Następnie masz dwie opcje:

git reset --hard origin/master

LUB Jeśli jesteś w jakimś innym oddziale:

git reset --hard origin/<branch_name>

Wyjaśnienie:

git fetch pobiera najnowszą wersję z komputera zdalnego bez próby scalania lub rebase niczego.

A później git reset resetuje gałąź główną do właśnie pobranej. The --hard opcja zmienia wszystkie pliki w drzewie roboczym, aby pasowały do ​​plików w origin/master


Utrzymuj bieżące lokalne zatwierdzenia

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

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

Następnie wszystkie stare commity będą przechowywane new-branch-to-save-current-commits.

Niezatwierdzone zmiany

Niezatwierdzone zmiany (nawet wystawiane) zostaną jednak utracone. Upewnij się, że przechowujesz i zatwierdzasz wszystko, czego potrzebujesz. Do tego możesz uruchomić następujące:

git stash

A następnie ponownie zastosować te niezatwierdzone zmiany:

git stash pop

7301
2018-01-17 00:02



Uważaj! Jeśli posiadasz lokalne, niezałamane zatwierdzenia, usuniesz je z oddziału! To rozwiązanie powoduje, że nieprzetworzone pliki nie są przechowywane w repozytorium, ale zastępują wszystko inne. - Matthijs P
To popularne pytanie, dlatego chciałbym wyjaśnić tutaj najważniejszy komentarz. Właśnie wykonałem polecenia opisane w tej odpowiedzi i nie usunięto WSZYSTKICH lokalnych plików. Tylko zdalnie śledzone pliki zostały nadpisane, a każdy lokalny plik, który tu był, pozostał nietknięty. - Red
To działało dla mnie, a moje lokalne pliki NIE zostały usunięte. - Tastybrownies
w przypadku, gdy ciągniesz z repozytorium, które ma swoją nazwę oddziału zdalnego inną niż "master", użyj git reset --hard origin/branch-name - Nerrve
Biorąc pod uwagę ilość przegranych na to pytanie i odpowiedź, myślę, że git powinien zawierać takie polecenie, jak git pull -f - Sophivorus


Spróbuj tego:

git reset --hard HEAD
git pull

Powinno robić to, co chcesz.


761
2018-05-09 19:45



Zrobiłem to, a niektóre pliki lokalne, które nie były już w repozytorium, pozostały na dysku. - Piotr Owsiak
Nie sądzę, że to jest poprawne. powyższe spowoduje scalenie, a nie nadpisanie, które było wymagane w pytaniu: "Jak zmusić gita, aby je zastąpił?" Nie mam odpowiedzi, aktualnie szukam jej. W tym momencie przełączam się na gałąź z kodem, który chcę zachować "git checkout BranchWithCodeToKeep", następnie wykonaj "git branch -D BranchToOverwrite", a następnie w końcu "git checkout -b BranchToOverwrite". teraz będziesz mieć dokładny kod z BranchWithCodeToKeep na gałęzi BranchToOverwrite bez konieczności przeprowadzenia scalenia. - felbus
zamiast łączenia za pomocą "git pull", spróbuj git fetch - all, a następnie "git reset --hard origin / master" - Lloyd Moore
Tak, rozwiązanie @lloydmoore działało dla mnie. Może to być odpowiedź, a nie tylko komentarz. - Max Williams
Spowoduje to zresetowanie bieżących zmian z powrotem do ostatniego wyciągnięcia gałęzi. Następnie git pull scala zmiany z najnowszego oddziału. Zrobiłem dokładnie to, co chciałem. Dzięki! - Codeversed


OSTRZEŻENIE: git clean usuwa wszystkie niepotane pliki / katalogi i nie można tego cofnąć.


Czasami po prostu clean -f nie pomaga. Jeśli masz niepoprawione DIRECTORIES, opcja -d również potrzebowała:

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

OSTRZEŻENIE: git clean usuwa wszystkie niepotane pliki / katalogi i nie można tego cofnąć.


381
2018-03-19 09:10



Wspaniale ... Zrobiłem to przeciwko repozytorium dotfiles ... W moim katalogu domowym. Dobrze, że tak naprawdę nie miałem nic ważnego ... - Lauri
Myślę, że opis scenariusza jasno pokazuje, że tak naprawdę nie chce wyrzucać treści. Raczej to, czego chce, to powstrzymać gitarzystę od nadpisywania plików. @Lauri, to nie powinno ci się przytrafić. Niestety ludzie błędnie odczytali istotę opisu scenariusza - zobacz moją sugestię. - Hedgehog
WRESZCIE. git clean -f -d jest przydatny, gdy make clean nie wyczyści wszystkiego. - earthmeLon
@crizCraig, chyba że zostaną dodane .gitignore - Bleeding Fingers
@earthmeLon, ponieważ możesz tego chcieć git clean -dfx. The -x ignoruje .gitignore. Zazwyczaj twoje produkty do budowania będą w .gitignore. - Paul Draper


Podobnie jak Jeż, myślę, że odpowiedzi są straszne. Ale chociaż odpowiedź Jeża może być lepsza, nie sądzę, by była tak elegancka, jak to tylko możliwe. Sposób, w jaki to zrobiłem, polega na "pobieraniu" i "scalaniu" ze zdefiniowaną strategią. Co powinno sprawić, że twoje lokalne zmiany zostaną zachowane, o ile nie są one jednym 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 nadpisz w przypadku konfliktu

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

"-X" jest nazwą opcji, a "ich" jest wartością dla tej opcji. W przypadku konfliktu wybierasz "swoje" zmiany zamiast "swoich" zmian.


335
2018-04-11 20:13



To najlepsza odpowiedź, jaką do tej pory widziałem. Nie próbowałem tego, ale w przeciwieństwie do innych odpowiedzi, to nie próbuje odrzucić wszystkich niepotkanych plików, co jest bardzo niebezpieczne z oczywistych powodów. - huyz
Ditto - to działało dla mnie, gdy robiłem bardzo duże połączenie (żądanie ściągania GitHub), w którym chciałem zaakceptować to wszystko na podstawie 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
Pytanie: Co to jest -X? Co to jest "ich"? - AlxVallejo
To spowoduje nadpisanie konfliktów z plikami repozytoriów, a nie lokalnymi, prawda? - Nathan Fiscaletti
"-X" jest nazwą opcji, a "ich" jest wartością dla tej opcji. W przypadku konfliktu wybierasz "swoje" zmiany zamiast "swoich" zmian. - Richard Kersey


Zamiast robić:

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

Radziłbym wykonać następujące czynności:

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

Nie musisz pobierać wszystkich pilotów i oddziałów, jeśli chcesz zresetować system do gałęzi pochodzenia / master?


237
2018-04-26 13:48



Twoja odpowiedź jest właśnie tym, czego potrzebujesz dla swojego przedstawiciela. Muszę zapytać, czy to też usuwa wszystkie nieśledzone pliki? - Nicolas De Jay
Tak, większość mojego przedstawiciela pochodzi stąd :) Spowoduje to również usunięcie wszystkich nieśledzonych plików. Coś, o czym zapomniałem i boleśnie przypomniało mi się zaledwie 2 dni temu ... - Johanneke
Zobacz komentarze do tej drugiej odpowiedzi: stackoverflow.com/a/8888015/2151700 - Johanneke
To nie usunęło moich nieśledzonych plików; co jest właściwie tym, czego bym się spodziewał. Czy jest jakiś powód dla niektórych ludzi, a nie dla innych? - arichards
Utracone pliki nie są afektowane4 przez reset git. Jeśli chcesz je również usunąć, zrób to git add . najpierw, wcześniej git reset --hard - Johanneke


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

git clean

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


122
2017-07-14 15:16



Próbowałem użyć "git clean", aby rozwiązać ten sam problem, ale go nie rozwiązałem. git status mówi "Twoja gałąź i" origin / master "rozdzieliły się, # i mają odpowiednio 2 i 9 różnych zatwierdzeń." i git pull mówi coś podobnego do tego, co masz powyżej. - slacy
git-clean to dość tępy instrument i może wyrzucić wiele rzeczy, które możesz chcieć zachować. Lepiej usunąć lub zmienić nazwy plików, na które git narzeka, dopóki ciągnie się sukcesem. - Neil Mayhew
Nie sądzę, że to działa w ogóle. Czy nie ma sposobu, aby zrobić w zasadzie demona git za pomocą wymuszonego git pull? - mathtick
@mathick: git fetch origin && git reset --hard origin/master - Arrowmaster
Jest git clean najlepsza odpowiedź tutaj? Wygląda na to, że usunięcie plików niekoniecznie jest tym, co chce OP. Poprosili o "nadpisanie plików lokalnych", a nie o usunięcie. - JohnAllen


Ostrzeżenie, spowoduje to trwałe usunięcie plików, jeśli posiadasz jakiekolwiek wpisy katalogu / * w pliku gitignore.

Niektóre odpowiedzi wydają się straszne. Okropne w sensie tego, co stało się z @Lauri, idąc za sugestią Davida Avsajanishvili.

Raczej (git> v1.7.6):

git stash --include-untracked
git pull

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

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, wszystko na raz:

$ git stash clear

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

$ git stash list
...
$ git stash apply stash@{5}

97
2018-02-11 23:00



Nie, nie sądzę. Przechowywanie po prostu przenosi niezatwierdzone pliki z drogi. Powyższe również przenosi (skrytki) pliki, których git nie śledzi. Zapobiega to usunięciu plików, które zostały dodane do pilota, które jeszcze nie zostały rozebrane na twój komputer - ale które zostały utworzone (!). Wszystko bez niszczenia niezaangażowanej pracy. Mam nadzieję, że ma to sens? - Hedgehog
Jeśli nie masz wersji 1.7.6, możesz naśladować --include-untracked po prostu tymczasowo git add-własne repozytorium, a następnie natychmiast je przechowuje. - nategood
Zgadzam się z Jeżem. Jeśli znajdziesz tu popularne odpowiedzi, najprawdopodobniej odkryjesz, że zabiłeś nieumyślnie wiele rzeczy, których tak naprawdę nie chciałeś stracić. - Guardius
Miałem inne nieśledzone pliki - oprócz tego, którego scalanie / przyciąganie chciało nadpisać, więc to rozwiązanie działało najlepiej. git stash apply przywróciłem wszystkie moje niepotwierdzone pliki z wyjątkiem (słusznie) tych, które zostały już stworzone: "już istnieje, nie ma kasy". Działa doskonale. - BigBlueHat
To najczystsza odpowiedź i powinna być zaakceptowana. Aby zapisać niektóre pisanie, możesz użyć krótkiego formularza: git stash -u. - ccpizza