Пример #1
0
        /// <summary>Updates the specified paths to the specified revision</summary>
        /// <exception type="SvnException">Operation failed and args.ThrowOnError = true</exception>
        /// <exception type="ArgumentException">Parameters invalid</exception>
        /// <returns>true if the operation succeeded; false if it did not</returns>
        public unsafe bool Update(ICollection <string> paths, SvnUpdateArgs args, out SvnUpdateResult updateResult)
        {
            if (paths == null)
            {
                throw new ArgumentNullException(nameof(paths));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            updateResult = null;

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

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

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

            apr_array_header_t.__Internal *revs_ptr = null;
            svn_opt_revision_t             uRev     = args.Revision.Or(SvnRevision.Head).AllocSvnRevision(pool);

            svn_error_t r = svn_client.svn_client_update4(
                (void **)&revs_ptr,
                aprPaths.Handle,
                uRev,
                (svn_depth_t)args.Depth,
                args.KeepDepth,
                args.IgnoreExternals,
                args.AllowObstructions,
                args.AddsAsModifications,
                args.UpdateParents,
                CtxHandle,
                pool.Handle);

            if (args.HandleResult(this, r, paths))
            {
                var revs = apr_array_header_t.__CreateInstance(new IntPtr(revs_ptr));

                var aprRevs = new AprArray <long, AprSvnRevNumMarshaller>(revs, pool);

                updateResult = new SvnUpdateResult(paths, aprRevs.ToArray(), (paths.Count >= 1) ? aprRevs[0] : -1);

                return(true);
            }

            return(false);
        }
Пример #2
0
        /// <summary>Adds the specified path</summary>
        /// <returns>true if the operation succeeded; false if it did not</returns>
        /// <exception type="SvnException">Operation failed and args.ThrowOnError = true</exception>
        /// <exception type="ArgumentException">Parameters invalid</exception>
        public unsafe bool Add(string path, SvnAddArgs args)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            EnsureState(SvnContextState.ConfigLoaded, SvnExtendedState.MimeTypesLoaded);
            using var pool  = new AprPool(_pool);
            using var store = new ArgsStore(this, args, pool);

            svn_error_t r = svn_client.svn_client_add5(
                pool.AllocDirent(path),
                (svn_depth_t)args.Depth,
                args.Force,
                args.NoIgnore,
                args.NoAutoProps,
                args.AddParents,
                CtxHandle,
                pool.Handle);

            return(args.HandleResult(this, r, path));
        }
Пример #3
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));
        }
Пример #4
0
        /// <summary>Streamingly lists directory entries in the repository. (<c>svn list</c>)</summary>
        public unsafe bool List(SvnTarget target, SvnListArgs args, EventHandler <SvnListEventArgs> listHandler)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            // We allow a null listHandler; the args object might just handle it itself

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

            args.Prepare(target, args.Revision.RevisionType != SvnRevisionType.None);

            if (listHandler != null)
            {
                args.List += listHandler;
            }

            try
            {
                svn_opt_revision_t pegrev = target.Revision.AllocSvnRevision(pool);
                svn_opt_revision_t rev    = args.Revision.Or(target.Revision).AllocSvnRevision(pool);

                using var svnclient_list_func_handle = new SafeFuncHandle <svn_client_list_func2_t>(svnclient_list_handler);

                svn_error_t r = svn_client.svn_client_list3(
                    target.AllocAsString(pool),
                    pegrev,
                    rev,
                    (svn_depth_t)args.Depth,
                    (uint)args.RetrieveEntries,
                    args.RetrieveLocks,
                    args.IncludeExternals,
                    svnclient_list_func_handle.Get(),
                    _clientBaton.Handle,
                    CtxHandle,
                    pool.Handle);

                return(args.HandleResult(this, r, target));
            }
            finally
            {
                if (listHandler != null)
                {
                    args.List -= listHandler;
                }
            }
        }
