Download & Install Git on your Machine
open up your Terminal / Console and type
git version
if this command is unknown, you have to install git
- Mac / Linux: most likely already installed
- All other operating systems: git-scm.com
Setup
If you're using git for the first time, you might want to setup some configuration settings:
git config --global user.name "Max Mustermann" git config --global user.email max@mustermann.de
These two settings help to identify you when you're pushing your files to a remote server.
Git can produce colorful output with some commands; since some people hate colors way more than the rest likes them, by default the colors are turned off. If you would like to have colors in your output:
git config --global color.diff auto git config --global color.status auto git config --global color.branch auto
Sometimes you have to enter messages in a terminal editor and the default may be vim or emacs. If you like to use another editor, there's this global option:
git config --global core.editor "nano"
These settings are global (for your machine), so you only need to do this once.
Create the Project Folder
Create or select your project folder, change to this dir in terminal and init git. This will create a ".git" folder inside your project. If you want to remove the git version control for whatever reason, you just need to delete this folder
cd ~/path/to/your/projectFolder
Now create a file. Either in your editor, or use the terminal:
touch README.md
We're creating a README textfile in the markup language. This file will be shown in most git servers as a starting page and should contain a general description, install and/or compiling instructions, contact and the license.
Init the Project Folder
Now, let's add git to our new folder:
git init
To check if this was successful you can query the status:
git status
This is acutally a command, you should remember!
Adding Files
The status should say something like this:
COMPUTERNAME:TestHub username$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# README.md
nothing added to commit but untracked files present (use "git add" to track)
So, the status is very useful, as it tells us everything: There's a file ("README.md") that is present in the directory, but not under git's version control. So we add it:
git add README.md
(Remember to use the TAB-Key for an autocompletion!)
Check again:
git status
All fine. If you have more files to add, you can use the wildcard operator * like this:
git add * git add *.m git add *.*
Change Stuff
Open REAMDE.md and type something.
Then use the terminal to check the status:
git status
And we should be informed, that the file was modified and we should commit our changes.
Let's do so:
Commit Changes
Commit early and commit often! Really, I mean that! And don't put in glibberish, make a useful comment about what you did:
git commit -a -m "initial commit"
This should be the result:
[master (root-commit) b109597] initial commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
now, check the status:
git status
and we should see a clean working directory:
# On branch master
nothing to commit (working directory clean)
Change Stuff (Again)
Repeat step 5 and change the README.md file.
Add a new file "LICENSE.md"
touch LICENSE.md
Then check the status again
git status
And you should see:
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README.md
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# LICENSE.md
Remembering git status really helps, as it basically tells you everything you have to do:
- Changes not staged for commit (so use: commit -a -m "Comment"!)
- Untracked files: use "git add <file>..." to include in what will be commited
btw, there's also:
git help git help commit
This explains the -a ("all files") and the -m ("message") parameters.
Exit help with ctrl+Z.
Commit (Again)
Commit early and commit often! Really, I mean that! And don't put in glibberish, make a useful comment about what you did:
git commit -a -m "Created License, Added welcome text to README"
Something like this should be the result:
[master bf50d31] Created License, Added welcome text to README
1 file changed, 7 insertions(+), 1 deletion(-)
now, check the status:
git status
and we should see a clean working directory:
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# LICENSE.md
oh, wait we didn't add the new LICENSE.md file:
git add * git commit -a -m "Added License" git status
okay, now it's a clean working directory.
# On branch master
nothing to commit (working directory clean)
btw, remember to use the Arrow UP and Arrow DOWN keys to jump in your terminal command history and reuse what you've typed before.
What's the diff?
Time for a cup of fresh coffee. Now you have a nice version control system for your project and you can work with git locally.
YAY!
So, to see the commits, use:
git log
and you'll see something like this:
commit a180dfb8aa6fc019fc2ed38a13ee4de517f8256a
Author: Max Mustermann <max@mustermann.de>
Date: Thu Apr 18 12:56:02 2013 +0200
Added License
commit bf50d31ecb17998dd45d462c9c2304a12dab3c1d
Author: Max Mustermann <max@mustermann.de>
Date: Thu Apr 18 12:53:30 2013 +0200
Created License, Added welcome text to README
commit b10959718cf43e5206ddbffc6b37ccc99726ee74
Author: Max Mustermann <max@mustermann.de>
Date: Thu Apr 18 12:44:09 2013 +0200
initial commit
Now you see why we wanted to set the name and email...
you can also try blame
git blame README.md
Now, change the REAMDE.md again and then see what's the difference to the previous version:
git diff
This will automatically show you the diff to the last commit:
diff --git a/README.md b/README.md
index d722c4c..2b1caa7 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
TestHub
-by BUW
+by Michael/BUW
-Hallo Welt!
+Hello World!
+This will be a cool project! Even cooler, because now I can use git.
GUI or not to GUI
Though, if you're not a nerd, you might enjoy a decent graphical user interface. Time to grab the GitHub.app
Drag your project folder onto the app.
With the GitHub.app, you experience a nicer commit history, including a file view with diff changes, you can admin branches, and configure your repository.
While we're still local, let's explore another really powerful git feature:
Branching
Adding another branch to your git repo is like duplicating the whole project folder (including the git commit history) and working on a second, completely different version. Like a real folder, you can delete this branch later on or (unlike a real folder) merge it with the current main branch.
So, this is perfect, if you want to test something or if you need to rearrange a lot of files and run in the danger of breaking your project.
Branches are simple and inexpensive, so don't hesitate to create new branches!
Let's see which branch we're currently working on:
git branch
and we see it's
* master
Create a new branch
git branch -b testing
you can also add -v to see the latest commit:
git branch -v
and we see:
* master a180dfb Added License
testing a180dfb Added License
So, we have our new branch, but the * indicates the active branch, which is still the master branch, let's change the branch with checkout:
git checkout testing
the reply is:
M README.md
Switched to branch 'testing'
Test again with
git branch
Now, we need to change a couple of things, for example, adding some files:
touch file1.txt touch file2.txt
Open a Finder or Explorer window and see, how the directory changes!
git status git add *.txt git commit -a -m "added file1 and file2" git status
if we call now:
git branch -v
we'll see the difference:
master a180dfb Added License
* testing 4aadefc added file1 and file2
But the real magic happens now, when we switch back to the master branch. Watch the directory!
git checkout master git checkout testing
nice, isn't it?
Now, you could either delete the branch if you think it was crap (using git branch -d testing or (and this is what we're going to do) merge this branch with the master branch. We need to switch to the main branch first, and then merge it with the testing branch:
git checkout master git merge testing
And see the result:
Updating a180dfb..4aadefc
Fast-forward
README.md | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
create mode 100644 file1.txt
create mode 100644 file2.txt
merging branches automatically commits, so we don't need to do anything:
git branch -v
if you like, you can delete the testing branch now:
git branch -d testing
Remember that up until this point, we were using git locally. Now, let's create an online repository to work with others
Using Remote Git Servers
You can extend your local git repository with an online git server. This has two advantages:
- If your computer or hard-disk is lost or damaged, you still have your online repository
- You can now collaborate with other people and work on the same files at the same time
There are a couple of online services:
- You set up your own git server (need to install git on your server and have webdav, ssh or other access to the server)
- You use one of the many online services, for example:
- github.com, free for open source projects
- bitbucket.com, free for small groups of up to 5 members
- please help adding more services here…
The following example shows how to create an account and a repository at github.com:
- go to github.com and create an account
- next, you need to create SSH Keys; this enables you to upload your files onto the server. You only have to do this once for every computer you're working on:
- This step is not part of this tutorial, but it's really simple, see:
- Generating SSH Keys
Creating an Online Repository
If you've uploaded your public SSH key for your machine, you can continue setting up your user account and finally, create a new repository:
- create a repository
- Add a repository name and a nice description (so that others know what this is about!)
- select "public" (free) or "private" (paid)
- For new repositories, you might select to "initialize this repository" and add a ".gitignore" file, for our example, do not check this
Now we see the commands we need to add. Most of them are already done, we just need to add the remote server and push our repository to the server (that means uploading the files)
Note the (probably) 5th and 6th line saying:
git remote add origin https://github.com/NameOfUserOrOrganization/NameOfTheRepository.git git push -u origin master
So, let's add the remote origin (btw, this will also work via ssh)
git remote add origin ssh://myserver.com
Push Changes to the Server
Pushing Changes, means uploading to the server. Because you can have more than one remote server in your repository, you have to state its name:
git push -u origin master
You are probably promted to give your github username and password for the first push.
The result should look like this:
Counting objects: 12, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (12/12), 1.08 KiB, done.
Total 12 (delta 0), reused 0 (delta 0)
To https://github.com/NameOfUserOrOrganization/NameOfTheRepository.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
Changing Stuff (Again)
This time, we want to simulate someone else changing our sources. The easiest way for this demo, is to go to github.com and edit the Readme file. E.g. apply some formatting ('#' creates a headline), and give it a commit message.
Pull or Fetch and Merge
Git has two commands to update itself from a remote repository:
git fetch git merge
will synchronize you with another repo, pulling down any data that you do not have locally and giving you bookmarks to where each branch on that remote was when you synchronized. These are called "remote branches" and are identical to local branches except that Git will not allow you to check them out - however, you can merge from them, diff them to other branches, run history logs on them, etc. You do all of that stuff locally after you synchronize.
The second command that will fetch down new data from a remote server is
git pull
This command will basically run a git fetch immediately followed by a git merge of the branch on that remote that is tracked by whatever branch you are currently in. Running the fetch and merge commands separately involves less magic and less problems.
You should see this reply:
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/NameOfUserOrOrganization/NameOfTheRepository.git
4aadefc..aca593b master -> origin/master
Updating 4aadefc..aca593b
Fast-forward
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
If you like, you can repeat this with fetch & merge instead of pull. First, edit the README.md again or select a LICENSE.md. Then type:
git fetch
The result is the same as before, only without the Updating... / Fast-forward part
git status
...however, reveals that our local branch is one commit behind:
# On branch master
# Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
#
nothing to commit (working directory clean)
git merge origin/master
and now the result is:
Updating aca593b..e2c12f6
Fast-forward
LICENSE.md | 1 +
1 file changed, 1 insertion(+)
and git status sais:
# On branch master
nothing to commit (working directory clean)
IDE Integration
While it's important to understand git, it's really not necessary to work with the terminal. Many IDEs have excellent version control support. For example Xcode, Coda or Sublime2 (via Plugin) have really nice GUI based git/svn integrations.
Where to go from here
- back to the main intro with links and books: git
- to the official Git Reference @ gitref.org