Jak mogę sprawić, by git ignorował przyszłe zmiany w pliku?

149

Utworzyłem domyślną wersję pliku zawartego w repozytorium git. Ważne jest, aby gdy ktoś sklonował repozytorium, otrzymał kopię tego pliku. Chciałbym jednak ustawić git tak, aby później ignorował zmiany w tym pliku. .gitignoredziała tylko na nieśledzonych plikach.

Moją motywacją jest to, że ten plik zawiera informacje specyficzne dla maszyny. Chciałbym podać wartości domyślne, jednocześnie pozwalając ludziom na dokonywanie lokalnych zmian, które nie zostaną wypchnięte z powrotem do repozytorium pochodzenia, tworząc konflikty scalania, gdy pobieramy nowe zmiany.

Generalnie jesteśmy dość leniwi i git add .dużo używamy , więc jestem prawie pewien, że jeśli nie mogę powiedzieć gitowi, aby zignorował ten plik, zmiany w nim zostaną zatwierdzone i wypchnięte.

Podsumowując,

  1. Chciałbym utworzyć plik, nazwać go, default_values.txtktóry jest dodawany do mojego repozytorium git i jest uwzględniany, gdy ktoś sklonuje to repozytorium.
  2. git add .nie powinien dodawać default_values.txtdo zatwierdzenia.
  3. To zachowanie należy przekazać do wszystkich klonów repozytorium.
Marc
źródło
2
Czy możesz skorzystać z haków git, aby mieć punkt zaczepienia przed zatwierdzeniem, który przerywałby zatwierdzenie, jeśli zmodyfikowany plik to default_values.txt (powiedzmy)?
sateesh
2
Puryści Git powiedzieliby, że nie bądź leniwy i prawidłowo korzystaj z obszaru przejściowego, do tego właśnie służy.
Xint0
1
Puryści Git powiedzieliby, że używają smudge / clean scripts. To najbardziej łatwe w utrzymaniu rozwiązanie.
Adam Dymitruk
1
Xint0: prawda. ale jak zapobiec przypadkowemu zameldowaniu się innym osobom?
Alan,
możliwy duplikat
Committing

Odpowiedzi:

125

Jak wielu innych wspomniało, dobrym nowoczesnym rozwiązaniem jest:

git update-index --skip-worktree default_values.txt

To zignoruje zmiany w tym pliku, zarówno lokalne, jak i nadrzędne, dopóki nie zdecydujesz się na nie ponownie za pomocą:

git update-index --no-skip-worktree default_values.txt

Możesz uzyskać listę plików oznaczonych jako pominięte:

git ls-files -v . | grep ^S

Zauważ, że w przeciwieństwie do tego --skip-worktree, --assume-unchangedstatus zostanie utracony po ściągnięciu zmiany nadrzędnej.

nastrój
źródło
2
Jeśli ktoś inny ściąga repozytorium i edytuje plik, czy zmiany w jego katalogu są ignorowane? Mam nadzieję, że będą musieli napisać, --no-skip-worktreeaby dodać zmiany.
neaumusic
4
To, co się dzieje z ich zmianami, jest przez nich kontrolowane. Innymi słowy, musieliby ustawić opcję skip-workktree dla pliku w swoim repozytorium, gdyby nie chcieli, aby ich zmiany zostały przesłane. Jeśli jest to plik, który ma być wysłany do wszystkich, a następnie wszystkie kolejne zmiany zostaną zignorowane, każdy będzie musiał postępować zgodnie z tymi samymi instrukcjami.
boom nastrojowy
3
Zwróć uwagę, że może być konieczne cofnięcie --skip-worktreestatusu pliku przed przełączeniem gałęzi, jeśli ten sam plik jest śledzony w innej gałęzi.
moodboom
3
hmm, to działa ... po dokonaniu jakiejś zmiany w pliku nie było to pokazane git status, ale jak próbowałem się wymeldować do innego oddziału, mam error: Your local changes to the following files would be overwritten by checkout: nawet -f nie pomagaerror: Entry 'wix-stores-merchant-app/demo/credentials.js' not uptodate. Cannot merge.
ykravv
3
Mam te aliasy do git ignorei git unignore.
Michael
49

To, czego szukasz, to git update-index --assume-unchanged default_values.txt.

