Post

Complete Guide to Git Commands: A Journey from Basics to Poficiency

Git is an indispensable decentralized version control tool in software development. Whether you’re a novice or an experienced developer, mastering Git is essential for effective code management. In this article, we’ll explore essential, advanced, and highly advanced Git commands to help you become an expert in version control.

Defining Git

Git is a version control system that tracks changes to files and allows collaboration with other developers. It records changes in a repository, enabling you to revert to a previous version if necessary, work on multiple features in parallel, and merge changes without losing data.

Installing Git

Before you start, make sure Git is installed on your machine. You can download and install Git from the official site: Git Downloads.

Configuring Git

After installation, configure your username and email. This information will be used to identify the author of commits.

1
2
3
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

Basic Git Commands

Initializing a Git Repository

To start using Git, you need to initialize a repository in your project directory.

1
2
git init

Cloning an Existing Repository

If you’re working on an existing project, you can clone a remote repository.

1
2
git clone https://github.com/user/project.git

Adding Files to the Repository

To track changes to a file, you need to add it to your index (or “staging area”).

1
git add filename

To add all modified files, use:

1
2
git add .

Committing Changes

Once the files are added, you can commit your changes with a descriptive message.

1
2
git commit -m "Commit message"

Checking the Repository Status

The git status command displays modified, added, and untracked files.

1
2
git status

Viewing Commit History

To see the commit history, use:

1
2
git log

For a more concise history, use:

1
2
git log --oneline

Branch Management

Branches allow you to work on different versions of your project simultaneously. To create and switch to a new branch, use:

1
2
git checkout -b new_branch

To switch between existing branches:

1
2
git checkout branch_name

Merging Branches

When you’re finished working on a branch and want to integrate the changes into your main branch, use:

1
2
git merge branch_name

Pushing and Pulling Changes To share your changes with a remote repository, use:

1
2
git push origin branch_name

To fetch changes from a remote repository:

1
2
git pull

Advanced Git Commands

Rebasing a Branch

Rebasing is an alternative to merging that allows you to rewrite commit history. It’s often used to maintain a clean commit history.

1
2
git rebase target_branch

To perform an interactive rebase and modify commit history:

1
2
git rebase -i HEAD~n

Stashing

The git stash command temporarily saves your work so you can return to a clean working directory.

1
2
git stash

To apply stashed changes:

1
2
git stash apply

Or to apply and remove the stash:

1
2
git stash pop

Blame

The git blame command displays line-by-line information about who modified each line and when.

1
2
git blame filename

Revert

To create a commit that undoes the changes of a specific commit:

1
2
git revert commit_id

Reset

The git reset command can be used to undo commits or changes. It has three main options:

–soft: Resets the index only, keeping changes in the staging area.

1
2
git reset --soft HEAD~1

–mixed (default): Resets the index and staging area, keeping changes in the working directory.

1
2
git reset HEAD~1

–hard: Resets the index, staging area, and working directory, discarding all changes.

1
2
git reset --hard HEAD~1

Cherry-pick

To apply a specific commit from one branch to another:

1
2
git cherry-pick commit_id

Diff

The git diff command shows differences between commits, branches, files, etc.

To see differences between your working directory and the index:

1
2
git diff

To see differences between the index and the last commit:

1
2
git diff --cached

Tagging

Tags are used to mark specific points in your project’s history, often for versions.

To create an annotated tag:

1
2
git tag -a v1.0 -m "Version 1.0"

To push tags to a remote repository:

1
2
git push origin --tags

Submodules

Submodules allow you to include other Git repositories in your repository.

To add a submodule:

1
2
git submodule add https://github.com/user/repo.git submodule_path

To initialize and update submodules:

1
2
3
git submodule init
git submodule update

Hooks

Git hooks allow you to execute custom scripts at different points in the Git workflow (commits, push, etc.).

Hooks are located in the .git/hooks directory. For example, to execute a script before each commit, modify the pre-commit.sample file and rename it to pre-commit.

