Version an existing project
A folder of code that was never tracked gets a repository; then you run git add . and git commit to record its starting state.
Git · Command
git init creates a new, empty Git repository, or reinitializes one that already exists. It is usually the first command you run to put a project under version control.
Last updated
git init builds the repository skeleton, which is normally a .git directory. It holds the object store, refs/heads and refs/tags, plus files copied from a template directory. It also creates an initial branch with no commits yet. You can set GIT_DIR to put the repository somewhere other than ./.git, and GIT_OBJECT_DIRECTORY to choose where objects are stored. If you pass a directory, Git runs inside it and creates it if needed. Options also control the hash algorithm, the ref storage format, the initial branch name and group-sharing permissions.
git init [-q | --quiet] [--bare] [--template=<template-directory>] [--separate-git-dir <git-dir>] [--object-format=<format>] [--ref-format=<format>] [-b <branch-name> | --initial-branch=<branch-name>] [--shared[=<permissions>]] [<directory>]| Name | Type | Description |
|---|---|---|
-q, --quiet | flag | Prints only errors and warnings; all other output is hidden. |
--bare | flag | Creates a bare repository, which has no working tree. If GIT_DIR is unset, the current directory is used. |
--template=<template-directory> | path | The directory whose template files are copied into the new repository. |
--separate-git-dir=<git-dir> | path | Stores the repository at <git-dir> and leaves a small text file pointing to it where .git would normally be. |
--object-format=<format> | sha1 | sha256 | The hash algorithm for the repository. sha1 is the default; sha256 only works if enabled. |
--ref-format=<format> | files | reftable | How refs are stored: files (loose files plus packed-refs, the default) or reftable. |
-b, --initial-branch=<branch-name> | string | The name of the first branch in the new repository. |
--shared[=<permissions>] | false | true | umask | group | all | world | everybody | 0xxx | Makes the repository shareable by several users by setting core.sharedRepository. With no value it means group. |
<directory> | path | The directory to run in; it is created if it does not exist. |
#!/usr/bin/env bash
set -euo pipefail
# Bare repository to act as a shared remote
git init --bare --initial-branch=main /tmp/demo-remote.git
# New working repository (directory is created automatically)
git init -b main /tmp/demo-app
cd /tmp/demo-app
echo "# Demo" > README.md
git add .
git commit -m "Initial commit"
git remote add origin /tmp/demo-remote.git
git push -u origin main
# Safe to rerun: existing data is left alone
git initThe script creates a bare remote and a working repository, both starting on main, makes a first commit, pushes it, and then runs git init again to show that rerunning is harmless.
A folder of code that was never tracked gets a repository; then you run git add . and git commit to record its starting state.
An admin creates a bare repository on a server, using --shared=group so team members can push to it.
With --separate-git-dir, the project folder holds only a pointer file, and the actual repository lives on another disk or path.
A company template directory and init.defaultBranch give every new repository the same hooks, exclude patterns and branch name.
A bare repository has no working tree, so there are no checked-out files to edit. With --bare, the repository itself is created in the current directory, or in GIT_DIR if that is set, instead of inside a .git subfolder. It is the usual choice for a central or server repository that people push to and fetch from.
Follow-up: Why add --shared to a server repository? It sets core.sharedRepository so new files get group-friendly permissions, which lets everyone in the Unix group push. It also turns on receive.denyNonFastForwards by default.
It is safe: Git reinitializes the repository without overwriting anything already there. People mostly do this to pick up newly added template files. It is also how you move the repository elsewhere with --separate-git-dir.
Follow-up: Does rerunning it turn on the sample hooks? No. Sample hooks stay disabled until you rename each file to drop its .sample suffix.
Pass -b <name> or --initial-branch=<name> to git init. To set it for every new repository, use the init.defaultBranch config variable. If you do neither, Git currently uses master, and the docs say this will become main in Git 3.0.
Follow-up: Which wins between the --object-format option, GIT_DEFAULT_HASH and init.defaultObjectFormat? Both the command-line option and the environment variable take precedence over the config setting.
git clonegit addgit commitgit configgit init-dbgithooksgitignore