3 Git Commands You Should NEVER Use
By: Marcus Quettan
Tags: Collaboration, Programming, Advice, Software Development, Git

Photo by Goh Rhy Yan on Unsplash

Git is a powerful tool. And, in my opinion, the only version control system software developers should be using in 2020. Perhaps there will be a new king in town one day. But in 2020, Git is the only solution worth investing your time with. Why? Because everyone uses it! Literally, everyone.

However, not everyone is an expert with git! These are three git commands that I believe you should NEVER use unless you truly understand what you’re doing!

Update 11/26/2020: This article got WAY more traction than I was expecting and there are a lot of comments with valid criticisms that are easier to address up front than individually. First, my appologies for the title and tone of the article. By “NEVER” I do not truly mean never. Although I am a fan of hyperbole, the idea I’m attempting to convey here is that these commands have the potential to increase complexity enough that it may be easier to just not use them and solve your problem more simply. For example — there are usually easier ways to handle pure dependencies than git submodule. Also, if you don’t have an overabundance of parallel active branches, I believe git merge to be generally easier to use and understand than git rebase. However, I recognize that I am biased because I work almost exclusively on relatively small projects which solve relatively pointed problems with smallish teams of 1–7 engineers. I’m not the guy developing the next Google (yet!). I’m the guy solving specific problems for each of our clients. If you work on larger teams with highly complex projects, git rebase and git submodule may be necessary to allow the history for your project or your sub-components to be reasonably navigable. If you are in this camp, hopefully an article written on a bit of a whim by a random person on the internet should not change your mind on whether or not using git rebase or git submodule is the correct answer. Let the official git documentation guide you. https://git-scm.com/doc

git submodule

Simply put, the git submodule command allows you to add a git repository into your git repository! However, managing a project where multiple submodules are used can be cumbersome.

git submodule add <repository location>

The above command adds the repository specified as a directory within your current git repository. This directory is itself a complete git repository. If you change directory into the new submodule you’ll notice that ALL of your git commands behave as if you just moved to a completely new repository. Because you have!

We’ll hereby reference the top-level repository as the “parent” repository and the submodule as the “child”. Within the parent repository, the directory which is the child submodule is treated more or less exactly how any other file within git would be treated. When the child repository is changed, you’ll see in the git status of the parent that the submodule has new commits or has modified content. Under the hood, from the perspective of the parent, a git submodule can be thought of as nothing more than a single file that contains a remote location and a commit id! The only way to update this file, and thus the parent’s reference to the submodule, is to track a different commit ID. Only when the most recent commit (aka the HEAD) of the child repository changes can the parent repository git add/git commit the updated submodule.

This intuitively means that if you are actively working within the child submodule, your workflow must also include managing the parent’s reference to the child. For instance, when you make a new commit in the child, you need to ALSO commit the parent’s reference to the child in order to keep the full project up to date. This can clearly become painful. Especially if you have many submodules or multiple levels of nested submodules. Each commit in any child repository equally requires updates to all references to that repository. This is why, in my opinion, submodules should only be used if the development team of the parent repository is different from the development team of the child. Submodules work well to keep track of references to external source code dependencies. However, I believe submodules do not work well to segment a single development team’s project into multiple sub-components. The resulting increase in complexity is not worth the additional effort required to maintain the parent/child relationship.

An additional note of interest: when using git submodules you must recognize that the parent repository will store no backup of the contents of the submodule. Only a reference. If you do not own the location which the submodule references, there is no guarantee that what you’re referencing will continue to exist at that location forever. If you do not own the remote location, I highly suggest creating your own remote location which is a clone of the original location as opposed to depending on a third party to maintain their repository at that exact location forever.