Uncommon Git Commands
I like to use the git CLI. I have tried UIs like GitKraken, Fork or GitHub Desktop. I don’t like them.
The majority of commands can be remembered after a short amount of time because you use them daily. However, there are some commands you only need here and there, which makes them really difficult to memorize. Every time I need them, I haven’t used them for so long that I forget which option it was. Then I have to look them up again, feeling frustrated and uncool for not knowing Git by heart. It’s embarrassing.
So I decided to write this little post, which doesn’t help memorizing them, but I’ll always know where I can look them up quickly 😅
When contributing to open source, it is common that you want to checkout a branch of the upstream branch, that doesn’t exist in your remote fork yet. Neither does it exist in your local repository. Now when it comes to checking out a remote branch on a local repository, git switch is your friend. Just remember to fetch the upstream, so git knows the reference you want to track. However, what if the branch is not in your remote repository - your fork.
I usually have set up the original remote repository as the upstream repo locally, which can be done with:
git remote add upstream https://github.com/<org>/<repo>With this information, git can then fetch the upstream:
git fetch upstreamAnd now comes the magic: Create and checkout a branch, that until then only exists in the original remote repo with:
git checkout -b <branch> upstream/<branch>I know that it is pretty annoying that you have to specify the branch name two times, but in theory you could name the local branch differently.
Also don’t forget that this branch does not yet exist in your remote fork, but you can push it easily with:
git push -u origin <branch>Renaming commits is not recommended when the commit is already pushed to the remote as you are changing the commit history for everyone.
If you want to rename the last commit, just use:
git commit --amendWhen you already have multiple local commits, you have to start an interactive rebase with:
git rebase -i HEAD~3Here, 3 is the number of commits you want to adapt. If your commit is back 10 commits, you need to put a 10 there instead.
Git will open your favourite editor with some text like:
pick 64e085f Commit Message 1pick e5f607a Commit Message 2pick a9b0c1d Commit Message 3You can now edit this text like a normal file and replace all the pick keywords where you want to change the commit message with reword. After you save and close the file, git will repeatedly open text files with the old commit message, which you can freely edit to your likings. After you adapted everything you wanted and close the last file, the rebase is finished and you can check your corrections with:
git log --onelineInteractive rebasing is incredibly useful, as other options like squash, break or even exec are available. Just keep in mind that it makes more sense to do this on a branch where only you work to avoid team friction.
When a PR is merged, the branch is usually deleted after it is safely merged into the default branch. But the branch still exists locally. If you want to delete all the local branches, which got deleted in your remote repository, you can run this command in most shells (use wsl on Windows):
git fetch -p && git branch -vv | awk '/: gone] / {print $1}' | grep -v '^\*$' | xargs -I{} git branch -d "{}"This is a destructive action. Therefore I included a safeguard by using the lowercase -d parameter. If your branches are not cleanly merged, git will not delete them. If you are sure you want to delete all those branches no matter what, use -D instead.
🛰️ Track Upstream Branch
git fetch upstream && git checkout -b <branch> upstream/<branch>Fetches the latest references from the original repository and creates a local branch that tracks the upstream version in one logical flow.
🔄 Rename Older Commits
git rebase -i HEAD~nUse this to rewrite history. In the interactive editor, change
picktorewordfor any of the lastncommits you want to modify.
🧹 Prune Local Branches
git fetch -p && git branch -vv | awk '/: gone] / {print $1}' | grep -v '^\*$' | xargs -I{} git branch -d "{}"A pipeline that identifies local branches whose remote counterparts have been deleted (“gone”) and attempts to delete them safely.
Here are some helpful resources for learning git and other situations you often find yourself in:
That’s it for now, more useful uncommon git commands might be added in the future!