Пример #5
0
        /// <summary>Streamingly retrieves information about a local or remote item (<c>svn info</c>)</summary>
        public unsafe bool Info(SvnTarget target, SvnInfoArgs args, EventHandler <SvnInfoEventArgs> infoHandler)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            // We allow a null infoHandler; the args object might just handle it itself

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

            if (infoHandler != null)
            {
                args.Info += infoHandler;
            }

            try
            {
                var pegRev = target.GetSvnRevision(SvnRevision.None, SvnRevision.Head).AllocSvnRevision(pool);
                var rev    = args.Revision.Or(target.GetSvnRevision(SvnRevision.None, SvnRevision.Head)).AllocSvnRevision(pool);

                using var svn_info_receiver_handle = new SafeFuncHandle <svn_client_info_receiver2_t>(svn_info_receiver);

                svn_error_t r = svn_client.svn_client_info4(
                    target.AllocAsString(pool, true),
                    pegRev,
                    rev,
                    (svn_depth_t)args.Depth,
                    args.RetrieveExcluded,
                    args.RetrieveActualOnly,
                    args.IncludeExternals,
                    CreateChangeListsList(args.ChangeLists, pool), // Intersect ChangeLists
                    svn_info_receiver_handle.Get(),
                    _clientBaton.Handle,
                    CtxHandle,
                    pool.Handle);

                return(args.HandleResult(this, r, target));
            }
            finally
            {
                if (infoHandler != null)
                {
                    args.Info -= infoHandler;
                }
            }
        }
Пример #6
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));
        }
Пример #7
0
        /// <summary>Performs a checkout of <paramref name="url" /> to <paramref name="path" /> to the specified param</summary>
        /// <exception type="SvnException">Operation failed and args.ThrowOnError = true</exception>
        /// <exception type="ArgumentException">Parameters invalid</exception>
        /// <returns>true if the operation succeeded; false if it did not</returns>
        public unsafe bool CheckOut(SvnUriTarget url, string path, SvnCheckOutArgs args, out SvnUpdateResult result)
        {
            if (url == null)
            {
                throw new ArgumentNullException(nameof(url));
            }
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            if (args.Revision.RequiresWorkingCopy)
            {
                throw new ArgumentException(SharpSvnStrings.RevisionTypeMustBeHeadDateOrSpecific, nameof(args));
            }
            if (url.Revision.RequiresWorkingCopy)
            {
                throw new ArgumentException(SharpSvnStrings.RevisionTypeMustBeHeadDateOrSpecific, nameof(url));
            }

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

            int version = 0;

            svn_opt_revision_t pegRev = url.Revision.AllocSvnRevision(pool);
            svn_opt_revision_t coRev  = args.Revision.Or(url.Revision).Or(SvnRevision.Head).AllocSvnRevision(pool);

            svn_error_t r = svn_client.svn_client_checkout3(
                ref version,
                pool.AllocUri(url.Uri),
                pool.AllocDirent(path),
                pegRev,
                coRev,
                (svn_depth_t)args.Depth,
                args.IgnoreExternals,
                args.AllowObstructions,
                CtxHandle,
                pool.Handle);

            result = SvnUpdateResult.Create(this, args, version);

            return(args.HandleResult(this, r, url));
        }
