Tired of Git Branch Case Sensitivity? Here's a Fix for Git Bash Users

Hey fellow devs! Here’s a small but super useful Git trick for dealing with that annoying branch case sensitivity issue. You know the drill—someone creates feature/UserAuth, but you type feature/userauth. On a case-sensitive OS, Git tells you the branch doesn’t exist. On a case-insensitive OS like Windows or macOS, it’s worse—you switch to the wrong branch without realizing it. Later, you discover both feature/userauth and feature/UserAuth exist on GitHub. Ouch.

This is particularly painful when working with Windows or macOS, where the filesystem is case-insensitive, but Git isn't. Add in a mix of developers with different habits (some love their CamelCase, others are all-lowercase fans), and you've got yourself a daily annoyance.

The Fix

I wrote a little Git alias that makes checkout case-insensitive. It's basically a smarter version of git checkout that you use as git co. Here's what it does:

$ git co feature/userauth
⚠️ Warning: "feature/userauth" is incorrect. Switching to: "feature/UserAuth"
Switched to branch 'feature/UserAuth'

Nice, right? No more "branch not found" errors just because you got the case wrong!

Important Note ⚠️

This works in:

  • Windows Git Bash (tested and used daily)
  • Should work in macOS/Linux (though I haven't tested it - let me know if you try!)

But it won't work in:

  • Windows CMD
  • Windows PowerShell
  • Any other Windows terminals

Why? Because it uses Bash commands and parameters. But hey, you're using Git Bash anyway, right? 😉

How to Install

Just run this in Git Bash:

git config --global alias.co '!f() {
  # If no args or help flag, show git checkout help
  if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
    git checkout --help;
    return;
  fi;
  # If any flags are present (except -q or --quiet), pass through to regular checkout
  if [ $# -gt 1 ] || [[ "$1" == -* && "$1" != "-q" && "$1" != "--quiet" ]]; then
    git checkout "$@";
    return;
  fi;
  # Pass through if argument is a commit reference (HEAD, SHA, tag, etc)
  if [[ "$1" =~ ^HEAD([~^]|@{)[0-9]*$ ]] || # HEAD~1, HEAD^1, HEAD@{1}
     [[ "$1" =~ ^[0-9a-f]{4,40}$ ]] || # SHA hashes
     [[ "$1" =~ ^(FETCH_HEAD|ORIG_HEAD|MERGE_HEAD)$ ]] || # Special refs
     [[ -f ".git/refs/tags/$1" ]]; then # Tags
    git checkout "$@";
    return;
  fi;
  # Fetch and prune to ensure we have latest refs
  git fetch --prune --quiet;
  # Check both remote and local branches
  correct_branch=$(git branch -r | sed "s/^  origin\///" | grep -i "^$1$");
  if [ -z "$correct_branch" ]; then
    correct_branch=$(git branch | sed "s/^[* ] //" | grep -i "^$1$");
  fi;
  # If branch found with different case, warn and use correct case
  if [ -n "$correct_branch" ] && [ "$1" != "$correct_branch" ]; then
    echo "⚠️ Warning: \"$1\" is incorrect. Switching to: \"$correct_branch\"";
    git checkout "$correct_branch";
    return;
  fi;
  # Otherwise just pass through to regular checkout
  git checkout "$1";
}; f'

What's Cool About It?

  • Finds your branch regardless of how you type the case
  • Still works normally for everything else (files, creating branches, etc.)
  • Shows you the correct branch name when you get the case wrong
  • Auto-fetches to make sure it sees all remote branches

The best part? If it doesn't recognize what you're trying to do, it just passes everything to regular git checkout. So it won't break any of your normal Git workflows.

Real World Usage

I use this daily in a Windows-heavy dev team where we have branches like:

  • feature/UpdateUser
  • hotfix/FixLoginBug
  • release/v2.0.0

And now I can type them however I want. Life's too short to remember exact branch capitalization!

Give It a Try!

If you're using Git Bash on Windows and tired of case sensitivity issues, give this a shot. It's one of those small tools that just makes your day a tiny bit better.

And hey, if you try this on macOS or Linux, let me know how it goes! Always curious to hear if these tricks work in other environments.

书摘:暗淡蓝点

卡尔·萨根

三、大降级

Page 122 @ 31 March 2024 10:11:44 AM

在目前人类技术发展的早期,我们已能用硅和金属创造出智慧,那么在今后几十年或若干世纪又将会如何呢?一旦灵巧的机器能够制造更灵巧的机器,将会出现什么样的情景啊!

Page 126 @ 31 March 2024 10:14:59 AM

如果宇宙在时间上是无限的——如果大约 150 亿年前的大爆炸只是宇宙在无穷多次的收缩和膨胀中最近的一个起点——那么它从来没有被开创过,因此它为什么成为现在这样,这个问题就变得毫无意义了。

Page 138 @ 31 March 2024 10:24:58 AM

大部分争论现都已得到最后解决,尽管结论令人痛苦,它肯定是支持这一句简练的话:在宇宙戏剧中,我们不是主角。

四、并非为我们造的宇宙

Page 140 @ 31 March 2024 10:26:14 AM

我们不说地球在旋转,而说太阳升起和下落。不妨试用哥白尼式的说法,难道你会讲,“比利(Billy),在地球转得够多,把太阳遮掩到此处地平线下的时候,你就回家吧”?你这句话还没说完,比利早就转身走掉了。我们甚至还没有找到一种优雅的习惯用语来准确表达日心学说的见解。我们是在中心,而一切天体都绕我们运转,这在我们的语言中已经根深蒂固了。我们也这样教孩子。我们是披着哥白尼外衣的顽固守旧的地心说信徒。①

Page 168 @ 31 March 2024 11:04:11 AM

我们的自高自大接连被戳穿,这使我们的时代背着累积而成的沉重包袱。我们是后来者;我们生活在宇宙的荒野中;我们来自微生物和污泥;猿猴是我们的远亲;我们的思想和感觉并不完全由自己控制;其他地方可能还有更灵巧得多的和大不一样的生灵。除了这一切之外,我们正在把自己的行星搅得一团糟,并正在对自己构成威胁

五、地球上有智慧生命吗?

Page 189 @ 31 March 2024 11:35:53 AM

在含氧的大气中,甲烷是生命的一个征兆。

六、“旅行者号”的胜利

Page 244 @ 31 March 2024 12:34:56 PM

“旅行者号”从发射到与海王星会合,每一年只花费每一个美国人不到一分钱。我认为对行星的探测,是我们不仅对美国,也是对全人类做得最好的事情之一。

八、第一颗新行星

Page 281 @ 31 March 2024 03:05:20 PM

我们不知道首先察觉行星与恒星不一样的祖先叫什么名字。他或她应当是活在几万年或甚至几十万年以前。但是全世界的人终于了解到,装饰夜空的明亮光点中有五个——只有五个——与别的光点步伐不一致,它们往往在几个月内古怪地运行,好像它们有自己的主见。这些行星一样,太阳和月亮也有奇怪的视运动。这样一来,在天界漫游的星体总数为七个。

二十、黑暗

Page 731 @ 01 April 2024 10:31:35 AM

在银河系里大约有 4000 亿颗恒星。在如此繁多的星体中,是否仅仅我们这个平凡的太阳才拥有有生物居住的行星?也许如此。也许生命与智慧的起源是太难得了。也有可能文明世界随时涌现.但是一旦办得到时它们就把自己毁灭了。

Page 764 @ 01 April 2024 01:42:19 PM

当然,把国库相当大的一部分经费用于这种探险事业是愚蠢的,但是我在想,是否肯花费一些注意力来争取解决若干重大问题,这可以衡量一个社会的文明水平。

二十一、上天去!

Page 777 @ 01 April 2024 01:55:08 PM

由于我们自己的行动或无所作为,由于滥用我们的技术,我们生活在一个至少对地球来说是非常的时代——第一次有一个种族可以把自己毁灭掉的时代

Page 778 @ 01 April 2024 01:56:56 PM

也许这种熟悉的进化过程在许多世界上发生——一个行星刚形成,宁静地绕它的恒星运转;生命缓慢地产生;万花筒似的形形色色生物在进化;智慧生物出现了,而至少在某一阶段智慧对生存有很大的价值;然后科技发明出来了。他们才逐渐明白有自然规律这种东西,而这些规律可用实验显示出来,掌握这些规律就能以前所未有的规模来拯救生命,但也可以用同样规律大规模地夺取生命。人们认识到,科学赋予他们以巨大的力量。只在一瞬间,他们就可以想出改变世界的发明。有的行星上的文明社会认清了这一点,它们对可以干和不能干的事情都加以限制,于是安全地度过了危险时期。其他的文明社会不是这样幸运,或者不是如此谨慎,就自行毁灭了

Page 794 @ 01 April 2024 02:14:23 PM

如果在太阳系中有其他生物,由于我们要去他们那里,就会给他们带去逼近眼前的危险。在这种情况下,我甚至会相信,为了保护人类而移居某些其他世界的益处至少有一部分被我们带给其他生物的危险抵销了。但是至少在目前就我们所知而言,在太阳系里并没有其他生物,甚至连一个微生物也没有。只是地球上才有生物。 在这个情况下,我代表地球上的生物强烈要求,在我们能力的有限范围内,我们应当大力增进对太阳系的认识,然后开始向其他世界移民定居。 这些就是以前没有谈到过的实用论据:保护地球,使它免于可以逃避的灾难性撞击,并避免对养育我们的环境的(已知或未知的)其他种种威胁下赌注。没有这些论据,也许就缺乏把人送往火星或其他世界的使人无话可说的论据。但是有了它们——以及包括科学、教育、前景和希望的旁证——我想进入太空就有了强有力的论据。如果人类的长期生存受到威胁,我们对人类去其他世界的探险就负有基本的责任。 我们是在宁静的海洋上航行的水手,我们感受到了微风的吹拂

二十二、踮着脚穿过银河系

Page 813 @ 02 April 2024 07:11:55 AM

太空浩瀚,恒星相距太远。即使有比我们更古老和更先进的文明社会,他们从自己本来的世界向外发展,改造出新的世界,然后继续向其他星球扩展;但是按加利福尼亚大学洛杉矶分校的纽曼{William Newman)和我的计算结果,他们未必会来到我们这里,现在还没有。此外,因为光速不是无限大,在太阳的某个行星上出现了技术文明的电视与雷达信息还没有传到他们那里,现在还没有。

Page 819 @ 02 April 2024 07:15:04 AM

从人类最后残余的游牧民族来判断,就在他们被现代的世界文明吞没之前,日子可能过得还是比较愉快的。我们就是在这样的生活中磨炼出来的

Page 829 @ 02 April 2024 09:30:06 AM

喜欢争吵的人不大可能在太空中长久生存。

Page 837 @ 02 April 2024 11:07:26 AM

如果我们继续仅仅聚集权力而不是智慧,我们肯定会毁灭掉自己

Page 839 @ 02 April 2024 12:24:29 PM

恒星之间相距遥远,这是一种天意。生灵以及世界都互相隔离。只是那些有充分自知之明和判断能力的生物,才能消除这种隔离,安全地从一颗恒星到另一颗恒星去旅行

Page 841 @ 02 April 2024 12:28:09 PM

会不会有朝一日我们对人类已度过的时光和自己的成就感到满足,于是自愿退出宇宙舞台呢

Page 850 @ 02 April 2024 05:30:33 PM

在过了一段短暂的定居生活后,我们又在恢复古代的游牧生活方式。我们遥远的后代们,安全地布列在太阳系或更远的许多世界上,他们将会联合起来。促使他们联合的因素是他们的共同遗产,他们对地球老家的惦念以及他们都认识到,无论遇到什么样的外星人,整个宇宙中独一无二的人类都来自地球。 他们将抬头凝视,在他们的天空中竭力寻找那个蓝色的光点。他们不会由于它的暗淡和脆弱而不热爱它。他们会感到惊奇,这个贮藏我们全部潜力的地方曾经是何等容易受伤害,我们的婴儿时代是多么危险,我们的出身是多么卑微,我们要跨越多少条河流,才能找到我们要走的道路。

Generated at: 2025-02-17-21-57-55

Claude.AI 帮我改进 IsHtml 判断

让我重新分析这个问题:

  1. 需要考虑的HTML情况:
  • 简单标签: <div>text</div>
  • 带属性标签: <a href="url">text</a>
  • 自闭合标签: <br/>
  • 带属性的自闭合标签: <img src="img.jpg"/>
  1. 需要排除的markdown链接格式:
  • 专指<https://...>这种格式
  • 特征是 < 后紧跟 http 或 https
  1. 当前正则的问题:

<\s*([a-zA-Z]+)[^>]*>.*</\s*\1\s*>|<\s*([a-zA-Z]+)[^>]*/>

它会匹配所有以 < 开头,包含字母的内容,这就导致了误匹配

  1. 改进思路:
  • 排除标签名以 http(s) 开头的情况
  • 使用负向预查 (?!http(s)?)
  • 放在标签名匹配的开始处
  1. 优化后的正则表达式:

<\s*(?!https?)([a-zA-Z]+)[^>]*>.*</\s*\1\s*>|<\s*(?!https?)([a-zA-Z]+)[^>]*/>

  1. 验证效果:
  • <div>text</div> ✓ 匹配
  • <a href="url">text</a> ✓ 匹配
  • <br/> ✓ 匹配
  • <img src="img.jpg"/> ✓ 匹配
  • <https://abc.com/> ✗ 不匹配

这个解决方案:

  • 保留了原有正则的基本结构
  • 只添加了对标签名的限制条件
  • 能正确处理各种HTML标签
  • 成功排除markdown格式的URL

建议修改代码为:

public static bool IsHtml(this string input)
{
    return Regex.IsMatch(input, 
        @"<\s*(?!https?)([a-zA-Z]+)[^>]*>.*</\s*\1\s*>|<\s*(?!https?)([a-zA-Z]+)[^>]*/>", 
        RegexOptions.Singleline | RegexOptions.IgnoreCase);
}

网友语录 - 第18期 - 人生是连续的刹那,(一定要)尽情活在当下。

这里记录我的一周分享,通常在周六发布。


我们总是觉得可以强迫孩子喜欢那些我们认为更好的书籍和玩具,可以让父母把他们囤积很久的旧东西都扔掉,但事实上“什么对我来说更重要”这件事,对每个人来说都像是内心一道坚固的城墙,靠外力几乎无法撼动。


Marskay AI再厉害又怎样呢,很多人类还是连爱都不敢说出口。


nuo诺诺诺诺 人生是连续的刹那,尽情活在当下。


Jolly 愿新年,胜旧年。2025,更好的爱自己爱生活 ❤️


Jolly 对未来的真正慷慨,是把一切都献给现在。

4o: 这句话的意思是:真正的慷慨不是空谈未来,而是全力以赴地活在当下,把现在能做的事做到最好。

从现实角度看,我们对未来的投资、梦想的实现,归根结底都取决于当下的努力。如果总是把希望寄托在“以后再做”或者“未来会变好”,反而可能让未来一无所有。真正的慷慨,是把时间、精力、热情毫无保留地投入到现在,而不是吝啬当下、幻想未来。

你怎么看这句话?

我:全力以赴的活在当下就是全力以赴的活在未来。因为未来正是由一个个当下组成的。

4o: 说得好!未来不是凭空而来的,而是由无数个“现在”叠加而成的。全力以赴地活在当下,其实就是在为未来铺路。

很多人把未来当作一种“遥远的理想”,但实际上,未来并不是等来的,而是做出来的。每一个认真的选择、每一分投入的努力,都会在未来的某个时刻回馈给自己。

所以,与其焦虑未来,不如把握当下;与其幻想未来,不如创造未来。

我:你小嘴叭叭的,比我能说啊


艾森豪威尔:如果人民只要温饱就能够满足,他们还不如待在监狱里。


Marskay摘 中国人终其一生想要爱但又耻于说爱,于是学了一个「情绪价值」不分场合到处用。


戈城 探求事实的逻辑,和做生意投资的逻辑,刚好是反的。投资做决策似乎就得“听风就是雨”;但在探索事实的时候,“听风就是雨”就是完全不可靠的。


Unix is much more than an operating system: it is nothing less than a culture. So as you read this book and think about what you are learning, realize that you are doing more than simply learning how to use yet another computer tool. You are becoming a member of the global Unix community, the largest collection of smart people in the history of the world. 摘自《Harley Hahn's guide to Unix and Linux》


当代作家玛丽安·威廉森(Marianne Williamson)说: 我们最大的恐惧不是我们不够完美,
我们最大的恐惧是我们无比强大。
我们的光明,而不是我们的黑暗,让我们心存畏惧。你是上帝的孩子。你的小心翼翼帮不了这个世界。
缩小自己,好让周围的人在你身边不会觉得不自在,这并不明智。
我们生下来就是为了彰显内在的荣光。那不仅存在于某些人,而是存在于每一个人!
当我们让自己的光芒闪耀,无意中我们也允许了他人散发光芒。
一旦我们从自我的恐惧中解放出来,我们的存在,也会让他人得到解放。

Why We Shouldn't Unconditionally Load Data in `didChangeDependencies

Flutter’s didChangeDependencies lifecycle method is a common source of redundant network requests and data reloads. Based on real-world code examples from a notes app, let’s explore why this happens and how to fix it.


When Does didChangeDependencies Trigger?

didChangeDependencies in Flutter triggers in these scenarios:

  • Immediately after initState()
  • When an InheritedWidget ancestor changes
  • When the widget's dependencies change

In the provided HomePage code:

@override  
void didChangeDependencies() {  
  super.didChangeDependencies();  
  navigateToPage(currentPageNumber); // ❌ Unconditional call  
}  

This causes duplicate API calls every time the event being triggerd.


The Fix: Initialize-Once Flag

class HomePageState extends State<HomePage> {  
  ...
  bool _isInitialized = false; // Add flag  

  @override  
  void didChangeDependencies() {  
    super.didChangeDependencies();  
    if (!_isInitialized) {  
      _isInitialized = true;  
      navigateToPage(currentPageNumber); // ✅ Only first load  
    }  
  }  
  ...
}  

Why This Works

  1. First Load: Initializes data once
  2. Subsequent Route Changes: Skips reload unless explicitly refreshed
  3. Memory Efficiency: Prevents duplicate API calls (evident from the NotesService cache-less implementation)

Key Takeaways

  1. didChangeDependencies isn’t just for initialization
  2. Always guard data-loading logic with flags