Entry tags:
rahaeli's first foray into github: a step-by-step travelogue
Tonight I decided I was going to figure out Git and Github enough to make a patch using it! Behind the cut is my adventures in Git-itude, detailing all the steps I took (and all the false starts, too.) I'm pretty sure this is all correct, but I haven't fact-checked the post with somebody who knows more than I do, so caveat lector (and if you spot an error, please do tell me so I can correct it!)
This post is also a bit vague on some process bits that we haven't decided yet, so when we flip the switch and move to using Github for development wholesale, some of these bits will look a little different. I just wanted to demystify the process a little, since I know that I was feeling a little trepidatious about this (AUUUGH, CHANGE IS SCARY) until I got into the guts of it and started playing around and realized how much nicer this process is going to be!
So, this is a log of the playing around I did tonight. :)
1. Create a Github account!
2. Download the git package for my computer.
3. Follow instructions on https://help.github.com/articles/set-up-git for setting up the command line package.
4. I have a Terminal window open. I type first command, get error. Realize I need to relaunch terminal window. (For those of you who don't use the Terminal regularly: it's in Applications/Terminal.)
5. Go to https://github.com/dreamwidth/dw-free and hit the "Fork" button in upper right. Click "Fork to rahaeli" on subsequent page. Now I have my own branch of dw-free! This branch is where I'll be doing my work.
6. Hit the "clone to Mac" button on the page that shows up once I fork the dw-free repo. * Realize there is a GUI client, yay! Hit the "Download the latest" link on the page it sends me to (http://mac.github.com/) and get errors. Try downloading in different browser. Fail. Decide to just go ahead and use the command line instead.
* The difference between forking and cloning confused the fuck out of me at first. I finally figured it out today during a conference session: you fork a repository to create what is essentially an "empty folder" in your local copy of git. Once you've forked the repo, and have told git "this repository should exist!", you need to clone the files from the dw-free repository on github to your local dw-free repository. Forking tells your local copy of git that you want to have a local copy of the dw-free code; cloning copies the files from the github dw-free to your local dw-free.
7. So, since downloading the GUI isn't working right now (I'm pretty sure it's this crappy hotel internet), I'm going to use the command line to clone the files to my local copy. First, I create a new directory in my home directory (so the code all gets put in a logical place) and change my working directory into it, and then I run the clone:
8. Still following the "Fork a Repo" instructions:
9. Decided to try downloading GUI again. Got it this time! Yay, install time. Install, go through setup, tell it to find my local repositories (it found the ones I'd just created with no problem).
10. I now have git set up and everything is configured! I have a local copy of the code (in the "dev" directory I created) and I can make my changes. We do not currently have any automatic-sync setup to move files from my computer to my Dreamhack, but I can do the actual file edits on my machine and then use my text editor (which doubles as a sftp client) to save the file both locally and on my 'hack.
11. So: time to do a bug! Step one, create a local branch. This will let me keep all my work on a single bug in a single branch (and not mix it with other changes). In fact, every bug you work on *should* be in a single branch: that way you're assured of only submitting the changes you mean to submit. (Although git makes it super super easy to manage this on your end, it's still a good idea to do it that way.) So, on the Branches page of the Git GUI frontend, I hit the plus-sign icon next to the 'develop' branch. This will give me a new branch to work in (where I'll be putting all my changes). I'm working on bug 4251, so I'll call my branch "bug-4251". Voila, I have a branch to work in.*
* You'll notice when you create the new branch that the string of 6 or so letters underneath the branch names will be the same for the 'develop' branch and the branch you just created. That string is a unique identifier (produced by the checksum of the branch's contents and its parent) and is what allows most of the really awesomely powerful tools of Git to work. You don't really need to understand how all that works at the moment, though -- but if you're interested, read Pro Git. Long story short, that identifier is what lets Git figure out which commits go into each branch and also lets Git figure out how to merge branches sensibly.
12. I make sure I'm switched to this branch (in the GUI, it's the downward-facing triangle icon) and go do my coding. Fix fix fix.
13. Once I'm done with my fix -- done and saved in the branch I have checked out locally on my laptop -- I want to put it onto my Dreamhack to test it. Eventually we'll have a better process for this (probably pretty soon, in fact), but I wanted to see if I really did learn enough about git at the talks I've been going to at these conferences so I didn't want to wait ;) Using my text editor, which doubles as an sftp client, I saved a copy to my Dreamhack as well. I tested the patch and it works just fine, so now it's time to generate a pull request.
14. I go to the "Changes" tab in my Git client. Since I've made changes that haven't had anything done to them yet, yay, there are changes there! By default, all my changes are included. (In this case, I changed two files, so both files are listed.) This is the staging area, also called a ton of different things (everything in git has like four names, which is one of the most confusing things about the process), and I think of it like checking out books in a library: first you wander around the library picking up all the books you might want, and then when you're ready to take your books home you go through your stack one-by-one and decide if you really want each book enough to want to take it up to the counter. (Or maybe that's just me.) In Git, first you wander around your directories changing a bunch of code, and then when you're ready
to send your changes to the main DW repository, you go through your changes one-by-one and decide if you really want each change enough to want to send it up to the repo.
15. A brief digression for a point of doctrine and a potential demystification: If you don't select a file in this step, it will not be included in the commit. You can even select individual lines of each changeset: if you're working on two different patches and they both touch the same file, or you're checking in code in stages and part of the file's changes are working already but the other part isn't ready for prime time, you can check the chunks in separately by unselecting the bits you don't want included in here. Forgetting about this part is apparently one of the most common problems with using Git.
16. In this case, I want all my changes to be included in this commit (it's still called a commit even though I'm committing it to my local repository, not to the main Dreamwidth repository), so I make sure they're all suggested. I include a commit summary (briefly describing what I did in the patch) and click 'commit'. (I'm sure we'll figure out the format for commit summaries soon! For now I'm just kind of guessing.)
17. Once you hit "commit" (after filling out a descriptive commit message!) the screen will refresh and the commit you just made will show in "unsynced commits". So, next we will hit "Publish branch" in the upper right corner, which will push my changes up to my copy of the code on github. (You could also hit "commit & sync", aka the recycley looking icon, to do both of these in one step.)
18. So, my changes are now present in both my local repository (the one on my computer) and on my Github account. (You can see my branch on Github! It's the bug-4251 branch I created earlier.) I look it over and yeah, it's ready for somebody to review it. Time for me to submit it to the main Dreamwidth branch! On my Github page, the recently-pushed branch will appear in my Public Activity in the sidebar, and I'll click through to the details of that branch. In the middle of the page is a big button marked "Pull Request". That's what I do to submit my changes to the main DW repo for review: by hitting that, I'm asking somebody to pull my changes into the main Dreamwidth repo. I click that button, look over the message to make sure it doesn't need to be edited further (it's the one I provided when I made the commit to my local branch in the Github client, so it's okay), and I click "send pull request".
19. For now, since we still haven't decided how we're going to handle integration between Github and Bugzilla, I will also need to generate an old-style patch file to attach to Bugzilla so it can go into the review queue and alert people that it needs to be looked at. Fortunately, I already uploaded the files to my 'hack when I was testing it worked, so I can just go back over to Bugzilla and generate the patch file the way I always have.
20. Once I'm done, I can switch back to the 'develop' branch so that any other branches I make will be branches of that branch. (In my client, it's done by going to the branches tab, then hitting the downward-triangle and selecting 'Switch to this branch'.) If my patch gets returned for further changes, I can switch back over to the bug-4251 branch. (Once my bug-4251 branch gets merged into the 'develop' branch, I can delete the branch to keep things tidy, but don't do that until after it's been merged into the main DW repository: otherwise you'll have to recreate your changes if the patch needs revision.)
And thus ends my first forays into git! There's a bunch of other stuff we'll need to go over, such as what to do if somebody else has made changes to the master DW branch while you were working on your patch, but that's a little bit hard to explain with words (usually it requires diagrams, although one of the talks I attended today had
schwern demonstrating it with Tinkertoys) so I'll hold off on that until another day. :)
This post is also a bit vague on some process bits that we haven't decided yet, so when we flip the switch and move to using Github for development wholesale, some of these bits will look a little different. I just wanted to demystify the process a little, since I know that I was feeling a little trepidatious about this (AUUUGH, CHANGE IS SCARY) until I got into the guts of it and started playing around and realized how much nicer this process is going to be!
So, this is a log of the playing around I did tonight. :)
1. Create a Github account!
2. Download the git package for my computer.
3. Follow instructions on https://help.github.com/articles/set-up-git for setting up the command line package.
4. I have a Terminal window open. I type first command, get error. Realize I need to relaunch terminal window. (For those of you who don't use the Terminal regularly: it's in Applications/Terminal.)
5. Go to https://github.com/dreamwidth/dw-free and hit the "Fork" button in upper right. Click "Fork to rahaeli" on subsequent page. Now I have my own branch of dw-free! This branch is where I'll be doing my work.
6. Hit the "clone to Mac" button on the page that shows up once I fork the dw-free repo. * Realize there is a GUI client, yay! Hit the "Download the latest" link on the page it sends me to (http://mac.github.com/) and get errors. Try downloading in different browser. Fail. Decide to just go ahead and use the command line instead.
* The difference between forking and cloning confused the fuck out of me at first. I finally figured it out today during a conference session: you fork a repository to create what is essentially an "empty folder" in your local copy of git. Once you've forked the repo, and have told git "this repository should exist!", you need to clone the files from the dw-free repository on github to your local dw-free repository. Forking tells your local copy of git that you want to have a local copy of the dw-free code; cloning copies the files from the github dw-free to your local dw-free.
7. So, since downloading the GUI isn't working right now (I'm pretty sure it's this crappy hotel internet), I'm going to use the command line to clone the files to my local copy. First, I create a new directory in my home directory (so the code all gets put in a logical place) and change my working directory into it, and then I run the clone:
mkdir dev
cd dev
git clone https://github.com/rahaeli/dw-free.git8. Still following the "Fork a Repo" instructions:
cd dw-free
git remote add upstream https://github.com/dreamwidth/dw-free.git
git fetch upstream
9. Decided to try downloading GUI again. Got it this time! Yay, install time. Install, go through setup, tell it to find my local repositories (it found the ones I'd just created with no problem).
10. I now have git set up and everything is configured! I have a local copy of the code (in the "dev" directory I created) and I can make my changes. We do not currently have any automatic-sync setup to move files from my computer to my Dreamhack, but I can do the actual file edits on my machine and then use my text editor (which doubles as a sftp client) to save the file both locally and on my 'hack.
11. So: time to do a bug! Step one, create a local branch. This will let me keep all my work on a single bug in a single branch (and not mix it with other changes). In fact, every bug you work on *should* be in a single branch: that way you're assured of only submitting the changes you mean to submit. (Although git makes it super super easy to manage this on your end, it's still a good idea to do it that way.) So, on the Branches page of the Git GUI frontend, I hit the plus-sign icon next to the 'develop' branch. This will give me a new branch to work in (where I'll be putting all my changes). I'm working on bug 4251, so I'll call my branch "bug-4251". Voila, I have a branch to work in.*
* You'll notice when you create the new branch that the string of 6 or so letters underneath the branch names will be the same for the 'develop' branch and the branch you just created. That string is a unique identifier (produced by the checksum of the branch's contents and its parent) and is what allows most of the really awesomely powerful tools of Git to work. You don't really need to understand how all that works at the moment, though -- but if you're interested, read Pro Git. Long story short, that identifier is what lets Git figure out which commits go into each branch and also lets Git figure out how to merge branches sensibly.
12. I make sure I'm switched to this branch (in the GUI, it's the downward-facing triangle icon) and go do my coding. Fix fix fix.
13. Once I'm done with my fix -- done and saved in the branch I have checked out locally on my laptop -- I want to put it onto my Dreamhack to test it. Eventually we'll have a better process for this (probably pretty soon, in fact), but I wanted to see if I really did learn enough about git at the talks I've been going to at these conferences so I didn't want to wait ;) Using my text editor, which doubles as an sftp client, I saved a copy to my Dreamhack as well. I tested the patch and it works just fine, so now it's time to generate a pull request.
14. I go to the "Changes" tab in my Git client. Since I've made changes that haven't had anything done to them yet, yay, there are changes there! By default, all my changes are included. (In this case, I changed two files, so both files are listed.) This is the staging area, also called a ton of different things (everything in git has like four names, which is one of the most confusing things about the process), and I think of it like checking out books in a library: first you wander around the library picking up all the books you might want, and then when you're ready to take your books home you go through your stack one-by-one and decide if you really want each book enough to want to take it up to the counter. (Or maybe that's just me.) In Git, first you wander around your directories changing a bunch of code, and then when you're ready
to send your changes to the main DW repository, you go through your changes one-by-one and decide if you really want each change enough to want to send it up to the repo.
15. A brief digression for a point of doctrine and a potential demystification: If you don't select a file in this step, it will not be included in the commit. You can even select individual lines of each changeset: if you're working on two different patches and they both touch the same file, or you're checking in code in stages and part of the file's changes are working already but the other part isn't ready for prime time, you can check the chunks in separately by unselecting the bits you don't want included in here. Forgetting about this part is apparently one of the most common problems with using Git.
16. In this case, I want all my changes to be included in this commit (it's still called a commit even though I'm committing it to my local repository, not to the main Dreamwidth repository), so I make sure they're all suggested. I include a commit summary (briefly describing what I did in the patch) and click 'commit'. (I'm sure we'll figure out the format for commit summaries soon! For now I'm just kind of guessing.)
17. Once you hit "commit" (after filling out a descriptive commit message!) the screen will refresh and the commit you just made will show in "unsynced commits". So, next we will hit "Publish branch" in the upper right corner, which will push my changes up to my copy of the code on github. (You could also hit "commit & sync", aka the recycley looking icon, to do both of these in one step.)
18. So, my changes are now present in both my local repository (the one on my computer) and on my Github account. (You can see my branch on Github! It's the bug-4251 branch I created earlier.) I look it over and yeah, it's ready for somebody to review it. Time for me to submit it to the main Dreamwidth branch! On my Github page, the recently-pushed branch will appear in my Public Activity in the sidebar, and I'll click through to the details of that branch. In the middle of the page is a big button marked "Pull Request". That's what I do to submit my changes to the main DW repo for review: by hitting that, I'm asking somebody to pull my changes into the main Dreamwidth repo. I click that button, look over the message to make sure it doesn't need to be edited further (it's the one I provided when I made the commit to my local branch in the Github client, so it's okay), and I click "send pull request".
19. For now, since we still haven't decided how we're going to handle integration between Github and Bugzilla, I will also need to generate an old-style patch file to attach to Bugzilla so it can go into the review queue and alert people that it needs to be looked at. Fortunately, I already uploaded the files to my 'hack when I was testing it worked, so I can just go back over to Bugzilla and generate the patch file the way I always have.
20. Once I'm done, I can switch back to the 'develop' branch so that any other branches I make will be branches of that branch. (In my client, it's done by going to the branches tab, then hitting the downward-triangle and selecting 'Switch to this branch'.) If my patch gets returned for further changes, I can switch back over to the bug-4251 branch. (Once my bug-4251 branch gets merged into the 'develop' branch, I can delete the branch to keep things tidy, but don't do that until after it's been merged into the main DW repository: otherwise you'll have to recreate your changes if the patch needs revision.)
And thus ends my first forays into git! There's a bunch of other stuff we'll need to go over, such as what to do if somebody else has made changes to the master DW branch while you were working on your patch, but that's a little bit hard to explain with words (usually it requires diagrams, although one of the talks I attended today had

no subject
"Fork" is entirely a Github thing. It doesn't exist outside Github. Inside Github, it's nearly the same thing as a clone, except it doesn't note the source in the same place and it takes care of Github user data and stuff.
So up there in point 5, what you did was to make a copy of the entire repository, all inside Github's system (they probably do some deduplication, or they'd waste huge amounts of disk). Then in point 7, you made another copy of the entire repository, this time from Github to your own machine.
Does that make that bit somewhat clearer?