Używając git, jak zignorować plik w jednej gałęzi, ale czy został on zatwierdzony w innej?

157

Mam projekt, który wdrażam w Heroku . Drzewo kodu źródłowego zawiera kilka plików mp3 (strona będzie dotyczyła projektu nagraniowego, w którym byłem mocno zaangażowany).

Chciałbym umieścić kod źródłowy na GitHub , ale GitHub ma limit 300 MB na swoich bezpłatnych kontach. Nie chcę wykorzystywać 50 MB z mojego limitu na kilka plików mp3. Oczywiście mogłem dodać je do .gitignorepliku, aby nie trafiały do ​​mojego repozytorium.

Jednak wdrażam do Heroku przy użyciu git push heroku. Pliki mp3 muszą znajdować się w gałęzi, którą wysyłam do Heroku, aby zostały wdrożone.

Najlepiej byłoby .gitignore, gdyby pliki mp3 znajdowały się w mojej lokalnej gałęzi głównej, aby po przesłaniu ich do GitHub pliki mp3 nie były uwzględniane. Następnie zachowałbym lokalny oddział produkcyjny, w którym pliki MP3 są zobowiązane, a nie ignorowane. Aby wdrożyć, połączyłem mistrza z produkcją, a następnie przekazałem gałąź produkcyjną do Heroku.

Nie mogę sprawić, żeby to działało dobrze.

Oto przykład tego, co próbuję zrobić ...

$ git init git-ignore-test
$ cd git-ignore-test
$ echo "*.ignored" >> .gitignore
$ git add .gitignore && git commit -m "Ignore .ignored files"
$ touch Foo.ignored

W tym momencie Foo.ignored jest ignorowany w mojej gałęzi master, ale nadal jest obecny, więc mój projekt może go używać.

$ git checkout -b unignored
$ cat /dev/null > .gitignore
$ git add Foo.ignored .gitignore && git commit -m "Unignore .ignored files"

Teraz mam gałąź z zatwierdzonymi plikami, tak jak chcę. Jednak kiedy przełączam się z powrotem do mojej gałęzi głównej, Foo.ignored zniknął.

Czy ktoś ma jakieś sugestie dotyczące lepszego sposobu konfiguracji?

Edycja: tylko dla wyjaśnienia, chcę, aby pliki mp3 były obecne w obu gałęziach, aby po uruchomieniu witryny lokalnie (przy użyciu dowolnej gałęzi) strona działała. Chcę tylko, aby pliki były ignorowane w jednej gałęzi, więc kiedy pcham do GitHub, również nie są wypychane. Zwykle .gitignore działa dobrze na tego typu rzeczy (tj. Przechowywanie lokalnej kopii pliku, który nie jest dołączany do zdalnego przekazywania), ale kiedy przełączam się do gałęzi z wpisanymi plikami, a następnie z powrotem do rozgałęzienia z ignorowanymi plikami pliki znikają.

Myron Marston
źródło
Dlaczego pliki MP3 muszą być kiedykolwiek przenoszone do repozytorium?
Dan Loewenherz
4
Dzięki heroku jedynym sposobem na dołączenie plików do aplikacji podczas wdrażania jest zatwierdzenie repozytorium. Jedyną alternatywą jest użycie czegoś takiego jak Amazon S3 do obsługi plików mp3, ale wolałbym tego uniknąć.
Myron Marston
Wygląda na to, że potykasz się o dolary, aby zaoszczędzić grosze ... Konfiguracja Rackspace Cloud jest bardzo prosta, a przechowywanie w niej <1 GB plików kosztowałoby bardzo niewiele ...
gahooa,
3
Zauważyłem, że oznaczyłeś odpowiedź jako poprawną, ale z tego, co przeczytałem, może nie być poprawna. Czy kiedykolwiek wypróbowałeś odpowiedź i czy zadziałała?
pętla
2
Off Topic: Czy rozważałeś użycie innego hosta repozytorium open source? BitBucket nie ma limitu rozmiaru w swoich repozytoriach Git, niezależnie od tego, czy są na darmowym koncie, czy nie (wspominają jednak o utrzymaniu rozmiaru w rozsądnym zakresie). Dopóki twoje repozytorium nie wymknie się spod kontroli, może to być opcja. UWAGA: Nie jestem związany z BitBucket, po prostu zadowolony klient.
NightOwl888

