Introduction to GIT

Omair Sajid

This work is a derivate of Pro Git book by Scott Chacon and Ben Straub and published by Apress. All content is licensed under the Creative Commons Attribution Non Commercial Share Alike 3.0 license.

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

Everything is local

Setup

Git Config

User 'git config' to set/get config properties.

Git Config (initial setup)

Git Config (Check your settigns)

Getting help

Getting a git repository (Excersie 1)

Recording Changes to the Repository

The Three stages

A git project has three main sections. Git directory, the working directory, and the staging area.

Checking the Status of Your Files

Adding new files (1)

Adding new files (2)

Staging Modified files (1)

Staging Modified files (2)

Staging Modified files (3)

Staging Modified files (4)

Viewing Your Staged and Unstaged Changes (1)

Viewing Your Staged and Unstaged Changes (2)

Committing Your Changes (1)

Committing Your Changes (2)

Committing Your Changes (3) - Exercise 2

Undoing Things (1)

Undoing Things (2)

Working with Remotes

Working with Remotes (1)

Working with Remotes (2) - Exercise 3

Listing remotes

$ git remote
Adding remotes
$ git remote add <name> <path-to-repo>
Deleting remotes
$ git remote rm <path-to-repo>

Git Branching

Git Branching (1)

Conceptually, a single commit looks something like.


Git Branching (2)

After couple of commits.


Git Branching (3)

A branch is simple a pointer to one of these commits.


A branch in Git is in actuality a simple file that contains the 40 character SHA-1 checksum of the commit it points to, branches are cheap to create and destroy. Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline).

Git Branching (4)

Creating a new branch creates a new pointer at the same commit you're currently on.


$ git branch testing 

Git Branching (5)

To keep track of branch we are currently on. Git uses a special pointer called HEAD (The git branch command only created a new branch — it didn’t switch to that branch )


Git Branching (6)

To switch to an existing branch, you run the git checkout command


$ git checkout testing 

Git Branching (7)

Let's do a commit

 $ vim test.rb
 $ git commit -a -m 'made a change'

Notice that only testing branch (pointer) has move forward. But master branch still points to the commit you were on when you ran git checkout to switch branches.

Git Branching (8)

Now switching to master branch will move the HEAD pointer to master branch, and will revert files in working directory to the snapshot master poitns to.

$ git checkout master

Git Branching (9) - Exercise 4

Doing another commit now will move master branch forward

$ vim test.rb 
$ git add test.rb 
$ git commit -m "...."

Merging

Merging (1)

Consider a repository with three branches as in figure below


Merging (2)

Fast Forward Merge: Let's first merge hotfix into master

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast forward
README |    1 -
1 files changed, 0 insertions(+), 1 deletions(-)

Merging (3)

As hotfix branch is merged into master so we will get rid of hotfix branch now

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).

Merging (4)

Continue work on iss53 branch

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m ’finished the new footer [issue 53]’
[iss53]: created ad82d7a: "finished the new footer [issue 53]"
 1 files changed, 1 insertions(+), 0 deletions(-)

Merging (5)

Three-way merge: Time to merge iss53 into master

$ git checkout master
[master *]$ git merge iss53
Merge made by recursive.
 README |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

Merging (6) - Exercise 5

Git automatically identifies the best common-ancestor merge base for branch merging. It then creates a new snapshot by doing a three-way merge and automatically creates a new commit that points to it. This is referred to as a merge commit and is special in that it has more than one parent.

Merge Conflicts

Merge Conflicts (1)

Occasionally, this process doesn’t go smoothly. Git will not always be able to merge files cleanly. E.g. If our fix for issue #53 modified the same part of a file as the hotfix, we’ll get a merge conflict that looks something like this:

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Running git status now will show us somthing like

[master*]$ git status
index.html: needs merge
# On branch master
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
# unmerged:   index.html

Merge Conflicts (2)

We can now open the file and resolve conflicts. File with conflicts will contain section that will look something like

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
  please contact us at support@github.com
</div>
>>>>>>> ss53:index.html

Merge Conflicts (3)

How we resolve conflict is upsto us. We can choese either side or merge the contents from both. E.g. in this case we can resolve conflict as


<div id="footer">
  please contact us at email.support@github.com
</div>

After resolving conflict use git add to add file to staging area and then commit code to complete merge prcess.

Managing Branches

Managing Branches (1)

To create new branch

$ git branch testing
$ git checkout testing

Or use shortcut to create and switch to new branch with one command

$ git checkout -b testing

To list branches (* indicates current branch)

$ git branch
  iss53
* master
  testing

To delete a branch

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).

Managing Branches (2)

To view list of branches that have been merged into current branch. Branches without * have already been merged into current branch and can be safely deleted.

$ git branch --merged
  iss53
* master

To see all the branches that contain work you haven’t yet merged in

$ git branch --no-merged
  testing

Trying to delete this branch will give error. In case you want to force deletion then use -D instead of -d

$ git branch -d testing
error: The branch ’testing’ is not an ancestor of your current HEAD.

Managing Branches (3)

To push branch to remote server. (This will push local serverfix and create a new serverfix branch on remote server.)

$ git push origin serverfix:serverfix
Counting objects: 20, done.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 1.74 KiB, done.
Total 15 (delta 5), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new branch]      serverfix -> serverfix

To push branch with a different name (This will push local serverfix branch as remote newname branch)

$ git push origin serverfix:newname

Managing Branches (4)

Pulling a new branch from server is two step process.

$ git fetch origin
remote: Counting objects: 20, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (15/15), done.
From git@github.com:schacon/simplegit
 * [new branch]      serverfix    -> origin/serverfix

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"

Managing Branches (5) - Exercise 6

To delete a remote branch.

$ git push origin :serverfix
To git@github.com:schacon/simplegit.git
 - [deleted]         serverfix

Recall that to create new branch we used git push [remotename] [localbranch]:[remotebranch]. For deleting remote branch we are leaving out local branch name. This is similar to saying take nothing from local repo and push to remote.

Tagging

Tagging (1)

Tags are simple pointers to commits, and they are incredibly useful for bookmarking important revisions like releases. The git tag command can be used to create a new tag

$ git tag -a v1.0 -m "Stable release"

and to list existing tags use

$ git tag

Tagging (2)

Git also lets you use git checkout with tags and commit IDs, but doing so puts you in a detached HEAD state. This means that you’re not on a branch anymore—you’re directly viewing a commit. This means that you’ll lose all your work as soon as you switch back to a real branch. To create a new branch in a detached HEAD state:

$ git checkout -b <new-branch-name>

After this we will have a new branch reference pointing to formerly detached HEAD

Some of the topics not covered

Branching Strategy

Thank you!