Więcej informacji można znaleźć w dokumentacji: http://www.kernel.org/pub/software/scm/git/docs/git-update-index.html

tamasd
źródło
11
to nie działa. chociaż sprawia, że ​​git dodaje. zignoruj ​​plik w lokalnej gałęzi, klon archiwum nie będzie miał takiego zachowania (jeśli zmienisz default_values.txt w sklonowanym archiwum, zostanie on dodany do zatwierdzenia za pomocą "git add.")
Marc
6
Tak, ponieważ ustawiasz go tylko dla lokalnego repozytorium. Nie możesz przepychać tego rodzaju informacji.
tamasd
8
@Indradhanush - to rozwiązanie nie spełnia kryterium 3 - „zachowanie powinno zostać przekazane do wszystkich klonów repozytorium” - dlatego go nie zaakceptowałem. To nie znaczy, że to nie jest dobra odpowiedź.
Marc
Nigdy nie zauważyłem trzeciego kryterium. Ponieważ tego nie szukałem. :)
Indradhanush Gupta
3
W przypadku lokalnych plików konfiguracyjnych z prywatnymi ustawieniami aplikacji prawdopodobnie zechcesz użyć skip-worktreezamiast assume-unchangedwięcej informacji stackoverflow.com/questions/13630849/ ...
Aaron Hoffman,
23

Podejście, które ogólnie widziałem, polega na utworzeniu pliku o innej nazwie, np. Default_values_template.txt i umieszczeniu default_values.txt w swoim .gitignore. Poinstruuj ludzi, aby skopiowali default_values_template.txt do default_values.txt w ich lokalnych obszarach roboczych i wprowadzili potrzebne zmiany.

Laurence Gonsalves
źródło
hmmm ... może mógłbym napisać podpięcie do automatycznego kopiowania szablonu default_values_template do default_values, jeśli default_values ​​nie istnieje?
Marc
2
Z mojego doświadczenia wynika, że ​​jest to najczęstszy sposób rozwiązania tego problemu. Jest to ścieżka najmniejszego oporu, ponieważ „po prostu działa” i możesz łatwo sprawić, by kod sprawdzał, czy lokalny plik konfiguracyjny istnieje, a jeśli tak nie jest, podaj pomocny błąd.
Jani Hartikainen
Myślę, że rozwiązaniem jest rzeczywiście zrobienie czegoś takiego, najlepiej ze skryptem wykonywanym za każdym razem, gdy ściągasz lub klonujesz. Jednym z pomysłów jest to, że wszystko z określonym rozszerzeniem (powiedzmy .basefile) zostanie skopiowane do pliku z usuniętym rozszerzeniem, a następnie nazwa pliku zostanie dodana do .gitignore w tym katalogu. Utworzyłbym więc plik default_values.txt.basefile i zatwierdziłbym go. Nie mam gita ani perla, żeby to zrobić, ale zapytam znajomego, który to robi i dam ci znać, jak to działa.
Marc
1
@AdamDymitruk: Tak, w tym przypadku można użyć czyszczenia / smużenia, ale nie jest jasne, czy to najlepsza opcja. Na przykład będzie to raczej trudne, jeśli ludzie naprawdę chcą zmienić plik, ponieważ czyszczenie / smuga przeszkadza. Właściwie wolałbym podejście opisane tutaj.
sleske
1
Biorę wskazówkę z samego gita (szczególnie haków git) i używam .samplesufiksu. A więc w twoim przypadkudefault_values.txt.sample
tir38
6

Przyjrzyj się rozmaitym / czystym skryptom. W ten sposób możesz kontrolować wersję pliku, ale kiedy jest on wyewidencjonowany, będziesz go „rozmazać”, zastępując dane ogólne / zastępcze danymi specyficznymi dla maszyny w pliku.

Po zatwierdzeniu go „wyczyścisz”, zastępując informacje specyficzne dla maszyny informacjami ogólnymi lub informacjami zastępującymi.

Rozmyte / czyste skrypty muszą być deterministyczne w tym sensie, że ich wielokrotne stosowanie w różnej kolejności będzie równoznaczne z uruchomieniem ostatniego w sekwencji.

To samo można zastosować z hasłami, jeśli chcesz ujawnić swoje repozytorium, ale zawartość może zawierać poufne informacje.

