Szukam lepszego gitignore

1

Potrzebowałbym tak ustawić gita, żeby zupełnie ignorował pewne zmiany. Znaczy mam zrobione trochę swoich zmian lokalnych, ale nie chcę ich nigdy commitować i wolałbym, żeby git je całkowicie ignorował. Zdaje się, że można zrobić sobie lokalnego gitignore, ale to nie rozwiązuje wszystkich problemów, bo żeby to były pojedyńcze zmiany, a nie całe pliki. To jest mam na przykład w jednym pliku zmienione coś w linii 2, ale w pewnym momencie dopisuje coś w linii 4 i chciałbym, żeby chamskie git add bez -p wzięło pod uwagę tylko te zmiany w linijce numer 4.

Da się to jakoś wyczarować?

0

git stash powinno Ci pomóc.

1

Nie, bo Git operuje na plikach, nie na pojedynczych zmianach. To by wymagało patch-based VCS jak Darcs lub Pijul.

1

Problem brzmi jakby w projekcie brakowało plików .env, tj. dev.env (ew. local.env), prod.env itp. - macie takie pliki albo coś podobnego?

0
Markuz napisał(a):

Problem brzmi jakby w projekcie brakowało plików .env, tj. dev.env (ew. local.env), prod.env itp. - macie takie pliki albo coś podobnego?

Mamy. Wszystko jest w ignorach. Chodzi o pliki, które nie zostały stworzone z myślą o lokalnej konfiguracji. Jak na przykład bajerek do analizy przy testach. W większości przypadków tylko wydłuża startup, odkomentowuję go tylko, gdy task jest już zrobiony, żeby zobaczyć czy coś się nie rypło.

2

A mnie zastanawia po co? To oznacza, że twoja wersja ma działać inaczej jak wszystkie inne. Jak w takim wypadku coś debugować ?

3

Wydaje mi się, że środowiska IntelliJ ogarniają takie zmiany w ramach changelist - tj. jeśli dorzucisz jakieś zmiany do osobnej changelisty, nie będą one Ci się pokazywały w trakcie commitowania.

2
UglyMan napisał(a):

A mnie zastanawia po co? To oznacza, że twoja wersja ma działać inaczej jak wszystkie inne. Jak w takim wypadku coś debugować ?

Choćby dlatego że chcemy by nasza wersja miała dodatkowe printy w logach.
Albo mniej śmieciowych printów w logach.
Albo zamockowane coś właśnie po to by się dało debugować czy testować.
Albo inny adres serwera (np. localhost).

Jest wiele takich sytuacji, kiedy chcemy mieć lokalnie jakieś zmiany na stałe lub na półstałe a jednocześnie nie wypychać ich do repo.

2
Azarien napisał(a):
UglyMan napisał(a):

A mnie zastanawia po co? To oznacza, że twoja wersja ma działać inaczej jak wszystkie inne. Jak w takim wypadku coś debugować ?

Choćby dlatego że chcemy by nasza wersja miała dodatkowe printy w logach.
Albo mniej śmieciowych printów w logach.

A od tego nie są poziomy logów?

Albo zamockowane coś właśnie po to by się dało debugować czy testować.

No to chyba na developerce wszyscy maja zamockowane

Albo inny adres serwera (np. localhost).

To chyba powinno być w plikach konfiguracyjnych.

3
hauleth napisał(a):

Nie, bo Git operuje na plikach, nie na pojedynczych zmianach. To by wymagało patch-based VCS jak Darcs lub Pijul.

przecież można w gicie zastage'ować pojedynczy hunk z pliku, ignorować też się powinno dać ale chyba na to nie wpadli
Lepiej wydzielić zmienne które mają się różnić do osobnego configa, wtedy można mieć lokalną wersję która będzie zignorowana. W kodzie może być warunek typu "jeśli plik .config.local istnieje to go użyj, jak nie to zwykły", albo wybierać config na podstawie środowiska.

Azarien napisał(a):

Choćby dlatego że chcemy by nasza wersja miała dodatkowe printy w logach.

Mieliśmy kiedyś w projekcie podobną rozkminę i ktoś rzucił moim zdaniem słusznie - skoro te dodatkowe logi okazały się pomocne przy debugowaniu tego problemu to czy nie powinny zostać w projekcie? Więc tylko zmieniliśmy poziom logowania na trace i normalnie wrzuciliśmy to do kodu.

Albo zamockowane coś właśnie po to by się dało debugować czy testować.

I czemu nie warto tego testu i mocka wrzucić normalnie do repo skoro już istnieje?

Albo inny adres serwera (np. localhost).

