Используя git, как мне проигнорировать файл в одной ветви, но зафиксировал ли он в другой ветви?

157

У меня есть проект, который я внедряю в Heroku . Дерево исходного кода включает в себя множество mp3-файлов (сайт будет для проекта записи, с которым я был активно связан).

Я хотел бы разместить исходный код для этого на GitHub , но GitHub имеет ограничение 300 МБ для их бесплатных учетных записей. Я не хочу использовать 50 МБ своего лимита на кучу mp3-файлов. Очевидно, я мог бы добавить их в .gitignoreфайл, чтобы они не попали в мой репозиторий.

Тем не менее, я развернуть в Heroku с помощью git push heroku. Файлы MP3 должны присутствовать в ветке, которую я отправляю в Heroku, чтобы они были развернуты.

В идеале, я бы хотел, чтобы .gitignoremp3-файлы были в моей локальной ветке master, чтобы при отправке этого файла на GitHub mp3-файлы не включались. Тогда я бы оставил местный производственный филиал, в котором mp3 записаны, а не проигнорированы. Чтобы развернуть, я бы слил мастера с производством, а затем отправил производственный филиал в Heroku.

Я не могу заставить это работать правильно.

Вот пример того, что я пытаюсь сделать ...

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

На данный момент Foo.ignored игнорируется в моей основной ветке, но он все еще присутствует, поэтому мой проект может его использовать.

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

Теперь у меня есть ветка с этими файлами, как я хочу. Однако, когда я переключаюсь обратно в свою основную ветку, Foo.ignored больше нет.

Кто-нибудь получил какие-либо предложения для лучшего способа установить это?

Изменить: просто чтобы уточнить, я хочу, чтобы mp3-файлы присутствовали в обеих ветках, чтобы при работе сайта локально (с использованием любой ветви) сайт работал. Я просто хочу, чтобы файлы игнорировались в одной ветке, поэтому, когда я отправляю на GitHub, они также не выталкиваются. Обычно .gitignore хорошо работает для такого рода вещей (т.е. для сохранения локальной копии файла, который не включается в push-уведомление на удаленном компьютере), но когда я переключаюсь на ветку с отмеченными файлами, а затем возвращаюсь к ветка с файлами игнорируется, файлы исчезают.

Мирон Марстон
источник
Почему файлы MP3 когда-либо должны быть переданы в хранилище?
Дэн Левенхерц
4
С помощью heroku фиксация в вашем репо - это единственный способ получить файлы, включенные в ваше приложение, при развертывании. Единственная альтернатива - использовать что-то вроде Amazon S3 для обслуживания mp3-файлов, но я бы предпочел этого избежать.
Мирон Марстон
Звучит так, будто вы спотыкаетесь о доллары, чтобы сэкономить копейки ... Rackspace Cloud очень прост в настройке, и хранить там менее 1 ГБ файлов будет очень мало ...
gahooa
3
Я заметил, что вы отметили ответ как правильный, но из того, что я прочитал, он может быть неправильным. Вы когда-нибудь пробовали ответить на этот вопрос, и он работал на вас?
цикл
2
Не по теме: Вы рассматривали возможность использования другого хоста с открытым исходным кодом? BitBucket не имеет ограничений по размеру для своих репозиториев Git, независимо от того, находятся ли они в бесплатной учетной записи или нет (хотя они упоминают, чтобы сохранить размер в пределах разумного). Пока ваше репо не выходит из-под контроля, это может быть вариантом. ПРИМЕЧАНИЕ: я не связан с BitBucket, просто счастливый клиент.
NightOwl888

Ответы:

84

Это решение работает только для определенных исправленных версий git. См. Новый ответ, указывающий на обходные пути, а также другой ответ и последующие комментарии для подсказки, какие версии могут работать.

Я написал сообщение в блоге о том, как эффективно использовать его excludesfileдля разных веток, например, для публичного github и для развертывания heroku.

Вот быстрый и грязный:

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

затем в файле .git / config добавьте эти строки:

[core]
excludesfile = +info/exclude


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

Теперь все глобальное игнорирование находится в info/excludeфайле, а ветвь - вinfo/exclude_from_public_viewing