Odpowiedzi:

84

Wydaje się, że to rozwiązanie działa tylko w przypadku niektórych poprawionych wersji git. Zobacz nową odpowiedź wskazującą obejścia i inną odpowiedź i kolejne komentarze, aby uzyskać wskazówkę, które wersje mogą działać.

Napisałem post na blogu o tym, jak efektywnie korzystać z excludesfileróżnych gałęzi, takich jak jeden do publicznego github i jeden do wdrażania heroku.

Oto szybkie i brudne:

$ git branch public_viewing
$ cd .git/
$ touch info/exclude_from_public_viewing
$ echo "path/to/secret/file" > info/exclude_from_public_viewing 

następnie w pliku .git / config dodaj te linie:

[core]
excludesfile = +info/exclude


[branch "public_viewing"]
excludesfile = +info/exclude_from_public_viewing

Teraz wszystkie globalne rzeczy związane z ignorowaniem znajdują się w info/excludepliku, a specyficzna gałąź znajduje się winfo/exclude_from_public_viewing

Mam nadzieję, że to pomoże!

http://cogniton-mind.tumblr.com/post/1423976659/howto-gitignore-for-different-branches

Poznanie Umysł
źródło
1
Przepraszam, że trwało to tak długo ... ale jeśli nie usuniesz plików .gitignore, domyślnie będą to te pierwsze.
Cognition.Mind
4
U mnie to nie działa, nawet jeśli projekt nie używa .gitignore. Czy masz coś przeciwko dostarczeniu transkrypcji poleceń konfigurujących to od podstaw ( git init, ...) i używanej wersji Git?
Davor Cubranic
34
To rozwiązanie nie działa. Na blogu odbyła się dyskusja i nikt nie był w stanie tego zrobić.
spuder
2
W waniliowym Gicie jestem prawie pewien, że to nie działa i nigdy nie działało. Ci z was, którym udało się to odtworzyć, czy możecie udostępnić swoją wersję Gita i inne istotne informacje o swoim środowisku? Może masz poprawioną wersję od opiekunów pakietów Git w Twojej dystrybucji.
Palec
20

Ważna wskazówka : zaakceptowana odpowiedź Cognition.Mind nie działa (już od kilku lat, a może dla waniliowych wersji gita); zobacz komentarze. Prawidłową odpowiedź i obejście można znaleźć tutaj:

https://stackoverflow.com/a/29583813/2157640

Innym alternatywnym obejściem (działającym dla mojego konkretnego problemu, ale wymagającym ręcznych operacji przechowywania lub implementacji haka) byłoby git stash -u -a. Jest to uciążliwe, gdy różnice są duże.

I wreszcie rozwiązanie, z którego teraz korzystam, polega na rozwidleniu mojej maszyny wirtualnej, w której trzymamy nasze środowisko programistyczne, i skonfigurowaniu jej info/excludesodpowiednio dla gałęzi, odpowiednio usuwając naruszające, niezatwierdzone pliki / foldery.

Murphy
źródło
14

Zdecydowanie radziłbym rozważyć umieszczenie tych plików MP3 na S3. Posiadanie ich jako części pchnięcia Heroku (a tym samym części ślimaka Heroku) znacznie spowolni czas uruchamiania hamowni. Ponieważ Heroku używa EC2, jeśli pliki znajdują się na S3 i są dostępne tylko przez twoją aplikację (jeśli użytkownicy nie są bezpośrednio połączeni z S3), nie zapłacisz nawet żadnych opłat za przepustowość, tylko opłatę za przechowywanie 50 MB.

