This page originated back when I started using Git, replacing my Subversion repositories. The page stayed still for a long time, full of almost useless information. Now I have decided to replace it with the question I usually look up on the internet
How to find a common ancestor
You have a working branch, and you want to know when it detached from the main branch.
git merge-base A B
where ‘A’ and ‘B’ can be tags, branches, or commits.
How to squash commits
There are two ways. The most intuitive one requires you to reset the local branch, i.e. removing top commits form it while preserving the changes, then adding changes alltogether. Second way involves rebasing.
Intuitive: reset / add / commit
git reset --soft <commit>
Where <commit> can be one of the following:
- a commit sha
- a tag or a branch name
- a relative reference e.g. HEAD~3 (one before the last three commits)
Note that git reset moves the HEAD pointer to the base on which the squashed commits will go.
Now you have to add and commit the changes –
- git add .
- git commit
Rebasing
This invokes an interacting process where you can decide for each commit what to do (squash or skip):
git rebase -i <ref>
Where ref is the base reference you want your single commit to be based on. It can be:
- a commit sha
- a tag or a branch name
- a relative reference e.g., HEAD~3 (one before the last three commits)
Your default editor will open with a list of the commits. By default, each commit is set to “pick”; you have to change “pick” to “squash” for squashing commits together. Note that commits are listed from the oldest to the newest. “squash” means to collapse together the commit marked “squash” with the previous one. So you have to leave “pick” the first commit and set to “squash” all the following.
After saving the file and exiting the editor, the editor will reopen and prompt for a commit message. By default, all the previous commit messages will be listed.
How to add a submodule to an existing repository
If you want to add the repo at <url> as a submodule of your repository, as directory <dir> use:
git submodule add <url> <dir>
<dir> is optional, if you omit it, the directory of the submodule will be named after submodule.
How to remove a submodule from a repository
How to replace the origin of a submodule
If you have a submodule in directory <dir> and you want to replace its source with a different repository you can follow this quite convoluted procedure:
- Modify the
.gitmodulesfile in the repo root to use the new URL. - Delete the submodule folder in the repo
rm -rf .git/modules/. - Delete the submodule folder in the working directory
rm -rf<dir> - Run
git submodule sync. - Run
git submodule update.