1
2
3
4
5
6
7
8
9
# Navigate to the .git/hooks directory of your Git repository
cd path/to/your/repo/.git/hooks

# Create the pre-commit hook
touch pre-commit

# Edit the pre-commit file (you can use any text editor; here we use nano for example)
nano pre-commit

Bisect

The git bisect command helps identify which commit introduced a bug using binary search.

To start bisecting:

1
2
git bisect start

Mark the current commit as bad:

1
2
git bisect bad

Mark a known good commit:

1
2
git bisect good commit_id

Git will guide you to test intermediate commits until the faulty commit is identified.

Reflog

Reflog records changes to the HEAD state and can be used to recover lost commits.

To display the reflog:

1
2
git reflog

Advanced Interactive Rebase

Interactive rebase can be used not only to rewrite commit history but also to clean up and organize your commits before merging.

1
2
git rebase -i HEAD~n

During interactive rebase, you can:

-pick: Use the commit.

-reword: Edit the commit message.

-edit: Edit the commit itself.

-squash: Combine this commit with the previous one.

-fixup: Combine this commit with the previous one, discarding the commit message.

-exec: Execute a shell command.

Git Filter-Branch and BFG Repo-Cleaner

Git Filter-Branch

The git filter-branch command allows you to rewrite the entire repository history. It is often used for tasks such as globally changing author email addresses or removing sensitive files from history.

1
2
3
4
5
6
7
8
git filter-branch --env-filter '
if [ "$GIT_COMMITTER_EMAIL" = "old-email@example.com" ]
then
    export GIT_COMMITTER_EMAIL="new-email@example.com"
    export GIT_AUTHOR_EMAIL="new-email@example.com"
fi
' -- --all

BFG Repo-Cleaner

BFG Repo-Cleaner is a faster and simpler tool for cleaning repositories. It is especially useful for removing large or sensitive files from history.

1
2
bfg --delete-files *.jar

Git Worktree

The git worktree command allows you to work on multiple branches simultaneously in separate working directories without cloning the repository multiple times.

To create a new worktree:

1
2
git worktree add ../new-directory branch_name

Git Archive

The git archive command creates a tar or zip archive of a repository snapshot. This is useful for distributing a specific version of your project without version control files.

1
2
git archive --format=tar HEAD | gzip > project.tar.gz

Git Bundle

The git bundle command creates a file containing a complete Git repository or part of it. This is useful for transferring a repository without direct network access.

To create a bundle:

1
2
git bundle create my_project.bundle --all

To clone from a bundle:

1
2
git clone my_project.bundle -b master my_project

Git Subtree

The git subtree command is used to manage nested repositories. Unlike submodules, subtrees do not require separate version management.

To add a repository as a subtree:

1
2
git subtree add --prefix=directory https://github.com/user/project.git branch

To extract a subtree:

1
2
git subtree split --prefix=directory -b new_branch

Git Notes

The git notes command allows you to add annotations to commits without modifying their content.

To add a note to a commit:

1
2
git notes add -m "Note about the commit" commit_id

To display notes:

1
2
git log --show-notes

Git FSCK (File System Consistency Check)

The git fsck command checks the integrity and connectivity of the objects in a Git repository.

1
2
3
git fsck
Git Grafts

Grafts temporarily rewrite history for operations such as repository recombination. Grafts are defined in the .git/info/grafts file.

To create a graft, add a line in the file:

1
new_parent commit_id

Git Replace

The git replace command allows you to replace one object with another without modifying history.

To replace a commit with another:

1
2
git replace old_commit new_commit

Git Sparse Checkout

The git sparse-checkout command allows you to check out only part of the repository, which is useful for large repositories with many files.

To configure a sparse checkout:

1
2
3
git sparse-checkout init --cone
git sparse-checkout set path/to/directory

Conclusion

These Git commands cover everything you need to know to manage and manipulate your repositories flexibly and precisely. By understanding and using these commands, you can significantly improve your workflow and resolve complex issues more easily. Continue exploring and experimenting with Git to become a version control expert.

This post is licensed under CC BY 4.0 by the author.