/// <summary>
        ///   Updates the target of a reference.
        /// </summary>
        /// <param name = "name">The canonical name of the reference.</param>
        /// <param name = "canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param>
        /// <param name = "refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> of the <paramref name="name"/> reference.</param>
        /// <returns>A new <see cref = "Reference" />.</returns>
        public static Reference UpdateTarget(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, string logMessage = null)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish");

            if (name == "HEAD")
            {
                return refsColl.Add("HEAD", canonicalRefNameOrObjectish, true);
            }

            Reference reference = refsColl[name];

            var directReference = reference as DirectReference;
            if (directReference != null)
            {
                return refsColl.UpdateTarget(directReference, canonicalRefNameOrObjectish, logMessage);
            }

            var symbolicReference = reference as SymbolicReference;
            if (symbolicReference != null)
            {
                Reference targetRef;

                RefState refState = TryResolveReference(out targetRef, refsColl, canonicalRefNameOrObjectish);

                if (refState == RefState.DoesNotLookValid)
                {
                    throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The reference specified by {0} is a Symbolic reference, you must provide a reference canonical name as the target.", name), "canonicalRefNameOrObjectish");
                }

                return refsColl.UpdateTarget(symbolicReference, targetRef, logMessage);
            }

            throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, "Reference '{0}' has an unexpected type ('{1}').", name, reference.GetType()));
        }
        /// <summary>
        /// Creates a direct or symbolic reference with the specified name and target
        /// </summary>
        /// <param name="name">The name of the reference to create.</param>
        /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param>
        /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="Reference"/></param>
        /// <returns>A new <see cref="Reference"/>.</returns>
        public static Reference Add(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false, string logMessage = null)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish");

            Reference reference;
            RefState  refState = TryResolveReference(out reference, refsColl, canonicalRefNameOrObjectish);

            var gitObject = refsColl.repo.Lookup(canonicalRefNameOrObjectish, GitObjectType.Any, LookUpOptions.None);

            if (refState == RefState.Exists)
            {
                return(refsColl.Add(name, reference, allowOverwrite, logMessage));
            }

            if (refState == RefState.DoesNotExistButLooksValid && gitObject == null)
            {
                using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(refsColl.repo.Handle, name, canonicalRefNameOrObjectish, allowOverwrite))
                {
                    return(Reference.BuildFromPtr <Reference>(handle, refsColl.repo));
                }
            }

            Ensure.GitObjectIsNotNull(gitObject, canonicalRefNameOrObjectish);

            return(refsColl.Add(name, gitObject.Id, allowOverwrite, logMessage));
        }
Exemple #3
0
        /// <summary>
        /// Creates a direct or symbolic reference with the specified name and target
        /// </summary>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="name">The name of the reference to create.</param>
        /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param>
        /// <param name="signature">The identity used for updating the reflog</param>
        /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="Reference"/></param>
        /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
        /// <returns>A new <see cref="Reference"/>.</returns>
        public static Reference Add(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, Signature signature, string logMessage, bool allowOverwrite = false)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish");

            Reference reference;
            RefState  refState = TryResolveReference(out reference, refsColl, canonicalRefNameOrObjectish);

            var gitObject = refsColl.repo.Lookup(canonicalRefNameOrObjectish, GitObjectType.Any, LookUpOptions.None);

            if (refState == RefState.Exists)
            {
                return(refsColl.Add(name, reference, signature, logMessage, allowOverwrite));
            }

            if (refState == RefState.DoesNotExistButLooksValid && gitObject == null)
            {
                using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(refsColl.repo.Handle, name, canonicalRefNameOrObjectish, allowOverwrite,
                                                                                        signature.OrDefault(refsColl.repo.Config), logMessage))
                {
                    return(Reference.BuildFromPtr <Reference>(handle, refsColl.repo));
                }
            }

            Ensure.GitObjectIsNotNull(gitObject, canonicalRefNameOrObjectish);

            if (logMessage == null)
            {
                logMessage = string.Format(CultureInfo.InvariantCulture, "{0}: Created from {1}",
                                           name.LooksLikeLocalBranch() ? "branch" : "reference", canonicalRefNameOrObjectish);
            }

            refsColl.EnsureHasLog(name);
            return(refsColl.Add(name, gitObject.Id, signature, logMessage, allowOverwrite));
        }
