Git Cheatsheet

–local-branching-on-the-cheap

Photo by Praveen Thirumurugan on Unsplash
Table of Contents

In today’s collaborative development world (as of 2024), version control is crucial for managing code effectively. Git, a distributed version control system (DVCS), has become the industry standard for developers of all backgrounds.

Git Configuration

The initial setup of Git involves configuring your user information and some helpful settings.

Command Description
git config --global user.name "[Your Name]" Sets the name associated with your commits and tags. Replace [Your Name] with your actual first and last name.
git config --global user.email "[your-valid-email@example.com]" Sets the email address associated with your commits and tags. Replace [your-valid-email@example.com] with your actual email address.
git config --global color.ui auto Enables automatic colorization of Git’s command-line output for better readability.

Starting a Project / INIT

Git provides two primary ways to begin working with a project: creating a new local repository or cloning an existing one.

Command Description
git init [project name] (optional) Initializes a new Git repository in the current directory. If you provide a [project name], Git will create a new directory with that name and initialize a repository inside it.
git clone <project URL> Downloads a complete project, including its entire history, from a remote repository specified by the <project URL>.

Day-to-Day Work / Stage & Snapshot

Essential Git commands for your daily workflow:

Command Description
git status Displays the current state of your working directory, including new, modified, and staged files. It also shows the current branch name, commit identifier, and any changes awaiting commit.
git add [file] Adds a specific file to the staging area, which prepares it for the next commit. Use . (dot) to add all changed files from the current directory and its subdirectories.
git diff [file] (optional) Shows the differences between the working directory (your uncommitted changes) and the staging area, allowing you to review modifications before committing.
git diff --staged [file] (optional) Reveals changes between the staging area (files prepared for commit) and the last committed snapshot, helping you verify staged modifications.
git checkout -- [file] (Use with caution! ) Discards all changes made to a specific file in the working directory. This action cannot be undone!
git reset [<path>] Reverts changes in the working directory or staging area to match the specified path or the latest commit (HEAD). Use cautiously, as it can lose unsaved work.
git commit -m "[descriptive message]" Creates a new commit snapshot, capturing the current state of the staged files. Include a clear and concise message describing the changes made.
git rm [file] Removes a file from both the working directory and the staging area, effectively deleting it from your project.

Git Stash Commands

Command Description
git stash Temporarily saves the current state of your working directory (uncommitted changes and staged files) for later use. This creates a “stash” entry, essentially a snapshot of your current work.
git stash list Lists all your stashed changes in reverse chronological order (most recent stash at the top). This helps you identify and manage specific stashed modifications.
git stash pop Applies the changes from the most recent stash (top of the stash list) to your working directory. This effectively “un-stashes” your work, incorporating the previously saved changes. The stash itself is removed after a successful pop.
git stash drop Permanently removes a specific stash entry from the stash list. Use the output from git stash list to identify the stash you want to delete (e.g., git stash drop stash@{0} to delete the most recent stash). Use with caution! Once dropped, a stash cannot be recovered.

Git Branching Model / Branch & Merge / Rewrite History

Effective branching strategies are essential for managing code development in Git. Here’s a breakdown of key Git commands for branching, merging, and history manipulation:

Command Description
git branch [-a] Lists all local branches in your repository. Use the -a flag to see both local and remote branches.
git branch [branch_name] Creates a new branch named [branch_name] that starts from the current HEAD commit.
git rebase [branch] (Use with caution! ) Rebases the current branch on top of the specified [branch]. This replays your commits on top of the [branch] history, potentially rewriting history and making it difficult for collaboration. Consider using git merge for collaborative workflows.
git checkout [-b] [branch_name] Switches your working directory to the specified [branch_name]. Use the -b flag to create a new branch named [branch_name] if it doesn’t exist yet.
git merge [branch_name] Merges the changes from the specified [branch_name] into the current branch, combining their histories. This is generally preferred over git rebase for collaborative development.
git branch -d [branch_name] Deletes the specified [branch_name], but only if it has already been merged into another branch. Use the -D flag (use with caution!) to force deletion even if unmerged, but be aware this can cause issues in collaborative workflows.
Additional Commands:
git branch Lists all local branches, indicating the currently active branch with an asterisk (*).
git checkout [branch] Switches to the specified [branch] and checks it out into your working directory.
git reset --hard [commit] (Use with extreme caution! ) Discards all uncommitted changes in your working directory and resets it to the state of the specified commit. This action cannot be undone!

