--- written by Jiang Xin, 2011.
I wrote this book in Chinese from 2010.10 till 2011.2. Parts of this book is from my works on some Git related open source projects, such as hacks on Topgit, Gitosis, Gitolite, repo (from Android project); Gistore a backup tools which I am inspired by etckeeper.
I translated the preface, Table of Contents, some figures of this book from Chinese into English, to help the people in English understanding the outline of this book. Sorry for my poor English. :(
Version Control (SCM) is the art of changes management, no matter whether the changes are from the same person or from a team. Version control system in the first place, must faithfully record the changes, and it could help people restore any historical revision or revert any historical changes. But as the most important part, the version control system could make the team members work together. Git is one of the best version control systems in the world.
My interests in version control system is from my practice on personal knowledge management. The core of my personal knowledge management is writing documents using maintainable format, and backup the documents in version control system. As to the maintainable document formats, they could be DocBook, FreeMind, reStructuredText, asciidoc and etc. I even hacked FreeMind to fit with version control system better, such as store VCS unfriendly node properties outside the .mm files into a .mmx file. This is my first open source activity, and the hacked FreeMind is hosted in as FreeMind-MMX. After chosen the proper document format, comes with the storage problem. Though a version control system can backup each historical commit, but how to avoid data loses if version control system corrupted? Git with its new design of the distributed operation model provides the best solution. Using Git, my knowledge base can be distributed by cloning it onto to different disks, or different hosts, and the synchronization between the repositories is simple, just through the push and pull operations. Data security has been greatly improved when using Git. With the care of the version control system, my mindmap (in FreeMind format) of Git becomes more and more clear over the time, and eventually becomes the prototype of the book.
Version control can determine the success of the project, even life of a company. During my experiences on promoting open source project management tools and consulting, I have seen so many teams failed, because of bad version control management. such as project postpone, fixed bugs reappear, can't locate bug in codes, no matter what version control system they used, open source or commercial.
Takes my company as a example, we are doing some open source projects customization services. In the begining, we use SVN (Subversion) for code management, but the vendor branch model is hard to use. More hacks we do, more difficulties it is to rebase onto new upstream version. We are confused at that time, then we meet with DVCS (distributed version control system).
My first attempt on DVCS is Hg (Mercurial), with the help of MQ (a Hg plugin). It works fine for our working model, but if two or more programmers involved in one project, conflicts on MQ patches make us crazy. Latter we tried Git with the help of Topgit, all problems gone.
...
This book is divided into nine parts with 41 chapters and appendices.
Part 1 is an overview of Git, and it is divided into three chapters. In Chapter 1, is the overview of the history of version control systems. In Chapter 2, I show over 10 examples of Git, and I wish the readers could fall in love with Git for these highlights. Chapter 3 introduces the installation and configurations of Git in the three main platforms: Linux, Mac OS X and Windows. When I wrote this book, 70% of the time is under the Debian Linux operating system, so Linux users should have no obstacles for running the examples in this book. At the end of 2010, after learning that there will be a publisher give me money for the first print for this book, I asked for money from my wife AQiao and bought my first MacBook Pro, so there are the contents on Git usages on Mac and new Topgit hacks for Mac OS X. When cooperated with the editors of this book, I have to use MS Word, so part of the work is on Windows running as a VirtualBox virtual machine in Mac OS X. Even with limited resources, Git in Cygwin environment still works perfect.
Part 2 and Part 3 describes the basic operation of Git, and they are the foundation and core of the book, take up about 40% of this book. Why this two parts call 'Git Solo' and 'Git harmony'? The names are from my habits from my earlier training experiences for Subversion. 'SOLO' stands for working with version control by one self. 'Harmony' refers to working with version control as a team. In part 2, I mixed the Git magic (design principles) with the operations, because only know the truth (Git principle), people can use it freely (resolve Git puzzles). In part 3, introduces milestones, branches, and how to resolve conflicts, etc.
Part 4 talks about the working models of Git. In addition to the traditional centralized and distributed model, Chapter 22 introduces Topgit in detail, it will help hackers on other projects and for customization projects. In this chapter also describes some of my Topgit improvements, they are developed in Topgit way. Chapter 23-25 handle multiple repositories for one project. Chapter 25 describes an new innovate solution introduced by Android project, it named repo. I hacked to make repo works with Git server directly without the help of Gerrit. Chapter 26 introduces git-svn, with the help of git-svn, nobody knows the commit to SVN is from a Git user.
Part 5 is focus on Git server. In deed, this part is the first part I've written, because my customers need details in Gitolite set up, while my training PPT only provides outline, so comes with Chapter 30. Chapter 32 introduces Gerrit, a special central model for Git.
Chapter 6 describes the migration of Git repository. Chapter 34 shows details for CVS repositories migrate to Git repositories, and the chapter is also helpful for CVS to SVN. Other version control systems are also covered, such as SVN and Hg. Latter in this part, a Git to Git powerful tools is covered, it's git-filter-branch.
Part 7 introduces other applications of Git, such as etckeeper, Gistore, and others. I developed Gistore for files backup with the inspiration of etckeeper.
Part 8 covered miscellaneous features of Git. The first chapter in this part is helpful for cross platform team.
...
The dark age wasn't so dark, there were diff and patch at least. In this section, diff and patch will be introduced by examples.
CVS history and CVS implement model.
![]()
Fig 1-1
SVN history and SVN implement model.
![]()
Fig 1-2
Git history.
Git hightlights by examples.
During the writing of the book, everyday's work at the end of a day will be pushed to the server, then the pushed commits will be mirrored to a outside server in the data center automatically.
![]()
Fig 2-1
How I synchoronize my work between different locations during the writing of this book, such as at home and at my office.
![]()
Fig 2-2
One single .git directory, comparing with SVN's .svn in each subdirs.
Git has another useful command: git grep.
git commit --amend
git reset and git rebase -i
Stage works like commit change set.
git diff --cached
git stash
git-svn, nobody knows your commit throught git.
No longer needs PIPE LESS ( | less ) after commands.
Smart protocol.
Works excellent in UTF8 environment, but may fail in other locales.
If Linux is in other locale, such as zh_CN.GBK, in this case :
Commit log.
Characters other then English CAN be used in commit log, only if do some proper settings. After add some proper settings, there will be a embed encoding directive in the commit object.
Filename.
CAN NOT use non-English characters as filename, because tree object is not encoded in UTF8.
Download Xcode is not rquired, as there was a copy in Mac OS X installer DVD already.
![]()
Fig 3-3
Works fine just like in Linux with UTF8 locale.
In the case of lowbandwidth (like me), setting up a cygwin mirror with the help of apt-cacher-ng in Debian could be helpful.
![]()
Fig 3-7
How to use cygwin package management program (setup.exe) --- to find and install git.
![]()
Fig 3-13
Works fine, just like in linux with UTF8 locale.
Current cygwin's ssh doesn't work on some situations, in this section I will introduce how to integrate Cygwin Git with putty's plink or pagent.
Insufficient support.
As "bad" as msysGit, and it's log process is not compatible with msysGit.
Play with Git by one self, so I call this part "Git solo".
git init, git add, git commit...
Compare Git's .git directory with CVS's CVS directories, SVN's .svn directories, and StarTeam's server-side tracking implementations.
Run git config --system -e to see where is your system config file.
Setup user.name and user.email once, and make it stable.
For example Redmine will map the committer to one of it user accounts, if the committer username or email changed, the map will be broken.
![]()
Fig 4-1
Another example is Gerrit, wrong user.name and user.email settings will make commits to Gerrit denied.
Fig 5-1
Fig 5-2
git stage save.
Object database:
![]()
Fig 6-1
Git implementation detail:
![]()
Fig 6-2
How git reset will affect branches, index and working directory.
![]()
Fig 7-1
How git checkout affect HEAD, index, and working directory.
![]()
Fig 8-1
Take a snap using git tag.
The following sections will use this Git repository:
git://github.com/ossxp-com/gitdemo-commit-tree.git
View this git repository using gitg.
![]()
Fig 11-19
A more clear commit tree of this git repository.
![]()
Fig 11-20
Mark the commit tree with short commit ID, which is convenient for the following research on git rev-parse and git rev-list.
![]()
Fig 11-21
Mark the commit tree with color for git bisect research. Note: red represents bad, and blue represents good.
![]()
Fig 11-22
"Back to future" is my favorite movie. In this section I will show side effect of changing history, and how to change history using 3 different ways.
![]()
Fig 12-1
This section contains 3 parts, and each part has 2 scenes.
The current commit tree:
Fig 12-2
Scene 1: change history (throw awy "bad" commit D) like the following commit tree using one type of time machine.
Fig 12-3
Scene 2: change history (merge commits C and D) like the commit tree below using another type of time machine.
Fig 12-4
The first type of the time machine is git cherry-pick :
After scene 1, the history looks like:
Fig 12-5
After scene 2, the history looks like:
Fig 12-6
The second type of time machine is git rebase.
The third type of time machine is git rebase -i.
Throw away history using git commit-tree and git rebase.
After threw away commits before commit A:
![]()
Fig 12-7
Don't put all your eggs in one basket. Create multiple baskets for your repository using git clone.
![]()
Fig 13-1
Exchange data between neighborhook workspace. git pull works but git push cause trouble.
![]()
Fig 13-2
Clone as a bare repository, then exchange data with it. git push works for this case.
![]()
Fig 13-3
Initiate a bare repository, then exchange data with it.
![]()
Fig 13-4
When git gc --auto runs, git will check directory .git/objects/17, if there are over 27 loose objects in it.
Why using subdir "17", not others? I suppose Mr. Junio C Hamano show special respect to Linus as he's been elected as 17th most important person for the 20 century. Am I right?
This part will focus on multiple users' cooperation, so I call this part "Git harmoney".
How does the smart protocol work:
![]()
Fig 15-1
When encounter a non-fast-forward push, a fetch-merge-push operation like the following should be done.
![]()
Fig 16-1
![]()
Fig 16-2
![]()
Fig 16-3
![]()
Fig 16-4
How to resolve conflict with the help of kdiff3.
![]()
Fig 16-5
![]()
Fig 16-6
![]()
Fig 16-7
![]()
Fig 16-8
![]()
Fig 16-9
When two commits both change the name of the same file, merge will end up with a conflict. This section introduces how to resolve this kind of conflicts either by hands or by tools.
The following examples are from my subversion training courses, but they also can be used for Git.
Problem: bugfix without the help of release branch.
![]()
Fig 18-1
Resolution: use release/bugfix branch.
![]()
Fig 18-2
Problem: features developments mixed in one branch could cause chaos and withdraw some features also cause headache.
![]()
Fig 18-1
Resolution: use feature branches to seperate each feature development.
![]()
Fig 18-4
Problem: hacks against other project using vendor branch.
![]()
Fig 18-5
Resolution: Git with the help of Topgit. Talk about it later.
After user2 create user2/i18n branch, the repository looks like:
![]()
Fig 18-6
When user2 finished the development of the feature in branch user2/i18n, master branch also had some commits. The repository looks like:
![]()
Fig 18-7
If branch user2/i18n merges with master, there will be a new commit (merge commit), which adds more code review tasks. The repository after merge looks like:
![]()
Fig 18-8
Rebase before push at some situations is hightly recommended. The repository after rebase would look like:
![]()
Fig 18-10
Central cooperation model: multiple users works with one shared repository.
![]()
Fig 21-1
Work flow 1: all users work on one branch in the shared repository.
![]()
Fig 21-2
Work flow 2: each person create his/her own branch, then merge into master branch.
![]()
Fig 21-3
Discuss Gerrit later.
Distributed Model looks like a pyramid hierarchy:
![]()
Fig 21-4
Three SCM milestones of myself for the past several years:
works like:
![]()
Fig 22-1
When using Git+Topgit hacks other projects, the feature branches may look like:
![]()
Fig 22-2
And there wll be a base branch for each feature branch, all the topic base branches look like:
![]()
Fig 22-3
I hacked Topgit in Topgit way, all the topgit features look like:
![]()
Fig 22-5
URL of my hacked topgit: http://github.com/ossxp-com/topgit
Workflow of repo:
![]()
Fig 25-1
I hacked repo, and the improved repo can work directly with Git repository without the control of Gerrit.
URL of my hacked repo : http://github.com/ossxp-com/repo
Workflow of git-svn:
![]()
Fig 26-1
My hacked Gitolite is at: http://github.com/ossxp-com/gitolite
My hacked Gitolite is at: http://github.com/ossxp-com/gitolite
My hacked Gitosis is at: http://github.com/ossxp-com/gitosis
Fig 32-28: review task after publish
Gistore = Git + Store.
Gistore is a backup tool based on Git. I contribute the code at http://github.com/ossxp-com/gistore.
This figure is from http://www.survs.com/results/33Q0OZZE/MV653KSPI2.
![]()
Fig 40-1
How to use non-English character in commit log and as filename.
Cross platform project, should set core.ignorecase to true after git clone.
Two type of EOL: LF and CR+LF.
Git notes used in github.com:
![]()
Fig 41-1