我想忽略分支中的某些文件,而不必依赖于在与其他分支合并期间将被覆盖的跟踪.gitignore
文件。
我密切关注a Stack Overflow answer和the linked blog post,但我的回购似乎没有认出我excludesfile
中指定的.git/config
。 Git文档(git-config
,gitignore
)似乎没有显示如何指定和解决特定分支的排除文件。
我的.git/config
看起来像这样:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
excludesfile = +/info/exclude
[branch "myspecialbranch"]
excludesfile = +/info/exclude_specialbranch
我的.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
我的“specialbranch”中没有.gitignore
文件。
如果我尝试忽略info.php
这样的文件,我的.git/info/exclude_specialbranch
文件如下所示:
info.php
...但它不会忽略该文件。
如果我运行git status --ignored
,它只列出默认.DS_Store
文件中的exclude
文件。
但是,如果我将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
它完全忽略了文件。
请注意,如果excludesfile = +/info/exclude
中的[core]
下的.git/config
行仍然有效,它仍可正常使用。 Git似乎知道系统范围exclude
在哪里,而我不必告诉它。
我感觉.git/config
无法识别我的自定义排除文件的地址:
excludesfile = +/info/exclude_specialbranch
...很可能是因为使用+
来描述.git
目录的位置。
在(最近的)Git版本中解决自定义排除文件的正确方法是什么?
我正在运行OSX 10.9.5和Git 2.2.1版。
答案 0 :(得分:25)
你正在努力实现Git不支持的东西。 blog post是这个恶作剧的原始来源the Stack Overflow answer只是鹦鹉学舌。正如在该答案的评论中所指出的那样,即使是原始博客文章也包含的讨论表明该解决方案不起作用,并且它链接到newer blog post,提到即使作者也无法重现该行为。
为什么它不起作用?如果您阅读man gitignore
和man git-config
,则会发现只有core.excludesfile
被引用。那里没有branch.<name>.excludesfile
。 core.excludesfile
旨在让您排除,例如Vim .swp文件或您的软件使用的其他临时文件。
core.excludesfile
除了
.gitignore
(每个目录)和.git/info/exclude
之外,Git还会查看此文件中是否存在无意跟踪的文件模式。 &#34;~/
&#34;被扩展为$HOME
和&#34;~user/
&#34;到指定用户的主目录。其默认值为$XDG_CONFIG_HOME/git/ignore
。如果$XDG_CONFIG_HOME
未设置或为空,则会使用$HOME/.config/git/ignore
。请参阅gitignore(5)。
我相信使用post-checkout hook和.gitignore
通过符号链接实现每个分支排除文件的最佳近似值。
每个分支都有例如一个.gitignores
目录,其中的文件以相应的分支命名。然后会有一个.gitignores/__default
文件默认使用。 .gitignore
将被所有排除文件排除,并且将由post-checkout挂钩创建为.gitignores
中相应文件的符号链接。
如果您不想跟踪排除文件,则可以使用.git/info/exclude
文件作为.git/info/excludes/__default
等的符号链接执行相同操作。
答案 1 :(得分:2)
这是我写的一个脚本:
#!/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