Hello Aravinda!
First of all I'd like to recommend you to use new SVNKit API, based on 
SvnOperationFactory class. In 
the future we will add feature only to this API, old SVNXXXClient-based API 
will be still 
operational, but won't have newer features. If you look at how 
SVNDiffClient#doDiffStatus is 
implemented you'll see that it's implemented via SvnOperationFactory, but it's 
better to use 
SvnOperationFactory in your application directly.

The only way to understand if the file was merged or not is to track 
svn:mergeinfo 
(SVNProperty.MERGE_INFO) changes between those revisions. This property can be 
changed on that 
certain file or on some of parent directory, if the whole directory was merged. 
Note that 
svn:mergeinfo property value consists of ranges that can be inheritable or 
non-inheritable. If non-
inheritable range was changed on some parent directory, the file shouldn't be 
considerd as merged.

Unfortunately doDiffStatus and its new analog SvnDiffSummarize allow to tell 
you that some 
properties were modified, but don't tell you which properties and how they were 
modified. As a 
solution, you can use low-level SVNKit API, based on SVNRepository class. To 
get all changes in one 
SVN request use SVNRepository#diff method to get diff between revisions in a 
form of ISVNEditor 
calls (set getContents=false in order to tell the server not to send you the 
content of the files). 
Pass your own implementation of ISVNEditor to collect new svn:mergeinfo values 
on directories on 
which it was changed. For those directories, where svn:mergeinfo was changed, 
call 
SVNRepository#getDir to get old svn:mergeinfo values. One more note: some 
servers for http(s) 
protocols don't send properties changes if getContents=false, but they send you 
a change of a 
virtual property svn:BOGOSITY. If your ISVNEditor#changeDirProperty is called 
with that property, 
you have to perform a separate SVNRepository#getDir request to get new 
svn:mergeinfo property (note: 
you can't do that directly using the same SVNRepository object, see 
http://vcs.atspace.co.uk/2012/09/21/are-svnkit-methods-reenterable/ for 
details, you can use another 
SVNRepository object or better perform SVNRepository#getDir after 
SVNRepository#diff is finished).

Once you get old and new svn:mergeinfo property values for directories and 
files where it was 
changed, you can calculate which ranges were changes in those values. To do 
that use 
SVNMergeInfoUtil#parseMergeInfo to convert svn:mergeinfo values to Map:s and 
SVNMergeInfoUtil#diffMergeInfo to find difference between those maps. Finally 
check those ranges: 
the path is merged if either
a) the difference contains changed ranges for that path
b) the difference contains any inheritable range (use 
SVNMergeRange#isInheritable method) for one of 
its parent paths (SVNPathUtil will help you a lot here).

Some notes: you can reuse the same SVNRepository#diff to understand if any 
files/directories were 
changed, so no separate diffClient.doDiffStatus request is required. Instead of 
ISVNReporterBaton 
object for SVNRepository#diff method use the following implementation:

new ISVNReporterBaton() {
            @Override
            public void report(ISVNReporter reporter) throws SVNException {
                reporter.setPath("", null, start, SVNDepth.INFINITY, false);
                reporter.finishReport();
            }
        }

The method described above may seem a bit tricky but to my opinion it's the 
fastest way to achieve 
your goals, because it requires just 1+N requests for all protocols except 
http(s) and 1+2N requests 
for http(s) (where N is the number of directories with changed svn:mergeinfo, 
usually 0 or 1): one 
SVNRepository#diff and N times SVNRepository#getDir to get old svn:mergeinfo 
values (and N requests 
by SVNRepository#getDir to get new svn:mergeinfo, if you receive svn:BOGOSITY). 
And one more 
advantage of SVNRepository#diff approach is that you don't have to receive file 
content from the 
server.

Maybe those N requests for svn:mergeinfo can be replaced with a single 
SVNRepository#getMergeInfo 
request, but I'm not sure, I should consult with my colleagues about that. But 
if this is true, you 
can get all information you need in 2 or 3(for http(s)) requests, that's a very 
good result.

SVNStatusType.MERGED has another purpose, and you'll never receive it when 
calling doDiffStatus

Hope this helps.
--
Dmitry Pavlenko,
TMate Software,
http://subgit.com/ - git-svn bridge

> Hi folks,
> 
> I am currently capturing the changes that happened to files in the
> following approach. Basically, based on the SVNSTatusType, I am filling up
> 3 lists that hold added, changed and deleted files between 2 revisions
> under a repo URL.
> 
>   diffClient.doDiffStatus(url, start, url, end, SVNDepth.INFINITY, false,
> 
>                 new ISVNDiffStatusHandler() {
> 
>                     @Override
>                     public void handleDiffStatus(final SVNDiffStatus
> diffStatus) throws SVNException {
>                         if (diffStatus.getKind() == SVNNodeKind.FILE) {
> 
>                             String ext =
> getFileExtension(diffStatus.getURL());
> 
>                             if (extensions.contains(ext)) {
>                                 SVNStatusType status =
> diffStatus.getModificationType();
> 
>                                 if (status == SVNStatusType.STATUS_ADDED) {
> 
> addedFiles.add(diffStatus.getURL().toDecodedString());
>                                 } else if (status ==
> SVNStatusType.STATUS_DELETED) {
> 
> deletedFiles.add(diffStatus.getURL().toDecodedString());
>                                 } else if (status ==
> SVNStatusType.STATUS_MODIFIED) {
> 
> changedFiles.add(diffStatus.getURL().toDecodedString());
>                                 }
>                             }
> 
>                         }
>                     }
>                 });
> 
> Now, I want to selectively add only the files that got affected during
> direct check-ins, and not ones that came in during merge operations (coz I
> felt that merged content is also getting counted. I wasn't sure if it was
> coz things were really merged or if it was merged in a non-svn-merge
> fashion by some file merge and direct checkins).
> 
> How do I capture whether an addition, change or a deletion is a result of a
> merge or not following this approach? I see a property 'MERGED' as well in
> SVNStatusType, and wondering if the above approach already has take care of
> it.
> 
> -Aravinda

Reply via email to