to już napisałem wyżej.
Ogólnie prawie zawsze napisany kod powinien się znaleźć w repozytorium. Lokalne configi np z IDE mają zazwyczaj konkretne nazwy albo są ukryte w podfolderach więc łatwo je zignorować.

Ale jeśli nadal Ci na tym zależy to mogę zaproponować obejście wykorzystujące symlinki (ln na linuksie, mklink na windowsie). Wystarczy że obok klona repo stworzysz sobie folder ze swoimi zmianami i stworzysz dowiązania do reszty plików i folderów (najłatwiej w ten sposób podmienić cały folder). Potem lokalnie korzystasz z tego nowego folderu a ten pierwszy, z working copy używasz tylko do commitowania i pushowania zmian.
To nie rozwiązuje problemu zmian w pojedynczych liniach, ale umożliwia trzymanie zmian bez ich ręcznego ignorowania za każdym razem i bez wrzucania pliku do .gitignore.
Możesz lokalnie postawić skrypt który będzie mergował zmiany z głównego folderu do dodatkowego. Możesz utworzyć z tego drugiego folderu lokalne repozytorium i użyć gita do mergowania, podpiąć się pod trigger post-update tego pierwszego i to wszystko zautomatyzować.

Minus takiego rozwiązania to że być może będziesz musiał ręcznie tworzyć nowe dowiązania i usuwać stare jeśli struktura plików się zmieni.

1

Uzależnij to od ustawienia środowiska, jak masz prod, to nie widzi tego kodu, a jak dev to widzi.

2

A od tego nie są poziomy logów?

To chyba powinno być w plikach konfiguracyjnych.

skoro te dodatkowe logi okazały się pomocne przy debugowaniu tego problemu to czy nie powinny zostać w projekcie?

I czemu nie warto tego testu i mocka wrzucić normalnie do repo skoro już istnieje?

Ogólnie prawie zawsze napisany kod powinien się znaleźć w repozytorium

Nie na wszystko zawsze ma się wpływ. Czasami panuje niedasizm i trzeba sobie radzić lokalnie.

Przykład: libka używana w projekcie, do której mam źródła ale do oficjalnego repo dostęp tylko read-only.
(akurat wtedy mogę mieć lokalnie branczę ze swoimi commitami, i robić rebase na master w razie potrzeby)

0
tsz napisał(a):

Da się to jakoś wyczarować?

Owszem, da. To bardzo proste rozwiązanie - nazywa się gałąź i jest podstawową funkcją gita. Gałąź trzymasz lokalnie, nigdy nikomu nie pokazujesz. Ja na wszelki wypadek wszystkie takie rozpoczynam prefiksem DONTPUSH. Sprawdza się doskonale od 10 lat.

Niezależnie oczywiście do tego, że lokalne poziomy logowania, urle i inne pierdoły powinny być skonfigurowane w lokalnym pliku konfiguracyjnym - ale to już od technologii, a nie gita zależy.

1
somekind napisał(a):
tsz napisał(a):

Da się to jakoś wyczarować?

Owszem, da. To bardzo proste rozwiązanie - nazywa się gałąź i jest podstawową funkcją gita.

ale co ma gałąź do tego? on chce pracować na konkretnej gałęzi którą wypchnie ale mieć lokalne zmiany w niektórych linijkach. Jak lokalna "gałąź" ma w tym pomóc? Czy masz na myśli zrobienie lokalnych zmian na gałęzi i jej mergowanie za każdym razem po checkoucie i revertowanie przed pushem?

W sumie chyba faktycznie gdyby to połączyć ze skryptami w triggerach które zrobią "niewidoczne commity" to chyba by się to dało tak zrobić. Ale łatwiej ze stashem.

Ja przyznam że w sumie mimo że tak prawię morały to mam podobny problem, bo często mam zmianę w jednej linijce żeby lokalnie udawać innego użytkownika w manualnych testach czego aplikacja normalnie nie wspiera bo ma integrację z domeną i używa automatycznie użytkownika domenowego bez możliwości zmiany. I to jest zmiana którą często mam, z tym że trzymam sobie ją normalnie w stashu i w miarę potrzeby robię apply i muszę potem pamiętać żeby jej przypadkiem nie dodać do indeksu ze wszystkim. Także całkowicie rozumiem autora wątku ale w moim przypadku nie robię tego tak często żeby było to uciążliwe. Chętnie się dowiem jak "gałąż" może mi pomóc

0
obscurity napisał(a):

ale co ma gałąź do tego? on chce pracować na konkretnej gałęzi którą wypchnie ale mieć lokalne zmiany w niektórych linijkach. Jak lokalna "gałąź" ma w tym pomóc?

