[<< Previous Page | Replicating An Existing Repository]
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:
...
public class WorkingCopy {
- private static SVNClientManager ourClientManager;
- ..
}]
Then go several demonstration functions that will be used in the main program. The following one creates a new directory immediately in a repository:
- private static SVNCommitInfo makeDirectory( SVNURL url , String commitMessage ) throws SVNException {
- return ourClientManager.getCommitClient( ).doMkDir( new SVNURL[] { url } , commitMessage );
}]
This one imports a local directory to a repository:
- private static SVNCommitInfo importDirectory( File localPath , SVNURL dstURL , String commitMessage , boolean isRecursive ) throws SVNException {
- return ourClientManager.getCommitClient( ).doImport( localPath , dstURL , commitMessage , isRecursive );
}]
This one recursively commits Working Copy modifications to a repository:
- private static SVNCommitInfo commit( File wcPath , boolean keepLocks , String commitMessage ) throws SVNException {
- return ourClientManager.getCommitClient().doCommit( new File[] { wcPath } , keepLocks , commitMessage , false , true );
}]
This one checks out a Working Copy given a repository url:
- private static long checkout( SVNURL url , SVNRevision revision , File destPath , boolean isRecursive ) throws SVNException {
- SVNUpdateClient updateClient = ourClientManager.getUpdateClient( );
- SVNUpdateClient updateClient = ourClientManager.getUpdateClient( );
}]
This one updates a Working Copy to a particular revision:
- private static long update( File wcPath , SVNRevision updateToRevision , boolean isRecursive ) throws SVNException {
- SVNUpdateClient updateClient = ourClientManager.getUpdateClient( );
/*
- sets externals not to be ignored during the update
- /
/*
- returns the number of the revision wcPath was updated to
- /
- SVNUpdateClient updateClient = ourClientManager.getUpdateClient( );
}]
This one switches a Working Copy to another url:
- private static long switchToURL( File wcPath , SVNURL url , SVNRevision updateToRevision , boolean isRecursive ) throws SVNException {
- SVNUpdateClient updateClient = ourClientManager.getUpdateClient( );
/*
- sets externals not to be ignored during the switch
- /
/*
- returns the number of the revision wcPath was updated to
- /
- SVNUpdateClient updateClient = ourClientManager.getUpdateClient( );
}]
This one recursively adds an existing local item under version control (schedules for addition):
- private static void addEntry( File wcPath ) throws SVNException {
- ourClientManager.getWCClient( ).doAdd( wcPath , false , false , false , true );
}]
This one locks a versioned item:
- private static void lock( File wcPath , boolean isStealLock , String lockComment ) throws SVNException {
- ourClientManager.getWCClient( ).doLock( new File[] { wcPath } , isStealLock , lockComment );
}]
This one deletes a versioned item from version control (schedules for deletion):
- private static void delete( File wcPath , boolean force ) throws SVNException {
- ourClientManager.getWCClient( ).doDelete( wcPath , force , false );
}]
This function copies or moves one location to another one within the same repository:
- private static SVNCommitInfo copy( SVNURL srcURL , SVNURL dstURL , boolean isMove , String commitMessage ) throws SVNException {
- return ourClientManager.getCopyClient().doCopy( srcURL , SVNRevision.HEAD , dstURL , isMove , commitMessage );
}]
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:
... public class StatusHandler implements ISVNStatusHandler, ISVNEventHandler {
- private boolean myIsRemote;
public StatusHandler( boolean isRemote ) {
- myIsRemote = isRemote;
/*
- Gets the status of file/directory/symbolic link text contents.
- It is SVNStatusType who contains information on the state of an
- item.
- /
/*
- The contents of the file have been Modified.
- /
/*
- The item is in a state of Conflict.
- /
/*
- The item has been scheduled for Deletion from the repository.
- /
/*
- The item has been scheduled for Addition to the repository.
- /
/*
- The item is not under version control.
- /
/*
- The item is unversioned, but is used by an eXternals definition.
- /
/*
- The item is Ignored.
- /
} else if ( contentsStatus == SVNStatusType.STATUS_MISSING || contentsStatus == SVNStatusType.STATUS_INCOMPLETE ) {
/*
- The file, directory or symbolic link item is under version
- control but is missing or somehow incomplete.
- /
/*
- The item is in the repository as one kind of object,
- but what's actually in the user's working
- copy is some other kind.
- /
/*
- The item was Replaced in the user's working copy; that is,
- the item was deleted, and a new item with the same name
- was added (within a single revision).
- /
} else if ( contentsStatus == SVNStatusType.STATUS_NONE || contentsStatus == SVNStatusType.STATUS_NORMAL ) {
/*
- The item was not modified (normal).
- /
/*
- If SVNStatusClient.doStatus(..) is invoked with remote = true the
- following code finds out whether the current item has been changed
- in the repository
- /
if ( status.getRemotePropertiesStatus( ) != SVNStatusType.STATUS_NONE || status.getRemoteContentsStatus( ) != SVNStatusType.STATUS_NONE ) {
/*
- the local item is out of date
- /
/*
- Now getting the status of properties of an item. SVNStatusType also
- contains information on the properties state.
- /
/*
- Default - properties are normal (unmodified).
- /
/*
- Properties were modified.
- /
/*
- Properties are in conflict with the repository.
- /
/*
- Whether the item was locked in the .svn working area (for example,
- during a commit or maybe the previous operation was interrupted, in
- this case the lock needs to be cleaned up).
- /
/*
- Whether the item is switched to a different URL (branch).
- /
/*
- If the item is a file it may be locked.
- /
/*
- If doStatus() was run with remote = true and the item is a file,
- checks whether a remote lock presents.
- /
/*
- at first suppose the file is locKed
- /
/*
- if the lock-token of the local lock differs from the lock-
- token of the remote lock - the lock was sTolen!
- /
- lockLabel = "T";
- if ( myIsRemote ) {
/*
- the local lock presents but there's no lock in the
- repository - the lock was Broken. This is true only if
- doStatus() was invoked with remote=true.
- /
/*
- the file is not locally locked but locked in the repository -
- the lock token is in some Other working copy.
- /
/*
- Obtains the working revision number of the item.
- /
/*
- Obtains the number of the revision when the item was last changed.
- /
/*
- status is shown in the manner of the native Subversion command line
- client's command "svn status"
- /
- + propertiesChangeType + ( isLocked ? "L" : " " ) + ( isAddedWithHistory ? "+" : " " ) + ( isSwitched ? "S" : " " ) + lockLabel + " " + remoteChangeType + " " + workingRevision + offsets[0]
+ ( lastChangedRevision >= 0 ? String.valueOf( lastChangedRevision ) : "?" ) + offsets[1] + ( status.getAuthor( ) != null ? status.getAuthor( ) : "?" ) + offsets[2] + status.getFile( ).getPath( ) );
- SVNEventAction action = event.getAction( );
/*
- Print out the revision against which the status was performed. This
- event is dispatched when the SVNStatusClient.doStatus() was invoked
- with the flag remote set to true - that is for a local status it
- won't be dispatched.
- /
- System.out.println( "Status against revision: " + event.getRevision( ) );
}
}]
We use this handler in a status function:
- private static void showStatus( File wcPath , boolean isRecursive , boolean isRemote , boolean isReportAll ,
- boolean isIncludeIgnored , boolean isCollectParentExternals ) throws SVNException {
- ourClientManager.getStatusClient( ).doStatus( wcPath , isRecursive , isRemote , isReportAll ,
- isIncludeIgnored , isCollectParentExternals ,
new StatusHandler( isRemote ) );
- isIncludeIgnored , isCollectParentExternals ,
}]
For getting info on Working Copy items (like command) we implement an [info handler | http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/wc/ISVNInfoHandler.html]:
... public class InfoHandler implements ISVNInfoHandler {
- public void handleInfo( SVNInfo info ) {
System.out.println( "
INFO
" );
- System.out.println( "Local Path: " + info.getFile( ).getPath( ) ); System.out.println( "URL: " + info.getURL( ) );
if ( info.isRemote( ) && info.getRepositoryRootURL( ) != null ) {
- System.out.println( "Repository Root URL: " + info.getRepositoryRootURL( ) );
- System.out.println( "Repository UUID: " + info.getRepositoryUUID( ) );
- System.out.println( "Schedule: " + ( info.getSchedule( ) != null ? info.getSchedule( ) : "normal" ) );
- System.out.println( "Properties Last Updated: " + info.getPropTime( ) );
if ( info.getKind( ) == SVNNodeKind.FILE && info.getChecksum( ) != null ) {
- if ( info.getTextTime( ) != null ) {
- System.out.println( "Text Last Updated: " + info.getTextTime( ) );
- if ( info.getLock( ).getID( ) != null ) {
- System.out.println( "Lock Token: " + info.getLock( ).getID( ) );
- System.out.println( "Lock Expires: " + info.getLock( ).getExpirationDate( ) );
- System.out.println( "Lock Comment: " + info.getLock( ).getComment( ) );
- }
}
}]
Which we then use in our info function:
- private static void showInfo( File wcPath , SVNRevision revision , boolean isRecursive ) throws SVNException {
ourClientManager.getWCClient( ).doInfo( wcPath , revision , isRecursive , new InfoHandler( ) );
}]
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.):
... public class UpdateEventHandler implements ISVNEventHandler {
- public void handleEvent( SVNEvent event , double progress ) {
/*
- Gets the current action. An action is represented by SVNEventAction.
- In case of an update an action can be determined via comparing
- SVNEvent.getAction() and SVNEventAction.UPDATE_-like constants.
- /
/*
- the item was added
- /
/*
- the item was deleted
- /
/*
- Find out in details what state the item is (after having been
- updated).
- Gets the status of file/directory item contents. It is
- SVNStatusType who contains information on the state of an item.
- /
/*
- the item was modified in the repository (got the changes
- from the repository
- /
/*
- The file item is in a state of Conflict. That is, changes
- received from the repository during an update, overlap with
- local changes the user has in his working copy.
- /
/*
- The file item was merGed (those changes that came from the
- repository did not overlap local changes and were merged
- into the file).
- /
- /*for externals definitions*/ System.out.println( "Fetching external item into '" + event.getFile( ).getAbsolutePath( ) + "'" ); System.out.println( "External at revision " + event.getRevision( ) ); return;
/*
- Working copy update is completed. Prints out the revision.
- /
- System.out.println( "A " + event.getPath( ) ); return;
- System.out.println( "D " + event.getPath( ) ); return;
- System.out.println( "L " + event.getPath( ) ); return;
- System.out.println( "failed to lock " + event.getPath( ) ); return;
/*
- Status of properties of an item. SVNStatusType also
- contains information on the properties state.
- /
/*
- Properties were updated.
- /
/*
- Properties are in conflict with the repository.
- /
/*
- Properties that came from the repository were merged with the
- local ones.
- /
/*
- Gets the status of the lock.
- /
/*
- The lock is broken by someone.
- /
}
...
public class CommitEventHandler implements ISVNEventHandler {
- public void handleEvent( SVNEvent event , double progress ) {
- SVNEventAction action = event.getAction( ); if ( action == SVNEventAction.COMMIT_MODIFIED ) {
- System.out.println( "Sending " + event.getPath( ) );
- System.out.println( "Deleting " + event.getPath( ) );
- System.out.println( "Replacing " + event.getPath( ) );
- System.out.println( "Transmitting file data...." );
/*
- Gets the MIME-type of the item.
- /
/*
- If the item is a binary file
- /
- System.out.println( "Adding " + event.getPath( ) );
- SVNEventAction action = event.getAction( ); if ( action == SVNEventAction.COMMIT_MODIFIED ) {
}
...
public class WCEventHandler implements ISVNEventHandler {
- public void handleEvent( SVNEvent event , double progress ) {
- SVNEventAction action = event.getAction( ); if ( action == SVNEventAction.ADD ) {
/*
- The item is scheduled for addition.
- /
/*
- The item is scheduled for addition with history (copied, in
- other words).
- /
/*
- The item is scheduled for deletion.
- /
/*
- The item is locked.
- /
/*
- Locking operation failed.
- /
- SVNEventAction action = event.getAction( ); if ( action == SVNEventAction.ADD ) {
}
}]
There are also two auxiliary functions: one for handling errors
- private static void error( String message , Exception e ) {
- System.err.println(message + ( e != null ? ": " + e.getMessage( ) : "" ) ); System.exit( 1 );
}]
and one for creating some local dummy file/directory trees:
- private static final void createLocalDir( File aNewDir , File[] localFiles , String[] fileContents ) {
- if ( !aNewDir.mkdirs( ) ) {
- error( "failed to create a new directory '" + aNewDir.getAbsolutePath( ) + "'.", null );
for( int i = 0; i < localFiles.length; i++ ) {
- File aNewFile = localFiles[i]; try {
- if ( !aNewFile.createNewFile( ) ) {
- error( "failed to create a new file '" + aNewFile.getAbsolutePath( ) + "'." , null );
- aNewFile.delete( ); error( "error while creating a new file '" + aNewFile.getAbsolutePath( ) + "'" , ioe );
if ( i > fileContents.length - 1 ) {
- continue;
/*
- writing a text into the file
- /
FileOutputStream fos = null; try {
fos = new FileOutputStream( aNewFile ); fos.write( contents.getBytes( ) );
} catch ( FileNotFoundException fnfe ) {
- error( "the file '" + aNewFile.getAbsolutePath( ) + "' is not found" , fnfe );
- error( "error while writing into the file '" + aNewFile.getAbsolutePath( ) + "'" , ioe );
- if ( fos != null ) {
- try {
- fos.close( );
- //
- try {
- if ( !aNewFile.createNewFile( ) ) {
- if ( !aNewDir.mkdirs( ) ) {
}]
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:
... public class WorkingCopy {
- private static SVNClientManager ourClientManager; private static ISVNEventHandler myCommitEventHandler; private static ISVNEventHandler myUpdateEventHandler; private static ISVNEventHandler myWCEventHandler; public static void main( String[] args ) throws SVNException {
- FSRepositoryFactory.setup( ); SVNURL repositoryURL = null; try {
repositoryURL = SVNURL.parseURIEncoded( "file://localhost/testRep" );
- //
String myWorkingCopyPath = "/MyWorkingCopy"; String importDir = "/importDir"; String importFile = importDir + "/importFile.txt"; String importFileText = "This unversioned file is imported into a repository"; String newDir = "/newDir"; String newFile = newDir + "/newFile.txt"; String fileText = "This is a new file added to the working copy";
/*
- That's where a new directory will be created
- /
SVNURL url = repositoryURL.appendPath( "MyRepos" , false ); /*
That's where '/MyRepos' will be copied to (branched)
- /
SVNURL copyURL = repositoryURL.appendPath( "MyReposCopy" , false );
/*
- That's where a local directory will be imported into.
- Note that it's not necessary that the '/importDir' directory must already
- exist - it will created if necessary.
- /
/*
- Creating custom handlers that will process events
- /
myCommitEventHandler = new CommitEventHandler( );
myUpdateEventHandler = new UpdateEventHandler( ); myWCEventHandler = new WCEventHandler( );
/*
- Creates a default run-time configuration options driver. Default options
- created in this way use the Subversion run-time configuration area (for
- instance, on a Windows platform it can be found in the '%APPDATA%\Subversion'
- directory).
- readonly = true - not to save any configuration changes that can be done
- during the program run to a config file (config settings will only
- be read to initialize; to enable changes the readonly flag should be set
- to false).
- SVNWCUtil is a utility class that creates a default options driver.
- /
/*
- Creates an instance of SVNClientManager providing a default auth
- manager and an options driver
- /
/*
- Registers a commit event handler
- /
/*
- Registers an update event handler
- /
/*
- Registers a WC event handler
- /
- ..
- FSRepositoryFactory.setup( ); SVNURL repositoryURL = null; try {
}]
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:
- .. long committedRevision = -1; System.out.println( "Making a new directory at '" + url + "'..." ); try {
/*
- creates a new version comtrolled directory in a repository and
- displays what revision the repository was committed to
- /
1 committedRevision = makeDirectory(url, "making a new directory at '" + url + "'").getNewRevision();
- } catch( SVNException svne ) {
- error( "error while making a new directory at '" + url + "'" , svne );
/*
- creates a new local directory - './importDir' and a new file -
- './importDir/importFile.txt' that will be imported into the repository
- into the '/MyRepos/importDir' directory
- /
/*
- recursively imports an unversioned directory into a repository
- and displays what revision the repository was committed to
- /
2 committedRevision = importDirectory( anImportDir , importToURL , "importing a new directory '" + anImportDir.getAbsolutePath( ) + "'" , isRecursive ).getNewRevision( );
- } catch( SVNException svne ) {
- error( "error while importing a new directory '" + anImportDir.getAbsolutePath( ) + "' into '" + importToURL + "'" , svne );
/*
- creates a local directory where the working copy will be checked out into
- /
- error ( "the destination directory '"
- + wcDir.getAbsolutePath( ) + "' already exists!" , null );
/*
- recursively checks out a working copy from url into wcDir.
- SVNRevision.HEAD means the latest revision to be checked out.
- /
3.1 checkout( url , SVNRevision.HEAD , wcDir , true );
- } catch ( SVNException svne ) {
- error( "error while checking out a working copy for the location '"
- + url + "'" , svne );
/*
- recursively displays info for wcDir at the current working revision
- in the manner of 'svn info -R' command
- /
- showInfo( wcDir , SVNRevision.WORKING , true );
- error( "error while recursively getting info for the working copy at'"
- + wcDir.getAbsolutePath( ) + "'" , svne );
/*
- creates a new local directory - 'wcDir/newDir' and a new file -
- '/MyWorkspace/newDir/newFile.txt'
- /
/*
- recursively schedules aNewDir for addition
- /
- error( "error while checking out a working copy for the location '"
3.2 addEntry( aNewDir );
- } catch ( SVNException svne ) {
- error( "error while recursively adding the directory '"
- + aNewDir.getAbsolutePath( ) + "'" , svne );
/*
- gets and shows status information for the WC directory.
- status will be recursive on wcDir, will also cover the repository,
- won't cover unmodified entries, will disregard 'svn:ignore' property
- ignores (if any), will ignore externals definitions.
- /
- isIncludeIgnored , isCollectParentExternals );
- error( "error while recursively performing status for '"
- + wcDir.getAbsolutePath( ) + "'" , svne );
/*
- recursively updates wcDir to the latest revision (SVNRevision.HEAD)
- /
- error( "error while recursively updating the working copy at '"
- + wcDir.getAbsolutePath( ) + "'" , svne );
/*
- commits changes in wcDir to the repository with not leaving items
locked (if any) after the commit succeeds; this will add aNewDir &
- aNewFile to the repository.
- /
- error( "error while recursively adding the directory '"
3.3 committedRevision = commit( wcDir , false , "'/newDir' with '/newDir/newFile.txt' were added" ).getNewRevision( );
- } catch ( SVNException svne ) {
- error( "error while committing changes to the working copy at '"
- + wcDir.getAbsolutePath( ) + "'" , svne );
- println( "Locking (with stealing if the entry is already locked) '"
- + aNewFile.getAbsolutePath( ) + "'." );
/*
- locks aNewFile with stealing (if it has been already locked by someone
- else), providing a lock comment
- /
- error( "error while locking the working copy file '"
- + aNewFile.getAbsolutePath( ) + "'" , svne );
/*
- displays status once again to see the file is really locked
- /
- isIncludeIgnored , isCollectParentExternals );
- error( "error while recursively performing status for '"
- + wcDir.getAbsolutePath( ) + "'" , svne );
/*
makes a branch of url at copyURL - that is URL->URL copying
- with history
- /
- error( "error while committing changes to the working copy at '"
4 committedRevision = copy( url , copyURL , false ,
- "remotely copying '" + url + "' to '" + copyURL + "'" )
- getNewRevision( );
- } catch ( SVNException svne ) {
- error( "error while copying '" + url + "' to '"
- + copyURL + "'" , svne );
- error( "error while copying '" + url + "' to '"
/*
- displays what revision the repository was committed to
- / System.out.println( "Committed to revision " + committedRevision ); System.out.println( ); System.out.println( "Switching '" + wcDir.getAbsolutePath() + "' to '"
- + copyURL + "'..." );
/*
- recursively switches wcDir to copyURL in the latest revision
- (SVNRevision.HEAD)
- /
5.1 switchToURL( wcDir , copyURL , SVNRevision.HEAD , true );
- } catch ( SVNException svne ) {
- error( "error while switching '"
- + wcDir.getAbsolutePath( ) + "' to '" + copyURL + "'" , svne );
/*
- recursively displays info for the working copy once again to see
- it was really switched to a new URL
- /
- showInfo( wcDir , SVNRevision.WORKING , true );
- error( "error while recursively getting info for the working copy at'"
- + wcDir.getAbsolutePath( ) + "'" , svne );
/*
- schedules aNewDir for deletion (with forcing)
- /
- error( "error while switching '"
5.2 delete( aNewDir , true );
- } catch ( SVNException svne ) {
- error( "error while schediling '"
- + wcDir.getAbsolutePath( ) + "' for deletion" , svne );
/*
- recursively displays status once more to see whether aNewDir
- was really scheduled for deletion
- /
- isIncludeIgnored , isCollectParentExternals );
- error( "error while recursively performing status for '"
- + wcDir.getAbsolutePath( ) + "'" , svne );
/*
- lastly commits changes in wcDir to the repository; all items that
- were locked by the user (if any) will be unlocked after the commit
- succeeds; this commit will remove aNewDir from the repository.
- /
- error( "error while schediling '"
5.3 committedRevision = commit(
- wcDir , false , "deleting '" + aNewDir.getAbsolutePath( )
- + "' from the filesystem as well as from the repository" ).getNewRevision( );
- } catch ( SVNException svne ) {
- error( "error while committing changes to the working copy '"
- + wcDir.getAbsolutePath( ) + "'" , svne );
- error( "error while committing changes to the working copy '"
- }
}]
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]