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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1836742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:27:28  来源:igfitidea点击:

Using git, how do I ignore a file in one branch but have it committed in another branch?

gitgitignore

提问by Myron Marston

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).

我有一个要部署到Heroku的项目。源代码树包括一堆 mp3 文件(该网站将用于我大量参与的录音项目)。

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 .gitignorefile to keep them out of my repo.

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

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.

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

Ideally, I'd like to .gitignorethe 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.

理想情况下,我希望.gitignore我的本地 master 分支中的 mp3 文件,以便当我将其推送到 GitHub 时,不包括 mp3。然后我会保留一个本地生产分支,该分支已提交而不是忽略 mp3。为了部署,我会将 master 合并到生产中,然后将生产分支推送到 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.

此时,我的主分支中忽略了 Foo.ignored,但它仍然存在,因此我的项目可以使用它。

$ 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.

现在我有了一个提交这些文件的分支,正如我所希望的。但是,当我切换回我的主分支时, Foo.ignored 消失了。

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.

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

采纳答案by Cognition.Mind

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

此解决方案似乎仅适用于某些已打补丁的 git 版本。请参阅指向变通方法的新答案另一个答案以及后续评论,以了解哪些版本可能有效。

I wrote a blog post on how to effectively use the excludesfilefor different branches, like one for public github and one for heroku deployment.

我写了一篇关于如何有效地将excludesfile用于不同分支的博客文章,例如一个用于公共 github 和一个用于 heroku 部署。

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:

然后在 .git/config 文件中添加这些行:

[core]
excludesfile = +info/exclude


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

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

现在所有全局忽略的东西都在info/exclude文件中,特定的分支在info/exclude_from_public_viewing

Hope that helps!

希望有帮助!

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

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

回答by Murphy

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:

重要提示:Cognition.Mind 接受的答案不起作用(现在已经好几年了,或者可能是 git 的香草版本);见评论。可以在此处找到有效的答案和解决方法:

https://stackoverflow.com/a/29583813/2157640

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.

另一种替代解决方法(适用于我的特定问题,但需要手动存储操作或实现挂钩)将是git stash -u -a. 当差异很大时,这很乏味。

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/excludesappropriately for the branch, respectively deleting the offending, uncommitted files/folders.

最后,我现在采用的解决方案是分叉我们保存开发环境的 VM,并info/excludes为分支进行适当的设置,分别删除有问题的、未提交的文件/文件夹。

回答by David Dollar

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.

我强烈建议考虑将这些 MP3 文件放在 S3 上。让它们成为您的 Heroku 推送的一部分(因此也是您的 Heroku slug 的一部分)将大大减慢您的 dyno 启动时间。由于 Heroku 使用 EC2,如果文件在 S3 上并且只能由您的应用程序访问(如果用户没有直接链接到 S3),您甚至不需要支付任何带宽费用,只需支付存储 50MB 的费用。

回答by sapy

Let's say we want to ignore buildfolder from all other branch except productionbranch . As we want to push buildfolder in production.

假设我们想忽略build来自除productionbranch之外的所有其他分支的文件夹。因为我们想build在生产中推送文件夹。

1) Dont include buildin .gitignore . If you do that it will always be ignored for all branches .

1) 不要包含build在 .gitignore 中。如果这样做,所有分支将始终忽略它。

2) Create a file exclude_from_public_viewinginside ./.git/info(This folder already exists) folder touch ./.git/info/exclude_from_public_viewing

2)exclude_from_public_viewing./.git/info(此文件夹已存在)文件夹中创建一个文件touch ./.git/info/exclude_from_public_viewing

3) Inside exclude_from_public_viewingwrite one line (As you are trying to ignore buildfor all the branches). !build

3)在里面exclude_from_public_viewing写一行(因为你试图忽略build所有分支)。 !build

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

4)有一个现有的文件.git/info/exclude。我们需要在其中添加以下行。

 build

We want to ignore buildfolder but hasn't added it in .gitignore . So how git will know what to ignore ? Answer is we are adding it to excludefile and conditionally passing that file to git config

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

5) Now we have to conditionally unignore buildfolder for productionbranch. to do that perform following

5)现在我们必须有条件地忽略分支的build文件夹production。要做到这一点,请执行以下操作

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

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

a) excludesfile = +info/excludebelow [core]

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

[core]
     excludesfile = +info/exclude

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

b) 在./.git/configas末尾创建一个新部分

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

Solution 2

解决方案2

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

有一种智能替代解决方案。假设您想build/production分支中添加文件夹并在所有其他分支中忽略它。

1) Add it to your gitignorefile.

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

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

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

回答by kEND

Have you tried having .gitignore be different in your branch?

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

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.

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

回答by Саша Черных

1. Summary

一、总结

  1. I use Travis CIfor 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.

    mvUNIX commandmove file; overwrite, if file already exist.

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

    before_deploy:
    - mv misc/.gitignore .gitignore
    

    哪里misc- 任何文件夹,包含另一个.gitignore.

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

When Travis CI deploy project, Travis CI will not push to deploying providerfiles and folders, that ignore in misc/.gitignore(not in the original .gitignoreof sources).

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



2. Limitations

2. 限制

  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.
  1. 这个答案可能并不适合作者的所有条件。但是这个答案回答了这个问题“使用 git,我如何忽略一个分支中的文件,但将它提交到另一个分支中?”
  2. 我不是 Heroku 用户,我的例子是GitHub,不是 Heroku。这个答案的数据在 GitHub 中对我有用,但在 Heroku 上可能不起作用。


3. Relevance

3. 相关性

This answer is relevant for April 2018. In the future, the data of this answer may be obsolete.

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



4. Demonstration

4. 演示

my real project.

真正的项目

Example of successful deployment.

成功部署的例子

4.1. Task

4.1. 任务

I deploy my project from src branch to dest branch of the same repository.

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

I want, that file PaletteMira.suricate-profile:

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

  • Local machine — exists for all branches,
  • src remote branch — not exists,
  • dest remote branch — exists.
  • 本地机器——存在于所有分支,
  • src 远程分支 — 不存在,
  • dest 远程分支 — 存在。

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

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

4.2. src

4.2. 源文件

sources branch — SashaYAML.

源分支 — SashaYAML

Part of .travis.yml:

部分.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:

部分.gitignore

*.sublime-snippet
*.suricate-profile

Part of misc/.gitignore

部分 misc/.gitignore

*.sublime-snippet

*.suricate-profilenot in misc/.gitignore.

*.suricate-profile不在misc/.gitignore

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

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

4.3. dest

4.3. 目的地

destination branch — SashaDevelop

目标分支——SashaDevelop

Part of .gitignore:

部分.gitignore

*.sublime-snippet

*.suricate-profilenot in misc/.gitignore.

*.suricate-profile不在misc/.gitignore

PaletteMira.suricate-profileexists for this branch remotelyand locally.

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

4.4. Steps to reproduce

4.4. 重现步骤

I enable PaletteMira GitHub repository for Travis CI→ I set environment variable$GITHUB_TOKENwith value — my GitHub token→ I make any commit to my src branch.

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

If no errors, I must get expected behavior.

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

回答by Tom

Can you commit and push from Heroku?

你可以从 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 和 heroku,在 Heroku 上删除工作副本上的文件。从 repo 中删除音频而不是从磁盘中删除,然后将该更改推送回 github。

回答by John Lozano

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

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