Reputation: 6695
I'm working on a feature branch for days. During this time I did so many mistakes and committed so many unnecessary code changes, which I had to revert in the next commit.
Finally, I found the best solution and now I'm ready to create a Pull-Request. However, I don't want that every one can see how many stupid commits I've don to the branch. :-)
What would be the best way to create a clean PR with the latest code but without all those commits?
I'm using Git in terminal.
Upvotes: 8
Views: 10524
Reputation: 26220
You can run an interactive git rebase:
git rebase -i HEAD~N
where N is the number of last commits in your history which you wish to take an action on (e.g modify the commit message, delete the commit, etc.).
This command allows you to choose from a series of actions to apply to each commit (up to the Nth commit). You can find more information on the available actions here.
Upvotes: 10
Reputation: 45819
If you've never pushed the branch,then you can do an interactive rebase to "squash" the unwanted commits without any problems. If you have ever pushed the branch, then doing a rebase would require that you then "force push' the branch, which may or may not be a problem.
Force pushing is a problem if the remote is configured to disallow it. There's not much you can do about that if it comes up.
Force pushing could be a problem if other users might have copies of the branch in their clones, especially if they might have based work on it. In this case you'd have to coordinate with the other users; see the git rebase
docs under "recovering from upstream rebase' for more info. https://git-scm.com/docs/git-rebase
So if the above prevents you from rebasing, then there's not much you can do and you'll just have to set the vanity of 'not wanting people to see the mistakes' aside. (But then again, if you've ever pushed the branch, then others can already see what you did anyway.)
So if you want to proceed with a rebase:
Assuming you created your feature branch from master
, you can say
git rebase -i master feature
if you want to also move your branch to the current master tip (integrating the changes from master
), or
git rebase -i $(git merge-base master feature) feature
to keep the rewritten branch based where your branch already is.
This will bring up a text editor with a "TODO list" that gives rebase its instructions. Each line represents a commit. For each commit you want to remove, find the commit in the list, then change the first word of the FOLLOWING COMMIT's line to squash.
For example, if the TODO list says
pick 1111111 a good commit
pick 2222222 a bad commit
pick 3333333 revert the bad commit
pick 4444444 another good commit
and you just want to keep 1111111 and 4444444, you would edit the list to say
pick 1111111 a good commit
pick 2222222 a bad commit
squash 3333333 revert the bad commit
squash 4444444 another good commit
This combines 3 into the commit before it (2), then combines 4 into the commit before it (the result of combining 2 and 3), so you're left with 1 and 4. (The changes from 2 and 3 are still included, but if 3 truly reverts 2 then that means nothing.)
Upvotes: 5