diff --git a/LibGit2Sharp.Tests/IndexFixture.cs b/LibGit2Sharp.Tests/IndexFixture.cs index 0b926318d..8dcdc4037 100644 --- a/LibGit2Sharp.Tests/IndexFixture.cs +++ b/LibGit2Sharp.Tests/IndexFixture.cs @@ -466,6 +466,20 @@ public void CanMimicGitAddAll() } } + [Fact] + public void RetrievingAssumedUnchangedMarkedIndexEntries() + { + var path = SandboxAssumeUnchangedTestRepo(); + using (var repo = new Repository(path)) + { + var regularFile = repo.Index["hello.txt"]; + Assert.False(regularFile.AssumeUnchanged); + + var assumeUnchangedFile = repo.Index["world.txt"]; + Assert.True(assumeUnchangedFile.AssumeUnchanged); + } + } + private static void AddSomeCornerCases(Repository repo) { // Turn 1.txt into a directory in the Index diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/COMMIT_EDITMSG b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/COMMIT_EDITMSG new file mode 100644 index 000000000..5852f4463 --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/COMMIT_EDITMSG @@ -0,0 +1 @@ +Initial commit diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/HEAD b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/HEAD new file mode 100644 index 000000000..cb089cd89 --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/config b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/config new file mode 100644 index 000000000..78387c50b --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/config @@ -0,0 +1,8 @@ +[core] + repositoryformatversion = 0 + filemode = false + bare = false + logallrefupdates = true + symlinks = false + ignorecase = true + hideDotFiles = dotGitOnly diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/index b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/index new file mode 100644 index 000000000..1af67f2d4 Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/index differ diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/info/exclude b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/info/exclude new file mode 100644 index 000000000..a5196d1be --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/logs/HEAD b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/logs/HEAD new file mode 100644 index 000000000..8a423a7ae --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 872129051d644790636b416d1ef1ec830c5f6b90 nulltoken 1422023333 +0100 commit (initial): Initial commit diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/logs/refs/heads/master b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/logs/refs/heads/master new file mode 100644 index 000000000..8a423a7ae --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 872129051d644790636b416d1ef1ec830c5f6b90 nulltoken 1422023333 +0100 commit (initial): Initial commit diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/87/2129051d644790636b416d1ef1ec830c5f6b90 b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/87/2129051d644790636b416d1ef1ec830c5f6b90 new file mode 100644 index 000000000..3c800a797 --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/87/2129051d644790636b416d1ef1ec830c5f6b90 @@ -0,0 +1,3 @@ +x��I +B1]��>��'��[����� ��o���U/�Z�n�i"���5�S�Q�hC��.��n��=? \ No newline at end of file diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/88/e38705fdbd3608cddbe904b67c731f3234c45b b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/88/e38705fdbd3608cddbe904b67c731f3234c45b new file mode 100644 index 000000000..783449ff9 Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/88/e38705fdbd3608cddbe904b67c731f3234c45b differ diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/cc/628ccd10742baea8241c5924df992b5c019f71 b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/cc/628ccd10742baea8241c5924df992b5c019f71 new file mode 100644 index 000000000..6b011038d Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/cc/628ccd10742baea8241c5924df992b5c019f71 differ diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/ce/013625030ba8dba906f756967f9e9ca394464a b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/ce/013625030ba8dba906f756967f9e9ca394464a new file mode 100644 index 000000000..6802d4949 Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/objects/ce/013625030ba8dba906f756967f9e9ca394464a differ diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/refs/heads/master b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/refs/heads/master new file mode 100644 index 000000000..2ed6cd9fa --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/dot_git/refs/heads/master @@ -0,0 +1 @@ +872129051d644790636b416d1ef1ec830c5f6b90 diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/hello.txt b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/hello.txt new file mode 100644 index 000000000..e965047ad --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/hello.txt @@ -0,0 +1 @@ +Hello diff --git a/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/world.txt b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/world.txt new file mode 100644 index 000000000..216e97ce0 --- /dev/null +++ b/LibGit2Sharp.Tests/Resources/assume_unchanged_wd/world.txt @@ -0,0 +1 @@ +World diff --git a/LibGit2Sharp.Tests/StatusFixture.cs b/LibGit2Sharp.Tests/StatusFixture.cs index 3e262e349..e8f9d7314 100644 --- a/LibGit2Sharp.Tests/StatusFixture.cs +++ b/LibGit2Sharp.Tests/StatusFixture.cs @@ -581,5 +581,16 @@ public void CanRetrieveTheStatusOfAGlobSpec() Assert.Equal(2, status.Untracked.Count()); } } + + [Fact] + public void RetrievingTheStatusHonorsAssumedUnchangedMarkedIndexEntries() + { + var path = SandboxAssumeUnchangedTestRepo(); + using (var repo = new Repository(path)) + { + var status = repo.RetrieveStatus(); + Assert.Equal("hello.txt", status.Modified.Single().FilePath); + } + } } } diff --git a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs index 5482d2ae1..ed60c2172 100644 --- a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs +++ b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs @@ -39,6 +39,7 @@ static BaseFixture() public static string RevertTestRepoWorkingDirPath { get; private set; } public static string SubmoduleTestRepoWorkingDirPath { get; private set; } private static string SubmoduleTargetTestRepoWorkingDirPath { get; set; } + private static string AssumeUnchangedRepoWorkingDirPath { get; set; } public static DirectoryInfo ResourcesDirectory { get; private set; } public static bool IsFileSystemCaseSensitive { get; private set; } @@ -67,6 +68,7 @@ private static void SetUpTestEnvironment() RevertTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "revert_testrepo_wd"); SubmoduleTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "submodule_wd"); SubmoduleTargetTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "submodule_target_wd"); + AssumeUnchangedRepoWorkingDirPath = Path.Combine(sourceRelativePath, "assume_unchanged_wd"); } private static bool IsFileSystemCaseSensitiveInternal() @@ -147,6 +149,11 @@ public string SandboxSubmoduleTestRepo() return Sandbox(SubmoduleTestRepoWorkingDirPath, SubmoduleTargetTestRepoWorkingDirPath); } + public string SandboxAssumeUnchangedTestRepo() + { + return Sandbox(AssumeUnchangedRepoWorkingDirPath); + } + protected string Sandbox(string sourceDirectoryPath, params string[] additionalSourcePaths) { var scd = BuildSelfCleaningDirectory(); diff --git a/LibGit2Sharp/Core/GitIndexEntry.cs b/LibGit2Sharp/Core/GitIndexEntry.cs index 51689fa17..05904c84d 100644 --- a/LibGit2Sharp/Core/GitIndexEntry.cs +++ b/LibGit2Sharp/Core/GitIndexEntry.cs @@ -6,6 +6,8 @@ namespace LibGit2Sharp.Core [StructLayout(LayoutKind.Sequential)] internal class GitIndexEntry { + internal const ushort GIT_IDXENTRY_VALID = 0x8000; + public GitIndexTime CTime; public GitIndexTime MTime; public uint Dev; diff --git a/LibGit2Sharp/IndexEntry.cs b/LibGit2Sharp/IndexEntry.cs index d6e97eb03..7dc6b0150 100644 --- a/LibGit2Sharp/IndexEntry.cs +++ b/LibGit2Sharp/IndexEntry.cs @@ -30,6 +30,11 @@ public class IndexEntry : IEquatable /// public virtual StageLevel StageLevel { get; private set; } + /// + /// Whether the file is marked as assume-unchanged + /// + public virtual bool AssumeUnchanged { get; private set; } + /// /// Gets the id of the pointed at by this index entry. /// @@ -51,7 +56,8 @@ internal static IndexEntry BuildFromPtr(IndexEntrySafeHandle handle) Path = path.Native, Id = entry.Id, StageLevel = Proxy.git_index_entry_stage(handle), - Mode = (Mode)entry.Mode + Mode = (Mode)entry.Mode, + AssumeUnchanged = (GitIndexEntry.GIT_IDXENTRY_VALID & entry.Flags) == GitIndexEntry.GIT_IDXENTRY_VALID }; }