Пометить файл как «uncommitable» с помощью Git

41

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

Есть ли способ пометить файл как недоступный для Git, чтобы он не мог появиться на GitHub?

Адам Картер
источник
1
Тангенциальное предложение: это может быть неприменимо на каждой платформе, так как некоторые из них очень сильно привязаны к файлам конфигурации, но вы можете рассмотреть возможность использования подхода 12factor для сохранения этих параметров в среде: 12factor.net/config . То есть код приложения никогда не предполагает наличие файла конфигурации. (В отличие от частного сценария запуска, который устанавливает их, но никогда не покидает ваш локальный компьютер.)
millimoose
1
Если вы случайно зафиксировали их, убедитесь, что вы удалили их из полной истории git (другие вопросы объяснят как), потому что даже если вы удалите и проигнорируете ее, старая подтвержденная версия останется в истории и будет отображаться на Github.
curiousdannii
3
Обратите внимание, что все ответы на самом деле не отвечают на ваш вопрос. Они не делают файл неприемлемым, они просто настраивают git так, чтобы он игнорировал его по умолчанию. Но если вы случайно вставите это имя файла в командную строку git, вы можете в конечном итоге передать его, даже если оно соответствует шаблону .gitignore. AFAIK, нет 100% полностью защищенного способа, gitчтобы избежать фиксации конкретного файла во всех случаях. Хотя это можно рассматривать как функцию ... позволяющую явным командам переопределять общие конфигурации.
Бакуриу
Вы можете удалить жестко запрограммированные пароли и перейти на более безопасную альтернативу. После этого вы можете переключать пароли базы данных. Старые пароли все еще находятся в коммитах, но они устарели, как только кто-то сможет их прочитать. Я уверен, что вы не можете изменить коммит, если он уже создан.
BlueWizard,
3
В дополнение к тому, что сказал @curiousdannii, у GitHub есть целая страница, посвященная тому, как удалить конфиденциальные данные, которые вы случайно зафиксировали. Помимо прочего, на этой странице написано, что нужно менять любые пароли и ключи, которые вы случайно опубликовали. help.github.com/articles/remove-sensitive-data
Кевин - Восстановить Монику

Ответы:

67

Есть ли способ пометить файл как недоступный для Git, чтобы он не мог появиться на GitHub?

Во-первых, нет никакого способа, чтобы некоторые файлы и коммиты были видны в вашем локальном Git-репозитории, но как-то не видны в GitHub; если у вас есть файл, зафиксированный в Git, он появится в GitHub.

Во-вторых, не существует простого и практичного способа пометить отдельный файл как «непригодный для использования». Но определенно есть способ игнорировать файл в репозитории Git: добавляя файлы, включая их относительный путь, если необходимо - в .gitignoreфайл :

.gitignoreФайл определяет намеренно неотслеживаемые файлы, Git должны игнорировать. Файлы, уже отслеженные Git, не затрагиваются; см. примечания ниже для деталей.

Создать простой .gitignoreдовольно просто, так как это простой текстовый файл. Так, например, если бы у меня был config.phpфайл в вашем корне, вы бы сделали это; Предполагается, что вы используете PHP, но концепция применима для любой установки. Также я использую Nano в качестве моего текстового редактора в этом примере, но не стесняйтесь использовать любой текстовый редактор, который вы обычно используете для этого:

nano .gitignore

И просто добавьте это имя файла в этот файл:

config.php

Сохраните его, и теперь Git просто проигнорирует этот файл.

Тем не менее, что я хотел бы сделать для таких настроек, как это, чтобы держать пример конфигурации / примера в чистом виде от деликатных особенностей в репозитории, поэтому у меня есть некоторая ссылка на то, что формат файла конфигурации - это файл с именем примерно так:

config.SAMPLE.php

Таким образом, вы точно знаете, как config.phpфайл должен быть настроен через Git, config.SAMPLE.phpи вы можете быть уверены, что config.phpGit никогда не затрагивает его.

Кроме того, если вы планируете демонстрировать свой код, вы должны ожидать, что кто-то попытается взять этот код и каким-то образом внедрить его в своей собственной системе. Помните, что мы не вы, и без примера файла конфигурации в вашем репо, люди не будут действительно понимать, как реализовать код самостоятельно. Черт возьми, они могут даже подумать, что вы не компетентны, потому что вы не предоставили базовый пример конфигурации.

