Creating new file without commiting it to a changeset using Java API
Hey everyone,
Using the RTC Java API, I want to create a new file, tell my sandbox about it, and have it be considered a "local change" ("Unresolved" using Eclipse terminology) until I decide to package it up in a changeset. I have the following snippet I put together from the examples, but for some reason, the LocalChangeManager is not recognizing my new file (it does recognize files that were modified and deleted though). I have a suspicion that I'm missing something simple, but the javadoc is not clear on this case.
Any ideas? Thanks!
Using the RTC Java API, I want to create a new file, tell my sandbox about it, and have it be considered a "local change" ("Unresolved" using Eclipse terminology) until I decide to package it up in a changeset. I have the following snippet I put together from the examples, but for some reason, the LocalChangeManager is not recognizing my new file (it does recognize files that were modified and deleted though). I have a suspicion that I'm missing something simple, but the javadoc is not clear on this case.
Any ideas? Thanks!
// Create a new file and give it some content IFileItem file = (IFileItem) IFileItem.ITEM_TYPE.createItem();
file.setName("file.txt");
file.setParent(projectFolder);
file.setContent(...);
workspaceConnection.configurationOpFactory().save(file);
// Refresh the sandbox and pick up any changes to our files
ILocalChangeManager lcm = FileSystemCore.getSharingManager().getLocalChangeManager();
lcm.refreshChanges(new ISandbox[] {sandbox}, RefreshType.TRAVERSE_ALL_WITH_RECOMPUTE_OF_KNOWN, null);
// !!! But the changes array does not contain the file I just added !!!
ILocalChange[] changes = lcm.getPendingChanges(workspaceConnection.getContextHandle(), component, sandbox));
Accepted answer
IConfigurationOpFactory
is used to update a repository workspace by adding changes to a change set. The usage pattern is to get a workspace connection, create a bunch of save operations, then run IWorkspaceConnection#commit()
on those ops. Calling save()
without committing the change drops the op onto the stack for the garbage collector to gobble up. ;)
If you want to change your sandbox, I suggest that you write the file with your preferred method: if you're running outside of Eclipse use java.io.File, or, if you're writing a plugin that runs inside Eclipse, use the resource layer. If you're using the java.io.File approach, hit Eclipse with the big hammer:
lcm.refreshChanges(TRAVERSE_ALL_WITH_RECOMPUTE_OF_KNOWN)
. I say "big hammer" because that will walk the entire filesystem under the sandbox. You can get better performance by refreshing the parent of the file you've added.
Comments
Note that for some reasons there are no pending changes without a
sandbox.allShares(null);
as written in local-changes-deliver
One other answer
This is really interesting but would point out that there's something else to take care about.
Everything works fine if you make a simple sequence:
- load a repository workspace in a filesystem
- make a change (add a file or change the content of a file)
- try to get local changes using plain java api (after a sandbox.allShares(null); )
but if you try again only to get local changes using plain java api (without loading the workspace again) you could get some exceptions related to com.ibm.team.filesystem.client.internal.core.SharingMetadata2.
I've seen that this situation follows the presence of a .isCorrupt file on the metadata and this file is created after the sandbox.allShares(progressMonitor) that I needed to get local changes.
Reading this post from Evan I understood that the problem arise if you don't deregister the sandbox after a prior operation.
So I fixed adding a final sharingManager.deregister(sandbox, progressMonitor); after the load operation and at the and of other operations that write a .jazzlock file.
Maybe Evan could also explain the reason :-) ....