Надеюсь, это поможет!

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

Cognition.Mind
источник
1
Извините, что занял так много времени ... но если вы не удалите файлы .gitignore, они по умолчанию будут первыми.
Познание.
4
Это не работает для меня, даже когда проект не использует .gitignore. Не возражаете против предоставления стенограммы команд, устанавливающих это с нуля ( git init, ...), и версии Git, которую вы использовали?
Давор Кубраник
34
Это решение не работает. В блоге было какое-то обсуждение, и никто не смог сделать эту работу.
spuder
2
Я уверен, что в vanilla Git это не работает и никогда не работало. Те из вас, кому удалось воспроизвести это, можете поделиться своей версией Git и другой соответствующей информацией о вашей среде? Возможно, у вас есть исправленная версия от сопровождающих Git вашего дистрибутива.
Palec
20

Важный совет : принятый ответ Cognition.Mind не работает (больше, в течение нескольких лет или, возможно, для ванильных версий git); смотрите комментарии. Действительный ответ и обходной путь можно найти здесь:

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

Другой альтернативный обходной путь (работающий для моей конкретной проблемы, но требующий ручных операций хранения или реализации хука) был бы git stash -u -a. Это утомительно, когда различия велики.

И, наконец, решение, с которым я сейчас работаю, заключается в том, чтобы разбудить мою виртуальную машину, в которой мы храним нашу среду разработки, и настроить ее info/excludesсоответствующим образом для ветви, соответственно удалив поврежденные, незафиксированные файлы / папки.

Мерфи
источник
14

Я бы настоятельно рекомендовал рассмотреть возможность размещения этих файлов MP3 на S3. Если они будут частью вашего толчка Heroku (и, следовательно, частью вашего слизняка Heroku), это значительно замедлит время запуска динамометра. Поскольку Heroku использует EC2, если файлы находятся на S3 и доступны только вашему приложению (если пользователи не имеют прямой связи с S3), вы даже не будете платить никакую плату за пропускную способность, только плату за хранение 50 МБ.

Дэвид Доллар
источник
13

Допустим, мы хотим игнорировать buildпапку из всех других веток, кроме productionветки. Как мы хотим запихнуть buildпапку в производство.

1) Не включать buildв .gitignore. Если вы сделаете это, он всегда будет игнорироваться для всех ветвей.

2) Создайте файл exclude_from_public_viewingв ./.git/infoпапке (эта папка уже существует)touch ./.git/info/exclude_from_public_viewing

3) Внутри exclude_from_public_viewingнапишите одну строку (так как вы пытаетесь игнорировать buildвсе ветки). !build

4) Есть существующий файл .git/info/exclude. Нам нужно добавить следующую строку в нем.

 build

Мы хотим игнорировать buildпапку, но не добавили ее в .gitignore. Так как мерзавец будет знать, что игнорировать? Ответ: мы добавляем его в excludeфайл и условно передаем этот файлgit config

5) Теперь мы должны условно проигнорировать buildпапку для productionветки. для этого выполните следующее

6) Существует существующий файл, который ./.git/configмы должны добавить следующее:

а) excludesfile = +info/excludeниже[core]

[core]
     excludesfile = +info/exclude

б) Создать новый раздел в конце ./.git/configкак

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

Решение 2

Есть одно умное альтернативное решение. Допустим, вы хотите добавить build/папку в productionветку и игнорировать ее во всех других ветках.

1) Добавьте его в свой gitignoreфайл.

2) В производственной ветке, при этом git add, принудительно добавляем buildпапку:git add -f --all build/

