Gerard Braad
gerard@unitedstack.com
You will learn the basic usage of git as a source management tool.
And the usage of Gerrit for the review process.
also known as Source Control Management
"The undo functionality for a developer"
"As with many great things in life, Git began with a bit of creative destruction and fiery controversy." - source
Linux kernel development is done as a large virtual global team
$ sudo yum install git git-review
$ sudo apt-get install git git-review
Nearly all operations are local, performed on a local repository
$ mkdir awesome_project
$ cd awesome_project
$ git init
Initialized empty Git repository in /home/gbraad/awesome_project/.git/
The command git init
created a .git
folder which represent the state of your work directory and contains a local repository.
$ echo "Hello, Git!" > hello
$ git add hello
$ git commit -m "Add hello file"
[master (root-commit) ea80784] Add hello file
1 file changed, 1 insertion(+)
create mode 100644 hello
We stored our first change
$ git log
commit ea8078459e0c569b0d055cc7d580a40ef36f5337
Author: Gerard Braad <me@gbraad.nl>
Date: Tue Apr 19 07:47:56 2016 +0000
Add hello file
Note: (root-commit)
Let's prepare a new commit.
$ echo "Goodbye, CVS!" >> hello
$ 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: hello
Git tells you that there is a change that has not been staged yet.
Always verify the changes you are going to commit
$ git diff
diff --git a/hello b/hello
index 670a245..4be5eec 100644
--- a/hello
+++ b/hello
@@ -1 +1,2 @@
Hello, Git!
+Goodbye, CVS!
Git has a convenient staging area, which allows you to prepare a commit from changes you have.
$ git add hello
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: hello
$ echo "Hello, Git! You rule!" > hello
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: hello
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: hello
$ git diff
diff --git a/hello b/hello
index 4be5eec..d198fd6 100644
--- a/hello
+++ b/hello
@@ -1,2 +1 @@
-Hello, Git!
-Goodbye, CVS!
+Hello, Git! You rule!
git commit -m "Say goodbye to cvs"
git add hello; git commit -m "I declare my preference"
$ git commit -m "Say goodbye to cvs"
[master bf5d3d8] Say goodbye to cvs
1 file changed, 1 insertion(+)
$ git log
commit bf5d3d87f4b354851ef5f41ec4bfba3673c326fa
Author: Gerard Braad <me@gbraad.nl>
Date: Wed Apr 20 02:55:00 2016 +0000
Say goodbye to cvs
$ cat hello
Hello, Git! You rule!
$ git show
commit bf5d3d87f4b354851ef5f41ec4bfba3673c326fa
Author: Gerard Braad <me@gbraad.nl>
Date: Wed Apr 20 02:55:00 2016 +0000
Say goodbye to cvs
diff --git a/hello b/hello
index 670a245..4be5eec 100644
--- a/hello
+++ b/hello
@@ -1 +1,2 @@
Hello, Git!
+Goodbye, CVS!
The last can be done manually with git diff master
$ git commit -m "I declare my preference"
[master b8586e3] I declare my preference
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log
commit b8586e361918fe8343b906706a1aa579badec64f
Author: Gerard Braad <me@gbraad.nl>
Date: Wed Apr 20 03:01:37 2016 +0000
I declare my preference
$ git show
commit b8586e361918fe8343b906706a1aa579badec64f
Author: Gerard Braad <me@gbraad.nl>
Date: Wed Apr 20 03:01:37 2016 +0000
I declare my preference
diff --git a/hello b/hello
index 670a245..d198fd6 100644
--- a/hello
+++ b/hello
@@ -1 +1 @@
-Hello, Git!
+Hello, Git! You rule!
$ git commit -m "Say goodbye to cvs"
[master bf5d3d8] Say goodbye to cvs
1 file changed, 1 insertion(+)
$ git add hello
$ git commit -m "I declare my preference"
[master 89486a6] I declare my preference
1 file changed, 1 insertion(+), 2 deletions(-)
Both changes are commited. Use staging to your advantage to 'stage' partial changes.
$ git log
commit 89486a636f60477d04637306ff75f382e0bac166
Author: Gerard Braad <me@gbraad.nl>
Date: Wed Apr 20 03:05:57 2016 +0000
I declare my preference
commit bf5d3d87f4b354851ef5f41ec4bfba3673c326fa
Author: Gerard Braad <me@gbraad.nl>
Date: Wed Apr 20 02:55:00 2016 +0000
Say goodbye to cvs
$ echo "Goodbye, CVS!" >> hello
$ git add hello
$ echo "Hello, Git! You rule!" > hello
$ git reset -- hello
This unstages the file and leaves the latest content
The previous files didn't exist in the repository. If you want to get a file contents from a commit.
$ git reset HEAD hello
$ git checkout -- hello
$ git checkout bf5d3d8 # or `git checkout master~1`
Note: checking out 'bf5d3d8'.
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 bf5d3d8... Say goodbye to cvs
$ cat hello
Hello, Git!
Goodbye, CVS!
$ git checkout master
Previous HEAD position was bf5d3d8... Say goodbye to cvs
Switched to branch 'master'
Master is the name given to a branch. Branch names are pointers to a change inside the git repository.
Branching in Git is a very cheap operation and initially exist locally.
To create a branch from the current checkout you can
$ git branch cool-feature
$ git checkout cool-feature
Switched to branch 'cool-feature'
or
$ git checkout -b cool-feature
$ git branch
* cool-feature
master
$ git log --oneline --graph --all
* 5ce4316 I declare my preference
* a4e6e04 Say goodbye to cvs
* e52304d Add hello file
$ echo > hello << EOF
> #include<stdio.h>
>
> int main(void) {
> printf("Hello, World\n");
> return 0;
> }
> EOF
$ mv hello hello.c
$ git status
On branch cool-feature
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: hello
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.c
no changes added to commit (use "git add" and/or "git commit -a")
$ git rm hello
$ git add hello.c
$ git rm hello
rm 'hello'
$ git add hello.c
$ git status
On branch cool-feature
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: hello
new file: hello.c
Note: the files are so different that no comparing can be done
$ git commit -m "Add Hello, C"
I have a master branch, and cool-feature.
Cool-feature is ahead by 1 change
* ccd51d4 Add Hello, C
/
* 5ce4316 I declare my preference
* a4e6e04 Say goodbye to cvs
* e52304d Add hello file
I haven't merged yet... so, let's test.
$ gcc hello.c -o hello
$ ./hello
Hello World
$ git status
Untracked files:
hello
$ vi .gitignore
hello
<ESC>:wq
Now check this with git status
and add this ignore file
$ git add .gitignore
$ git commit -m "Add ignored files (hello)"
With merging to bring two branches together.
$ git checkout master
$ git merge cool-feature
Updating 5ce4316..cf932b8
Fast-forward
.gitignore | 1 +
hello | 1 -
hello.c | 6 ++++++
3 files changed, 7 insertions(+), 1 deletion(-)
create mode 100644 .gitignore
delete mode 100644 hello
create mode 100644 hello.c
* master
|\
| * cf932b8 Add ignored files (hello)
| * ccd51d4 Add Hello, C
|/
* 5ce4316 I declare my preference
* a4e6e04 Say goodbye to cvs
* e52304d Add hello file
Note: standard behavior is Fast-forward
What if someone else has also worked on the code
* 2c80817 Add basic Hello, C
| * cf932b8 Add ignored files (hello)
| * ccd51d4 Add Hello, C
|/
* 5ce4316 I declare my preference
* a4e6e04 Say goodbye to cvs
* e52304d Add hello file
Master is now ahead with a new change that was merged
Rewriting history to take place in the future.
$ git checkout cool-feature
Switched to branch 'cool-feature'
Get ready for conflicts
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Add Hello, C
Using index info to reconstruct a base tree...
A hello
Falling back to patching base and 3-way merge...
Auto-merging hello.c
CONFLICT (add/add): Merge conflict in hello.c
Failed to merge in the changes.
Patch failed at 0001 Add Hello, C
The copy of the patch that failed is found in:
/home/ubuntu/workspace/awesome_project/.git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
#include<stdio.h>
int main(void) {
<<<<<<< HEAD
printf("Hello, World\n");
=======
printf("Hello World\n");
return 0;
>>>>>>> Add Hello, C
}
We are told that there is a conflict from <<<<<<< HEAD
to =======
and from =======
to >>>>>>> Add Hello, C
.
We edit the file till we think it is OK. leaving the ,
and the return 0;
.
Make sure the code works; 'compile', 'run/test', and add resolved conflict.
$ git add hello.c
$ git rebase --continue
Applying: Add Hello, C
Applying: Add ignored files (hello)
$ git log --graph --oneline --all
* 066372d Add ignored files (hello)
* f0a97ce Add Hello, C
* 2c80817 Add basic Hello, C
* 5ce4316 I declare my preference
* a4e6e04 Say goodbye to cvs
* e52304d Add hello file
$ git checkout master
Switched to branch 'master'
$ git merge cool-feature
Updating 2c80817..066372d
Fast-forward
.gitignore | 1 +
hello.c | 1 +
2 files changed, 2 insertions(+)
create mode 100644 .gitignore
Note: our change now only adds a return 0;
The repository’s commit history is a record of what actually happened.
The repository’s commit history is the story of how your project was made.
In the case of OpenStack, we do not merge. We propose a change and rebase on top of master to make sure we are up-to-date
Gerrit is used to perform the code-reviews and git review
is used to submit/ propose your changes for review.
Create a topic branch
$ git checkout -b [branchname]
Code, code, code, commit
$ git commit
Write a great commit message
$ git review
First time you have to set your gerrit username and make sure your ssh
identity is known. I assume you have done this...
git review
remote: Processing changes: new: 1, refs: 1, done
remote:
remote: New Changes:
remote: https://review.openstack.org/[reviewid] [Title]
remote:
To ssh://gbraad@review.openstack.org:29418/openstack/[repo].git
* [new branch] HEAD -> refs/publish/master/[branchname]
Have a look at http://review.openstack.org/
Make changes and resubmit for review
$ git add [file]
$ git commit --amend
$ git review
Note: do not edit the Change-Id
in the commit message. This is how Gerrit tracks patch sets to the same commit.
git push --force