Master Git Bare Repositories and Advanced Worktree Techniques for Clean Multi‑Branch Development
This tutorial explains how bare Git repositories differ from non‑bare ones, shows how to create and configure a bare repo, and demonstrates an advanced Git worktree workflow that keeps all branch worktrees organized within a single project directory for seamless multi‑branch development.
Introduction
The previous article introduced Git worktree and how it lets you work on multiple branches simultaneously without interference. However, the worktree directories are created outside the current project, which can be inconvenient for users who prefer tidy disk management. This guide presents an advanced method using bare repositories to solve that problem.
Prerequisites
Before using the advanced technique, you need to understand the concept of a bare repo. Start with the familiar commands:
git init
git clone https://github.com/FraserYu/amend-crash-demo.gitThese commands create a non-bare repo, which contains your project files and is where you normally add, commit, pull, and push.
To create a bare repo, simply add the --bare flag:
git init --bare
git clone --bare https://github.com/FraserYu/amend-crash-demo.gitRunning these clone commands and inspecting the files reveals the differences.
bare repocontains only Git metadata and no project files such as .java, .js, or .py. In contrast, a non-bare repo holds all source files.
The default name of a bare repo ends with .git, confirming the first point.
A bare repo lacks a working .git directory, so you cannot perform add, commit, pull, or push directly on it.
Although a bare repo may seem empty, its immutability makes it ideal for a centralized private repository, preventing accidental modifications.
You can try the following commands locally to experiment:
user@server:$~ git init --bare name_to_repo.git
user@machine1:$~ git clone user@server:/path/to/repo/name_to_repo.git .
user@machine1:$~ cd name_to_repo
user@machine1:$~ touch README
user@machine1:$~ echo "Hello world" >> README
user@machine1:$~ git add README
user@machine1:$~ git commit -m "Adding a README"
user@machine1:$~ git push origin master
user@server:$~ ls /path/to/repo/name_to_repo.git/
branches/ config description HEAD hooks/ info/ objects/ refs/
user@machine2:$~ git clone user@server:/path/to/repo/name_to_repo.git .
user@machine2:$~ ls name_to_repo.git/
README
user@machine2:$~ cat README
Hello worldThe result shows that no matter how many files you push from machine1, the bare repo never stores those files—only Git metadata—while machine2 can see the pushed files after cloning, demonstrating Git's magic.
Now, leveraging the bare repo's properties, we can improve the multi‑branch workflow introduced in the previous Git worktree article.
Advanced Git Worktree Usage
Create a dedicated folder for your project (e.g., amend-crash-demo) and enter it:
mkdir amend-crash-demo
cd amend-crash-demoClone the project as a bare repository into a .bare directory:
git clone --bare [email protected]:FraserYu/amend-crash-demo.git .bareCreate a .git file that points to the .bare directory using the gitdir syntax:
echo "gitdir: ./.bare" > .gitEdit .bare/config to ensure the remote origin is correctly defined:
vim .bare/config
# -----------------------------------------------
[remote "origin"]
url = [email protected]:FraserYu/amend-crash-demo.git
fetch = +refs/heads/*:refs/remotes/origin/*Add a worktree for the main branch:
git worktree add main
# Preparing worktree (checking out 'main')
HEAD is now at 82b8711 add main fileThen create a feature worktree, for example feature/JIRA234-feature3:
git worktree add -b "feature/JIRA234-feature3" feature3
# Preparing worktree (new branch 'feature/JIRA234-feature3')
HEAD is now at 82b8711 add main fileListing the directory shows only the visible worktree folders ( main and feature3) while .bare and .git remain hidden, keeping the workspace clean:
ls -l
# total 0
# drwxr-xr-x 10 rgyb staff 320 Nov 23 21:44 feature3
# drwxr-xr-x 10 rgyb staff 320 Nov 23 21:36 main
ls -al
# total 8
# drwxr-xr-x 6 rgyb staff 192 Nov 23 21:44 .
# drwxr-xr-x 3 rgyb staff 96 Nov 23 21:14 ..
# drwxr-xr-x 12 rgyb staff 384 Nov 23 21:36 .bare
# -rw-r--r-- 1 rgyb staff 16 Nov 23 21:29 .git
# drwxr-xr-x 10 rgyb staff 320 Nov 23 21:44 feature3
# drwxr-xr-x 10 rgyb staff 320 Nov 23 21:36 mainNow you can work independently on each branch, performing add, commit, pull, and push without interference:
echo "feature3 development" > feature3.yaml
git add feature3.yaml
git commit -m "feat: [JIRA234-feature3] feature3 development"
git push --set-upstream origin feature/JIRA234-feature3The four core worktree commands from the previous article make multi‑branch collaborative development straightforward:
git worktree add
git worktree list
# /Users/rgyb/Documents/projects/amend-crash-demo/.bare (bare)
# /Users/rgyb/Documents/projects/amend-crash-demo/feature3 aeaac94 [feature/JIRA234-feature3]
# /Users/rgyb/Documents/projects/amend-crash-demo/main 82b8711 [main]
git worktree remove
git worktree pruneConclusion
By exploiting the characteristics of a bare repository, you can keep all worktrees neatly managed within the project directory, enabling clean multi‑branch collaborative development.
.
└── amend-crash-demo
├── feature3
│ ├── README.md
│ ├── config.yaml
│ ├── feat1.txt
│ ├── feature3.yaml
│ ├── file1.yaml
│ ├── hotfix.yaml
│ ├── main.properties
│ └── main.yaml
└── main
├── README.md
├── config.yaml
├── feat1.txt
├── file1.yaml
├── hotfix.yaml
├── main.properties
└── main.yaml
3 directories, 15 filesIf you are particular about disk organization, this method is an excellent solution.
To fully understand the process, examine the Git‑related files while executing the commands.
References
https://www.blopig.com/blog/2017/06/using-bare-git-repos/
https://lists.mcs.anl.gov/pipermail/petsc-dev/2021-May/027448.html
https://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/
https://infrequently.org/2021/07/worktrees-step-by-step/
https://morgan.cugerone.com/blog/how-to-use-git-worktree-and-in-a-clean-way/
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
