涉及笔刷/清洁过滤器的相关问题有很多 - 我花了几个小时阅读它们,并尝试了各种选项,但仍然失败。我希望我能以一种方式提出问题,以便我可以得到适用于我的答案。
具体来说,我已经阅读了大多数这些答案链接回到的页面:
tl;dr
这是一个详细的问题,但摘要如下:
- 我可以使用笔刷/清洁过滤器将
DEBUG = false
存储在一个分支的文件中,并将DEBUG = true
存储在另一个分支中吗?如何实现?
背景
我有各种远程存储库托管在 bitbucket 上。我在 Win8 上使用 SourceTree 将远程存储库克隆到我的笔记本电脑上。我为开发、功能、发行等创建不同的分支(遵循A successful Git branching model,不管好坏)。
我有一个名为 Dbug.java
的 Android Java 类,其中包含一个布尔值,用于在我的代码中打开/关闭各种调试日志记录、模拟等功能。
public static final boolean DEBUG = false;
在我的“生产”(master)分支上,我希望这个值为false
,在我的功能分支上,我希望它为true
。
- 使用过滤器可以实现这个目标吗?还是我已经误解了用例?
- 我不确定过滤器是否在同一本地托管的存储库的两个分支之间起作用,或者过滤器只在两个不同的存储库之间起作用。
创建过滤器
在本地工作时,我切换到生产分支。我创建了一个名为debug_flag.txt
的测试文件,其内容如下:
// false on production branch
// true on other branches
DEBUG = false;
我在本地仓库的根目录下创建了一个名为.gitattributes
的文件,并向其中添加了过滤器引用:
debug_flag.txt filter=debug_on_off
我更新了.git/config
文件,加入了过滤器定义:
[filter "debug_on_off"]
clean = sed -e 's/DEBUG = true/DEBUG = false/'
smudge = sed -s 's/DEBUG = false/DEBUG = true/'
- 在我的理解中,这应该确保我的文件在生产环境中始终具有false值,但在我从生产分支分离时具有true值。
- 这个理解正确吗?
测试过滤器
我使用以下命令创建了一个名为test
的新分支:
git checkout -b test
我检查了我的文件内容:
$ cat debug_flag.txt
// false on production branch
// true on other branches
DEBUG = false;
- 我希望在文件中看到值为
true
- "smudge" 过滤器不应该在我检出文件时运行吗?
我向文件添加了一行,并进行了提交。然后我切换回生产分支,这就是事情变得奇怪的地方。
如果我在 SourceTree 中查看文件,则自创建该分支以来,此分支上没有任何更改。这是我所期望的,因为唯一的更改是在不同的分支上进行的。
如果我在终端或 Notepad++ 中查看文件,则会看到我的值已更改:
$ cat debug_flag.txt
// false on production branch
// true on other branches
DEBUG = true;
我还没有将测试分支上的更改合并到生产分支上,也没有在生产分支上进行提交,但是文件已经发生了变化。
- 看起来在这个分支内已经对文件运行了smudge过滤器,但是跨分支还没有运行。
我缺少一个关键的部分,希望有经验的人能够发现这个简单的问题。
我打赌这是一个简单的概念误解。
请提示任何缺失的信息......
基于VonC的回复更新
设置基本过滤器效果很好。在config
文件中定义了过滤器:
[filter "debug_on_off"]
clean = sed -e 's/DEBUG = true/DEBUG = false/'
smudge = sed -s 's/DEBUG = false/DEBUG = true/'
创建新分支可以解决false -> true的问题,合并回来会将true -> false。
将更改限制在生产(主)分支上需要具有所在分支意识的自定义脚本。因此,config
文件变为:
[filter "debug_on_off"]
clean = ./scripts/master_clean.sh
smudge = ./scripts/master_smudge.sh
master_clean.sh:
#!/bin/sh
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
if [ "master" = "$branch" ]; then
sed -e s/DEBUG = true/DEBUG = false/ $1
else
cat $1
fi
master_smudge.sh:
#!/bin/sh
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
if [ "master" = "$branch" ]; then
sed -e s/DEBUG = false/DEBUG = true/ $1
else
cat $1
fi
目前,我遇到了一个问题,SourceTree看到的内容与Notepad++显示的调试文件内容不一致。 SourceTree显示有更改,但Notepad++没有。
我接受VonC的答案,因为它回答了我提出的基本问题。
然而,我可能会实现我编写的解决方案,因为它以一种更简单(对我来说)的方式解决了我尝试解决的根本问题:在不同的分支上保留不同的配置文件。