使用git,如何忽略一个分支中的文件,但又将其提交到另一个分支中?


157

我有一个要部署到Heroku的项目。源代码树包含一堆mp3文件(该网站将用于与我密切相关的录音项目)。

我想将其源代码放在GitHub上,但是GitHub的免费帐户限制为300 MB。我不想在一堆mp3文件上使用50 MB的限制。显然,我可以将它们添加到.gitignore文件中以将其排除在我的存储库之外。

但是,我使用部署到Heroku git push heroku。mp3文件必须存在于我推送到Heroku的分支中,以便部署。

理想情况下,我希望.gitignore在本地master分支中找到mp3文件,以便在将其推送到GitHub时不包含mp3。然后,我将保留已提交而不是忽略mp3的本地生产分支。要进行部署,我需要将master合并到生产中,然后将生产分支推送到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在我的master分支中被忽略,但是它仍然存在,因此我的项目可以使用它。

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

现在,我有一个分支,可以根据需要提交这些文件。但是,当我切换回主分支时,Foo.ignored消失了。

任何人都提出了更好的设置建议?

编辑:只是为了澄清,我希望两个分支中都存在mp3文件,以便当我在本地运行站点(使用任一分支)时该站点可以工作。我只希望文件在一个分支中被忽略,所以当我推送到GitHub时,它们也不会被推送。通常,.gitignore可以很好地用于这种情况(即,保留文件的本地副本,该副本不会包含在推送到远程的操作中),但是当我切换到带有已签入文件的分支,然后返回到忽略文件分支,文件消失。


为什么MP3文件以往任何时候都需要被提交到库?
Dan Loewenherz,2009年

4
使用heroku时,提交回购文件是部署时获取包含在应用程序中的文件的唯一方法。唯一的选择是使用Amazon S3之类的东西来提供mp3,但我希望避免这种情况。
迈伦·马斯顿

听起来您要花很多钱才能节省几分钱... Rackspace Cloud非常易于安装,并且在其中存储<1 GB的文件将花费很少的

3
我注意到您将答案标记为正确,但是根据我的阅读,它可能不正确。您是否曾经尝试过答案,对您有用吗?
循环

2
主题外:您是否考虑过使用其他开源存储库主机?BitBucket的Git存储库没有大小限制,无论它们是否在免费帐户中(尽管它们确实提到要使大小保持合理)。只要您的存储库不会失控,这就是一种选择。注意:我与BitBucket无关,只是一个满意的客户。
NightOwl888

Answers:


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


1
抱歉,花了这么长时间..但是,如果您不删除.gitignore文件,它将默认为第一个。
Cognition.Mind

4
即使项目不使用.gitignore,这对我也不起作用。您介意提供从头开始设置此命令的脚本(git init,...),以及您使用的Git版本吗?
Davor Cubranic 2012年

34
此解决方案不起作用。博客上进行了一些讨论,也没有人能够进行这项工作。
13年


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子弹的一部分)会大大减慢您的dyno启动时间。由于Heroku使用EC2,因此,如果文件位于S3上并且只能由您的应用访问(如果用户未直接链接到S3),则您甚至无需支付任何带宽费用,而只需支付存储50MB的费用。


13

假设我们要忽略buildbranch以外的所有其他分支的folder 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中添加它。那么git如何知道要忽略什么呢?答案是我们要将其添加到exclude文件中,并有条件地将该文件传递给git config

5)现在我们必须有条件地忽略build文件夹的production分支。为此,请执行以下操作

6)有一个现有文件,./.git/config我们需要添加以下内容-

a)excludesfile = +info/exclude下面[core]

[core]
     excludesfile = +info/exclude

b)中创建的端部的新的部分./.git/config作为

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

解决方案2

有一个聪明的替代解决方案。假设您要build/production分支中添加文件夹,而在所有其他分支中忽略它。

1)将其添加到您的gitignore文件中。

2)在生产分支中,边做边git add强行添加build文件夹:git add -f --all build/


这与公认的解决方案有何不同?您使用哪个版本的git测试了它?正如链接的答案指出的那样,它失败了,因为不再支持branch.<name>.excludesfilegit(不再支持),仅支持core.excludesfile,而我自己的测试似乎证实了这一点。
墨菲

@murphy它可以正常使用git version 2.7.4 (Apple Git-66),我没有branch.<name>.excludesfile 在我的解决方案中使用。
Sapy 2016年

4
@sapy:我根据OP的用例进行了尝试,当我从生产切换到母版时,该文件仍然消失。请注意,“ build”文件夹应提交到“ production”分支。(另外,我注意到,如果不在“ production”分支中提交“ build”文件夹,则“ production”分支将忽略“ build”文件夹的存在,即[branch“ production”] excludesfile配置不会不起作用)。我使用与您完全相同的git版本。我还尝试了[分支“生产”]方法,仅在生产分支中忽略文件,这也不起作用,就像墨菲说的那样。
justhalf

解决方案2是我一直在寻找的东西。谢谢!
Vyacheslav Cotruta

4

您是否尝试过让.gitignore在您的分支中有所不同?

只要未在该分支上跟踪文件,您就应该能够根据所处的分支忽略您想要的内容。


6
我已经尝试过了。如果看一下我上面发布的命令,您会发现这正是我所做的。问题是,当我从签入文件的分支切换到忽略文件的分支时,git丢弃了这些文件。我想将mp3保留在我的master分支中,这样即使文件被忽略,该站点也可以在dev模式下正常运行。
Myron Marston

1
他已经说过他做了什么。也许只是删除此答案可能是最好的:-)造成干扰。
blamb

3

1.总结

  1. 我使用Travis CI进行部署 它支持Heroku部署
  2. 我添加到我的.travis.yml

    before_deploy:
    - mv misc/.gitignore .gitignore

    其中misc-任何文件夹包含另一个.gitignore

    mvUNIX命令移动文件;如果文件已经存在,则覆盖。

当Travis CI部署项目时,Travis CI不会推送部署忽略其中的提供程序文件和文件夹misc/.gitignore(不在原始.gitignore源文件中)。


2.局限性

  1. 此答案可能并不适合作者的所有情况。但这答案回答了以下问题:“使用git,如何忽略一个分支中的文件,但又将其提交到另一个分支中?”
  2. 我不是Heroku用户,我的例子是GitHub,不是Heroku。这个答案的数据在GitHub上对我有用,但在Heroku上可能不起作用。

3.相关性

该答案与2018年4月相关。将来,该答案的数据可能已过时。


4.示范

我的真实项目

成功部署的示例

4.1。任务

我将项目从src分支部署到同一存储库的dest分支。

我想要那个文件PaletteMira.suricate-profile

  • 本地计算机-所有分支机构都存在,
  • src远程分支-不存在,
  • dest远程分支-存在。

如果我正确地理解了问题的作者,那么他也有类似的任务。

4.2。src

源分支— SashaYAML

的一部分.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。目的

目的地分支— SashaDevelop

的一部分.gitignore

*.sublime-snippet

*.suricate-profile不在misc/.gitignore

PaletteMira.suricate-profile该分支在远程和本地都存在。

4.4。重现步骤

我为Travis CI启用了PaletteMira GitHub存储库 →我为环境变量设置 $GITHUB_TOKEN了值-我的 GitHub令牌 →我对src分支进行了任何提交。

如果没有错误,我必须得到预期的行为


0

您可以从Heroku提交并推送吗?

例如,添加音频,将其推送到github并进入heroku,在Heroku上删除工作副本上的文件。从存储库中删除音频,但从磁盘中删除,然后将更改推回github。


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.