예제 #1
0
        /// <summary>Send changes from your working copy to the repository (<c>svn commit</c>)</summary>
        public bool Commit(ICollection <string> paths, out SvnCommitResult result)
        {
            if (paths == null)
            {
                throw new ArgumentNullException(nameof(paths));
            }

            return(Commit(paths, new SvnCommitArgs(), out result));
        }
예제 #2
0
        /// <summary>Send changes from your working copy to the repository (<c>svn commit</c>)</summary>
        public bool Commit(string path, out SvnCommitResult result)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            return(Commit(NewSingleItemCollection(path), new SvnCommitArgs(), out result));
        }
예제 #3
0
        /// <summary>Duplicate something in repository, remembering history (<c>svn copy</c>)</summary>
        public bool RemoteCopy(SvnTarget source, Uri toUri, out SvnCommitResult result)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (toUri == null)
            {
                throw new ArgumentNullException(nameof(toUri));
            }

            return(RemoteCopy(NewSingleItemCollection(source), toUri, new SvnCopyArgs(), out result));
        }
예제 #4
0
        /// <summary>Move and/or rename something in repository, remembering history (<c>svn move</c>)</summary>
        public bool RemoteMove(ICollection <Uri> sourceUris, Uri toUri, out SvnCommitResult result)
        {
            if (sourceUris == null)
            {
                throw new ArgumentNullException(nameof(sourceUris));
            }
            if (toUri == null)
            {
                throw new ArgumentNullException(nameof(toUri));
            }

            return(RemoteMove(sourceUris, toUri, new SvnMoveArgs(), out result));
        }
예제 #5
0
        /// <summary>Remove files and directories from version control at the repository (<c>svn delete|remove</c>)</summary>
        public bool RemoteDelete(ICollection <Uri> uris, SvnDeleteArgs args, out SvnCommitResult result)
        {
            if (uris == null)
            {
                throw new ArgumentNullException(nameof(uris));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            result = null;

            var uriData = new string[uris.Count];
            int i       = 0;

            foreach (Uri uri in uris)
            {
                if (uri == null)
                {
                    throw new ArgumentException(SharpSvnStrings.ItemInListIsNull, nameof(uris));
                }
                if (!IsValidReposUri(uri))
                {
                    throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAValidRepositoryUri, nameof(uris));
                }

                uriData[i++] = UriToCanonicalString(uri);
            }

            EnsureState(SvnContextState.AuthorizationInitialized);
            using var pool  = new AprPool(_pool);
            using var store = new ArgsStore(this, args, pool);
            using var crr   = new CommitResultReceiver(this);

            var aprPaths = new AprArray <string, AprUriMarshaller>(uriData, pool);

            svn_error_t r = svn_client.svn_client_delete4(
                aprPaths.Handle,
                args.Force,
                args.KeepLocal,
                CreateRevPropList(args.LogProperties, pool),
                crr.CommitCallback.Get(),
                crr.CommitBaton,
                CtxHandle,
                pool.Handle);

            result = crr.CommitResult;

            return(args.HandleResult(this, r, uris));
        }
예제 #6
0
        /// <summary>Move and/or rename something in repository, remembering history (<c>svn move</c>)</summary>
        public bool RemoteMove(Uri sourceUri, Uri toUri, SvnMoveArgs args, out SvnCommitResult result)
        {
            if (sourceUri == null)
            {
                throw new ArgumentNullException(nameof(sourceUri));
            }
            if (toUri == null)
            {
                throw new ArgumentNullException(nameof(toUri));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            return(RemoteMove(NewSingleItemCollection(sourceUri), toUri, args, out result));
        }
예제 #7
0
        /// <summary>Remove files and directories from version control at the repository (<c>svn delete|remove</c>)</summary>
        public bool RemoteDelete(Uri uri, SvnDeleteArgs args, out SvnCommitResult result)
        {
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (!IsValidReposUri(uri))
            {
                throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAValidRepositoryUri, nameof(uri));
            }

            return(RemoteDelete(NewSingleItemCollection(uri), args, out result));
        }
