Creating a Git Repository
Before Git can track the history of a project, the project must be inside a Git repository.
The command used to create a new Git repository is:
git initThis command initializes a Git repository inside the current directory.
Start with a Normal Folder
Section titled “Start with a Normal Folder”Suppose we create a normal project directory:
mkdir my-projectcd my-projectAt this point, my-project is only a normal folder. It is not yet a Git
repository.
If we run a Git command that requires a repository:
git statusGit may display an error similar to:
fatal: not a git repository (or any of the parent directories): .gitThis means Git could not find repository information in the current directory or its parent directories.
Initialize the Repository
Section titled “Initialize the Repository”While inside the project folder, run:
git initGit creates a hidden directory named:
.gitThe project folder is now associated with a local Git repository.
You can verify this using:
git statusYou may see output similar to:
On branch main
No commits yet
nothing to commitThe exact initial branch name may depend on your Git configuration.
What Does git init Actually Do?
Section titled “What Does git init Actually Do?”git init creates the internal structure Git needs to manage repository data.
Conceptually, the result looks like:
my-project/├── .git/ Git repository data├── src/ Visible project files├── README.md└── other filesThe visible project directory is called the working tree or working directory.
The hidden .git directory stores Git’s internal repository data.
Project folder├── Working tree → Files you open and edit└── .git → Git metadata, objects, references, and historyWorking Tree vs Repository
Section titled “Working Tree vs Repository”These terms are related, but they are not exactly the same.
Working tree
The checked-out project files you open, edit, create, and delete in your editor.
For example: index.html, auth.js, src/, README.md
.git directory
Git’s private data: objects, branch and tag references, repository configuration, the index once the staging area is used, and history once commits exist.
You work with it through Git commands, not by editing it directly.
Working Tree
Section titled “Working Tree”The working tree contains the checked-out project files that you can view and edit.
Examples:
index.htmlauth.jssrc/README.mdGit Repository
Section titled “Git Repository”Technically, the hidden .git directory contains the local Git repository data.
It stores the information Git uses to manage:
- Commits and other Git objects.
- Branch references.
- Tags.
- Repository configuration.
- The current branch reference.
- The staging area or index when it is created.
- Repository history after commits exist.
In everyday conversation, developers may call the entire project folder “the
repository,” even though the working tree and .git directory have different
responsibilities.
What Is Inside .git?
Section titled “What Is Inside .git?”After initialization, .git may contain entries such as:
.git/├── HEAD├── config├── objects/├── refs/└── hooks/Some files, such as the index, may appear only after performing additional Git operations.
HEAD tells Git which branch or commit is currently checked out.
Before the first commit, the initial branch exists as an unborn branch: it has a name, but it does not point to a commit yet.
config
Section titled “config”Stores configuration specific to this repository.
You can view local configuration using:
git config --local --listobjects/
Section titled “objects/”Stores Git objects, including blobs, trees, and commits, after those objects are created.
Stores references used by branches and tags.
Represents the staging area. It stores the project state prepared for the next commit.
The .git/index file may not exist immediately after an empty git init; Git
creates or updates it when the staging area is used.
hooks/
Section titled “hooks/”Contains sample hooks that can run scripts when certain Git events occur.
Hooks are an advanced topic and will be explained later if needed.
Is .git the Repository?
Section titled “Is .git the Repository?”In a normal, non-bare project, the hidden .git directory is the local Git
repository database and metadata.
The visible files beside it form the working tree.
Together, they provide the normal development experience:
Working tree .git repositoryFiles you edit ↔ History and Git dataDoes git init Store the Current Files?
Section titled “Does git init Store the Current Files?”No. Running:
git initcreates the repository structure, but it does not automatically place the current project files into Git history.
Immediately after initialization, existing files normally appear as untracked files:
git statusExample:
Untracked files: README.md auth.jsTo prepare files for the first commit:
git add README.md auth.jsThen record the staged snapshot:
git commit -m "Initial commit"The detailed behavior of git add, the index, and git commit is covered in the
following workflow lessons.
The First Commit
Section titled “The First Commit”After git init, the repository has no commits.
The first commit is commonly called the initial commit:
git add .git commit -m "Initial commit"After this commit:
- Git has its first recorded snapshot.
- The current branch points to the new commit.
- The repository history has begun.
View the Hidden .git Directory
Section titled “View the Hidden .git Directory”On Git Bash, Linux, or macOS:
ls -laOn PowerShell:
Get-ChildItem -ForceYou should see .git inside the initialized project folder.
What If .git Does Not Exist?
Section titled “What If .git Does Not Exist?”If neither the current directory nor one of its parent directories contains a
valid .git repository, commands such as these will fail:
git statusgit add .git commitgit logCommands that do not require an existing repository, such as the following, can still work:
git --versiongit config --global --listGit Searches Parent Directories
Section titled “Git Searches Parent Directories”When you run a Git command inside a subdirectory, Git usually searches upward
through parent directories until it finds .git.
For example:
my-project/├── .git/└── src/ └── features/Running git status from src/features/ still uses the repository located at
my-project/.git.
This means you normally run git init once at the project root, not inside every
subfolder.
Avoid Accidental Nested Repositories
Section titled “Avoid Accidental Nested Repositories”Do not normally run git init inside a subfolder that is already part of another
repository.
This can create a nested repository:
main-project/├── .git/└── package/ └── .git/The outer repository may then treat the inner repository differently from normal files, which can confuse beginners.
Initialize Git at the intended project root.
Reinitializing an Existing Repository
Section titled “Reinitializing an Existing Repository”If you accidentally run git init again inside an existing Git repository, Git
normally reports that it reinitialized the repository.
It does not normally erase existing commits, but repeatedly running the command is unnecessary.
Always confirm your current directory before initialization:
pwdgit statusIn PowerShell, you can also display the current path using:
Get-LocationComplete Example
Section titled “Complete Example”mkdir my-projectcd my-project
git initgit status
touch README.mdgit status
git add README.mdgit commit -m "Initial commit"
git log --onelineOn PowerShell, create the file using:
New-Item README.mdKey Takeaway
Section titled “Key Takeaway”git init converts a normal directory into a directory containing a local Git
repository by creating the hidden .git folder.
The visible files form the working tree. The .git directory stores Git’s
internal repository data, including objects, references, configuration, staging
information, and recorded history.
Initialization makes version tracking possible, but it does not automatically track or commit your files:
Normal folder
A plain directory. Git is not tracking anything yet.
Git repository
git init
Creates the hidden .git directory. Version tracking is now possible.
Changes prepared
git add
Selected files are placed in the staging area.
First snapshot
git commit
History begins; the current branch points to the new commit.