Your first commit
init, add, commit, status, log. Why you need .gitignore.
In this lesson you'll create a repository, build your first commit, and learn to keep clutter out of
history: logs, dependencies, and files with passwords. Commands for this lesson: git init,
git add, git commit, git status, git log, and the .gitignore file.
Creating a repository
In an empty project folder:
git init
A hidden .git/ folder appeared. That's the repository: objects, refs, and config live inside it. If
you delete it, the whole project history is gone. The project's own files stay on disk; only the
versions disappear.
git init is safe to run in an already initialized folder. Git replies
Reinitialized existing Git repository and leaves the history alone.
Along the way it also prints a hint about the name of the first branch (Git 2.52, shortened):
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint: git config --global init.defaultBranch <name>
...
This isn't an error. Git itself still calls the first branch master for now, and Git 3.0 plans to
switch to main. The familiar main comes from GitHub and GitLab: that's
the default branch for new repositories there. That's why git clone leaves you on main, while
git init leaves you on master.
To make the name the same no matter where the repository came from, set it once, globally:
git config --global init.defaultBranch main
The hint will go away, and new repositories will start on main.
Who is the commit author
Every commit records the author's name and email. Git takes them from the user.name and
user.email settings. Set them once before your first commit:
git config --global user.name "Ivan Ivanov"
git config --global user.email "ivan@example.com"
Skip this, and one of two things happens. Either Git refuses to commit with the error
Author identity unknown and fatal: no email was given. Or it fills in your username and machine
name (something like ivan@MacBook-Pro.local) and warns:
Your name and email address were configured automatically. The second case is worse: the commit
goes through, but with an address that means nothing to anyone. The --global flag writes the
setting for every repository; without it, it only applies to the current one.
Three states of a file
In Git, a file lives in one of three places:
[ working dir ] --git add--> [ staging (index) ] --git commit--> [ repo ]
- Working directory — the files sitting on disk.
- Staging area (the index) — what will go into the next commit.
- Repository — committed versions, stored in
.git/.
git add moves changes from the working directory into the index. git commit locks in the
contents of the index as a new commit.
Why not "edit, and it commits right away": the index lets you build a commit selectively. Changed five files but only want two in the commit? Add just those two.
The basic cycle
git status # what changed, what's staged
git add file.md # add one specific file
git add . # everything in this folder and below, check git status first
git commit -m "message" # lock the index into a commit
git log # commit history
git log --oneline # compact log
git log --oneline --graph # with an ASCII branch graph
You'll run git status more than any other command. It shows three groups: what's staged and will
go into the commit (Changes to be committed), what's modified but not staged
(Changes not staged for commit), and what Git doesn't track at all (Untracked files, usually new
files).
git add . is convenient, but it sweeps up everything, including .env and logs if .gitignore
hasn't kept them out. So check git status before running it.
A good commit message
Your colleagues read the message, and so will you, six months from now. The minimum rules:
- one subject line, imperative mood, up to ~72 characters:
fix: nginx 502 on worker restart; - if you need to explain why (not just what), leave the second line blank and write a paragraph after it;
- prefixes like
fix:,feat:,chore:help sort the log, and many teams require them (the Conventional Commits convention).
Don't write update, fix bug, or wip on the main branch. A log like that tells nobody anything a
year from now.
.gitignore
A file at the root of the repository that lists what Git should not see.
Example:
# dependencies
node_modules/
.venv/
# build artifacts
dist/
build/
*.log
# secrets
.env
.env.local
# IDE and OS
.idea/
.DS_Store
Syntax:
node_modules/ignores the whole folder;*.logcatches every file with that extension;/distonly applies at the root,sub/distisn't affected;!keep.logsets an exception: don't ignore this file.
The exception has a limit. If a whole folder is ignored (logs/), you can't bring a file back out of
it with !logs/keep.log: Git doesn't even look inside that folder. The way that works is
logs/*, followed by !logs/keep.log.
.gitignore should always be committed to the repository: the rules need to reach everyone on the
team.
Check why a file is ignored with git check-ignore -v:
git check-ignore -v logs/x.log
.gitignore:2:logs/* logs/x.log
It prints the file with the rule, the line number, and the rule itself.
Trap: a secret got into a commit
You accidentally committed .env with a password in it. Adding .env to .gitignore won't help
here: .gitignore only affects untracked files. If the file is already in the repository,
git status keeps showing its changes.
Remove the file from the index, but leave it on disk:
git rm --cached .env
This command stages the file's removal; the file on disk stays put. After the next commit, Git stops
tracking it, and the line in .gitignore stops it from being added again.
But the file is still in earlier commits, and git log -- .env will show them. If the repository has
already been pushed, treat the secret as leaked and rotate it.
Cleaning up what's already committed needs separate tools (git filter-repo, BFG). Prevention is
simpler: .gitignore and a git status check before you commit.
Common mistakes
- No
user.nameanduser.email. The commit fails withAuthor identity unknown, or goes through with an author likeuser@host.local. git add .withoutgit statusfirst..env, logs, and dependencies ride along into the commit.- A rule got added to
.gitignoreafter the file was already committed. Git keeps tracking it until you rungit rm --cachedand commit. git rmwithout--cached. The file is deleted from both the index and disk..gitignorewas created, but never committed. Your teammates have no rules, and they add the same junk.logs/and!logs/keep.logtogether. The exception doesn't work; you needlogs/*.
What you'll need for the tasks
git initandgit -C <folder> <command>, to work with a repository in another folder withoutcd-ing into it;git config user.nameandgit config user.email;git status,git add <file>,git commit -m;git log --onelineandgit log -- <file>;.gitignore: folders,*.extmasks, checking withgit check-ignore -v;git rm --cached.
The next lesson covers branches and working in parallel.
Interview-style questions
Interview questions on this topic: 3
Included with practice access, $49 one-time. Get access
Answer out loud or in writing, then reveal the answer and honestly mark whether you knew it.
Done reading?
Mark the lesson as read to move your track progress forward.
Lesson marked as done.
Go through it with an AI agent
The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.
Tell the agent: use MCP izi, give me lesson git-basics-02-first-commit
Progress saved in this browser
Clear your history or open this on your phone, and the marks will be gone. Leave your email and they'll move to your account. No password needed.
Done. moved to your account. You can see your progress on any device. My progress