-
Notifications
You must be signed in to change notification settings - Fork 3
Git and Github
Here's a useful reference for git commands and github integration.
Git is a version control system. The problem that git solves is this: say you have about 10 people working on a project (like we will), and you divide up tasks between people, which makes sense. Let's call two of them person A and person B. Suppose person A needs person B's code.
How does person B give his code to person A? He could email it, but then person A has to download and copy and paste the new code every time, and as soon as person B does more work, he has to email his new code to person A again. That's no good.
Person A and person B could use Dropbox (or something similar), but then sometimes person A's files would get automatically updated with person B's new code, causing person A to lose his work. That's no good either. Not to mention, none of the other people on the team have any idea what person A and person B are doing!
This is where git comes in. When person B completes the code that he's working on, he can "push" the code to a "repository" (in this case, our space on github), and person A can "pull" the new code from the repository. Then, when person A is done, he can push his code to the repository too. Now everyone on the project has access to everything, easily.
The most efficient way for everyone to have access to our code is of course to store it in the cloud. We can do this with github. If you look at our github page, you will be able to see all the files in our repository as well as all the times that we've pushed.
If you have a mac with homebrew installed, you can simply run brew install git from the command line and everything should work. You can also download a non-command line client here.
If you're on Windows, read the instructions on the git website and let me know if you have any questions. You will be able to download a shell program called Git Bash which will let you run all the commands that I'm going to reference here (if you're on Mac/Linux, you'll be able to run the commands from the terminal). Please don't run any git commands from the Windows command prompt - though this is possible, it's just bound to create more setup errors, so use Git Bash instead.
In order to pull all the files from the cloud for the first time, you'll need to "clone" our repository.
We're storing all the files that make members only work on Github (you can see them at https://github.com/calband/calchart), which means they're stored on a server somewhere that Github owns. In order to make changes to those files, you'll need to have them on your own computer. To do this, you need to copy the files from Github's server to your own computer. This is called "cloning the repo" because it takes every file that Github has on it's server and gives you a copy of it.
To clone the repo, get to whatever folder you'd like to put the files into via command line or Git Shell. If you're not familiar with the command line, use the commands pwd to print your current location, ls to list all the files and folders in this location, and cd to change to a specific folder: see here for more. Then run git clone https://github.com/calband/calchart.git (if you're on Mac, you should do this from Terminal. If you're on Windows, you should do this from Git Shell). This will pull all the files in the github repo into a folder called members-only.
For example, I keep the repo in a folder called programming/calband. Running git clone https://github.com/calband/calchart.git will put all the files into programming/calband/calchart.
You can also set up git to work over ssh rather than HTTPS. Check out the instructions on setting up git for more information - this is totally optional but recommended since you won't have to enter your github username and password each time.
In order to be able to push and pull from a git repository, you have to tell git where the repository is (ours is in the cloud on github). After you clone the repo, run the command git remote -v (be sure to run this inside the members-only folder). You should see something like this:
origin [email protected]:calband/calchart.git (fetch)
origin [email protected]:calband/calchart.git (push)
This means that git knows the specific places to pull (fetch) and push (push) your files to and from. Git calls these "places" remotes. Here, git knows that the origin remote means some server from github.com: [email protected]:calband/calchart.git. You can learn more about git remotes here, but you probably won't need much more than this.
Often times, when we have a few people working on one thing and a few people working on another, it gets to be a hassle to have to pull and merge every time someone wants to commit code.
For example, say I'm working on a fix to make the homepage look better. I'll probably have a lot of edits, but someone else might be editing the same files as me! This means that we might change the same line, and if this happens, then git has to figure out whose edits to actually put in. This is frustrating to do every time anyone edits the same files as you!
For this reason, we can create "branches" of our edit history, edit them to our hearts content, and merge them back together later.
Every git repo starts out with a master branch, and our goal at the end is to have one master branch with everything in it done and working. In the mean time, we might have branches such as noah__trip-signup__14 for coding the frontend/backend for signing up for away trips, or custom-tools for development work about adding custom tools. Each of these branches would be a little different than master, but they will have edit history in common with master - in fact, they will have "branched off" somewhere in the edit history of master.
- To make a new branch:
git branch noah__my_first_branch(this will create a new branch callednoah_my_first_branch) - To list all branches:
git branch - To switch to a branch
git checkout noah__my_first_branch
Please read this, this, this, and this about branching.
Now, say you have been totally rewriting the trip signup pages, and you're collaborating with a few other people on it. You might have a branch on github called trip-signup-master that would always have the most up to date (though not yet complete) trip signup code. After fixing a bug in your implementation you'd run git push origin trip-signup-master when you're done. Be careful not to push to master when you mean to push to another branch - it is not the end of the world, but it might create a lot of merge errors which will give me a headache.
After you've changed the files that you need to, you'll need to "commit" them so that the changes will be logged and so you can push them to the repository. A commit is basically a snapshot of how your files look and what kind of changes you've made. Having commits is good because you can look through all of your commit history and revert back to any past commit if you need to. In general, it's good to make small commits - implement one new feature, commit. Implement another one, commit. This helps you, and everyone else, see where and why any file got changed.
When your code works in your local environment, first run git status. This will show you the name of the branch you're on (more on branches later) and a list of changes that you've made so far. Make sure that everything looks okay. You can also run git diff to see an output of all your changes that stand to be added to a commit.
If all the changes look okay, run git add -A. This will add all the changes you've made to all the files to a commit (basically, this tells git what changes you've made and saves them so that you can restore them later if you need to). You'll notice that if you run git status again, the files will have a different label next to them.
Now you're ready to finish the commit. Run git commit -m "this is what i did and why i did it" to add a message and finalize the commit (replace the message in quotes with a short description of whatever you were working on - this will show up on github). After committing, you should see a message like this one:
[master d673c80] this is what i did and why i did it
1 file changed, 2 insertions(+), 2 deletions(-)
Now you're ready to push your changes to the remote repository on github so that everyone else will be able to see it. Before pushing, you should make sure you have the most current versions of all the other files in the repo. To do this, run git pull origin master (or replace master with whatever branch you're on; again, more on this later.) Hopefully there are no error messages (more on how to fix merge errors later). If not, run git push origin HEAD (you can replace HEAD with the name of the branch you're on - don't worry about this for now) to push all your changes to github. The push command should give you an output like this:
Delta compression using up to 4 threads.
Compressing objects: 100% (24/24), done.
Writing objects: 100% (24/24), 9.61 KiB, done.
Total 24 (delta 18), reused 0 (delta 0)
To [email protected]:calband/calchart.git
f4d7d40..d673c80 master -> master
Again, here's a list of what commands you should run when you're ready to push code to github:
git status
<make sure branch is right>
git add -A
git commit -m "<message>"
git pull origin <branch>
git push origin <branch>
And that's how you push a change to the members only repository.
Sometimes, two people will both be editing the same file at the same time, and git won't be able to tell which edits to keep and which edits to discard. This results in a "merge error" that looks something like this:
Auto-merging public/assets/manifest.yml
CONFLICT (add/add): Merge conflict in public/assets/manifest.yml
Auto-merging public/assets/application.js.gz
CONFLICT (add/add): Merge conflict in public/assets/application.js.gz
Auto-merging public/assets/application.js
CONFLICT (add/add): Merge conflict in public/assets/application.js
Auto-merging public/assets/application.css.gz
CONFLICT (add/add): Merge conflict in public/assets/application.css.gz
Auto-merging public/assets/application.css
Automatic merge failed; fix conflicts and then commit the result.
Don't be scared, all you have to do is take a look at each file that git lists a CONFLICT for. In those files, you'll see something like this:
>>>>>>>>>>>>>>>>> HEAD
something something blah blah blah …
=================
something else something else
<<<<<<<<<<<<<<<<< 8e637d62b1
Simply erase the =,<,> signs, change the file so that everything is how it should be (while making sure not to just delete everything else except what you did), and commit everything again. Note that how it should be does not just mean that you should erase everything which you changed - instead, you should look at what the affected code does and make sure you know that you're not undoing someone else's work before you're done.
If you need to know who committed some lines in order to ask them about it, check out git blame.
There are also programs that allow you to merge easily using a pretty interface. More about these here.
Git can be very confusing the first time you use it - I know that I had no idea what was going on when I tried to use it for the first time. This is bad! If you don't know what's going on at any time (or even if you have questions about this document), please ask! It's much better for you to pester me with questions (even if you think they're dumb questions) than to have people trying to work on a project who don't know how to use the tools.