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

发布于 2024-08-13 17:09:16 字数 1285 浏览 7 评论 0原文

我有一个项目要部署到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

梦中楼上月下 2024-08-20 17:09:16

此解决方案似乎仅适用于某些已修补的 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/ 中except_from_public_viewing

http://cogniton-mind .tumblr.com/post/1423976659/howto-gitignore-for- different-branches

This solution appears to work only for certain, patched versions of git. See a new answer pointing to workarounds and another answer and subsequent comments for a hint which versions may work.

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:

$ git branch public_viewing
$ cd .git/
$ touch info/exclude_from_public_viewing
$ echo "path/to/secret/file" > info/exclude_from_public_viewing 

then in the .git/config file add these lines:

[core]
excludesfile = +info/exclude

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

Now all the global ignore stuff is in the info/exclude file and the branch specific is in the info/exclude_from_public_viewing

http://cogniton-mind.tumblr.com/post/1423976659/howto-gitignore-for-different-branches

别靠近我心 2024-08-20 17:09:16

重要提示: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.

生来就爱笑 2024-08-20 17:09:16

假设我们要忽略除 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

我们想要忽略 build 文件夹,但尚未将其添加到 .gitignore 中。那么 git 如何知道要忽略什么?答案是我们将其添加到 exclude 文件中,并有条件地将该文件传递给 git config

5) 现在我们必须有条件地取消忽略 build 文件夹代码>生产分支。为此,请执行以下操作

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/ 文件夹,并在所有其他分支中忽略它。

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

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

Let's say we want to ignore build folder from all other branch except production branch . As we want to push build 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) folder touch ./.git/info/exclude_from_public_viewing

3) Inside exclude_from_public_viewing write one line (As you are trying to ignore build for all the branches).
!build

4)There's an existing file .git/info/exclude . We need to add following line in it.

 build

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 to exclude file and conditionally passing that file to git config

5) Now we have to conditionally unignore build folder for production branch. to do that perform following

6) There is a existing file called ./.git/config we need to add following -

a) excludesfile = +info/exclude below [core]

[core]
     excludesfile = +info/exclude

b) Create a new section in the end of ./.git/config as

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

Solution 2

There is one smart alternate solution . Lets say you want to add build/ folder in production branch and ignore it in all other branches.

1) Add it to your gitignore file.

2) In production branch, while doing git add, force add build folder: git add -f --all build/

原来分手还会想你 2024-08-20 17:09:16

我强烈建议考虑将这些 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.

隱形的亼 2024-08-20 17:09:16

您是否尝试过让 .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.

恏ㄋ傷疤忘ㄋ疼 2024-08-20 17:09:16

1.总结

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

    before_deploy:
    - mv 杂项/.gitignore .gitignore
    

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

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

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


2. 局限性

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

3. 相关性

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


4. 演示

我的真实项目

成功部署示例

4.1.任务

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

我想要该文件 PaletteMira.suricate-profile

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

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

4.2. src

源分支 - SashaYAML

.travis.yml< 的一部分/strong>

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< 的一部分/code>

*.sublime-snippet
*.suricate-profile

misc/.gitignore 的一部分

*.sublime-snippet

*.suricate-profile 不在 misc/.gitignore 中。

PaletteMira.suricate-profile 远程不存在于该分支中,但存在于本地。

4.3. dest

目标分支 — SashaDevelop

.gitignore

*.sublime-snippet

*.suricate-profile 不在 misc/.gitignore 中。

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

4.4.重现步骤

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

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

1. Summary

  1. I use Travis CI for deploying (it supports Heroku deployment)
  2. I add to my .travis.yml:

    before_deploy:
    - mv misc/.gitignore .gitignore
    

    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

  1. This answer may not be suitable for all conditions of the author. But this answer answers the question “Using git, how do I ignore a file in one branch but have it committed in another branch?”
  2. I'm not Heroku user, my examples for GitHub, not for Heroku. Data of this answer works for me in GitHub, but may doesn't work on Heroku.

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:

  • Local machine — exists for all branches,
  • src remote branch — not exists,
  • dest remote branch — exists.

If I correctly understood the author of the question, he have similar task.

4.2. src

sources branch — SashaYAML.

Part of .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

Part of .gitignore:

*.sublime-snippet
*.suricate-profile

Part of misc/.gitignore

*.sublime-snippet

*.suricate-profile not in misc/.gitignore.

PaletteMira.suricate-profile not exists in this branch remotely, but exists locally.

4.3. dest

destination branch — SashaDevelop

Part of .gitignore:

*.sublime-snippet

*.suricate-profile not in misc/.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.

浅忆流年 2024-08-20 17:09:16

你能从 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.

乖乖公主 2024-08-20 17:09:16

Github 现在支持大文件存储,请在此处查看更多信息 https://git-lfs.github.com/

Github now has support for Large file storage, see more here https://git-lfs.github.com/

月竹挽风 2024-08-20 17:09:16

最初的问题有点奇怪,但我遇到了它,因为我刚刚写了一篇关于它,我认为这可能对某人有帮助。

我个人已经通过 Git hooks 解决了这个问题a href="https://typicode.github.io/husky/#/" rel="nofollow noreferrer">husky - 似乎是最简单、最可靠的解决方案。

显然,我建议阅读这篇文章,但这里是重现步骤

  • 第 1 步: yarn add -D husky &&纱线哈斯基安装
  • 步骤2: 纱线哈斯基添加.husky/post-checkout
  • 步骤3: mkdir .husky/吉蒂尼奥雷斯 && cp .gitignore .husky/gitignores
  • 第 4 步: touch .husky/gitignores/.gitignore_husky
  • 第 5 步: 复制并粘贴 < a href="https://gist.github.com/Poolshark/52e9ee27ddad34faff282f9b1f716bc9" rel="nofollow noreferrer">此要点内容到 .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

  • step 1: yarn add -D husky && yarn husky install
  • step 2: yarn husky add .husky/post-checkout
  • step 3: mkdir .husky/gitignores && cp .gitignore .husky/gitignores
  • step 4: touch .husky/gitignores/.gitignore_husky
  • step 5: copy and paste this gist content into .husky/post-checkout
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文