有许多涉及涂抹/清洁过滤器的相关问题 - 我花了几个小时阅读它们,并尝试各种选项,但仍然失败。我希望我能以某种方式询问我得到的答案对我有用。
具体来说,我已经阅读了大部分这些答案链接回来的页面:
这是一个详细的问题,但摘要是:
DEBUG = false
存储在一个分支上的文件中,将DEBUG = true
存储在另一个分支中,使用涂抹/清除过滤器来管理该文件吗?怎么样?我在bitbucket上有各种远程回购。我在Win8上使用SourceTree,将远程存储库克隆到我的笔记本电脑上。我为开发,功能,发布等创建了不同的分支(在A successful Git branching model之后更好或更差)。
我有一个名为Dbug.java
的Android java类,它包含一个布尔值,可以在我的代码中打开/关闭各种调试日志记录,模拟等功能。
public static final boolean DEBUG = false;
我希望这个值在{"生产"}上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/'
我使用:
创建了一个新的分支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;
我尚未合并测试分支的更改,我还没有在生产分支上提交,但是文件已更改。
我错过了这个谜题的重要部分,希望这是一个简单的事情,有经验的人可以发现它。
我敢打赌,这是对这个概念的一个简单误解。
请提示任何遗失的信息......
设置基本过滤器效果很好。将config
文件中的过滤器定义为:
[filter "debug_on_off"]
clean = sed -e 's/DEBUG = true/DEBUG = false/'
smudge = sed -s 's/DEBUG = false/DEBUG = 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,因为它以一种更简单的方式(对我来说)解决了我试图解决的潜在问题:在不同的分支上保留不同的配置文件。
答案 0 :(得分:7)
我希望在文件
中看到值true
您刚创建了一个新分支,未检出其内容(其内容与您所在的分支相同)
要强制涂抹,请在回购顶部执行:
git checkout HEAD --
我还没有在测试分支中合并更改,我还没有在生产分支上进行提交,但文件已经更改。
这就是内容过滤器驱动程序的想法:它会修改内容,而不会影响git status
(仍会将修改后的文件报告为"未更改")。
为了让每个分支的涂抹效果不同,我建议调用一个脚本,该脚本首先查看当前分支的名称。
请参阅旧答案中的示例" Best practice - Git + Build automation - Keeping configs separate"。
#!/bin/sh
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
答案 1 :(得分:3)
看看expandr。这是一个脚本,允许您使用涂抹/清洁在不同的分支上设置不同的配置。基本上就是你原来要求的东西。
现在最大的问题就是切换分支后,有时我需要做一个git checkout HEAD -- "$(git rev-parse --show-toplevel)"
来正确弄脏工作目录。但是,其他时候,似乎工作正常;我还没弄明白为什么。我认为它可能与“merge reormalize”被打开有关,导致一些问题?我不确定。 (我有它。)
另一个问题是,您必须使用merge=ours
添加一行来保护每个分支的.gitattributes文件本身.gitattributes merge=ours
,然后为此启用驱动程序(如您所述) 。这里的 gotcha 是在创建每个单独的分支之后,现在您必须进入每个.gitattributes文件并修改每个分支(我建议现在添加#touched for merge=ours on master
之类的评论,{{1}等等,所以你会记住它为什么存在)。您必须执行此操作,因为如果在传入分支及其父分支上创建分支后该文件已更改,#touched for merge=ours on test branch
将仅保护文件不会更改为合并中传入分支的版本。 (记住git处理更改,而不是文件。)
答案 2 :(得分:2)
VonC's advice解决了我提出的确切问题,但我无法确定最终细节(根据我对问题的更新)。这个答案给出了我如何做事的细节。
下面的方法适用于第一次合并。但之后它就不再起作用了。我将它留在这里,因为它代表了我调查的当前状态。
似乎不再调用合并驱动程序。
还尝试使用exit 0
,touch %A
或自定义脚本合并驱动程序(https://stackoverflow.com/a/930495/383414)代替true
的相关问题进行各种修改,如下所示。
我找到了一个解决方法,它使用自定义merge
策略来解决根本问题,即:
我根据以下问题提供了以下信息:.gitattributes & individual merge strategy for a file
1)
在.git/config
文件中定义自定义合并驱动程序,如下所示:
[merge "ours"]
name = "Keep ours merge"
driver = true
我不确定是否需要此步骤 - 但似乎它可能是某些(较旧的?)系统上的错误的解决方法。
(详情请见https://stackoverflow.com/a/13000959/383414)
2)
在build / production / pristine分支中设置.gitattributes
文件,以便特殊调试标志使用上述合并策略。
因此,使用我的问题中的文件,转到“生产”分支,并将以下行添加到.gitattributes
文件中:
debug_flag.txt merge=ours
每当合并回到“production”分支时,git将查找定义为“ours”的合并策略,并阻止debug_flag.txt被覆盖。
3)
在其他分支上,设置.gitattributes
文件而不使用该自定义合并策略。
4) 配置过程的最后(但很重要)步骤是在所有分支中正确设置debug_flag.txt文件,并为每个分支提交更改。
您现在应该有2个分支,每个分支包含不同版本的.gitattributes
& debug_flag.txt文件。这可以确保每次合并时都会发生冲突。
如果没有冲突,则不会调用自定义“我们的”合并策略,并且文件可能会被覆盖。
(详情请见https://stackoverflow.com/a/16739788/383414)
5) 最后将您的新分支合并回“生产”。由于步骤3和步骤3,您将发生合并冲突。 4.解决冲突,使两个分支保持差异。提交更改。
这两个分支之间的所有未来合并都将无缝地忽略debug_flag.txt文件。
这实现了在不同分支上拥有2个不同配置文件的目标,这样您就可以轻松地将调试与生产代码等分开。这似乎是一个常见的用例,在此论坛上有许多相关问题,但它仍然需要我好几天才能做对。
答案 3 :(得分:0)
最直接的解决方案是更新您的makefile以包括检查当前检出的分支。如果分支是命名列表的一部分,则定义新的构建参数-DDEBUG = true或-DDEBUG = false。
请参阅How to programmatically determine the current checked out Git branch
branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}
PROD_BRANCHES := master \
QA
debug_flag=
ifneq ($(filter $(branch_name),$(PROD_BRANCHES)),)
debug_flag="-DDEBUG=true"
endif
ifeq($debug_flag,)
debug_flag="-DDEBUG=false"
endif
答案 4 :(得分:0)
我有一个类似的用例,并且能够使用过滤器和结帐后挂钩解决它。这个钩子很好,因为它为你做了清理+涂抹,并在通过 GitHub Desktop 切换分支时立即更新文件。通过这种方法,每个沙箱/层的每个分支都有自己的配置。