Notes:

  • Use git branch regularly to keep track of your branches.
  • Favor git merge over git rebase in collaborative development to avoid rewriting history and potential conflicts.
  • Be cautious with git reset --hard and git branch -D as they can lead to data loss.
  • Consider using a visual Git client to get a better understanding of branch relationships.

Inspect History / Inspect & Compare

Understanding your project’s history is crucial in Git. Here’s a table outlining essential commands for inspecting commits, comparing branches, and viewing Git objects:

Command Description
git log Lists the commit history of your current branch, starting from the most recent commit and working backwards.
git log [-n count] Shows a limited view of the commit history, displaying only the most recent n commits.
git log --oneline --graph --decorate Provides a concise overview of the commit history with a visual graph, reference labels, and decorations (e.g., author names, commit messages). Each commit is displayed on a single line.
git log ref^.. Lists commits that exist on your current branch (ref) but haven’t been merged into the specified reference (ref). This reference can be a branch name or a tag name.
git log --first-parent origin/master..HEAD (Advanced: Use with caution!) Shows commits specific to your current branch (HEAD) that are not present in the origin/master branch’s linear history (excluding merges). This is useful for identifying your local changes on top of the remote master branch.
git reflog Displays a history of operations (like checkouts and commits) performed on your local repository.
git log branchB..branchA Reveals the commits that are present on branch branchA but not on branch branchB. This helps you understand what changes exist in branchA that are not yet included in branchB.
git log --follow [file] Tracks the history of a specific file named [file], even if it has been renamed during development. This allows you to see all commits that modified the file throughout its lifetime.
git diff branchB...branchA Shows the difference between branches branchB and branchA. This essentially reveals what changes are present in branchA compared to branchB.
git show [SHA] Displays any Git object (e.g., a commit, a blob, or a tree) in a human-readable format, given its SHA-1 hash ([SHA]).

Notes:

  • Use git log variations to explore your commit history at different levels of detail.
  • git reflog can be helpful for tracking your actions in the repository.
  • Commands like git log branchB..branchA and git diff branchB...branchA are valuable for comparing branches.
  • git show allows you to examine specific Git objects by their unique identifier.

Reverting Changes

Git provides two primary ways to undo changes in your project: git reset and git revert. Here’s a table explaining these commands:

Command Description
git reset [--hard] [target reference] Moves the current branch pointer (HEAD) to the specified target reference (e.g., a commit SHA or branch name). This essentially undoes changes by rewinding your working directory and staging area to match the target state.
* Without --hard (default): Changes made since the target reference become uncommitted changes in your working directory. However, be cautious as these changes can be easily lost.
* With --hard (Use with extreme caution!): Discards all uncommitted changes in your working directory and staging area, completely resetting them to the state of the target reference. This action cannot be undone!
git revert [commit SHA] Creates a new commit that effectively reverses the changes introduced in the specified commit identified by its SHA. This is generally a safer option than git reset as it creates a new commit to track the reversal, allowing you to revert the revert if needed.

Notes:

  • Use git reset cautiously, especially with the --hard flag, as it can lead to permanent data loss.
  • Consider git revert as a safer alternative for undoing changes as it creates a new commit for tracking.
  • Before using either command, it’s highly recommended to back up your work or use a stash (covered in a previous section) to preserve uncommitted changes if needed.

