svn日常工作流程

The typical work cycle looks like this:

  1. Update your working copy.
    • svn update
  2. Make changes.
    • svn add
    • svn delete
    • svn copy
    • svn move
  3. Examine your changes.
    • svn status
    • svn diff
  4. Possibly undo some changes.
    • svn revert
  5. Resolve conflicts (merge others’ changes).
    • svn update
    • svn resolve
  6. Commit your changes.
    • svn commit

svn status

To get an overview of your changes before committing, you’ll use the svn status command. Here are a few examples of the most common status codes that svn status can return. (Note that the text following # is not actually printed by svn status.)

? scratch.c         # file is not under version control
A stuff/loot/bloo.h # file is scheduled for addition
C stuff/loot/lump.c # file has textual conflicts from an update
D stuff/fish.c # file is scheduled for deletion
M bar.c # the content in bar.c has local modifications

Command svn status does not contact the repository. Instead, they compare the metadata in the .svn directory with the working copy. There is the —show-updates (-u) option, which contacts the repository and adds information about things that are out of date:

$ svn status -u -v
M * 44 23 sally README
M 44 20 harry bar.c
* 44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
A 0 ? ? stuff/things/bloo.h
Status against revision: 46

svn status also has a —verbose (-v) option, which will show you the status of every item in your working copy, even if it has not been changed. Notice the two asterisks: if you were to run svn update at this point, you would receive changes to README and trout.c. This tells you some very useful information—you’ll need to update and get the server changes on README before you commit, or the repository will reject your commit for being out of date.

svn revert

Suppose while viewing the output of svn diff you determine that all the changes you made to a particular file are mistakes. Maybe you shouldn’t have changed the file at all, or perhaps it would be easier to make different changes starting from scratch.Subversion reverts the file to its premodified state by overwriting it with the cached “pristine” copy from the .svn area. But also note that svn revert can undo any scheduled operations

$ svn status README
$ svn delete README
D README
$ svn revert README
Reverted 'README'
$ svn status README

Resolve Conflicts (Merging Others’ Changes)

We’ve already seen how svn status -u can predict conflicts. Suppose you run svn update and some interesting things occur:

$ svn update
U INSTALL
G README
Conflict discovered in 'bar.c'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h) help for more options:

The U and G codes are no cause for concern; those files cleanly absorbed changes from the repository. The files marked with U contained no local changes but were Updated with changes from the repository. The G stands for merGed, which means that the file had local changes to begin with, but the changes coming from the repository didn’t overlap with the local changes. But the next two lines are part of a feature called interactive conflict resolution. This means that the changes from the server overlapped with your own, and you have the opportunity to resolve this conflict. The most commonly used options are displayed, but you can see all of the options by typing h:

(p) postpone - mark the conflict to be resolved later
(df) diff-full - show all changes made to merged file
(e) edit - change merged file in an editor
(r) resolved - accept merged version of file
(mf) mine-full - accept my version of entire file (ignore their changes)
(tf) theirs-full - accept their version of entire file (lose my changes)
(l) launch - launch external tool to resolve conflict
(h) help - show this list

Let’s briefly review each of these options before we go into detail on what each option means.

(p)ostpone
Leave the file in a conflicted state for you to resolve after your update is complete.
(d)iff
Display the differences between the base revision and the conflicted file itself in unified
diff format.
(e)dit
Open the file in conflict with your favorite editor, as set in the environment
variable EDITOR.
(r)esolved
After editing a file, tell svn that you've resolved the conflicts in the file and that
it should accept the current contents—basically that you've “resolved” the conflict.
(m)ine-(f)ull
Discard the newly received changes from the server and use only your local changes for
the file under review.
(t)heirs-(f)ull
Discard your local changes to the file under review and use only the newly received
changes from the server.
(l)aunch
Launch an external program to perform the conflict resolution. This requires a bit of
preparation beforehand.
(h)elp
Show the list of all possible commands you can use in interactive conflict resolution.

Before deciding how to attack a conflict interactively, odds are that you’d like to see exactly
what is in conflict, and the diff command (d) is what you’ll use for this:

Select: (p) postpone, (df) diff-full, (e) edit,
(h)elp for more options : d
--- .svn/text-base/sandwich.txt.svn-base Tue Dec 11 21:33:57 2007
+++ .svn/tmp/tempfile.32.tmp Tue Dec 11 21:34:33 2007
@@ -1 +1,5 @@
-Just buy a sandwich.
+<<<<<<< .mine
+Go pick up a cheesesteak.
+=======

+Bring me a taco!
+>>>>>>> .r32

The first line of the diff content shows the previous contents of the working copy (the BASE revision), the next content line is your change, and the last content line is the change that was just received from the server (usually the HEAD revision).

When you postpone a conflict resolution, svn typically does three things to assist you in noticing and resolving that conflict:

  1. Subversion prints a C during the update and remembers that the file is in a state of conflict.
  2. If Subversion considers the file to be mergeable, it places conflict markers—special strings of text that delimit the “sides” of the conflict—into the file to visibly demonstrate the overlapping areas. (Subversion uses the svn:mime-type property to decide whether a file is capable of contextual, line-based merging)
  3. For every conflicted file, Subversion places three extra unversioned files in your working copy:
  • filename.mine
    This is your file as it existed in your working copy before you updated your working
    copy—that is, without conflict markers. This file has only your latest changes in it.
  • filename.rOLDREV
    This is the file that was the BASE revision before you updated your working copy. That
    is, the file that you checked out before you made your latest edits.
  • filename.rNEWREV
    This is the file that your Subversion client just received from the server when you updated your working copy. This file corresponds to the HEAD revision of the repository.

If you’ve postponed a conflict, you need to resolve the conflict before Subversion will allow you to commit your changes. You’ll do this with the svn resolve command and one of several arguments to the —accept option.

  • If you want to choose the version of the file that you last checked out before making your edits, choose the base argument.
  • If you want to choose the version that contains only your edits, choose the mine-full argument.
  • If you want to choose the version that your most recent update pulled from the server, choose the theirs-full argument.
  • However, if you want to pick and choose from your changes and the changes that your update fetched from the server, merge the conflicted text “by hand” (by examining and editing the conflict markers within the file) and then choose the working argument.

svn resolve removes the three temporary files and accepts the version of the file that you specified with the —accept option, and Subversion no longer considers the file to be in a state of conflict:

$ svn resolve --accept working sandwich.txt
Resolved conflicted state of 'sandwich.txt'