macOS automatically creates .DS_Store files in every folder you open in Finder. They're harmless on your own machine but are notorious for cluttering Git repositories. This guide covers how to delete them, keep them out of Git, and prevent future pollution.


What Is a .DS_Store File?

DS_Store stands for Desktop Services Store. macOS creates this hidden file in each directory to store metadata about the folder's Finder view: icon positions, window size, background image, sort order, and other display preferences.

The file is invisible in Finder by default (it starts with a dot), but it shows up in Git diffs and git status output, where it creates noise and accidental commits.


Delete All .DS_Store Files in the Current Folder

Run this command from your project's root directory to recursively find and delete every .DS_Store file:

find . -name ".DS_Store" -delete

The find command searches from the current directory (.) through all subdirectories. -name ".DS_Store" matches the filename exactly, and -delete removes each match.

To see what would be deleted before actually deleting (a dry run):

find . -name ".DS_Store"

This lists all matching files without removing them. Once you're confident, add -delete to do the cleanup.


Delete .DS_Store Files from a Specific Directory

# Delete from a specific path
find /Users/yourname/projects/myapp -name ".DS_Store" -delete

# Delete from your entire home directory
find ~ -name ".DS_Store" -delete

Remove .DS_Store Files Already Committed to Git

If .DS_Store files were committed before you added them to .gitignore, deleting them from disk isn't enough — they remain in Git's history and will keep reappearing. You need to untrack them:

# Remove from Git's index (stops tracking), but keep the file on disk
git rm --cached .DS_Store

# Remove all .DS_Store files from tracking recursively
git rm --cached -r --ignore-unmatch "**/.DS_Store"

# Then commit the removal
git commit -m "Remove .DS_Store files from tracking"
Note: --cached removes the file from Git's index without deleting it from your filesystem. Without --cached, Git would delete the file from disk too.

Prevent .DS_Store from Being Committed — .gitignore

Add .DS_Store to your project's .gitignore to prevent it from ever being committed:

# .gitignore
.DS_Store
**/.DS_Store

The **/.DS_Store pattern matches .DS_Store in any subdirectory, not just the root. Commit the .gitignore change so your whole team benefits.


Global .gitignore — Apply to All Your Repositories

If you work on many projects, set a global .gitignore so you never have to think about this again:

# Create (or edit) the global gitignore file
echo ".DS_Store" >> ~/.gitignore_global

# Tell Git to use it for all repositories
git config --global core.excludesfile ~/.gitignore_global

This applies to every repository on your machine, without touching each project's own .gitignore.


Other macOS Clutter Files Worth Ignoring

While you're at it, these other macOS artifacts are also worth adding to your .gitignore:

# macOS metadata and system files
.DS_Store
**/.DS_Store
.AppleDouble
.LSOverride
._*

# macOS Spotlight index files
.Spotlight-V100
.Trashes

# macOS icon files
Icon?

Why .DS_Store Files Matter in Git

Leaving .DS_Store files unignored causes several practical problems:

  • Polluted git status — they appear as untracked files constantly
  • Accidental commits — developers commit them without realizing
  • Merge conflicts — two developers editing Finder view preferences in the same folder creates a merge conflict on a file with no meaningful content
  • Repository bloat — they accumulate over time if not cleaned up
  • Security consideration.DS_Store files can leak folder structure information about your machine

Summary

Run find . -name ".DS_Store" -delete to clean up existing files. Add .DS_Store to .gitignore (or a global ~/.gitignore_global) to prevent future commits. If the files were already committed, use git rm --cached to untrack them without deleting them from disk.

Apache Maven is the most widely used Java build tool. macOS does not ship Maven pre-installed, so you need to add it yourself — either manually from the official download or through Homebrew. This guide covers both approaches, plus how to set up your shell environment so the mvn command is available in every terminal session.


Prerequisites

Maven requires a JDK. Verify Java is installed before proceeding:

java -version
# java version "21.0.2" 2024-01-16 LTS

If this fails, install a JDK first (e.g., from Adoptium or via brew install openjdk). Maven 3.9+ requires Java 8 or later; Maven 4.x requires Java 17 or later.


Option 1: Manual Installation (Recommended for Version Control)

Step 1 — Download the Binary Archive

Go to the Apache Maven download page and grab the binary tar.gz for the latest stable release (3.9.x as of this writing). You can also download it directly from the terminal:

# Replace 3.9.6 with the current version from maven.apache.org/download
curl -O https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz

Step 2 — Extract to a Stable Location

Extract the archive to a directory you control. A dedicated runtime directory in your home folder keeps things tidy:

