【发布时间】:2014-05-19 12:44:30
【问题描述】:
有许多涉及涂抹/清洁过滤器的相关问题 - 我花了几个小时阅读它们,并尝试了各种选项,但仍然失败。我希望我能以一种我能得到适合我的答案的方式提问。
具体来说,我已经阅读了大部分答案链接到的页面:
tl;博士
这是一个详细的问题,但总结是:
- 我可以将
DEBUG = false存储在一个分支的文件中,并将DEBUG = true存储在另一个分支中,使用涂抹/清洁过滤器来管理该文件吗?怎么做?
背景
我在 bitbucket 上托管了各种远程存储库。我在 Win8 上使用 SourceTree,将远程存储库克隆到我的笔记本电脑。我为开发、功能、发布等创建了不同的分支(遵循A successful Git branching model 是好是坏)。
我有一个名为 Dbug.java 的 Android java 类,其中包含一个布尔值,可以在我的代码中打开/关闭各种调试日志记录、模拟等功能。
public static final boolean DEBUG = false;
我希望这个值在我的“生产”(主)分支上是 false,在我的功能分支上是 true。
- 这是否可以使用过滤器,还是我已经误解了用例?
- 我不确定过滤器是否在同一个本地托管存储库的 2 个分支之间像这样工作,或者过滤器是否仅在 2 个存储库之间工作。
创建过滤器
在本地工作,我检查了生产分支。我创建了一个名为debug_flag.txt 的测试文件,其内容如下:
// false on production branch
// true on other branches
DEBUG = false;
我在本地 repo 的根目录中创建了一个名为 .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/'
- 据我了解,这应确保我的文件始终具有 生产中的错误值,但当我从 生产。
- 这是正确的理解吗?
测试过滤器
我创建了一个新分支 test 使用:
git checkout -b test
我检查了文件的内容:
$ cat debug_flag.txt
// false on production branch
// true on other branches
DEBUG = false;
- 我希望在文件中看到值
true - 当我签出文件时,“污迹”过滤器是否应该运行?
我在文件中添加了一个新行,并提交了。然后我切换回生产分支,这就是事情变得奇怪的地方。
如果我查看 SourceTree 中的文件,该分支自创建以来没有任何更改。这是我所期望的,因为唯一的更改是在不同的分支上进行的。
如果我在终端或 Notepad++ 中查看文件,我发现我的值已更改:
$ cat debug_flag.txt
// false on production branch
// true on other branches
DEBUG = true;
我还没有合并测试分支对面的更改,我还没有在生产分支上提交,但是文件已经改变了。
- 看起来污迹过滤器是在此分支内的文件上运行的,但不是跨分支。
我错过了一个重要的难题,希望它是一些简单的东西,可以被有经验的人发现。
我敢打赌,这是对这个概念的简单误解。
请提示任何缺失的信息...
根据 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's answer,因为它回答了我提出的基本问题。
但是,我可能会实施solution I wrote,因为它以一种更简单的方式(对我而言)解决了我试图解决的基本问题:在不同的分支上保留不同的配置文件。
【问题讨论】:
-
您可能需要在 $1 周围添加引号以支持带有空格的文件。
-
你不是在配置文件中缺少 %f 吗? (不确定是否带引号,以防万一您需要转义它们,因为 git 本身在解析配置文件 AFAIK 时也会解释它们)
-
@phk 一年多前我就放弃了。我现在手动进行(当然这很痛苦)。但是,如果您有时间并认为您有一个正常工作的解决方案,请随时发布。根据我的发现,git 不支持此功能,我认为这是“设计使然”。
-
我当时也放弃了,Linus 的名言让我在构建脚本中做这些事情。
标签: git gitattributes