Introduction To

Rejah Rehim

What is Git?

Open-source code management tool

Created by Linus Torvalds when he was building the Linux kernel.

Git is DSCS (Distributed Source Control System)

Git allows you to work on your code with the peace of mind that everything you do is reversible.

Why should i use git?



Git allows and encourages you to have multiple local branches that can be entirely independent of each other. 

Frictionless Context Switching - Create a branch to try out an idea, commit a few times, switch back to where you branched from.

Feature Based Work-flowCreate new branches for each new feature you're working on so you can seamlessly switch back and forth between them, then delete each branch when that feature gets merged into your main line.

Disposable Experimentation - Create a branch to experiment in, realize it's not going to work, and just delete it - abandoning the work


    init benchmarks init benchmarks init benchmarks init benchmarks init benchmarks init benchmarks
    init benchmarks init benchmarks init benchmarks init benchmarks init benchmarks init benchmarks


    This means that even if you're using a centralized work-flow, every user essentially has a full backup of the main server. Each of these copies could be pushed up to replace the main server in the event of a crash or corruption. In effect, there is no single point of failure with Git unless there is only a single copy of the repository.

    Staging Area

    • Unlike the other systems, Git has something called the "staging area" or "index". This is an intermediate area where commits can be formatted and reviewed before completing the commit.
    •  It's possible to quickly stage some of your files and commit them without committing all of the other modified files in your working directory

      GIT is new standard

      PHP (decided to migrate to Git)
      Many more...

      Install Git



      Linux (Debian Based)

      $ sudo apt-get install git-core 


      Setup Name and Email

      Run the following commands so that git knows 
      • - your name
      • - your email

      $ git config --global "Your Name"
      $ git config --global "" 

      Setup Line Ending Preferences

       Unix/Mac users:

      git config --global core.autocrlf input
      git config --global core.safecrlf true
       Windows users:

      git config --global core.autocrlf true
      git config --global core.safecrlf true 

      SetUp Editor & Diff tool

      $ git config --global core.editor emacs

      Another useful option you may want to configure is the default diff tool to use to resolve merge conflicts. 

      $ git config --global merge.tool vimdiff


      Create the Repository

      $ git init 
      Initialized empty Git repository in /Users/rejah/working/directory/.git/

      Clone a Repository

      $  git clone
      Cloning into 'testing'...
      remote: Counting objects: 21, done.
      remote: Compressing objects: 100% (17/17), done.
      remote: Total 21 (delta 2), reused 0 (delta 0)
      Receiving objects: 100% (21/21), 2.50 MiB, done.
      Resolving deltas: 100% (2/2), done

      Add the program to the repository

      $ git add hello.php
      $ git commit -m "First Commit"
      [master (root-commit) 9416416] First Commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 hello.php

      Check the status of the repository

      git status  to check the current status of the repo.

      $ git status
      # On branch master
      nothing to commit (working directory clean) 
      $ git status
      # On branch master
      # Changes not staged for commit:
      #   (use "git add ..." to update what will be committed)
      #   (use "git checkout -- ..." to discard changes in working directory)
      #	modified:   hello.php
      no changes added to commit (use "git add" and/or "git commit -a") 

      Staging Changes

      $ git add hello.php
      $ git status
      # On branch master
      # Changes to be committed:
      #   (use "git reset HEAD ..." to unstage)
      #	modified:   hello.php

      The change to the hello.php file has been staged. This means that git now knows about the change, but the change hasn’t been permanently recorded in the repository yet. The next commit operation will include the staged changes. If you decide you don’t want to commit that change after all, the status command reminds you that the  git reset command can be used to unstage that change.

      Staging and Committing

      Suppose you edited three files (a.php, b.php, and c.php). Now you want to commit all the changes, but you want the changes in a.php and b.php to be a single commit, while the changes to c.php are not logically related to the first two files and should be a separate commit.

      git add a.php
      git add b.php
      git commit -m "Changes for a and b"
      git add c.php
      git commit -m "Unrelated change to c" 

      By separating staging and committing, you have the ability to easily fine tune what goes into each commit.

      Committing Changes

      git commit 
      You should see the following in your default editor:
      # Please enter the commit message for your changes. Lines starting
      # with '#' will be ignored, and an empty message aborts the commit.
      # On branch master
      # Changes to be committed:
      #   (use "git reset HEAD ..." to unstage)
      #	modified:   hello.php
      On the first line, enter the comment: “Test Commit”. Save the file and exit the editor.
      Provide Commit message

      git commit -m "Test Commit"

      better commit message

      • The first line should always be 50 characters or less and that it should be followed by a blank line.
      • Never use the -m <msg> / --message=<msg> flag to   git commit
      • Consider making including a link to the issue/story/card in the commit message a standard for your project. Full urls are more useful than issue numbers, as they are more permanent and avoid confusion over which issue tracker it references.

      Answer the following questions:

      Why is this change necessary?

      This question tells reviewers what to expect in the commit, allowing them to more easily identify and point out unrelated changes.

      How does it address the issue?

      Describe, at a high level, what was done to affect change. “Validated X condition” or
      “Remove <troublesome module X>, which was causing <specific description of issue introduced by gem>” are good examples.

      What side effects does this change have?

      This is the most important question to answer, as it can point out problems where you are making too many changes in one commit or branch. One or two bullet points for related changes may be okay, but five or six are likely indicators of a commit that is doing too many things.

      A more useful commit message might be:

      Redirect user to the requested page after login users where being redirected to the home page after login, which is less useful than redirecting to the page they had originally requested.before being redirected to the login form.* Store requested path in a session variable* Redirect to the stored location after successfully logging in the user


      Getting a listing of what changes have been made is the function of the git log command.

      $ git log
      commit 1f7ec5eaa8f37c2770dae3b984c55a1531fcc9e7
      Author: Rejah 
      Date:   Sat Apr 13 15:20:42 2013 -0400
          Added a comment
      commit 582495ae59ca91bca156a3372a72f88f6261698b
      Author: Rejah 
      Date:   Sat Apr 13 15:20:42 2013 -0400
          Added a default value

      One Line Histories

      $ git log --pretty=oneline
      1f7ec5eaa8f37c2770dae3b984c55a1531fcc9e7 Added a comment
      582495ae59ca91bca156a3372a72f88f6261698b Added a default value
      323e28d99a07d404c04f27eb6e415d4b8ab1d615 Using ARGV
      94164160adf8faa3119b409fcfcd13d0a0eb8020 First Commit

      Controlling Which Entries are Displayed

      You have a great deal of control over exactly what the log command displays.

      git log --pretty=oneline --max-count=2
      git log --pretty=oneline --since='5 minutes ago'
      git log --pretty=oneline --until='5 minutes ago'
      git log --pretty=oneline --author=
      git log --pretty=oneline --all 

      Getting Old Versions

      $ git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short
      * 1f7ec5e 2013-09-13 | Added a comment (HEAD, master) [Rejah]
      * 582495a 2013-09-13 | Added a default value [Rejah]
      * 323e28d 2013-09-13 | Using ARGV [Rejah]
      * 9416416 2013-09-13 | First Commit [Rejah] 
      $ git checkout 9416416
      Note: checking out '9416416'.
      You are in 'detached HEAD' state. You can look around, make experimental
      changes and commit them, and you can discard any commits you make in this
      state without impacting any branches by performing another checkout.
      If you want to create a new branch to retain commits you create, you may
      do so (now or later) by using -b with the checkout command again. Example:
        git checkout -b new_branch_name
      HEAD is now at 9416416... First Commit 

      Return the latest version in the master branch

      $ git checkout master
      Previous HEAD position was 9416416... First Commit
      Switched to branch 'master' 


      Tagging versions

      $ git tag v1 

      Now you can refer to the current version of the program as v1.

      Checking Out by Tag Name

      $ git checkout v1
      Previous HEAD position was 582495a... Added a default value
      HEAD is now at 1f7ec5e... Added a comment
      $ git checkout v1-beta
      Previous HEAD position was 1f7ec5e... Added a comment
      HEAD is now at 582495a... Added a default value

      Viewing Tags using the tag command

      $ git tag

      Viewing Tags in the Logs

      $ git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short master --all 
      * 1f7ec5e 2013-04-13 | Added a comment (v1, master) [Jim Weirich]
      * 582495a 2013-04-13 | Added a default value (HEAD, v1-beta) [Jim Weirich] * 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
      * 9416416 2013-04-13 | First Commit [Jim Weirich]

      Removing tag

      $ git tag -d oops
      Deleted tag 'oops' (was a10293f)



      Local Changes (before staging)

      Sometimes you have modified a file in your local working directory and you wish to just revert to what has already been committed. The checkout command will handle that.

      git checkout hello.php
      git status
      vim hello.php 

      Staged Changes (before committing)

      $ git reset HEAD hello.php
      Unstaged changes after reset:
      M	hello.php

      The reset command resets the staging area to be whatever is in HEAD. This clears the staging area of the change we just staged.

      The reset command (by default) doesn’t change the working directory. So the working directory still has the unwanted code in it.

      We can use the checkout command to remove the unwanted change from the working directory.

      Undoing Committed Changes

       Change that you have already committed was not correct and you wish to undo that commit.

      $ git revert HEAD --no-edit 
      [master a10293f] Revert "Oops, we didn't want this commit" 1 files changed, 1 insertions(+), 1 deletions(-)

      Since we were undoing the very last commit we made, we were able to use HEAD as the argument . We can revert any arbitrary commit earlier in history by simply specifying its hash value.

      Note: The --no-edit in the output can be ignored. used to generate the output without opening the editor.
      $ git reset --hard v1
      HEAD is now at 1f7ec5e Added a comment
      $ git hist
      * 1f7ec5e 2013-04-13 | Added a comment (HEAD, master) [Rejah]
      * 582495a 2013-04-13 | Added a default value (v1-beta) [Rejah]

      Amending Commits

      After you make the commit, you realize that any good author comment should have an email included. Update the hello program to include an email.

      git add hello.php
      git commit --amend -m "Add an author/email comment" 


      Create a Branch

      $ git checkout -b greet
      $ git status 

            git checkout -b <branchname>  is  a  shortcut for git branch <branchname> followed by a git checkout <branchname>.

      Notice that the git status command reports that you are on the ‘greet’ branch.

      Navigating Branches

      $ git checkout master
      Switched to branch 'master'

      Merge the branches

      $ git merge master 
      Merge made by recursive. README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
      create mode 100644 README


      Resolving Conflicts

      $ git checkout newbranch
      Switched to branch 'newbranch'
      $ git merge master
      Auto-merging lib/hello.php
      CONFLICT (content): Merge conflict in lib/hello.php
      Automatic merge failed; fix conflicts and then commit the result.

      If you open lib/hello.php, you will see:

      <<<<<<< HEAD:mergetest 
      This is my third line
      ======= This is a fourth line I am adding
      >>>>>>> 4e2b407f501b68f8588aa645acafffa0224b9b78:mergetest

      <<<<<<<: Indicates the start of the lines that had a merge conflict. The first set of lines are the lines from the file that you were trying to merge the changes into.

      =======: Indicates the break point used for comparison. Breaks up changes that user has committed (above) to changes coming from merge (below) to visually see the differences.

      >>>>>>>: Indicates the end of the lines that had a merge conflict.

      How do I resolve a merge conflict in a file?

      You resolve a conflict by editing the file to manually merge the parts of the file that git had trouble merging. 

      This may mean discarding either your changes or someone else's or doing a mix of the two.

      You will also need to delete the '<<<<<<<', '=======', and '>>>>>>>' in the file.

      What do I do after I've resolved conflicts in all affected files?

      Commit the Conflict Resolution

      git add the file(s)

      $ git  add -A 

      git commit and git push (Push only for branches tracked.)

      $git commit -m "Resolve Conflict in merge A and B" 
      $git push

      Using an external merge tool

      $ apt-get install  meld$ git config --global merge.tool meld




      What is Origin?

      $ git remote
      We see that the cloned repository knows about a remote repository
      $ git remote show origin
      * remote origin
      Fetch URL:
      Push URL:
      HEAD branch: master
      Remote branch:
      master tracked
      Local branch configured for 'git pull':
      master merges with remote master
      Local ref configured for 'git push':
      master pushes to master (up to date)

      What is Origin?

      Now we see that the remote repository “origin” is simply the original central repository. 

       Remote repositories typically live on a separate machine, possibly a centralized server.

      There is nothing particularly special about the name “origin”, however the convention is to use the name “origin” for the primary centralized repository (if there is one).

      Remote Branches

      $ git branch 
      * master

      That’s it, only the master branch is listed.
       The git branch command only lists the local branches by default.

      $ git branch -a
      * master
        remotes/origin/HEAD -> origin/master
      Git has all the commits from the original repository, but branches in the remote repository are not treated as local branches here. If we want our own , we need to create it ourselves.

      Working With Remote

      Adding a Remote Repository

      Let’s add the testing.git repo to our original repo.

      git remote add 

      Add a local branch that tracks a remote branch

      $ git branch --track newbranch origin/greet
      Branch newbranch set up to track remote branch newbranch from origin.
      $ git branch -a
      * master
        remotes/origin/HEAD -> origin/master
      We can now see the greet branch in the branch list and in the log.

      Fetching Changes

      $ git fetch
      From /Users/jim/working/git/git_immersion/auto/hello 2fae0b2..2e4c559 master -> origin/master
      The “git fetch” command will fetch new commits from the remote repository, but it will not merge these commits into the local branches.

      Merging Pulled Changes

      $ git merge origin/master 
      Updating 2fae0b2..2e4c559 Fast-forward README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)

      Pushing a Change

      $ git push origin master
      To 2e4c559..3923dd5  master -> master
      origin is the name of the repository receiving the changes we are pushing. (Remember, we added it as a remote)

      Pulling Change

      We’re not going to go through the process of creating another change and pulling it again, but we do want you to know that doing:

      $ git pull origin master

      is indeed equivalent to the two steps:

      $ git fetch
      $ git merge origin/master 

      Migrating from Svn to Git


       Clone the SVN repository to Git

      git svn clone [SVN repo URL] 

      Mirror from SVN to Git

      After the migration was complete, we set up a script to mirror every commit to SVN into Git


      Learn Git Branching

      Try Git



      Made with