sapy
источник
И чем это отличается от принятого решения? С какой версией git вы его тестировали? Как указывает связанный ответ, он терпит неудачу, потому что branch.<name>.excludesfileв git нет поддержки (больше?), Только для core.excludesfile, и мои собственные тесты, казалось, подтвердили это.
Мерфи
@murphy работает нормально, git version 2.7.4 (Apple Git-66)и я не использовал branch.<name>.excludesfile в своем решении.
Сапи
4
@sapy: я попробовал это в соответствии с вариантом использования OP, и файл все еще исчезает, когда я переключаюсь с производства на мастер. Обратите внимание, что папка «build» должна быть зафиксирована в ветке «production». (Также отмечу, что если я не фиксирую папку «build» в ветке «production», то ветка «production» игнорирует наличие папки «build» - т. Е. [Ветка «production»]] исключает конфигурационный файл не работает). Я использую ту же версию Git, что и ваша. Я также попробовал подход [отраслевой «производственный»], чтобы игнорировать файл только в производственной ветке, он также не работает, как сказал Мерфи.
Половина
Решение 2 было то, что я искал. Спасибо!
Вячеслав Котрута
4

Вы пробовали, чтобы .gitignore был другим в вашей ветке?

Вы должны иметь возможность игнорировать то, что вы хотите, основываясь на ветке, в которой вы находитесь, если файлы не отслеживаются в этой ветке.

Kend
источник
6
Я попробовал это. Если вы посмотрите на команды, которые я опубликовал выше, вы увидите, что именно это я и сделал. Проблема в том, что когда я переключаюсь с ветки с зарегистрированными файлами на ветку с игнорируемыми файлами, git отбрасывает файлы. Я хочу сохранить mp3-файлы в моей основной ветке, чтобы сайт правильно работал в режиме разработки, даже если файлы игнорируются.
Мирон Марстон
1
он уже сказал, вот что он сделал. может быть, лучше просто удалить этот ответ :-) это отвлекает.
Буб
3

1. Резюме

  1. Я использую Travis CI для развертывания ( он поддерживает развертывание Heroku )
  2. Я добавляю в мой .travis.yml:

    before_deploy:
    - mv misc/.gitignore .gitignore
    

    Где misc- любая папка, содержит другую .gitignore.

    mvКоманда перемещения файла UNIX ; перезаписать, если файл уже существует.

Когда Travis CI развертывает проект, Travis CI не будет настаивать на развертывании файлов и папок провайдера , которые игнорируются misc/.gitignore(не в оригинальных .gitignoreисточниках).


2. Ограничения

  1. Этот ответ может не подходить для всех условий автора. Но этот ответ отвечает на вопрос «Используя git, как мне проигнорировать файл в одной ветви, но зафиксировал ли он в другой ветви?»
  2. Я не пользователь Heroku, мои примеры для GitHub , а не для Heroku. Данные этого ответа у меня работают в GitHub, но могут не работать на Heroku.

3. Актуальность

Этот ответ актуален для апреля 2018 года. В дальнейшем данные этого ответа могут устареть.


4. Демонстрация

мой настоящий проект .

Пример успешного развертывания .

4.1. задача

Я развертываю свой проект из ветки src в ветку dest того же хранилища.

Я хочу, чтобы этот файл PaletteMira.suricate-profile:

  • Локальная машина - существует для всех филиалов,
  • удаленная ветка src - не существует,
  • удаленная ветка dest - существует.

Если я правильно понял автора вопроса, у него схожая задача.

4.2. ЦСИ

Источники ветки - СашаЯМЛ .

Часть .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

Часть .gitignore:

*.sublime-snippet
*.suricate-profile

Часть misc/.gitignore

*.sublime-snippet

*.suricate-profileне в misc/.gitignore.

PaletteMira.suricate-profile не существует в этой ветке удаленно, но существует локально.

4,3. Dest

филиал назначения - SashaDevelop

Часть .gitignore:

*.sublime-snippet

*.suricate-profileне в misc/.gitignore.

PaletteMira.suricate-profileсуществует для этой ветки удаленно и локально.

4.4. Действия по воспроизведению

Я включаю хранилище PaletteMira GitHub для Travis CI → Я устанавливаю переменную среды $GITHUB_TOKEN со значением - мой токен GitHub → Я делаю любые коммиты в мою ветку src.

Если нет ошибок, я должен получить ожидаемое поведение .

Саша Черных
источник
0

Можете ли вы совершить и оттолкнуть от Heroku?

Например, добавьте аудио, вставьте их в github и в heroku, удалите файлы из рабочей копии на Heroku. Удалите аудио из репозитория, но не с диска, затем верните это изменение в github.

Том
источник