generated from sinedied/devto-github-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
30f991b
commit 94d85e5
Showing
2 changed files
with
74 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.