mkdir -p ~/DevRuntime
tar -xzf apache-maven-3.9.6-bin.tar.gz -C ~/DevRuntime
ls ~/DevRuntime/apache-maven-3.9.6/
# bin  boot  conf  lib  LICENSE  NOTICE  README.txt

Step 3 — Set MAVEN_HOME and Update PATH

macOS Catalina and later use Zsh as the default shell. Add environment variables to ~/.zshenv — this file is sourced for all shell sessions, including non-interactive ones started by IDEs and build pipelines:

# Open ~/.zshenv in any text editor, or append with echo:
echo 'export MAVEN_HOME="$HOME/DevRuntime/apache-maven-3.9.6"' >> ~/.zshenv
echo 'export PATH="$MAVEN_HOME/bin:$PATH"' >> ~/.zshenv

After editing, reload the file in your current shell:

source ~/.zshenv

Step 4 — Verify

mvn --version
# Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
# Maven home: /Users/yourname/DevRuntime/apache-maven-3.9.6
# Java version: 21.0.2, vendor: Eclipse Adoptium, runtime: /Library/Java/...
# Default locale: en_US, platform encoding: UTF-8
# OS name: "mac os x", version: "14.2", arch: "aarch64", family: "mac"

The output confirms Maven is on the PATH and shows which JDK it's using.


Option 2: Install via Homebrew

Homebrew is the simpler option if you don't need to manage multiple Maven versions:

brew install maven

Homebrew installs Maven to /opt/homebrew/opt/maven (Apple Silicon) or /usr/local/opt/maven (Intel) and adds it to your PATH automatically. Verify:

mvn --version
# Apache Maven 3.9.6

which mvn
# /opt/homebrew/bin/mvn

To upgrade later: brew upgrade maven. To see available versions: brew info maven.


Switching Between Multiple Maven Versions

If you need different Maven versions for different projects (e.g., Maven 3.6 for a legacy project, Maven 3.9 for a new one), the manual approach makes switching straightforward. Extract each version to its own subdirectory:

~/DevRuntime/
  apache-maven-3.6.3/
  apache-maven-3.9.6/

Then update MAVEN_HOME in ~/.zshenv to point at the version you want active, and source ~/.zshenv. Alternatively, use a version manager like sdkman, which handles Java and Maven versions together:

# Install sdkman (if not already installed)
curl -s "https://get.sdkman.io" | bash

# Install a specific Maven version
sdk install maven 3.9.6

# Switch to a different version
sdk use maven 3.6.3

The ~/.zshenv vs ~/.zshrc Difference

FileWhen sourcedBest for
~/.zshenvEvery Zsh session — interactive, non-interactive, login, and scriptEnvironment variables like MAVEN_HOME, JAVA_HOME, PATH
~/.zshrcInteractive shells onlyAliases, prompt configuration, completions
~/.zprofileLogin shells onlyCommands that should run once at login

Using ~/.zshenv for MAVEN_HOME and PATH ensures your IDE (IntelliJ IDEA, VS Code) picks up the correct Maven even when it launches a non-interactive shell to run builds.


Running Your First Build

Once Maven is installed, create a simple project to confirm everything works end-to-end:

mvn archetype:generate \
  -DgroupId=com.example \
  -DartifactId=hello-maven \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.4 \
  -DinteractiveMode=false

cd hello-maven
mvn package
java -cp target/hello-maven-1.0-SNAPSHOT.jar com.example.App
# Hello World!

Configuring the Local Repository

Maven downloads dependencies to ~/.m2/repository by default. To change this location (useful if your home directory is on a small SSD), edit ~/.m2/settings.xml:

<settings>
  <localRepository>/Volumes/FastDrive/.m2/repository</localRepository>
</settings>

Summary

To install Maven on macOS manually: download the binary archive, extract it to a stable directory like ~/DevRuntime, set MAVEN_HOME and update PATH in ~/.zshenv, then run source ~/.zshenv and verify with mvn --version. For a simpler one-command install, use brew install maven. Use ~/.zshenv (not ~/.zshrc) for environment variables so that IDEs and non-interactive shells also see the correct Maven installation.

macOS ships with Bash, but the version Apple includes is ancient — Bash 3.2 from 2007. If your scripts rely on features introduced in Bash 4 or later (associative arrays, mapfile, globstar), you need to know what you're running and how to upgrade. Here are all the ways to check.


Method 1: bash --version

The most direct way — run the bash binary with the --version flag:

bash --version

On a stock macOS installation you'll see:

GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23)
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>

If you've installed a newer version via Homebrew, the output will reflect that instead (e.g., 5.2.26(1)-release).


Method 2: $BASH_VERSION Variable

Inside any running Bash session, the $BASH_VERSION variable always holds the current shell's version:

