Advanced Git Features¶
Once you have mastered the basics, consider adding its more advanced features to your tool box.
Rebase¶
Rebase is a powerful, but if used incorrectly it can permanently mess up your Git history.
Always remember to check the commit history with git log
to ensure that it is what you want
before force pushing it to the remote repository with git push -f
.
Standard Mode¶
Assume the following history exists and the current branch is "topic":
From this point, the result of either of the following commands:
would be:
If the local main branch is outdated with the remote main branch, use
to rebase the current branch onto the remote main branch.
Interactive Mode¶
Running git rebase with the -i
flag begins an interactive rebasing session.
Instead of blindly moving all of the commits to the new base, interactive rebasing gives you the opportunity to alter individual commits in the process.
This lets you clean up history by removing, splitting, and altering an existing series of commits.
rebases the current branch onto main but uses an interactive rebasing session. This opens an editor where you can enter commands for each commit to be rebased. These commands determine how individual commits will be transferred to the new base. You can also reorder the commit listing to change the order of the commits themselves. Once you've specified commands for each commit in the rebase, Git will begin playing back commits applying the rebase commands.
Interactive Rebasing Edit Commands
pick 2231360 some old commit
pick ee2adc2 Adds new feature
# Rebase 2cf755d..ee2adc2 onto 2cf755d (9 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
Resolving Conflicts¶
In case of conflict, git rebase will stop at the first problematic commit and leave conflict markers in the tree. You can use git diff to locate the markers (<<<<<<) and make edits to resolve the conflict. For each file you edit, you need to tell Git that the conflict has been resolved, typically this would be done with
After resolving the conflict manually and updating the index with the desired resolution, you can continue the rebasing process with
Alternatively, you can undo the git rebase with
Remote Repositories¶
There may be cases where you want to keep mirrors of your repository.
- The original remote repository is given the identifier
origin
by default
Command | Description |
---|---|
git remote add <repo name> <repo base url>.git |
Add a remote repository and give it the identifier <repo name> |
git push <repo name> --all |
Push all branches to a remote repository |
git remote -v |
List remote repositories |
git remote remove <repo name> |
Remove a remote repository |
Submodules¶
Add a Git repository inside another Git repository, usually to serve as a dependency.
Command | Description |
---|---|
git submodule add <repo base url>.git |
Add a repository as a submodule of the current repository |
git diff --submodule |
Better diff for submodules from the parent repository |
git submodule update --remote --merge |
Update submodules to their latest remote commits |
git submodule update --init --recursive |
Recursively initialize and update submodules to the commits in the remote parent repository |
git clone --recurse-submodules <repo base url>.git |
Clone a repository and recursively initialize all its submodules |
Resources:
- Submodule chapter in the Git book
- Create a submodule that tracks a specific branch
- Properly remove a submodule
Tags¶
Tag a commit. I usually create tags as part of publishing a release on GitHub, but the CLI commands may come in handy if you want to delete a release and its associated tag.
Command | Description |
---|---|
git tag -d <tag name> |
Delete local tag |
git tag -a <tag name> -m "<description>" |
Create an annotated tag for the current commit |
git push --tags |
Push tags to the remote repository |
git show <tag name> |
See tag information |
git checkout <tag name> |
Checkout to the commit that a tag points to |
Resources:
Work Trees¶
Git work trees allow you to have allow you to develop multiple branches of a repository at the same time.
Command | Description |
---|---|
git clone --bare <repo base url>.git |
Clone a repository as a bare repository |
git worktree add <directory> |
Create a work tree at the specified location, checking out to the branch of the same name or creating one if it does not exist |
git worktree add -b <branch name> <directory> |
Same as above, but needed if <branch name> contains forward slashes |
git worktree list |
List all work trees |
git worktree remove <directory> |
Remove a worktree at the specified location |
Resources: