Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions GVFS/GVFS.Common/Prefetch/Git/GitIndexGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ public GitIndexGenerator(ITracer tracer, Enlistment enlistment, bool shouldHashI

public bool HasFailures { get; private set; }

public void CreateFromHeadTree(uint indexVersion, HashSet<string> sparseCheckoutEntries = null)
public void CreateFromHeadTree(uint indexVersion)
{
using (ITracer updateIndexActivity = this.tracer.StartActivity("CreateFromHeadTree", EventLevel.Informational))
{
Thread entryWritingThread = new Thread(() => this.WriteAllEntries(indexVersion, sparseCheckoutEntries));
Thread entryWritingThread = new Thread(() => this.WriteAllEntries(indexVersion));
entryWritingThread.Start();

GitProcess git = new GitProcess(this.enlistment);
Expand Down Expand Up @@ -94,7 +94,7 @@ private void EnqueueEntriesFromLsTree(string line)
}
}

private void WriteAllEntries(uint version, HashSet<string> sparseCheckoutEntries)
private void WriteAllEntries(uint version)
{
try
{
Expand All @@ -109,11 +109,7 @@ private void WriteAllEntries(uint version, HashSet<string> sparseCheckoutEntries
LsTreeEntry entry;
while (this.entryQueue.TryTake(out entry, Timeout.Infinite))
{
bool skipWorkTree =
sparseCheckoutEntries != null &&
!sparseCheckoutEntries.Contains(entry.Filename) &&
!sparseCheckoutEntries.Contains(this.GetDirectoryNameForGitPath(entry.Filename));
this.WriteEntry(writer, version, entry.Sha, entry.Filename, skipWorkTree, ref lastStringLength);
this.WriteEntry(writer, version, entry.Sha, entry.Filename, ref lastStringLength);
}

// Update entry count
Expand Down Expand Up @@ -143,7 +139,7 @@ private string GetDirectoryNameForGitPath(string filename)
return filename.Substring(0, idx + 1);
}

private void WriteEntry(BinaryWriter writer, uint version, string sha, string filename, bool skipWorktree, ref uint lastStringLength)
private void WriteEntry(BinaryWriter writer, uint version, string sha, string filename, ref uint lastStringLength)
{
long startPosition = writer.BaseStream.Position;

Expand All @@ -156,14 +152,8 @@ private void WriteEntry(BinaryWriter writer, uint version, string sha, string fi
byte[] filenameBytes = Encoding.UTF8.GetBytes(filename);

ushort flags = (ushort)(filenameBytes.Length & 0xFFF);
flags |= version >= 3 && skipWorktree ? ExtendedBit : (ushort)0;
writer.Write(EndianHelper.Swap(flags));

if (version >= 3 && skipWorktree)
{
writer.Write(EndianHelper.Swap(SkipWorktreeBit));
}

if (version >= 4)
{
this.WriteReplaceLength(writer, lastStringLength);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ public class DiskLayoutUpgradeTests : TestsWithEnlistmentPerTestCase

private FileSystemRunner fileSystem = new SystemIORunner();

[SetUp]
public override void CreateEnlistment()
{
base.CreateEnlistment();

// Since there isn't a sparse-checkout file that is used anymore one needs to be added
// in order to test the old upgrades that might have needed it
string sparseCheckoutPath = Path.Combine(this.Enlistment.RepoRoot, TestConstants.DotGit.Info.SparseCheckoutPath);
this.fileSystem.WriteAllText(sparseCheckoutPath, "/.gitattributes\r\n");
}

[TestCase]
public void MountUpgradesFromVersion7()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public void MountUpgradesLocalSizesToSharedCache()
versionJsonPath.ShouldBeAFile(this.fileSystem);
this.fileSystem.DeleteFile(versionJsonPath);

// Since there isn't a sparse-checkout file that is used anymore one needs to be added
// in order to test the old upgrades that might have needed it
string sparseCheckoutPath = Path.Combine(enlistment.RepoRoot, TestConstants.DotGit.Info.SparseCheckoutPath);
this.fileSystem.WriteAllText(sparseCheckoutPath, "/.gitattributes\r\n");

// "13.0" was the last version before blob sizes were moved out of Esent
string metadataPath = Path.Combine(enlistment.DotGVFSRoot, GVFSHelpers.RepoMetadataName);
this.fileSystem.CreateEmptyFile(metadataPath);
Expand Down Expand Up @@ -103,6 +108,11 @@ public void MountUpgradesLocalSizesToSharedCache()
versionJsonPath.ShouldBeAFile(this.fileSystem);
this.fileSystem.DeleteFile(versionJsonPath);

// Since there isn't a sparse-checkout file that is used anymore one needs to be added
// in order to test the old upgrades that might have needed it
string sparseCheckoutPath2 = Path.Combine(enlistment2.RepoRoot, TestConstants.DotGit.Info.SparseCheckoutPath);
this.fileSystem.WriteAllText(sparseCheckoutPath2, "/.gitattributes\r\n");

// "13.0" was the last version before blob sizes were moved out of Esent
metadataPath = Path.Combine(enlistment2.DotGVFSRoot, GVFSHelpers.RepoMetadataName);
this.fileSystem.CreateEmptyFile(metadataPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@ public void DehydrateShouldBackupFiles()

// .git folder items
string gitFolder = Path.Combine(backupFolderItems[0], ".git");
this.DirectoryShouldContain(gitFolder, "index", "info");

string gitInfoFolder = Path.Combine(gitFolder, "info");
this.DirectoryShouldContain(gitInfoFolder, "sparse-checkout");
Comment thread
kewillford marked this conversation as resolved.
this.DirectoryShouldContain(gitFolder, "index");

// .gvfs folder items
string gvfsFolder = Path.Combine(backupFolderItems[0], ".gvfs");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public void RenameFolderTest()

[TestCase, Order(6)]
[Category(Categories.MacTODO.M2)]
public void CaseOnlyRenameOfNewFolderKeepsExcludeEntries()
public void CaseOnlyRenameOfNewFolderKeepsModifiedPathsEntries()
{
string[] expectedModifiedPathsEntries =
{
Expand All @@ -162,7 +162,7 @@ public void CaseOnlyRenameOfNewFolderKeepsExcludeEntries()
}

[TestCase, Order(7)]
public void ReadingFileDoesNotUpdateIndexOrSparseCheckout()
public void ReadingFileDoesNotUpdateIndexOrModifiedPaths()
{
string gitFileToCheck = "GVFS/GVFS.FunctionalTests/Category/CategoryConstants.cs";
string virtualFile = this.Enlistment.GetVirtualPathTo(gitFileToCheck);
Expand Down Expand Up @@ -296,13 +296,13 @@ public void DeletedFolderAndChildrenAddedToToModifiedPathsFile()
}

[TestCase, Order(13)]
public void FileRenamedOutOfRepoAddedToModifiedPathsFile()
public void FileRenamedOutOfRepoAddedToModifiedPathsAndSkipWorktreeBitCleared()
{
string fileToRenameEntry = "GVFlt_MoveFileTest/PartialToOutside/from/lessInFrom.txt";
string fileToRenameVirtualPath = this.Enlistment.GetVirtualPathTo(fileToRenameEntry);
this.VerifyWorktreeBit(fileToRenameEntry, LsFilesStatus.SkipWorktree);

string fileOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, "FileRenamedOutOfRepoAddedToSparseCheckoutAndSkipWorktreeBitCleared.txt");
string fileOutsideRepoPath = Path.Combine(this.Enlistment.EnlistmentRoot, $"{nameof(this.FileRenamedOutOfRepoAddedToModifiedPathsAndSkipWorktreeBitCleared)}.txt");
this.fileSystem.MoveFile(fileToRenameVirtualPath, fileOutsideRepoPath);
fileOutsideRepoPath.ShouldBeAFile(this.fileSystem).WithContents("lessData");

Expand All @@ -315,13 +315,13 @@ public void FileRenamedOutOfRepoAddedToModifiedPathsFile()
}

[TestCase, Order(14)]
public void OverwrittenFileAddedToSparseCheckoutAndSkipWorktreeBitCleared()
public void OverwrittenFileAddedToModifiedPathsAndSkipWorktreeBitCleared()
{
string fileToOverwriteEntry = "Test_EPF_WorkingDirectoryTests/1/2/3/4/ReadDeepProjectedFile.cpp";
string fileToOverwriteVirtualPath = this.Enlistment.GetVirtualPathTo(fileToOverwriteEntry);
this.VerifyWorktreeBit(fileToOverwriteEntry, LsFilesStatus.SkipWorktree);

string testContents = "Test contents for FileRenamedOutOfRepoWillBeAddedToSparseCheckoutAndHaveSkipWorktreeBitCleared";
string testContents = $"Test contents for {nameof(this.OverwrittenFileAddedToModifiedPathsAndSkipWorktreeBitCleared)}";

this.fileSystem.WriteAllText(fileToOverwriteVirtualPath, testContents);
this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");
Expand All @@ -336,13 +336,13 @@ public void OverwrittenFileAddedToSparseCheckoutAndSkipWorktreeBitCleared()

[TestCase, Order(15)]
[Category(Categories.MacTODO.M2)]
public void SupersededFileAddedToSparseCheckoutAndSkipWorktreeBitCleared()
public void SupersededFileAddedToModifiedPathsAndSkipWorktreeBitCleared()
{
string fileToSupersedeEntry = "GVFlt_FileOperationTest/WriteAndVerify.txt";
string fileToSupersedePath = this.Enlistment.GetVirtualPathTo("GVFlt_FileOperationTest\\WriteAndVerify.txt");
this.VerifyWorktreeBit(fileToSupersedeEntry, LsFilesStatus.SkipWorktree);

string newContent = "SupersededFileWillBeAddedToSparseCheckoutAndHaveSkipWorktreeBitCleared test new contents";
string newContent = $"{nameof(this.SupersededFileAddedToModifiedPathsAndSkipWorktreeBitCleared)} test new contents";

SupersedeFile(fileToSupersedePath, newContent).ShouldEqual(true);
this.Enlistment.WaitForBackgroundOperations().ShouldEqual(true, "Background operations failed to complete.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ public void FolderContentsCorrectAfterCreateNewFolderRenameAndCheckoutCommitWith
folder.ShouldNotExistOnDisk(this.fileSystem);
GVFSHelpers.ModifiedPathsShouldNotContain(this.fileSystem, this.Enlistment.DotGVFSRoot, folderName);

// Confirm sparse-checkout picks up renamed folder
// Confirm modified paths picks up renamed folder
string newFolder = this.Enlistment.GetVirtualPathTo("newFolder");
this.fileSystem.CreateDirectory(newFolder);
this.fileSystem.MoveDirectory(newFolder, folder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
using GVFS.FunctionalTests.Tools;
using GVFS.Tests.Should;
using NUnit.Framework;
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

namespace GVFS.FunctionalTests.Tests.EnlistmentPerTestCase
Expand All @@ -18,33 +16,33 @@ public class ModifiedPathsTests : TestsWithEnlistmentPerTestCase
private static readonly string FileToDelete = "Readme.md";
private static readonly string FileToRename = Path.Combine("GVFS", "GVFS.Mount", "MountVerb.cs");
private static readonly string RenameFileTarget = Path.Combine("GVFS", "GVFS.Mount", "MountVerb2.cs");
private static readonly string FolderToCreate = "PersistedSparseExcludeTests_NewFolder";
private static readonly string FolderToRename = "PersistedSparseExcludeTests_NewFolderForRename";
private static readonly string RenameFolderTarget = "PersistedSparseExcludeTests_NewFolderForRename2";
private static readonly string FolderToCreate = $"{nameof(ModifiedPathsTests)}_NewFolder";
private static readonly string FolderToRename = $"{nameof(ModifiedPathsTests)}_NewFolderForRename";
private static readonly string RenameFolderTarget = $"{nameof(ModifiedPathsTests)}_NewFolderForRename2";
private static readonly string DotGitFileToCreate = Path.Combine(".git", "TestFileFromDotGit.txt");
private static readonly string RenameNewDotGitFileTarget = "TestFileFromDotGit.txt";
private static readonly string FileToCreateOutsideRepo = "PersistedSparseExcludeTests_outsideRepo.txt";
private static readonly string FolderToCreateOutsideRepo = "PersistedSparseExcludeTests_outsideFolder";
private static readonly string FileToCreateOutsideRepo = $"{nameof(ModifiedPathsTests)}_outsideRepo.txt";
private static readonly string FolderToCreateOutsideRepo = $"{nameof(ModifiedPathsTests)}_outsideFolder";
private static readonly string FolderToDelete = "Scripts";
private static readonly string ExpectedModifiedFilesContentsAfterRemount =
@"A .gitattributes
A GVFS/TestAddFile.txt
A GVFS/GVFS/Program.cs
A Readme.md
A GVFS/GVFS.Mount/MountVerb.cs
A GVFS/GVFS.Mount/MountVerb2.cs
A PersistedSparseExcludeTests_NewFolder/
A PersistedSparseExcludeTests_NewFolderForRename/
A PersistedSparseExcludeTests_NewFolderForRename2/
A TestFileFromDotGit.txt
A PersistedSparseExcludeTests_outsideRepo.txt
A PersistedSparseExcludeTests_outsideFolder/
A Scripts/CreateCommonAssemblyVersion.bat
A Scripts/CreateCommonCliAssemblyVersion.bat
A Scripts/CreateCommonVersionHeader.bat
A Scripts/RunFunctionalTests.bat
A Scripts/RunUnitTests.bat
A Scripts/
private static readonly string ExpectedModifiedFilesContentsAfterRemount =
$@"A .gitattributes
A {GVFSHelpers.ConvertPathToGitFormat(FileToAdd)}
A {GVFSHelpers.ConvertPathToGitFormat(FileToUpdate)}
A {FileToDelete}
A {GVFSHelpers.ConvertPathToGitFormat(FileToRename)}
A {GVFSHelpers.ConvertPathToGitFormat(RenameFileTarget)}
A {FolderToCreate}/
A {FolderToRename}/
A {RenameFolderTarget}/
A {RenameNewDotGitFileTarget}
A {FileToCreateOutsideRepo}
A {FolderToCreateOutsideRepo}/
A {FolderToDelete}/CreateCommonAssemblyVersion.bat
A {FolderToDelete}/CreateCommonCliAssemblyVersion.bat
A {FolderToDelete}/CreateCommonVersionHeader.bat
A {FolderToDelete}/RunFunctionalTests.bat
A {FolderToDelete}/RunUnitTests.bat
A {FolderToDelete}/
";

[Category(Categories.MacTODO.M2)]
Expand Down Expand Up @@ -72,14 +70,14 @@ public void ModifiedPathsSavedAfterRemount(FileSystemRunner fileSystem)
string folderToRenameTarget = this.Enlistment.GetVirtualPathTo(RenameFolderTarget);
fileSystem.MoveDirectory(folderToRename, folderToRenameTarget);

// Moving the new folder out of the repo should not change the always_exclude file
// Moving the new folder out of the repo should not change the modified paths
string folderTargetOutsideSrc = Path.Combine(this.Enlistment.EnlistmentRoot, RenameFolderTarget);
folderTargetOutsideSrc.ShouldNotExistOnDisk(fileSystem);
fileSystem.MoveDirectory(folderToRenameTarget, folderTargetOutsideSrc);
folderTargetOutsideSrc.ShouldBeADirectory(fileSystem);
folderToRenameTarget.ShouldNotExistOnDisk(fileSystem);

// Moving a file from the .git folder to the working directory should add the file to the sparse-checkout
// Moving a file from the .git folder to the working directory should add the file to the modified paths
string dotGitfileToAdd = this.Enlistment.GetVirtualPathTo(DotGitFileToCreate);
fileSystem.WriteAllText(dotGitfileToAdd, "Contents for the new file in dot git");
fileSystem.MoveFile(dotGitfileToAdd, this.Enlistment.GetVirtualPathTo(RenameNewDotGitFileTarget));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ public void DeleteFileThenCheckout()
[Category(Categories.MacTODO.M3)]
public void CheckoutEditCheckoutWithoutFolderThenCheckoutWithMultipleFiles()
{
// Edit the file to get the entry in the sparse-checkout file
// Edit the file to get the entry in the modified paths database
this.EditFile("Changing the content of one file", "DeleteFileWithNameAheadOfDotAndSwitchCommits", "1");
this.RunGitCommand("reset --hard -q HEAD");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void UpdateIndexRemoveAddFileOpenForWrite()
GitHelpers.InvokeGitAgainstGVFSRepo(this.Enlistment.RepoRoot, "update-index --remove Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt");
this.FilesShouldMatchCheckoutOfTargetBranch();

// Open Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt for write so that it's added to the sparse-checkout
// Open Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt for write so that it's added to the modified paths database
using (FileStream stream = File.Open(Path.Combine(this.Enlistment.RepoRoot, @"Test_ConflictTests\AddedFiles\AddedByBothDifferentContent.txt"), FileMode.Open, FileAccess.Write))
{
// TODO 940287: Remove this File.Open once update-index --add\--remove are working as expected
Expand Down
7 changes: 6 additions & 1 deletion GVFS/GVFS.FunctionalTests/Tools/GVFSHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ public static class GVFSHelpers
private const string DiskLayoutMinorVersionKey = "DiskLayoutMinorVersion";
private const string LocalCacheRootKey = "LocalCacheRoot";
private const string GitObjectsRootKey = "GitObjectsRoot";
private const string BlobSizesRootKey = "BlobSizesRoot";
private const string BlobSizesRootKey = "BlobSizesRoot";

public static string ConvertPathToGitFormat(string path)
{
return path.Replace(Path.DirectorySeparatorChar, TestConstants.GitPathSeparator);
}

public static void SaveDiskLayoutVersion(string dotGVFSRoot, string majorVersion, string minorVersion)
{
Expand Down
2 changes: 0 additions & 2 deletions GVFS/GVFS.FunctionalTests/Tools/GitHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ namespace GVFS.FunctionalTests.Tools
{
public static class GitHelpers
{
public const string AlwaysExcludeFilePath = @".git\info\always_exclude";

/// <summary>
/// This string must match the command name provided in the
/// GVFS.FunctionalTests.LockHolder program.
Expand Down
1 change: 1 addition & 0 deletions GVFS/GVFS.FunctionalTests/Tools/TestConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public static class TestConstants
{
public const string AllZeroSha = "0000000000000000000000000000000000000000";
public const string PartialFolderPlaceholderDatabaseValue = " PARTIAL FOLDER";
public const char GitPathSeparator = '/';

public static class DotGit
{
Expand Down
2 changes: 1 addition & 1 deletion GVFS/GVFS.Virtualization/FileSystemCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ private FileSystemTaskResult ExecuteBackgroundOperation(FileSystemTask gitUpdate
exceptionMetadata.Add("virtualPath", gitUpdate.VirtualPath);
exceptionMetadata.Add(TracingConstants.MessageKey.InfoMessage, "DirectoryNotFoundException while traversing folder path");
exceptionMetadata.Add("folderPath", folderPath);
this.context.Tracer.RelatedEvent(EventLevel.Informational, "DirectoryNotFoundWhileUpdatingAlwaysExclude", exceptionMetadata);
this.context.Tracer.RelatedEvent(EventLevel.Informational, "DirectoryNotFoundWhileUpdatingModifiedPaths", exceptionMetadata);
}
catch (IOException e)
{
Expand Down
Loading