Many developers use Git daily, but few truly understand the underlying commands that power version control. This article demystifies the fundamental Git commands, explaining their purpose and how they interact to manage your project's history. Knowing these commands moves you beyond blindly typing commands to confidently controlling your codebase.
What is a Git Repository?
A Git repository, or repo, is the central storage for your project. Think of it as a highly organized digital filing cabinet that not only holds your project files but also meticulously records every single change made to them over time. At its heart, a Git repo is a hidden .git folder within your project directory. This folder is Git's brain, tracking your code's evolution, enabling collaboration with others on the same codebase, and providing the ability to revert to previous states of your project.
The necessity of a version control system (VCS) like Git becomes clear when considering potential data loss. If your machine fails, your code vanishes. A VCS acts as a safeguard, ensuring your work isn't lost. Even for solo projects, a VCS provides a safety net and a clear history of development decisions.
Initializing a New Repository: git init
The journey with Git begins with git init. This command transforms an existing project directory into a Git repository or creates a new directory with a Git repository inside. When you run git init, Git creates the crucial .git subdirectory. This subdirectory contains all the necessary metadata for version tracking, including the repository's object database and configuration files. It’s the silent engine that makes all other Git operations possible.
Before git init, your project is just a collection of files. After running it, Git starts watching these files. It doesn't automatically track every change yet; that's a subsequent step. But git init lays the groundwork, establishing the repository structure ready to record your project's history.
Checking Repository Status: git status
Once you've initialized a repository and started making changes, git status becomes your most frequently used command. It provides a snapshot of the current state of your working directory and staging area. This command tells you which files have been modified, which are staged for the next commit, and which are untracked by Git.
Understanding git status output is key. You'll see files listed under "Changes to be committed" (staged) and "Changes not staged for commit" (modified but not staged). It also highlights "Untracked files," which are new files Git has detected but isn't yet tracking. This command is your primary tool for understanding what Git sees and what it's about to do.

Staging Changes: git add
Git operates in stages. Before you can permanently record changes (commit them), you must first tell Git which specific changes you want to include in the next commit. This is done using the git add command. You can add individual files, multiple files, or even all changes in the current directory.
git add stages a specific file. git add . stages all modified and new files in the current directory and its subdirectories. Staging is like preparing a package for shipment; you select exactly what goes inside before sealing it. It allows for granular control over your commit history, enabling you to group related changes together logically.
Committing Changes: git commit
A commit is a snapshot of your repository at a specific point in time. It represents a saved state of your project. The git commit command takes all the changes you've staged using git add and permanently records them in the repository's history. Each commit has a unique identifier (a SHA-1 hash) and is associated with a commit message, which should clearly describe the changes made.
The command git commit -m "Your descriptive message" is the most common way to commit. The message is crucial for understanding the history later. Think of each commit as a chapter in your project's story. A well-written commit message is like a clear chapter title, making it easy to navigate and understand the narrative of your project's development. Without a descriptive message, the commit history becomes a confusing jumble of changes.
Viewing Commit History: git log
To understand where your project has been, you use git log. This command displays a history of commits, showing the commit hash, author, date, and commit message for each snapshot. It's an essential tool for reviewing past changes, understanding the progression of features, and identifying when specific modifications were made.
The default output can be quite verbose. You can use various flags to customize the output, such as git log --oneline for a compact view showing only the commit hash and the first line of the message, or git log --graph --oneline --decorate --all for a visual representation of branches and merges. This command is your project's timeline, allowing you to trace its evolution step by step.

Ignoring Files: .gitignore
Not all files in a project should be tracked by Git. Temporary files, build artifacts, dependency directories (like node_modules), and sensitive configuration files often clutter the repository and should be excluded. The .gitignore file is a text file where you specify patterns for files and directories that Git should ignore.
You create a .gitignore file in the root of your repository. Each line in this file specifies a pattern. For example, *.log will ignore all files ending with `.log`, and `node_modules/` will ignore the entire `node_modules` directory. This keeps your repository clean and focused on the source code and essential project files. It's like having a personal assistant who knows which documents are important for the official record and which can be discarded after use.
The Main Branch: Understanding main (or master)
Historically, the default branch in Git was named master. However, in recent years, there has been a widespread shift towards using main as the default branch name. This change is part of a broader effort to adopt more inclusive language in technology. Regardless of the name, the default branch serves as the primary line of development.
When you initialize a repository, Git creates this default branch. Most of your work, commits, and feature development will often branch off from and eventually merge back into this main branch. Understanding its role is crucial for coordinating work, especially in team environments. If someone asks how you name your main branch, you now know the context and the common naming conventions.
