Introduction to GitHub


Setup used: Mac OS X Mountain Lion 10.8, Xcode 4.5.1. The version of PhoneGap is not an issue in this article.

Xcode allows us to add source control to a project, such as online by using GitHub.com, or just publishing it locally. With source control on github.com, we could go backward and forward in time to various stages of code changes, and even create a new branch to test or create a different version of the project. That collection of a project’s files is called a repository. GitHub.com allows us to create public repositories (free) or private (paid monthly).

There are several helpful tutorials on how to start a GitHub repository (git repo) when starting a new Xcode 4 project, but I wanted to learn how to create a git repo from an existing Xcode 4 project where the repository option had not been checked when starting up.

Xcode already allows us to make a Snapshot of a project’s state and get back to it, but a GitHub repository has extra advantages of being able to share your code with others as well as store it offsite. I wanted to write about a how-to article on a recent project I worked on and make it available to everyone for download. It was a great time to try out GitHub.com. My final modest effort is seen here: https://github.com/iPhoneDevLog/fonts-bookmarks-notes 

The word “git,” by the way, is a word I picked up from reading the Harry Potter books, frequently uttered by Ron Weasley. It is British slang for an unpleasant, stupid, or contemptible person. Just trivia, folks! Git is a distributed revision control system designed by Linus Torvalds of Linux fame.

The source-control world comes with its own vocabulary, which we’ll try to learn as we go along. The basics are well spelled out here. Please take time to read it, for it gives you the definitions of important words we’ll use throughout this article. Git is so huge that one article can’t really do it justice; this article will focus on step-by-step instructions for setting up and basic housekeeping, and how to use Xcode with it. More information is provided in links at the end of this page.

Sign Up at GitHub.com

1. Sign up at GitHub.com and give yourself a sensible username as well as email and password. (This tutorial has to do with making an online repo; another option is to create a repo only on the desktop computer.) Choose a paid plan (to keep it private) or the free, open-source plan. Your username will be in the URL for your git site, and thus prepended to all your repos. Since this git has to do with iPhoneDevLog, it made sense to use that for my username. You can have only one git per email.
2. Click on New Repository.
3. Give the repo a name, no spaces (mine was “Font-Change-and-Bookmarks”).
4. Give a brief description. It will appear under your repo name in listings, and will also become a temporary README. We will create a substantial README file later.
5. Select the checkbox for “Initialize this repository with a README.”
6. Click on the drop-down for Add .gitignore and choose “Objective-C” if you are using Xcode. This creates a list of (unnecessary) files NOT to be added to the repository. We’ll learn more about the gitignore later when we create our own list.
7. Click on Create repository.
8. The next page shows you the public face of your git repo under the “Code” tab, “Files” sub-tab. Clicking on the Admin tab, you’ll see where you can change the repo name, and unselect Wikis and Issues checkboxes if you don’t think you’ll need or use them. Scroll down and you’ll see a “Delete this repository” button.
9. Click on your repository page to return. I clicked on a drop-down button at upper right (next to the Pull Request button) and selected Watching to receive all notifications. Notifications will appear at the upper left of the screen, to the right of “github.” A grayed-out dot means no notifications, natch.
10. To the right of the Clone button you’ll find a URL box. Tapping on SSH will give your SSH key. Mine was git@github.com:iPhoneDevLog/Font-Change-and-Bookmarks.git. Tapping on HTTP gives you the WWW location of the site. Mine was https://github.com/iPhoneDevLog/Font-Change-and-Bookmarks.git. Click to see the layout.

Set Up a Git Graphical User Interface Locally

1. I downloaded GitHub for Mac from here: http://mac.github.com/ to experiment with. It gives me a graphical user interface for managing files. There are other GUIs available for git.
2. “mac_GitHub for Mac 66.zip” was placed in my Downloads folder. Double-clicking on it unzipped it and produced the app file “GitHub” with a cute icon. I dragged it to my Applications folder.
3. After double-clicking on the icon, I was led through several steps to set up a free account accessible to the public (private accounts are monthly paid accounts).
4. I received a notice via email that a public SSH key was added to my account, which key was full of paired letters and digits separated by colons. I copied it to a safe place on a folder that is backed up regularly. (Not sure what I’m supposed to do with the key at this point.)
5. Opening the GitHub app, I went to GitHub > Install Command Line Utility, and it said it was set up at

