Git 排除分支的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29579546/
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
Git excludesfile for a branch
提问by goredwards
I want to ignore certain files within a branch without having to rely on a tracked .gitignore
file that will be overwritten during merges with other branches.
我想忽略分支中的某些文件,而不必依赖在.gitignore
与其他分支合并期间将被覆盖的跟踪文件。
I've closely followed a Stack Overflow answeralong with the linked blog post, but my repo doesn't seem to be recognizing the specified excludesfile
in my .git/config
. The Git documentation (git-config
, gitignore
) doesn't seem to show how to specify and address an excludes file for a specific branch.
我密切关注Stack Overflow 的回答以及链接的博客文章,但我的回购似乎没有识别出excludesfile
我的.git/config
. Git 文档 ( git-config
, gitignore
) 似乎没有显示如何为特定分支指定和处理排除文件。
My .git/config
looks like this:
我的.git/config
看起来像这样:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
excludesfile = +/info/exclude
[branch "myspecialbranch"]
excludesfile = +/info/exclude_specialbranch
My .git/info/exclude
file looks like this (by default, I didn't touch it):
我的.git/info/exclude
文件看起来像这样(默认情况下,我没有碰它):
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store
I don't have a .gitignore
file in my “specialbranch”.
.gitignore
我的“specialbranch”中没有文件。
If I try to ignore a file like info.php
, my .git/info/exclude_specialbranch
file looks like this:
如果我尝试忽略类似 的文件info.php
,我的.git/info/exclude_specialbranch
文件如下所示:
info.php
… but it doesn't ignore the file.
...但它不会忽略该文件。
If I run git status --ignored
, it only lists the .DS_Store
file from the default exclude
file.
如果我运行git status --ignored
,它只列出.DS_Store
默认exclude
文件中的文件。
However, if I add info.php
to my .git/info/exclude
file:
但是,如果我添加info.php
到我的.git/info/exclude
文件中:
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store
info.php
it ignores the file perfectly.
它完美地忽略了该文件。
Note that it still works without the line excludesfile = +/info/exclude
under [core]
in .git/config
. Git seems to know where the system-wide exclude
is without me having to tell it.
请注意,它仍然可以在没有in下的行的情况excludesfile = +/info/exclude
下[core]
工作.git/config
。Git 似乎知道系统范围的exclude
位置,而我不必告诉它。
I have a feeling that .git/config
isn't recognizing the address of my custom excludes file:
我有一种感觉,.git/config
无法识别我的自定义排除文件的地址:
excludesfile = +/info/exclude_specialbranch
… most likely because of the use of +
to describe the location of the .git
directory.
... 很可能是因为使用+
来描述.git
目录的位置。
What's the correct method for addressing custom exclude files in the (more recent) versions of Git?
在(更新的)Git 版本中处理自定义排除文件的正确方法是什么?
I'm running OSX 10.9.5 and Git version 2.2.1.
我正在运行 OSX 10.9.5 和 Git 版本 2.2.1。
回答by Palec
Git does not support per-branch excludes files
Git 不支持每个分支排除文件
You're trying to achieve something that Git does not support. The blog postis the original source of this hoax that the Stack Overflow answeronly parroted. As noted in comments under that answer, even the original blog post contains discussion that brings out that the solution does not work and it links to a newer blog postthat mentions that even the author is unable to reproduce the behavior.
您正在尝试实现 Git 不支持的东西。这篇博文是这个骗局的原始来源,Stack Overflow 的回答只是鹦鹉学舌。正如在该答案下的评论中所指出的,即使是原始博客文章也包含表明该解决方案不起作用的讨论,并且它链接到更新的博客文章,其中提到即使作者也无法重现该行为。
Why it does not work? If you read man gitignore
and man git-config
, you'll find just core.excludesfile
referenced. No branch.<name>.excludesfile
there. The core.excludesfile
is meant to enable you to exclude e.g. Vim .swp files or other temporary stuff your software uses.
为什么它不起作用?如果您阅读man gitignore
和man git-config
,您会发现刚刚被core.excludesfile
引用。没有branch.<name>.excludesfile
。这core.excludesfile
旨在使您能够排除例如 Vim .swp 文件或您的软件使用的其他临时文件。
core.excludesfile
In addition to
.gitignore
(per-directory) and.git/info/exclude
, Git looks into this file for patterns of files which are not meant to be tracked. "~/
" is expanded to the value of$HOME
and "~user/
" to the specified user's home directory. Its default value is$XDG_CONFIG_HOME/git/ignore
. If$XDG_CONFIG_HOME
is either not set or empty,$HOME/.config/git/ignore
is used instead. See gitignore(5).
core.excludesfile
除了
.gitignore
(per-directory) and 之外.git/info/exclude
,Git还会查看此文件以查找不打算跟踪的文件模式。"~/
" 扩展为$HOME
和 "~user/
"的值到指定用户的主目录。其默认值为$XDG_CONFIG_HOME/git/ignore
。如果$XDG_CONFIG_HOME
未设置或为空,$HOME/.config/git/ignore
则改为使用。参见gitignore(5)。
Work-around
变通方法
I believe that the best approximation of a per-branch excludes file is achieved using the post-checkout hookand realization of the .gitignore
via a symlink.
我相信每个分支排除文件的最佳近似是使用post-checkout 钩子和.gitignore
通过符号链接实现的。
Each branch would have e.g. a .gitignores
directory with files named after the corresponding branches. Then there would be a .gitignores/__default
file that would be used by default. The .gitignore
would be excluded by all the excludes files and would be created by the post-checkout hook as a symlink to the corresponding file in .gitignores
.
每个分支都会有一个.gitignores
目录,其中包含以相应分支命名的文件。然后会有一个.gitignores/__default
默认使用的文件。该.gitignore
会由所有不包括文件被排除在外,并将由后结账钩作为一个符号链接到相应的文件被创建.gitignores
。
If you don't want to track the excludes files, you may do the same with .git/info/exclude
file as a symlink to .git/info/excludes/__default
etc.
如果您不想跟踪排除文件,您可以使用.git/info/exclude
文件作为符号链接.git/info/excludes/__default
等。
回答by Jeremy John
Here's a script I wrote to do this:
这是我为此编写的脚本:
#!/bin/bash
# This is designed to allow per-branch un-ignoring of certain files.
# Use case: Compiled CSS files on master to push to server.
# A special .gitignore file will be present on master at
# {$gitignorePath}/{$disabledMasterGitignoreName} and that file should
# enable the css files using the ! flag. @https://git-scm.com/docs/gitignore
# When the branch specified by script parameters
# is checked out, {$gitignorePath}/{$disabledMasterGitignoreName} is
# copied to .gitignore.
# On other branches this gitignore file is named $disabledMasterGitignoreName, versioned,
# and {$gitignorePath}.gitignore will be deleted. Note, you must ignore
# {$gitignorePath}.gitignore from your main .gitignore file
#
# To enable put this file in your path and call this script
# in .git/hooks/post-checkout with pass a list of single-space-separated branches that
# will enable the branch-specific .gitignore.
# One caveat is that you can only merge into the branch containing the .gitignore
# file. Otherwise you'll end up re-committing the files. This is fine if you are
# using gitflow and `master` contains your special .gitigore using the ! syntax
# that is un-ignoring files.
#
# Background: @http://stackoverflow.com/questions/29579546/git-excludesfile-for-a-branch
set -e
gitignorePath='docroot/sites/all/themes'
disabledMasterGitignoreName='.gitignore_master--disabled'
#branchWithGitignoreEnabled='master'
branch=$(git rev-parse --abbrev-ref HEAD)
gitignoreRoot="$(git rev-parse --show-toplevel)/${gitignorePath}"
if [ -f "${gitignorePath}/.gitignore" ]
then
masterGitignoreExists=true
fi
if [ -f "${gitignorePath}/${disabledMasterGitignoreName}" ]
then
disabledMasterGitignoreExists=true
fi
IFS=' ' read -a params <<< "$@"
if [[ " ${params[@]} " =~ " ${branch} " ]]
then
if [ $disabledMasterGitignoreExists ]
then
cp -f "${gitignoreRoot}/${disabledMasterGitignoreName}" "${gitignoreRoot}/.gitignore"
echo "Enabled ${gitignorePath}/.gitignore"
fi
elif [ $masterGitignoreExists ]
then
rm -f "${gitignorePath}/.gitignore"
if [ masterGitignoreExists ]
then
echo "Disabled ${gitignorePath}/.gitignore"
fi
fi