Exemple #4
0
        /// <summary>
        ///   Initializes a new instance of the <see cref = "Repository" /> class, providing ooptional behavioral overrides through <paramref name="options"/> parameter.
        ///   <para>For a standard repository, <paramref name = "path" /> should either point to the ".git" folder or to the working directory. For a bare repository, <paramref name = "path" /> should directly point to the repository folder.</para>
        /// </summary>
        /// <param name = "path">
        ///   The path to the git repository to open, can be either the path to the git directory (for non-bare repositories this
        ///   would be the ".git" folder inside the working directory) or the path to the working directory.
        /// </param>
        /// <param name="options">
        ///   Overrides to the way a repository is opened.
        /// </param>
        public Repository(string path, RepositoryOptions options = null)
        {
            Ensure.ArgumentNotNullOrEmptyString(path, "path");

            Ensure.Success(NativeMethods.git_repository_open(out handle, path));
            RegisterForCleanup(handle);

            bool isBare = NativeMethods.RepositoryStateChecker(handle, NativeMethods.git_repository_is_bare);

            Func <Index> indexBuilder = () => new Index(this);

            string configurationGlobalFilePath = null;
            string configurationSystemFilePath = null;

            if (options != null)
            {
                bool isWorkDirNull = string.IsNullOrEmpty(options.WorkingDirectoryPath);
                bool isIndexNull   = string.IsNullOrEmpty(options.IndexPath);

                if (isBare && (isWorkDirNull ^ isIndexNull))
                {
                    throw new ArgumentException("When overriding the opening of a bare repository, both RepositoryOptions.WorkingDirectoryPath an RepositoryOptions.IndexPath have to be provided.");
                }

                isBare = false;

                if (!isIndexNull)
                {
                    indexBuilder = () => new Index(this, options.IndexPath);
                }

                if (!isWorkDirNull)
                {
                    Ensure.Success(NativeMethods.git_repository_set_workdir(handle, options.WorkingDirectoryPath));
                }

                configurationGlobalFilePath = options.GlobalConfigurationLocation;
                configurationSystemFilePath = options.SystemConfigurationLocation;
            }

            if (!isBare)
            {
                index = indexBuilder();
            }

            commits  = new CommitCollection(this);
            refs     = new ReferenceCollection(this);
            branches = new BranchCollection(this);
            tags     = new TagCollection(this);
            info     = new Lazy <RepositoryInformation>(() => new RepositoryInformation(this, isBare));
            config   = new Lazy <Configuration>(() => RegisterForCleanup(new Configuration(this, configurationGlobalFilePath, configurationSystemFilePath)));
            remotes  = new Lazy <RemoteCollection>(() => new RemoteCollection(this));
            odb      = new Lazy <ObjectDatabase>(() => new ObjectDatabase(this));
            diff     = new Diff(this);
            notes    = new NoteCollection(this);
        }
