Full-Stack PHP/JS developer
0,2
рейтинг
19 ноября 2013 в 12:39

Разработка → Правильные способы исключения файлов в Git

Git*
Иногда встречаю в файле .gitignore то, чего там быть никак не должно. Например, папка .idea, в которой лежат конфиги известных IDE от JetBrains. Это часть вашего рабочего окружения и она никаким боком не относится к проекту и репозиторию. Если над проектом работает несколько человек и каждый из них добавит конфиги своего окружения в .gitignore, то он превратится в нечитаемую помойку.

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

Исключение для репозитория


Когда у вас есть файлы, которые специфичны для данного проекта и для вашего рабочего окружения(например, логи, third-party утилита) используйте .git/info/exclude. Этот файл не коммитуется и остается только в локальном репозитории.

Исключение для компьютера


Когда у вас несколько проектов и везде создается что-либо, что вы не хотите коммитить(например, *.swp файлы Vim) используйте ~/.gitconfig. Вышеприведённый пример папки .idea, которая создается для каждого проекта как раз подходит сюда. Создайте файл .gitexcludes и выполните:

git config --global core.excludesfile ~/.gitexcludes

или вручную добавьте в ~/.gitconfig:
[core]
	excludesfile = ~/.gitexcludes

Сразу после сохранения ~/.gitconfig вы не должны видеть указанные файлы/папки в списке Untracked files.

Я люблю Git, но и он порой непоследователен в мелочах. Обращаю ваше внимание на то, что в первом случае мы редактируем файл .git/info/exclude (без s на конце), а во втором используем опцию excludeSfile (c s в середине). Не потеряйте время из-за возможной опечатки.

