skip to content

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.

Log

To view a history of all the commits, use the log command.

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 main branch.

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 --abort flag.

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

Interactive Rebase

The rebase command’s -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

The 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

The --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!

Commit

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

Git’s 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?

The 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.

Reset

To reset your head back to a particular commit:

git reset --hard commit_hash

Cherry Pick

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: recursive, octopus, ours, and resolve.

Recursive

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

The 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

Ours

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

The 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.

Conclusion

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!