Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

UNIX UNLEASHED PHẦN 6 docx
PREMIUM
Số trang
132
Kích thước
833.9 KB
Định dạng
PDF
Lượt xem
1499

UNIX UNLEASHED PHẦN 6 docx

Nội dung xem thử

Mô tả chi tiết

Part VI — Advanced File Utilities

Source Control with SCCS and RCS

Archiving

Backups

 30 — Source Control with SCCS and RCS

 By Rachel and Robert Startin

 What Is Source Control?

 Basic Source Control Concepts

 Interacting with Source Control

 Locks—Mediating Conflict

 Revising the Trunk—Straight up the Tree

 Branches—Complicating the Tree

 Revision Numbers

 Merges—Controlling Parallel Changes

 Symbolic Names, Baselines, and Releases

 Using Releases to Replace Symbolic Names

 Introduction to RCS

 Interacting with RCS

 Initial Revisions

 RCS files

 Checking Out a File

 Checking In a File

 Examining Revision Details and History

 rcsdiff

 Keywords

 Locks—Mediating Conflict

 Branches—Complicating the Tree

 Merges—Controlling Parallel Changes

 Symbolic Names, Baselines, and Releases

 Introduction to SCCS

 Interacting with SCCS

 Initial Revisions

 SCCS files

 Checking Out a File

 Checking In a File

 Examining Revision Details and History

 Keywords

 Locks—Mediating Conflict

 Branches—Complicating the Tree

 Merges—Controlling Parallel Changes

 Extra SCCS Features

 Using Source Control for Backups

 A Simple Example

 Starting to Use Source Control

 Creating an Empty Source Control File and Adding

the Initial Revision

 Creating a Full Source Control File with Manually

Supplied Comments

 Creating a Full Source Control File with Command

Line Comments

 Modifying Files

 Lock, Modify, Check In

 Modify (Oops!), Lock, Check In—Recovering from

a Mistake

 Shipping a Prerelease

 Recording a Configuration with RCS

 Using SCCS for a Prerelease

 Release 1

 A Complex Example

 Beginning Changes for Release 2

 Creating Patches for Release 1 and Alpha

 Merging Patches into the Trunk

 Merging with rcsmerge

 Merging with SCCS and merge

 Receiving Patches from Others and Merging Them

 Merging with co

 Using SCCS and merge

 Requiring Proper Authorization for Changes (SCCS Only)

 Shutting Down Development on Release 1 (SCCS Only)

 Using make with Source Control

 Default Rules

 Rules Using Time Stamps

 Summary

30 — Source Control with SCCS and RCS

By Rachel and Robert Startin

This chapter covers the basic concepts of source control. These concepts apply to almost

any system that does source control and should help you even if you use a system for

source control other than the ones described here. You will learn the specific structure

and commands used by two widely available source control systems: Revision Control

System (RCS) and Source Code Control System (SCCS).

You will also learn, through examples, how source control can be used. One example

covers the use of source control on a simple software project that has only a single active

version. Another covers the complexity added when you continue to make revisions to a

prior release while still doing development. Yet another example covers how you can use

source control to work on documents. Finally, you will learn how to use source control to

perform simple backups of critical files.

What Is Source Control?

Source control refers to controlling the process of modifying software by mediating

changes. It lets you control who can make changes and when. It helps to prevent conflict

that could arise when many people edit the same file. It lets you save multiple versions of

a file and choose the one you would like to use. It lets you review the history of changes

made to a file. It lets you save configurations, or baselines, which are lists of collections

of files and revisions that are part of a common release.

This section introduces some of the functions of source control and the need for those

functions. It helps answer the question What are the advantages of source control?

Normally, you want to use the most recent version of a file, but using source control

gives you flexibility and the ability to examine the history of changes that went into a

file. There are some important advantages to this.

If you are using UNIX to do software development, you may need to support older

releases of your product. Using source control, you can recall the exact sources that were

used to build the older release and use those files to track down and fix the problem.

After you fix the problem in the old release, you can merge the changes, as appropriate,

into the current release.

Source control also gives you the ability to review the history of changes to a file. This is

useful for almost any evolving file, be it source code or the files used to create a book.

You can also use source control to perform a limited personalized backup of critical files.

If your system is backed up once a week and you write daily progress notes, you can

check the notes into a source control system and have a safe copy in case you

accidentally erase or damage the file. This is not a replacement for doing system backups

because you will still be vulnerable to system or disk problems, but it does give you finer

control over recovering from your own mistakes.

By saving the history of revisions to a file, you give yourself the ability to analyze that

