Typowy scenariusz, kiedy tworzę, jest taki, że baza kodu będzie zawierała kilka plików konfiguracyjnych, które wymagają ustawień specyficznych dla komputera. Te pliki zostaną wpisane do Gita, a inni programiści zawsze przypadkowo sprawdzą je z powrotem i zepsują konfigurację innej osoby.
Prostym rozwiązaniem byłoby po prostu nie wpisywanie ich do Gita, a nawet dodanie dla nich wpisu .gitignore. Jednak uważam, że o wiele bardziej eleganckie jest posiadanie pewnych rozsądnych ustawień domyślnych w pliku, które programista może zmodyfikować zgodnie ze swoimi potrzebami.
Czy istnieje elegancki sposób, aby Git ładnie współpracował z takimi plikami? Chciałbym móc zmodyfikować plik konfiguracyjny specyficzny dla komputera, a następnie uruchomić „git commit -a” bez wpisywania tego pliku.
źródło
Odpowiedzi:
Niech twój program przeczyta parę plików konfiguracyjnych dla swoich ustawień. Najpierw powinien odczytać
config.defaults
plik, który miałby znaleźć się w repozytorium. Następnie powinien odczytaćconfig.local
plik, który powinien być wymieniony w.gitignore
W takim układzie nowe ustawienia pojawiają się w pliku ustawień domyślnych i zaczynają obowiązywać zaraz po ich zaktualizowaniu. Będą się różnić w poszczególnych systemach tylko wtedy, gdy zostaną zastąpione.
Jako odmianę tego, możesz mieć tylko ogólny
config
plik, który wysyłasz w ramach kontroli wersji i sprawi, że będzie wykonywał coś w rodzajuinclude config.local
wprowadzenia wartości specyficznych dla maszyny. Wprowadza to bardziej ogólny mechanizm (w przeciwieństwie do zasad) w kodzie, a tym samym umożliwia bardziej skomplikowane konfiguracje (jeśli jest to pożądane w przypadku aplikacji). Popularnym rozszerzeniem tego, widzianym w wielu programach open source na dużą skalę, jest toinclude conf.d
, które odczytuje konfigurację ze wszystkich plików w katalogu.Zobacz także moją odpowiedź na podobne pytanie.
źródło
Możesz spróbować
git update-index --skip-worktree filename
. To każe gitowi udawać, że lokalne zmiany nazwy pliku nie istnieją, więcgit commit -a
je zignoruje. Ma tę dodatkową zaletę, że jest również odpornygit reset --hard
, więc przypadkowo nie utracisz lokalnych zmian. Ponadto automatyczne scalanie zakończy się niepowodzeniem, jeśli plik zostanie zmieniony nadrzędnie (chyba że kopia katalogu roboczego pasuje do kopii indeksu, w którym to przypadku zostanie automatycznie zaktualizowana). Wadą jest to, że polecenie musi być uruchamiane na wszystkich zaangażowanych komputerach i trudno jest to zrobić automatycznie. Zobacz także,git update-index --assume-unchanged
aby uzyskać nieco inną wersję tego pomysłu. Szczegóły dotyczące obu można znaleźć pod adresemgit help update-index
.źródło
--skip-worktree
w tym przypadku chcesz .Innym podejściem jest zachowanie lokalnych zmian we wspólnych plikach konfiguracyjnych w innej gałęzi prywatnej. Robię to dla niektórych projektów, które wymagają kilku lokalnych zmian. Ta technika może nie mieć zastosowania we wszystkich sytuacjach, ale w niektórych przypadkach działa.
Najpierw tworzę nową gałąź na podstawie gałęzi master (w tym konkretnym przypadku używam git-svn, więc muszę zatwierdzić od mastera, ale nie jest to szczególnie ważne):
Teraz zmodyfikuj pliki konfiguracyjne zgodnie z potrzebami i zatwierdź. Zwykle umieszczam w komunikacie o zmianach coś charakterystycznego, na przykład „NOCOMMIT” lub „PRIVATE” (będzie to przydatne później). W tym momencie możesz pracować na swojej prywatnej gałęzi, używając własnego pliku konfiguracyjnego.
Jeśli chcesz popchnąć swoją pracę z powrotem w górę, wybierz każdą zmianę ze swojej
work
gałęzi do mastera. Mam skrypt, który pomoże mi to zrobić, który wygląda mniej więcej tak:To pierwsze sprawdzenie, czy jestem w
master
oddziale (kontrola poczytalności). Następnie wyświetla listę wszystkich zatwierdzeńwork
, odfiltrowuje te, które wspominają o słowie kluczowym NOCOMMIT, odwraca kolejność i ostatecznie wybiera każde zatwierdzenie (teraz od najstarszego) domaster
.Wreszcie, po wprowadzeniu zmian w master upstream, przełączam się z powrotem na
work
i rebase:Git ponownie zastosuje każde z zatwierdzeń w
work
gałęzi, skutecznie pomijając te, które zostały już zastosowane podczasmaster
wybierania wiśniowego. Powinieneś pozostać tylko z lokalnymi zatwierdzeniami NOCOMMIT.Ta technika sprawia, że proces wypychania jest nieco bardziej czasochłonny, ale rozwiązała problem, więc pomyślałem, że się nim podzielę.
źródło
git commit -a
bez troski po świecie?git rebase --onto
igit fetch
zrobić to samoJedną z możliwości jest posiadanie rzeczywistych plików w swoim .gitignore, ale wpisanie domyślnych konfiguracji z innym rozszerzeniem. Typowym przykładem aplikacji Railsowej byłby plik config / database.yml. Sprawdzilibyśmy w config / database.yml.sample, a każdy programista utworzył swój własny plik config / database.yml, który jest już .gitignored.
źródło
Sprawdź domyślną konfigurację z innym rozszerzeniem (powiedzmy .default), użyj dowiązania symbolicznego do domyślnego dowiązania symbolicznego do właściwej lokalizacji, dodaj poprawną lokalizację do .gitignore i dodaj wszystko inne związane z konfiguracją do .gitignore (więc jedyne rzeczą, która jest wpisywana, jest config.default).
Dodatkowo napisz skrypt szybkiej instalacji, który ustawi dowiązania symboliczne dla całej aplikacji.
Podobne podejście zastosowaliśmy w poprzedniej firmie. Skrypt instalacyjny automatycznie wykrył, w jakim środowisku działasz (piaskownica, programowanie, kontrola jakości, produkcja) i automatycznie zrobiłby właściwą rzecz. Gdybyś miał plik config.sandbox i był uruchomiony z piaskownicy, połączyłby go (w przeciwnym razie po prostu połączyłby plik .defaults). Typową procedurą było skopiowanie .defaults i zmiana ustawień w razie potrzeby.
Pisanie skryptu instalacyjnego jest łatwiejsze, niż można by sobie wyobrazić, i zapewnia dużą elastyczność.
źródło
Zgadzam się z najlepszą odpowiedzią, ale chciałbym też coś dodać. Używam skryptu ANT do usuwania i modyfikowania plików z repozytorium GIT, więc jestem pewien, że żadne pliki produkcyjne nie zostaną nadpisane. W ANT jest fajna opcja modyfikacji plików właściwości java. Oznacza to umieszczenie lokalnych zmiennych testowych w pliku właściwości w stylu Java i dodanie kodu do jego przetworzenia, ale daje to możliwość zautomatyzowania budowania witryny przed wysłaniem jej na serwer FTP. Zwykle informacje o produkcji należy umieścić w pliku site.default.properties i pozwolić ANT zarządzać ustawieniami. Twoje ustawienia lokalne będą znajdować się w site.local.properties.
następnie użyj go:
Twoja site.default.properties wyglądałaby następująco:
a Twoja witryna site.local.properties będzie wyglądać (zwróć uwagę na różnice w środowisku i włączonych modułach):
Oraz instrukcje ANT: ($ d {deploy} to katalog docelowy wdrożenia)
źródło
Obecnie (2019) używam zmiennych ENV np. W pythonie / django, można też dodawać do nich wartości domyślne. W kontekście dockera mogę zapisać zmienne ENV w pliku docker-compose.yml lub w dodatkowym pliku, który jest ignorowany w kontroli wersji.
źródło
Najprostszym rozwiązaniem jest edycja pliku do wartości domyślnych, zatwierdzenie go, a następnie dodanie do pliku
.gitignore
. W ten sposób programiści nie popełnią tego przypadkowo podczas wykonywaniagit commit -a
, ale nadal mogą to zrobić w (prawdopodobnie rzadkim) przypadku, w którym chcesz zmienić ustawienia domyślne za pomocągit add --force
.Jednak posiadanie pliku konfiguracyjnego
.default
i.local
jest ostatecznie najlepszym rozwiązaniem, ponieważ umożliwia to każdemu, kto ma konfigurację specyficzną dla komputera, zmianę ustawień domyślnych bez konieczności przerywania własnej konfiguracji.źródło
.gitignore
późniejszych, zmiany są nadal śledzone.Robię to tak, jak jest to zalecane tutaj z domyślnymi i lokalnymi plikami konfiguracyjnymi. Aby zarządzać moimi lokalnymi plikami konfiguracyjnymi, które są w projektach
.gitignore
, utworzyłem repozytorium git~/settings
. Tam zarządzam wszystkimi moimi ustawieniami lokalnymi ze wszystkich projektów. Utworzyć, na przykład folderproject1
w~/settings
i umieścić wszystkie rzeczy lokalną config dla tego projektu do niego. Następnie możesz dowiązać symbolicznie te pliki / folder do swojegoproject1
.Dzięki takiemu podejściu możesz śledzić lokalne pliki konfiguracyjne i nie umieszczać ich w normalnym repozytorium kodu źródłowego.
źródło
Opierając się na odpowiedzi @Greg Hewgill, możesz dodać określone zatwierdzenie z lokalnymi zmianami i oznaczyć je jako zmianę lokalną:
Następnie przejdź do dodawania zatwierdzeń funkcji. Po zakończeniu pracy możesz scalić tę gałąź z powrotem do mastera bez zatwierdzania zmiany lokalnej, wykonując następujące czynności:
Te polecenia:
1) Przebuduj gałąź funkcji do mastera, ignorując zatwierdzenie zmiany lokalnej. 2) Przewiń do przodu master bez opuszczania gałęzi funkcji 3) Dodaj zatwierdzenie zmiany lokalnej z powrotem na górę gałęzi funkcji, abyś mógł kontynuować pracę nad nią. Możesz to zrobić w dowolnej innej branży, w której chcesz kontynuować pracę. 4) Zresetuj tag zmiany lokalnej do tego wybranego zatwierdzenia, abyśmy mogli użyć go
rebase --onto
ponownie w ten sam sposób.Nie ma to na celu zastąpienia zaakceptowanej odpowiedzi jako najlepszego rozwiązania ogólnego, ale jako sposób nieszablonowego myślenia o problemie. Zasadniczo unikasz przypadkowego łączenia lokalnych zmian z wzorcem, zmieniając tylko bazę od
localchange
dofeature
i przewijając do przodu .źródło