Git Commands & Concepts – Demystified (part 3)

Being overwhelmed by Git's commands & concepts is unfortunately not too uncommon. This final post in the small series, aimed at making your life with Git more durable, focuses on branch manipulation!

Git Commands & Concepts – Demystified (part 3)
Photo by Luke Richardson / Unsplash

In this final post in the short series demystifying common commands and concepts with Git, we'll look at some fundamental actions used to manipulate branches and integrate changes.

In the previous posts we've already gone through the overall components of Git, so the illustrations used in this one shouldn't be new to you. However, if you still find them confusing I suggest recapping the first and second post on the subject before continuing with this one.

Integrating changes

There are a few ways to integrate code changes between branches, where merge and rebase are the two most common operations. Below is a slightly more extended list of commands used for integration work.

  • Fetch: Updates remote references in your cloned local repository. E.g. if a developer has pushed changes to a remote branch, those changes will be pulled down to your repository whenever fetch is performed. Note: fetch won't automatically merge any changes, only update references.
  • Pull: Similar to fetch with the difference that it not only fetches updates from remote, but also tries to merge any changes straight away in the branch you're pulling into. In a way, pull is fetch + merge.
Side by side illustration of fetch vs pull. Prior to each command (in the bottom boxes) history looks the same for the two developers, where both are missing the C2 commit present on remote. For Teammate 1, fetch only updates the remote reference "o/master"; whereas for Teammate 2, pull updates the reference and merges the change straight into the local counterpart: "master".
  • Merge: Joins two or more development histories together, preserving history as it happened. This is the most basic way of integrating changes between branches.
  • Rebase: Reapplies commits on top of another base branch, essentially rewriting history. This is a more dynamic way of integrating changes but also comes with some minor gotchas.
Side by side illustration of the resulting end states of merge vs rebase; start case on the far left.
If you'd like a deep dive on the subject about how merge and rebase differ, take a look at this post I wrote for BetterProgramming earlier.
  • Cherry-pick: Applies changes introduced by existing commits on top of HEAD. Generally cherry-picking is used to pick one (or several commits) made in one branch and reapply them in another, creating new commits in the target branch without modifying the original branch.

Branch manipulation

In Git, branching comes cheap and it's one of its main features. Knowing how to manipulate them and move in between branches is a must for anyone using Git. Below are some fundamental commands worth knowing by heart (at least their scope of use, so you know which command to look for).

  • Switch: Checks out the specified branch by moving HEAD to it, ultimately mirroring the content of the underlying commit into your Working Tree. When switch is used together with its --detached flag it checks out the underlying commit in detached state. Prior to v2.23 of Git, checkout was used exclusively for these operations.
Still not 100% sure what detached state implies? Spend a couple of minutes brushing up on the matter with this post: What is HEAD in Git? – It will for sure do you good!
  • Checkout: Checks out a particular version of one or multiple files from history into your Working Tree. When an entire branch is checked out, it works the same way as switch.
  • Reset: If commit moves history forward by adding a new commit to the end of HEAD, reset does the opposite. It can be used in a multitude of ways but in its most basic usage it simply moves a branch to an earlier commit in history (generally back in time).
  • Revert: Undoes an earlier commit by "rolling forward" and creates a new commit, on top of HEAD, containing the reversed changes from the specific commit.
Feel overwhelmed by the different options of undoing changes? Sit tight! I've got another post in the making, explaining the difference between reset, revert, and restore, including what to use when.

Conclusion

This was the final post in the short series Git Commands & Concepts – Demystified! You should now be aware of the most fundamental parts of Git, so that you can easily follow along in the online lingo whenever you're looking for more detailed answers!

📖 Tip: Bookmark these posts and use them as your basic Git glossary!

Thanks for reading, and good luck improving you SCM skills! 🦸‍♀️