Git

A short introduction with some pictures

Git...

  • Distributed Source Control System (DSCS).
  • Open Source code management tool.
  • Initially designed and developed by Linus Tovals for Linux kernel (2005). 
  • Emphasis on speed, data integrity, and support for distributed, non-linear workflows.

Distributed means...

... there is no centralized repository.

Things to know for better understanding Git...

The spaces...

The spaces...

Remote

Local

The spaces...

Remote

Local

Upstream

Repository

Local

Repository

...

The spaces...

Remote

Local

Upstream

Repository

Local

Repository

Workspace

...

...

The spaces...

Remote

Local

Upstream

Repository

Local

Repository

Index

(Staging)

Workspace

...

The spaces...

Remote

Local

Upstream

Repository

Local

Repository

Index

(Staging)

Workspace

Stash

Files lifecycle...

Branches !!! 

We always work with branches and put some marks, so called tags.

HEAD, master and origin

  • HEAD: the current commit your repo is on.
  • master: The name of the default branch that git creates for you when first creating a repo.
  • origin: The default name that git gives to your main remote repo.

Local

Remote (origin)

Let's Git !!!

> mkdir repo1
> cd repo1
> ls -la
total 8
drwxrwxr-x 2 asp asp 4096 jun  5 13:28 .
drwxrwxr-x 3 asp asp 4096 jun  5 13:28 ..
> git init
Initialized empty Git repository in /home/asp/repositories/repo1/.git/
> ls -la
total 12
drwxrwxr-x 3 asp asp 4096 jun  5 13:28 .
drwxrwxr-x 3 asp asp 4096 jun  5 13:28 ..
drwxrwxr-x 7 asp asp 4096 jun  5 13:28 .git

... and create a file:

> cat > file.txt
this is a file
^C
> ls -la
total 16
drwxrwxr-x 3 asp asp 4096 jun  5 13:30 .
drwxrwxr-x 3 asp asp 4096 jun  5 13:28 ..
-rw-rw-r-- 1 asp asp   15 jun  5 13:30 file.txt
drwxrwxr-x 7 asp asp 4096 jun  5 13:28 .git

Initialize a local repo...

> git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	file.txt

nothing added to commit but untracked files present (use "git add" to track)
> 

... track the new file...

> git add file.txt 
> git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   file.txt

> 

...check repo status...

> git config user.name "Your name here"
> git config user.email "your@email.here"

Before the first commit let git know about us:

This information is used to know which user has done which commits.

> git commit -m "New file file.txt"
[master (root-commit) d87946f] New file file.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt
> git status
On branch master
nothing to commit, working directory clean
> 

... and see our repo history:

> git log
commit d87946fa2d170113dcbda46d4b095a1a30e852ca
Author: acanimal <asantiago@acuriousanimal.com>
Date:   Fri Jun 5 13:38:27 2015 +0200

    New file file.txt

... lets make our first commit...

... and with a little more detail:

> git log --decorate=full --name-status
commit d87946fa2d170113dcbda46d4b095a1a30e852ca (HEAD, refs/heads/master)
Author: acanimal <asantiago@acuriousanimal.com>
Date:   Fri Jun 5 13:38:27 2015 +0200

    New file file.txt

A       file.txt

git status, show the working tree status

git log, show the history of changes through the commit logs.

git status VS git log

... create new file "other.txt", modify the existing "file.txt" and check the status again:

> git status
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:   file.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	other.txt

no changes added to commit (use "git add" and/or "git commit -a")

... add the new "other.txt" file to be tracked:

> git add other.txt 
> git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   other.txt

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:   file.txt

... stag the modified file and commit changes at the same time:

> git commit -am "Added new file other.txt"
[master a709c60] Added new file other.txt
 2 files changed, 2 insertions(+)
 create mode 100644 other.txt
> git status
On branch master
nothing to commit, working directory clean

... lets see the history again:

> git log --decorate=full --name-status
commit a709c60d5c885beeeaf2a7d6fd6f129dbeead216 (HEAD, refs/heads/master)
Author: acanimal <asantiago@acuriousanimal.com>
Date:   Fri Jun 5 15:59:05 2015 +0200

    Added new file other.txt

