git涂抹/清除分支之间的过滤器

Ric*_*ier 17 git gitattributes

有很多相关的问题涉及涂抹/清洁过滤器 - 我花了几个小时阅读它们,并尝试各种选项,但仍然失败.我希望我能以某种方式询问我得到的答案对我有用.

具体来说,我已经阅读了大部分这些答案链接回来的页面:


TL;博士

这是一个详细的问题,但摘要是:

  • 我可以将DEBUG = false文件存储在一个分支上,DEBUG = true在另一个分支中,使用涂抹/清除过滤器来管理该文件吗?如何?

背景

我在bitbucket有各种远程回购.我在Win8上使用SourceTree,将远程存储库克隆到我的笔记本电脑上.我为开发,功能,发布等创建了不同的分支(遵循一个成功的Git分支模型,无论好坏).

我有一个名为的Android java类Dbug.java,它包含一个布尔值,可以在我的代码中打开/关闭各种调试日志记录,模拟等功能.

public static final boolean DEBUG = false;
Run Code Online (Sandbox Code Playgroud)

我希望这个值false在我的"生产"(主)分支上,并且true在我的功能分支上.

  • 这可能是使用过滤器,还是我已经误解了用例?
  • 我不确定过滤器是否在同一本地托管的仓库的两个分支之间如此工作,或者过滤器仅在2个回购之间工作.

创建过滤器

在本地工作,我检查了生产分支.我创建了一个debug_flag.txt使用以下内容调用的测试文件:

// false on production branch
// true on other branches
DEBUG = false;
Run Code Online (Sandbox Code Playgroud)

我在我的本地仓库的根目录中创建了一个文件.gitattributes并添加了过滤器引用:

debug_flag.txt filter=debug_on_off
Run Code Online (Sandbox Code Playgroud)

.git/config用过滤器定义更新了文件:

[filter "debug_on_off"]
    clean = sed -e 's/DEBUG = true/DEBUG = false/'
    smudge = sed -s 's/DEBUG = false/DEBUG = true/'
Run Code Online (Sandbox Code Playgroud)
  • 根据我的理解,这应该确保我的文件在生产中始终具有错误值,但是当我从生产中分支时将具有真值.
  • 这是正确的理解吗?

测试过滤器

我创建了一个新的分支test使用:

git checkout -b test
Run Code Online (Sandbox Code Playgroud)

我检查了我的文件内容:

$ cat debug_flag.txt

// false on production branch
// true on other branches
DEBUG = false;
Run Code Online (Sandbox Code Playgroud)
  • 我希望看到true文件中的值
  • 我签出文件时不应该运行"涂抹"过滤器吗?

我在文件中添加了一个新行,并提交了.然后我切换回生产分支,这就是事情变得奇怪的地方.

如果我在SourceTree中查看该文件,则该分支自创建以来没有任何更改.这是我所期望的,因为唯一的变化是在另一个分支上进行的.

如果我查看终端中的文件或Notepad ++,我看到我的值已经改变:

$ cat debug_flag.txt

// false on production branch
// true on other branches
DEBUG = true;
Run Code Online (Sandbox Code Playgroud)

我尚未从测试分支合并更改,我还没有在生产分支上提交,但文件已更改.

  • 看起来涂抹过滤器在此分支内的文件上运行,但不在分支上运行.

我错过了一个重要的难题,希望这是一个简单的事情,有经验的人可以发现这一点.

我敢打赌,这是对这个概念的一个简单误解.

请提示任何遗漏的信息......


根据VonC的回复进行更新

设置基本过滤器效果很好.将config文件中的过滤器定义为:

[filter "debug_on_off"]
    clean = sed -e 's/DEBUG = true/DEBUG = false/'
    smudge = sed -s 's/DEBUG = false/DEBUG = true/'
Run Code Online (Sandbox Code Playgroud)

创建一个新分支修复了false - > true,合并返回更改true - > false.

将更改限制在生产(主)分支所需的自定义脚本需要知道正在运行的分支.所以config文件成了:

[filter "debug_on_off"]
    clean = ./scripts/master_clean.sh
    smudge = ./scripts/master_smudge.sh
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

此时,我遇到了SourceTree看到的内容与Notepad ++中显示的调试文件内容之间的不一致.SourceTree正在显示更改,但Notepad ++不是.

我接受VonC的回答,因为它回答了我提出的基本问题.

但是,我可能会实现我编写解决方案,因为它解决了我试图解决的基本问题,以一种更简单的方式(对我而言):在不同的分支上保留不同的配置文件.

Von*_*onC 7

我希望在文件中看到值true

您刚刚创建了一个新分支,未检出其内容(其内容与您所在的分支相同)

要强制涂抹,请在回购顶部执行:

git checkout HEAD --
Run Code Online (Sandbox Code Playgroud)

我尚未从测试分支合并更改,我还没有在生产分支上提交,但文件已更改.

这就是内容过滤器驱动程序的想法:它修改内容,而不会影响git status(仍然将修改后的文件报告为"未更改").

为了使每个分支的涂抹效果不同,我建议调用一个脚本,该脚本首先查看当前分支的名称.
请参阅我的旧答案中的示例" 最佳实践 - Git +构建自动化 - 保持配置分离 ".

#!/bin/sh
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
Run Code Online (Sandbox Code Playgroud)