Developers who want to tidy up a cluttered Git project log often turn to interactive rebase. This tool lets you combine, split, reorder, or remove commits with accuracy. Before making changes, weigh the risks: avoid rebasing commits that others have already seen, since rewriting shared history can create problems for collaborators. Git’s official documentation points out that interactive rebase is meant for unpublished local history. Rewriting public history can force teammates to manually fix diverging branches. Git offers recovery tools like the reflog, but these do not automatically fix every downstream clone or branch. For those teaching or learning in coding bootcamps or university settings, knowing these risks is key for group projects and assignments (git-rebase Documentation).
What Is Interactive Rebase?
Interactive rebase lets you rewrite a series of commits in Git. Unlike a standard rebase, which just moves a branch to a new base, interactive rebase gives you detailed control over each commit. You can change messages, squash commits together, split one into several, reorder them, or drop commits. This flexibility helps you clean up your work before merging a feature branch into the main project. Git’s documentation explains that interactive rebase works on commits after the chosen upstream commit, so the upstream itself is left out unless you pick an earlier parent or use the --root option. The interactive todo list uses commands like pick, reword, edit, squash, fixup, exec, and drop. Each action rewrites commit identities, since a commit’s hash depends on its parent, metadata, and content (official documentation).
Key Interactive Rebase Actions
When you launch an interactive rebase with git rebase -i <commit-id>, Git opens a list of recent commits in your editor. Each line shows a commit and starts with a command:
- pick: Keep the commit unchanged.
- reword: Change the commit message.
- squash: Merge this commit with the previous one, combining their changes and messages.
- fixup: Like squash, but drops this commit's message and keeps the earlier one.
- edit: Pause to change the commit's content.
- drop: Remove the commit from history.
- exec: Run a shell command at this step in the rebase.
The interactive rebase todo list uses a set command vocabulary, not free-form editing. Git also supports shorthand like fixup -C and fixup -c to control which commit message is kept or edited. To include the very first commit, add the --root option. The commit you pick as the base is not included in the rebase; changes start from the next commit.
Combining Commits with Squash
If you want to merge two related commits, start the rebase from the commit before the first one you want to combine. For example, to squash commits b7d83e2 and 5e20620 on the merhaba branch, check out that branch and run:
git checkout merhaba git rebase -i 21c0fec
In your editor, change the command for the second commit from pick to squash:
pick b7d83e2 merhaba commit 1 squash 5e20620 merhaba2 commit 2 pick 7715b76 merhaba dan mastera mesaj
After saving, Git prompts you to edit the combined commit message. When finished, the two commits become one, and the branch history is clearer. Squashing commits does more than hide intermediate entries; it creates a new commit graph where the originals are no longer ancestors of the rewritten branch tip. This happens because Git uses content-addressed object names, and changing a commit’s message, author, content, or parent relationship creates a new commit object ID (Git Internals—Git Objects).
Splitting a Commit into Multiple Commits
If you grouped unrelated changes into one commit by mistake, interactive rebase lets you split them. Mark the commit with edit during rebase, then use git reset --mixed HEAD~ to unstage its changes. Add and commit the files separately, then continue the rebase. This keeps commits logical and focused, making them easier to review. During an edit stop, you can amend the commit with git commit --amend, create more commits, and continue with git rebase --continue. If you cannot finish the intended result safely, git rebase --abort restores the branch to its original state. git rebase --skip omits the current commit, which is destructive and should be used only when you mean to drop it.
Reordering and Dropping Commits
To change commit order, rearrange their lines in the rebase editor. If conflicts come up—such as when a file is deleted in one commit and changed in another—Git stops and asks you to resolve them before moving on. To remove a commit, replace pick with drop on its line. This deletes the commit from history, which helps remove mistakes or sensitive data. Rebasing works by finding commits that are on the current branch but not on the selected upstream, then replaying those changes in a new order or place. Git warns that rebasing changes commit ancestry and can make previously published commits look like new ones. The effect is structural: branches, tags, pull requests, and collaboration tools may still point to the old object IDs after rewriting.
Advanced Interactive Rebase Features
Interactive rebase supports advanced actions. The exec command lets you run shell commands at certain points, such as running tests after each commit. If you need to change the rebase plan while it's running, use git rebase --edit-todo to adjust the remaining steps. Options like --rebase-merges can keep merge topology by recreating merge commits, while standard interactive rebasing usually makes the sequence linear. The --autosquash option recognizes commits with messages starting with fixup! or squash! and moves them next to their target commits. --update-refs can move local branches that point into the rewritten commit range, except for references checked out in worktrees (git-rebase Documentation).
Precautions and Best Practices
Rewriting history is powerful but comes with risks. Always make sure your changes are local and not pushed to a shared repository. If you must force-push after a rebase, use --force-with-lease to lower the risk of overwriting others' work. GitHub’s documentation advises treating published commit history as shared infrastructure and notes that rewriting it can affect collaborators who have based work on the original commits. After pushing a rewritten branch, the updated remote reference may need a force push, and GitHub recommends --force-with-lease because it refuses to overwrite the remote branch if it has moved ahead. Teams may use protected branches to block or limit force pushes on important branches. When a rebase rewrites commits already in a remote repository, collaborators may see non-fast-forward errors or duplicated-looking commits because their local references still point to the old commit graph. GitHub’s workflow guidance separates local cleanup before publication from rewriting branches that others may have fetched. The pull-request model can show rewritten history differently depending on which commits remain reachable and how the branch is updated. In practice, interactive rebase is safest before review or integration, while rewriting after publication needs clear team communication and careful reference updates (About Git Rebase).
Beyond Interactive Rebase: Cleaning History at Scale
For large-scale edits, such as removing a file from every commit, tools like git filter-branch or the BFG Repo-Cleaner work more efficiently. These commands let you rewrite the entire commit graph based on set criteria, such as deleting a file or filtering commits by author. Git uses content-addressed object names, historically SHA-1 hashes and, in supported setups, SHA-256 object formats. Since a commit object records its parent references, changing a commit’s message, author, content, or parent relationship creates a new commit object ID. The visible effect depends on whether the rewritten branch is local, pushed, merged elsewhere, or referenced by tags and automation.
Related Git Workflows
Interactive rebase is one way to manage Git history. For a broader look at how rebase can help keep a readable project log and when to use it instead of merge, see our earlier breakdown.
Summary
Interactive rebase gives developers a way to present a clean, logical commit history. By learning its commands and knowing when to use them, you can make your project history easier to read and maintain. Always use caution, especially with shared branches, and apply these techniques to improve workflow and teamwork. For educators and students learning version control, practicing interactive rebase in a safe, local setting helps build skills for collaborative software development and digital project management.