예제 #8
0
        /// <summary>Move and/or rename something in repository, remembering history (<c>svn move</c>)</summary>
        public bool RemoteMove(Uri sourceUri, Uri toUri, out SvnCommitResult result)
        {
            if (sourceUri == null)
            {
                throw new ArgumentNullException(nameof(sourceUri));
            }
            if (toUri == null)
            {
                throw new ArgumentNullException(nameof(toUri));
            }
            if (!IsValidReposUri(sourceUri))
            {
                throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAValidRepositoryUri, nameof(sourceUri));
            }
            if (!IsValidReposUri(toUri))
            {
                throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAValidRepositoryUri, nameof(toUri));
            }

            return(RemoteMove(NewSingleItemCollection(sourceUri), toUri, new SvnMoveArgs(), out result));
        }
예제 #9
0
        /// <summary>Duplicate something in repository, remembering history (<c>svn copy</c>)</summary>
        /// <remarks>Can be called with either a list of <see cref="SvnTarget" />, <see cref="SvnUriTarget" /> or <see cref="SvnPathTarget" />.
        /// All members must be of the same type.</remarks>
        public bool RemoteCopy <TSvnTarget>(ICollection <TSvnTarget> sources, Uri toUri, out SvnCommitResult result)
            where TSvnTarget : SvnTarget
        {
            if (sources == null)
            {
                throw new ArgumentNullException(nameof(sources));
            }
            if (toUri == null)
            {
                throw new ArgumentNullException(nameof(toUri));
            }

            return(RemoteCopy(sources, toUri, new SvnCopyArgs(), out result));
        }
예제 #10
0
        /// <summary>Duplicate something in repository, remembering history (<c>svn copy</c>)</summary>
        /// <remarks>Can be called with either a list of <see cref="SvnTarget" />, <see cref="SvnUriTarget" /> or <see cref="SvnPathTarget" />.
        /// All members must be of the same type.</remarks>
        public unsafe bool RemoteCopy <TSvnTarget>(ICollection <TSvnTarget> sources, Uri toUri, SvnCopyArgs args, out SvnCommitResult result)
            where TSvnTarget : SvnTarget
        {
            if (sources == null)
            {
                throw new ArgumentNullException(nameof(sources));
            }
            if (toUri == null)
            {
                throw new ArgumentNullException(nameof(toUri));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (!SvnBase.IsValidReposUri(toUri))
            {
                throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAValidRepositoryUri, nameof(toUri));
            }
            if (sources.Count == 0)
            {
                throw new ArgumentException(SharpSvnStrings.CollectionMustContainAtLeastOneItem, nameof(sources));
            }

            bool isFirst = true;
            bool isLocal = false;

            foreach (SvnTarget target in sources)
            {
                if (target == null)
                {
                    throw new ArgumentException(SharpSvnStrings.ItemInListIsNull, nameof(sources));
                }

                SvnPathTarget pt = target as SvnPathTarget;
                if (isFirst)
                {
                    isLocal = (null != pt);
                    isFirst = false;
                }
                else if (isLocal != (null != pt))
                {
                    throw new ArgumentException(SharpSvnStrings.AllTargetsMustBeUriOrPath, nameof(sources));
                }
            }

            EnsureState(SvnContextState.AuthorizationInitialized);

            using var pool  = new AprPool(_pool);
            using var store = new ArgsStore(this, args, pool);
            using var crr   = new CommitResultReceiver(this);

            apr_array_header_t copies = AllocCopyArray(sources, pool);

            if (copies != null && args.Revision.RevisionType != SvnRevisionType.None)
            {
                svn_opt_revision_t rev = args.Revision.AllocSvnRevision(pool);

                for (int i = 0; i < copies.nelts; i++)
                {
                    var cp = ((svn_client_copy_source_t.__Internal * *)copies.elts)[i];

                    cp->revision = rev.__Instance;
                }
            }

            svn_error_t r = svn_client.svn_client_copy7(
                copies,
                pool.AllocUri(toUri),
                args.AlwaysCopyAsChild || (sources.Count > 1),
                args.CreateParents,
                args.IgnoreExternals,
                args.MetaDataOnly,
                args.PinExternals,
                null /* */,
                CreateRevPropList(args.LogProperties, pool),
                crr.CommitCallback.Get(),
                crr.CommitBaton,
                CtxHandle,
                pool.Handle);

            result = crr.CommitResult;

            return(args.HandleResult(this, r, sources));
        }
