Thanks Dmitry! This is awesome info! Let me try these suggestions and share
my findings.

Regards,
Aravinda


On Tue, Sep 3, 2013 at 6:17 PM, Dmitry Pavlenko <pavle...@tmatesoft.com>wrote:

> 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