Editing Operation: commiting to a repository

The low-level layer provides for an ability to build and change tree-like hierarchies in a repository giving a 

 

Using the ISVNEditor Interface

ISVNEditor is the interface for editing 

Imagine that we have got the following tree structure in our repository:

使用SVNkit删除版本库的文件

And we want to change it to something like this:

使用SVNkit删除版本库的文件

In other words we want to:

  • delete /nodeB/itemB1

  • change contents of /nodeB/nodeC/itemC1

  • add /nodeB/nodeC/itemC2 with some versioned properties attached to it

  • add /nodeB/nodeD

Now we'll discuss how to do these changes using a commit editor. We'll assume that we are working with a local 

 

切换行号显示
   1     ...
   2 setup( );
   3 ;
   4 
   5 url ) );
   6     ...

Here we don't use an authentication manager - a session user name will be used as an author of a commit. Getting a 

 

切换行号显示
   1     ...
   2 ;
   3 /*mediator*/ );
   4     ...

Now when we have got an editor we can not call any reposiotory access methods of our SVNRepository driver till we 

 

切换行号显示
   1     ...
   2 //provide your local revision of nodeB
   3 r = ...;
   4 r );
   5 
   6 //provide your local revision of itemB1
   7 r = ...;
   8 r );
   9 
  10 //provide your local revision of nodeC
  11 r = ...;
  12 r );
  13 
  14 //provide your local revision of itemC1
  15 r = ...;
  16 r );

Now about applying text delta - text changes (only differences) made locally to itemC1. A base checksum is used to 

 

切换行号显示
   1     
   2 baseChecksum = ...;
   3 baseChecksum );

Use a delta generator to calculate differences between base and working versions of the item. The generator produces 

 

切换行号显示
   1 baseData = ...;
   2 workingData = ...;
   3 
   4 //100Kb-window generator
   5 SVNDeltaGenerator( );
   6 true );

The delta generator passes each produced diff window to the editor calling its textDeltaChunk() 

 

When the generator is finished it calls the editor's textDeltaEnd() 

 

sendDelta() 

 

切换行号显示
   1 checksum );
   2     
   3 //the second and the third parameters are the path and revision respectively 
   4 //of the item's ancestor if the item is being added with history
   5 1 );
   6 
   7 baseChecksum = ...;
   8 baseChecksum );
   9 
  10 baseData = ...;
  11 workingData = ...;
  12 true );
  13 checksum );
  14     
  15  );
  16  );
  17     ...
  18     
  19 //we are finished with changes under nodeC, so closing nodeC
  20 closeDir( );
  21 
  22 //now we are under nodeB again
  23 1 );
  24     
  25 //close nodeD
  26 closeDir( );
  27 
  28 //close root - nodeB
  29 closeDir( );

In the step 5 we are adding a new item, not copying an existing one. But if we need to make a copy of an existing item we should provide the copy source absolute path and the revision of the copy source path as the second and third arguments of the editor.addFile() method respectively. If you would like only to copy an item 

In regard to addition of a directory - parameters are like in addFile(). We are not copying a directory, just adding 

As you see every opened/added directory (including the root one) as well as every opened/added file must be closed with 

 

切换行号显示
   1 closeEdit();

If transaction succeeds and this call makes our changes immutable in the repository, the editor returns an 

 

切换行号显示
   1 try {
   2         ...
   3 1 );
   4 svne ) {
   5 abortEdit( );
   6     }

After we have closed the editor we may go on using our SVNRepository driver. The following diagram illustrates our 

使用SVNkit删除版本库的文件

Notes:

  • with ISVNEditor you edit your repository in a hierarchical way traversing a necessary subtree; that is if your driver is bound to /a and you are going to change /a/b/c/d, you can not just open dwithout moving down in the tree to the node /a/b/c, you have to open the root (/a), then open /a/b, and then /a/b/c, after what you open /a/b/c/d.

  • for all versioned data which is present on your local machine, you have to keep local revision numbers somehow, so that when you try to change an item, a repository server can check whether your local item is out of date or not.
  • you don't have to apply text deltas immediately after you have opened a file; you may first open all necessary files in the way described above, then close all directories (including the root one) remaining opened in a way inverse to the one you opened them, then apply deltas to opened files and finally close files; you can not change directory properties after you've closed target directories.
  • In repository edition operations you'll never need to use the following methods of a commit editor (they are irrelevant in commits, but relevant in updates):

 