예제 #11
0
        /// <summary>Move and/or rename something in repository, remembering history (<c>svn move</c>)</summary>
        public unsafe bool RemoteMove(ICollection <Uri> sourceUris, Uri toUri, SvnMoveArgs args, out SvnCommitResult result)
        {
            if (sourceUris == null)
            {
                throw new ArgumentNullException(nameof(sourceUris));
            }
            if (toUri == null)
            {
                throw new ArgumentNullException(nameof(toUri));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (!IsValidReposUri(toUri))
            {
                throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAValidRepositoryUri, nameof(toUri));
            }

            var uris = new List <string>(sourceUris.Count);

            foreach (Uri u in sourceUris)
            {
                if (u == null)
                {
                    throw new ArgumentException(SharpSvnStrings.ItemInListIsNull, nameof(sourceUris));
                }
                if (!IsValidReposUri(u))
                {
                    throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAValidRepositoryUri, nameof(sourceUris));
                }

                uris.Add(UriToCanonicalString(u));
            }

            EnsureState(SvnContextState.AuthorizationInitialized);
            using var pool  = new AprPool(_pool);
            using var store = new ArgsStore(this, args, pool);
            using var crr   = new CommitResultReceiver(this);

            svn_error_t r = svn_client.svn_client_move7(
                AllocArray(uris, pool),
                pool.AllocUri(toUri),
                args.AlwaysMoveAsChild || (sourceUris.Count > 1),
                args.CreateParents,
                args.AllowMixedRevisions,
                args.MetaDataOnly,
                CreateRevPropList(args.LogProperties, pool),
                crr.CommitCallback.Get(),
                crr.CommitBaton,
                CtxHandle,
                pool.Handle);

            result = crr.CommitResult;

            return(args.HandleResult(this, r, sourceUris));
        }