M       file.txt
A       other.txt

commit d87946fa2d170113dcbda46d4b095a1a30e852ca
Author: acanimal <asantiago@acuriousanimal.com>
Date:   Fri Jun 5 13:38:27 2015 +0200

    New file file.txt

A       file.txt

Summary

Working with branches...

By default, when we create a repository Git creates a master branch:

> git branch
* master

Let's create a new branch to fix something:

> git branch bug01
> git branch
  bug01
* master

We are working on the master branch, let's make the bug01 branch the working branch:

> git checkout bug01
Switched to branch 'bug01'
> git branch
* bug01
  master

 

  > git branch newBr

  > git checkout newBr

 

 

 

  > git checkout -b newBr

 

 

... the same ...

> cat > file_on_bug01.txt
fix the bug
^C
> git status
On branch bug01
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	file_on_bug01.txt

nothing added to commit but untracked files present (use "git add" to track)

... create a new file to solve the bug...

...add new file and commit:

> git add file_on_bug01.txt 
> git status
On branch bug01
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   file_on_bug01.txt

> git commit -am "Bug fixed"
[bug01 776d7ee] Bug fixed
 1 file changed, 1 insertion(+)
 create mode 100644 file_on_bug01.txt
> git status
On branch bug01
nothing to commit, working directory clean
> git status
On branch bug01
nothing to commit, working directory clean
> ls -l
total 12
-rw-rw-r-- 1 asp asp 12 jun 11 12:08 file_on_bug01.txt
-rw-rw-r-- 1 asp asp 17 jun  5 15:55 file.txt
-rw-rw-r-- 1 asp asp 21 jun  5 15:54 other.txt

...change to master and list files:

> git checkout master
Switched to branch 'master'
> ls -l
total 8
-rw-rw-r-- 1 asp asp 17 jun  5 15:55 file.txt
-rw-rw-r-- 1 asp asp 21 jun  5 15:54 other.txt

List the files on branch bug01:

> git merge bug01
Updating a709c60..776d7ee
Fast-forward
 file_on_bug01.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 file_on_bug01.txt

... and list the files:

> ls -l
total 12
-rw-rw-r-- 1 asp asp 12 jun 11 15:16 file_on_bug01.txt
-rw-rw-r-- 1 asp asp 35 jun 11 13:48 file.txt
-rw-rw-r-- 1 asp asp 21 jun  5 15:54 other.txt

Now we are on master merge with branch bug01:

Finally remove the bug01 branch:

> git branch -d bug01
Deleted branch bug01 (was 776d7ee).

Let's create a new branch bug02 and modify the first line of file.txt and commit changes:

> git checkout master
Switched to branch 'master'
> vi file.txt 
> git commit -am "Added new line on file.txt at master"
[master 3c07391] Added new line on file.txt at master
 1 file changed, 1 insertion(+)
> git checkout -b bug02
Switched to a new branch 'bug02'
> git branch
* bug02
  master
>
> vi file.txt
>
> git commit -am "Modified file.txt on bug02"
[bug02 fa2a1b4] Modified file.txt on bug02
 1 file changed, 1 insertion(+)

Go to branch master and modify its file.txt too:

Just for fun, let's generate a conflict !!!

Try to merge bug02 into master:

> git branch
  bug02
* master
> git merge bug02
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.

> more file.txt 
<<<<<<< HEAD
New line at 'master'
=======
New line here at 'bug02'.
>>>>>>> bug02
this is a file
.

What does git status say?

> git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:      file.txt

no changes added to commit (use "git add" and/or "git commit -a")

Edit file.txt, resolve conflicts and try again:

> vi file.txt 
> more file.txt 
New line at 'master'
New line here at 'bug02'.
this is a file

> git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:      file.txt
no changes added to commit (use "git add" and/or "git commit -a")

Run git add to indicate conflict is solved and commit:

> git add file.txt 
> git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

