Git - Ignoruj ​​pliki podczas scalania

115

Mam repozytorium wywołane myrepona zdalnym beanstalkserwerze.

Sklonowałem go na mój lokalny komputer. Utworzono dwie dodatkowe gałęzie: stagingi dev. Zepchnął również te gałęzie na odległość.

Teraz:

 local                   remote                   server
 --------------------------------------------------------  
 master  ==> Pushes to  `master`  ==> deployed to `prod`
 staging ==> Pushes to  `staging` ==> deployed to `staging`
 dev     ==> Pushes to  `dev`     ==> deployed to `dev`

Mam plik o nazwie, config.xmlktóry jest inny w każdej gałęzi.

Chcę zignorować ten plik tylko podczas scalania. Ale chcę, aby było to uwzględnione, gdy płacę lub zatwierdzam z / do gałęzi repo.

Chcę tego, ponieważ mamy skrypt wdrażania, który pobiera (pobiera) określoną gałąź i wdraża na odpowiednich serwerach. Więc potrzebujemy, aby config.xmlplik tej konkretnej gałęzi trafiał na określony serwer, jak wskazano powyżej, po wdrożeniu.

Chyba .gitignorenie zadziała. Jakie są inne opcje? Zauważ, że ignorowany plik powinien być częścią wypisania i zatwierdzenia, co jest ważne. należy go ignorować tylko podczas scalania.

Dzięki!

Kevin Rave
źródło
W swoim domyślnym trybie git pull jest skrótem dla pobierania git, po którym następuje git merge FETCH_HEAD. Więc stwierdzenia są ze sobą sprzeczne.
zzk
Cóż, powiedziałbym, jego kasie. Nie ciągnij. Zaktualizuję pytanie, aby było jasne.
Kevin Rave
2
czy kiedykolwiek znalazłeś rozwiązanie tego problemu? Atrybuty git są przydatne tylko w przypadku, gdy plik ma konflikty między scalanymi gałęziami, więc nie zawsze jest wystarczający.
pvinis
czy zajrzałeś do symbolicznych (po których nie następuje git) lub nawet twardych linków do pomocy?
Frank Nocke

Odpowiedzi:

94

Poradziłem sobie z tym problemem, używając polecenia git merge z --no-commitopcją, a następnie jawnie usunąłem plik pomostowy i zignorowałem zmiany w pliku. Np .: powiedz, że chcę zignorować wszelkie zmiany myfile.txt, postępuję w następujący sposób:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

Możesz umieścić instrukcje 2 i 3 w pętli for, jeśli masz listę plików do pominięcia.

unmesh-gurjar
źródło
2
Dodałbym „--no-ff”, jeśli chcesz, aby plik nie był nadpisywany, gdy scalanie odbywa się w strategii szybkiego przewijania do przodu.
Ilia Shakitko
1
więc co git reset HEAD myfile.txtdokładnie robi? Jak to pomaga w realizacji naszego celu tutaj?
Kid_Learning_C
Jak umieścić linie 2 i 3 w pętli?
AndroidDev
52

Skończyło się na znalezieniu gita attributes . Próbuję tego. Pracuję do tej pory. Nie sprawdziłem jeszcze wszystkich scenariuszy. Ale to powinno być rozwiązanie.

Scal strategie - atrybuty Git

Kevin Rave
źródło
1
Oto poprawny link do sekcji strategii scalania w dokumentacji atrybutów git: git-scm.com/book/en/v2/ ...
Adrian Laurenzi
3
Znalazłem to dobrze wyjaśnione w artykule medium.com/@porteneuve/ ...
ShawnFeatherly
10
Wydaje się, że jest to problem, jeśli nie ma konfliktów? Pliki nadal będą scalane?
Brett,
18

.gitattributes - to plik poziomu głównego repozytorium, który definiuje atrybuty podkatalogu lub podzbioru plików.

Możesz określić atrybut, aby poinformować Git, aby używał różnych strategii scalania dla określonego pliku. Tutaj chcemy zachować istniejący config.xmldla naszej branży. Musimy ustawić merge=ourssię config.xmlw .gitattributespliku.