Example On Using ISVNEditor In A Commit Operation

In the following example we'll continue discussing application of ISVNEditor in low-level commit operations. 

  • add a directory with a file to a repository,
  • modify the added file,
  • copy the whole added directory within a repository,
  • delete both the original and copied directories.

For each of these four commit operations we'll write separate functions:

1. Addition:

 

切换行号显示
   1 SVNException {
   2 1 );
   3 
   4 1 );
   5 
   6 1 );
   7 
   8 null );
   9 
  10 SVNDeltaGenerator( );
  11 true );
  12 
  13 checksum);
  14 
  15 //Closes dirPath.
  16 closeDir();
  17 
  18 //Closes the root directory.
  19 closeDir();
  20 
  21 closeEdit();
  22     }

2. File modification:

 

切换行号显示
   1 SVNException {
   2 1 );
   3 
   4 1 );
   5 
   6 1 );
   7         
   8 null );
   9         
  10 SVNDeltaGenerator( );
  11 true );
  12 
  13 //Closes filePath.
  14 checksum );
  15 
  16 // Closes dirPath.
  17 closeDir( );
  18 
  19 //Closes the root directory.
  20 closeDir( );
  21 
  22 closeEdit( );
  23     }

Here we use invalid revision numbers (-1) for simplifying the example since they will work for us, and that's all we 

3. Directory copying:

 

切换行号显示
   1 SVNException {
   2 1 );
   3         
   4 revision );
   5 
   6 //Closes dstDirPath.
   7 closeDir( );
   8 
   9 //Closes the root directory.
  10 closeDir( );
  11 
  12 closeEdit( );
  13     }

4. Directory deletion:

 

切换行号显示
   1 SVNException {
   2 1 );
   3 
   4 1 );
   5 
   6 //Closes the root directory.
   7 closeDir( );
   8 
   9 closeEdit( );
  10     }

Now when we've got these functions we are ready to start:

 

切换行号显示
   1 Commit {
   2 
   3 args ) {
   4 
   5 setup( );
   6  );
   7 ;
   8 ;
   9         
  10 getBytes( );
  11 getBytes( );
  12 
  13 url );
  14 
  15 userPassword );
  16 authManager );
  17 
  18 1 );
  19 
  20 NONE ) {
  21 url );
  22 1 );
  23 FILE ) {
  24  );
  25 1 );
  26         }
  27         
  28 //Get exact value of the latest (HEAD) revision.
  29 getLatestRevision( );
  30 latestRevision );
  31         
  32 null );
  33         
  34 try {
  35 contents );
  36 commitInfo );
  37 svne ) {
  38 abortEdit( );
  39 svne;
  40         }
  41         
  42 null );
  43 try {
  44 modifiedContents );
  45 commitInfo );
  46 svne ) {
  47 abortEdit( );
  48 svne;
  49         }
  50 
  51 //converts a relative path to an absolute one
  52  );
  53 getLatestRevision( );
  54 
  55 null );        
  56 try {
  57 srcRevision );
  58 commitInfo );
  59 svne ) {
  60 abortEdit( );
  61 svne;
  62         }
  63 
  64         
  65 
  66 null );
  67 try {
  68  );
  69 commitInfo );
  70 svne ) {
  71 abortEdit( );
  72 svne;
  73         }
  74 
  75 
  76 null );
  77 try {
  78  );
  79 commitInfo );
  80 svne ) {
  81 abortEdit( );
  82 svne;
  83         }
  84         
  85 getLatestRevision( );
  86 latestRevision );
  87         ...
  88     }
  89     ...
  90 }

That's what you'll see if you run the program:

 

Repository latest revision (before committing): 0
The directory was added: r1 by 'foo' at Tue Jun 27 15:46:59 NOVST 2006
The file was changed: r2 by 'foo' at Tue Jun 27 15:46:59 NOVST 2006
The directory was copied: r3 by 'foo' at Tue Jun 27 15:46:59 NOVST 2006
The directory was deleted: r4 by 'foo' at Tue Jun 27 15:46:59 NOVST 2006
The copied directory was deleted: r5 by 'foo' at Tue Jun 27 15:47:00 NOVST 2006
Repository latest revision (after committing): 5

 


example program source code.

相关文章: