Skip to content

Commit

Permalink
post: Git rebase force
Browse files Browse the repository at this point in the history
  • Loading branch information
navarroaxel committed Oct 15, 2024
1 parent 30f991b commit 94d85e5
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions posts/navarroaxel/21.git-rebase-force.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
title: Recreating Commits with git rebase for Seamless Workflow
published: true
description: 'We dive into the advanced use of git rebase to recreate commits, especially useful when GitHub struggles with commit detection.'
tags: 'git, bash, productivity, tooling'
cover_image: ./assets/git-rebase-force.png
id: 2017205
---

In this series we've learned how to merge or split commits using the `git rebase` command, now it's time to learn how to recreate commits and when this can be useful. πŸͺ„

## Forcing the rebase

By default, the rebase makes a _fast-forward_ when it's possible πŸ€”. This means that the commits aren't re-created when they're being applied over the same previous commit, keeping the commit ID (SHA) unchanged. You can force this recreation and get a new commit ID using the [`--force-rebase`](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---force-rebase) flag.

```bash
git rebase --force-rebase main
```

This may be useful in those sad days when GitHub has issues detecting new commits in the repository and fails to trigger the GitHub Actions or the pull request is out of sync with the Git repo. 🌚

Also, this could be useful when you revert a failed merge and you need to remerge the same code now expecting to work properly 🀞 without _revert the reversion_ πŸ˜΅β€πŸ’«. Let's explain this complex scenario a little more.

### Remerging a reverted merge

For this example we merge a topic branch into a shared branch as always.

```bash
git checkout staging
git merge mytopic-branch
git push origin staging
```

But let's say you merged these changes too soon, or you need another topic to be merged into `staging` first. Just [revert](https://git-scm.com/docs/git-revert) the merge.

```bash
git revert mytopic-branch
git push origin staging
```

After pushing more commits into `staging` it's time to remerge your topic πŸŽ‰ again, and you get a Git output worse than a merge conflict. πŸ™€

```text
$ git merge mytopic-branch
Already up to date.
```

![Pablo Escobar is sad because he received an "Already up to date" output in the terminal after applying a Git merge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0k4f4c3ktcg6iuoybvv1.jpg)

Why are we getting `Already up to date` if the merge was reverted? Git is inspired by the [patch-set](https://en.wikipedia.org/wiki/Patch_(computing)) workflow of open-source development, the `mytopic-branch`'s commits already exist in the `staging` branch even if they were reverted. Let's use `git rebase` to recreate these 3 commits of the topic branch:

```bash
git checkout mytopic-branch
git rebase --force-rebase HEAD~3
git checkout staging
git merge mytopic-branch
```

What if `mytopic-branch` is a shared branch like `development` and I can't rewrite its history? You could _revert the reversion_ using this:

```bash
git checkout staging
git revert 0680aa7 # SHA of the revert commit.
```

In this latest scenario you're undoing the reversion and you can get Git conflicts too. Just resolve this as always. You can choose any method to do this but if anyone is not too familiar with Git a revert of a revert could be hard to understand just checking the Git log if the commit message is not clear about what happened and what commits you're reapplying.

## Conclusion

Always remember that the commit ID is used by Git for traceability, If you change the commit ID of a set of changes this is not the same commit for Git.

This not only occurs when you recreate commits using `git rebase`, [`git cherry-pick`](https://git-scm.com/docs/git-cherry-pick) applies changes changing the parent commit and that means a new commit ID is used for these picked changes.

I hope you find this post useful. Let me know in the comments how you resolved the _revert the reversion_. πŸ‘‡ See ya!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 94d85e5

Please sign in to comment.