예제 #12
0
        /// <summary>Send changes from your working copy to the repository (<c>svn commit</c>)</summary>
        public bool Commit(ICollection <string> paths, SvnCommitArgs args, out SvnCommitResult result)
        {
            if (paths == null)
            {
                throw new ArgumentNullException(nameof(paths));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (paths.Count == 0)
            {
                throw new ArgumentException(SharpSvnStrings.CollectionMustContainAtLeastOneItem, nameof(paths));
            }

            foreach (string path in paths)
            {
                if (string.IsNullOrEmpty(path))
                {
                    throw new ArgumentException(SharpSvnStrings.ItemInListIsNull, nameof(paths));
                }
                if (!IsNotUri(path))
                {
                    throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAPathNotAUri, nameof(paths));
                }
            }

            EnsureState(SvnContextState.AuthorizationInitialized, args.RunTortoiseHooks ? SvnExtendedState.TortoiseSvnHooksLoaded : SvnExtendedState.None);
            using var pool  = new AprPool(_pool);
            using var store = new ArgsStore(this, args, pool);
            using var crr   = new CommitResultReceiver(this);

            var aprPaths = new AprArray <string, AprCStrDirentMarshaller>(paths, pool);

#if TORTOISE_HOOKS_AVAILABLE
            string        commonPath     = null;
            string        pathsFile      = null;
            string        msgFile        = null;
            SvnClientHook preCommitHook  = null;
            SvnClientHook postCommitHook = null;

            if (args.RunTortoiseHooks)
            {
                const char *pCommonPath;
                SVN_HANDLE(svn_dirent_condense_targets(&pCommonPath, NULL, aprPaths->Handle, FALSE, pool.Handle, pool.Handle));
                if (pCommonPath && pCommonPath[0] != '\0')
                {
                    commonPath = Utf8_PathPtrToString(pCommonPath, % pool);
                }

                if (!String::IsNullOrEmpty(commonPath))
                {
                    FindHook(commonPath, SvnClientHookType::PreCommit, preCommitHook);
                    FindHook(commonPath, SvnClientHookType::PostCommit, postCommitHook);
                }

                if (preCommitHook || postCommitHook)
                {
                    AprPool subpool(% pool);

                    const char *              path;
                    svn_stream_t *            f;
                    const apr_array_header_t *h = aprPaths->Handle;

                    /* Delete the tempfile on disposing the SvnClient */
                    SVN_HANDLE(svn_stream_open_unique(&f, &path, null, svn_io_file_del_on_pool_cleanup,
                                                      _pool.Handle, subpool.Handle));

                    for (int i = 0; i < h->nelts; i++)
                    {
                        SVN_HANDLE(svn_stream_printf(f, subpool.Handle, "%s\n",
                                                     svn_dirent_local_style(APR_ARRAY_IDX(h, i, const char *), subpool.Handle)));
                    }
                    SVN_HANDLE(svn_stream_close(f));
                    pathsFile = Utf8_PathPtrToString(path, % subpool);

                    /* Delete the tempfile on disposing the SvnClient */
                    SVN_HANDLE(svn_stream_open_unique(&f, &path, null, svn_io_file_del_on_pool_cleanup,
                                                      _pool.Handle, subpool.Handle));

                    SVN_HANDLE(svn_stream_printf(f, subpool.Handle, "%s",
                                                 subpool.AllocString(args->LogMessage)));
                    SVN_HANDLE(svn_stream_close(f));

                    msgFile = Utf8_PathPtrToString(path, % subpool);
                }
            }

            if (preCommitHook != null)
            {
                if (!preCommitHook->Run(this, args,
                                        pathsFile,
                                        ((int)args->Depth).ToString(CultureInfo::InvariantCulture),
                                        msgFile,
                                        commonPath))
                {
                    return(args->HandleResult(this, new SvnClientHookException("TortoiseSVN Client hook 'pre-commit' rejected commit")));
                }

                // Read the log message back from the hook script
                AprPool subpool(% pool);

                svn_stream_t *f;
                svn_string_t *msg;

                SVN_HANDLE(svn_stream_open_readonly(&f, subpool.AllocDirent(msgFile), subpool.Handle, subpool.Handle));
                SVN_HANDLE(svn_string_from_stream(&msg, f, subpool.Handle, subpool.Handle));
                SVN_HANDLE(svn_stream_close(f));

                // Overwrite the previous log message with the (possibly) adjusted one from the hook script
                args->LogMessage = SvnBase::Utf8_PtrToString(msg->data, msg->len);
            }
#endif // TORTOISE_HOOKS_AVAILABLE

            svn_error_t r = svn_client.svn_client_commit6(
                aprPaths.Handle,
                (svn_depth_t)args.Depth,
                args.KeepLocks,
                args.KeepChangeLists,
                true,
                args.IncludeFileExternals,
                args.IncludeDirectoryExternals,
                CreateChangeListsList(args.ChangeLists, pool), // Intersect ChangeLists
                CreateRevPropList(args.LogProperties, pool),
                crr.CommitCallback.Get(),
                crr.CommitBaton,
                CtxHandle,
                pool.Handle);

            result = crr.CommitResult;

#if TORTOISE_HOOKS_AVAILABLE
            if (postCommitHook != null)
            {
                AprPool subpool(% pool);

                const char *  path;
                svn_stream_t *f;
                char *        tmpBuf = (char *)subpool.Alloc(1024);

                /* Delete the tempfile on disposing the SvnClient */
                SVN_HANDLE(svn_stream_open_unique(&f, &path, null, svn_io_file_del_on_pool_cleanup,
                                                  _pool.Handle, subpool.Handle));

                svn_error_t *rr = r;

                while (rr)
                {
                    SVN_HANDLE(svn_stream_printf(f, subpool.Handle, "%s\n",
                                                 svn_err_best_message(rr, tmpBuf, 1024)));

                    rr = rr->child;
                }

                SVN_HANDLE(svn_stream_close(f));
                String ^ errFile = Utf8_PathPtrToString(path, % subpool);

                if (!postCommitHook->Run(this, args,
                                         pathsFile,
                                         ((int)args->Depth).ToString(CultureInfo::InvariantCulture),
                                         msgFile,
                                         (result ? result->Revision : -1).ToString(CultureInfo::InvariantCulture),
                                         errFile,
                                         commonPath))
                {
                    return(args->HandleResult(this, new SvnClientHookException("TortoiseSVN Client hook 'post-commit' failed")));
                }
            }
#endif // TORTOISE_HOOKS_AVAILABLE

            return(args.HandleResult(this, r, paths));
        }