|
| 1 | +[[_github_flow]] |
| 2 | +=== The GitHub Flow |
| 3 | + |
| 4 | +(((GitHub, Flow))) |
| 5 | +GitHub is designed around a particular collaboration workflow, centered on Pull Requests. |
| 6 | +This flow works whether you're collaborating with a tightly-knit team in a single shared repository, or a globally-distributed company or network of strangers contributing to an project through dozens of forks. |
| 7 | +It is centered on the <<_topic_branch>> workflow covered in <<_git_branching>>. |
| 8 | + |
| 9 | +Here's how it generally works: |
| 10 | + |
| 11 | +1. Create a topic branch from `master`. |
| 12 | +2. Make some commits to improve the project. |
| 13 | +3. Open a Pull Request on GitHub. |
| 14 | +4. Discuss and continue committing. |
| 15 | +5. The project owner merges or closes the Pull Request. |
| 16 | + |
| 17 | +This is basically the Integration Manager workflow covered in <<_integration_manager>>, but instead of using email to communicate and review changes, teams use GitHub's web based tools. |
| 18 | + |
| 19 | +Let's walk through an example of proposing a change to an open source project hosted on GitHub using this flow. |
| 20 | + |
| 21 | +==== Example Contribution Cycle |
| 22 | + |
| 23 | +Tony is looking for code to run on his Arduino programmable microcontroller and has found a great program file on GitHub at https://github.com/schacon/blink[]. |
| 24 | + |
| 25 | +.The project we want to contribute to. |
| 26 | +image::images/blink-start.png[The project we want to contribute to.] |
| 27 | + |
| 28 | +The only problem is that the blinking rate is too fast, we think it's much nicer to wait 3 seconds instead of 1 in between each state change. So let's improve the program and submit it back to the project as a proposed change. |
| 29 | + |
| 30 | +First, we click the 'Fork' button as mentioned earlier to get our own copy of the project. Our user name here is ``tonychacon'' so our copy of this project is at `https://github.com/tonychacon/blink` and that's where we can edit it. We will clone it locally, create a topic branch, make the code change and finally push that change back up to GitHub. |
| 31 | + |
| 32 | +[source,shell] |
| 33 | +---- |
| 34 | +$ git clone https://github.com/tonychacon/blink <1> |
| 35 | +Cloning into 'blink'... |
| 36 | +
|
| 37 | +$ cd blink |
| 38 | +$ git checkout -b slower-blink <2> |
| 39 | +Switched to a new branch 'slower-blink' |
| 40 | +
|
| 41 | +$ sed -i '' 's/1000/3000/' blink.ino <3> |
| 42 | +
|
| 43 | +$ git diff --word-diff <4> |
| 44 | +diff --git a/blink.ino b/blink.ino |
| 45 | +index 15b9911..a6cc5a5 100644 |
| 46 | +--- a/blink.ino |
| 47 | ++++ b/blink.ino |
| 48 | +@@ -18,7 +18,7 @@ void setup() { |
| 49 | +// the loop routine runs over and over again forever: |
| 50 | +void loop() { |
| 51 | + digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) |
| 52 | + [-delay(1000);-]{+delay(3000);+} // wait for a second |
| 53 | + digitalWrite(led, LOW); // turn the LED off by making the voltage LOW |
| 54 | + [-delay(1000);-]{+delay(3000);+} // wait for a second |
| 55 | +} |
| 56 | +
|
| 57 | +$ git commit -a -m 'three seconds is better' <5> |
| 58 | +[master 5ca509d] three seconds is better |
| 59 | + 1 file changed, 2 insertions(+), 2 deletions(-) |
| 60 | +
|
| 61 | +$ git push <6> |
| 62 | +Username for 'https://github.com': tonychacon |
| 63 | +Password for 'https://[email protected]': |
| 64 | +Counting objects: 5, done. |
| 65 | +Delta compression using up to 8 threads. |
| 66 | +Compressing objects: 100% (3/3), done. |
| 67 | +Writing objects: 100% (3/3), 340 bytes | 0 bytes/s, done. |
| 68 | +Total 3 (delta 1), reused 0 (delta 0) |
| 69 | +To https://github.com/tonychacon/blink |
| 70 | + * [new branch] slower-blink -> slower-blink |
| 71 | +---- |
| 72 | + |
| 73 | +<1> Clone our fork of the project locally |
| 74 | +<2> Create a descriptive topic branch |
| 75 | +<3> Make our change to the code |
| 76 | +<4> Check that the change is good |
| 77 | +<5> Commit our change to the topic branch |
| 78 | +<6> Push our new topic branch back up to our GitHub fork |
| 79 | + |
| 80 | +Now if we go back to our fork on GitHub, we can see that they noticed that we pushed a new topic branch up and present us with a big green button to check out our changes and open a Pull Request to the original project. |
| 81 | + |
| 82 | +.Pull Request button |
| 83 | +image::images/blink-pr.png[Pull Request button] |
| 84 | + |
| 85 | +(((GitHub, pull requests))) |
| 86 | +If we click that green button, we'll see a screen that allows us to create a title and description for the change we would like to request so the project owner has a good reason to consider it. It is generally a good idea to spend some effort making this description as useful as possible so the author knows why this is being suggested and why it would be a valuable change for them to accept. |
| 87 | + |
| 88 | +We also see a list of the commits in our topic branch that are ``ahead'' of the `master` branch (in this case, just the one) and a unified diff of all the changes that will be made should this branch get merged by the project owner. |
| 89 | + |
| 90 | +.Pull Request creation page |
| 91 | +image::images/blink-pull-request-open.png[Pull Request creation] |
| 92 | + |
| 93 | +When you hit the 'Create pull request' button on this screen, the owner of the project you forked will get a notification that someone is suggesting a change and will link to a page that has all of this information on it. |
| 94 | + |
| 95 | +[NOTE] |
| 96 | +==== |
| 97 | +Though Pull Requests are used commonly for public projects like this when the contributor has a complete change ready to be made, it's also often used in internal projects at the beginning of the development cycle. Since you can keep pushing to the topic branch even *after* the Pull Request is opened, it's often opened early and used as a way to iterate on work as a team within a context, rather than opened at the very end of the process. |
| 98 | +==== |
| 99 | + |
| 100 | +At this point, the project owner can look at the suggested change and merge it, reject it or comment on it. Let's say that he likes the idea, but would prefer a slightly longer time for the light to be off than on. |
| 101 | + |
| 102 | +Where this conversation may take place over email in the workflows presented in the previous chapter, on GitHub this happens online. The project owner can review the unified diff and leave a comment by clicking on any of the lines. |
| 103 | + |
| 104 | +.Pull Request line comment |
| 105 | +image::images/blink-3-seconds.png[PR line comment] |
| 106 | + |
| 107 | +They can also leave a general comment on the Pull Request. In <<_pr_discussion>> we can see an example of the project owner both commenting on a line of code and then leaving a general comment in the discussion section. You can see that the code comments are brought into the conversation as well. |
| 108 | + |
| 109 | +[[_pr_discussion]] |
| 110 | +.Pull Request discusson page |
| 111 | +image::images/blink-comment.png[PR discussion page] |
| 112 | + |
| 113 | +Now the contributor can see what they need to do in order to get their change accepted. Luckily this is also a very simple thing to do. Where over email you may have to re-roll your series and resubmit it to the mailing list, with GitHub you simply commit to the topic branch again and push. |
| 114 | + |
| 115 | +If the contributor does that then the project owner will get notified again and when they visit the page they will see that it's been addressed. In fact, since a line of code changed that had a comment on it, GitHub notices that and collapses the outdated diff. |
| 116 | + |
| 117 | +.Pull Request final |
| 118 | +image::images/blink-final.png[PR final] |
| 119 | + |
| 120 | +The other thing you'll notice is that GitHub checks to see if the Pull Request merges cleanly and provides a button to do the merge for you on the server. This button only shows up if you have write access to the repository and if you click it GitHub will perform a ``non-fast-forward'' merge, meaning that even if the merge *could* be a fast-forward, it will still create a merge commit. |
| 121 | + |
| 122 | +If you would prefer, you can simply pull the branch down and merge it locally. If you merge this branch into the `master` branch and push it to GitHub, the Pull Request will automatically be closed. |
| 123 | + |
| 124 | +This is the basic workflow that most GitHub projects use. Topic branches are created, Pull Requests are opened on them, a discussion ensues, possibly more work is done on the branch and eventually the request is either closed or merged. |
| 125 | + |
| 126 | +[NOTE] |
| 127 | +.Not Only Forks |
| 128 | +==== |
| 129 | +It's important to note that you can also open a Pull Request between two branches in the same repository. If you're working on a feature with someone and you both have write access to the project, you can push a topic branch to the repository and open a Pull Request on it to the `master` branch of that same project to initiate the code review and discussion process. No forking neccesary. |
| 130 | +==== |
0 commit comments