usr/local/github

6. We’ll need to set up this path in Terminal so that succeeding git commands will work. (In other words, for those who don’t use Terminal, we’ll be issuing commands in the terminal window that are file names, and in those files are the actual commands to carry out. The terminal will need to know where those file names reside. For instance, if we begin with “add,” it’ll need to know where the file “add” is so it could follow the commands in it.) Open Terminal (click on the magnifying glass at upper right and type in Terminal to locate) and copy/paste the following line:

sudo pico /etc/paths

7. Enter your computer password to give permission to continue. (From now on, I won’t be telling you to enter your password; the message boxes informing you of this step will be obvious.)
8. Tap your keyboard’s Down Arrow key to a blank line and type in the following:

/usr/local/github

9. Hit Control-X to exit, then Y to save, then Return.

Create an Empty Repository Locally

In a nutshell, you will use “git add” to start “tracking” new files and also to “stage” changes to already tracked files, then “git status” to see what has been modified and “staged” and finally “git commit” to record your snapshot into your history and commit the files locally. You’ll use “git push” to copy the files to your online repo. This will be the basic workflow that you’ll use most of the time, and what we’ll be following next. The terms in quotes are all explained in the page I linked to among this article’s opening explanatory paragraphs.

Create a thorough readme file in rich text or plain text format explaining how to implement your project and save it as README.md in the root folder of your Xcode project’s folder. GitHub.com should respect all hard returns when it receives this file. For more on creating a README, see here.  README files are often written poorly. I wrote my README based on the excellent suggestions given here. More information about great READMEs are given here and here.

The following steps will put your files in the local repo, then with one command put all of them online. (You may choose to not put them online if you are the only person working on the project, and you’ll only have access to the files while at your computer.) In my first attempt, it was a mistake to do this because I included all the files in the Xcode PhoneGap project when I just wanted just six files to include. These steps assume you want all files in your repo.

If you do know which files you don’t want to include, then create a .gitignore file, and put it in your project’s root. Using * as a wildcard is acceptable. For instance, you’d open your favorite text editor, and type:

.DS_Store

and other filenames, one per line, then save it to the root folder as:

.gitignore

The prepended period makes it a hidden file. For more about gitignore, visit http://git-scm.com/docs/gitignore

I. Create an empty local repo
1. Drag your project’s folder to the Terminal icon to set the starting directory.
2. Now initialize it:

git init

Terminal: Initialized empty Git repository in /Users/Steve/Documents/PhoneGap_apps/Storage-Repo/.git/
This created a local empty git repo in your project folder: a hidden “git” folder.

II. Add files to the staging area
1. If you want git to track a file, you must add it to the staging area. This is key to being able to go back in time to get earlier versions of your files. Type in git add and the file name like this to start off:

git add README.md

This adds your README.md file to the staging area. The staging area, or staging index, holds all the files you will later commit to the repo. (It’s like adding groceries to your shopping cart at the checkout stand; after that, you load, or commit, to your car.)
2. Add any other files to the repo. Git does not automatically add your new or modified files. Each must be added in separately if you wish them to be added to the repo. If you want to add all the files to the staging area at once, use a period instead of the filename:

git add .

3. Check the status of the repo:

git status -s

Terminal result: I see an A to the left of all the files I added. Please note that you’ll do this every single time you want to update the repo. Every file you modified should be added to the staging area if you want the repo updated with it. If you modify a file later, it is not automatically added to a repo!
More about the status command here: http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository

III. Commit staged files to the repo
1. The following “commit” command is accompanied by a note within quotes to remind you of what the commit is all about and will accompany your commit. Read more about notes: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#how-to-make-a-commit

