git for beginners
/ 8 min read
Learn the basic of git - distributed version control system
Mastering the Git Command: A Primer
While scrolling through my Discord server the other day, I stumbled upon a question that had me thinking—why answer this query in isolation when I can share the wealth of knowledge with all? The question was about how to ‘force commit’ in Git. So, I decided to pen down this comprehensive guide about Git, hoping to help not just one, but many of you out there. Dear reader, this is for you!
What is Git?
Git is a free and open-source distributed version control system, designed to handle projects both small and grandiose with efficiency and ease. Originally developed by Linus Torvalds in 2005, Git has transformed the way developers collaborate. GitHub (among others), the cherry on top, is an online platform that utilizes Git for version control, making it easier for developers to collaborate on projects from anywhere around the globe.
Popular Git Commands
To view a history of all the commits, use the
git log --oneline --graph --decorate
Branch: More Than Just a Divergence
Branching is one of Git’s most powerful features, allowing you to work on different tasks, features, or bug-fixes without affecting the main code. Let’s unravel some commonly-used commands that bring this concept to life.
Creating a New Branch
To spawn a new branch from your current working branch, use the following command. This will not only create a new branch but also switch you over to it.
git checkout -b branch-name-goes-here
Checking Out an Existing Branch
Sometimes, you might need to switch to an already existing branch, maybe to review someone else’s code or to switch tasks. You can do so with:
git checkout branch-name
Checking Out the Previous Branch
Ah, the classic scenario—you switched branches but realize you need to go back to the previous one. No need to remember and type out the branch name, Git has a shorthand for this:
git checkout -
This command will take you back to the branch you were on before you made the last
git checkout command. It’s a nifty trick that saves you from unnecessary typing and potential misspellings.
Branching in Git is like a multi-lane highway where each lane (branch) serves a different purpose but is part of the same journey (project). Understanding these
checkout commands gives you the skill to navigate this highway efficiently.
Rebase: Rewriting Commit History, The Right Way
Rebasing is another one of Git’s powerful features for streamlining your project’s history. While merging takes the contents of a source branch and integrates them with the target branch, rebasing moves or combines the feature branch onto the base branch. Here’s how to wield the power of
rebase effectively through some commonly used commands.
Rebase Against Main Branch
The command below takes all the changes in your current branch and applies them on top of the changes in the
git rebase main
Abort a Rebase
Rebasing isn’t always smooth sailing. If you find yourself in a sticky situation during a rebase operation and want to revert to the state before you started the rebase, use the
git rebase --abort
Continue After Resolving Conflicts
During a rebase, you may encounter merge conflicts. After manually resolving those conflicts, use the
--continue flag to proceed with the rebase.
git rebase --continue
-i flag allows you to enter into an interactive rebase session. This enables you to edit, squash, reword, or even discard commits. Here,
HEAD~3 signifies that you want to interactively rebase the last three commits.
git rebase -i HEAD~3
Interactive rebase is your playground for cleaning up commit history, making it easier to understand and follow. You can squash multiple commits into a single, meaningful one, reword existing commit messages, or discard what you don’t need.
Rebase is more than just a simple Git command; it’s a powerful tool for curating your project’s history, making it logical, linear, and easier to comprehend.
Push: Taking Your Local Changes Global
push command is your express ticket from local development to the wider world. It uploads your changes to a remote repository, ensuring that what you’ve worked on is shared with your team or the public. Here’s how to make the most of
push with a few variations of the command.
Push the Current Branch to Remote
Want to push changes from your current local branch to a remote repository? The following command will do just that.
To update your remote repository with your local changes, use push.
git push origin main
If the remote reference doesn’t exist, it will automatically be created for you, example:
git push origin HEAD
Safely Force Push with Lease
Force pushing is often treated with caution, and for good reason—it has the potential to overwrite changes on the remote repository. However,
--force-with-lease is a safer option. This command forces the push but first ensures that no one else has pushed to the same branch in the meantime. This is particularly useful after operations like rebasing or amending commits, which rewrite history.
git push origin HEAD --force-with-lease
--force-with-lease flag provides an extra layer of safety, ensuring you don’t accidentally overwrite someone else’s work. It’s the courteous way of saying, “Step aside, I’ve got this, but if someone was here before me, I’ll wait.”
Understanding the different
push commands and their nuances is key to successful team collaboration and project management. This is your chance to share your coding genius with the world, so push responsibly!
For committing changes to the local repository, the
commit command is your go-to.
git commit -m "Your message here"
Stash: Your Git Workspace’s Safety Net
stash command is akin to a temporary storage area—a safety net, if you will—that lets you save changes without committing them. It’s immensely useful when you’re in the middle of a task and need to switch contexts. Let’s dive into some commonly used
stash commands to see how they can make your Git life easier.
Save Changes with a Message
You can stash your current changes—both staged and unstaged—with a descriptive message. This helps you remember the purpose of the stash for future reference.
git stash save "Your stash message here"
Stash with a Descriptive Name
In some cases, you might want to name your stash with something more descriptive than the automatically generated message that Git provides. You can do this by specifying the name while saving the stash.
git stash save stash-name-goes-here
Apply a Particular Stash
Stashes are stored in a stack, each with its index starting from 0. To apply a particular stash by its index, you can use the
apply command followed by the index number.
git stash apply n
For example, if you have multiple stashes and you want to apply the one at index 2, you’d use
git stash apply 2.
Why Use Stash?
stash command is particularly useful for:
- Quickly saving work to switch to another branch for a high-priority task.
- Experimenting with new code without committing, allowing for easy reverts.
- Safely storing partial changes before a risky operation like a hard reset.
Understanding and utilizing the
stash command can significantly improve your Git experience. It provides the flexibility to juggle multiple tasks efficiently and acts as a safeguard for your in-progress work.
To reset your head back to a particular commit:
git reset --hard commit_hash
For applying changes from a specific commit to your current working branch:
git cherry-pick commit_hash
Merge Strategies: A Deep Dive
When you’re about to merge branches in Git, the process may seem straightforward—just a simple
git merge command, right? Well, not so fast! Git offers you various merging strategies to ensure a seamless integration of code. Let’s delve deeper into some of the more common merge strategies:
This is the default strategy when you’re merging two branches. It’s designed to handle cases where the branches have diverged. If you’ve added some features in one branch and fixed a bug in another,
recursive will create a new commit combining both changes.
git merge -s recursive branch_to_merge
octopus strategy is useful when you want to merge more than two branches simultaneously. It works well when the branches being merged have no conflicting changes.
git merge -s octopus branch1 branch2 branch3
Sometimes you may want to discard changes from the branch you’re merging, and keep your current branch’s code as-is. The
ours strategy allows for that.
git merge -s ours branch_to_discard
resolve strategy uses a two-headed merge and will prompt you for manual conflict resolution if needed. It’s an older strategy and not as automated as
recursive, but in some cases, you may find it more appropriate.
git merge -s resolve branch_to_merge
Choosing the Right Strategy
So how do you choose the best merging strategy for your scenario? Consider the complexity of the branches, the type of changes, and whether you expect any conflicts. For routine merges where both branches have distinct, non-conflicting changes,
recursive is a good default. For multi-branch merges with no conflicts,
octopus is your friend. When you want to maintain the integrity of your current branch, go for
ours. And for two-headed merges requiring manual intervention,
resolve could be your best bet.
Understanding and selecting the right merge strategy can make your Git experience smoother and your codebase cleaner. After all, a well-merged codebase is often a well-maintained one.
Rebasing vs. Merging
Both are strategies for integrating changes from one branch into another, but rebasing provides a much cleaner project history.
Git is more than just a command-line tool; it’s a versatile system that brings order and collaboration to coding projects. Whether you’re working solo or as part of a team, mastering Git commands can significantly streamline your workflow.
So, the next time you’re tempted to bypass learning Git, remember this post and take a leap into the world of efficient code management!