Title: Version Control Abstract Data Types
1Version ControlAbstract Data Types
2Outcomes Version Control
- Applying RCS and SCCS, by Don Bolinger and Tan
Bronson, on reserve in the library. Official RCS
homepage www.cs.purdue.edu/homes/trinkle/RCS/ - Version Control with Subversion, Ben
Collins-Sussman, Brian W. Fitzpatrick, C. Michael
Pilato - http//svnbook.red-bean.com/
- After the conclusion of this section you should
be able to - Use RCS for personal version control for personal
projects, and for collaboration on small projects - Understand the principles of version control, so
that other VC systems (CVS, Subversion, ...) can
be mastered quickly
3Source File Modification Cycle
Create or Modify file
Test the modified file
no
Tests Succesful?
yes
Capture result
4Managing Source Code Files and Revisions
- Very important to be able to trace the changes
made throughout the life of software - May want to revert to a previous version of a
file, in the event of a problem, or simply to
compare versions - Could create a backup of each version
- Better way is to have changes to a file tracked
for us - this is what version control does
5Modification Cycle with Archiving
Get existing revision
Modify
Test
Capture
Save modified file as new revision
Get existing revision
Modify
Test
Capture
Save modified file as new revision
6Goals of Source Control
- Ability to record file revisions
- Ability to retrieve previous file revisions
- Control over new revision creation
- sometimes need to modify older version
- Ability to record why a new revision was made
- Control of file modification
- Prevent conflicting modifications
- Easy access to all file revisions
- all revisions kept in a single file
7SCCS, RCS, CVS
- There are many revision control systems
- SCCS
- available on most commercial Unices, but not on
Linux - RCS
- available on Linux and many BSD-based Unices
- very popular for personal version control and
small projects - CVS
- Built on top of RCS
- Manages groups of files and projects distributed
over a network better than RCS - Widely used for Open Source projects, however,...
8Subversion
- Since August 2001
- Open source, all platforms
- Addresses limitations of CVS
- Features include
- Directory versioning
- File renaming
- Plugs into Apache HTTP server
- ...
9The Problem of File Sharing
10Lock-Modify-Unlock Solution (eg. RCS)
11Copy-Modify-Merge Solution (e.g., Subversion,
CVS)
12(No Transcript)
13Basics of Source Control
- So what do I archive?
- dynamic source files
- files that can't be reconstructed from other
files - What don't I archive
- derived files
- static (read-only files)
14Basics of Source Control
- Nomenclature
- revision
- each archived version of a source file
- associated with a revision number
- check-in
- adding a new revision to an archive file
- check-out
- removing new revision from an archive file
- working file
- source file revision checked out
15Basics of Source Control
- Source file revision numbers
- n.m. major (n) and minor (m) revision numbers
- 1.1, 1.2, ...
- Not necessarily the same as release numbers
- Source file revision storage
- only one revision of source file stored in
literal form - all others stored as differences (or diffs) from
that single revision - saves disk space!
16Basics of Source Control
- Log
- archive file also contains reasons why each
revision was checked-in - Steps in source control
- create an archive file for each source file
- get a working file for reading
- source control system forces you to say
explicitly when you intend to modify a file
revision - OK if you just want to compile or read
- get a working file for modification
17Basics of Source Control
- Steps in source control (cont'd)
- get a working file for modification
- if no one else has that revision locked, it will
be locked in your name - if someone else has that revision locked, you
won't be allowed to lock it - while lock is set, no one else can modify that
revision - comparing a working file to its archive file
- adding a working file to an archive file
18Basics of Source Control
- Steps in source control (cont'd)
- discarding a working file
- can't just delete working file
- need also to remove lock
- viewing history of an archive file
19Basic Source Control Operations
Create an archive file
archive file exists
Get working file for reading
Get working file for modification
View working file history
Compare working file to archive file
keep changes ?
Discard working file
no
yes
Add working file to archive file
archive file updated
20RCS
- ci check in RCS revisions
- co check out RCS revisions
- rcs change RCS file attributes
- rcsdiff compare RCS revisions
- rlog print log messages
21RCS Basics
- Create an RCS directory in your development
directory - Place the file under source control
- ci filename
- Check out a file to make a change
- co -l filename
- Edit the file as normal (emacs filename)
- Compare working file to its RCS file
- rcsdiff filename
- Check the file back in, creating a new version
- ci filename
22RCS initial check in ci
- ci source.c
- enter description, terminated with a '.' or end
of file - Your description here
- .
- initial revision 1.1
- done
-
- Working file checked in to archive and deleted
23RCS check out for modification co
- co -l source.c
- RCS/source.c,v -- source.c
- revision 1.1
- done
-
- Latest revision checked out and stored in working
file
24Compare working file to RCS file
- rcsdiff source.c
- RCS file source.c,v
- retrieving version 1.1
- diff -r1.1 source.c
- .... (output from diff command)
- Can compare working file to any version
- rcsdiff -r1.3 prog.c
- Can compare any version to any other
- rcsdiff -r1.2 -r1.3 prog.c
25Discard working file
- rcs -u source.c
- RCS file source.c,v
- 1.1 unlocked
- done
- Can then remove working file
- rm source.c
26RCS check in ci
- ci source.c
- new revison 1.2 previous revision 1.1
- enter log message, terminated with a '.' or end
of file - Your messsage here
- .
- done
27RCS check in with implicit check out ci -l and
ci -u
- ci -l source.c
- Checks in source.c, and checks it out again with
a lock - ci -u source.c
- Checks in source.c, checks it out again without a
lock
28View history of RCS file
- rlog source.c
- RCS file source.c,v
- working file source.c
- head 1.2
- ...
- description
- ...
- revision 1.2
- date ..
- your log message
- revision 1.1
- date ...
- initial revision (default log message)
29Basic Source Control Operations
Create an archive file
ci
archive file exists
Get working file for reading
Get working file for modification
View working file history
co
rlog
co -l
Compare working file to archive file
keep changes ?
Discard working file
no
rcsdiff
rcs -u rm
yes
Add working file to archive file
ci
archive file updated
30RCS Identifiers
- RCS can put special strings inside your files, to
give version information - These strings automatically get updated each time
a new version is created - Place string markers inside your source files
(eg. in comments) - Id
- Gives information on version no., date,
author,... - Log
- Displays entire file history with version
description
31Version Control within emacs
- Use ctrl-x v v to register, check in/out
- Upon check-in, working file not erased, but
changed to read-only. - must check out in order to modify
- When checking in changes, enter log message into
window, and terminate with crtrl-c ctrl-c
32Outcomes Abstract Data Types
- Books on reserve
- C for Java Programmers, Chapter 11 (11.5) and C
Programming - a Modern Approach, Chapter 19 - After the conclusion of this section you should
be able to - Use opaque data types to create modules that
implement abstract data types
33Stack Module
- stack.h
- ifndef STACK_H
- define STACK_H
- void make_empty(void)
- int is_empty(void)
- void push(int i)
- int pop(void)
- endif
34Stack as array
- include "stack.h"
- define STACK_SIZE 100
- static int contentsSTACK_SIZE
- static int top 0
- void make_empty(void)
- top 0
-
- int is_empty(void)
- return top 0
35- static int is_full(void)
- return top STACK_SIZE
-
- void push(int i)
- if (is_full())
- fprintf(stderr, "push stack is full\n")
- exit(EXIT_FAILURE)
-
- contentstop i
-
- int pop(void)
- if(is_empty())
- fprintf(stderr, "pop stack is empty\n")
- exit(EXIT_FAILURE)
-
- return contents--top
36Stack as Linked List
- include "stack.h"
- typedef struct node
- int data
- struct node next
- NodeT
- static NodeT top NULL
37- void make_empty(void)
-
- NodeT next
- while(top ! NULL)
- next top-next
- free(top)
- top next
-
-
- int is_empty(void)
- return top NULL
-
38- void push(int i)
- NodeT newNode
- newNode malloc(sizeof(NodeT))
- if (newNode NULL)
- fprintf(stderr, "push stack is full\n")
- exit(EXIT_FAILURE)
-
- newNode-data i
- newNode-next top
- top newNode
-
39- int pop(void)
- NodeT oldTop
- int i
- if(is_empty())
- fprintf(stderr, "pop stack is empty\n")
- exit(EXIT_FAILURE)
-
- oldTop top
- i top-data
- top top-next
- free(oldTop)
- return i
40Stack Data Type
- Can only have one instance of preceding stack
modules - Need to create a stack type
- include "stack.h"
- int main()
-
- StackT s1, s2
- new_stack(s1)
- new_stack(s2)
- push(s1, 1)
- if (!is_empty(s1))
- printf("d\n", pop(s1)) / prints "1" /
- ...
41Stack Data Type
- stack.h
- typedef struct node
- int data
- struct node next
- NodeT
- typedef struct
- NodeT top
- StackT
- void new_stack(StackT s)
- void make_empty(StackT s)
- int is_empty(const StackT s)
- void push(StackT s, int i)
- int pop(StackT s)
42Stack Type as Linked List
- include "stack.h"
- void new_stack(StackT s)
- s-top NULL
-
- void make_empty(StackT s)
- NodeT next
- while(s-top ! NULL)
- next s-top-next
- free(s-top)
- s-top next
-
-
43- void push(StackT s, int i)
- NodeT newNode
- newNode malloc(sizeof(NodeT))
- if (newNode NULL)
- fprintf(stderr, "push stack is full\n")
- exit(EXIT_FAILURE)
-
- newNode-data i
- newNode-next s-top
- s-top newNode
-
44- int is_empty(const StackT s)
- return s-top NULL
-
- int pop(StackT s)
- NodeT oldTop
- int i
- if(is_empty(s))
- fprintf(stderr, "pop stack is empty\n")
- exit(EXIT_FAILURE)
-
- oldTop s-top
- i s-top-data
- s-top s-top-next
- free(oldTop)
- return i
45Stack Type
- The previous module allowed for multiple
instances, but at the expense of information
hiding! - Nothing prevents a client from using a StackT
variable as a structure - StackT s1
- s1.top NULL
- ...
46Opaque Data Type
- Incomplete structure definition
- can define the type of a structure that hasn't
been defined yet - typedef struct hidden Visible
- allows one to use the type Visible as a synonym
for struct hidden .
47Opaque Data Type
- A data type is opaque because the client cannot
access its full representation - all the client knows is that it is represented by
another data type - client doesn't know that that data type is
- Consider module Mod that exports a data type
called Abstract to the client - mod.h defines a type Abstract as a pointer to a
structure type called Concrete - typedef struct Concrete Abstract
- there is no definition of Concrete in this file
-
48Client
Implementation
mod.h
mod.c
typedef struct Concrete Abstract
typedef struct Concrete Abstract
struct Concrete ...
49Opaque Data Type
- The type Concrete is defined in an
implementation file - The client can use the type provided there are
no attempts to dereference values of this type - void f(Abstract p)
- is legal, but
- Abstract p
- p-x
- is illegal, because the type Abstract represents
a pointer to the Concrete type, and the compiler
has no information about this type
50Stack ADT Module
- 1) the type DataType of the data stored in the
stack is known to the implementation - 2) any number of stacks can be created all
stacks must have elements of the same type,
DataType - 3) the representation of the stack and stack
elements are not visible to the client. - The first version will operate on a stack of
integers.
51Stack ADT Header
- ifndef STACK_H
- define STACK_H
- typedef int DataType
- typedef struct StackCDT StackADT
- StackADT Stack_new(void)
- int Stack_empty(StackADT s)
- void Stack_push(StackADT s, DataType i)
- DataType Stack_pop(StackADT s)
- void Stack_free(StackADT s)
- endif
52Application of Stack ADT
- include "stack.h"
- StackADT s1, s2
- s1 Stack_new()
- s2 Stack_new()
- Stack_push(s1, 1)
- if (!Stack_empty(s1))
- printf("d\n", Stack_pop(s1))
- ...
53Stack ADT Implementation
- include "stack.h"
- typedef struct node
- DataType d
- struct node next
- NodeT
- typedef struct StackCDT
- int count
- NodeT top
- StackCDT
54Stack ADT Implementation
- StackADT Stack_new(void)
- StackADT s
- if((s malloc(sizeof(StackCDT))) NULL)
- exit(EXIT_FAILURE)
- s-count 0
- s-top NULL
- return s
-
- int Stack_empty(StackADT s)
- return s-count 0
55Stack ADT Implementation
- void Stack_push(StackADT s, DataType d)
- NodeT newNode
- if ((newNode malloc(sizeof(NodeT)))
NULL) - fprintf(stderr, "push stack is full\n")
- exit(EXIT_FAILURE)
-
- newNode-d d
- newNode-next s-top
- s-top newNode
- s-count
56Stack ADT Implementation
- DataType Stack_pop(StackADT s)
- DataType d
- NodeT oldNode
- oldNode s-top
- s-top oldNode-next
- s-count--
- d oldNode-d
- free(oldNode)
- return d
57Stack ADT Implementation
- void Stack_free(StackADT s)
- NodeT p, q
- for (p (s)-top p p q)
- q p-next
- free(p)
-
- free(s)
- s NULL
58Shallow and Deep Copy
- To push a new element d onto the stack
- newNode-d d
- If newNode-d and d are pointers, this results in
a shallow copy. - If client deallocates variable pointed to by d
then newNode-d becomes a dangling reference
59Shallow and Deep Copy
- For a deep copy, use a callback function
copyData_Stack() - For example, for strings and doubles
- DataType copyData_Stack(const DataType v)
- return strdup(v)
-
- DataType copyData_Stack(const DataType v)
- return v
-
60char strdup(const char s) / return a copy of
s / char kopy / copy of s /
if((kopy calloc(strlen(s) 1,
sizeof(char))) NULL) return NULL
strcpy(kopy, s) return kopy
61Shallow and Deep Copy
- We need another callback function,
freeData_Stack() - For example, for string and doubles
- void freeData_Stack(DataType v)
- free(v)
-
- void freeData_Stack(DataType v)
-
62Stack ADT Header with Deep Copy
- typedef char DataType
- typedef struct StackCDT StackADT
- DataType copyData_Stack(const Datatype v)
- void freeData_Stack(DataType v)
- StackADT Stack_new(void)
- int Stack_empty(StackADT s)
- void Stack_push(StackADT s, DataType i)
- DataType Stack_pop(StackADT s)
- void Stack_free(StackADT s)
63Stack ADT Header with Deep Copy
- Implementation of callback functions must be
provided by the client - DataType copyData_Stack(const Datatype v)
- void freeData_Stack(DataType v)
- They are declared in the header file so that the
implementation code can call them
64Stack ADT Implementation with Deep Copy
- void Stack_push(StackADT s, DataType d)
- NodeT newNode
- if ((newNode malloc(sizeof(NodeT)))
NULL) - fprintf(stderr, "push stack is full\n")
- exit(EXIT_FAILURE)
-
- newNode-d copyData_Stack(d)
- newNode-next s-top
- s-top newNode
- s-count
65Stack ADT Implementation with Deep Copy
- DataType Stack_pop(StackADT s)
- DataType d
- NodeT oldNode
- oldNode s-top
- s-top oldNode-next
- s-count--
- d copyData_Stack(oldNode-d)
- freeData_Stack(oldNode-d)
- free(oldNode)
- return d
66Stack ADT Implementation with Deep Copy
- void Stack_free(StackADT s)
- NodeT p, q
- for (p (s)-top p p q)
- q p-next
- freeData_Stack(p-d)
- free(p)
-
- free(s)
- s NULL