Create a Git Repository Safely with git-init-db
git-init-db is the old name for git init, kept around for compatibility, and this guide covers it directly. If you found it in a script or an old tutorial and wondered whether it is safe to run, it is. The installed command is Git 2.43.0 from Ubuntu package 2.43.0-1ubuntu7.3. Allow about ten minutes for a first repository.
The route
Jump straight to the step you need, or tick off Done means at the end.
git init is the form you will see in current Git documentation. The examples below use git init-db so the command this guide is actually about stays explicit.
1. Choose the directory before creating anything
Creating a repository changes the target directory by adding Git metadata. Work as your ordinary user in a directory you own. No example here needs sudo; elevated privileges can leave the repository owned by root and make later commits awkward.
For an existing project, replace the placeholder with its real path and inspect it first:
$ PROJECT_DIR=/path/to/project
$ pwd
$ find "$PROJECT_DIR" -maxdepth 1 -mindepth 1 -printf '%f\n' | sort
Checkpoint
Confirm that PROJECT_DIR names the project you intend to track. Do not point this command at your home directory or a filesystem root unless you have deliberately checked what will be included later.
2. Initialise a normal working repository
Change into the project and run the command without a directory argument. Git creates .git in the current directory, including the object and reference directories needed for future commits:
$ cd "$PROJECT_DIR"
$ git init-db
hint: Using 'master' as the name for the initial branch
Initialized empty Git repository in /path/to/project/.git/
The exact hint can differ. On this installed Git, the default initial branch is currently master, but the manual says this is subject to change and can be customised with init.defaultBranch. The repository has no commits yet.
Verify the result without changing it:
$ git status --short --branch
## No commits yet on master
$ test -d .git/objects && test -d .git/refs/heads && echo 'repository layout is present'
repository layout is present
3. Set the initial branch explicitly when it matters
git-init-db's synopsis does not expose --initial-branch, even though the current git init command does. If the first branch name is part of your workflow, set init.defaultBranch before running the compatibility command, or just use git init directly:
$ git config --global init.defaultBranch main
$ git init-db /path/to/another-project
Initialized empty Git repository in /path/to/another-project/.git/
This changes your global Git configuration, so treat it as a deliberate user-level setting. To avoid changing global configuration at all, use the modern command with an explicit branch for just this repository:
$ git init --initial-branch=main /path/to/another-project
If you set a global default only for this test, check it with git config --global --get init.defaultBranch and remove it later with git config --global --unset init.defaultBranch. The unset command changes configuration and may report an error if no value exists.
4. Create a bare repository for a server-side Git endpoint
A bare repository has no working tree. It is appropriate as a shared push target, not as a directory where you edit files. Create it in a new, clearly named directory:
$ git init-db --bare /path/to/project.git
Initialized empty Git repository in /path/to/project.git/
$ git --git-dir=/path/to/project.git rev-parse --is-bare-repository
true
Git places HEAD, objects, refs, hooks and configuration directly in the bare directory. Do not run ordinary working-tree commands there or assume a checkout will appear beside it.
Security boundary
If several users will write to the bare repository, permissions are an operational and security matter. The --shared option changes core.sharedRepository and is not a substitute for choosing the right Unix group and directory ownership. Test the access model with the intended accounts before accepting pushes.
5. Keep the Git directory somewhere else
Use --separate-git-dir when the working tree and repository metadata must live in different places:
$ git init-db --separate-git-dir /path/to/git-data /path/to/project
Initialized empty Git repository in /path/to/git-data/
$ cat /path/to/project/.git
gitdir: /path/to/git-data
In this mode, .git is a text file containing the actual repository path. Check both paths before moving either one; a broken path makes the working tree appear not to be a repository at all.
6. Reinitialisation and recovery
Running the command in an existing repository is normally safe: Git does not overwrite existing repository data. It may pick up newly added templates, and --separate-git-dir can move the repository metadata. That does not mean every invocation is harmless. Stop if the path is unexpected, if ownership is wrong, or if a separate Git directory would replace a layout you still need.
Warning
If you created a repository in the wrong empty directory, the command itself has no undo. Preserve any files you care about, then remove only the unwanted .git directory once you have checked its path. For a separate repository, preserve both the working tree's .git file and the target Git directory until you have confirmed the correct replacement. Do not use a broad recursive deletion command as a shortcut.
A failed initialisation may leave a partial directory. Read the error, inspect the target and check ownership before retrying. If the directory holds valuable data, copy or back it up first. Most failures are path, permission or invalid template-directory problems, not reasons to run the command as root.
Done means
- Target checked. The target path was checked before it was modified.
- Repository created.
git init-dbcreated a normal repository, or--barecreated the intended server-side one. - Type confirmed.
git status --short --branchorgit rev-parse --is-bare-repositoryconfirms the type and initial state. - Branch choice understood. The initial branch choice is a deliberate one, not copied from an unexamined default.
- Separate dir intact. Any separate Git directory and its
.gitpointer are both present and readable.