Some of my most visited Stack Overflow answers are on how to use Git!
We all remember how to add, commit, push, but how often to do you rebase, resolve merge conflicts, modify old commits?
Here I’m going to list out all the Git commands I usually look-up! Including any relevant updates, since Git and the way we use Git is always evolving!
Git config for a directory full of repositories
When you have sets of git repositories with different credentials it can be useful to manage shared git configuration across them.
Example directory layout:
code ├─ orgXYZ │ ├─ repoA | └─ repoB └─ org123 ├─ repo1 └─ repo2
Now, to set git config for “orgXYZ” I create a file in that directory named
.gitconfig and edit
[includeIf "gitdir:~/code/orgXYZ/"] path = ~/code/orgXYZ/.gitconfig
This instructs git to include directory-specific config that can be shared across multiple repos, in my case I often set a committer email address for each org.
Change committer name and email across multiple commits
One machine, multiple GitHub accounts, and whoops you commited as personX to orgY and you need to correct it!
There are a lot of approaches to this problem, this is the command I have used.
git filter-branch emits a warning that it shouldn’t be used.. 🤷♂️
⚠ This only works on repositories with a single committer, it overwrites ALL commits.
git filter-branch -f --env-filter " GIT_AUTHOR_NAME='Newname' GIT_AUTHOR_EMAIL='[email protected]' GIT_COMMITTER_NAME='Newname' GIT_COMMITTER_EMAIL='[email protected]' " HEAD
Push to remote with current branch name
I like to be careful with my pushes, sometimes I have multiple repository with the same name or multiple remotes in one repository, and I want to be sure which remote I am pushing to, and I would rather not type a long generated branch name each time.
git push origin HEAD
This pushes to a branch on origin with the same name as your current branch, this is safer than
git push and hoping you set the correct default remote for this branch. Assuming your branch is named “my_branch”, then this command has the same effect as
git push origin my_branch.
Combine multiple commits into one
Maybe you want to hide “fix”, “fixed the fix”, “really fixed this time”, or maybe you just noticed your commit messages a exhausted jibberish!
git reset --soft HEAD~3 git commit
This re-stages the last three commits, leaving the local changes there and the relevant files added to Git, allowing you to write a single new commit message covering all changes.
Modify an old commit
Git Rebase, it’s terrifying.
To start a rebase:
git rebase --interactive 'abc123ef^'
Git opens an editor and you need to flag the commits to modify, saving & exiting the editor causes git to open the repository at that commit.
Once your changes are made, commit them with
git commit --all --amend --no-edit and then
git rebase --continue to move on to the next commit flagged for modification, or if you are finished it will take you back to
Since each git commit is cryptographically based on the commits preceding it, this process causes all commit ID’s from the rebased commit upwards to be changed. If anyone else is working on this repository they will encounter errors trying to push or pull and will need to
git pull -f to forcefully overwrite the discarded history.
If your motivation is to clean up the history, it’s better done in a squash merge.
Push to a remote branch with a different name
This is a weird one, but if you are working in
localBranch and want to push to a branch with a different name then this syntax will help.
git push origin localBranch:remoteBranchToBeCreated
You might want this if you plan to continue wokring on localBranch but want to open a merge request at its current state of development. It’s best to keep your local and remote branches in sync though, this approach gets messy quickly!
Move uncommited changes to a new branch
We’ve all forgotten to change branch before making changes before, this command changes to a new branch and brings your uncommitted changes with you.
git switch -c <new-branch>
Prior to Git 2.23 we used
git checkout -b <new-branch>. The result is the same, but “switch” is more descriptive and less confusing than the overused “checkout”.
Thanks Move existing, uncommitted work to a new branch in Git
Merge changes from another repository
Let’s say someone forked your project and you want to locally pull their changes into your branch, the following instructions set up the fork’s remote, checks out a local branch based on the forked repository, at which point you can perform your merge.
git remote add fork <url of fork> git fetch fork <branch> git checkout -b fork_branch fork/<branch>
This will create the local branch fork_branch with the same history like
in the fork, i.e. fork_branch will branch off of your master where does in the fork. Additionally, your local branch will now track that branch in the fork, so you can easily pull in new changes committed in the fork.