Пример #8
0
        /// <summary>Exports the specified target to the specified path</summary>
        /// <remarks>Subversion optimizes this call if you specify a workingcopy file instead of an url</remarks>
        public unsafe bool Export(SvnTarget from, string toPath, SvnExportArgs args, out SvnUpdateResult result)
        {
            if (from == null)
            {
                throw new ArgumentNullException(nameof(from));
            }
            if (toPath == null)
            {
                throw new ArgumentNullException(nameof(toPath));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            EnsureState(SvnContextState.AuthorizationInitialized);

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

            result = null;

            int resultRev             = 0;
            svn_opt_revision_t pegRev = from.Revision.AllocSvnRevision(pool);
            svn_opt_revision_t rev    = args.Revision.Or(from.GetSvnRevision(SvnRevision.Working, SvnRevision.Head)).AllocSvnRevision(pool);

            svn_error_t r = svn_client.svn_client_export5(
                ref resultRev,
                from.AllocAsString(pool),
                pool.AllocDirent(toPath),
                pegRev,
                rev,
                args.Overwrite,
                args.IgnoreExternals,
                args.IgnoreKeywords,
                (svn_depth_t)args.Depth,
                pool.AllocString(GetEolPtr(args.LineStyle)),
                CtxHandle,
                pool.Handle);

            if (args.HandleResult(this, r, from))
            {
                result = SvnUpdateResult.Create(this, args, resultRev);
                return(true);
            }

            return(false);
        }
Пример #9
0
        /// <summary>Move and/or rename something in working copy, remembering history (<c>svn move</c>)</summary>
        public unsafe bool Move(ICollection <string> sourcePaths, string toPath, SvnMoveArgs args)
        {
            if (sourcePaths == null)
            {
                throw new ArgumentNullException(nameof(sourcePaths));
            }
            if (string.IsNullOrEmpty(toPath))
            {
                throw new ArgumentNullException(nameof(toPath));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

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

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

            svn_error_t r = svn_client.svn_client_move7(
                AllocDirentArray(sourcePaths, pool),
                pool.AllocDirent(toPath),
                args.AlwaysMoveAsChild || (sourcePaths.Count > 1),
                args.CreateParents,
                args.AllowMixedRevisions,
                args.MetaDataOnly,
                null,
                null,
                IntPtr.Zero,
                CtxHandle,
                pool.Handle);

            return(args.HandleResult(this, r, sourcePaths));
        }
Пример #10
0
        /// <summary>Remove files and directories from version control, scheduling (<c>svn delete|remove</c>)</summary>
        public bool Delete(ICollection <string> paths, SvnDeleteArgs args)
        {
            if (paths == null)
            {
                throw new ArgumentNullException(nameof(paths));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            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.ConfigLoaded);
            using var pool  = new AprPool(_pool);
            using var store = new ArgsStore(this, args, pool);

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

            svn_error_t r = svn_client.svn_client_delete4(
                aprPaths.Handle,
                args.Force,
                args.KeepLocal,
                null,
                null,
                IntPtr.Zero,
                CtxHandle,
                pool.Handle);

            return(args.HandleResult(this, r, paths));
        }
Пример #11
0
        unsafe bool InternalSetProperty(string target, string propertyName, svn_string_t value, SvnSetPropertyArgs args, AprPool pool)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentNullException(nameof(propertyName));
            }
            if (string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentNullException(nameof(propertyName));
            }

            EnsureState(SvnContextState.ConfigLoaded); // We might need repository access
            using var store = new ArgsStore(this, args, pool);

            sbyte *pcPropertyName = pool.AllocString(propertyName);

            if (!svn_props.svn_prop_name_is_valid(pcPropertyName))
            {
                throw new ArgumentException(SharpSvnStrings.PropertyNameIsNotValid, nameof(propertyName));
            }

            svn_error_t r = svn_client.svn_client_propset_local(
                pcPropertyName,
                value,
                AllocDirentArray(NewSingleItemCollection(SvnTools.GetNormalizedFullPath(target)), pool),
                (svn_depth_t)args.Depth,
                args.SkipChecks,
                CreateChangeListsList(args.ChangeLists, pool), // Intersect ChangeLists
                CtxHandle,
                pool.Handle);

            return(args.HandleResult(this, r, target));
        }
Пример #12
0
        unsafe bool InternalWrite(SvnTarget target, Stream output, SvnWriteArgs args, apr_hash_t.__Internal **props, AprPool resultPool)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }
            if (args == null)
            {
                throw new ObjectDisposedException(nameof(args));
            }

            using var scratchPool = new AprPool(resultPool);
            EnsureState(SvnContextState.AuthorizationInitialized);
            using var store = new ArgsStore(this, args, scratchPool);

            using var wrapper = new SvnStreamWrapper(output, false, true, scratchPool);

            svn_opt_revision_t pegRev = target.Revision.AllocSvnRevision(scratchPool);
            svn_opt_revision_t rev    = args.Revision.Or(target.Revision).AllocSvnRevision(scratchPool);

            svn_error_t r = svn_client.svn_client_cat3(
                (void **)props,
                wrapper.Handle,
                target.AllocAsString(scratchPool, true),
                pegRev,
                rev,
                !args.IgnoreKeywords,
                CtxHandle,
                resultPool.Handle,
                scratchPool.Handle);

            return(args.HandleResult(this, r, target));
        }