merge=ours powiedz gitowi, aby użył naszego pliku (bieżącej gałęzi), jeśli wystąpi konflikt podczas łączenia.

  1. Dodaj .gitattributesplik na głównym poziomie repozytorium

  2. Możesz ustawić atrybut dla confix.xml w .gitattributespliku

    config.xml merge=ours
    
  3. A następnie zdefiniuj fikcyjną naszą strategię scalania z:

    $ git config --global merge.ours.driver true
    

Jeśli scalisz gałąź stagformularza dev, zamiast konfliktu scalania z plikiem config.xml, config.xml gałęzi stag zachowa tę wersję, którą pierwotnie posiadałeś.

eigenharsha
źródło
16
Ale co, jeśli nie ma konfliktu? Jak zawsze zachować określony plik podczas scalania?
Igor Yalovoy
2
@IgorYalovoy: Jeśli nie ma konfliktu ... cóż, jest to trochę skomplikowane, ponieważ w rzeczywistości działa z hash ID, ale: jeśli config.xmljest całkowicie niezmienione od bazy scalania do dowolnej wersji końcówki gałęzi, Git po prostu przyjmuje zmienioną wersję, bez patrząc na merge.ours.driverotoczenie. Więc masz rację, jeśli się o to martwisz.
torek
1
kopiuj-wklej z Git Docs: Merge Strategies - Git Atrybuty. Link
kyb
Ta metoda skutkuje "merge commits" za każdym razem FYI.
rsmets
2
„nasza” wydaje się być dowolną nazwą wprowadzanej nowej strategii. Wydało mi się to zagmatwane, ponieważ theirsjest to wbudowana strategia scalania. Ale wydaje się, że można napisać <pattern> merge=foo, a następnie git config --global merge.foo.driver true, i to będzie działać w ten sam sposób.
Kyle Strand
8

Możesz zacząć od użycia git merge --no-commit, a następnie edytować scalanie w config.xmldowolny sposób, np. Przez usunięcie z poczekalni lub dowolnego innego pliku, a następnie zatwierdzenie. Podejrzewam, że chciałbyś później zautomatyzować to za pomocą haków, ale myślę, że warto byłoby przynajmniej raz przejść przez to ręcznie.

gcbenison
źródło
2
Czy git attributesoferuje jakieś proste rozwiązanie? Nie jestem w stanie tego zrozumieć. git-scm.com/book/en/ ...
Kevin Rave
4

Możesz użyć, .gitignoreaby zatrzymać config.xmlrepozytorium, a następnie użyć haka po zatwierdzeniu, aby przesłać odpowiedni config.xmlplik na serwer.

tlehman
źródło
1
Wiem, że to trochę hack. Próbuję znaleźć czyste rozwiązanie. A co z git attributes. Masz jakiś pomysł, jak to działa? Nie jestem w stanie tego zrozumieć. git-scm.com/book/en/ ...
Kevin Rave
1
Nie słyszałem o tym, próbuję zastosować atrybut merge = ours, wygląda obiecująco.
tlehman
1
Atrybuty Git są niesamowite! Możesz nawet powiedzieć gitowi, jak porównywać pliki nietekstowe, więc możesz użyć pdf2text do porównywania plików PDF!
tlehman
2

Przykład:

  1. Masz dwie gałęzie: master ,develop
  2. Utworzyłeś plik w developgałęzi i chcesz go zignorować podczas scalania

Kod:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

Możesz także zignorować pliki z tym samym rozszerzeniem

na przykład wszystkie pliki z .txtrozszerzeniem:

echo "*.txt merge=ours" >> .gitattributes
Sole Sensei
źródło
1

Tutaj git-update-index - rejestruje zawartość pliku w drzewie roboczym do indeksu.

git update-index --assume-unchanged <PATH_OF_THE_FILE>

Przykład:-

git update-index --assume-unchanged somelocation/pom.xml

Sireesh Yarlagadda
źródło
To miłe, gdy pchasz, ale nadal narzeka, że ​​wyciąganie może nadpisać plik.
Rolf
1
czy próbowałeś dodać swój wpis do pliku .gitignore. @Rolf
Sireesh Yarlagadda