Tagging Commits

Tags are a powerful way to mark specific points in your Git history for easy reference.

Command Description
git tag Lists all existing tags associated with your Git repository.
git tag [name] [commit SHA] Creates a new tag named [name] that points to the current HEAD commit (the latest commit in your current branch). You can optionally specify a specific commit SHA to tag instead of the current one.
git tag -a [name] [commit SHA] (Advanced: Use with caution!) Creates an annotated tag named [name] for the specified commit (either the current HEAD or a specific SHA). Annotated tags store additional information like a tag message, which can be helpful for documentation purposes. However, annotated tags can be larger than lightweight tags (created by git tag without -a). Consider using lightweight tags for simplicity in most cases.
git tag -d [name] Removes the specified tag named [name] from your local repository.

Notes:

  • Use clear and descriptive names for your tags to enhance readability.
  • Lightweight tags (created with git tag) are generally preferred due to their smaller size.
  • Annotated tags (created with git tag -a) can be useful for storing additional information, but use them judiciously when size is a concern.

Synchronizing Repositories / Share & Update

Collaboration and keeping your project code in sync are essential aspects of Git.

Command Description
git fetch [remote] Retrieves changes from the remote repository specified by [remote] (e.g., origin) but doesn’t automatically integrate them into your local branch. This is useful when you want to see what changes exist on the remote without merging them yet.
git fetch --prune [remote] Fetches changes from the remote repository and additionally removes any local references (refs) to branches that have been deleted on the remote. This helps keep your local repository clean.
git pull [remote] Combines git fetch and git merge in one step. It downloads changes from the remote repository and attempts to merge them into your current branch. This is a convenient way to stay up-to-date with the remote’s latest changes.
git push [--tags] [remote] Pushes your local commits to the remote repository specified by [remote]. Use the --tags flag to include tags along with your commits.
git push -u [remote] [branch] Pushes your local branch named [branch] to the remote repository and sets the corresponding remote branch as an “upstream” branch. This simplifies future pushes as you won’t need to specify the remote branch name explicitly.
git remote add [alias] [url] Adds a new remote repository identified by its URL [url] and assigns a short alias name [alias] for easier reference.
git fetch [alias] Fetches changes from the remote repository associated with the specified alias [alias].
git merge [alias]/[branch] Merges the remote branch named [branch] from the remote repository identified by [alias] into your current local branch. This allows you to incorporate changes from a specific remote branch.
git push [alias] [branch] Pushes your local branch named [branch] to the remote branch named [branch] on the remote repository identified by [alias].

Notes:

  • Use git fetch when you want to be aware of remote changes without merging them immediately.
  • git pull is a convenient way to fetch and merge in one step, but be prepared to handle potential merge conflicts.
  • Use git push to share your local commits with the remote repository.
  • Manage remote repositories with aliases for easier handling using git remote add.
  • Consider using a visual Git client to simplify branch management and visualization.

Git Repository Maintenance

Regular maintenance of your Git repository is essential for optimal performance and organization.

Command Description
git gc Cleans up unnecessary files and optimizes the local repository’s database. This command is useful for reducing disk usage and improving Git’s performance.
git fsck Verifies the integrity of your repository’s objects and references, checking for any corruption or inconsistencies. This is helpful for ensuring the reliability of your Git data.
git prune Removes unreachable objects (e.g., commits, blobs) from your repository, freeing up disk space and keeping your repository clean.
git reflog expire --expire=now --all Expires all reflog entries immediately, removing any outdated or unnecessary references. This helps maintain a clean and efficient repository.
git clean -dnx | sed 's/Would remove //;s/Would skip repository //' Lists untracked files in your working directory that are not ignored by your .gitignore file. This command is useful for identifying files that may need to be removed or added to the ignore list. (remove x to hide ignored files)

Link to my presentation/talk about Git …not just version control

George Litos
George Litos
Senior Software Engineer