git pull zachowując lokalne zmiany

135

Jak mogę bezpiecznie zaktualizować (wyciągnąć) projekt git, zachowując określone pliki nietknięte, nawet jeśli wystąpią zewnętrzne zmiany?

myrepo / config / config.php

Czy jest sposób, nawet jeśli ten plik był zmieniany zdalnie, kiedy git pull, wszystko inne jest aktualizowane, ale ten plik jest niezmieniony (nawet nie scalony)?

PS. Muszę zrobić to, o co proszę, ponieważ piszę tylko skrypty wdrażania oparte na git. Nie mogę zmienić plików konfiguracyjnych na szablony.

potrzebuję więc sposobu na pisanie skryptów aktualizacyjnych, które nie tracą tego, co zostało lokalnie zmienione. Liczyłem na coś tak prostego, jak:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

następnie git pull

Johnny Everson
źródło
Czy zmiany są zatwierdzone config.php?
Mark Longair
To nie jest popełnione. Wolałbym nie musieć
Johnny Everson
@JhonnyEverson: To ta sama ogólna klasa problemów (masz plik konfiguracyjny i nie chcesz zatwierdzać określonych ustawień, ale struktura pliku konfiguracyjnego musi być śledzona.)
Daenyth

Odpowiedzi:

254

Istnieje proste rozwiązanie oparte na skrytce Gita. Schowaj wszystko, co zmieniłeś, wyciągnij wszystkie nowe rzeczy, zastosuj swoją skrytkę.

git stash
git pull
git stash pop

W przypadku stash pop mogą wystąpić konflikty. W przypadku, gdy opisujesz, faktycznie wystąpiłby konflikt o config.php. Ale rozwiązanie konfliktu jest łatwe, ponieważ wiesz, że to, co wkładasz do skrytki, jest tym, czego chcesz. Więc zrób to:

git checkout --theirs -- config.php
GoZoner
źródło
5
że polecenie git checkout - ich polecenie jest bardzo mylące. Raz zrobił to, co chciałem, a innym razem coś naprawdę złego. Masz dobrą dokumentację na ten temat?
Milimetryczny
3
Tak, czasami słowa „ich” i „nasze” mogą być mylące. W git merge„naszym” jest to, co aktualnie znajduje się w katalogu roboczym. Ale dla git rebase(lub git rebase -onto) znaczenie można zamienić.
GoZoner,
1
git stash , git pull , git stash apply Możesz upuścić skrytkę za pomocą: git stash dropPo pomyślnym scaleniu zmian
BeingSuman
13
Rzecz w git polega na tym, że musisz zrozumieć, co zrobi. Inną rzeczą w przypadku git jest to, że nawet inteligentnym ludziom często bardzo trudno jest zrozumieć, co zrobi git.
Brad Thomas,
1
Powinieneś sprawdzić, czy naprawdę jest coś do ukrycia. W przeciwnym razie możesz umieścić zachowane zmiany z wcześniejszego pliku git stash.
Jörn Reimerdes,
15

Jeśli masz w repozytorium plik, który powinien być dostosowany przez większość ściągaczy, zmień nazwę pliku na podobną config.php.templatei dodaj config.phpdo .gitignore.

KurzedMetal
źródło
5
sprawdź również tę odpowiedź , możesz użyć, .gitattributesaby zawsze zachować zmiany podczas scalania.
KurzedMetal
To bardziej przypomina to, czego potrzebowałem. Szablon jest eleganckim rozwiązaniem, ale obawiam się, że nie mogę go użyć, ponieważ piszę tylko skrypty wdrażania.
Johnny Everson
6

Aktualizacja: to dosłownie odpowiada na zadane pytanie, ale myślę, że odpowiedź KurzedMetal jest naprawdę tym, czego chcesz.

Przy założeniu, że:

  1. Jesteś na gałęzi master
  2. Upstream oddział jest masterworigin
  3. Nie masz niezatwierdzonych zmian

.... mógłbyś:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

Możesz utworzyć dla tego alias, jeśli chcesz to robić często. Zwróć uwagę, że jeśli masz niezatwierdzone zmiany w programie config/config.php, spowoduje to ich odrzucenie.

Mark Longair
źródło
4

Możemy również spróbować git pull z rebase

git pull --rebase origin dev
Bhavesh Maniya
źródło
1

Aby odpowiedzieć na pytanie: jeśli chcesz wykluczyć niektóre pliki z kasy, możesz użyć sparse-checkout

1) W .git/info/sparse-checkout, określ, co chcesz zatrzymać. Tutaj chcemy all (*) ale (zwróć uwagę na wykrzyknik) config.php:

 /*
 !/config.php

2) Powiedz gitowi, że chcesz wziąć pod uwagę rzadkie płatności

 git config core.sparseCheckout true

3) Jeśli masz już ten plik lokalnie, zrób to, co robi git przy rzadkim pobieraniu (powiedz mu, że musi wykluczyć ten plik, ustawiając na nim flagę "skip-worktree")

git update-index --skip-worktree config.php

4) Korzystaj z repozytorium, w którym plik config.php należy do Ciebie - niezależnie od zmian w repozytorium.


Należy pamiętać, że wartości konfiguracyjne NIE POWINNY znajdować się w kontroli źródła:

  • Jest to potencjalne naruszenie bezpieczeństwa
  • Powoduje problemy takie jak ten podczas wdrażania

Oznacza to, że MUSISZ je wykluczyć (umieścić je w .gitignore przed pierwszym zatwierdzeniem) i utworzyć odpowiedni plik w każdej instancji, w której pobierasz swoją aplikację (kopiując i dostosowując plik „szablonu”)

Zauważ, że gdy plik zostanie przejęty przez git, .gitignore nie przyniesie żadnego efektu.

Biorąc pod uwagę, że gdy plik jest pod kontrolą źródła, masz tylko dwie możliwości (): - ponownie bazuj całą historię, aby usunąć plik (za pomocą git filter-branch) - utwórz zatwierdzenie, które usunie plik. To jak staczanie przegranej bitwy, ale cóż, czasami trzeba z tym żyć.

Pierre-Olivier Vares
źródło
0

Uwzględnij ich lokalne niezatwierdzone zmiany i unikaj konfliktów scalania podczas ciągnięcia.

git stash save
git pull
git stash pop

refer - https://happygitwithr.com/pull-tricky.html

Ujjwal Roy
źródło