Pozwala przechowywać zmiany.

Czy masz na myśli zrobienie lokalnych zmian na gałęzi i jej mergowanie za każdym razem po checkoucie i revertowanie przed pushem?

Bynajmniej. Po co mergować i revertować, skoro prościej po prostu nie commitować tych zmian?
Trzymasz swoje zmiany w gałęzi lokalnej, zaczynasz pracę na dowolnej innej gałęzi, jeśli potrzebujesz swoich lokalnych zmian, to robisz cherry picka tych zmian, korzystasz z nich, ale ich nie wrzucasz ich do gałęzi roboczej ani nie publikujesz w żaden sposób.

W sumie chyba faktycznie gdyby to połączyć ze skryptami w triggerach które zrobią "niewidoczne commity" to chyba by się to dało tak zrobić. Ale łatwiej ze stashem.

Ale na jakiej zasadzie stash jest łatwiejszy od gałęzi?
Jak dla mnie gałąź jest bardziej widoczna, a stash to w ogóle służy do tymczasowego przechowywania zmian. W tym przypadku zmiany chcemy przechowywać raczej długo.

1

Wygląda na problem X/Y.

Jeśli w jakiś sposób środowisko lokalne ma działać inaczej niż produkcyjne, to należałoby to jakoś uniezależnić, tak żebyś nie musiał pracować na dirty tree. Np property'sami, jak tu wielu próbowało.

2

przecież można w gicie zastage'ować pojedynczy hunk z pliku, ignorować też się powinno dać ale chyba na to nie wpadli

No nie, bo stage niejako "tworzy plik na nowo". Problemem tutaj byłyby operacje w postaci git status, które musiałby za każdym razem tworzyć diff by móc odfiltrować linie, które mają być zignorowane. To byłoby zdecydowanie za wolne, pomijając już fakt, że nie do końca pewne, bo zmiana ustawień w Gicie może spowodować zmianę diffa.

0

To jest problem XY, ale wg mnie to całkiem sensowny X do tego Y — tzn. jest to całkiem sensowne rozwiązanie problemu „chcę mieć coś innego lokalnie niż w głównym repo”. Konkurencyjne rozwiązania są, oczywiście, też sensowne, ale nie widzę oczywistej wyższości jednego nad drugim — „weź se tę wartość ze zmiennej środowiskowej” jest nieco uciążliwe w ustawianiu na produkcji czy czasem nawet przy testach i komplikuje nam infrastrukturę; „weź se tę wartość z pliku, którego nie commitujemy” ma podobny problem, jeśli się tego pliku nie wrzuca do repo, a jeśli jest wersja w repo, którą lokalnie nadpisujemy, to też nie jest najpiękniejsze, i wreszcie „weź se tę wartość taką, jaka jest, a niech system kontroli wersji tego nie wersjonuje” jest rozwiązaniem, rzekłbym, na poziomie tamtych dwóch — tyle że fundamentalnie sprzecznym z tym, jak działa git.

0

To nie bardzo jest problem X, jeśli rozwiązaniem X jest napisz od nowa w technologii, która wspiera różne bajery i w ogóle użyj rijakta i dokiera.

Przykład - praca nad API gatewayem, który korzysta z 40 wewnętrznych serwisów. Normalnie lokalnie mam ustawione na jakieś środowisko, ale wskakuje bug i trzeba zdebugować interakcję z 4 z tych serwisów. Stawiam je lokalnie, przekierowuję gateway na nie (reszta konfiguracji oczywiście zostaje bez zmian), mogę debugować. A ponieważ zdarza się to często, to mogę sobie tą zmienioną konfigurację wrzucić do gałęzi, i mieć lokalnie, następnym razem zrobię tylko cherry picka i będę miał środowisko gotowe do debugowania.

0

Polecam .dockerignore

2
TomRiddle napisał(a):

Wygląda na problem X/Y.

Jeśli w jakiś sposób środowisko lokalne ma działać inaczej niż produkcyjne, to należałoby to jakoś uniezależnić, tak żebyś nie musiał pracować na dirty tree. Np property'sami, jak tu wielu próbowało.

Ale - jak już wyżej napisałem - to nie jest zawsze możliwe. Powiedzmy że te nasze lokalne zmiany są tyle genialne co kontrowersyjne i dziwaczne i nie spotkały się z aprobatą reszty zespołu.

0
Azarien napisał(a):
TomRiddle napisał(a):

Wygląda na problem X/Y.

Jeśli w jakiś sposób środowisko lokalne ma działać inaczej niż produkcyjne, to należałoby to jakoś uniezależnić, tak żebyś nie musiał pracować na dirty tree. Np property'sami, jak tu wielu próbowało.

