Posts tagged with “git”

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.

Using `git diff HEAD` to show All Changes

You probably know:

  • git diff shows unstaged changes.
  • git diff --cached shows staged changes.

But how do you see all changes in one go? Just use:

git diff HEAD

Here's the breakdown:

  • git diff compares the working directory to the staged index. If nothing is staged, it's the same as git diff HEAD.
  • git diff --cached compares the staged index to HEAD. It's a shortcut for git diff --cached HEAD.
  • git diff HEAD (or git diff <commit/branch/tag>) compares your current working directory with the specified commit.

A tip to ease the process creating new feature branch

We use feature/ticket-number-team-abbr as feature branch name, such as feature/mt-1234-axo at work.

If you mainly work with a huge repository. Everytime, you switch to the integration/main branch and run git pull before you create a feature branch, it would take a while as it needs to update your work directory and normally there are a lot of files changed.

I use a different way which is a little bit speedy. Whatever which branch you are now in, run

git fetch && git checkout -b feature/mt-xxxx-axo origin/integration 

It helps but I still need to type the above, which is still a lot of letters! So, I create a bash script to help me more,

see the following command nbi 38546

nbi 38546
remote: Enumerating objects: 22, done.
remote: Counting objects: 100% (22/22), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 22 (delta 17), reused 22 (delta 17), pack-reused 0
Unpacking objects: 100% (22/22), 4.43 KiB | 5.00 KiB/s, done.
From github.com:Euronet-XE/DFX
   941796a8a..11f76bff7  feature/mt-38183-fugu -> origin/feature/mt-38183-fugu
 * [new branch]          feature/mt-39492-ice  -> origin/feature/mt-39492-ice
 * [new branch]          feature/mt-39744-ice-card -> origin/feature/mt-39744-ice-card
branch 'feature/mt-38546-axo' set up to track 'origin/integration'.
David.Wei @ /d/git/xemt-core/dfx - [feature/mt-38546-axo] $

what’s in this nbi script? here it is

cat ~/bin/nbi
#!/bin/bash

# Check if the current directory is a git repository
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
    echo "Error: Current directory is not a git repository."
    exit 1
fi

# Run git fetch to get the latest changes from the remote repository
git fetch

# Determine the action based on the script name
case "$(basename "$0")" in
    nbi)
        # Check if an argument is provided
        if [[ $# -eq 1 ]]; then
            # Run git checkout to create and switch to a new branch based on the integration branch
            git checkout -b "feature/mt-$1-axo" "origin/integration"
            exit $?
        else
            echo "Usage: $0 <anumber>"
            exit 1
        fi
        ;;
    nbm)
        # Check if an argument is provided
        if [[ $# -eq 1 ]]; then
            # Run git checkout to create and switch to a new branch based on the main branch
            git checkout -b "feature/mt-$1-axo" "origin/main"
            exit $?
        else
            echo "Usage: $0 <anumber>"
            exit 1
        fi
        ;;
    *)
        echo "Error: Unsupported script name."
        exit 1
        ;;
esac

why do I call it nbi ? haha, it is a ABBR from new branch from integration

Wait, why did I mention nbm in the script? Yes, you can copy this nbi script with name nbm , then using the nbm command it will work the same way with the repositories that use main as the integration branch.

Did you see? How lazy I am!

2024-07-22 Update: I also wrote another script sw to ease the switching branches operation:

#!/bin/bash

# Check if the user provided a number
if [ -z "$1" ]; then
  echo "Usage: sw <number>"
  exit 1
fi

# Construct the branch name
branch_name="feature/mt-$1-axo"

# Switch to the branch
git switch "$branch_name"

# Check if the switch was successful
if [ $? -eq 0 ]; then
  echo "Switched to branch '$branch_name'"
else
  echo "Failed to switch to branch '$branch_name'"
fi

git stash -S # stash staging changes only

git-stash-s.png

How to show space and tabs with git-diff

git config diff.wsErrorHighlight all

Reference