history later. This can be invaluable for software projects because it gives you the ability

to see the logic of each incremental change that led from the original source to the current

source.

The ability to recreate old versions of a single file or a group of files allows you to use

source control as a simple backup system and to recover and modify earlier releases of a

product or document.

Source control systems usually allow some form of branching (see the section "Basic

Source Control Concepts") that gives you the ability to produce variants of a file. This

gives you the capability to perform parallel development of two different variants of the

same file. For example, while working on the 2.0 release of your product you can

produce a maintenance update to the 1.0 release of your product by modifying one or

more of the source files from the 1.0 release. You can merge the changes to the 1.0

release into the 2.0 release if you desire.

Source control systems are good tools for controlling all sorts of files, not just source

code. This chapter was edited and produced using source control with one file containing

each section. The final copy of the chapter was produced using make to merge the

sections together and reformat them to meet the publisher's submission guidelines. This

allowed both authors to work independently to a certain extent and to merge changes

after reviews.

Basic Source Control Concepts

Source control systems store files as a series of revisions (in SCCS they're called deltas),

a set of documents that evolved from each other, as a tree. See Figure 30.1 for a generic

example. Refer to this figure as you read this section on source control concepts. Each

node in the tree represents a revision of the same file.

Figure 30.1. A tree of revisions.

NOTE: RCS uses the term revision and SCCS uses the term delta. The two terms

can be used interchangeably. This chapter uses the RCS terms except when explicitly

discussing SCCS. Definitions of terms used in RCS include the SCCS term in parenthetic

comments.

The tree has a root, which is the original text of the file. In Figure 30.1, the node labeled

root is the root. The trunk of the revision tree is the main sequence of revisions of the file

that were derived from the root. In Figure 30.1, the node root and all of the nodes in a

straight line above it (branch_start, a_revision, and head) are the trunk of the tree. The

simplest form of revision control will have only a root and a trunk. For example, if you

are developing a single document and want to save the development history, you are

likely to only use the trunk for storing edits.

A branch occurs where a single revision has two or more revisions derived from it. In

Figure 30.1, the node labeled branch_start is a trunk node that has a descendent on the

trunk and a branch starting at node branch_node. Each branch and the trunk have a head,

which is the latest revision on the branch. In Figure 30.1, the nodes head and

branch_head are the respective heads of the trunk and a branch. Branches are useful when

you need to split into parallel development paths for your file. You will learn more about

branches in the section "Branches—Complicating the Tree."

Interacting with Source Control

There are several common interactions with a source control system that everyone who

uses source control needs to understand.

In order to use a copy of a file, you need to check out (in SCCS, get) the file, or ask the

source control system for a copy of a particular revision of a file. You will need to check

out a file if you want to read its contents, print it out, or use it as part of a make.

In order to modify a copy of a file, you need to check out with a lock (in SCCS, get for

edit) to tell the source control system that you intend to make a modification to the file.

See the section "Locks—Mediating Conflict" for more information on how and why

locks are useful.

In order to register your changes with the source control system, you need to check in (in

SCCS, delta) the file. This registers your changes with the source control system and

makes them available for anyone else using the source control system.

Locks—Mediating Conflict

Source control systems enable you to place a lock on a revision, which indicates that you

intend to modify the file. This helps to prevent loss of changes when two people attempt

to modify a file at the same time. For other possible solutions to this problem, see the

sections "Branches—Complicating the Tree" and "Merges—Controlling Parallel

Changes."

Although both RCS and SCCS use locks, some source control systems do not explicitly

use locks. Notably (and perhaps confusingly), the free CVS, which uses RCS for

managing revisions, does not use locks; many commercial source control or configuration

management systems also do not use locks. Instead they include tools that allow you to

deal with problems after the fact. This usually includes some form of automatic merging

with a manual review of conflicts. The section "Merges—Controlling Parallel Changes"

describes this alternative in greater detail.

See Figures 30.2 and Figure 30.3 for the progression of a typical conflict.

Figure 30.2. Unresolved conflicting changes.

Figure 30.3. Using locks to prevent conflicts.

In the first time line (Figure 30.2) there is no revision locking. Arthur grabs a copy of

revision root of foo and begins editing it. While he is making changes, Beverly also grabs

a copy of revision root of foo and begins making her changes, independently of Arthur.

Arthur checks in his changes as revision root+a, reports to his manager that the changes

are complete, and confidently flies to Belize for his two-week scuba diving vacation.

Beverly checks in her changes as revision root+b, which now contains none of Arthur's

changes! Charlie, their manager, discovers that Arthur's changes are not in the weekly

release and calls Arthur to find out why, completely ruining Arthur's vacation. Note that

even though revision root+b is the descendent of root+a, it doesn't contain the changes

Arthur made.

Compare this with the second time line (Figure 30.3). Arthur grabs a copy of revision

root of foo, setting a lock on that revision, and begins editing it. While he is making

changes, Beverly tries to grab a copy of revision root of foo, but the source control

system informs her that the revision is locked and that she is not allowed to check it out.

Beverly waits for Arthur to finish, or if her changes are urgent, she contacts Arthur to

work out a way to get her changes done quickly. Arthur checks in his changes as revision

root+a, reports to his manager that the changes are complete, and blissfully flies to

Australia for his four-week scuba diving vacation, on which he is spending the bonus he

received for implementing a source control system for the company. Beverly learns that

foo is no longer locked and checks out revision root+a with lock. Beverly checks in her

changes as revision root+a+b, which contains both her modifications and Arthur's.

Charlie notices that Arthur's changes are in the weekly release and remembers what a

great thing it was that they finally implemented that source control system after Arthur's

previous vacation.

Revising the Trunk—Straight up the Tree

Many efforts that use source control require only the use of modifications to the trunk. If

your needs do not require parallel efforts (see the section "Branches—Complicating the

Tree") you should be able to manage your revisions without any of the complications

introduced by branches. If you develop on the trunk, you will create an initial root

revision of your file and then each time you change the file, you will check in a new

trunk revision of the file.

See Figure 30.4 for a sample tree that uses modifications to the trunk only. In the sample

tree, each revision was created by modifying the previous revision, and all modifications

were done serially; there was no overlap between edits on the file.

Figure 30.4. Straight up the tree.

Branches—Complicating the Tree

As you have learned, branches are used when you need to split into parallel modification

paths for your file. Often this happens when you need to produce patches for a released

version of the file (or product built using the file). It can also happen when you wish to

create a parallel track for doing a major long-term effort. For example, if you are creating

an internationalized version of your application while doing development on the

application itself, you might want to make the internationalization changes on a stable

base and check them in as branches. You would then merge them into the trunk

development. See the section on "Merges—Controlling Parallel Changes" for information

on how to merge changes from branches back into the main trunk.

See Figure 30.5 for an example of a revision tree that has branches. For this project, there

is a main line of development that is targeting the next product release and a branch on

product development that is producing patches to the previous release. The previous

release patches are made as a branch based on the revision of the file that was released.

Often, you will want to merge changes from a branch back into the trunk. See the section

"Merges—Controlling Parallel Changes" for more information on how this works. (This

example will be given in greater detail in the section "A Complex Example.")

Figure 30.5. A revision tree with branches.

RCS actually supports an even more flexible branching scheme. See "Introduction to

RCS" for more information.

Revision Numbers

Most source control systems, including both RCS and SCCS, name revisions using

revision numbers, which describe where the revision is in the tree of revisions. See Figure

30.6 for an example of how both RCS and SCCS number a revision tree. Notice that this

figure is the same tree as Figure 30.5, with revision numbers replacing the earlier names.

A revision on the main trunk is identified by a pair of numbers. The release number is

often used to specify an internal release number for the product. The level number

specifies which revision within a release is being referenced. The release and level

numbers are there to allow a structure that has the release number incremented each time

the product is released.

Figure 30.6. Revision numbers.

Branches extend this naming structure using the same release and level as the

branchpoint, the revision on which the branch is based (nodes 1.1 and 1.2 in the figure).

Branches add a branch number to identify the particular branch and a sequence number to

identify the revision within the branch. The first branch from revision R.L is numbered

R.L.1.1.

NOTE: The terms branch and sequence for revision numbers in branches are

actually from SCCS. The RCS documentation does not use specific terms here. Because

RCS largely uses the same revision model as SCCS, this chapter uses the SCCS terms.

Merges—Controlling Parallel Changes

You may also be effectively performing parallel development by releasing your files

(rather than access to the source control system) to other people. This can happen when

you send out preliminary versions of a document for review or when you do a release of

the source code for a project or product. After you have made your own postrelease

changes, you may find that people with access to the released files suggest changes to

you. One way to deal with this is to use merge facilities of your source control system,

which support merging sets of changes that have a common base.

See Figure 30.7 for an example of parallel revisions and merging them. In this example,

instead of using a source control system you use the merge command. Many source

control systems use merge or a similar program to perform the merging task. If your

source control system does not explicitly support merges, you can use the merge

command to perform merges manually.

Figure 30.7. Merging parallel changes.

NOTE: The source for merge is included in the RCS package on the CD-ROM. If

your system doesn't have merge, you may want to install merge even if you don't plan to

use RCS.

For this example, you should create three files, called base, revmain, and revbranch. The

first is the base from which both of the others are created. The common ancestor revision

is needed so the merge program can determine the changes from base to revbase and

from base to revmain and merge the changes together. The file base should contain the

following:

A line in the base file

Another line in the base file

A third line in the base file

The final line of the base file

The file revmain should contain the following:

A line in the base file

A line added in revmain

Another line in the base file

A third line in the base file

The final line of the base file

The file revbranch should contain the following:

A line in the base file

Another line in the base file

A third line in the base file

A line added in revbranch

The final line of the base file

After you create these three files, type merge -p revmain base revbranch > merged. When

you look at the resulting file merged, you should see the following:

A line in the base file

A line added in revmain

Another line in the base file

A third line in the base file

A line added in revbranch

The final line of the base file

Because the merge process is automated and not intelligent, it can run into problems

trying to merge changes that are in conflict. Try rerunning the merge command after

changing the contents of revbranch to the following:

A line in the base file

A line added in revbranch

Another line in the base file

A third line in the base file

The final line of the base file

This time you should wind up with significantly different results. First, you should get a

warning message from merge that says something like this: merge warning: overlaps or

other problems during merge. Second, the file merged should look something like this:

A line in the base file

<<<<<<< revmain

A line added in revmain

=======

A line added in revbranch

>>>>>>> revbranch

Another line in the base file

A third line in the base file

The final line of the base file

When you try to merge files that have overlaps of the changed areas of the file, you will

need to resolve the conflicts. You will need to manually review the merged file for all of

the conflict areas marked. Some commercial source control systems and other products

include graphical tools to help perform and verify merges.

Symbolic Names, Baselines, and Releases

A symbolic name is a name that is attached to a particular revision of a file and that you

can use to check out the desired revision of a file without having to know the exact

revision number. For example, if you send out for review copies of your great American

novel, you might want to attach symbolic names to the revisions of the chapters you sent

out so you can effectively use any editorial comments you get back.

SCCS does not support symbolic names. Some uses of symbolic names can be

replaced by using SCCS release numbers. For other uses it is possible to replicate the

behavior of symbolic names by keeping the correspondence between names, files, and

revision numbers in an outside file or database and implementing scripts that will

perform SCCS operations based on that configuration information.

See Figure 30.8 for an example of how you might use symbolic names to record reviews

of your novel. Your novel in this example has three chapters. For the first review, you

sent revision 1.3 of Chapter 1 and only had the original outlines for Chapters 2 and 3

(both revision 1.1). You used the name REVIEW1 for this review. For the second review,

you had made minor changes to Chapter 1 (in revision 1.4) and had written Chapter 2

(revision 1.3) and drafted Chapter 3 (revision 1.2). This review was marked REVIEW2.

You can now use the REVIEW1 and REVIEW2 names to refer to the correct versions of

the novel to remember which revision of which chapter that meant. Revision names are a

powerful tool for performing baselines and releases.

Figure 30.8. Symbolic names.

A baseline is a captured set of revisions that have some special property. That property

might be "sent out for review," "compiles successfully," "passes lint successfully,"

"released for alpha testing," or anything that you find useful. In the example on symbolic

names, the files of REVIEW1 and REVIEW2 were baselines. A release is really a special

kind of baseline with the property "released," and you can decide exactly what you mean

by released. Often, when you declare a release, you will check in new trunk revisions of

all of your files so that you can use release numbers on source control commands.

Using Releases to Replace Symbolic Names

Without symbolic names you can achieve a similar effect using release numbers. Every

time you ship out your novel for review, you increase the revision number of all files

after the release. This allows you to use checkout commands that name the release, which

in both RCS and SCCS check out the highest level within a release. In this example, after

shipping release, you check in the next revision of the file as release 2, level 1. Therefore,

instead of REVIEW1, you use release 1, which includes chap1 revision 1.3, chap2

revision 1.1, and chap3 revision 1.1. When you make you minor revisions to chap1, you

check them in as revision 2.1. When you write and then rewrite chap2, you check it in as

revision 2.1 and then as 2.2. When you draft chap3 you check it in as revision 2.1. Instead

of REVIEW2, you use release 2, which includes chap1 revision 2.1, chap2 revision 2.2,

and chap3 revision 2.1. This achieves the same effect (but with slightly more effort) as

using symbolic names. Unfortunately, this approach is not always able to replace

symbolic names. If you have checked in a new revision of a file using the old release

number before deciding that you want to release the files, you may face some difficulties

using this method.

Introduction to RCS

RCS was originally designed and developed by Walter Tichy of Purdue University as a

version control system intended primarily for source code, documents, and test cases.

Since its original release, the system has evolved somewhat over the years, but it

maintains a great deal of backward compatibility with the initial release. The most

popular current version is probably GNU RCS 5.6. RCS addresses several areas that are

not well covered by SCCS, such as merging branches and marking baselines and

configurations.

RCS is not available by default on all platforms, and only old versions are available on

others. The 5.6.0.1 version of GNU RCS is included on the CD-ROM in case you need (a

newer version of) RCS on your system.

Interacting with RCS

The basics of RCS are simply checking in a version of your file (ci), and checking out a

version of your file (co). If you are a first-time user working alone, you may never need

to do more. Viewing the history (rlog) and comparing changes from one revision to

another (rcsdiff) may be useful to you. As your needs grow, you can start using branches

and merging. If you are in a multiperson project, you should start using locking.

Depending on the level of detail you need, RCS can be peripheral or central to your

development environment.

Initial Revisions

In order to start using RCS to control revisions of a particular file, you need to create an

initial revision, which is the root of the revision tree for this file. Maybe you have already

created and edited a file. Now you realize that your development will be enhanced by

using RCS. Or you may be planning ahead, just trying to get a project started, and you

have no file contents yet. You would like to create an RCS file and you will check in an

initial revision later.

In the first case, you have a file with contents. In RCS terminology, this is your working

file. You can create an initial revision by using the RCS check-in command, ci. RCS will

save the working file as the initial revision and prompt for a description of the revision

group. Your working file is then removed from your directory.

In the second case, you have a file name but no contents. You can create an RCS file with

the command rcs -i. RCS will prompt for the revision group description. Later, when you

have some file contents, you can do an initial check in using ci. For now, there is no

initial revision.

RCS files

RCS views your file as a pair of files. The file that you have named and to which you

make changes is called the working file. You create this file in a directory of your

choosing. When you check in this file, RCS creates an RCS file (if this is the first check

in) or adds to an existing RCS file. The RCS filename is simply your working filename

with a suffix added to the end. The default suffix on UNIX systems is usually v. You can

control the suffix of a file via the -x option during check in. This option lets you specify a

list of possible suffixes that will be tried, in order, during check in and check out.

RCS commands enable you to specify one of or both the working file and the RCS file. It

is common to specify only the working file and let RCS handle the placement of the RCS

file. If the RCS file is not specified, RCS first tries to deposit the revision in a

subdirectory, RCS. If no such directory exists, the revision is placed in the current

working directory. Creating a directory called RCS in your working directory helps to

organize your work. All the RCS files are kept in this directory, out of sight.

Checking Out a File

To use a file you have under RCS control, you must check it out via the RCS command

co, which causes RCS to copy the revision of the specified file into a working file. Then

you can use the file, for example, for printing or compiling. But if you want to make

changes to this file, you must obtain a lock for the file. You can check out a file with a

lock via co -l. See the section "Locks—Mediating Conflict" for details of using locks.

Checking In a File

To save a version of your working file after making changes, use the ci command. If you

want to keep a copy of the working file around to use, you can add the -u option. This is

just like doing a ci, followed by a co. Whenever you do a ci, you will be asked to enter a

log message, a description of the changes you have made. This is for your (and your co￾workers') use. Keep in mind that a short phrase might be very meaningful now, but these

logs may be perused down the road. The more specific you are now, the easier it will be

to figure out revision contents later.

It is common to check in several files at once, perhaps ones that are related to one

another. For example, you are fixing a defect in your product, and several files must be

modified to solve the problem. You check out the files as needed and work in your

working directory until the product defect is fixed. You test your solution. When you are

convinced that everything works, you want to check in the changes. It could be tedious to

enter a log message for each file as it's checked in. When you check in more than one file

at once, after the first file, RCS asks if you want to use the same log as the previous file.

This speeds things up a bit. To totally automate the check in, you can specify the log

message via the check in command's -m option. So if the log message is to be the same

for each file, using the -m option to specify the log message, along with shell

metacharacters to specify all the working files, can shorten a huge job so that it takes only

a single command.

TIP: If you have a lengthy log message that is common to more than one file,

enter the text of the message into a file. Then on the check in command line, use -m'cat

filename' to specify that the contents of the file filename should be used as the log

message

Tải ngay đi em, còn do dự, trời tối mất!
UNIX UNLEASHED PHẦN 6 docx | Siêu Thị PDF