Version Control
Diomidis Spinellis
Department of Management Science and Technology
Athens University of Economics and Business
Athens, Greece
dds@aueb.gr
Version Control
- Tracks project across time
- Collaboration, documentation, undo
- Open source systems in order of increasing capabilities
- RCS
- CVS
- Subversion, Git, Mercurial, Bazaar
The Great Debate
- Centralized (CVS, Subversion)
- Single source of truth
- Pre-commit checks
- Distributed (Bazaar, Git, Mercurial, darcs)
- Can work off line
- Easier participation (no committer bit)
- Cheap local commits
Version Control Operations
- Central repository keeps historical data
- A commit or check-in adds a change into the repository
- A pull or update or check-out
retrieves a version from the repository
- Versions are tracked with version numbers or hashes
- Numeric or hashes: automatically assigned
- Symbolic: assigned by humans to track milestones
- On some VCSs Keywords in the source files are automatically
expanded, identifying version, status, author, etc.
Branching
- Development can split into different branches e.g.
- Trunk or head
- Stable or release
- Feature
- Vendor
- Branches can join again
Revision Tree Example
cat.c revision tree
Life Under a VCS
- Import or clone or checkout
- Update or synchronize or pull
- Commit
- (Optional) push
- Label or tag
The Goodies
- Identify conflicting changes
- Versioning:
- Annotated listings
- Version history
- File differences
- Branching
- Source of truth
- Metrics
Example of a Change Log
RCS file: /cvsroot/basesrc/bin/cat/cat.c,v
Working file: cat.c
head: 1.28
branch:
locks: strict
access list:
symbolic names:
netbsd-1-5-PATCH002: 1.23
[...]
netbsd-1-5: 1.23.0.4
[...]
netbsd-1-2-BETA: 1.11
netbsd-1-2-base: 1.11
netbsd-1-2: 1.11.0.6
[...]
keyword substitution: kv
total revisions: 33; selected revisions: 33
description:
----------------------------
revision 1.28
date: 2001/09/16 12:12:13; author: wiz; state: Exp; lines: +6 -4
Some KNF, via patch by Petri Koistinen in private mail.
----------------------------
revision 1.27
date: 2001/07/29 22:40:57; author: wiz; state: Exp; lines: +6 -6
Some style improvements. [Nearly] #13592 by Petri Koistinen.
[...]
----------------------------
revision 1.15.2.1
date: 1998/02/08 21:45:36; author: mellon; state: Exp; lines: +18 -9
Pull up 1.16 and 1.17 (kleink)
Example of a File Difference List
$ cvs diff -c -r1.12 -r1.13 basesrc/bin/cat/cat.c
Index: basesrc/bin/cat/cat.c
===================================================================
RCS file: /cvsroot/basesrc/bin/cat/cat.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -c -r1.12 -r1.13
[...]
***************
*** 136,141 ****
--- 136,142 ----
fp = stdin;
else if ((fp = fopen(*argv, "r")) == NULL) {
warn("%s", *argv);
+ rval = 1;
++argv;
continue;
}
Example of an Annotated Listing
1.166 (jhb 16-Oct-02): fdp = p->p_fd;
1.114 (alfred 13-Jan-02): FILEDESC_LOCK(fdp);
1.157 (iedowse 02-Sep-02): if ((unsigned)fd >= fdp->fd_nfiles ||
1.157 (iedowse 02-Sep-02): (fp = fdp->fd_ofiles[fd]) == NULL) {
1.114 (alfred 13-Jan-02): FILEDESC_UNLOCK(fdp);
1.106 (dillon 01-Sep-01): error = EBADF;
1.106 (dillon 01-Sep-01): goto done2;
1.106 (dillon 01-Sep-01): }
1.157 (iedowse 02-Sep-02): pop = &fdp->fd_ofileflags[fd];
1.94 (dillon 18-Nov-00):
1.157 (iedowse 02-Sep-02): switch (cmd) {
1.1 (rgrimes 24-May-94): case F_DUPFD:
1.241 (rwatson 07-Aug-04): /* mtx_assert(&Giant, MA_NOTOWNED); */
1.158 (jhb 03-Sep-02): FILEDESC_UNLOCK(fdp);
Extracting Metrics
- Changes per source file
- Changes per author
- Authors per source file
- Lines per day
- Changes corresponding to bug categories
Tracking Example
Maintainability index over time in the FreeBSD kernel.
Best Practices
- Put everything under version control
- Use VCS on your personal projects
- Think carefully about file name and organization
- Perform one separate commit for every change
- Label all releases
- Establish and follow policies and procedures
Subversion Cheat Sheet
(Results appear after the # sign.)
Create Repository
pwd
# /home/dds
svnadmin create repo
chmod -R go+rwX repo/
Create Project Structure
mkdir template
cd template
mkdir myproject
cd myproject/
mkdir trunk tags branches
cd ..
pwd
# /home/dds/template
ls
# myproject
Initial Addition of a Project to the Repository
pwd
# /home/dds/template
svn import . file:///home/dds/repo/ --message 'Initial repository layout'
# Adding myproject
# Adding myproject/trunk
# Adding myproject/branches
# Adding myproject/tags
#
# Committed revision 1.
cd ..
Initial Checkout from the Repository
pwd
# /home/dds/
mkdir work
cd work
svn co file:///home/dds/repo/myproject
# A myproject/trunk
# A myproject/branches
# A myproject/tags
# Checked out revision 1.
ls
# myproject
Add a File to the Project
pwd
# /home/dds/work
cd myproject/trunk
echo hi >file.txt
svn add file.txt
# A file.txt
svn commit --message 'Added file.txt'
# Adding trunk/file.txt
# Transmitting file data .
# Committed revision 2.
Tag a Release and Create a Branch
svn copy file:///home/dds/repo/myproject/trunk file:///home/dds/repo/myproject/tags/version-1.0 --message 'Tag version 1.0'
# Committed revision 3.
svn copy file:///home/dds/repo/myproject/trunk file:///home/dds/repo/myproject/branches/bug-fix-r1.0 --message 'Branch version 1.0 for bug fixes'
# Committed revision 4.
Update with Changes
cd ..
pwd
# /home/dds/work/myproject
svn up
#A branches/bug-fix-r1.0
#A tags/version-1.0
#Updated to revision 4.
Commit a Change
echo hello >file.txt
svn up
# At revision 5.
svn commit -m 'Made greeting more formal'
#Sending trunk/file.txt
#Transmitting file data .
#Committed revision 5.
Git Cheat Sheet
(Results appear after the # sign.)
Create Repository
pwd
# /home/dds
git init repo
chmod -R go+rwX repo/
Create Project
cd repo
mkdir myproject
cd myproject
pwd
# /home/dds/repo/myproject
Add a File to the Project
pwd
# /home/dds/repo
cd myproject
echo "My project repo." >README
git add README (or git add . to include every file present.)
git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: README
#
git commit -m 'README file for repo.'
#[master (root-commit) 138f654] README file for repo.
#1 files changed, 1 insertions(+), 0 deletions(-)
#create mode 100644 README
echo "TODO: configure the repo in $GIT_DIR/config." >>README
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: README
#
# no changes added to commit (use "git add" and/or "git commit -a")
git commit -a -m 'Updated README file.'
#[master 1376204] Updated README file.
#1 files changed, 1 insertions(+), 0 deletions(-)
Create a Branch
git branch
#* master
git branch bug-fixing
git branch -a
# bug-fixing
#* master
Initial Checkout from the Repository
pwd
# /home/dds/
mkdir work
cd work
git clone file:///home/dds/repo
#Cloning into repo...
#remote: Counting objects: 306, done.
#remote: Compressing objects: 100% (92/92), done.
#remote: Total 306 (delta 214), reused 306 (delta 214)
#Receiving objects: 100% (306/306), 213.91 KiB, done.
#Resolving deltas: 100% (214/214), done.
ls
# repo
Update with Changes
pwd
#/home/dds/work/repo/myproject
git pull
#Already up-to-date.
Work with Branches
pwd
#/home/dds/work/repo/myproject
git checkout bug-fixing
#Branch bug-fixing set up to track remote branch bug-fixing from origin.
#Switched to a new branch 'bug-fixing'.
Commit a Change
pwd
#/home/dds/work/repo/myproject
git branch
#* bug-fixing
echo "TODO: Improve layout in README." >>README
git commit -a -m 'New TODO in README.'
#[bug-fixing d758c7f] New TODO in README.
# 1 files changed, 1 insertions(+), 0 deletions(-)
git push
#Counting objects: 5, done.
#Delta compression using up to 2 threads.
#Compressing objects: 100% (2/2), done.
#Writing objects: 100% (3/3), 324 bytes, done.
#Total 3 (delta 0), reused 0 (delta 0)
#Unpacking objects: 100% (3/3), done.
#To file:///home/dds/repo/
#c6439c5..d758c7f bug-fixing -> bug-fixing
Tag a Release
pwd
#/home/dds/work/repo/myproject
git tag "v1.1"
git push --tags
#Total 0 (delta 0), reused 0 (delta 0)
#To file:///home/dds/repo/
# * [new tag] v1.1 -> v1.1
More Resources
Further Reading
- Bryan O'Sullivan.
Making sense of revision-control systems.
Commun. ACM, 52(9):56–62, 2009.
(doi:10.1145/1562164.1562183 (http://dx.doi.org/10.1145/1562164.1562183))
- M. J. Rochkind.
The source code control system.
IEEE Transactions on Software Engineering, SE-1(4):255–265,
1975.
- Diomidis Spinellis.
Software
engineering glossary, version control, part 2.
IEEE Software, 22(6):c2–c3, November/December 2005.
(doi:10.1109/MS.2005.169 (http://dx.doi.org/10.1109/MS.2005.169))
- Diomidis Spinellis.
Software
engineering glossary, version control, part I.
IEEE Software, 22(5):107, September/October 2005.
(doi:10.1109/MS.2005.141 (http://dx.doi.org/10.1109/MS.2005.141))
- Diomidis Spinellis.
Version
control systems.
IEEE Software, 22(5):108–109, September/October 2005.
(doi:10.1109/MS.2005.140 (http://dx.doi.org/10.1109/MS.2005.140))
- Walter F. Tichy.
Design, implementation, and evaluation of a revision control system,.
In Proceedings of the 6th International Conference on Software
Engineering. IEEE, September 1982.