Exemple #5
0
        /// <summary>
        /// Find the <see cref="Reference"/>s among <paramref name="refSubset"/>
        /// that can reach at least one <see cref="Commit"/> in the specified <paramref name="targets"/>.
        /// </summary>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="refSubset">The set of <see cref="Reference"/>s to examine.</param>
        /// <param name="targets">The set of <see cref="Commit"/>s that are interesting.</param>
        /// <returns>A subset of <paramref name="refSubset"/> that can reach at least one <see cref="Commit"/> within <paramref name="targets"/>.</returns>
        public static IEnumerable <Reference> ReachableFrom(
            this ReferenceCollection refsColl,
            IEnumerable <Reference> refSubset,
            IEnumerable <Commit> targets)
        {
            Ensure.ArgumentNotNull(refSubset, "refSubset");
            Ensure.ArgumentNotNull(targets, "targets");

            var refs = new List <Reference>(refSubset);

            if (refs.Count == 0)
            {
                return(Enumerable.Empty <Reference>());
            }

            List <ObjectId> targetsSet = targets.Select(c => c.Id).Distinct().ToList();

            if (targetsSet.Count == 0)
            {
                return(Enumerable.Empty <Reference>());
            }

            var result = new List <Reference>();

            foreach (var reference in refs)
            {
                var peeledTargetCommit = reference
                                         .ResolveToDirectReference()
                                         .Target.DereferenceToCommit(false);

                if (peeledTargetCommit == null)
                {
                    continue;
                }

                var commitId = peeledTargetCommit.Id;

                foreach (var potentialAncestorId in targetsSet)
                {
                    if (potentialAncestorId == commitId)
                    {
                        result.Add(reference);
                        break;
                    }

                    if (Proxy.git_graph_descendant_of(refsColl.repo.Handle, commitId, potentialAncestorId))
                    {
                        result.Add(reference);
                        break;
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Updates the target of a direct reference.
        /// </summary>
        /// <param name="directRef">The direct reference which target should be updated.</param>
        /// <param name="objectish">The revparse spec of the target.</param>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> of the <paramref name="directRef"/> reference.</param>
        /// <returns>A new <see cref="Reference"/>.</returns>
        public static Reference UpdateTarget(this ReferenceCollection refsColl, Reference directRef, string objectish, string logMessage = null)
        {
            Ensure.ArgumentNotNull(directRef, "directRef");
            Ensure.ArgumentNotNull(objectish, "objectish");

            GitObject target = refsColl.repo.Lookup(objectish);

            Ensure.GitObjectIsNotNull(target, objectish);

            return(refsColl.UpdateTarget(directRef, target.Id, logMessage));
        }
Exemple #7
0
        private static RefState TryResolveReference(out Reference reference, ReferenceCollection refsColl, string canonicalName)
        {
            if (!Reference.IsValidName(canonicalName))
            {
                reference = null;
                return(RefState.DoesNotLookValid);
            }

            reference = refsColl[canonicalName];

            return(reference != null ? RefState.Exists : RefState.DoesNotExistButLooksValid);
        }
        /// <summary>
        /// Delete a reference with the specified name
        /// </summary>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="name">The canonical name of the reference to delete.</param>
        public static void Remove(this ReferenceCollection refsColl, string name)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");

            Reference reference = refsColl[name];

            if (reference == null)
            {
                return;
            }

            refsColl.Remove(reference);
        }
        /// <summary>
        /// Rename an existing reference with a new name
        /// </summary>
        /// <param name="currentName">The canonical name of the reference to rename.</param>
        /// <param name="newName">The new canonical name.</param>
        /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <returns>A new <see cref="Reference"/>.</returns>
        public static Reference Move(this ReferenceCollection refsColl, string currentName, string newName, bool allowOverwrite = false)
        {
            Ensure.ArgumentNotNullOrEmptyString(currentName, "currentName");

            Reference reference = refsColl[currentName];

            if (reference == null)
            {
                throw new LibGit2SharpException(
                          string.Format(CultureInfo.InvariantCulture,
                                        "Reference '{0}' doesn't exist. One cannot move a non existing reference.", currentName));
            }

            return(refsColl.Move(reference, newName, allowOverwrite));
        }
        /// <summary>
        /// Find the <see cref="Reference"/>s among <paramref name="refSubset"/>
        /// that can reach at least one <see cref="Commit"/> in the specified <paramref name="targets"/>.
        /// </summary>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="refSubset">The set of <see cref="Reference"/>s to examine.</param>
        /// <param name="targets">The set of <see cref="Commit"/>s that are interesting.</param>
        /// <returns>A subset of <paramref name="refSubset"/> that can reach at least one <see cref="Commit"/> within <paramref name="targets"/>.</returns>
        public static IEnumerable <Reference> ReachableFrom(
            this ReferenceCollection refsColl,
            IEnumerable <Reference> refSubset,
            IEnumerable <Commit> targets)
        {
            Ensure.ArgumentNotNull(refSubset, "refSubset");
            Ensure.ArgumentNotNull(targets, "targets");

            var refs = new List <Reference>(refSubset);

            if (refs.Count == 0)
            {
                return(Enumerable.Empty <Reference>());
            }

            var targetsSet = new HashSet <Commit>(targets);

            if (targetsSet.Count == 0)
            {
                return(Enumerable.Empty <Reference>());
            }

            var allCommits = refsColl.repo.Commits;

            var result = new List <Reference>();

            foreach (var reference in refs)
            {
                foreach (var commit in allCommits.QueryBy(new CommitFilter {
                    Since = reference
                }))
                {
                    if (!targetsSet.Contains(commit))
                    {
                        continue;
                    }

                    result.Add(reference);
                    break;
                }
            }

            return(result);
        }
        /// <summary>
        ///   Initializes a new instance of the <see cref = "Repository" /> class.
        ///   <para>For a standard repository, <paramref name = "path" /> should point to the ".git" folder. For a bare repository, <paramref name = "path" /> should directly point to the repository folder.</para>
        /// </summary>
        /// <param name = "path">The path to the git repository to open.</param>
        public Repository(string path)
        {
            Ensure.ArgumentNotNullOrEmptyString(path, "path");

            int res = NativeMethods.git_repository_open(out handle, PosixPathHelper.ToPosix(path));

            Ensure.Success(res);

            isBare = NativeMethods.git_repository_is_bare(handle);

            if (!isBare)
            {
                index = new Index(this);
            }

            commits  = new CommitCollection(this);
            refs     = new ReferenceCollection(this);
            branches = new BranchCollection(this);
            tags     = new TagCollection(this);
            info     = new Lazy <RepositoryInformation>(() => new RepositoryInformation(this, isBare));
            config   = new Lazy <Configuration>(() => new Configuration(this));
            remotes  = new Lazy <RemoteCollection>(() => new RemoteCollection(this));
        }
Exemple #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Repository"/> class, providing ooptional behavioral overrides through <paramref name="options"/> parameter.
        /// <para>For a standard repository, <paramref name="path"/> should either point to the ".git" folder or to the working directory. For a bare repository, <paramref name="path"/> should directly point to the repository folder.</para>
        /// </summary>
        /// <param name="path">
        /// The path to the git repository to open, can be either the path to the git directory (for non-bare repositories this
        /// would be the ".git" folder inside the working directory) or the path to the working directory.
        /// </param>
        /// <param name="options">
        /// Overrides to the way a repository is opened.
        /// </param>
        public Repository(string path, RepositoryOptions options = null)
        {
            Ensure.ArgumentNotNullOrEmptyString(path, "path");

            try
            {
                handle = Proxy.git_repository_open(path);
                RegisterForCleanup(handle);

                isBare = Proxy.git_repository_is_bare(handle);

                Func <Index> indexBuilder = () => new Index(this);

                string configurationGlobalFilePath = null;
                string configurationXDGFilePath    = null;
                string configurationSystemFilePath = null;

                if (options != null)
                {
                    bool isWorkDirNull = string.IsNullOrEmpty(options.WorkingDirectoryPath);
                    bool isIndexNull   = string.IsNullOrEmpty(options.IndexPath);

                    if (isBare && (isWorkDirNull ^ isIndexNull))
                    {
                        throw new ArgumentException(
                                  "When overriding the opening of a bare repository, both RepositoryOptions.WorkingDirectoryPath an RepositoryOptions.IndexPath have to be provided.");
                    }

                    isBare = false;

                    if (!isIndexNull)
                    {
                        indexBuilder = () => new Index(this, options.IndexPath);
                    }

                    if (!isWorkDirNull)
                    {
                        Proxy.git_repository_set_workdir(handle, options.WorkingDirectoryPath);
                    }

                    configurationGlobalFilePath = options.GlobalConfigurationLocation;
                    configurationXDGFilePath    = options.XdgConfigurationLocation;
                    configurationSystemFilePath = options.SystemConfigurationLocation;
                }

                if (!isBare)
                {
                    index = indexBuilder();
                }

                commits  = new CommitLog(this);
                refs     = new ReferenceCollection(this);
                branches = new BranchCollection(this);
                tags     = new TagCollection(this);
                stashes  = new StashCollection(this);
                info     = new Lazy <RepositoryInformation>(() => new RepositoryInformation(this, isBare));
                config   =
                    new Lazy <Configuration>(
                        () =>
                        RegisterForCleanup(new Configuration(this, configurationGlobalFilePath, configurationXDGFilePath,
                                                             configurationSystemFilePath)));
                odb        = new Lazy <ObjectDatabase>(() => new ObjectDatabase(this));
                diff       = new Diff(this);
                notes      = new NoteCollection(this);
                ignore     = new Ignore(this);
                network    = new Lazy <Network>(() => new Network(this));
                pathCase   = new Lazy <PathCase>(() => new PathCase(this));
                submodules = new SubmoduleCollection(this);

                EagerlyLoadTheConfigIfAnyPathHaveBeenPassed(options);
            }
            catch
            {
                CleanupDisposableDependencies();
                throw;
            }
        }
Exemple #13
0
 internal ReferenceCollection(LibGit2Sharp.ReferenceCollection collection)
 => this.innerCollection = collection.NotNull();
Exemple #14
0
 /// <summary>
 /// Updates the target of a direct reference
 /// </summary>
 /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
 /// <param name="directRef">The direct reference which target should be updated.</param>
 /// <param name="objectish">The revparse spec of the target.</param>
 /// <returns>A new <see cref="Reference"/>.</returns>
 public static Reference UpdateTarget(this ReferenceCollection refsColl, Reference directRef, string objectish)
 {
     return(UpdateTarget(refsColl, directRef, objectish, null, null));
 }
Exemple #15
0
 public static Reference Move(this ReferenceCollection refsColl, string currentName, string newName,
                              Signature signature = null, string logMessage = null, bool allowOverwrite = false)
 {
     return(refsColl.Rename(currentName, newName, signature, logMessage, allowOverwrite));
 }
 /// <summary>
 /// Find the <see cref="Reference"/>s
 /// that can reach at least one <see cref="Commit"/> in the specified <paramref name="targets"/>.
 /// </summary>
 /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
 /// <param name="targets">The set of <see cref="Commit"/>s that are interesting.</param>
 /// <returns>The list of <see cref="Reference"/> that can reach at least one <see cref="Commit"/> within <paramref name="targets"/>.</returns>
 public static IEnumerable <Reference> ReachableFrom(
     this ReferenceCollection refsColl,
     IEnumerable <Commit> targets)
 {
     return(ReachableFrom(refsColl, refsColl, targets));
 }
Exemple #17
0
 /// <summary>
 /// Updates the target of a reference
 /// </summary>
 /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
 /// <param name="name">The canonical name of the reference.</param>
 /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param>
 /// <returns>A new <see cref="Reference"/>.</returns>
 public static Reference UpdateTarget(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish)
 {
     return(UpdateTarget(refsColl, name, canonicalRefNameOrObjectish, null, null));
 }
Exemple #18
0
 /// <summary>
 /// Creates a direct or symbolic reference with the specified name and target
 /// </summary>
 /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
 /// <param name="name">The name of the reference to create.</param>
 /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param>
 /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
 /// <returns>A new <see cref="Reference"/>.</returns>
 public static Reference Add(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false)
 {
     return(Add(refsColl, name, canonicalRefNameOrObjectish, null, null, allowOverwrite));
 }
        /// <summary>
        /// Moves the head target.
        /// </summary>
        /// <typeparam name="T">Type of target.</typeparam>
        /// <param name="references">The references.</param>
        /// <param name="target">The target.</param>
        /// <returns>The new <see cref="Reference"/>.</returns>
        internal static Reference MoveHeadTarget <T>(this ReferenceCollection references, T target)
        {
            var method = _referenceCollectionMoveHeadTarget.MakeGenericMethod(typeof(T));

            return((Reference)method.Invoke(references, new object[] { target }));
        }