使用Git将文件标记为“不可提交”


41

我想通过将一些作品上传到我的GitHub帐户来展示我的一些作品。但是,有些文件包含密码,例如数据库连接。

有没有一种方法可以使用Git将文件标记为不可提交,使其不能出现在GitHub上?


1
切线建议:可能不适用于所有平台,因为某些平台与配置文件非常吻合,但是您可以考虑采用12factor方法将这些参数保留在环境中:12factor.net/config。即,使应用程序代码从不假定配置文件的存在。(与设置这些脚本的私人启动脚本相反,但从未离开您的本地计算机。)
millimoose15年

1
如果您不小心提交了它们,请确保将其从完整的git历史记录中删除(其他问题将解释如何),因为即使您删除并忽略它,旧的提交版本也将保留在历史记录中并在Github上可见。
curiousdannii 2015年

3
请注意,所有答案并不能真正回答您的问题。他们不会使文件不可使用,他们只是配置git以便默认情况下忽略它。但是,如果您不小心将文件名插入git命令行中,即使它与中的模式匹配,也可以最终提交该文件名.gitignore。AFAIK并没有100%完全证明的方法git来避免在所有情况下都提交特定文件。尽管这可能被视为一项功能...允许显式命令覆盖通用配置。
巴库里

您可以删除硬编码的密码,然后切换到更安全的替代方法。之后,您可以切换数据库密码。旧密码仍然在提交中,但是一旦有人能够读取您的密码,它们就会过时。我非常确定,一旦它已经建立就不能更改提交。
BlueWizard,2015年

3
除了@curiousdannii所说的,GitHub上还有整页的内容,讨论如何删除您意外提交的敏感数据。除其他事项外,该页面还说要更改您不小心发布的所有密码和密钥。 help.github.com/articles/remove-sensitive-data
凯文-恢复莫妮卡

Answers:


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应如何设置文件,config.SAMPLE.php并且可以确保config.phpGit绝不会触及实际文件。

另外,如果您打算展示代码,则需要期望有人会尝试采用该代码并以某种方式在自己的系统上实现它。请记住,我们不是您,并且您的仓库中没有示例配置文件,所以人们不会真正理解如何自己实现代码。他们甚至可能会认为您没有能力,因为您没有提供基本的配置示例。


11
+1以获取正确答案,提供示例配置文件。有一些像Figaro for Ruby这样的库会朝这个方向推动。您应该拥有一个与实际值相似的值的示例文件,以便查看您的代码的人知道环境的外观。某些平台(例如Heroku)使用环境变量,因此您可以将配置设置为,database_url = Environment.DATABASE_URL并在上方留下注释# postgres://username:password@localhost/dbname
克里斯·西里菲斯

@ChrisCirefice谢谢!总是让我感到惊讶的是,新出现的“工具”应该使您想起显而易见的事情:如果其他人将要阅读此代码,那么不解释配置的工作原理究竟是什么呢?再次感谢。
JakeGould 2015年

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)。
David Z

2
@R ..是和否。当问题提出“将文件标记为可使用”时,其精神是“防止文件被提交。” .gitignore对于使用Git的任何人,创建现实 是非常普遍的做法,并且通常被理解。但是大多数Git用户并没有真正使用预提交脚本。它需要一些设置方面的知识,并且需要一些真实的原因,为什么这样的方法比简单地使用.gitignore文件更好。但这对于某些更复杂的情况非常有用,但是当您真正知道需要使用它时,绝对可以使用该概念。
JakeGould 2015年

2
我可以看到在您可能不会100%信任.gitignore的情况下使用此功能(您可能会做一些愚蠢的事情,无意中要求git添加该文件以进行提交)。或者,也许其他人可能会编辑.gitignore文件(毕竟,它受版本控制)。如果您确实需要一个可测试的过程,那么可以将其应用于这样的过程。
Cort Ammon 2015年

@CortAmmon并不总是与信任有关。您可以在源代码中添加一些您不想提交的临时非公共调试信息,但是您不能忽略该文件。相反,您想在提交之前检查它是否不包含任何非法内容。对于此用例,这看起来是一个很好的解决方案。作为事实,这就是我发现此问题的方法,因为这是我的用例。
t3chb0t

12

@JakeGould说什么。在某些情况下,您还可以使用特殊文件位,例如skip-worktreeassume-unchanged可以通过以下方式设置;有关两者之间的区别,请参见以下堆栈溢出答案

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

然后,这将隐藏对现有文件的其他更改;如果您确实希望在每次拉动之后将文件保存在其中,则可以使用该更改。但我建议您仅在真正知道自己在做什么的情况下使用它。


8

使用一个.gitignore像@JakeGould所说的。另外,一些相关信息:

  • .gitignore防止文件被跟踪;如果它们已经被跟踪使用git rm --cached来删除它们
  • 中的文件/模式$GIT_DIR/info/exclude也将被忽略
  • 用户的core.excludesFile指定的文件中的文件/模式~/.gitconfig也将被忽略。

有关更多详细信息,请参见官方Git文档


2

扩展Jake和46的答案:一个非常好的做法是对包含私人信息的文件使用一致的扩展名,并.gitignore始终在全局范围内排除具有该扩展名的.gitconfig文件(使用在其他地方提到的文件始终将其忽略)为您的用户)。

这样,您可以拥有例如:

/projectname/mypasswords.exc 

并且如果您已*.exc全局排除,则即使您忘记单独排除该特定文件,也知道不会提交该文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.