It's all about the answers!

Ask a question

Progammatically getting the diff between two changesets


Crispin Veall (5131) | asked Jun 02 '09, 10:28 a.m.
I have succeeded in programmatically loading and updating a file, but now wish to view the diff between the two changsets. In RTC, using firebug, I can see that the diff is performed:

<changes>
<changeType>2</changeType>
<itemType>com.ibm.team.filesystem.FileItem</itemType>
<itemId>_6O-noE99Ed63A67qOg82Bw</itemId>

<beforeStateId>_6PhaNE99Ed6eRK5QUiD-YQ</beforeStateId>
<afterStateId>_6VJhEk99Ed6eRK5QUiD-YQ</afterStateId>
<path>project/config1</path>
<diff>diff -u -N project/config1 project/config1
--- project/config1	2009-06-02 14:01:46.000000565 +0000
+++ project/config1	2009-06-02 14:01:47.000000155 +0000
@@ -1,6 +1,11 @@
 this
-thats about all for now, but y'all be good now and come back another day top see how it's all gettin' on.
+that
+the other
+and one of those
+extra liff
+another extra loff
+another extra laff
 fifth line
-sixth line
 seventh line
 eighth line
+nineth line
</diff>

</changes>

I'm using RTC 2.0 rc2 btw
Does anyone have any idea how I can access that diff using plain java? If more information is needed, please just shout!
TIA,
Crispin

7 answers



permanent link
Crispin Veall (5131) | answered Jun 04 '09, 9:19 a.m.
Ok, I'll try a different tack. Does anyone know how the diff is extracted? Is it by doing a system call to to diff (I guess not, because RTC is available for Windows as well), or is there some implementation of diff in java which is not GPL'ed, and therefore suitable for commercial/proprietary use?

Thanks in advance,
Crispin

permanent link
Michael Valenta (3.6k3) | answered Jun 04 '09, 10:00 a.m.
FORUM MODERATOR / JAZZ DEVELOPER
Crispin,

RTC uses its own implementation of an LCS based diff algorithm to
generate the diff. The RTC implementation is not API but you can still
look at it as it is available in the RTC source code
(com.ibm.team.filesystem.common.internal.patch.LCS). This is only the
low level portion of the patch generation. The code that determines what
contents need to be compared is tightly coupled to the UI and is highly
generalized (or, in other words, very complicated ;-) and there is no
high level API in RTC for this. The command line also performs diffs.
Perhaps you coudl use the command line client to get the diff you want.

Michael

crispibits wrote:
Ok, I'll try a different tack. Does anyone know how the diff is
extracted? Is it by doing a system call to to diff (I guess not,
because RTC is available for Windows as well), or is there some
implementation of diff in java which is not GPL'ed, and therefore
suitable for commercial/proprietary use?

Thanks in advance,
Crispin

permanent link
Crispin Veall (5131) | answered Jun 04 '09, 10:47 a.m.
Crispin,

RTC uses its own implementation of an LCS based diff algorithm to
generate the diff. The RTC implementation is not API but you can still
look at it as it is available in the RTC source code
(com.ibm.team.filesystem.common.internal.patch.LCS).


Aha! Ace, thanks Michael - I'll have a gander now. I can already extract the file content for different versions of a file, so this might do the trick!

permanent link
Crispin Veall (5131) | answered Jun 04 '09, 12:51 p.m.
The code that determines what
contents need to be compared is tightly coupled to the UI and is highly
generalized (or, in other words, very complicated ;-)


Blimey, you're right, it is a tad complicated isn't it?
So far I've got:

private void diff(List<IChangeSet> changeSetList) throws TeamRepositoryException {
ConfigurationChange cc = ClientConfigurationChangeFactory.createChange(repo, changeSetList, monitor);
Collection<FileChange> changes = cc.getChanges();
Charset c = Charset.defaultCharset();
IPathResolver ipr = null; // No idea how to set this?
ResolvedConfigurationChangePaths paths = ResolvedConfigurationChangePaths.resolve(ipr, cc, monitor);
for ( FileChange change : changes) {
try {
com.ibm.team.filesystem.common.internal.patch.CreatePatchUtil.writeDiff(System.out, change, paths, c, monitor);
} catch ( TeamRepositoryException tre ) {
tre.printStackTrace();
} catch ( IOException ioe ) {
ioe.printStackTrace();
}
}
}


I must say I'm flying blind here, and no idea if this will ever run, as I'm guessing what most of the objects/methods are or do.

The last thing I can't work out before I finally debug all the NPE's that are bound to come my way is the IPathResolver. Any ideas what it is or how I get/set/create one?

I don't really want to use the cli as I'm doing all this programmatically.

Thanks again,
Crispin

permanent link
Evan Hughes (2.4k1018) | answered Jun 04 '09, 1:47 p.m.
JAZZ DEVELOPER
Blimey indeed.

If you're digging around in the source, I recommend that you take a look at the CLI's 'diff' subcommand (com.ibm.team.filesystem.cli.client.internal.subcommands.DiffCmd). It sounds like its functionality is close to what you're looking for, and it has the advantage of being somewhat self contained. Start by looking at getFileStateFromChangeSet(), as it extracts a change from a change set.

Regarding the diff: skip the whole diff thing, and pull the before and after states from each change set. You can then use external utilities/libraries to do the comparison and produce the diff. As Michael says, our libraries are complex. =)

Out of curiosity: What are you trying to do?

e

permanent link
Crispin Veall (5131) | answered Jun 04 '09, 3:26 p.m.
Blimey indeed.

If you're digging around in the source, I recommend that you take a look at the CLI's 'diff' subcommand (com.ibm.team.filesystem.cli.client.internal.subcommands.DiffCmd). It sounds like its functionality is close to what you're looking for, and it has the advantage of being somewhat self contained. Start by looking at getFileStateFromChangeSet(), as it extracts a change from a change set.

Regarding the diff: skip the whole diff thing, and pull the before and after states from each change set. You can then use external utilities/libraries to do the comparison and produce the diff. As Michael says, our libraries are complex. =)

Out of curiosity: What are you trying to do?

e

Your libraries, complex? Surely not ;-) I'm not envious of the people maintaining it I must say!

What I'm trying to do is use the PlainJavaClient libs to write an interface to a (Tivoli) product to enable basic and easy web-side upload/checkin/compare of files. I've got all the basics pretty much together, so I can pull out two files (any version) from SCM - but currently I am actually doing a system call i.e:

Runtime rt = Runtime.getRuntime ();
Process process = rt.exec ("diff -u -N "+fileFrom.getAbsolutePath()+" "+fileTo.getAbsolutePath());

This is fine if
a) You know diff is on the system
b) You're running *nix, cygwin or ported diff.
c) You aren't running scared of the GPL
d) You don't know that RTC already has the capability to do it already in there somewhere!

The SCM CLI's diff command would do the job (and several others), but I can't seem to find the source for that (any pointers gratefully received!)

Cheers,
Crispin

permanent link
Evan Hughes (2.4k1018) | answered Jun 05 '09, 9:59 a.m.
JAZZ DEVELOPER

Your libraries, complex? Surely not ;-) I'm not envious of the people maintaining it I must say!


In our defense, I'd like to point out that we're the folks who maintain it. :-)


What I'm trying to do is use the PlainJavaClient libs to write an interface to a (Tivoli) product to enable basic and easy web-side upload/checkin/compare of files. I've got all the basics pretty much together, so I can pull out two files (any version) from SCM - but currently I am actually doing a system call i.e:


Assuming this is for an in-house tool, I'd suggest looking for a non-GPL LCS implementation.

e

Your answer


Register or to post your answer.