[<< Previous Page | Replicating An Existing Repository]

TableOfContents

Managing A Working Copy

Finally we came to discussing the SVNKit [http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/wc/package-summary.html high-level API] - the one for manipulating Working Copies. All Working Copy operations are logically organized in different SVN*Client classes. At the same time there's [http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/wc/SVNClientManager.html SVNClientManager] class which composes all SVN*Client classes and, thus, simplifies work on creating and keeping various client classes:

attachment:WC_Class_Diagram.png

So, you may instantiate different SVN*Client classes separately or keep a single SVNClientManager for the same purposes. In fact, SVNClientManager instantiates each SVN*Client object at the first time you request it, but not earlier.

Methods of each SVN*Client class are similar to commands of the [http://svnbook.red-bean.com/nightly/en/svn.ref.html#svn.ref.svn native Subversion command line client]. We will show several simple operations you can perform upon Working Copies using SVNKit. We write a class WorkingCopy which utilizes an SVNClientManager object:

[{Java2HtmlPlugin

...

public class WorkingCopy {

}]

Then go several demonstration functions that will be used in the main program. The following one creates a new directory immediately in a repository:

[{Java2HtmlPlugin

}]

This one imports a local directory to a repository:

[{Java2HtmlPlugin

}]

This one recursively commits Working Copy modifications to a repository:

[{Java2HtmlPlugin

}]

This one checks out a Working Copy given a repository url:

[{Java2HtmlPlugin

}]

This one updates a Working Copy to a particular revision:

[{Java2HtmlPlugin

}]

This one switches a Working Copy to another url:

[{Java2HtmlPlugin

}]

This one recursively adds an existing local item under version control (schedules for addition):

[{Java2HtmlPlugin

}]

This one locks a versioned item:

[{Java2HtmlPlugin

}]

This one deletes a versioned item from version control (schedules for deletion):

[{Java2HtmlPlugin

}]

This function copies or moves one location to another one within the same repository:

[{Java2HtmlPlugin

}]

We also need a function which will report us status (including remote status) of our Working Copy. The high-level API introduces several types of handlers to procees information on the fly. For our purposes we need to implement two handler interfaces so that we could perform status operations on our Working Copy: [ISVNStatusHandler | http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/wc/ISVNStatusHandler.html] and [ISVNEventHandler | http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/wc/ISVNEventHandler.html]. This handler will receive status information about Working Copy items as a [status client | http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/wc/SVNStatusClient.html] traverses the Working Copy tree:

[{Java2HtmlPlugin

... public class StatusHandler implements ISVNStatusHandler, ISVNEventHandler {

}

}]

We use this handler in a status function:

[{Java2HtmlPlugin

}]

For getting info on Working Copy items (like svn info command) we implement an [info handler | http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/wc/ISVNInfoHandler.html]:

[{Java2HtmlPlugin

... public class InfoHandler implements ISVNInfoHandler {


INFO


" );

}

}]

Which we then use in our info function:

[{Java2HtmlPlugin

}]

We also use several hooks (event handlers) to display progress information in a console while an operation is running. We implement handlers for the following operations: update, commit, several local operations (add, delete, lock, etc.):

[{Java2HtmlPlugin

... public class UpdateEventHandler implements ISVNEventHandler {

}

...

public class CommitEventHandler implements ISVNEventHandler {

}

...

public class WCEventHandler implements ISVNEventHandler {

}

}]

There are also two auxiliary functions: one for handling errors

[{Java2HtmlPlugin

}]

and one for creating some local dummy file/directory trees:

[{Java2HtmlPlugin

}]

And now, step by step, we demonstrate using all these functions in a main program. Firts of all, we need some initializations to be performed:

[{Java2HtmlPlugin

... public class WorkingCopy {

}]

Then (listing main actions):

1.First we make a directory in our repository

[{Image src = 'WC_Example1.png'}]

2. Then we import a local dummy directory into it

[{Image src = 'WC_Example2.png'}]

3. Then we # checkout MyRepos, # locally add a new directory into the Working Copy and # commit it to the repository

[{Image src = 'WC_Example3.png'}]

4. Then we copy MyRepos to a new location - MyReposCopy

[{Image src = 'WC_Example4.png'}]

5. Then we # switch the Working Copy to MyReposCopy, # locally delete newDir and # commit it to the repository

[{Image src = 'WC_Example5.png'}]

The same steps (marked with numbers to the left) in code:

[{Java2HtmlPlugin

1 committedRevision = makeDirectory(url, "making a new directory at '" + url + "'").getNewRevision();

2 committedRevision = importDirectory( anImportDir , importToURL , "importing a new directory '" + anImportDir.getAbsolutePath( ) + "'" , isRecursive ).getNewRevision( );

3.1 checkout( url , SVNRevision.HEAD , wcDir , true );

3.2 addEntry( aNewDir );

3.3 committedRevision = commit( wcDir , false , "'/newDir' with '/newDir/newFile.txt' were added" ).getNewRevision( );

4 committedRevision = copy( url , copyURL , false ,

5.1 switchToURL( wcDir , copyURL , SVNRevision.HEAD , true );

5.2 delete( aNewDir , true );

5.3 committedRevision = commit(

}]

And if the program runs successfully you'll see in your console the following output:

Making a new directory at 'file:///G:/testRep/MyRepos'...
Committed to revision 5

Importing a new directory into 'file:///G:/testRep/MyRepos/importDir'...
Adding         importFile.txt
Committed to revision 6

Checking out a working copy from 'file:///G:/testRep/MyRepos'...
A         importDir
AU        importDir/importFile.txt
At revision 6

-----------------INFO-----------------
Local Path: G:\MyWorkingCopy
URL: file:///G:/testRep/MyRepos
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 6
Node Kind: dir
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 6
Last Changed Date: Fri Jul 07 16:19:37 NOVST 2006
-----------------INFO-----------------
Local Path: G:\MyWorkingCopy\importDir
URL: file:///G:/testRep/MyRepos/importDir
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 6
Node Kind: dir
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 6
Last Changed Date: Fri Jul 07 16:19:37 NOVST 2006
-----------------INFO-----------------
Local Path: G:\MyWorkingCopy\importDir\importFile.txt
URL: file:///G:/testRep/MyRepos/importDir/importFile.txt
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 6
Node Kind: file
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 6
Last Changed Date: Fri Jul 07 16:19:37 NOVST 2006
Properties Last Updated: Fri Jul 07 16:19:38 NOVST 2006
Text Last Updated: Fri Jul 07 16:19:37 NOVST 2006
Checksum: 75e9e68e21ae4453f318424738aef57e
 
Recursively scheduling a new directory 'G:\MyWorkingCopy\newDir' for addition...
A     newDir
A     newDir/newFile.txt   
 
Status for 'G:\MyWorkingCopy':
A          0     ?    ?                               G:\MyWorkingCopy\newDir\newFile.txt
A          0     ?    ?                               G:\MyWorkingCopy\newDir
 
Updating 'G:\MyWorkingCopy'...
At revision 6 
 
Committing changes for 'G:\MyWorkingCopy'...
Adding         newDir
Adding         newDir/newFile.txt
Transmitting file data....
Committed to revision 7
 
Locking (with stealing if the entry is already locked) 'G:\MyWorkingCopy\newDir\newFile.txt'.
L     newFile.txt
 
Status for 'G:\MyWorkingCopy':
     K     7     7     userName                        G:\MyWorkingCopy\newDir\newFile.txt
 
Copying 'file:///G:/testRep/MyRepos' to 'file:///G:/testRep/MyReposCopy'...
Committed to revision 8
 
Switching 'G:\MyWorkingCopy' to 'file:///G:/testRep/MyReposCopy'...
  B       newDir/newFile.txt
At revision 8
 
-----------------INFO-----------------
Local Path: G:\MyWorkingCopy
URL: file:///G:/testRep/MyReposCopy
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 8
Node Kind: dir
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 8
Last Changed Date: Fri Jul 07 16:19:42 NOVST 2006
-----------------INFO-----------------
Local Path: G:\MyWorkingCopy\importDir
URL: file:///G:/testRep/MyReposCopy/importDir
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 8
Node Kind: dir
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 6
Last Changed Date: Fri Jul 07 16:19:37 NOVST 2006
-----------------INFO-----------------
Local Path: G:\MyWorkingCopy\importDir\importFile.txt
URL: file:///G:/testRep/MyReposCopy/importDir/importFile.txt
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 8
Node Kind: file
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 6
Last Changed Date: Fri Jul 07 16:19:37 NOVST 2006
Properties Last Updated: Fri Jul 07 16:19:38 NOVST 2006
Text Last Updated: Fri Jul 07 16:19:37 NOVST 2006
Checksum: 75e9e68e21ae4453f318424738aef57e
-----------------INFO-----------------
Local Path: G:\MyWorkingCopy\newDir
URL: file:///G:/testRep/MyReposCopy/newDir
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 8
Node Kind: dir
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 7
Last Changed Date: Fri Jul 07 16:19:41 NOVST 2006
-----------------INFO-----------------
Local Path: G:\MyWorkingCopy\newDir\newFile.txt
URL: file:///G:/testRep/MyReposCopy/newDir/newFile.txt
Repository UUID: bcf16199-7f9e-be47-a3e5-e4d194b5d0ae
Revision: 8
Node Kind: file
Schedule: normal
Last Changed Author: userName
Last Changed Revision: 7
Last Changed Date: Fri Jul 07 16:19:41 NOVST 2006
Properties Last Updated: Fri Jul 07 16:19:40 NOVST 2006
Text Last Updated: Fri Jul 07 16:19:40 NOVST 2006
Checksum: 023b67e9660b2faabaf84b10ba32c6cf 
 
Scheduling 'G:\MyWorkingCopy\newDir' for deletion ...
D     newDir/newFile.txt
D     newDir
 
Status for 'G:\MyWorkingCopy':
D          8     7     userName                        G:\MyWorkingCopy\newDir\newFile.txt
D          8     7     userName                        G:\MyWorkingCopy\newDir
 
Committing changes for 'G:\MyWorkingCopy'...
Deleting   newDir
Committed to revision 9


Download the full sources of this example program: # [WorkingCopy.java | http://svn.svnkit.com/repos/svnkit/trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/WorkingCopy.java] # [CommitEventHandler.java | http://svn.svnkit.com/repos/svnkit/trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/CommitEventHandler.java] # [InfoHandler.java | http://svn.svnkit.com/repos/svnkit/trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/InfoHandler.java] # [StatusHandler.java | http://svn.svnkit.com/repos/svnkit/trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/StatusHandler.java] # [UpdateEventHandler.java | http://svn.svnkit.com/repos/svnkit/trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/UpdateEventHandler.java] # [WCEventHandler.java | http://svn.svnkit.com/repos/svnkit/trunk/doc/examples/src/org/tmatesoft/svn/examples/wc/WCEventHandler.java]

Or view the source code files in separate pages: # [WorkingCopy.java Source File] # [CommitEventHandler.java Source File] # [InfoHandler.java Source File] # [StatusHandler.java Source File] # [UpdateEventHandler.java Source File] # [WCEventHandler.java Source File]