使用 git,如何忽略一个分支中的文件但将其提交到另一个分支中?
我有一个项目要部署到 Heroku。源代码树包括一堆 mp3 文件(该网站将用于我深入参与的一个录音项目)。
我想将其源代码放在 GitHub 上,但 GitHub 的免费帐户有 300 MB 的限制。我不想在一堆 mp3 文件上使用 50 MB 的限制。显然,我可以将它们添加到 .gitignore 文件中,以使它们远离我的存储库。
但是,我使用 git push heroku 部署到 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 在我的主分支中被忽略,但它仍然存在,因此我的项目可以使用它。
$ git checkout -b unignored
$ cat /dev/null > .gitignore
$ git add Foo.ignored .gitignore && git commit -m "Unignore .ignored files"
现在我已经有了一个分支,按照我的意愿提交了这些文件。但是,当我切换回主分支时,Foo.ignored 消失了。
有人对更好的设置方法有什么建议吗?
编辑:只是为了澄清一下,我希望 mp3 文件都存在于两个分支中,以便当我在本地运行该网站(使用任一分支)时该网站可以正常工作。我只是希望在一个分支中忽略这些文件,这样当我推送到 GitHub 时,它们也不会被推送。通常 .gitignore 对于这种事情效果很好(即保留未包含在远程推送中的文件的本地副本),但是当我切换到签入文件的分支,然后返回到忽略文件的分支,文件消失。
I've got a project that I'm deploying to Heroku. The source code tree includes a bunch of mp3 files (the website will be for a recording project I was heavily involved with).
I'd like to put the source code for it up on GitHub, but GitHub has a 300 MB limit on their free accounts. I don't want to use 50 MB of my limit on a bunch of mp3 files. Obviously, I could add them to the .gitignore
file to keep them out of my repo.
However, I deploy to Heroku using git push heroku
. The mp3 files must be present in the branch I push to Heroku so that they get get deployed.
Ideally, I'd like to .gitignore
the mp3 files in my local master branch so that when I push that to GitHub, the mp3s are not included. Then I'd keep a local production branch that has the mp3s committed rather than ignored. To deploy, I would merge master into production, and then push the production branch to Heroku.
I can't get this to work right.
Here's an example of what I'm trying to do...
$ git init git-ignore-test
$ cd git-ignore-test
$ echo "*.ignored" >> .gitignore
$ git add .gitignore && git commit -m "Ignore .ignored files"
$ touch Foo.ignored
At this point, Foo.ignored is ignored in my master branch, but it's still present, so my project can use it.
$ git checkout -b unignored
$ cat /dev/null > .gitignore
$ git add Foo.ignored .gitignore && git commit -m "Unignore .ignored files"
Now I've got a branch with these files committed, as I want. However, when I switch back to my master branch, Foo.ignored is gone.
Anyone got any suggestions for a better way to set this up?
Edit: just to clarify, I want the mp3 files to be present in both branches so that when I run the site locally (using either branch) the site works. I just want the files ignored in one branch so when I push to GitHub they are not pushed as well. Usually .gitignore works well for this kind of thing (i.e. keeping a local copy of a file that does not get included in a push to a remote), but when I switch to the branch with the files checked in, and then back to the branch with the files ignored, the files vanish.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我写了一篇关于如何针对不同分支有效使用
excludesfile
的博文,例如一个用于公共 github 和一个用于 heroku 部署。这是快速和肮脏的:
然后在 .git/config 文件中添加这些行:
现在所有全局忽略的内容都在
info/exclude
文件中,并且特定的分支在info/ 中except_from_public_viewing
http://cogniton-mind .tumblr.com/post/1423976659/howto-gitignore-for- different-branches
I wrote a blog post on how to effectively use the
excludesfile
for different branches, like one for public github and one for heroku deployment.Here's the quick and dirty:
then in the .git/config file add these lines:
Now all the global ignore stuff is in the
info/exclude
file and the branch specific is in theinfo/exclude_from_public_viewing
http://cogniton-mind.tumblr.com/post/1423976659/howto-gitignore-for-different-branches
重要提示:Cognition.Mind 接受的答案不起作用(已经好几年了,或者可能对于普通版本的 git 来说);看评论。可以在此处找到有效的答案和解决方法:
https://stackoverflow.com/a/29583813/2157640
另一种替代解决方法(解决我的特定问题,但需要手动存储操作或实现挂钩)将是 git stash -u -a 。当差异很大时,这很乏味。
最后,我现在采用的解决方案是对我们保存开发环境的虚拟机进行分叉,并为分支适当地设置
info/excludes
,分别删除有问题的、未提交的文件/文件夹。Important hint: The accepted answer by Cognition.Mind doesn't work (anymore, for several years now, or perhaps for vanilla versions of git); see the comments. A valid answer and workaround can be found here:
https://stackoverflow.com/a/29583813/2157640
Another alternative workaround (working for my particular problem, but demanding manual stash operations or implementation of a hook) would be
git stash -u -a
. This is tedious when the differences are large.And finally, the solution I'm now going with is having forked my VM that we hold our development environment in, and set up
info/excludes
appropriately for the branch, respectively deleting the offending, uncommitted files/folders.假设我们要忽略除
product
分支之外的所有其他分支中的build
文件夹。因为我们想要在生产中推送build
文件夹。1) 不要在 .gitignore 中包含
build
。如果您这样做,所有分支都将始终忽略它。2)在
./.git/info
(此文件夹已存在)文件夹touch ./.git/info/exclude_from_public_viewing
内创建一个文件exclude_from_public_viewing
3)在
exclude_from_public_viewing
内写一行(因为您试图忽略所有分支的build
)。!build
4) 有一个现有文件
.git/info/exclude
。我们需要在其中添加以下行。我们想要忽略
build
文件夹,但尚未将其添加到 .gitignore 中。那么 git 如何知道要忽略什么?答案是我们将其添加到exclude
文件中,并有条件地将该文件传递给git config
5) 现在我们必须有条件地取消忽略
build
文件夹代码>生产分支。为此,请执行以下操作6) 有一个名为
./.git/config
的现有文件,我们需要在
下面添加以下内容 - a)
excludesfile = +info/exclude
>[core]b) 在
./.git/config
末尾创建一个新部分,如下有一种智能替代解决方案。假设您要在
生产
分支中添加build/
文件夹,并在所有其他分支中忽略它。1) 将其添加到您的 gitignore 文件中。
2)在生产分支中,在执行
git add
时,强制添加build
文件夹:git add -f --all build/
Let's say we want to ignore
build
folder from all other branch exceptproduction
branch . As we want to pushbuild
folder in production.1) Dont include
build
in .gitignore . If you do that it will always be ignored for all branches .2) Create a file
exclude_from_public_viewing
inside./.git/info
(This folder already exists) foldertouch ./.git/info/exclude_from_public_viewing
3) Inside
exclude_from_public_viewing
write one line (As you are trying to ignorebuild
for all the branches).!build
4)There's an existing file
.git/info/exclude
. We need to add following line in it.We want to ignore
build
folder but hasn't added it in .gitignore . So how git will know what to ignore ? Answer is we are adding it toexclude
file and conditionally passing that file togit config
5) Now we have to conditionally unignore
build
folder forproduction
branch. to do that perform following6) There is a existing file called
./.git/config
we need to add following -a)
excludesfile = +info/exclude
below[core]
b) Create a new section in the end of
./.git/config
asThere is one smart alternate solution . Lets say you want to add
build/
folder inproduction
branch and ignore it in all other branches.1) Add it to your
gitignore
file.2) In production branch, while doing
git add
, force addbuild
folder:git add -f --all build/
我强烈建议考虑将这些 MP3 文件放在 S3 上。让它们成为您的 Heroku 推送的一部分(从而成为您的 Heroku slug 的一部分)将大大减慢您的 dyno 启动时间。由于 Heroku 使用 EC2,如果文件位于 S3 上并且仅由您的应用程序访问(如果用户没有直接链接到 S3),您甚至不需要支付任何带宽费用,只需支付存储 50MB 的费用。
I would strongly advise considering putting those MP3 files on S3. Having them be part of your Heroku push (and thus part of your Heroku slug) will greatly slow down your dyno startup time. Since Heroku uses EC2, if the files are on S3 and are only accessed by your app (if users aren't directly linked to S3) you won't even pay any bandwidth charges, only the charge to store 50MB.
您是否尝试过让 .gitignore 在您的分支中有所不同?
只要文件不在该分支上跟踪,您就应该能够根据您所在的分支忽略您想要的内容。
Have you tried having .gitignore be different in your branch?
You should be able to ignore what you want based on the branch you are in as long as the files are not tracked on that branch.
1.总结
我添加到我的
.travis .yml
:其中
misc
— 任何文件夹,包含另一个.gitignore
。mv
UNIX 命令 移动文件;如果文件已存在,则覆盖。当 Travis CI 部署项目时,Travis CI 不会推送到 部署提供商 文件和文件夹,在
misc/.gitignore
中忽略(不在源的原始.gitignore
中)。2. 局限性
3. 相关性
该答案与 2018 年 4 月相关。将来,该答案的数据可能会过时。
4. 演示
我的真实项目。
成功部署示例。
4.1.任务
我将项目从 src 分支部署到同一存储库的 dest 分支。
我想要该文件
PaletteMira.suricate-profile
:如果我正确理解了问题的作者,他也有类似的任务。
4.2. src
源分支 - SashaYAML。
.travis.yml
< 的一部分/strong>:.gitignore< 的一部分/code>
:
misc/.gitignore
的一部分*.suricate-profile
不在misc/.gitignore
中。PaletteMira.suricate-profile
远程不存在于该分支中,但存在于本地。4.3. dest
目标分支 — SashaDevelop
.gitignore
:*.suricate-profile
不在misc/.gitignore
中。此分支存在
PaletteMira.suricate-profile
远程和本地。4.4.重现步骤
I为 Travis CI 启用 PaletteMira GitHub 存储库 → I 设置环境变量
$GITHUB_TOKEN
的值 - 我的GitHub 令牌 → 我对我的 src 分支进行任何提交。如果没有错误,我必须得到预期行为。
1. Summary
I add to my
.travis.yml
:Where
misc
— any folder, contains another.gitignore
.mv
UNIX command move file; overwrite, if file already exist.When Travis CI deploy project, Travis CI will not push to deploying provider files and folders, that ignore in
misc/.gitignore
(not in the original.gitignore
of sources).2. Limitations
3. Relevance
This answer is relevant for April 2018. In the future, the data of this answer may be obsolete.
4. Demonstration
my real project.
Example of successful deployment.
4.1. Task
I deploy my project from src branch to dest branch of the same repository.
I want, that file
PaletteMira.suricate-profile
:If I correctly understood the author of the question, he have similar task.
4.2. src
sources branch — SashaYAML.
Part of
.travis.yml
:Part of
.gitignore
:Part of
misc/.gitignore
*.suricate-profile
not inmisc/.gitignore
.PaletteMira.suricate-profile
not exists in this branch remotely, but exists locally.4.3. dest
destination branch — SashaDevelop
Part of
.gitignore
:*.suricate-profile
not inmisc/.gitignore
.PaletteMira.suricate-profile
exists for this branch remotely and locally.4.4. Steps to reproduce
I enable PaletteMira GitHub repository for Travis CI → I set environment variable
$GITHUB_TOKEN
with value — my GitHub token → I make any commit to my src branch.If no errors, I must get expected behavior.
你能从 Heroku 提交并推送吗?
例如添加音频,将它们推送到github和heroku,删除Heroku工作副本上的文件。从存储库中删除音频,但不从磁盘中删除,然后将该更改推送回 github。
Can you commit and push from Heroku?
e.g. Add the audio, push them to github and into heroku, remove the files on the working copy on Heroku. Remove the audio from the repo but not from the disk, then push that change back to github.
Github 现在支持大文件存储,请在此处查看更多信息 https://git-lfs.github.com/
Github now has support for Large file storage, see more here https://git-lfs.github.com/
最初的问题有点奇怪,但我遇到了它,因为我刚刚写了一篇关于它,我认为这可能对某人有帮助。
我个人已经通过 Git hooks 解决了这个问题a href="https://typicode.github.io/husky/#/" rel="nofollow noreferrer">husky - 似乎是最简单、最可靠的解决方案。
显然,我建议阅读这篇文章,但这里是重现步骤
yarn add -D husky &&纱线哈斯基安装
纱线哈斯基添加.husky/post-checkout
mkdir .husky/吉蒂尼奥雷斯 && cp .gitignore .husky/gitignores
touch .husky/gitignores/.gitignore_husky
.husky/post-checkout
The original question is a little oder but I came across it since I've just written a medium article about it, I thought this might help someone.
I personally have solved this with Git hooks via husky - seems to be the easiest and most reliable solution.
Obviously, I suggest to read the article but here are the steps to reproduce
yarn add -D husky && yarn husky install
yarn husky add .husky/post-checkout
mkdir .husky/gitignores && cp .gitignore .husky/gitignores
touch .husky/gitignores/.gitignore_husky
.husky/post-checkout