Git Advanced Tools: Interactive Rebase, Bisect, Worktree, Submodules, and Hooks


Introduction





Most developers use Git at a surface level: add, commit, push, pull, merge. Git's advanced features, however, provide powerful capabilities for history manipulation, debugging, parallel development, dependency management, and automation. These tools separate proficient Git users from experts and significantly impact code quality and development workflow efficiency.





This article covers interactive rebase, git bisect, worktree, submodules, and hooks.





Interactive Rebase





Interactive rebase rewrites commit history by reordering, squashing, editing, dropping, or splitting commits. It is the primary tool for maintaining a clean, readable commit history before merging feature branches.






git rebase -i HEAD~5







The interactive rebase editor presents a list of commits with actions:


* `pick` — Use the commit as-is.

* `reword` — Change the commit message.

* `edit` — Amend the commit content.

* `squash` — Combine with the previous commit, merging messages.

* `fixup` — Combine with the previous commit, discarding message.

* `drop` — Remove the commit entirely.




Best practices include squashing fixup commits, splitting large commits into logical units, and rewriting messages for clarity. Interactive rebase should only be used on branches not shared with other developers — rewriting public history causes painful merge conflicts for collaborators.





Conflict resolution during rebase requires solving conflicts per commit, not per merge. Each commit in the rebase sequence is applied and paused on conflict. The `git rerere` (reuse recorded resolution) feature automatically applies previously resolved conflict resolutions.






git config --global rerere.enabled true







Git Bisect: Binary Search for Bugs





git bisect performs binary search through commit history to find the exact commit that introduced a bug. It automates what would otherwise be a manual, tedious process.






git bisect start


git bisect bad HEAD # Current commit is broken


git bisect good v2.3.0 # This tag is known good


# Git checks out a commit halfway between good and bad


# Test the commit and mark:


git bisect good # This commit is still good


# or


git bisect bad # This commit is already broken


# Repeat until the first bad commit is identified


git bisect reset # Return to original HEAD







Automating bisect with a test script speeds the process significantly:






git bisect run npm test







The script should exit 0 for good commits and non-zero for bad commits. For best results, the test should be fast and focused on the bug's symptom.





Bisect is most effective when commits are small, atomic, and well-described. Large commits touching multiple files make bisect identification harder.





Git Worktree





git worktree allows checking out multiple branches simultaneously in separate directories, sharing a single Git repository. This eliminates the need for multiple clones or stashing changes when switching contexts.






git worktree add ../feature-branch feature-branch


git worktree add ../hotfix hotfix --detach







Use cases include:


* Working on a hotfix while mid-project in another branch.

* Running parallel CI verification on different branches.

* Reviewing pull requests without disrupting current work.

* Maintaining separate directories for development and production builds.




Worktrees share the same repository objects but maintain separate working directories and indexes. Each worktree has its own HEAD, branch, and staging area.






git worktree list


git worktree remove ../feature-branch


git worktree prune # Clean up references to removed worktrees







Git Submodules





Submodules embed one Git repository inside another at a specific commit. They are Git's native mechanism for managing external dependencies.






git submodule add https://github.com/org/library.git lib/library


git submodule update --init --recursive







Submodules track a specific commit, not a branch. Updating requires explicitly checking out a new commit in the submodule and committing the change in the parent repository.






cd lib/library


git checkout v2.1.0


cd ../..


git add lib/library


git commit -m "Update library to v2.1.0"







Subtree merging is an alternative to submodules that merges external repositories directly into the parent repository's directory tree. Unlike submodules, subtrees have no separate configuration and do not require developers to learn submodule commands. The trade-off is less clear separation of concerns.





Git Hooks





Git hooks are scripts that execute at specific points in the Git workflow. They automate validation, enforcement, and integration tasks.





Client-side hooks include:


* `pre-commit`: Lint code, run formatters, check for secrets.

* `commit-msg`: Validate commit message format.

* `pre-push`: Run test suite before pushing.

* `post-commit`: Notify CI system, update issue tracker.




Server-side hooks include:


* `pre-receive`: Enforce commit policies, block force pushes.

* `update`: Per-branch policy enforcement.

* `post-receive`: Deploy to production, send notifications.




The pre-commit framework manages hooks declaratively:






# .pre-commit-config.yaml


repos:


- repo: https://github.com/pre-commit/pre-commit-hooks


rev: v4.5.0


hooks:


- id: trailing-whitespace


- id: end-of-file-fixer


- id: check-yaml


- repo: https://github.com/psf/black


rev: 24.2.0


hooks:


- id: black







Conclusion





Advanced Git tools significantly improve development workflows. Interactive rebase maintains clean history. git bisect accelerates debugging through automated binary search. git worktree enables parallel branch work without context switching. Submodules manage dependencies with precise version tracking. Git hooks automate quality enforcement at every workflow stage. Mastering these tools distinguishes proficient Git users and directly improves code quality and team productivity.