diff options
author | nulltoken <emeric.fermas@gmail.com> | 2011-09-20 18:01:24 +0400 |
---|---|---|
committer | Emeric Fermas <emeric.fermas@gmail.com> | 2011-09-29 02:01:59 +0400 |
commit | 02dbc31a91fa7dccebf7cda33f24dc768fefbb17 (patch) | |
tree | 9e5bbbf70fef8763e2fa4cc363a3fd16a30d6706 /LibGit2Sharp/RepositoryStatus.cs | |
parent | f25065331a0fafe4ccaefdff109536252169e385 (diff) |
Add determination of repository status
- Doesn't handle line endings conversion
- Doesn't honor .gitignore
- Test repositories have been moved under LibGit2Sharp.Tests
- .gitattributes file has been added to prevent unexpected line endings conversion of the test repositories files
Should fix issue #49.
Diffstat (limited to 'LibGit2Sharp/RepositoryStatus.cs')
-rw-r--r-- | LibGit2Sharp/RepositoryStatus.cs | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/LibGit2Sharp/RepositoryStatus.cs b/LibGit2Sharp/RepositoryStatus.cs new file mode 100644 index 00000000..ba3ae792 --- /dev/null +++ b/LibGit2Sharp/RepositoryStatus.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using LibGit2Sharp.Core; + +namespace LibGit2Sharp +{ + /// <summary> + /// Holds the result of the determination of the state of the working directory. + /// <para>Only files that differ from the current index and/or commit will be considered.</para> + /// </summary> + public class RepositoryStatus : IEnumerable<StatusEntry> + { + private readonly List<StatusEntry> statusEntries = new List<StatusEntry>(); + private readonly List<string> added = new List<string>(); + private readonly List<string> staged = new List<string>(); + private readonly List<string> removed = new List<string>(); + private readonly List<string> missing = new List<string>(); + private readonly List<string> modified = new List<string>(); + private readonly List<string> untracked = new List<string>(); + private readonly bool isDirty; + + private readonly NativeMethods.status_callback callback; + + private readonly IDictionary<FileStatus, Action<RepositoryStatus, string>> dispatcher = Build(); + + private static IDictionary<FileStatus, Action<RepositoryStatus, string>> Build() + { + return new Dictionary<FileStatus, Action<RepositoryStatus, string>> + { + { FileStatus.Untracked, (rs, s) => rs.untracked.Add(s) }, + { FileStatus.Modified, (rs, s) => rs.modified.Add(s) }, + { FileStatus.Missing, (rs, s) => rs.missing.Add(s) }, + { FileStatus.Added, (rs, s) => rs.added.Add(s) }, + { FileStatus.Staged, (rs, s) => rs.staged.Add(s) }, + { FileStatus.Removed, (rs, s) => rs.removed.Add(s) }, + }; + } + + internal RepositoryStatus(RepositorySafeHandle handle) + { + callback = new NativeMethods.status_callback(StateChanged); + Process(handle); + isDirty = statusEntries.Count != 0; + } + + private void Process(RepositorySafeHandle handle) + { + int res = NativeMethods.git_status_foreach(handle, callback, IntPtr.Zero); + Ensure.Success(res); + } + + private int StateChanged(string filePath, uint state, IntPtr payload) + { + var gitStatus = (FileStatus)state; + statusEntries.Add(new StatusEntry(filePath, gitStatus)); + + foreach (KeyValuePair<FileStatus, Action<RepositoryStatus, string>> kvp in dispatcher) + { + if ((gitStatus & kvp.Key) != kvp.Key) + { + continue; + } + + kvp.Value(this, filePath); + } + + return 0; + } + + /// <summary> + /// Returns an enumerator that iterates through the collection. + /// </summary> + /// <returns>An <see cref = "IEnumerator{T}" /> object that can be used to iterate through the collection.</returns> + public IEnumerator<StatusEntry> GetEnumerator() + { + return statusEntries.GetEnumerator(); + } + + /// <summary> + /// Returns an enumerator that iterates through the collection. + /// </summary> + /// <returns>An <see cref = "IEnumerator" /> object that can be used to iterate through the collection.</returns> + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// <summary> + /// List of files added to the index, which are not in the current commit + /// </summary> + public IEnumerable<string> Added + { + get { return added; } + } + + /// <summary> + /// List of files added to the index, which are already in the current commit with different content + /// </summary> + public IEnumerable<string> Staged + { + get { return staged; } + } + + /// <summary> + /// List of files removed from the index but are existent in the current commit + /// </summary> + public IEnumerable<string> Removed + { + get { return removed; } + } + + /// <summary> + /// List of files existent in the index but are missing in the working directory + /// </summary> + public IEnumerable<string> Missing + { + get { return missing; } + } + + /// <summary> + /// List of files with unstaged modifications. A file may be modified and staged at the same time if it has been modified after adding. + /// </summary> + public IEnumerable<string> Modified + { + get { return modified; } + } + + /// <summary> + /// List of files existing in the working directory but are neither tracked in the index nor in the current commit. + /// </summary> + public IEnumerable<string> Untracked + { + get { return untracked; } + } + + /// <summary> + /// True if the index or the working directory has been altered since the last commit. False otherwise. + /// </summary> + public bool IsDirty + { + get { return isDirty; } + } + } +} |