git init is the command that turns an ordinary folder into a Git repository. It creates a hidden .git subdirectory containing the object database, refs, and config that Git needs to start tracking history. You only run it once per project — after that, every git add and git commit writes into that same .git directory. This is the first post in this site’s Git command guide, so if you’re setting up a brand-new project, this is where you start.
Basic Usage
Let’s say you have a folder on your desktop named project. Open a terminal in that directory and run git init:
$ cd ~/Desktop/project
$ git init
Initialized empty Git repository in /Users/USER/Desktop/project/.git/
That’s it. Git is now watching this directory. Nothing is tracked yet — git init only creates the repository structure, it doesn’t commit anything on its own.
Setting the Default Branch Name to main
If you’ve initialized repositories before late 2020, you’ll remember that git init used to create a branch called master by default. In October 2020, the Git project added support for configuring the initial branch name, and shortly after, GitHub, GitLab, and Bitbucket all switched their default to main for new repositories. If you’re running an older Git client, or you just want to be explicit, you can set the branch name at init time instead of renaming it later:
$ git init -b main
Initialized empty Git repository in /Users/USER/Desktop/project/.git/
-b main is shorthand for --initial-branch=main — both do the same thing. If you’d rather not type the flag every time, set it once globally and every future git init (and every fresh GitHub-style clone setup) will default to main automatically:
$ git config --global init.defaultBranch main
Modern Git (2.28+) will actually nag you about this if you haven’t set it — you’ll see a hint like hint: Using 'master' as the name for the initial branch. This default branch name is subject to change. the first time you run git init without configuring it. Setting init.defaultBranch once gets rid of that hint for good and saves you from the old workflow: initialize, work, then realize halfway through a tutorial that you need to git branch -m master main to match the rest of the world’s examples.
How the Code Works
git initcreates a.gitfolder containingobjects/,refs/,HEAD, and a defaultconfigfile — this is the entire repository database.- No files in your working directory are touched or tracked automatically. You still need
git addandgit commit. -b <name>sets the name of the first branch that will be created once you make your first commit (the branch doesn’t formally exist until then — it’s just a pointer waiting for a commit).- Running
git initagain in a directory that’s already a repository is safe — it won’t overwrite history, it just reinitializes missing pieces (useful for restoring a corrupted.git/config).
Reference: Common git init Flags
| Flag | What it does |
|---|---|
git init | Initializes a repo with whatever init.defaultBranch is set to (or master if unset, on older Git) |
git init -b main | Initializes a repo and names the first branch main |
git init <directory> | Creates <directory> if needed and initializes it as a repo |
git init --bare | Creates a bare repository with no working directory — used for shared/server-side remotes |
git config --global init.defaultBranch main | Sets the default initial branch name for all future git init calls |
FAQs
Does git init connect to a remote repository?
No. git init only creates a local repository. If you want a local copy of a repository that already exists on GitHub or another server, you want git clone instead.
Is it safe to run git init in a folder that already has files?
Yes. git init doesn’t touch your existing files — it just adds the .git tracking folder. Your files won’t be tracked until you explicitly git add them.
How do I rename master to main after I’ve already initialized the repo?
Run git branch -m master main locally, then push with git push -u origin main and delete the old branch on the remote. See the Git Branch post for the full rename workflow.
What’s the difference between git init and git init –bare?
A normal git init creates a working directory you can edit files in. A --bare repository has no working directory at all — it only stores the Git history. Bare repos are what you’d set up on a server as a push target, not something you work in directly.
See Also: This Site’s Git Command Guide
This post is part of a 13-part Git command guide on this site. Here’s the rest, in the order I’d actually read them:
- Git Clone — copying an existing repository instead of starting from scratch
- Git Add — staging specific files for a commit
- Git Add . (All) — staging all changes at once
- Git Commit — saving staged changes to the repository
- Git Status — checking what’s changed before you commit
- Git Branch — creating, listing, and renaming branches
- Git Checkout — switching branches and restoring files
- Git Push — sending your commits to a remote
- Git Pull — fetching and merging remote changes
- Git Log — reading commit history
- Git: Delete Last Commit — undoing a commit safely
- Git – Autocorrect Spelling — typo recovery and productivity config
Conclusion
The thing that trips people up about git init isn’t the command itself — it’s the branch name default lagging behind what every tutorial and CI config now assumes. Set init.defaultBranch main once, globally, and you’ll never have to think about it again. Next up: cloning a repository that already exists, in Git Clone.