Пример #13
0
        unsafe bool InternalLog(ICollection <string> targets, Uri searchRoot, SvnRevision altPegRev, SvnLogArgs args, EventHandler <SvnLogEventArgs> logHandler)
        {
            if (targets == null)
            {
                throw new ArgumentNullException(nameof(targets));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

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

            args._mergeLogLevel = 0; // Clear log level
            args._searchRoot    = searchRoot;

            if (logHandler != null)
            {
                args.Log += logHandler;
            }

            try
            {
                apr_array_header_t retrieveProperties;

                if (args.RetrieveAllProperties)
                {
                    retrieveProperties = null;
                }
                else if (args.RetrievePropertiesUsed)
                {
                    retrieveProperties = AllocArray(args.RetrieveProperties, pool);
                }
                else
                {
                    retrieveProperties = svn_compat.svn_compat_log_revprops_in(pool.Handle);
                }

                svn_opt_revision_t pegRev = args.OriginRevision.Or(altPegRev).AllocSvnRevision(pool);

                int count          = args.RangesUsed ? args.Ranges.Count : 1;
                var revisionRanges = apr_tables.apr_array_make(
                    pool.Handle, count, sizeof(svn_opt_revision_range_t.__Internal *));

                if (args.RangesUsed)
                {
                    foreach (SvnRevisionRange r in args.Ranges)
                    {
                        var range = (svn_opt_revision_range_t.__Internal *)pool.Alloc(
                            sizeof(svn_opt_revision_range_t.__Internal));

                        range->start = r.StartRevision.Or(SvnRevision.Head).ToSvnRevision();
                        range->end   = r.EndRevision.Or(SvnRevision.Zero).ToSvnRevision();

                        *((svn_opt_revision_range_t.__Internal * *)apr_tables.apr_array_push(revisionRanges)) = range;
                    }
                }
                else
                {
                    var range = (svn_opt_revision_range_t.__Internal *)pool.Alloc(
                        sizeof(svn_opt_revision_range_t.__Internal));

                    range->start = args.Start.Or(args.OriginRevision).Or(SvnRevision.Head).ToSvnRevision();
                    range->end   = args.End.Or(SvnRevision.Zero).ToSvnRevision();

                    *((svn_opt_revision_range_t.__Internal * *)apr_tables.apr_array_push(revisionRanges)) = range;
                }

                using var svnclient_log_receiver_handle = new SafeFuncHandle <svn_log_entry_receiver_t>(svnclient_log_handler);

                svn_error_t err = svn_client.svn_client_log5(
                    AllocArray(targets, pool),
                    pegRev,
                    revisionRanges,
                    args.Limit,
                    args.RetrieveChangedPaths,
                    args.StrictNodeHistory,
                    args.RetrieveMergedRevisions,
                    retrieveProperties,
                    svnclient_log_receiver_handle.Get(),
                    _clientBaton.Handle,
                    CtxHandle,
                    pool.Handle);

                return(args.HandleResult(this, err, targets));
            }
            finally
            {
                if (logHandler != null)
                {
                    args.Log -= logHandler;
                }

                args._searchRoot    = null;
                args._mergeLogLevel = 0;
            }
        }
Пример #14
0
        /// <summary>Sets the specified property on the specfied path to value</summary>
        /// <remarks>Use <see cref="DeleteProperty(string, string, SvnSetPropertyArgs)" /> to remove an existing property</remarks>
        public unsafe bool GetProperty(SvnTarget target, string propertyName, SvnGetPropertyArgs args, out SvnTargetPropertyCollection properties)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException(nameof(propertyName));
            }

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

            var pegRev    = target.Revision.AllocSvnRevision(pool);
            var rev       = args.Revision.Or(target.Revision).AllocSvnRevision(pool);
            int actualRev = 0;

            apr_hash_t.__Internal *pHash = null;

            sbyte *pName = pool.AllocString(propertyName);

            sbyte *prefix     = null;
            sbyte *targetName = target.AllocAsString(pool);

            if (!svn_path.svn_path_is_url(targetName))
            {
                prefix = targetName;

                targetName = target.AllocAsString(pool, true);
            }

            svn_error_t r = svn_client.svn_client_propget5(
                (void **)&pHash,
                null,
                pName,
                targetName,
                pegRev,
                rev,
                ref actualRev,
                (svn_depth_t)args.Depth,
                CreateChangeListsList(args.ChangeLists, pool), // Intersect ChangeLists
                CtxHandle,
                pool.Handle,
                pool.Handle);

            if (pHash != null)
            {
                var rd = new SvnTargetPropertyCollection();

                apr_hash_t hash = apr_hash_t.__CreateInstance(new IntPtr(pHash));

                for (apr_hash_index_t hi = apr_hash.apr_hash_first(pool.Handle, hash); hi != null; hi = apr_hash.apr_hash_next(hi))
                {
                    sbyte *pKey;
                    long   keyLen = 0;
                    svn_string_t.__Internal *propVal;

                    apr_hash.apr_hash_this(hi, (void **)&pKey, ref keyLen, (void **)&propVal);

                    SvnTarget itemTarget;
                    if (prefix != null && !svn_path.svn_path_is_url(pKey))
                    {
                        string path = Utf8_PathPtrToString(
                            svn_dirent_uri.svn_dirent_join(
                                prefix,
                                svn_dirent_uri.svn_dirent_skip_ancestor(targetName, pKey),
                                pool.Handle),
                            pool);

                        if (!string.IsNullOrEmpty(path))
                        {
                            itemTarget = path;
                        }
                        else
                        {
                            itemTarget = ".";
                        }
                    }
                    else
                    {
                        itemTarget = Utf8_PtrToUri(pKey, SvnNodeKind.Unknown);
                    }

                    var propValStr = svn_string_t.__CreateInstance(new IntPtr(propVal));
                    rd.Add(SvnPropertyValue.Create(pName, propValStr, itemTarget, propertyName));
                }

                properties = rd;
            }

            return(args.HandleResult(this, r, target));
        }
