/// <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)); }
/// <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)); }
/// <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); }
/// <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)); }
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)); }
/// <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; } }
internal ReferenceCollection(LibGit2Sharp.ReferenceCollection collection) => this.innerCollection = collection.NotNull();
/// <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)); }
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)); }
/// <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)); }
/// <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 })); }