echo $BASH_VERSION
# 3.2.57(1)-release   (Apple's built-in)
# 5.2.26(1)-release   (Homebrew-installed)

This is useful inside scripts when you want to check the runtime version programmatically:

#!/bin/bash
if [[ "${BASH_VERSINFO[0]}" -lt 4 ]]; then
    echo "This script requires Bash 4 or later. You have: $BASH_VERSION" >&2
    exit 1
fi
echo "Good — running Bash ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}"

$BASH_VERSINFO is an array: [0] is the major version, [1] is the minor version.


Method 3: which bash and file Path Check

To see which bash binary is actually on your PATH:

which bash
# /bin/bash          (Apple's system bash)
# /opt/homebrew/bin/bash   (Homebrew bash on Apple Silicon)
# /usr/local/bin/bash      (Homebrew bash on Intel)

If which bash shows /bin/bash but you installed Homebrew's bash, your PATH may not be putting /opt/homebrew/bin first. Check with echo $PATH.


Why Does macOS Ship Bash 3.2?

This comes down to licensing. Bash 3.2 is the last version released under GPLv2. Starting with Bash 4.0, the project moved to GPLv3. Apple's legal policy prevents them from shipping GPLv3 software in macOS, so they're stuck distributing the 2007 Bash 3.2 binary.

This is also why Apple switched the default interactive shell to Zsh in macOS Catalina (10.15, 2019). Zsh uses the MIT license — no GPL restrictions. If you open Terminal on a fresh Mac, you're already using Zsh, not Bash.


Bash 3.2 vs Bash 5: What's Missing

FeatureBash 3.2Bash 4+
Associative arrays (declare -A)Not availableBash 4.0+
mapfile / readarrayNot availableBash 4.0+
** globstar (recursive glob)Not availableBash 4.0+ with shopt -s globstar
read -i (default value in read)Not availableBash 4.0+
Case-insensitive matchingLimitedBash 4.0+ with shopt -s nocasematch
Improved string manipulationBasicBash 4.0+ adds ${var^^}, ${var,,}
Nameref variables (declare -n)Not availableBash 4.3+

Installing a Modern Bash with Homebrew

To get Bash 5 on macOS:

brew install bash

Homebrew installs it at /opt/homebrew/bin/bash (Apple Silicon) or /usr/local/bin/bash (Intel). Verify:

/opt/homebrew/bin/bash --version
# GNU bash, version 5.2.26(1)-release

Making Homebrew Bash the Default

To use it as your default login shell, first add it to the list of approved shells, then change your shell:

# Add to /etc/shells (requires sudo)
echo "/opt/homebrew/bin/bash" | sudo tee -a /etc/shells

# Change your login shell
chsh -s /opt/homebrew/bin/bash

Open a new terminal session and verify:

echo $BASH_VERSION
# 5.2.26(1)-release

Note: Even after this, /bin/bash still exists and is still Bash 3.2. Scripts with #!/bin/bash shebangs continue to use the old version. Use #!/usr/bin/env bash to pick up whichever bash is first on your PATH.


Should You Upgrade or Switch to Zsh?

Since macOS Catalina, Zsh is Apple's recommended default shell for interactive use. Zsh has feature parity with modern Bash and adds improvements like better tab completion, array handling, and the Oh My Zsh ecosystem. If you're writing shell scripts for portability across macOS and Linux, consider:

  • Use Zsh (#!/bin/zsh) for macOS-specific scripts
  • Use POSIX sh (#!/bin/sh) for maximum portability
  • Use Bash 5 from Homebrew (#!/usr/bin/env bash) for scripts that need Bash-specific Bash 4+ features on macOS

Summary

Check the Bash version on macOS with bash --version or by reading $BASH_VERSION inside a script. macOS ships Bash 3.2 (from 2007) because Apple cannot distribute newer Bash versions due to the GPLv3 license. Install Bash 5 via brew install bash for access to associative arrays, globstar, mapfile, and other modern features. macOS Catalina and later default to Zsh; use #!/usr/bin/env bash in scripts so they pick up whichever bash is first on the PATH.

Apple's #WWDC2019 (Worldwide Developers Conference) was held on June 3-7.
Details of the cool announcements  can be found here
https://developer.apple.com/wwdc19/

macOS's next big upgrade will be called Catalina and with it comes a big change for developers.
Catalina macOS

By default macOS has used bash as the default shell. New user accounts in macOS Catalina will use zsh. Zsh is an open source shell very popular and comes with a ton of features.

Zsh Shell

Zsh git repository link is https://github.com/robbyrussell/oh-my-zsh/

Apple support page contains details about how to set the Zsh shell as default for macOS Mojave and earlier https://support.apple.com/en-us/HT208050