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...
- We can use many different workflows when working with git: centralized workflow, feature branch workflow, ...
- Gitflow is based on A successful Git branching model by Vincent Driessen.
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
- Git Cheatsheet: Visual page to know allowed command between spaces.
- Gitflow: Explanation of the gitflow branching model.
- Getting Git Right: Atlassian Git tutorials.
- Learn Git Branching: Interactive way to learn Git.