Ale - jak już wyżej napisałem - to nie jest zawsze możliwe. Powiedzmy że te nasze lokalne zmiany są tyle genialne co kontrowersyjne i dziwaczne i nie spotkały się z aprobatą reszty zespołu.

Sposób ich wykonania ("nasz sposób") możliwe że jest kontrowersyjny i dziwaczny, ale jego zasadność prawdopodobnie nie. I być może zespół znajdzie lepsze rozwiązanie. Jak np podmiana hosta w kodzie źródłowym jest dziwacznym rozwiązaniem, ale uniezależnienie się od jednej domeny jest zasadne, i team mógłbym znaleźć alternatywę.

Jeśli natomiast cały pomysł zostanie uznany za niezasadny przez zespół, to czemu taki osobnik ciągle chciałby kontynuować taką praktykę?

Co ma na tyle sensu żeby ryzykować pracę na dirty tree, ale tak mało żeby czyjś zespół nie chciał dać takiej możliwości każdemu?

1
somekind napisał(a):

To nie bardzo jest problem X, jeśli rozwiązaniem X jest napisz od nowa w technologii, która wspiera różne bajery i w ogóle użyj rijakta i dokiera.

Przykład - praca nad API gatewayem, który korzysta z 40 wewnętrznych serwisów. Normalnie lokalnie mam ustawione na jakieś środowisko, ale wskakuje bug i trzeba zdebugować interakcję z 4 z tych serwisów. Stawiam je lokalnie, przekierowuję gateway na nie (reszta konfiguracji oczywiście zostaje bez zmian), mogę debugować. A ponieważ zdarza się to często, to mogę sobie tą zmienioną konfigurację wrzucić do gałęzi, i mieć lokalnie, następnym razem zrobię tylko cherry picka i będę miał środowisko gotowe do debugowania.

Podałem wyżej przykład, gdzie takie coś jest potrzebne jednej konkretnej osobie, ale nie całemu zespołowi. - somekind 11 minut temu

Tylko ten przykład brzmi jak coś jednokrotnego. Jakby, ile razy można naprawiać tego samego buga? Najpewniej go fixniesz raz, potem popraiwsz jak coś dalej nie będzie działać i tyle. Po fixie, pewnie nie wrócisz do tych lokalnych zmian które miałeś.

Autor wątku sugeruje takie dirty local tree, które jest utrzymywane cały czas, niezależnie od tego nad jakim feature'em pracuje.

0
TomRiddle napisał(a):

Tylko ten przykład brzmi jak coś jednokrotnego. Jakby, ile razy można naprawiać tego samego buga? Najpewniej go fixniesz raz, potem popraiwsz jak coś dalej nie będzie działać i tyle. Po fixie, pewnie nie wrócisz do tych lokalnych zmian które miałeś.

Jednego buga jeden raz, ale zawsze mogą pojawić się nowe bugi na styku tych samych serwisów, więc trzeba te zmiany mieć ciągle dostępne.

2

Podam przykład z życia jak rozwiązano problem z hardkodowanym adresem serwera.

Początkowo serwer był stringiem zdefiniowanym w (dużym) pliku źródłowym. To powodowało niekomfortową sytuację że często pracowało się przy „brudnym” tym akurat (dużym) pliku.
W końcu ktoś wpadł na pomysł żeby adres serwera wyciągnąć do osobnego, małego pliku, w którym będzie zdefiniowany praktycznie tylko ten adres.
To już lepiej, bo możemy się przyzwyczaić do ignorowania zmian w tym pliku, ale nadal to jest praca na “dirty tree”.
Plik więc zamiast normalnie być w repo jest teraz generowany jako jeden z pierwszych etapów budowania projektu (robienie builda ma kilka faz, to nie jest jedno make). Po tym pierwszym etapie możemy wyedytować plik z adresem i odpalić właściwą kompilację.
Nic nam nie brudzi bo generowany plik jest w gitignore.

Wadą rozwiązania jest że możemy (w zależności od tego jak odpalimy make'a) niechcący nadpisać plik przywracając adres domyślny.

0

Teoretyczna obsługa takiego ficzera przez hipotetyczny neo-git miałaby też tę zaletę, że umiarkowanie łatwo byłoby się edytorom/IDE podpiąć pod nią i być w stanie wyświetlać od razu/na żądanie obu wersji — moglibyśmy widzieć od razu, że u nas jest taka, a na produkcji taka. Coś, co jest drastycznie trudniejsze do osiągnięcia w jakikolwiek „normalny” sposób.

1 użytkowników online, w tym zalogowanych: 0, gości: 1