Search code examples
c#svnsharpsvn

SharpSvn Notify-Event on Update


I am currently implementing some SVN functionalities in an application. One of them is the "svn update".

Unfortunately, the outputs from the "svn update" command in a command line and from the Notify event regarding the files that have changed are differing. E.g. If I update a working copy with just one folder with a simple text file in it whereby only the content of the text file changed, I am getting Action.UpdateUpdate events three times (the file, the containing folder, and the working copy itself). Is it possible to reduce the events just to the "root cause"? I do understand that each of these items change, at least in terms of the recorded revision ("svn info"), but I would like to simply display the root cause.

This is even more different, if I only update the file itself (not the whole working copy). I will then receive two Action.UpdateUpdate events namely for the file itself and the folder that contains the file (but only for the direct parent folder).

I am using the SharpSvn.dll in version 1.8009.3299.43.

Thanks!

Example Code:

SharpSvn.SvnUpdateResult updateResult;
            SvnUpdateArgs updateArgs = new SvnUpdateArgs();
            updateArgs.IgnoreExternals = ignoreExternals;
            if (revision >= 0)
                updateArgs.Revision = revision;

            // Use throw on error, since this provides much more information why the operation failed
            // might slow down a little bit, since the exception must be handled
            updateArgs.ThrowOnError = true;

            List<Tuple<string, SvnUpdateFileChangeType>> changedFiles = new List<Tuple<string, SvnUpdateFileChangeType>>();
            using (var svnClient = new SvnClient())
            {
                svnClient.Notify += (sender, notifyEventArgs) =>
                {
                    switch (notifyEventArgs.Action)
                    {
                        case SvnNotifyAction.UpdateAdd:
                            changedFiles.Add(new Tuple<string, SvnUpdateFileChangeType>(notifyEventArgs.FullPath, SvnUpdateFileChangeType.Added));
                            break;
                        case SvnNotifyAction.UpdateDelete:
                            changedFiles.Add(new Tuple<string, SvnUpdateFileChangeType>(notifyEventArgs.FullPath, SvnUpdateFileChangeType.Deleted));
                            break;
                        case SvnNotifyAction.UpdateUpdate:
                            changedFiles.Add(new Tuple<string, SvnUpdateFileChangeType>(notifyEventArgs.FullPath, SvnUpdateFileChangeType.Updated));
                            break;
                        case SvnNotifyAction.UpdateShadowedAdd:
                            changedFiles.Add(new Tuple<string, SvnUpdateFileChangeType>(notifyEventArgs.FullPath, SvnUpdateFileChangeType.Added));
                            break;
                        case SvnNotifyAction.UpdateShadowedDelete:
                            changedFiles.Add(new Tuple<string, SvnUpdateFileChangeType>(notifyEventArgs.FullPath, SvnUpdateFileChangeType.Deleted));
                            break;
                        case SvnNotifyAction.UpdateShadowedUpdate:
                            changedFiles.Add(new Tuple<string, SvnUpdateFileChangeType>(notifyEventArgs.FullPath, SvnUpdateFileChangeType.Updated));
                            break;
                        case SvnNotifyAction.ConflictResolverStarting:
                            changedFiles.Add(new Tuple<string, SvnUpdateFileChangeType>(notifyEventArgs.FullPath, SvnUpdateFileChangeType.Conflicted));
                            break;
                    };
                };

                svnClient.Update(localPath, updateArgs, out updateResult);
            }

Update: The output becomes even more complicated if the check out depth is specified. For example a repository contains a file and a directory with another file inside. Both files receive a change in there content. Checking out the repository and then updating to the revision where the files content where changed, I receive a Action.UpdateUpdate event for the single file and the working copy directory, but not for the directory containing the as well updated file, despite svn info shows that the revision of the directory has changed.


Solution

  • What is notified is determined by the Subversion core libraries, not the SharpSvn layer on top. In general you can be sure that svn creates its output from 100% these same notifications. In some cases it will just drop or combine expected notifications to filter it to useful output.

    In general Subversion will try to update from one level higher than the target you specify (but just the target inside) to allow replacing the root operation in case that is what is needed to perform the update. This is needed as Subversion only allows updating everything in a tree as an edit operation on that tree.

    I usually peek at notify.c to see how it handles the notification. If you just want to show the same output there is an helper SvnClientReporter class inside SharpSvn that allows you to mostly recreate the svn output. (It should really replicate the output, but sometimes things get out of sync). This is the output you see in the AnkhSVN Subversion output window.