Пример #15
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));
        }
Пример #16
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));
        }
Пример #17
0
        /// <summary>Gets status data for the specified path</summary>
        public unsafe bool Status(string path, SvnStatusArgs args, EventHandler <SvnStatusEventArgs> statusHandler)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (!IsNotUri(path))
            {
                throw new ArgumentException(SharpSvnStrings.ArgumentMustBeAPathNotAUri, nameof(path));
            }

            // We allow a null statusHandler; the args object might just handle it itself

            if (args.ContactRepository)
            {
                EnsureState(SvnContextState.AuthorizationInitialized);
            }
            else
            {
                EnsureState(SvnContextState.ConfigLoaded);
            }

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

            if (statusHandler != null)
            {
                args.Status += statusHandler;
            }

            try
            {
                int version = 0;

                svn_opt_revision_t pegRev = args.Revision.AllocSvnRevision(pool);

                using var svnclient_status_func_handle = new SafeFuncHandle <svn_client_status_func_t>(svnclient_status_handler);

                svn_error_t r = svn_client.svn_client_status6(
                    ref version,
                    CtxHandle,
                    pool.AllocDirent(path),
                    pegRev,
                    (svn_depth_t)args.Depth,
                    args.RetrieveAllEntries,
                    args.RetrieveRemoteStatus,
                    !args.IgnoreWorkingCopyStatus,
                    args.RetrieveIgnoredEntries,
                    args.IgnoreExternals,
                    args.KeepDepth,
                    CreateChangeListsList(args.ChangeLists, pool), // Intersect ChangeLists
                    svnclient_status_func_handle.Get(),
                    _clientBaton.Handle,
                    pool.Handle);

                return(args.HandleResult(this, r, path));
            }
            finally
            {
                if (statusHandler != null)
                {
                    args.Status -= statusHandler;
                }
            }
        }