Git Commands Every Developer Uses Daily
Git is the backbone of modern software development, and fluency with its command-line interface is a skill that pays dividends every single working day. Whether you are working solo on a personal project or collaborating with dozens of developers on an enterprise codebase, knowing the right Git commands for each situation saves time, prevents mistakes, and keeps your version control history clean and meaningful. This guide covers the Git commands that developers use most frequently, organized by workflow stage, with detailed explanations of what each command does, when to use it, and practical context that goes beyond what you will find in a basic cheat sheet.
Initializing and Configuring Repositories
The git init command creates a new Git repository in the current directory. It sets up the hidden .git subdirectory that contains all the metadata Git needs to track changes, including object storage, branch references, and configuration. You use this command when starting a new project from scratch. After running git init, the directory becomes a working repository where you can add files, create commits, and manage branches. In most cases, however, you will clone an existing repository rather than initializing a new one, making git init more common for quick experiments and local scratch projects.
The git clone command copies an existing remote repository to your local machine, creating a complete working copy with the full commit history. The clone operation creates a new directory, initializes it as a Git repository, sets up remote tracking branches, and checks out the default branch. When you specify a directory name as the second argument, Git uses that name instead of deriving it from the repository URL. The depth flag enables shallow cloning, which downloads only the most recent commits rather than the full history, saving time and disk space for very large repositories. The branch flag lets you clone a specific branch instead of the default one.
The git config command sets configuration options at the global, repository, or system level. The most essential configurations are your name and email address, which Git includes in every commit you make. Setting the default branch name, preferred editor, and pull behavior are common customizations that improve your workflow. Configuration set at the repository level takes precedence over global settings, which in turn override system settings. Understanding these scopes helps you manage different identities or preferences across personal, work, and open-source projects.
Staging Changes
The git status command shows the current state of your working directory and staging area, including which files have been modified, which changes are staged for the next commit, and which files are untracked. This command should be your first reflex before any other Git operation because it tells you exactly what is happening in your repository at any moment. The short flag provides a compact output format, and the branch flag shows which branch you are on and how it relates to the remote branch. Running git status frequently prevents surprises and ensures you know exactly what changes will be included in your next commit.
The git add command moves changes from your working directory to the staging area, which prepares them for inclusion in the next commit. You can add individual files by path, add all changes in the current directory with a dot, or add changes interactively using the patch flag to review and select individual hunks of changes. Staging gives you precise control over what goes into each commit, allowing you to group related changes and exclude unrelated modifications. A disciplined staging practice leads to cleaner commit history and makes code reviews more focused and effective.
The git diff command shows the differences between various states in your repository. Without any flags, it compares your working directory against the staging area, showing changes that are not yet staged. The staged flag compares the staging area against the most recent commit, showing what will be included in the next commit. You can also diff between any two commits, branches, or tags by specifying them as arguments. Understanding the different comparison targets helps you review changes precisely at each stage of your workflow.
Committing Changes
The git commit command saves a snapshot of your staged changes along with a descriptive message. Each commit creates a permanent record in your repository history with a unique identifier, author information, timestamp, and the set of changes it represents. The message flag lets you write a short commit message directly on the command line, which is useful for small commits. The amend flag modifies the most recent commit by adding newly staged changes or updating the commit message, which is helpful for fixing typos or adding forgotten files without creating an additional commit.
Writing good commit messages is a skill that improves code review efficiency and makes repository history genuinely useful. A well-crafted commit message explains what changed and why, uses the imperative mood, and keeps the first line under fifty characters as a summary. Detailed body text after a blank line provides additional context about the motivation for the change, the approach taken, and any implications for related systems. Teams that enforce commit message conventions benefit from searchable history, automated changelog generation, and easier bisecting when debugging regressions.
The git stash command temporarily shelves changes that are not ready to be committed, allowing you to switch branches or pull updates without losing your work in progress. Stashed changes are saved as a stack of entries that you can list, inspect, and reapply later. The include-untracked flag also stashes files that have not been added to the repository yet, which is useful when you need a completely clean working directory. The pop flag reapplies the most recent stash and removes it from the stack, while the apply flag reapplies it while keeping it saved.
Branching Strategies
The git branch command creates, lists, or deletes branches. Without any flags, it lists all local branches and marks the current branch. The create flag with a name creates a new branch pointing to the current commit. The delete flag removes a branch that has been fully merged. The uppercase D flag force-deletes a branch even if it has not been merged, which is useful for cleaning up abandoned feature branches. Branching is one of Git's most powerful features, enabling parallel development workflows where multiple developers work on different features simultaneously without interfering with each other.
The git checkout command switches your working directory to a different branch or commit. When switching branches, Git updates your working directory to match the target branch and moves the HEAD reference. The lowercase b flag creates a new branch and switches to it in one operation, which is the most common way to start working on a new feature. The detach flag checks out a specific commit without being on any branch, which is useful for inspecting historical states but requires care because commits made in this state can be easily lost.
The git switch command is the modern, purpose-built alternative to git checkout for branch operations. It was introduced to reduce the cognitive load of using checkout for both branch switching and file restoration, which were conceptually different operations sharing the same command. The create flag with git switch creates and switches to a new branch. The detach flag checks out a specific commit. This command is recommended over git checkout for branch operations because its intent is explicit and it reduces the chance of accidental file modifications.
Merging and Integrating Changes
The git merge command combines changes from one branch into your current branch. Git performs a three-way merge, using the common ancestor of the two branches to determine how to integrate the changes. When the branches have not modified the same lines, Git resolves the merge automatically. When conflicting changes exist in the same file, Git marks the conflicts and requires you to resolve them manually before completing the merge. The no-ff flag forces Git to create a merge commit even when a fast-forward merge is possible, which preserves branch history and makes it easier to understand when a feature was integrated.
The git rebase command reapplies your branch's commits on top of another branch, creating a linear history instead of a merge commit. This results in a cleaner project history that is easier to read and bisect. The interactive flag opens an editor where you can reorder, squash, edit, or drop individual commits before applying them, giving you fine-grained control over your branch history. However, rebasing rewrites commit history, which means you should never rebase commits that have been pushed to a shared remote branch, as this will cause confusion for other developers.
Merge conflicts occur when two branches modify the same lines of a file and Git cannot automatically determine which changes should take precedence. Git marks conflicting sections in the affected files with special markers showing the content from each branch. Resolving conflicts requires you to edit the file, choosing which changes to keep, combining elements from both branches, or rewriting the conflicting section entirely. After resolving all conflicts, you stage the resolved files and complete the merge. Regularly pulling and merging changes from the main branch into your feature branch reduces the frequency and severity of merge conflicts.
Working with Remote Repositories
The git remote command manages the connections between your local repository and remote repositories. The add flag creates a new remote connection with a name and URL. The verbose flag shows detailed information about each remote, including the fetch and push URLs. The rename flag changes a remote's name, and the remove flag deletes a remote connection. The most common remote name is origin, which Git sets up automatically when you clone a repository. Teams often add a second remote called upstream for tracking the canonical source of a forked repository.
The git fetch command downloads objects and references from a remote repository without merging them into your local branches. This updates your remote tracking branches, which represent the state of the remote repository, without changing your working directory. Fetching first before pulling or merging is a good practice because it lets you see what changes are available before integrating them. The prune flag removes references to remote branches that no longer exist on the remote, keeping your local view clean.
The git pull command combines fetching from a remote with merging or rebasing the fetched changes into your current branch. The rebase flag uses rebasing instead of merging to integrate the changes, which keeps history linear. Pulling regularly from the shared branch reduces the divergence between your local branch and the remote, minimizing merge conflicts and ensuring your work stays compatible with the latest changes from your team.
The git push command uploads your local branch commits to a remote repository, updating the remote branch to match your local one. The upstream flag sets the remote branch that your local branch tracks, so subsequent pushes and pulls know which remote branch to synchronize with. The force flag overwrites the remote branch with your local version, which is necessary after rebasing or amending commits that have been pushed. However, force pushing to shared branches should be avoided because it rewrites history for other developers.
Undoing Changes and Fixing Mistakes
The git reset command moves your current branch pointer and optionally resets the staging area and working directory. The soft flag moves the branch pointer without changing the staging area, effectively unstaging commits while keeping their changes staged. The mixed flag, which is the default, moves the branch pointer and resets the staging area but preserves working directory changes. The hard flag resets everything, moving the branch pointer, clearing the staging area, and discarding working directory changes. Understanding the differences between these modes is crucial for safely undoing mistakes.
The git revert command creates a new commit that undoes the changes introduced by a previous commit, preserving the original commit history. This is the safe way to undo published changes because it does not rewrite history. You can revert a single commit or a range of commits. When reverting a merge commit, special flags are needed to specify which parent branch should be considered the main line. Revert is preferred over reset for undoing changes that have been pushed to shared repositories because it maintains a clean, understandable history.
The git restore command is the modern, dedicated tool for undoing changes to files in your working directory and staging area. The staged flag restores the staging area to match the most recent commit, effectively unstaging files. Without flags, it restores files in the working directory to match the staging area. The source flag allows you to restore files to match any commit. This command replaces the confusing use of git checkout for file restoration and makes the intent of undoing changes explicit.
Inspecting History and Changes
The git log command displays the commit history of your repository, showing each commit's hash, author, date, and message. The oneline flag condenses each commit to a single line, which is useful for getting a quick overview. The graph flag adds an ASCII art representation of the branch structure, making it easy to visualize how branches diverge and merge. Thestat flag shows which files changed and how many lines were added or removed in each commit. The author and since flags let you filter the log to specific contributors or time ranges.
The git show command displays detailed information about a specific Git object, including commits, tags, and blobs. When given a commit hash, it shows the commit metadata and the diff introduced by that commit. When given a tag, it shows the tag message and the commit it references. This command is particularly useful for reviewing the exact changes in a specific commit, understanding what a colleague changed in their latest merge, or inspecting the contents of a blob at a particular point in history.
The git bisect command performs a binary search through your commit history to identify the commit that introduced a bug. You start by marking a known good commit and a known bad commit, then Git checks out the midpoint commit and you test whether the bug is present. Based on your response, Git narrows the search range by half and repeats the process until the offending commit is identified. This automated binary search can dramatically reduce the time it takes to find regression bugs, especially in repositories with long commit histories.
Collaboration Patterns and Best Practices
Pull requests are the standard mechanism for proposing changes to shared repositories. While pull requests are a feature of hosting platforms like GitHub and GitLab rather than Git itself, the Git commands discussed throughout this article form the foundation of every pull request workflow. A typical pull request involves creating a feature branch, pushing it to the remote, opening the request on the platform, responding to code review feedback with additional commits, and merging the approved changes. Keeping feature branches short-lived, focused on a single concern, and regularly rebased against the main branch ensures smooth pull request experiences.
Git hooks are scripts that execute automatically at specific points in the Git workflow, such as before a commit, after a commit, or before pushing. Pre-commit hooks are commonly used to run linting, format checking, and unit tests, preventing problematic changes from entering the repository. Pre-push hooks can run more comprehensive test suites or security scans. Commit message hooks enforce naming conventions. Installing hooks through tools like Husky makes it easy to share hook configuration across a team, ensuring consistent code quality standards.
Cherry-picking with the git cherry-pick command applies changes from specific commits onto your current branch. This is useful when you need to bring a bug fix from one branch to another without merging the entire branch. You can cherry-pick a single commit or a range of commits. However, cherry-picking creates new commits with different hashes, which can cause confusion if the same change exists in multiple branches and one gets merged before the other. Cherry-picking should be used judiciously and documented clearly.
For developers working on projects deployed through CI/CD pipelines, maintaining a clean Git history is especially important because many pipelines trigger on specific branch patterns or commit messages. Understanding these commands and applying them consistently ensures that your commits trigger the correct pipeline stages, that deployments are traceable to specific code changes, and that rollback procedures work correctly. When combined with modern deployment platforms like Deployxa Cloud v4.2.0, a disciplined Git workflow becomes the foundation of a reliable and efficient software delivery process that scales from individual developers to large teams.