nothing to commit, working directory clean
> git commit -am "Merge done"
[master cb2da7c] Merge done
> git status
On branch master
nothing to commit, working directory clean

Summary

Remote repositories

Remotes

  • Repositories hosted elsewhere in the net.
  • Needed to work collaboratively.
  • We push/pull data from remote to local repositories.

Remember the spaces...

Remote

Local

Upstream

Repository

Local

Repository

Index

(Staging)

Workspace

Stash

Add a remote repository to our local project:

> git remote add origin http://asp@smcdevatlas01/stash/scm/test/test.git
> git remote
origin
> git remote -v
origin	http://asp@smcdevatlas01/stash/scm/test/test.git (fetch)
origin	http://asp@smcdevatlas01/stash/scm/test/test.git (push)
>
> git push origin master
Password for 'http://asp@smcdevatlas01': 
Counting objects: 17, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (17/17), 1.45 KiB | 0 bytes/s, done.
Total 17 (delta 3), reused 0 (delta 0)
To http://asp@smcdevatlas01/stash/scm/test/test.git
 * [new branch]      master -> master
> 

Push to "origin" our "master" branch:

 

git push --set-upstream origin master

 

Configure the current branch to always upstream to a origin...

> git clone http://asp@some_gitserver/test.git test
Cloning into 'test'...
Password for 'http://asp@some_gitserver': 
remote: Counting objects: 23, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 23 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (23/23), done.
Checking connectivity... done.

...and see our branches and remotes  configuration:

> git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/fix01
  remotes/origin/master

> git remote -v
origin	http://asp@some_gitserver/test.git (fetch)
origin	http://asp@some_gitserver/test.git (push)

Go to another folder and clone a remote repository:

git clone...

 

  • Setups the origin remote.
  • Downloads the master branch.

 

Create a new file02.txt, commit and push to the remote repository:

> vi file02.txt
> git add file02.txt 
> git commit -m "New file 02"
[master d78e486] New file 02
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file02.txt
> git push
Password for 'http://asp@some_gitserver': 
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 337 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://asp@some_gitserver/test.git
   720262a..d78e486  master -> master

Return to previous folder (the initial local repo folder), add a new file, commit and try to push:

> git push origin master
Password for 'http://asp@some_gitserver': 
To http://asp@some_gitserver/test.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'http://asp@some_gitserver/test.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Remote has changes we need to download and merge with our local branch:

> git pull origin master
Password for 'http://asp@some_gitserver': 
From http://some_gitserver/test
 * branch            master     -> FETCH_HEAD
Merge made by the 'recursive' strategy.
 file02.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file02.txt

There are no conflicts, so now we can push our branch:

> git push origin master
Password for 'http://asp@some_gitserver': 
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 556 bytes | 0 bytes/s, done.
Total 5 (delta 2), reused 0 (delta 0)
To http://asp@some_gitserver/test.git
   d78e486..4c15a4e  master -> master

Gitflow

Let flow the flow...

The gitflow workflow...

  • Defines a strict branching model designed around the project release.
  • Provides a robust framework for managing larger projects.
  • Assigns very specific roles to different branches and defines how and when they should interact.

Gitflow branches

  • master
  • develop
  • feature
  • hotfix

Branch: master

Stores the official release history, so we must tag all commits in the master branch with a version number.

Branch: develop

Acts as integration branch for feature branches.

Branch: feature

  • Each new feature should reside in its own branch.
  • Use develop branch as their parent branch.
  • When a feature is complete, it gets merged back into develop.
  • Features should never interact directly with master.

Branch: release

Once develop has acquired enough features for a release:

  • Create a release branch using develop as their parent branch.
  • No new features can be added after this point (only release related tasks: bugs, documentation, etc).

Once it's ready:

  • the release gets merged into master and tagged with a version number.
  • the release is merged back into develop (which may have progressed since the release was initiated).

Branch: hotfix

  • Maintenance or “hotfix” branches are used to quickly patch production releases.
  • Should fork directly off of master.
  • Once fix is complete, it should be merged into both master and develop (or the current release branch)
  • master should be tagged with an updated version number.

References

Questions ???