private DiffSafeHandle BuildDiffList( ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, DiffModifiers diffOptions, IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) { var matchedPaths = new MatchedPathsAggregator(); var filePaths = repo.ToFilePaths(paths); using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions)) { var diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options); if (explicitPathsOptions != null) { try { DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths); } catch { diffList.Dispose(); throw; } } DetectRenames(diffList, compareOptions); return(diffList); } }
/// <summary> /// Show changes between a <see cref="Tree"/> and the Index, the Working Directory, or both. /// <para> /// The level of diff performed can be specified by passing either a <see cref="TreeChanges"/> /// or <see cref="Patch"/> type as the generic parameter. /// </para> /// </summary> /// <param name="oldTree">The <see cref="Tree"/> to compare from.</param> /// <param name="diffTargets">The targets to compare to.</param> /// <param name="paths">The list of paths (either files or directories) that should be compared.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> /// <param name="compareOptions">Additional options to define patch generation behavior.</param> /// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or /// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam> /// <returns>A <typeparamref name="T"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns> public virtual T Compare <T>(Tree oldTree, DiffTargets diffTargets, IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) where T : class, IDiffResult { var comparer = HandleRetrieverDispatcher[diffTargets](repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) ? DiffModifiers.IncludeUntracked : DiffModifiers.None; if (explicitPathsOptions != null) { diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffModifiers.IncludeUnmodified; } } using (DiffSafeHandle diff = BuildDiffList(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions)) { return(BuildDiffResult <T>(diff)); } }
/// <summary> /// Promotes to the staging area the latest modifications of a collection of files in the working directory (addition, updation or removal). /// </summary> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public virtual void Stage(IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions = null) { Ensure.ArgumentNotNull(paths, "paths"); var changes = repo.Diff.Compare <TreeChanges>(DiffModifiers.IncludeUntracked | DiffModifiers.IncludeIgnored, paths, explicitPathsOptions); foreach (var treeEntryChanges in changes) { switch (treeEntryChanges.Status) { case ChangeKind.Unmodified: continue; case ChangeKind.Deleted: RemoveFromIndex(treeEntryChanges.Path); continue; case ChangeKind.Added: /* Fall through */ case ChangeKind.Modified: AddToIndex(treeEntryChanges.Path); continue; default: throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Entry '{0}' bears an unexpected ChangeKind '{1}'", treeEntryChanges.Path, treeEntryChanges.Status)); } } UpdatePhysicalIndex(); }
/// <summary> /// Removes a file from the staging area, and optionally removes it from the working directory as well. /// <para> /// If the file has already been deleted from the working directory, this method will only deal /// with promoting the removal to the staging area. /// </para> /// <para> /// The default behavior is to remove the file from the working directory as well. /// </para> /// <para> /// When not passing a <paramref name="explicitPathsOptions"/>, the passed path will be treated as /// a pathspec. You can for example use it to pass the relative path to a folder inside the working directory, /// so that all files beneath this folders, and the folder itself, will be removed. /// </para> /// </summary> /// <param name="repository">The repository in which to operate</param> /// <param name="path">The path of the file within the working directory.</param> /// <param name="removeFromWorkingDirectory">True to remove the file from the working directory, False otherwise.</param> /// <param name="explicitPathsOptions"> /// The passed <paramref name="path"/> will be treated as an explicit path. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public static void Remove(IRepository repository, string path, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) { Ensure.ArgumentNotNull(repository, "repository"); Ensure.ArgumentNotNull(path, "path"); Remove(repository, new[] { path }, removeFromWorkingDirectory, explicitPathsOptions); }
internal virtual T Compare <T>( DiffModifiers diffOptions, IEnumerable <string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class, IDiffResult { var comparer = WorkdirToIndex(repo); if (explicitPathsOptions != null) { diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffModifiers.IncludeUnmodified; } } DiffHandle diff = BuildDiffList(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); try { return(BuildDiffResult <T>(diff)); } catch { diff.SafeDispose(); throw; } }
internal virtual T Compare <T>(DiffModifiers diffOptions, IEnumerable <string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class { Func <DiffSafeHandle, object> builder; if (!ChangesBuilders.TryGetValue(typeof(T), out builder)) { throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, "Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof(T), typeof(TreeChanges), typeof(Patch))); } var comparer = WorkdirToIndex(repo); if (explicitPathsOptions != null) { diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffModifiers.IncludeUnmodified; } } using (DiffSafeHandle diff = BuildDiffList(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions)) { return((T)builder(diff)); } }
/// <summary> /// Removes from the staging area all the modifications of a file since the latest commit (addition, updation or removal). /// </summary> /// <param name="repository">The repository in which to act</param> /// <param name="path">The path of the file within the working directory.</param> /// <param name="explicitPathsOptions"> /// The passed <paramref name="path"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public static void Unstage(IRepository repository, string path, ExplicitPathsOptions explicitPathsOptions) { Ensure.ArgumentNotNull(repository, "repository"); Ensure.ArgumentNotNull(path, "path"); Unstage(repository, new[] { path }, explicitPathsOptions); }
/// <summary> /// Show changes between the working directory and the index. /// <para> /// The level of diff performed can be specified by passing either a <see cref="TreeChanges"/> /// or <see cref="Patch"/> type as the generic parameter. /// </para> /// </summary> /// <param name="paths">The list of paths (either files or directories) that should be compared.</param> /// <param name="includeUntracked">If true, include untracked files from the working dir as additions. Otherwise ignore them.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> /// <param name="compareOptions">Additional options to define patch generation behavior.</param> /// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or /// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam> /// <returns>A <typeparamref name="T"/> containing the changes between the working directory and the index.</returns> public virtual T Compare <T>( IEnumerable <string> paths, bool includeUntracked, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) where T : class, IDiffResult { return(Compare <T>(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions, compareOptions)); }
/// <summary> /// Replaces entries in the <see cref="Index"/> with entries from the specified <see cref="Commit"/>. /// </summary> /// <param name="commit">The target <see cref="Commit"/> object.</param> /// <param name="paths">The list of paths (either files or directories) that should be considered.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public virtual void Replace(Commit commit, IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions) { Ensure.ArgumentNotNull(commit, "commit"); var changes = repo.Diff.Compare <TreeChanges>(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }); Replace(changes); }
/// <summary> /// Replaces entries in the <see cref="Repository.Index"/> with entries from the specified commit. /// </summary> /// <param name="commit">The target commit object.</param> /// <param name="paths">The list of paths (either files or directories) that should be considered.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public void Reset(Commit commit, IEnumerable <string> paths = null, ExplicitPathsOptions explicitPathsOptions = null) { if (Info.IsBare) { throw new BareRepositoryException("Reset is not allowed in a bare repository"); } Ensure.ArgumentNotNull(commit, "commit"); TreeChanges changes = Diff.Compare(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions); Index.Reset(changes); }
/// <summary> /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). /// </summary> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public virtual void Unstage(IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions = null) { Ensure.ArgumentNotNull(paths, "paths"); if (repo.Info.IsHeadUnborn) { var changes = repo.Diff.Compare <TreeChanges>(null, DiffTargets.Index, paths, explicitPathsOptions); Reset(changes); } else { repo.Reset("HEAD", paths, explicitPathsOptions); } }
private DiffHandle BuildDiffList( ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, DiffModifiers diffOptions, IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) { var filePaths = repo.ToFilePaths(paths); MatchedPathsAggregator matchedPaths = null; // We can't match paths unless we've got something to match // against and we're told to do so. if (filePaths != null && explicitPathsOptions != null) { if (explicitPathsOptions.OnUnmatchedPath != null || explicitPathsOptions.ShouldFailOnUnmatchedPath) { matchedPaths = new MatchedPathsAggregator(); } } using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions)) { var diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options); if (matchedPaths != null) { try { DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths); } catch { diffList.Dispose(); throw; } } DetectRenames(diffList, compareOptions); return(diffList); } }
/// <summary> /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). /// </summary> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public virtual void Unstage(IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions = null) { Ensure.ArgumentNotNull(paths, "paths"); if (repo.Info.IsHeadOrphaned) { var compareOptions = new CompareOptions { SkipPatchBuilding = true }; TreeChanges changes = repo.Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions, compareOptions); Reset(changes); } else { repo.Reset("HEAD", paths, explicitPathsOptions); } }
private TreeChanges BuildTreeChangesFromComparer( ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, DiffOptions diffOptions, IEnumerable <string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var matchedPaths = new MatchedPathsAggregator(); var filePaths = ToFilePaths(repo, paths); using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions)) using (DiffListSafeHandle diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options)) { if (explicitPathsOptions != null) { DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths); } return(new TreeChanges(diffList)); } }
internal virtual TreeChanges Compare(DiffOptions diffOptions, IEnumerable <string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var comparer = WorkdirToIndex(repo); if (explicitPathsOptions != null) { diffOptions |= DiffOptions.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffOptions.IncludeUnmodified; } } return(BuildTreeChangesFromComparer(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions)); }
/// <summary> /// Show changes between two <see cref="Tree"/>s. /// </summary> /// <param name="oldTree">The <see cref="Tree"/> you want to compare from.</param> /// <param name="newTree">The <see cref="Tree"/> you want to compare to.</param> /// <param name="paths">The list of paths (either files or directories) that should be compared.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> /// <param name="compareOptions">Additional options to define comparison behavior.</param> /// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns> public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var comparer = TreeToTree(repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; ObjectId newTreeId = newTree != null ? newTree.Id : null; var diffOptions = DiffModifiers.None; if (explicitPathsOptions != null) { diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffModifiers.IncludeUnmodified; } } return BuildTreeChangesFromComparer(oldTreeId, newTreeId, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); }
private static void DispatchUnmatchedPaths(ExplicitPathsOptions explicitPathsOptions, IEnumerable <FilePath> filePaths, IEnumerable <FilePath> matchedPaths) { List <FilePath> unmatchedPaths = (filePaths != null ? filePaths.Except(matchedPaths) : Enumerable.Empty <FilePath>()).ToList(); if (!unmatchedPaths.Any()) { return; } if (explicitPathsOptions.OnUnmatchedPath != null) { unmatchedPaths.ForEach(filePath => explicitPathsOptions.OnUnmatchedPath(filePath.Native)); } if (explicitPathsOptions.ShouldFailOnUnmatchedPath) { throw new UnmatchedPathException(BuildUnmatchedPathsMessage(unmatchedPaths)); } }
/// <summary> /// Show changes between a <see cref="Tree"/> and the Index, the Working Directory, or both. /// <para> /// The level of diff performed can be specified by passing either a <see cref="TreeChanges"/> /// or <see cref="Patch"/> type as the generic parameter. /// </para> /// </summary> /// <param name="oldTree">The <see cref="Tree"/> to compare from.</param> /// <param name="diffTargets">The targets to compare to.</param> /// <param name="paths">The list of paths (either files or directories) that should be compared.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> /// <param name="compareOptions">Additional options to define patch generation behavior.</param> /// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or /// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam> /// <returns>A <typeparamref name="T"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns> public virtual T Compare <T>(Tree oldTree, DiffTargets diffTargets, IEnumerable <string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class { Func <DiffSafeHandle, object> builder; if (!ChangesBuilders.TryGetValue(typeof(T), out builder)) { throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, "Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof(T), typeof(TreeChanges), typeof(Patch))); } var comparer = HandleRetrieverDispatcher[diffTargets](repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) ? DiffModifiers.IncludeUntracked : DiffModifiers.None; if (explicitPathsOptions != null) { diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffModifiers.IncludeUnmodified; } } using (DiffSafeHandle diff = BuildDiffList(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions)) { return((T)builder(diff)); } }
/// <summary> /// Removes a collection of fileS from the staging, and optionally removes them from the working directory as well. /// <para> /// If a file has already been deleted from the working directory, this method will only deal /// with promoting the removal to the staging area. /// </para> /// <para> /// The default behavior is to remove the files from the working directory as well. /// </para> /// <para> /// When not passing a <paramref name="explicitPathsOptions"/>, the passed paths will be treated as /// a pathspec. You can for example use it to pass the relative paths to folders inside the working directory, /// so that all files beneath these folders, and the folders themselves, will be removed. /// </para> /// </summary> /// <param name="repository">The repository in which to operate</param> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="removeFromWorkingDirectory">True to remove the files from the working directory, False otherwise.</param> /// <param name="explicitPathsOptions"> /// The passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public static void Remove(IRepository repository, IEnumerable <string> paths, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) { Ensure.ArgumentNotNull(repository, "repository"); Ensure.ArgumentNotNullOrEmptyEnumerable <string>(paths, "paths"); var pathsToDelete = paths.Where(p => Directory.Exists(Path.Combine(repository.Info.WorkingDirectory, p))).ToList(); var notConflictedPaths = new List <string>(); var index = repository.Index; foreach (var path in paths) { Ensure.ArgumentNotNullOrEmptyString(path, "path"); var conflict = index.Conflicts[path]; if (conflict != null) { index.Remove(path); pathsToDelete.Add(path); } else { notConflictedPaths.Add(path); } } // Make sure status will see the changes from before this index.Write(); if (notConflictedPaths.Count > 0) { pathsToDelete.AddRange(RemoveStagedItems(repository, notConflictedPaths, removeFromWorkingDirectory, explicitPathsOptions)); } if (removeFromWorkingDirectory) { RemoveFilesAndFolders(repository, pathsToDelete); } index.Write(); }
private static IEnumerable <string> RemoveStagedItems(IRepository repository, IEnumerable <string> paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { var removed = new List <string>(); using (var changes = repository.Diff.Compare <TreeChanges>(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions)) { var index = repository.Index; foreach (var treeEntryChanges in changes) { var status = repository.RetrieveStatus(treeEntryChanges.Path); switch (treeEntryChanges.Status) { case ChangeKind.Added: case ChangeKind.Deleted: removed.Add(treeEntryChanges.Path); index.Remove(treeEntryChanges.Path); break; case ChangeKind.Unmodified: if (removeFromWorkingDirectory && ( status.HasFlag(FileStatus.ModifiedInIndex) || status.HasFlag(FileStatus.NewInIndex))) { throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", treeEntryChanges.Path); } removed.Add(treeEntryChanges.Path); index.Remove(treeEntryChanges.Path); continue; case ChangeKind.Modified: if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex)) { throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.", treeEntryChanges.Path); } if (removeFromWorkingDirectory) { throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", treeEntryChanges.Path); } removed.Add(treeEntryChanges.Path); index.Remove(treeEntryChanges.Path); continue; default: throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.", treeEntryChanges.Path, treeEntryChanges.Status); } } index.Write(); return(removed); } }
/// <summary> /// Removes a collection of fileS from the staging, and optionally removes them from the working directory as well. /// <para> /// If a file has already been deleted from the working directory, this method will only deal /// with promoting the removal to the staging area. /// </para> /// <para> /// The default behavior is to remove the files from the working directory as well. /// </para> /// <para> /// When not passing a <paramref name="explicitPathsOptions"/>, the passed paths will be treated as /// a pathspec. You can for example use it to pass the relative paths to folders inside the working directory, /// so that all files beneath these folders, and the folders themselves, will be removed. /// </para> /// </summary> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="removeFromWorkingDirectory">True to remove the files from the working directory, False otherwise.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public virtual void Remove(IEnumerable <string> paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { var pathsList = paths.ToList(); var changes = repo.Diff.Compare <TreeChanges>(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, pathsList, explicitPathsOptions); var pathsTodelete = pathsList.Where(p => Directory.Exists(Path.Combine(repo.Info.WorkingDirectory, p))).ToList(); foreach (var treeEntryChanges in changes) { var status = repo.Index.RetrieveStatus(treeEntryChanges.Path); switch (treeEntryChanges.Status) { case ChangeKind.Added: case ChangeKind.Deleted: pathsTodelete.Add(RemoveFromIndex(treeEntryChanges.Path)); break; case ChangeKind.Unmodified: if (removeFromWorkingDirectory && ( status.HasFlag(FileStatus.Staged) || status.HasFlag(FileStatus.Added))) { throw new RemoveFromIndexException(string.Format(CultureInfo.InvariantCulture, "Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", treeEntryChanges.Path)); } pathsTodelete.Add(RemoveFromIndex(treeEntryChanges.Path)); continue; case ChangeKind.Modified: if (status.HasFlag(FileStatus.Modified) && status.HasFlag(FileStatus.Staged)) { throw new RemoveFromIndexException(string.Format(CultureInfo.InvariantCulture, "Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.", treeEntryChanges.Path)); } if (removeFromWorkingDirectory) { throw new RemoveFromIndexException(string.Format(CultureInfo.InvariantCulture, "Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", treeEntryChanges.Path)); } pathsTodelete.Add(RemoveFromIndex(treeEntryChanges.Path)); continue; default: throw new RemoveFromIndexException(string.Format(CultureInfo.InvariantCulture, "Unable to remove file '{0}'. Its current status is '{1}'.", treeEntryChanges.Path, treeEntryChanges.Status)); } } if (removeFromWorkingDirectory) { RemoveFilesAndFolders(pathsTodelete); } UpdatePhysicalIndex(); }
/// <summary> /// Show changes between the working directory and the index. /// </summary> /// <param name="paths">The list of paths (either files or directories) that should be compared.</param> /// <param name="includeUntracked">If true, include untracked files from the working dir as additions. Otherwise ignore them.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> /// <param name="compareOptions">Additional options to define comparison behavior.</param> /// <returns>A <see cref="TreeChanges"/> containing the changes between the working directory and the index.</returns> public virtual TreeChanges Compare(IEnumerable<string> paths = null, bool includeUntracked = false, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { return Compare(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions, compareOptions); }
internal virtual TreeChanges Compare(DiffModifiers diffOptions, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var comparer = WorkdirToIndex(repo); if (explicitPathsOptions != null) { diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffModifiers.IncludeUnmodified; } } return BuildTreeChangesFromComparer(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); }
/// <summary> /// Removes a file from the staging area, and optionally removes it from the working directory as well. /// <para> /// If the file has already been deleted from the working directory, this method will only deal /// with promoting the removal to the staging area. /// </para> /// <para> /// The default behavior is to remove the file from the working directory as well. /// </para> /// <para> /// When not passing a <paramref name="explicitPathsOptions"/>, the passed path will be treated as /// a pathspec. You can for example use it to pass the relative path to a folder inside the working directory, /// so that all files beneath this folders, and the folder itself, will be removed. /// </para> /// </summary> /// <param name="path">The path of the file within the working directory.</param> /// <param name="removeFromWorkingDirectory">True to remove the file from the working directory, False otherwise.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="path"/> will be treated as an explicit path. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public virtual void Remove(string path, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { Ensure.ArgumentNotNull(path, "path"); Remove(new[] { path }, removeFromWorkingDirectory, explicitPathsOptions); }
public void Unstage(IEnumerable<string> paths, ExplicitPathsOptions explicitPathsOptions) { throw new NotImplementedException(); }
/// <summary> /// Removes a collection of fileS from the staging, and optionally removes them from the working directory as well. /// <para> /// If a file has already been deleted from the working directory, this method will only deal /// with promoting the removal to the staging area. /// </para> /// <para> /// The default behavior is to remove the files from the working directory as well. /// </para> /// <para> /// When not passing a <paramref name="explicitPathsOptions"/>, the passed paths will be treated as /// a pathspec. You can for example use it to pass the relative paths to folders inside the working directory, /// so that all files beneath these folders, and the folders themselves, will be removed. /// </para> /// </summary> /// <param name="repository">The repository in which to operate</param> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="removeFromWorkingDirectory">True to remove the files from the working directory, False otherwise.</param> /// <param name="explicitPathsOptions"> /// The passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public static void Remove(IRepository repository, IEnumerable<string> paths, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) { Ensure.ArgumentNotNull(repository, "repository"); Ensure.ArgumentNotNullOrEmptyEnumerable<string>(paths, "paths"); var pathsToDelete = paths.Where(p => Directory.Exists(Path.Combine(repository.Info.WorkingDirectory, p))).ToList(); var notConflictedPaths = new List<string>(); var index = repository.Index; foreach (var path in paths) { Ensure.ArgumentNotNullOrEmptyString(path, "path"); var conflict = index.Conflicts[path]; if (conflict != null) { index.Remove(path); pathsToDelete.Add(path); } else { notConflictedPaths.Add(path); } } // Make sure status will see the changes from before this index.Write(); if (notConflictedPaths.Count > 0) { pathsToDelete.AddRange(RemoveStagedItems(repository, notConflictedPaths, removeFromWorkingDirectory, explicitPathsOptions)); } if (removeFromWorkingDirectory) { RemoveFilesAndFolders(repository, pathsToDelete); } index.Write(); }
/// <summary> /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). /// </summary> /// <param name="repository">The repository in which to act</param> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="explicitPathsOptions"> /// The passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public static void Unstage(IRepository repository, IEnumerable<string> paths, ExplicitPathsOptions explicitPathsOptions) { Ensure.ArgumentNotNull(repository, "repository"); Ensure.ArgumentNotNull(paths, "paths"); if (repository.Info.IsHeadUnborn) { using (var changes = repository.Diff.Compare<TreeChanges>(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None })) repository.Index.Replace(changes); } else { repository.Index.Replace(repository.Head.Tip, paths, explicitPathsOptions); } }
/// <summary> /// Show changes between the working directory and the index. /// <para> /// The level of diff performed can be specified by passing either a <see cref="TreeChanges"/> /// or <see cref="Patch"/> type as the generic parameter. /// </para> /// </summary> /// <param name="paths">The list of paths (either files or directories) that should be compared.</param> /// <param name="includeUntracked">If true, include untracked files from the working dir as additions. Otherwise ignore them.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> /// <param name="compareOptions">Additional options to define patch generation behavior.</param> /// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or /// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam> /// <returns>A <typeparamref name="T"/> containing the changes between the working directory and the index.</returns> public virtual T Compare <T>(IEnumerable <string> paths = null, bool includeUntracked = false, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class { return(Compare <T>(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions, compareOptions)); }
/// <summary> /// Permite hacer un guardado /// </summary> /// <param name="name"></param> /// <param name="email"></param> /// <param name="message"></param> public void git_commit(string name, string email, string message) { //feed.Logs.WriteText("Commit", "Se hace commit normal de " + this.NombreProyecto); //repo.Index.Remove(estado.FilePath,false); Commit newC = null; RepositoryStatus status = getStatus(); if (status != null) { ExplicitPathsOptions explicitOptions = new ExplicitPathsOptions(); if (status.Modified.Count() > 0) { foreach (var archivo in status.Modified) { if (extensionesPermitidas(archivo.FilePath, null)) { Repo.Index.Stage(archivo.FilePath); } } } } CommitOptions options = new CommitOptions(); Signature signature = new Signature(name, email, DateTimeOffset.Now); try { options.AmendPreviousCommit = false; newC = Repo.Commit(message, signature, signature, options); // /*Deprecated*/ newC = Repo.Commit(message, signature, signature, false); // newC.Parents } catch (Exception ex) { options.AmendPreviousCommit = true; newC = Repo.Commit(message, signature, signature, options); //newC = Repo.Commit(message, signature, signature, true); } }
/// <summary> /// Removes from the staging area all the modifications of a collection of file since the latest commit (addition, updation or removal). /// </summary> /// <param name="repository">The repository in which to act</param> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="explicitPathsOptions"> /// The passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public static void Unstage(IRepository repository, IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions) { Ensure.ArgumentNotNull(repository, "repository"); Ensure.ArgumentNotNull(paths, "paths"); if (repository.Info.IsHeadUnborn) { using (var changes = repository.Diff.Compare <TreeChanges>(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None })) repository.Index.Replace(changes); } else { repository.Index.Replace(repository.Head.Tip, paths, explicitPathsOptions); } }
private TreeChanges BuildTreeChangesFromComparer( ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, DiffModifiers diffOptions, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var matchedPaths = new MatchedPathsAggregator(); var filePaths = repo.ToFilePaths(paths); using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions)) using (DiffListSafeHandle diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options)) { if (explicitPathsOptions != null) { DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths); } return new TreeChanges(diffList); } }
public void Unstage(string path, ExplicitPathsOptions explicitPathsOptions) { throw new NotImplementedException(); }
/// <summary> /// Replaces entries in the <see cref="Index"/> with entries from the specified commit. /// </summary> /// <param name="repository">The <see cref="Repository"/> being worked with.</param> /// <param name="committish">A revparse spec for the target commit object.</param> /// <param name="paths">The list of paths (either files or directories) that should be considered.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public static void Reset(this IRepository repository, string committish = "HEAD", IEnumerable <string> paths = null, ExplicitPathsOptions explicitPathsOptions = null) { if (repository.Info.IsBare) { throw new BareRepositoryException("Reset is not allowed in a bare repository"); } Ensure.ArgumentNotNullOrEmptyString(committish, "committish"); Commit commit = LookUpCommit(repository, committish); repository.Reset(commit, paths, explicitPathsOptions); }
public void Remove(IEnumerable<string> paths, bool removeFromWorkingDirectory, ExplicitPathsOptions explicitPathsOptions) { throw new NotImplementedException(); }
/// <summary> /// Show changes between a <see cref="Tree"/> and the Index, the Working Directory, or both. /// </summary> /// <param name="oldTree">The <see cref="Tree"/> to compare from.</param> /// <param name="diffTargets">The targets to compare to.</param> /// <param name="paths">The list of paths (either files or directories) that should be compared.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="paths"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> /// <param name="compareOptions">Additional options to define comparison behavior.</param> /// <returns>A <see cref="TreeChanges"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns> public virtual TreeChanges Compare(Tree oldTree, DiffTargets diffTargets, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) { var comparer = handleRetrieverDispatcher[diffTargets](repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) ? DiffModifiers.IncludeUntracked : DiffModifiers.None; if (explicitPathsOptions != null) { diffOptions |= DiffModifiers.DisablePathspecMatch; if (explicitPathsOptions.ShouldFailOnUnmatchedPath || explicitPathsOptions.OnUnmatchedPath != null) { diffOptions |= DiffModifiers.IncludeUnmodified; } } return BuildTreeChangesFromComparer(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); }
private static void DispatchUnmatchedPaths(ExplicitPathsOptions explicitPathsOptions, IEnumerable<FilePath> filePaths, IEnumerable<FilePath> matchedPaths) { List<FilePath> unmatchedPaths = (filePaths != null ? filePaths.Except(matchedPaths) : Enumerable.Empty<FilePath>()).ToList(); if (!unmatchedPaths.Any()) { return; } if (explicitPathsOptions.OnUnmatchedPath != null) { unmatchedPaths.ForEach(filePath => explicitPathsOptions.OnUnmatchedPath(filePath.Native)); } if (explicitPathsOptions.ShouldFailOnUnmatchedPath) { throw new UnmatchedPathException(BuildUnmatchedPathsMessage(unmatchedPaths)); } }
public void Reset(Commit commit, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null) { throw new NotImplementedException(); }
/// <summary> /// Removes from the staging area all the modifications of a file since the latest commit (addition, updation or removal). /// </summary> /// <param name="path">The path of the file within the working directory.</param> /// <param name="explicitPathsOptions"> /// If set, the passed <paramref name="path"/> will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// </param> public virtual void Unstage(string path, ExplicitPathsOptions explicitPathsOptions = null) { Ensure.ArgumentNotNull(path, "path"); Unstage(new[] { path }, explicitPathsOptions); }
private static IEnumerable<string> RemoveStagedItems(IRepository repository, IEnumerable<string> paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { var removed = new List<string>(); using (var changes = repository.Diff.Compare<TreeChanges>(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions)) { var index = repository.Index; foreach (var treeEntryChanges in changes) { var status = repository.RetrieveStatus(treeEntryChanges.Path); switch (treeEntryChanges.Status) { case ChangeKind.Added: case ChangeKind.Deleted: removed.Add(treeEntryChanges.Path); index.Remove(treeEntryChanges.Path); break; case ChangeKind.Unmodified: if (removeFromWorkingDirectory && ( status.HasFlag(FileStatus.ModifiedInIndex) || status.HasFlag(FileStatus.NewInIndex))) { throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", treeEntryChanges.Path); } removed.Add(treeEntryChanges.Path); index.Remove(treeEntryChanges.Path); continue; case ChangeKind.Modified: if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex)) { throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.", treeEntryChanges.Path); } if (removeFromWorkingDirectory) { throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", treeEntryChanges.Path); } removed.Add(treeEntryChanges.Path); index.Remove(treeEntryChanges.Path); continue; default: throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.", treeEntryChanges.Path, treeEntryChanges.Status); } } index.Write(); return removed; } }
public virtual void Unstage(string path, ExplicitPathsOptions explicitPathsOptions = null) { repo.Unstage(path, explicitPathsOptions); }
public virtual void Unstage(IEnumerable <string> paths, ExplicitPathsOptions explicitPathsOptions = null) { repo.Unstage(paths, explicitPathsOptions); }
public virtual void Remove(string path, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { repo.Remove(new[] { path }, removeFromWorkingDirectory, explicitPathsOptions); }
/// <summary> /// Promotes to the staging area the latest modifications of a collection of files in the working directory (addition, updation or removal). /// /// Any paths (even those listed explicitly) that are ignored by configuration will not be staged unless <see cref="StageOptions.IncludeIgnored"/> is unset. /// </summary> /// <param name="repository">The repository in which to act</param> /// <param name="paths">The collection of paths of the files within the working directory.</param> /// <param name="stageOptions">Determines how paths will be staged.</param> public static void Stage(IRepository repository, IEnumerable <string> paths, StageOptions stageOptions) { Ensure.ArgumentNotNull(repository, "repository"); Ensure.ArgumentNotNull(paths, "paths"); DiffModifiers diffModifiers = DiffModifiers.IncludeUntracked; ExplicitPathsOptions explicitPathsOptions = stageOptions != null ? stageOptions.ExplicitPathsOptions : null; if (stageOptions != null && stageOptions.IncludeIgnored) { diffModifiers |= DiffModifiers.IncludeIgnored; } using (var changes = repository.Diff.Compare <TreeChanges>(diffModifiers, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None })) { var unexpectedTypesOfChanges = changes .Where( tec => tec.Status != ChangeKind.Added && tec.Status != ChangeKind.Modified && tec.Status != ChangeKind.Conflicted && tec.Status != ChangeKind.Unmodified && tec.Status != ChangeKind.Deleted).ToList(); if (unexpectedTypesOfChanges.Count > 0) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Entry '{0}' bears an unexpected ChangeKind '{1}'", unexpectedTypesOfChanges[0].Path, unexpectedTypesOfChanges[0].Status)); } /* Remove files from the index that don't exist on disk */ foreach (TreeEntryChanges treeEntryChanges in changes) { switch (treeEntryChanges.Status) { case ChangeKind.Conflicted: if (!treeEntryChanges.Exists) { repository.Index.Remove(treeEntryChanges.Path); } break; case ChangeKind.Deleted: repository.Index.Remove(treeEntryChanges.Path); break; default: continue; } } foreach (TreeEntryChanges treeEntryChanges in changes) { switch (treeEntryChanges.Status) { case ChangeKind.Added: case ChangeKind.Modified: repository.Index.Add(treeEntryChanges.Path); break; case ChangeKind.Conflicted: if (treeEntryChanges.Exists) { repository.Index.Add(treeEntryChanges.Path); } break; default: continue; } } repository.Index.Write(); } }
public virtual void Remove(IEnumerable <string> paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { repo.Remove(paths, removeFromWorkingDirectory, explicitPathsOptions); }
/// <summary> /// Meter en el indice un archivo /// </summary> /// <param name="filePath"></param> public void git_trackFile(string filePath) { try { try { ExplicitPathsOptions op = new ExplicitPathsOptions(); FileStatus sta = Repo.Index.RetrieveStatus(filePath); if (sta == FileStatus.Nonexistent) { Repo.Index.Unstage(filePath); } core.logs.Logs.WriteText("Control Git", "estado: " + sta.ToString() + " archivo: " + filePath); } catch(Exception ex) { core.logs.Logs.WriteError("Error track file", ex); } Repo.Index.Stage(filePath); } catch (Exception ex){ var l = filePath; } }