git 涂抹/清洁分支之间的过滤器 [英] git smudge/clean filter between branches

查看:27
本文介绍了git 涂抹/清洁分支之间的过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有许多与污迹/清洁过滤器相关的问题 - 我花了几个小时阅读它们,并尝试了各种选项,但仍然失败.我希望我能以一种对我有用的方式提问.

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

<小时>

tl;博士

这是一个详细的问题,但总结是:

  • 我可以将 DEBUG = false 存储在一个分支上的文件中,并将 DEBUG = true 存储在另一个分支中,使用污迹/清洁过滤器来管理该文件吗?以及如何?
<小时>

背景

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

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

public static final boolean DEBUG = false;

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

  • 这是否可以使用过滤器,或者我是否已经误解了用例?
  • 我不确定过滤器是否在同一个本地托管存储库的 2 个分支之间像这样工作,或者过滤器是否只在 2 个存储库之间工作.
<小时>

创建过滤器

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

//在生产分支上为假//在其他分支上为真调试 = 假;

我在本地存储库的根目录中创建了一个名为 .gitattributes 的文件,并向其添加了过滤器引用:

debug_flag.txt filter=debug_on_off

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

[过滤器debug_on_off"]清洁 = sed -e 's/DEBUG = true/DEBUG = false/'涂抹 = sed -s 's/DEBUG = false/DEBUG = true/'

  • 据我所知,这应该确保我的文件始终具有生产中的假值,但当我从生产.
  • 这是正确的理解吗?
<小时>

测试过滤器

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

git checkout -b test

我检查了我的文件的内容:

$ cat debug_flag.txt//在生产分支上为假//在其他分支上为真调试 = 假;

  • 我希望在文件中看到值 true
  • 当我检出文件时,污迹"过滤器不应该运行吗?

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

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

如果我在终端或 Notepad++ 中查看文件,我会发现我的值已更改:

$ cat debug_flag.txt//在生产分支上为假//在其他分支上为真调试 = 真;

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

  • 看起来涂抹过滤器是在此分支内的文件上运行的,但没有跨分支运行.
<小时>

我错过了拼图的一个重要部分,希望有经验的人可以发现它很简单.

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

请提示任何缺失的信息...

<小时>

根据 VonC 的回复更新

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

[过滤器debug_on_off"]清洁 = sed -e 's/DEBUG = true/DEBUG = false/'涂抹 = sed -s 's/DEBUG = false/DEBUG = true/'

创建新分支修复 false -> true,合并更改 true -> false.

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

[过滤器debug_on_off"]干净 = ./scripts/master_clean.sh涂抹 = ./scripts/master_smudge.sh

master_clean.sh:

#!/bin/sh分支=$(git rev-parse --symbolic --abbrev-ref HEAD)if [ "master" = "$branch" ];然后sed -e s/DEBUG = true/DEBUG = false/$1别的猫 $1菲

master_smudge.sh:

#!/bin/sh分支=$(git rev-parse --symbolic --abbrev-ref HEAD)if [ "master" = "$branch" ];然后sed -e s/DEBUG = false/DEBUG = true/$1别的猫 $1菲

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

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

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

解决方案

我希望在文件中看到 true 值

您刚刚创建了一个新分支,没有检查其内容(因为它的内容与您所在的分支相同)

要强制涂抹运行,请在 repo 的顶部执行:

git checkout HEAD --

<块引用>

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

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

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

#!/bin/sh分支=$(git rev-parse --symbolic --abbrev-ref HEAD)

There are many related questions involving smudge/clean filters - I have spent some hours reading them, and trying various options, but still failing. I hope I can ask in a way that I get an answer that works for me.

Specifically, I have read the page most of these answers link back to:


tl;dr

Its a detailed question, but the summary is:

  • Can I store DEBUG = false in a file on one branch, and DEBUG = true in another branch, using smudge/clean filters to manage that file? And how?

Background

I have various remote repos hosted at bitbucket. I am using SourceTree on Win8, to clone the remote repos to my laptop. I create different branches for development, features, releases etc (following A successful Git branching model for better or worse).

I have an Android java class called Dbug.java that contains a boolean which turns on/off various debug logging, mocking etc features in my code.

public static final boolean DEBUG = false;

I would like this value to be false on my "production" (master) branch, and to be true on my feature branches.

  • Is this possible using filters, or have I already misunderstood the use case?
  • I am unsure if filters work like this between 2 branches of the same locally hosted repo, or if the filters only work between 2 repos.

Creating the filters

Working locally, I checked out the production branch. I created a test file called debug_flag.txt with the following contents:

// false on production branch
// true on other branches
DEBUG = false;

I created a file in the root of my local repo called .gitattributes and added the filter reference to it:

debug_flag.txt filter=debug_on_off

I updated the .git/config file with the filter definition:

[filter "debug_on_off"]
    clean = sed -e 's/DEBUG = true/DEBUG = false/'
    smudge = sed -s 's/DEBUG = false/DEBUG = true/'

  • In my understanding, this should ensure that my file always has a false value in production, but will have a true value when I branch from production.
  • Is this a correct understanding?

Testing the filters

I created a new branch test using:

git checkout -b test

I checked the contents of my file:

$ cat debug_flag.txt

// false on production branch
// true on other branches
DEBUG = false;

  • I expected to see the value true in the file
  • Shouldn't the "smudge" filter have run when I checked out the file?

I added a new line to the file, and committed. I then switched back to the production branch, and this is where things get weird.

If I look at the file in SourceTree, there are no changes on this branch since it was created. That is what I would expect, since the only change was made on a different branch.

If I look at the file in the terminal, or Notepad++, I see my value has changed:

$ cat debug_flag.txt

// false on production branch
// true on other branches
DEBUG = true;

I have not yet merged the change across from the test branch, I have not made a commit on the production branch, yet the file has changed.

  • it looks like the smudge filter was run on the file within this branch, but not across branches.

I'm missing a vital piece of the puzzle, and hopefully it is something simple that can be spotted by someone with experience doing this.

My bet is this is a simple misunderstanding of the concept.

Pls prompt for any missing info...


Update based on VonC's reply

Setting up the basic filters worked quite well. Defined the filter in the config file as:

[filter "debug_on_off"]
    clean = sed -e 's/DEBUG = true/DEBUG = false/'
    smudge = sed -s 's/DEBUG = false/DEBUG = true/'

Creating a new branch fixes false -> true, merging back changes true -> false.

Confining the change to just the production (master) branch required custom scripts that were aware of the branch they are being run from. So the config file became:

[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

At this point, I am running into inconsistencies between what SourceTree is seeing, and what is being shown in Notepad++ for the contents of the debug file. SourceTree is showing the changes, but Notepad++ is not.

I am accepting VonC's answer, since it answers the basic question I posed.

However, I will likely be implementing the solution I wrote, since it solves the underlying problem that I am trying to solve, in an easier way (for me): retaining a different config file on separate branches.

解决方案

I expected to see the value true in the file

You just created a new branch, not checked out its content (sice its content is the same as the branch you were in)

To force the smudge to run, do at the top of the repo:

git checkout HEAD --

I have not yet merged the change across from the test branch, I have not made a commit on the production branch, yet the file has changed.

That is the idea of a content filter driver: it modifies the content, without affecting git status (which still reports the modified file as "unchanged").

To have a smudge acting differently per branch, I would recommend calling a script which starts by looking the name of the current branch.
See an example in my older answer "Best practice - Git + Build automation - Keeping configs separate".

#!/bin/sh
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)

这篇关于git 涂抹/清洁分支之间的过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