Git Tutorial
Git Tutorial
GIT
Audience
This tutorial will help beginners learn the basic functionality of Git version control
system. After completing this tutorial, you will find yourself at a moderate level
of expertise in using Git version control system from where you can take
yourself to the next levels.
Prerequisites
We assume that you are going to use Git to handle all levels of Java and nonJava projects. So it will be good if you have some amount of exposure to
software development life cycle and working knowledge of developing webbased and non-web-based applications.
GIT
Table of Contents
About the Tutorial i
Audience i
Prerequisites i
Copyright & Disclaimer i
Table of Contents ii
1. BASIC CONCEPTS 1
Version Control System 1
Distributed Version Control System 1
Advantages of Git 2
DVCS Terminologies 3
2. ENVIRONMENT SETUP 7
Installation of Git Client 7
Customize Git Environment 7
3. LIFE CYCLE 10
4. CREATE OPERATION 11
Create New User 11
Create a Bare Repository 11
Generate Public/Private RSA Key Pair 12
Adding Keys to authorized_keys 13
Push Changes to the Repository 14
5. CLONE OPERATION 17
6. PERFORM CHANGES 18
ii
GIT
7. REVIEW CHANGES 21
8. COMMIT CHANGES 24
9. PUSH OPERATION 26
10. UPDATE OPERATION 29
Modify Existing Function 29
Add New Function 32
Fetch Latest Changes 34
iii
GIT
iv
1. BASIC CONCEPTS
GIT
GIT
Advantages of Git
Free and open source
Git is released under GPLs open source license. It is available freely over the
internet. You can use Git to manage propriety projects without paying a single
penny. As it is an open source, you can download its source code and also
perform changes according to your requirements.
Implicit backup
The chances of losing data are very rare when there are multiple copies of it.
Data present on any client side mirrors the repository, hence it can be used in
the event of a crash or disk corruption.
Security
Git uses a common cryptographic hash function called secure hash function
(SHA1), to name and identify objects within its database. Every file and commit
is check-summed and retrieved by its checksum at the time of checkout. It
implies that it is impossible to change file, date, and commit message and any
other data from the Git database without knowing Git.
Easier branching
CVCS uses cheap copy mechanism. If we create a new branch, it will copy all the
codes to the new branch, so it is time-consuming and not efficient. Also, deletion
and merging of branches in CVCS is complicated and time-consuming. But
branch management with Git is very simple. It takes only a few seconds to
create, delete, and merge branches.
2
GIT
DVCS Terminologies
Local Repository
Every VCS tool provides a private workplace as a working copy. Developers
make changes in their private workplace and after commit, these changes
become a part of the repository. Git takes it one step further by providing them
a private copy of the whole repository. Users can perform many operations with
this repository such as add file, remove file, rename file, move file, commit
changes, and many more.
Suppose you modified two files, namely sort.c and search.c and you want
two different commits for each operation. You can add one file in the staging
3
GIT
area and do commit. After the first commit, repeat the same procedure for
another file.
# First commit
[bash]$ git add sort.c
Blobs
Blob stands for Binary Large Object. Each version of a file is represented by
blob. A blob holds the file data but doesnt contain any metadata about the file.
It is a binary file and in Git database, it is named as SHA1 hash of that file. In
Git, files are not addressed by names. Everything is content-addressed.
Trees
Tree is an object, which represents a directory. It holds blobs as well as other
sub-directories. A tree is a binary file that stores references to blobs and trees
which are also named as SHA1 hash of the tree object.
Commits
Commit holds the current state of the repository. A commit is also named
by SHA1 hash. You can consider a commit object as a node of the linked list.
Every commit object has a pointer to the parent commit object. From a given
commit, you can traverse back by looking at the parent pointer to view the
history of the commit. If a commit has multiple parent commits, then that
particular commit has been created by merging two branches.
Branches
Branches are used to create another line of development. By default, Git has a
master branch, which is same as trunk in Subversion. Usually, a branch is
created to work on a new feature. Once the feature is completed, it is merged
back with the master branch and we delete the branch. Every branch is
4
GIT
referenced by HEAD, which points to the latest commit in the branch. Whenever
you make a commit, HEAD is updated with the latest commit.
Tags
Tag assigns a meaningful name with a specific version in the repository. Tags
are very similar to branches, but the difference is that tags are immutable. It
means, tag is a branch, which nobody intends to modify. Once a tag is created
for a particular commit, even if you create a new commit, it will not be updated.
Usually, developers create tags for product releases.
Clone
Clone operation creates the instance of the repository. Clone operation not only
checks out the working copy, but it also mirrors the complete repository. Users
can perform many operations with this local repository. The only time
networking gets involved is when the repository instances are being
synchronized.
Pull
Pull operation copies the changes from a remote repository instance to a local
one. The pull operation is used for synchronization between two repository
instances. This is same as the update operation in Subversion.
Push
Push operation copies changes from a local repository instance to a remote one.
This is used to store the changes permanently into the Git repository. This is
same as the commit operation in Subversion.
HEAD
HEAD is a pointer, which always points to the latest commit in the branch.
Whenever you make a commit, HEAD is updated with the latest commit. The
heads of the branches are stored in .git/refs/heads/ directory.
[CentOS]$ ls -1 .git/refs/heads/
master
GIT
Revision
Revision represents the version of the source code. Revisions in Git are
represented by commits. These commits are identified by SHA1 secure hashes.
URL
URL represents the location of the Git repository. Git URL is stored in config file.
[tom@CentOS tom_repo]$ pwd
/home/tom/tom_repo
2. ENVIRONMENT SETUP
GIT
Before you can use Git, you have to install and do some basic configuration
changes. Below are the steps to install Git client on Ubuntu and Centos Linux.
GIT
repository on the system. To set these values, you must have the root rights
and use the --system option.
When the above code is compiled and executed, it produces the following result:
Setting username
This information is used by Git for each commit.
[jerry@CentOS project]$ git config --global user.name "Jerry Mouse"
Setting email id
This information is used by Git for each commit.
[jerry@CentOS project]$ git config --global user.email
"jerry@tutorialspoint.com"
Color highlighting
The following commands enable color highlighting for Git in the console.
[jerry@CentOS project]$ git config --global color.ui true
GIT
Git does not provide a default merge tool for integrating conflicting changes into
your working tree. We can set default merge tool by enabling following settings.
[jerry@CentOS project]$ git config --global merge.tool vimdiff
3. LIFE CYCLE
GIT
In this chapter, we will discuss the life cycle of Git. In later chapters, we will
cover the Git commands for each operation.
General workflow is as follows:
1. You clone the Git repository as a working copy.
2. You modify the working copy by adding/editing files.
3. If necessary, you also update the working copy by taking other
developers' changes.
4. You review the changes before commit.
5. You commit changes. If everything is fine, then you push the changes to
the repository.
6. After committing, if you realize something is wrong, then you correct the
last commit and push the changes to the repository.
Shown below is the pictorial representation of the workflow.
10
4. CREATE OPERATION
GIT
In this chapter, we will see how to create a remote Git repository; from now on,
we will refer to it as Git Server. We need a Git server to allow team
collaboration.
# change password
[root@CentOS ~]# passwd gituser
The above command will produce the following result.
Changing password for user gituser.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
11
GIT
[gituser@CentOS project.git]$ ls
[gituser@CentOS project.git]$ ls
branches config description HEAD hooks info objects refs
GIT
GIT
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
Similarly, Jerry added his public key to the server by using ssh-copy-id
command.
[jerry@CentOS ~]$ pwd
/home/jerry
GIT
[tom@CentOS tom_repo]$ echo 'TODO: Add contents for README' > README
Initial commit
Tom committed his changes to the local repository. Now, its time to push the
changes to the remote repository. But before that, we have to add the
repository as a remote, this is a one-time operation. After this, he can safely
push the changes to the remote repository.
Note: By default, Git pushes only to matching branches: For every branch that
exists on the local side, the remote side is updated if a branch with the same
name already exists there. In our tutorials, every time we push changes to the
15
GIT
16
5. CLONE OPERATION
GIT
We have a bare repository on the Git server and Tom also pushed his first
version. Now, Jerry can view his changes. The Clone operation creates an
instance of the remote repository.
Jerry creates a new directory in his home directory and performs the clone
operation.
[jerry@CentOS ~]$ mkdir jerry_repo
[jerry@CentOS jerry_repo]$ ls
README
17
6. PERFORM CHANGES
GIT
Jerry clones the repository and decides to implement basic string operations. So
he creates string.c file. After adding the contents, string.c will look as follows:
#include <stdio.h>
while (*p)
++p;
return (p - s);
}
int main(void)
{
int i;
char *s[] = {
"Git tutorials",
"Tutorials Point"
};
return 0;
}
He compiled and tested his code and everything is working fine. Now, he can
safely add these changes to the repository.
Git add operation adds file to the staging area.
18
GIT
GIT
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit
20
7. REVIEW CHANGES
GIT
After viewing the commit details, Jerry realizes that the string length cannot be
negative, thats why he decides to change the return type of my_strlen function.
Jerry uses the git log command to view log details.
[jerry@CentOS project]$ git log
GIT
+#include <stdio.h>
+
+int my_strlen(char *s)
+{
+
char *p = s;
+
+
while (*p)
+ ++p;
+ return (p -s );
+}
+
He changes the return type of the function from int to size_t. After testing the
code, he reviews his changes by running the git diff command.
[jerry@CentOS project]$ git diff
The above command will produce the following result:
diff --git a/string.c b/string.c
index 187afb9..7da2992 100644
--- a/string.c
+++ b/string.c
@@ -1,6 +1,6 @@
#include <stdio.h>
GIT
23
8. COMMIT CHANGES
GIT
Jerry has already committed the changes and he wants to correct his last
commit. In this case, git amend operation will help. The amend operation
changes the last commit including your commit message; it creates a new
commit ID.
Before amend operation, he checks the commit log.
[jerry@CentOS project]$ git log
The above command will produce the following result.
commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit
Jerry commits the new changes with -- amend operation and views the commit
log.
[jerry@CentOS project]$ git status -s
M string.c
?? string
GIT
?? string
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit
25
9. PUSH OPERATION
GIT
Jerry modified his last commit by using the amend operation and he is ready to
push the changes. The Push operation stores data permanently to the Git
repository. After a successful push operation, other developers can see Jerrys
changes.
He executes the git log command to view the commit details.
[jerry@CentOS project]$ git log
The above command will produce the following result:
commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530
GIT
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+size_t my_strlen(char *s)
+{
+
char *p = s;
+
+
while (*p)
+ ++p;
+ return (p -s );
+}
+
+int main(void)
+{
+ int i;
+ char *s[] = {
+ "Git tutorials",
+ "Tutorials Point"
+
};
+
+
+
for (i = 0; i < 2; ++i)
printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
+
+
return 0;
+}
Jerry is happy with his changes and he is ready to push his changes.
27
GIT
28
GIT
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
29
GIT
Initial commit
After observing the log, he realizes that the file string.c was added by Jerry to
implement basic string operations. He is curious about Jerrys code. So he opens
string.c in text editor and immediately finds a bug. In my_strlen function, Jerry
is not using a constant pointer. So, he decides to modify Jerrys code. After
modification, the code looks as follows:
[tom@CentOS project]$ git diff
The above command will produce the following result:
diff --git a/string.c b/string.c
index 7da2992..32489eb 100644
--- a/string.c
+++ b/string.c
@@ -1,8 +1,8 @@
#include
-size_t my_strlen(char *s)
+size_t my_strlen(const char *s)
{
- char *p = s;
+ const char *p = s;
while (*p)
++p;
After testing, he commits his change.
[tom@CentOS project]$ git status -s
M string.c
?? string
GIT
commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit
Tom uses git push command to push his changes.
[tom@CentOS project]$ git push origin master
The above command will produce the following result:
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 336 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
31
GIT
GIT
"Git tutorials",
"Tutorials Point"
@@ -20,5 +31,7 @@ int main(void)
for (i = 0; i < 2; ++i)
printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
+
printf("%s\n", my_strcpy(p1, "Hello, World !!!"));
+
return 0;
}
After testing, he is ready to push his change.
[jerry@CentOS project]$ git status -s
M string.c
?? string
commit d1e19d316224cddc437e3ed34ec3c931ad803958
33
GIT
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit
Jerry is happy with the changes and he wants to push his changes.
[jerry@CentOS project]$ git push origin master
The above command will produce the following result:
To gituser@git.server.com:project.git
! [rejected]
master > master (non-fast-forward)
error: failed to push some refs to 'gituser@git.server.com:project.git'
To prevent you from losing history, non-fast-forward updates were
rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.
But Git is not allowing Jerry to push his changes. Because Git identified that the
remote repository and Jerrys local repository are not in sync. Because of this,
he can lose the history of the project. To avoid this mess, Git failed this
operation. Now, Jerry has to first update the local repository and only thereafter,
he can push his own changes.
GIT
commit cea2c000f53ba99508c5959e3e12fff493ba6f69
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 08:32:07 2013 +0530
commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530
35
GIT
commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit
Now, Jerrys local repository is fully synchronized with the remote repository. So
he can safely push his changes.
[jerry@CentOS project]$ git push origin master
The above command will produce the following result:
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 455 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
cea2c00..e86f062 master > master
36
GIT
Suppose you are implementing a new feature for your product. Your code is in
progress and suddenly a customer escalation comes. Because of this, you have
to keep aside your new feature work for a few hours. You cannot commit your
partial code and also cannot throw away your changes. So you need some
temporary space, where you can store your partial changes and later on commit
it.
In Git, the stash operation takes your modified tracked files, stages changes,
and saves them on a stack of unfinished changes that you can reapply at any
time.
[jerry@CentOS project]$ git status -s
M string.c
?? string
Now, you want to switch branches for customer escalation, but you dont want to
commit what youve been working on yet; so youll stash the changes. To push a
new stash onto your stack, run the git stash command.
[jerry@CentOS project]$ git stash
Saved working directory and index state WIP on master: e86f062 Added
my_strcpy function
HEAD is now at e86f062 Added my_strcpy function
Now, your working directory is clean and all the changes are saved on a stack.
Let us verify it with the git status command.
[jerry@CentOS project]$ git status -s
?? string
Now you can safely switch the branch and work elsewhere. We can view a list of
stashed changes by using the git stash list command.
[jerry@CentOS project]$ git stash list
stash@{0}: WIP on master: e86f062 Added my_strcpy function
Suppose you have resolved the customer escalation and you are back on your
new feature looking for your half-done code, just execute the git stash pop
command to remove the changes from the stack and place them in the current
working directory.
37
GIT
38
GIT
As the name suggests, the move operation moves a directory or a file from one
location to another. Tom decides to move the source code into the src directory.
The modified directory structure will appear as follows:
[tom@CentOS project]$ pwd
/home/tom/project
[tom@CentOS project]$ ls
README string string.c
GIT
To gituser@git.server.com:project.git
e86f062..7d9ea97 master > master
In Jerrys local repository, before the pull operation, it will show the old directory
structure.
[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project
[jerry@CentOS project]$ ls
README string string.c
But after the pull operation, the directory structure will get updated. Now, Jerry
can see the src directory and the file present inside that directory.
[jerry@CentOS project]$ git pull
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git.server.com:project
e86f062..7d9ea97 master > origin/master
First, rewinding head to replay your work on top of it...
Fast-forwarded master to 7d9ea97683da90bcdb87c28ec9b4f64160673c8a.
[jerry@CentOS project]$ ls
README src string
40
GIT
Till now, both Tom and Jerry were using manual commands to compile their
project. Now, Jerry decides to create Makefile for their project and also give a
proper name to the file string.c.
[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project
[jerry@CentOS project]$ ls
README src
GIT
42
GIT
Tom updates his local repository and finds the compiled binary in the src
directory. After viewing the commit message, he realizes that the compiled
binary was added by Jerry.
[tom@CentOS src]$ pwd
/home/tom/project/src
[tom@CentOS src]$ ls
Makefile string_operations string_operations.c
GIT
44
GIT
To err is human. So every VCS provides a feature to fix mistakes until a certain
point. Git provides a feature that we can use to undo the modifications that have
been made to the local repository.
Suppose the user accidentally does some changes to his local repository and
then wants to undo these changes. In such cases, the revert operation plays an
important role.
[tom@CentOS src]$ ls -1
Makefile
string_operations.c
GIT
[tom@CentOS src]$ ls -1
Makefile
[tom@CentOS src]$ ls -1
Makefile
string_operations.c
GIT
47
GIT
Soft
Each branch has a HEAD pointer, which points to the latest commit. If we use
Git reset command with --soft option followed by commit ID, then it will reset
the HEAD pointer only without destroying anything.
.git/refs/heads/master file stores the commit ID of the HEAD pointer. We can
verify it by using the git log -1 command.
[jerry@CentOS project]$ cat .git/refs/heads/master
577647211ed44fe2ae479427a0668a4f12ed71a1
Now, view the latest commit ID, which will match with the above commit ID.
[jerry@CentOS project]$ git log -2
The above command will produce the following result.
commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530
commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530
GIT
commit 94f7b26005f856f1a1b733ad438e97a0cd509c1a
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:08:01 2013 +0530
mixed
Git reset with --mixed option reverts those changes from the staging area that
have not been committed yet. It reverts the changes from the staging area only.
The actual changes made to the working copy of the file are unaffected. The
default Git reset is equivalent to the git reset -- mixed.
hard
If you use --hard option with the Git reset command, it will clear the staging
area; it will reset the HEAD pointer to the latest commit of the specific commit
ID and delete the local file changes too.
49
GIT
GIT
#
Git status is showing that the file is present in the staging area. Now, reset
HEAD with -- hard option.
[jerry@CentOS src]$ git reset --hard
577647211ed44fe2ae479427a0668a4f12ed71a1
Git status is showing that the file has been reverted from the staging area.
[jerry@CentOS src]$ head -2 string_operations.c
#include <stdio.h>
The head command also shows that the reset operation removed the local
changes too.
51
GIT
Create Tags
Let us tag the current HEAD by using the git tag command. Tom provides a tag
name with -a option and provides a tag message with m option.
tom@CentOS project]$ pwd
/home/tom/top_repo/project
View Tags
Tom created tags. Now, Jerry can view all the available tags by using the Git tag
command with l option.
[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src
52
GIT
commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530
GIT
Delete Tags
Tom uses the following command to delete tags from the local as well as the
remote repository.
[tom@CentOS project]$ git tag
Release_1_0
54
GIT
Patch is a text file, whose contents are similar to Git diff, but along with code, it
also has metadata about commits; e.g., commit ID, date, commit message, etc.
We can create a patch from commits and other people can apply them to their
repository.
Jerry implements the strcat function for his project. Jerry can create a path of
his code and send it to Tom. Then, he can apply the received patch to his code.
Jerry uses the Git format-patch command to create a patch for the latest
commit. If you want to create a patch for a specific commit, then
use COMMIT_ID with the format-patch command.
[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project/src
GIT
GIT
char *p = t;
+
+
+
while (*p)
++p;
+
while (*p++ = *s++)
+ ;
+ return t;
+}
+
size_t my_strlen(const char *s)
{
const char *p = s;
@@ -23,6 +34,7 @@ int main(void)
{
57
GIT
Branch operation allows creating another line of development. We can use this
operation to fork off the development process into two different directions. For
example, we released a product for 6.0 version and we might want to create a
branch so that the development of 7.0 features can be kept separate from 6.0
bug fixes.
Create a Branch
Tom creates a new branch using the git branch <branch name> command. We
can create a new branch from an existing one. We can use a specific commit or
tag as the starting point. If any specific commit ID is not provided, then the
branch will be created with HEAD as its starting point.
[jerry@CentOS src]$ git branch new_branch
58
GIT
Delete a Branch
A branch can be deleted by providing D option with git branch command. But
before deleting the existing branch, switch to the other branch.
59
GIT
Rename a Branch
Jerry decides to add support for wide characters in his string operations project.
He has already created a new branch, but the branch name is not appropriate.
So he changes the branch name by using m option followed by the old branch
name and the new branch name.
[jerry@CentOS src]$ git branch
* master
new_branch
60
GIT
61
GIT
62
GIT
Tom is curious about what Jerry is doing in his private branch and he checks the
log from the wchar_support branch.
[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src
commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530
GIT
Now, the branch wchar_support has been merged with the master branch. We
can verify it by viewing the commit message or by viewing the modifications
done into the string_operation.c file.
[tom@CentOS project]$ cd src/
commit 64192f91d7cc2bcdf3bf946dd33ece63b74184a3
64
GIT
while (*p)
++p;
return (p - s);
}
After testing, he pushes his code changes to the master branch.
[tom@CentOS src]$ git push origin master
Total 0 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
5776472..64192f9 master > master
Rebase Branches
The Git rebase command is a branch merge command, but the difference is that
it modifies the order of commits.
The Git merge command tries to put the commits from other branches on top of
the HEAD of the current local branch. For example, your local branch has
commits A>B>C>D and the merge branch has commits A>B>X>Y,
then git merge will convert the current local branch to something like
A>B>C>D>X>Y.
65
GIT
The Git rebase command tries to find out the common ancestor between the
current local branch and the merge branch. It then pushes the commits to the
local branch by modifying the order of commits in the current local branch. For
example, if your local branch has commits A>B>C>D and the merge branch
has commits A>B>X>Y, then Git rebase will convert the current local
branch to something like A>B>X>Y>C>D.
When multiple developers work on a single remote repository, you cannot
modify the order of the commits in the remote repository. In this situation, you
can use rebase operation to put your local commits on top of the remote
repository commits and you can push these changes.
66
GIT
GIT
68
GIT
GIT
+++ b/src/string_operations.c
@@ -1,6 +1,16 @@
#include <stdio.h>
#include <wchar.h>
+wchar_t *my_wstrchr(wchar_t *ws, wchar_t wc)
+{
+
while (*ws) {
+
if (*ws == wc)
+
return ws;
+
++ws;
+ }
+ return NULL;
+}
+
size_t my_wstrlen(const wchar_t *s)
{
const wchar_t *p = s;
After verifying, he commits his changes.
[jerry@CentOS src]$ git status -s
M string_operations.c
GIT
Tackle Conflicts
Tom wants to see what Jerry is doing on his private branch and so, he tries to
pull the latest changes from the wchar_support branch, but Git aborts the
operation with the following error message.
[tom@CentOS src]$ git pull origin wchar_support
The above command produces the following result:
remote: Counting objects: 11, done.
63Git Tutorials
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From git.server.com:project
* branch
wchar_support -> FETCH_HEAD
Auto-merging src/string_operations.c
CONFLICT (content): Merge conflict in src/string_operations.c
Automatic merge failed; fix conflicts and then commit the result.
Resolve Conflicts
From the error message, it is clear that there is a conflict in
src/string_operations.c . He runs the git diff command to view further details.
[tom@CentOS src]$ git diff
The above command produces the following result:
diff --cc src/string_operations.c
71
GIT
index 52bec84,163a779..0000000
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@@ -1,8 -1,17 +1,22 @@@
#include <stdio.h>
#include <wchar.h>
++<<<<<<< HEAD
+/* wide character strlen fucntion */
+size_t my_wc_strlen(const wchar_t *s)
++=======
+ wchar_t *my_wstrchr(wchar_t *ws, wchar_t wc)
+{
+
+
while (*ws) {
if (*ws == wc)
+
return ws;
+
++ws;
+ }
+ return NULL;
+}
+
+ size_t my_wstrlen(const wchar_t *s)
++>>>>>>>9d201a9c61bc4713f4095175f8954b642dae8f86
{
const wchar_t *p = s;
As both Tom and Jerry changed the name of the same function, Git is in a state
of confusion and it asks the user to resolve the conflict manually.
Tom decides to keep the function name suggested by Jerry, but he keeps the
comment added by him as it is. After removing the conflict markers, git diff will
look like this.
72
GIT
GIT
74
GIT
GNU/Linux and Mac OS uses line-feed (LF), or new line as line ending
character,
while
Windows
uses
line-feed
and
carriage-return
(LFCR) combination to represent the line-ending character.
To avoid unnecessary commits because of these line-ending differences, we
have to configure the Git client to write the same line ending to the Git
repository.
For Windows system, we can configure the Git client to convert line endings
to CRLF format while checking out, and convert them back to LF format during
the commit operation. The following settings will do the needful.
[tom@CentOS project]$ git config --global core.autocrlf true
For GNU/Linux or Mac OS, we can configure the Git client to convert line endings
from CRLF to LF while performing the checkout operation.
[tom@CentOS project]$ git config --global core.autocrlf input
75
GIT
Push Operation
Tom decides to use the GitHub server. To start a new project, he creates a new
directory and one file inside that.
[tom@CentOS]$ mkdir github_repo
[tom@CentOS]$ cd github_repo/
[tom@CentOS]$ vi hello.c
[tom@CentOS]$ ./hello
The above command will produce the following result:
Hello, World !!!
After verifying his code, he initializes the directory with the git init command and
commits his changes locally.
[tom@CentOS]$ git init
Initialized empty Git repository in /home/tom/github_repo/.git/
76
GIT
77
GIT
Pull Operation
Tom successfully pushed all his changes to the GitHub repository. Now, other
developers can view these changes by performing clone operation or updating
their local repository.
Jerry creates a new directory in his home directory and clones the GitHub
repository by using the git clone command.
[jerry@CentOS]$ pwd
/home/jerry
[jerry@CentOS]$ ls test_repo/
hello.c
78