Disclaimer: I’m not a git ninja, and I’m pretty sure a lot of people have written more sophisticated things on this topic. My only qualification is having made a lot of mistakes in the past.
So in the hope of being useful, here is my take on how to contribute simply and effectively a pull request:
- I git clone the original repo.
origin/master
should point to the latest and greatest, not to my soon un-maintened fork - I hit “fork” on github and add my fork as a remote
- I contribute a failing test that showcase what you have in mind
- I open a pull-request to start the discussion
The discussion can have many outcomes: I may have requested something already possible, or outside of the scope of the project, or it’s a bad idea, or it’s good idea that the maintainers will implement ASAP, or it’s a good idea that I am ready to implement myself.
Let’s assume the later case. I do the diligent work locally. Days or weeks later, I’m back in the pull request. I have some feedback, very good, I improve my code.
What then happens especially well-maintained fast-moving projects is that I’m at this point way behind the commit I forked on. At this point I have been stuck in the past by having to do too heavy git gymnastics. (Looking at you git rebase!)
Here is a 4 steps workflow that gets the job done:
- Pull and merge origin/master (reminder: origin is the project’s repo,)
- Resolve conflicts, update things then commit
-
git reset --soft origin/master
then commit again. - Force push to my repo
The commits at steps 2 and 3 will have the same content, the git history will be clean from the perspective of the maintainers of the project, and the whole thing has the nice feature to be idiot proof.
TL;DR
Here is my idiot-proof solution for having a clean PR that is one commit above origin/main
git fetch
git merge origin/main
# if conflicts
echo "resolve conflicts in your IDE"
git commit -a -m "resolve conflicts"
# end if
git reset --soft origin/main
git commit -a -m "⚡️ implement xxx"
git push --force
Top comments (4)
Really well described. Will reference this in the future.
See also
Rewrite your git history in 4 friendly commands
Salma Alam-Naylor ・ Sep 6 ・ 4 min read
How does this help?
git reset --soft origin/master
Can you explain?
Sure!
origin
is the original project and not your fork.origin/master
, that commit represents the latest and greatest that the project has.origin/master
so that you are not behind the project's latest and greatest. The commit that you did after merging contains the right working tree that you want to submit.git reset --soft origin/master
, when you commit again, you have the exact same right working working tree BUT its direct parent will beorigin/master
. (1)(1) As the friendly manual says,
Hope that helps :)