loading...

Pull Requests: a simple workflow

jmfayard profile image Jean-Michel Fayard 🇫🇷🇩🇪🇬🇧🇪🇸🇨🇴 ・2 min read

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.

Discussion

markdown guide
 

Really well described. Will reference this in the future.

 

How does this help?

git reset --soft origin/master

Can you explain?

 

Sure!

  • origin is the original project and not your fork.
  • since you have pulled origin/master, that commit represents the latest and greatest that the project has.
  • since you have merged 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.
  • after git reset --soft origin/master, when you commit again, you have the exact same right working working tree BUT its direct parent will be origin/master. (1)
  • from the perspective of the maintainer, the git history is clean : exactly one new commit above his master branch.

(1) As the friendly manual says,

  git reset --soft <commit> # here <commit> = origin/master
    Does not touch the index file or the working tree at all 
    (but resets the head to <commit>, just like all modes do). 
    This leaves all your changed files "Changes to be committed", 
    as git status would put it.

Hope that helps :)