Работа с Git в большинстве случаев означает работу в команде, поэтому не усложняйте жизнь тем, кто будет работать с вами деталями вашего рабочего окружения. Хороших коммитов! :)
@limonte
карма
69,7
рейтинг 0,2
Full-Stack PHP/JS developer
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (67)

  • +15
    А потом кто-нибудь, у кого эти .gitconfig не настроены — возьмет и закоммитит все, что под руку попадется.
    • +4
      Ну и дурак, что с того?
      • +8
        Да ничего, просто потом разгребать.
      • –4
        А если это новичек? Тоже дурак?
        • 0
          Ну «дурак» — это грубовато. Но, ДА! Новичок на то и новичок, что опыта у него маловато. И в таких случаях не обзывать людей надо, а учить.

          PS: В крайнем случае «проучить», если одна и та же оплошность постоянно повторяется.
    • +6
      Для этого и сделаны пулл-реквесты — чтобы какой-нибудь чудак не коммитил ерунду.
      • +4
        У вас гит только гитхубом ограничивается?
        • +15
          А пулл-реквесты только на гитхабе?
          • –24
            нет, но, я думаю, смысл все уловили.
            • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          Нет, у меня всякие чудаки не имеют доступа в основной репозиторий безотносительно.
          А вам понятие пулл-реквеста только по гитхабу знакомо?
          Вот неплохой мануал про это, там и про git request-pull можно прочитать.
          • –4
            По принципу Мерфи, такой чудик в вашей команде рано или поздно появится. Пусть это будет новичек и это будет его первый коммит, но потом разгребать.
            Я лучше буду уверенным, что сделав пул, коммит и пуш — ничего в репозитории не изменится.
            • +3
              Ну так первый коммит и превратится в первый пулл-реквест, я же об этом выше написал.

              сделав пул, коммит и пуш — ничего в репозитории не изменится
              А зачем вносить пустой коммит? Вы что-то другое хотели сказать, наверное.
              • –2
                > Вы что-то другое хотели сказать, наверное.

                Нет, я хотел сказать именно то, что сказал. У команды, в которой игноры раскиданы вот по таким волшебным местам, у новичка, который работает первый день такой коммит будет не пустой. А вот у команды, в которой используется нормальный .gitignore коммит будет пустой, ну или содержать именно те и только те изменения, который были сделаны умышленно.
                • +1
                  а если новичек настроил какой нибудь другой IDE? где папка не .idea а другая…
            • 0
              Эдак вам придется делать файлы .gitignore с содержимым вида

              *
              !.gitignore
              !foo/bar
              # И так еще тысячи строк?
              
              • 0
                Почему-то не приходится.
          • –6
            or run the git request-pull command and e-mail the output to the project maintainer manually.
            Представил, как в команде разработчиков кто-то сидит и апплаит патчи.
            • +14
              Представили Линуса Торвальдса и других разработчиков ядра Linux? Вы молодец.
          • +2
    • 0
      Закоммитит со своей машины то чего нет в репозитории?
  • 0
    Спасибо. Не знал.
  • +5
    На самом деле, настройка гита на рабочей машине девелопера в команде тоже должна происходить централизованно.

    Проблема в том, что, во-первых, каждый будет тратить свое время на настройку одного и тогоже. В команде зачастую 80% настроек одинково (почти все пользуются одним ide и т.п.)

    Во-вторых, если централизованно этого не делать, то обязательно что-нибудь забудется и протечет в репозиторий. Человеческий фактор он есть.

    Вы не думали как можно настройку гита положить тоже под vcs или сделать командный дистрибутив?
    • +5
      не нужно парится — пошел на гитхаб и скачал .gitignore для своего языка / IDE / фреймворка
      • +1
        Не юзабельно
        качается оно один раз а потом собирается из нескольких свой
        потому как например юзаешь симфони2, для нее есть файл, но еще юзаешь идею, для которой есть еще один файл
        а потом еще юзаешь на разработческой машине складывание логов в папочку проекта, которые тоже заигнорить надо.
        в результате собираешь свой из двух-трех, а потом он качует из проекта в проект.
      • 0
        gitignore.io/ удобнее будет, имхо…
        • 0
          Не все любят исполнять на своей машине код, приходящий при каждом вызове со стороннего ресурса.
          • 0
            Почему при каждом вызове?
            • 0
              Ошибся, здесь только отдается результат выполнения функции:
              function gi() { curl http://gitignore.io/api/\$@ ;}
              


              Перепутал ещё с чем-то из таких утилит, использующих паттерн
              curl http://some-url/ | bash -s
              
    • +3
      И даже цвета редактора тим лида должны спускаться в консоли нижестоящих. Аминь.
  • +50
    Лучше загадить gitignore, чем репу.
  • –10
    .idea это не конфиги, а кэш. а я ведь даже их продуктами не пользуюсь, что бы знать.
    • +6
      Вы не правы.
      The .idea directory contains a set of configuration files (.xml). Each file contains only a portion of configuration data pertaining to a certain functional area which is reflected in the name of a file, for example, compiler.xml, encodings.xml, modules.xml.
      proof
      • –11
        странно но при удалении этой папки ничего не ломалось ни у кого
        • +3
          И не должно.
  • +7
    Если в проекте используется, к примеру, Idea, то скорее всего её используют все разработчики (ну, редко бывает иначе). Так почему бы один раз не положить в gitignore данные для Idea? Неужели лучше отвлекать N человек на настройку локальных репозиториев?

    А если какой-то фанат другой IDE решит её использовать, то во-первых, не умрёт ваш gitignore от десятка лишних строк, а во-вторых, вот этого чудака и можно (и нужно!) заставить настраивать локальный репозиторий указанным в статье способом.
    • +1
      Внесу свои 3 копейки. Используем как раз Idea, но проект собираем с помощью maven из которого Idea умеет импортировать проект.

      Сначала закоммитили .idea для удобства и вроде бы все шло хорошо, но потом началось веселье: Idea занимается в фоне особой магией, и иногда меняет порядок записей в файлах — регулярно вылезали конфликты на пустом месте. Кроме того, на каждую зависимость из maven в подпапке .idea на лету создается XML-файл и иногда не удаляется при чекауте другого бранча без этой зависимости (см. фоновая магия), для чекаута обратно нужно вручную чистить.

      Через несколько недель эта возня всем надоела и .idea отправилась в .gitignore.

      P.S. В .gitignore у нас помойка, но пока никто не жалуется.
  • 0
    а просто в нужную папку положить .gitignore с * — не?
    • 0
      Речь о том, что бывают иногда именно личные файлы, может какой-то удобный мне конфиг с индивидуальными данными, зачем же его в .gitignore добавлять и коммитать?
  • +4
    Не задумывался как-то над этим.

    У нас обычно каждый в .gitignore свои исключения добавляет. Не знаю, может у нас просто проекты небольшие, но особой путаницы не происходило ни разу.
    • +1
      Тоже не нахожу огромной проблемы в этом.
      К тому же хорошо — людям с одинаковыми окружениями не придётся мучаться с добавлением уже имеющихся вещей в .gitignore, достаточно один раз проверить что лишних untracked не появляется после импорта в своё окружение.
  • +2
    А что ж вы тогда оставите в .gitignore, можно поинтересоваться?
    • 0
      cache/*
      avatars/*
      .sass-cache
      • 0
        Я имел ввиду, с обьяснением, почему. Вы обьяснили, почему что-то не надо добавлять туда, если можно, обьясните что и почему надо.
      • +1
        Лучше так:

        cache/
        avatars/
        .sass-cache 
        

        Иначе git clean -df и git stash -u будут удалять Ваши папки.
        • 0
          А как сделать чтобы он ideшные файлы из корня проекта не удалял?
          • +1
            Добавьте их в .gitignore. Должно помочь.
  • 0
    А не проще в .gitignore сначала всё запретить и разрешить только то, что нужно. Например
    *
    !.gitignore
    !*.py
    !*.html
    
    • +4
      Нет, не проще.
      После такого решения вы или кто-то из вашей команды потратит уйму времени, чтобы понять, почему же у него картинки.jpg появились в репозитории, картинка.jpeg – нет.
  • +4
    Спасибо. В целом с мнением автора я не согласен — как и многим тут, мне кажется, что окружение лучше писать в .gitignore.
    Но иногда хочется заигнорить какие-то свои тестовые/экспериментальные контроллеры, вьюхи, тесты или ещё что-нибудь, которые удалять пока рано, в общий gitignore пихать смысла нет, а видеть их болтающимися в текущих незакоммиченных изменениях не хочется.
    • +7
      С мнением автора тоже категорически не согласен.

      Репозиторий должен быть самодостаточным, – взял и начал работать. Не тратя время на разбирательства, кто и как готовил репозиторий и свое локальное окружение.

      Аргументация в пользу таких усложнений, как я понимаю только одна – .gitignore превратиться в помойку.

      Файлы проектов IDE – сколько актуальных ide или редакторов существует для вашего стека? Не думаю, что больше 5.
      Дотфайлы локального окружения для запуска проекта (если такие есть).
      Всякий мусор ОС (.DS_Store, thumbs_db).
      Файлы специфичные для вашего стека, которых не должно быть в репозитории.

      Первые два пункта – это 10-15 строчек, в худшем случае.
      Разве это стоит вероятности наступления на БольшиеГрабли?
  • +6
    «Раз пошла такая пьянка — режь последний пирожок!»

    Расскажу, как это устроено у нас в рабочем репе.

    1. Dev-окружение каждого разработчика — виртуальная машина с настроеным Сhef-client через Vagrant, образ которой тянется из локальной сети и обновляется оттуда же.

    2. Мы стараемся держать весь стек as new as possible, соответственно, мы решили сползти на клиент-серверный chef, все виртуальные машины настроены как клиенты, в итоге каждый разработчик получает последнюю версию самого актуального стека практически без последствий (обновление образа — среда, тестирование — среда-пятница, раскатка обновлений на все дев-машины — суббота), нет проблем с разными версиями либ, т.к. везде используется одно и то же. В общем, много плюшек.

    3. Политика работы с .git'ом — все конфиги и прочее обозначены в .gitignore проекта, исходники конфигов проименованы через <name>.default.cfg, при этом есть доходчивый мануал по настройке окружения, ну и бинарные файлы/конфиги добавляются по необходимости через --force. Настройка же через Chef позволяет полностью исключить этап «запуска» на машине разработчика. Не нужно копировать конфиги, настраивать подключения, etc — это все уже реализовано в рецепте application и нужно всего лишь подождать 5-10 минут.

    4. Отдельное слово про пустые каталоги — если в проекте 100% нужна какая-то точка на FS — мы форсим добавление .gitfolder в этой точке, на который уже есть запись в .gitignore.

    5. Все изменения в .gitignore бьются по разделам и комментируются, дабы избежать глобальной помойки для «будущих» поколений.

    Как-то так, в общем.
    Путь к такой схеме работы достоин отдельной статьи, ибо набили шишек мы очень порядочно. В том числе и с перечисленными пунктами топикстартера…
    • 0
      Если не секрет, какой у вас размер команды?
      И какой основной стек технологий, на чем разрабатываете)?
      • 0
        В лучшие времена до 15 программистов, сейчас в среднем 8-10 человек.
        Разрабатываем Web, PHP/JS/Python
    • 0
      Спасибо за наводки (Chef Vagrant).
      Тоже пытаюсь похожую систему настроить — рассинхрон версий и длительный подъем окружения начинает напрягать.
      Если была бы статья — было бы здорово.
  • +1
    Заставлять ленивых разработчиков настраивать окружение вместо того, чтобы написать нормальный проектно-специфичный .gitignore… С моей точки зрения это глупо.
  • +1
    Не нахожу особо проблеными лишние десять-двадцать строк в .*ignore для используемых IDE и редакторов, честно говоря. Никто из команд, где я работал, тоже не высказывал опасений.
  • 0
    Спасибо. Как раз сегодня возникла проблема с idea.
  • 0
    Папку .idea как раз можно было бы и положить в реп. Так можно зафиксировать стиль кода, например.
    • 0
      Только после этого не стоит клонировать её по другому пути, то idea начнет глючить. Не лучший вариант.
      • 0
        А можно подробнее? Тут об этом не пишут.
        • 0
          Сталкивался с абсолютными путями в .idea где-то года полтора назад. Проект на java с использованием maven. Не репортил за ненадобностью.

          Сейчас посмотрел эти xml глазами, вроде всё шаблонизировано.

          По ссылке:
          .ipr file based format
          Share the project .ipr file and and all the .iml module files, don't share the .iws file as it stores user specific settings.

          .idea directory based format
          Share all the files under .idea directory in the project root except the workspace.xml and tasks.xml files which store user specific settings, also share all the .iml module files.

          Явно указывают, какие файлы добавлять не стоит.
          • 0
            Странно добавлять в реп файлы, которые изменяются при каждом запуске IDE. Конфиги проекта в других файлах.
            • 0
              .idea была добавлена по ошибке. Хуков для предотвращения добавления .project, .nbproject, .idea и прочего в репозиториях я не делал, считая инструктаж достаточной мерой.

              В какой-то прекрасный день обнаружился такой подарок, уронивший idea. Версию не помню, возможно была EAP. Чистка репозитория и мозгов пострадавшего исправили ситуацию.
  • 0
    Неприятно, когда .gitignore встречается во вложенных папках. Проверяю так:
    $ find . -iname .gitignore
    
  • 0
    Я статью написал о файле .gitignore со всевозможными примерами.
  • 0
    для Windows вместо:

    git config --global core.excludesfile ~/.gitexcludes

    надо делать:

    git config --global core.excludesfile %userpath%/.gitexcludes

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.