git commit -m “This is a note about my commit”

Terminal result: You’ll see a list of the files committed to the repo.
This added all your staged files to the local repo.
2. Check the status of the repo:

git status -s

IV. Push your local repo to GitHub.com
Again, use this step only if you are keeping an online repo on GitHub.com.

1. Type in the following command and then your HTTP address, with a space after “origin.” You’ll find it on your GitHub project’s page by clicking on “HTTP.” (in my earlier posting on this, I had the SSH address here – my bad!)

git remote add origin <your git address>

Don’t include the “<” and “>”. I received the error “-bash: syntax error near unexpected token `newline’ ” because I included them.

2. Type:

git push -u origin master

Have patience while this step executes.
This push command copied the repo from your local drive to online. It is now online and accessible by anyone if it’s a free account or privately as a paid account.
3. Go to your GitHub.com page, refresh, and view all your files!

Remove Unwanted Files

Unfortunately, because I had not made a gitignore file first, this added files I did not really want added to the repo. How to remove them? We use git rm. For more thorough coverage about removing files, and to understand the remove options following, see: http://git-scm.com/docs/git-rm
1. Drag your project’s folder to the Terminal icon to set the starting directory.
2. Look at your GitHub.com list of files. The .DS_Store file is not needed; this command force-removes it:

git rm -f .DS_Store

Terminal result: rm ‘.DS_Store’
This file is now in the staging area with a “modified” status.
3. Now commit it into the local repo. This command is accompanied by a note within quotes to remind you of what the commit is all about and will appear in GitHub.com:

git commit -m “Removing .DS_Store files”

Terminal tells you how many changes and insertions git made.
4. Now push it to GitHub.com to update it there too:

git push

Terminal tells you what git’s done.
5. Go to GitHub.com, hit refresh for the project page, and see the changes.

View Local Repo in Xcode (of project created via Xcode)

Xcode 4.5+ can view the local repo of projects produced by Xcode. The following info was adapted from Stack Overflow here).
1. In Xcode, open the project and click on the Organizer icon at top right.
2. Click on Repositories at top.
3. Click on the Remotes folder icon of your project at left. Click on Refresh at bottom if you have to.
4. Click on Add Remote at bottom.
5. For the Remote Name, copy/paste the repo name as it is in GitHub.com
6. For the Location, copy/paste the git@githumb.com/<username>/<repo name> from your GitHub.com project’s repo.
7. Click on the Create button.
8. You’ll be asked for your username and password. Fill those in.
9. If you click on your project’s repo name at left, you’ll see the different commits you’ve made, if any. During my many attempts at learning this, I saw several listed. If you click on the down arrow, you’ll see a listing of the actual files involved. Click on a file and a window will pop up showing the file (if it can read it).
10. Exit Organizer.

View Local Repo in GitHub app (of any git project)

1. Open the GitHub app downloaded earlier.
2. Drag the project folder from Finder into My Repositories. The repo appears.
3. Double-click on the repo or click on its right arrow. The breadcrumb trail at top now reads Repositories > <repo name> and the screen shows files that have lately been added or modified, but not committed.
4. Drag a file into your Finder window for the project and you’ll see the GitHub app screen change to indicate the “NEW” file. The files will be checked by default, which assumes you want them all included in the repo. Uncheck the ones you don’t want.
5. Open a file in the project folder and make a change, and save. The Github app window updates to list the file. Notice that “NEW” is not included for that file; it was only modified. If you click on that file, you may see at right what changes were made. I had added <!– –> to an HTML file, and that portion of the file was shown along with the lines above and below. The changed line was highlighted in pale green.
6. Write a Commit summary in the field of that name, and then click on Commit. The committed files disappear from the listing. If you do a status check in Terminal, you’ll find those files not listed either, but you’ll see the other staged files, if any, possibly with a ?? to the left of each filename showing that they were not yet added to the staging area.

Cliff’s Notes on Creating Succeeding Repos on Github

If you already have an account at GitHub, follow these steps for a new repo. They are all documented above.

1. Go to github.com and sign in.
2. At bottom right, click on “New repository.”
3. Fill out the fields for the new repository.
Note your address (like: https://github.com/iPhoneDevLog/fonts-bookmarks-notes.git)
4. Drag your local folder to the Terminal.
5. git init
6. git status -s
7. git add README.md
8. Use “git add ” to keep adding files or use “git add .” to add all new and changed files.
9. git commit -m “This is a note about the commit”
10. git remote add origin https://github.com/your-name/repo-name.git
11. git push -u origin master

Understanding “Fork me at GitHub!”

You’ll see a button with these words on a site once in a while. It is inviting you to go to GitHub.com and make a copy of the repo in your own GitHub repo area. Click on the Fork button. Now you have a copy of the repo in your own site on GitHub. However, you can’t actually work on it until it’s on your hard drive. So you click on Clone and it goes to your hard drive.

Please read this page about forking: https://help.github.com/articles/fork-a-repo

Cloning a Repo

This command copies the online repo to your hard drive so you can work on it.

1. Click on the GitHub.com Clone button of the site you want a local copy of.
2. “Allow” the program to operate.
2. Choose a location for the repo locally. I put mine in Documents/GitHub-forks
3. The GitHub app opens and you see your repo listed under the Repositories tab.
4. Click on the repo’s right arrow.
5. Click on History at left. You see a list of all the files.
6. Click on any right arrow button to view the file contents under the Commit tab.
7. Exit Github app and go to the folder where you cloned the files. You’ll see the files there, ready to open and modify. Remember, when you are finished, you’ll need to “add” the files to the staging area, “commit” them, then “push” them to the online version (if you want to update that version), steps II-IV above.

Understanding “Send a Pull Request”

If you have some ideas on how to modify someone’s else’s repo, and you ask the repo’s owner about it, he may tell you: “Send a Pull Request.” To do that, you would go to his GitHub page, fork and clone the repo, make and commit the changes, and click on his repo’s button for the Pull Request. Then he will review the changes.

For complete directions on this, please visit: https://help.github.com/articles/using-pull-requests and https://help.github.com/articles/creating-a-pull-request

Informative Git Sites

There is so much more to learn! Here are several sites I’ve found helpful during my training period:

http://www.vogella.com/articles/Git/article.html
http://git-scm.com/doc
http://gitref.org/
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
https://help.github.com/
http://www.mindthe.net/devices/2011/04/28/12-steps-to-using-github-with-xcode-4/
http://cheat.errtheblog.com/s/git/
http://alvinalexander.com/git/git-cheat-sheet-git-reference-commands
https://gist.github.com/

My Notes

Download Git Bash console program:
http://git-scm.com (Mac or PC – will auto-detect)
For Mac, downloads a .dmg file; open and double-click on the .pkg file.

Branching model:
http://nvie.com/posts/a-successful-git-branching-model/

Check installation (where it is stored) [$ = your command prompt in the console window – don’t type this!]
$ which git

Check version:
$ git –version

Go to directory:
$ cd D:\Git

Go backwards 1 directory:
$ cd ..

A colon at left on the console means there is more content. Type q to escape.

See directory listing [these are ells, not ones]:
ls -la [ls to list the directory, -la to show hidden files, like .git]
——————-
STORING CONFIGURATIONS

System-wide setting (the defaults are fine):
PC location (must start from this directory): Program Files/Git/etc/gitconfig
$ git config –system

User settings:
location: $HOME/.gitconfig
PC location: Documents and Settings/shusting
$ git config –global

Project (settings specific to a project):
location: my_project/.git/config
$ git config

More basic configurations:
$ git config –global user.name “name”
$ git config –global user.email “email”
$ git config –list
[result]
$ git config –global core.editor “notepad++.exe -wl1″
[above is: w L 1”]
$ git config –global color.ui true

———————-
First thing is to bring the git console to the project’s folder and type …
$ git init
… to get a git repo started on the hard drive. This tells Git to start tracking.
————————–

Helpful commands:
$ git help
$ git help <command>
$ q [to quit]
$ cat .gitconfig [look inside the file]
$ ls -la [list the files, including hidden files]

———————–
COMMITS

3-tree Architecture, moving from one to the other

Tree: “WORKING” (on hard drive)
Make changes to Working directory, then:
$ git add “note” file.txt [move to Staging Index with note, below]
$ git add . [add all files to Staging Index]
$ git add -am “note” [add and commit ALL working directory files to repo, skipping Staging Index. Not good for new and deleted files, only modifying files.]

Tree: “STAGING INDEX”
Can pick which of the files to send to Repo
$ git commit file.txt [1 file to Repo]
$ git commit -m “describe changes taking place here” [to Repo]

Tree: “REPO” (Git is now tracking these files)

————————
$ git status [tells us the status among the 3 trees]:
Will say what branch we are on
Will list any untracked files
Will give sample commands for what to do next
————————-

Writing Commit Messages

Single-line summary, <50 chars.
Optionally followed by a blank line and a more complete description if change is too complicated for 1 line.
Keep lines to <72 chars.
Use present tense. “UPDATE [html,js] Fixes a form bug that ….”
Use asterisks for bullet points.
Use ticket tracking numbers.
Use shorthand to indicate what kind of files were changed. “[css]”

Using Git Log to list things (and why it’s important to have thorough commit messages – to make them searchable by git.)
$ git log -n 5 [List the last 5 commits]
$ git log –since=2012-06-15 [List commits since that date.]
$ git log –until=2013-08-03 [List commits up to that date.]
$ git log –author “Steve” [List all commits with author of Steve.]
$ git log –grep=”init” [List all commits containing that string of chars.]
————————-
Referring to Commits

Checksums ensure the data in the commit set is the same (essential for data integrity).
Uses SHA-1 hash algorithm, a 40-char string.
It’s seen next to our commit line in the git log.

A commit set has:

SHA hash value at top
Parent (links to immediately prior SHA or commit)
Author
Commit Message

Navigating the Commit Tree: Referencing Commits
Tree-ish: something that references a part of the tree; it references a commit, and then to the tree. “-ish” because what that something is can vary widely:
.  Use full or short version of SHA-1 hash
.  Use head pointer
.  Branch reference, tag ref
.  Refer to that object’s ancestry: HEAD^, acf8723^, master^

A tree is a directory. A blob is a file.

$ git ls-tree HEAD [shows what files are in the HEAD. Current set of repo files.]
$ git ls-tree master www/ [shows commit of master]
$ git ls-tree master^ www/ [shows previous commit/state of master]
$ git ls-tree sha8q9qp4qg1gh1p5g12p5p5 [shows tree/directory’s contents]

————————
HEAD pointer

Points to next spot, or where last repo stopped; points to tip of current branch in repo. Like a playback-and-record head in a VCR. It points to the SHA of the last parent, for that will be put in the next repo’s SHA, referencing the last parent. It will point to where we will record next, so if we move the Head further back, it will overwrite from there.
Drill-down sequence:
$ ls -la [to see list. will see file named HEAD]
$ cat HEAD [will show file structure of HEAD]
$ cd refs [first folder of above structure.]
$ ls -la [to see list. Will see file named heads]
$ cd heads
$ ls -la [to see content list. will see file named master]
$ cat master [result will show 40-char SHA of the commit set]

————————-

Ignoring Files: using .gitignore

Use basic regular expr: * ? {aeiou] [0-9]
Negate expressions with !
Ignore all files in a directory with a trailing slash: assets/
Comment lines: # comment

Can create this file with the command line
$ nano .gitignore

Can globally ignore files so that file applies to all files on my machine.
1. Create the file and contents:
$ nano /Users/Me/.gitignore

2. Add the above to the config file:
git config –global core.excludesfile ~/.gitignore_global

Ignoring tracked files (deletes from the staging index, but not the working):
$ git rm –cached filename.html

Git ignores directories with no files. So create a hidden file with no content in it to track the directory:
touch directory/new-directory/.gitkeep
———————–
Git Log
$ git log to see what changes have been made.
$ git log –oneline [a terse presentation of the log]
$ git log –oneline -3 [limits list to last 3 commits]
$ git log –since=”2013-08-05″ [entries since that date. May use after instead of since]
$ git log –until=”2013-08-05″ [may use before instead of until]
$ git log –since=”2 weeks ago” –until=”today” [shows commits within time range]
$ git log –author=”Steve H”

Use GREP  [GREP = global regular expression]:
$ git log –grep=”TUT” [show lists with those chars]
$ git log -n 5 [to get 5 most recent logs]
$ git log aw4tq4t4.. index.html [show what happened to a file from a particular commit, using SHA.]
$ git show <SHA> [show the difference]
———————–
Comparing changed files in master and working trees:
$ git status
$ git diff
or
$ diff –color-words filename.txt

Comparing files in staged tree to repo:
$ git status
$ git diff –staged

$git diff <SHAa>..<SHAb> <filename.html> [show changes just to that file between those two SHAs]

$ git log –oneline
$ git diff –stat –summary <SHA>..HEAD [show summary of what’s changed]

———————-
Editing files

Deleting files from repo, 2 methods:
1.
Drag file from folder on hard drive to trash can.
$ git rm file-to-delete.txt
$ git commit -m “removed deleted file”
[this method will “save” the file in the trash can for later retrieval]
2.
$ git rm file-to-delete.txt
[this method will completely delete the file from your hard drive; no trash can]

Moving and renaming files
$ git mv file.txt new_folder/renamed_file.txt

———————
Undoing working directory changes

UNDO
Pulling a file out of Repo, switching from the one in Working
$ git checkout — index.html [the ” — ” means to stay in the same branch. useful in case a branch has the same name.]

Unstaging a file while keeping the working file
$ git reset HEAD filename.txt

Amending Commits
This is trickier because changing a commit means if changing the SHA, the snapshots after that would be affected, and this would affect data integrity. So, you can only make changes to the last commit.

$ git log [top of the listing is latest commit we could change]
Put changed files into the staging area, then:
$ git commit –amend -m “note changed”
Or do the above second step by itself if you just want to change the note of the commit.

To change earlier commits, one must make a copy of the version previous to the wrong commit and change and commit that. Steps:
$ git log
copy the SHA of the commit before the wrong file.
$ git checkout <SHA> — filename.txt
$ git status [moved above file into Staging Index]
$ git diff –staged [to see the revisions]
$ git reset HEAD filename.txt [puts it in working directory]
$ git commit -m “note about changed commit”

A faster way than above to revert a commit:
$ git log
copy the SHA of the commit of the prior(?) file
$ git revert <paste SHA here>
My text editor should mention the changes and make them, and give room for me to make a comment of my own about it.

————————-
BRANCHING

There is only one working directory. Git uses “Fast context switching” when going between branches, making the working directory match the branch.

$git branch [show all branches]
* master [* next to the branch name indicates the current checked-out branch. What your working directory matches.]
$ cat .git/HEAD [show current tip of branch, where the Head is now]
$ ls -la .git/refs/heads [show all branches listed]
$ cat .git/refs/heads/master [show SHA of current branch tip]

$ git branch UPDATE_Add_New_2013_Pix [create branch; no spaces or punctuation]
$ git branch [shows all branches, including new one made]
$ cat .git/HEAD [shows us the checked out branch]

$ git checkout branch-name [switch to named branch]
$ git checkout -b UPDATE_Add_2014_Pix [create new branch off of the current branch and switch to it]
$ git checkout — filename.html [– means checkout file in same branch, not checkout branch.]

2 thoughts on “Introduction to GitHub

  1. Reblogged this on Giacomo Balli and commented:
    Wish I found this when I first started!
    It makes it extremely easy and clear for everyone. Even though might not like they idea at first, you have to know how to use it.

Leave a reply to 650jesse Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.