David Dollar
źródło
13

Powiedzmy, że chcemy zignorować buildfolder ze wszystkich innych gałęzi oprócz productiongałęzi. Ponieważ chcemy wypchnąć buildfolder w produkcji.

1) Nie umieszczaj buildw .gitignore. Jeśli to zrobisz, będzie to zawsze ignorowane dla wszystkich gałęzi.

2) Utwórz plik exclude_from_public_viewingw ./.git/infofolderze (ten folder już istnieje)touch ./.git/info/exclude_from_public_viewing

3) Wewnątrz exclude_from_public_viewingnapisz jedną linię (tak jak próbujesz zignorować builddla wszystkich gałęzi). !build

4) Istnieje istniejący plik .git/info/exclude. Musimy dodać w nim następującą linię.

 build

Chcemy zignorować buildfolder, ale nie dodaliśmy go w .gitignore. Więc skąd git będzie wiedział, co ignorować? Odpowiedź brzmi: dodajemy go do excludepliku i warunkowo przekazujemy dogit config

5) Teraz musimy warunkowo anulować ignorowanie buildfolderu dla productiongałęzi. aby to zrobić, wykonaj następujące czynności

6) Istnieje istniejący plik o nazwie ./.git/configmusimy dodać następujące -

a) excludesfile = +info/excludeponiżej[core]

[core]
     excludesfile = +info/exclude

b) Utwórz nową sekcję na końcu ./.git/configas

[branch "production"]
    excludesfile = +info/exclude_from_public_viewing

Rozwiązanie 2

Jest jedno inteligentne alternatywne rozwiązanie. Powiedzmy, że chcesz dodać build/folder do productiongałęzi i zignorować go we wszystkich innych gałęziach.

1) Dodaj go do swojego gitignorepliku.

2) W gałęzi produkcyjnej, podczas wykonywania git add, wymuś dodanie buildfolderu:git add -f --all build/

sapy
źródło
I jak to się różni od przyjętego rozwiązania? Z jaką wersją gita to przetestowałeś? Jak stwierdza połączona odpowiedź, nie udaje się to, ponieważ nie ma wsparcia dla branch.<name>.excludesfilein git (już?), Tylko dla core.excludesfile, a moje własne testy zdawały się to potwierdzać.
Murphy
@murphy działa dobrze git version 2.7.4 (Apple Git-66)i nie używałem go branch.<name>.excludesfile w moim rozwiązaniu.
sapy
4
@sapy: Próbowałem tego zgodnie z przypadkiem użycia OP, a plik nadal znika, gdy przełączam się z produkcji na master. Zauważ, że folder „build” powinien zostać zatwierdzony w gałęzi „production”. (Zauważam również, że jeśli nie zatwierdzę folderu "build" w gałęzi "production", gałąź "production" ignoruje obecność folderu "build" - tj. [Branch "production"] wyklucza konfigurację pliku nie działa). Używam dokładnie tej samej wersji gita, co Twoja. Wypróbowałem też podejście [gałąź "produkcja"], aby ignorować plik tylko w gałęzi produkcyjnej, to też nie działa, jak powiedział Murphy.
justhalf
Rozwiązanie 2 było czymś, czego szukałem. Dzięki!
Wiaczesław Cotruta,
4

Czy próbowałeś zmienić domenę .gitignore w swojej branży?

Powinieneś być w stanie zignorować to, co chcesz na podstawie gałęzi, w której się znajdujesz, o ile pliki nie są śledzone w tej gałęzi.

kEND
źródło
6
Próbowałem tego. Jeśli spojrzysz na polecenia, które zamieściłem powyżej, zobaczysz, że dokładnie to zrobiłem. Problem polega na tym, że kiedy przełączam się z gałęzi z wpisanymi plikami do gałęzi z ignorowanymi plikami, git odrzuca te pliki. Chcę zachować pliki mp3 w gałęzi master, aby witryna działała poprawnie w trybie deweloperskim, nawet jeśli pliki są ignorowane.
Myron Marston,
1
on już powiedział, że to właśnie zrobił. może po prostu usunięcie tej odpowiedzi będzie najlepsze :-) powoduje to rozproszenie uwagi.
blamb
3