Adam Dymitruk
źródło
Czy skrypty Clean and Smudge są lokalne lub stanowią część repozytorium?
Alan,
tak. :) ... to znaczy, możesz udostępnić smugę w czystym repozytorium, ale nie jest to dobry pomysł, gdy zawierają poufne dane, takie jak hasła produkcyjne. Jeśli to nie dotyczy, git wymaga jawnego włączenia skryptu. W przeciwnym razie ludzie mogliby robić złośliwe rzeczy za pośrednictwem github i innych udostępnionych repozytoriów innym użytkownikom.
Adam Dymitruk
Muszę przeczytać o tym trochę więcej. Zasadniczo chcę skonfigurować projekt, który ma wartość domyślną, user.jsonktórą należy nadpisać za pomocą każdego napisu dewelopera, ale nie chcę, aby deweloper przypadkowo sprawdzał swoje dane.
Alan,
Rozejrzałbym się po przykładowe skrypty do czystych smug. Zobacz, co się wydarzy. Wskocz też na pokój git irc na freenode. Natychmiast otrzymasz pomoc.
Adam Dymitruk
3

Rozwiązałem ten problem, definiując „czysty” filtr, który po prostu umieszcza zawartość pliku w indeksie.

git show :path/to/myfile powinniśmy po prostu wydrukować zawartość indeksu dla określonego pliku, abyśmy mogli użyć tego w skrypcie, aby zastąpić kopię roboczą nietkniętą kopią w indeksie:

#! /bin/sh

git show :$1

Ustaw go jako „czysty” filtr dla danego pliku (zakładając, że umieściłeś go w „discard_changes”):

$ git config filter.ignore_myfile.clean "discard_changes path/to/myfile"
$ echo "path/to/myfile filter=ignore_myfile" >> .gitattributes

Niestety nie mogę znaleźć sposobu na uogólnienie tego dla wielu plików, ponieważ nie ma sposobu, aby stwierdzić, który plik przetwarzamy z wnętrza czystego skryptu. Oczywiście nic nie stoi na przeszkodzie, aby dodać inną regułę filtrowania dla każdego pliku, ale jest to trochę niewyraźne.

Haddon CD.
źródło
1

Znalazłem rozwiązanie, które działa dla mojego zespołu. Udostępniamy nasze githooki za pośrednictwem linków symbolicznych i po dodaniu pliku szablonu do gita dodałem hak przed zatwierdzeniem, który sprawdza, czy plik szablonu został zmodyfikowany, a jeśli tak, to ja git reset -- templatefile.txt. Jeśli jest to jedyny zmieniony plik, również przerywam zatwierdzanie.

fruitcoder
źródło
-2

Proponuję zajrzeć do podmodułów. Jeśli umieścisz pliki specyficzne dla komputera w module podrzędnym, git add powinien je zignorować.

ivanpro
źródło
to dobry pomysł, ale wtedy muszę też umieścić repozytorium pojedynczych plików na serwerze git, co jest mniej niż optymalne, tylko dlatego, że używamy github i mamy ograniczoną liczbę repozytoriów.
Marc
@Marc rzuć okiem na usługi Visual Studio Team Services, nieograniczone bezpłatne projekty prywatne i repozytoria git. Tablice Kanban, śledzenie elementów pracy i błędów, kojarzenie zameldowania z elementami pracy, zarządzanie sprintami, jeśli jesteś w Scrum lub inne typy projektów. Oprócz tego, że ma doskonałe narzędzia do budowania na wielu platformach, zbyt wiele rzeczy, aby wspomnieć, że wszystkie są bezpłatne. Niektórzy ludzie żartują, ponieważ jest to Microsoft, ale bez wątpienia bije to, co Github ma do zaoferowania pod względem narzędzi, oprócz samego hostingu repozytoriów. Są granice tego, co możesz zrobić za darmo, ale rzadko je przekraczam.
Aran Mulholland
@Marc Jeszcze jedna rzecz, która jest dla mnie bardzo przydatna, to fakt, że mogę założyć tyle kont, ile chcę, więc jeśli piszę projekt dla klienta, który chce mieć kontrolę źródła, mogę utworzyć konto, użyć go zaplanować, zaprojektować i wykonać projekt, a kiedy skończę, mogę przenieść własność konta na klienta.
Aran Mulholland