JakeGould
источник
11
+1 за правильный ответ и предложение образца файла конфигурации. Некоторые библиотеки, такие как Figaro для Ruby, подталкивают вас в этом направлении. У вас должен быть файл примера, зафиксированный со значениями, похожими на реальные значения, чтобы человек, который просматривает ваш код, знал, как должна выглядеть среда. Некоторые платформы, такие как Heroku, используют переменные среды, поэтому вы можете настроить свою конфигурацию на что-то подобное database_url = Environment.DATABASE_URLи оставить комментарий выше, например # postgres://username:password@localhost/dbname.
Крис Cirefice
@ChrisCirefice Спасибо! Меня всегда поражает то, что появляются новые «инструменты», которые должны напоминать вам об очевидном: если этот код будут читать другие люди, то что именно делает не объяснение того, как работает конфигурация? Еще раз спасибо.
JakeGould
27

Вы также можете добавить хук перед фиксацией для реализации проверок работоспособности. В каталоге .git/hooksкаждого репозитория git есть несколько примеров скриптов.

Вызываемый скрипт pre-commitвыполняется, если он существует перед каждым коммитом, и ненулевое возвращаемое значение отменяет коммит.

Например, у вас может быть простой скрипт вроде этого:

#! /bin/sh -e
git ls-files --cached | grep -qx 'filename' && { echo "Excluded file included in the commit" >&2; exit 1; }
exit 0

И если это filenameсовпадает, фиксация завершается неудачно.

Юхо Остман
источник
1
+1 это правильный ответ, который фактически предотвращает явное добавление и фиксацию файла.
R ..
Действительно, хотя рекомендуемая практика не полагается на наличие этой профилактики (т.е. используйте вместо нее `.gitignore).
Дэвид Z
2
@R .. Да и нет. В то время как вопрос гласит, «помечая файл как неприемлемый», дух «препятствует тому, чтобы файл был зафиксирован». Реальность создания .gitignoreявляется очень распространенной и общепризнанной практикой для любого, кто использует Git. Но сценарий предварительной фиксации не используется большинством пользователей Git. Это требует определенных знаний по настройке и истинной причины, почему такой метод предпочтительнее простого использования .gitignoreфайла. Но это очень полезно для некоторых более сложных случаев, но это определенно концепция, которую вы бы использовали, когда действительно знаете, что вам нужно ее использовать.
JakeGould
2
Я мог бы использовать это в ситуациях, когда вы не можете доверять .gitignore на 100% (вы можете сделать что-то глупое, случайно потребовав, чтобы git добавил файл для коммитов). Или, может быть, кто-то другой может отредактировать файл .gitignore (в конце концов, он находится под контролем версий). Если вам действительно нужен тестируемый процесс, это то, что вы можете включить в такой процесс.
Cort Ammon
@CortAmmon это не всегда о доверии. Вы можете добавить некоторую временную и непубличную отладочную информацию в ваш исходный код, которую вы не хотите фиксировать, но вы не можете игнорировать такой файл. Вместо этого вы хотите проверить его перед совершением, если в нем нет ничего противозаконного . Это выглядит как хорошее решение для этого варианта использования. И на самом деле, именно так я и нашел этот вопрос, потому что это мой вариант использования.
t3chb0t
12

Что сказал @JakeGould. В некоторых случаях вы также можете использовать специальные биты файлов, такие как skip-worktreeили assume-unchangedкоторые могут быть установлены следующим образом; различия между ними см. в ответе «Переполнение стека» :

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

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

PHK
источник
8

Используйте .gitignoreкак @JakeGould сказал. Кроме того, некоторая связанная информация:

  • .gitignoreпредотвращает отслеживание файлов; если они уже отслежены, используйте git rm --cachedдля их удаления
  • файлы / шаблоны в $GIT_DIR/info/excludeтакже будут игнорироваться
  • файлы / шаблоны в файле, указанном в файле core.excludesFile пользователя, ~/.gitconfigтакже игнорируются.

Смотрите официальную документацию Git для более подробной информации.

46and2
источник
2

Чтобы расширить на вопросы Джейка и 46: одна очень хорошая практика - иметь постоянное расширение, которое вы используете для файлов, в которые вы включаете личную информацию, и использовать, .gitignoreчтобы всегда исключать файлы с таким расширением глобально (используя .gitconfigфайл, как упоминалось в другом месте, чтобы его всегда игнорировали для вашего пользователя).

Таким образом, вы можете иметь, например:

/projectname/mypasswords.exc 

и если вы исключили *.excглобально, то вы знаете, что оно не будет зафиксировано, даже если вы забудете отдельно исключить этот конкретный файл.

Джо
источник