1. Podsumowanie

  1. Używam Travis CI do wdrażania ( obsługuje wdrażanie Heroku )
  2. Dodaję do mojego .travis.yml:

    before_deploy:
    - mv misc/.gitignore .gitignore

    Gdzie misc- dowolny folder, zawiera inny .gitignore.

    mvPlik przenoszenia poleceń systemu UNIX ; nadpisać, jeśli plik już istnieje.

Podczas wdrażania projektu Travis CI Travis CI nie będzie naciskać na wdrażanie plików i folderów dostawcy , które ignorują w misc/.gitignore(nie w oryginalnych .gitignoreźródłach).


2. Ograniczenia

  1. Ta odpowiedź może nie być odpowiednia dla wszystkich warunków autora. Ale ta odpowiedź odpowiada na pytanie „Używając git, jak zignorować plik w jednej gałęzi, ale czy został on zatwierdzony w innej?”
  2. Nie jestem użytkownikiem Heroku, moje przykłady dla GitHub , nie dla Heroku. Dane tej odpowiedzi działają dla mnie w GitHub, ale mogą nie działać w Heroku.

3. Trafność

Ta odpowiedź dotyczy kwietnia 2018 r. W przyszłości dane tej odpowiedzi mogą być nieaktualne.


4. Demonstracja

mój prawdziwy projekt .

Przykład pomyślnego wdrożenia .

4.1. Zadanie

Wdrażam projekt z gałęzi src do gałęzi dest tego samego repozytorium.

Chcę, aby ten plik PaletteMira.suricate-profile:

  • Maszyna lokalna - istnieje dla wszystkich oddziałów,
  • zdalna gałąź src - nie istnieje,
  • dest zdalna gałąź - istnieje.

Jeśli dobrze zrozumiałem autora pytania, ma on podobne zadanie.

4.2. src

gałąź źródeł - SashaYAML .

Część .travis.yml:

before_deploy:
- mv misc/.gitignore .gitignore

deploy:
  provider: pages
  on:
    branch: SashaYAML
  keep-history: true
  skip-cleanup: true
  target-branch: SashaDevelop
  repo: Kristinita/PaletteMira
  github-token: $GITHUB_TOKEN
  committer-from-gh: true
  project-name: PaletteMira
verbose: true

Część .gitignore:

*.sublime-snippet
*.suricate-profile

Część misc/.gitignore

*.sublime-snippet

*.suricate-profilenie w misc/.gitignore.

PaletteMira.suricate-profile nie istnieje w tej gałęzi zdalnie, ale istnieje lokalnie.

4.3. dest

oddział docelowy - SashaDevelop

Część .gitignore:

*.sublime-snippet

*.suricate-profilenie w misc/.gitignore.

PaletteMira.suricate-profileistnieje dla tej gałęzi zdalnie i lokalnie.

4.4. kroki ku reprodukcji

Włączam repozytorium PaletteMira GitHub dla Travis CI Ustawiam zmienną środowiskową $GITHUB_TOKEN z wartością - mój token GitHub Wykonuję dowolne zatwierdzenie do mojej gałęzi src.

Jeśli nie ma błędów, muszę uzyskać oczekiwane zachowanie .

Саша Черных
źródło
0

Czy możesz zatwierdzać i naciskać z Heroku?

np. Dodaj audio, wypchnij je na github i do heroku, usuń pliki z kopii roboczej na Heroku. Usuń dźwięk z repozytorium, ale nie z dysku, a następnie prześlij tę zmianę z powrotem na github.

Tomek
źródło
0

Github obsługuje teraz przechowywanie dużych plików, zobacz więcej tutaj https://git-lfs.github.com/

John Lozano
źródło