Wednesday, February 8, 2012

Finally Understanding Git

So, I've finally decided to step through examples and figure this versioning software out. I've used it quite a bit, but it is about time for me to really understand what is going on. I'm going to mess around with a test repository and show examples in this post. I'll modify this as it I go.

Starting a Repository


git init

Initializes a git repository – creates the initial ‘.git’ directory in a new or in an existing project.

Toggle Example

The hidden .git folder contains the repository information. By default starts on the master branch.

git clone [url] [destination]

Retrieves a remote repository from a specified URL. This is usually from github unless you have created your own git server. Also specifies remote inside the git config as that URL, so you can push and fetch as needed.

Toggle Example

Toggle Notes

Preparing next commit


git add [files]

Add the specified files to the 'stage,' or essentially 'what you are specifying to be added to the next commit.' This should be done before each commit, or it'll say 'Nothing to commit.' Which is bad. You can specify with * to add everything in the current directory. You're actually adding to the 'index' file here.

Below we see there are unchanged files that haven't been staged yet, so we do so using git add *

Toggle Example

Toggle Notes

Submitting next commit


git commit -m "message"

Commits all currently staged files to the local repository. No commits are reflected on remote repository until git push is called.
Below we pick up from the git add example and commit (get a snapshot of) the staged modified files using the command. Usually messages are added to report the changes made, and are pretty helpful.

Toggle Example

Toggle Notes

Getting Information


git status

Shows you what branch you are currently on, which files have been modified and which are currently staged (ready to commit). GIT's explanation is pretty awesome

"Displays paths that have differences between the index file and the current HEAD commit, paths that have differences between the working tree and the index file, and paths in the working tree that are not tracked by git (and are not ignored by gitignore). The first are what you would commit by running git commit; the second and third are what you could commit by running git add before running git commit."

Toggle Example

git config user.name

Reports the currently configured user name. Set with git config --global user.name "[name]"

git config user.email

Reports the currently configured user email. Set with git config --global user.email email@myemail.net Both of these options are important to set so git and other people know who commited what.

Branch Management


git branch

Lists the current branches in the local repository.A '*' notates the current branch.

Toggle Example
Toggle Notes

git checkout [branch]

Switch current working branch. This will swap the files to match the specified branch.

Toggle Example

Modify Current State


The best source of information for me was at [2]. I will try and give an informal description of them but it was best for me to just actually try them out in a test repository so I knew exactly what they did.

git fetch

Fetches changes from a remote repository. The new files and changes found in the remote repository aren't applied to your current working directory just yet. This function only updates the references to the remote branches on your computer. This is the safe way to bring changes your computer, followed by a git merge. This is helpful for when you want to see the changes on the remote branch before changing your working files.

Toggle Example

Toggle Notes

git merge [branch]

Merges changes from one branch into current branch.

Toggle Example

git pull [branch]

Performs a git fetch followed by a git merge. This is considered a bit more risky than doing fetch and merge separately as the changes are dones automatically. Refer to [2]

Toggle Example

git reset [commit]

Resets current working state to the specified commit. If you specify --hard it will reset state completely and your modified files cannot be recovered, so be careful.

Toggle Notes

Toggle Example

git stash

Store any changes you've made since the last commit. Can be restored with 'git stash apply.' Useful if you've made changes and have found a bug, but you dont want the bugfix under current commit. So you git stash, switch branch/commit fix the bug, commit wherever, and then stash apply and you're back!

Toggle Example

SSH Keys and GitHUB


This is a part of github that I always have trouble with in the past, so I figured it was worth noting here. I'm essentially following the guide found here [3] but maybe I can provide some insight to a few of the problems.

If you don't have a SSH Key Pair


[~]: cd ~/.ssh
[~/.ssh]: ls
known_hosts

We're looking for two files 'id_rsa' and 'id_rsa.pub' are the common names for them. So lets generate them so github can communicate with our computer and know its us.

[~/.ssh]: ssh-keygen -t rsa -C "your@email.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/mojavestorm/.ssh/id_rsa):

We generate a key pair given out email. Hit enter to use the default file name

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Using a passphrase is apparently pretty important. It just prevents anyone who simply has access to your computer to access your ssh keys. I forget these all the time, so write it down (bad) or make it easy to remember.

Your identification has been saved in /Users/mojavestorm/.ssh/id_rsa.
Your public key has been saved in /Users/mojavestorm/.ssh/id_rsa.pub.
The key fingerprint is:
dd:5b:c2:b6:ba:54:84:7e:d9:d2:4b:cb:bf:f9:16:8c your@email.com
The key's randomart image is:
+--[ RSA 2048]----+
| |
| . |
| . . |
| o + + |
| S o X B |
| + E = |
| . o + .|
| . . .o|
| o. +=|
+-----------------+

Just some random art that is related to the key itself, but your keys are generated! On to the next step.

Giving Github Your Public Key


If github has your public key, it'll be able to communicate with your computer and its private key. It's pretty simple. Currently, under your account settings at github.com which can be found in the top right menu on your home page, you'll see a link named SSH Public Keys in the bottom right.

Here you can add another public key and specify which computer this public key belongs to. So I'd name mine "MojaveStormWork" and then copy the contents of id_rsa.pub into the box github provides. You can simply open up the contents of id_rsa.pub in your favorite text editor and copy/paste.

To test out this connection:

[~/.ssh]: ssh -T git@github.com
Identity added: /Users/mojavestorm/.ssh/id_rsa (/Users/mojavestorm/.ssh/id_rsa)
Hi mojavestorm! You've successfully authenticated, but GitHub does not provide shell access.

You'll get this message after you've typed your password and if everything is correct! You're good to go.


Completing Tasks


Here I'm just going to go through some certain tasks that I've run into and how to accomplish them. Pretty much will mostly be explained via example with a link providing where I found the solution if applicable.

Managing .gitignore


.gitignore is a file which specifies which files the repository will ignore. You can specify specific files, directory, or use wild cards.

An interesting behavior I found was that if a file is already being tracked by the repo, .gitignore won't remove it. You have to do the following

Toggle Notes

Then once it is in your .gitignore, you won't have to worry about it anymore.

[Links]
[1] A Tale of Three Trees
[2] git: Fetch and Merge, Don't Pull
[3] Set Up Git
[4] 'git add -p'
[5] Git Cheatsheet
[6] Git - Google Tech Talk

No comments: