示例#1
0
        public void CheckoutBranchWithSymLinks()
        {
            GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart1");
            GitHelpers.CheckGitCommandAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "status",
                "On branch FunctionalTests/20180925_SymLinksPart1",
                "nothing to commit, working tree clean");

            string testFilePath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFileName));

            testFilePath.ShouldBeAFile(this.bashRunner).WithContents(TestFileContents);
            this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeFalse($"{testFilePath} should not be a symlink");
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + TestFileName);

            string testFile2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFile2Name));

            testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents);
            this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink");
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + TestFile2Name);

            string childLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildLinkName));

            this.bashRunner.IsSymbolicLink(childLinkPath).ShouldBeTrue($"{childLinkPath} should be a symlink");
            childLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFileContents);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildLinkName);

            string grandChildLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolderName, GrandChildLinkName));

            this.bashRunner.IsSymbolicLink(grandChildLinkPath).ShouldBeTrue($"{grandChildLinkPath} should be a symlink");
            grandChildLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildFolderName + "/" + GrandChildLinkName);
        }
        public void GitStatusAndObjectAfterGitAdd()
        {
            string existingFilename = "test.cs";

            this.Enlistment.GetVirtualPathTo(existingFilename).ShouldBeAFile(this.fileSystem);

            GitHelpers.CheckGitCommandAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "add " + existingFilename,
                new string[] { });

            // Status should be correct
            GitHelpers.CheckGitCommandAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "status",
                "On branch " + Properties.Settings.Default.Commitish,
                "Changes to be committed:",
                existingFilename);

            // Object file for the test file should have the correct contents
            ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "hash-object " + existingFilename);

            string objectHash = result.Output.Trim();

            result.Errors.ShouldBeEmpty();

            this.Enlistment.GetObjectPathTo(objectHash).ShouldBeAFile(this.fileSystem);

            GitHelpers.CheckGitCommandAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "cat-file -p " + objectHash,
                this.testFileContents);
        }
示例#3
0
        private void GitCommandWaitsForLock(string gitWorkingDirectory)
        {
            ManualResetEventSlim resetEvent = GitHelpers.AcquireGSDLock(this.Enlistment, out _, resetTimeout: 3000);
            ProcessResult        statusWait = GitHelpers.InvokeGitAgainstGSDRepo(gitWorkingDirectory, "status", removeWaitingMessages: false);

            statusWait.Errors.ShouldContain(ExpectedStatusWaitingText);
            resetEvent.Set();
            this.Enlistment.WaitForBackgroundOperations();
        }
示例#4
0
        public void NoReminderWhenUpgradeNotAvailable()
        {
            this.EmptyDownloadDirectory();

            for (int count = 0; count < 50; count++)
            {
                ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo(
                    this.Enlistment.RepoRoot,
                    "status");

                string.IsNullOrEmpty(result.Errors).ShouldBeTrue();
            }
        }
        public void UpdateIndexRemoveAddFileOpenForWrite()
        {
            // TODO 940287: Remove this test and re-enable UpdateIndexRemoveFileOnDisk
            this.ValidateGitCommand("checkout " + GitRepoTests.ConflictTargetBranch);

            // git-status will not match because update-index --remove does not check what is on disk if the skip-worktree bit is set,
            // meaning it will always remove the file from the index
            GitProcess.InvokeProcess(this.ControlGitRepo.RootPath, "update-index --remove Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt");
            GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "update-index --remove Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt");
            this.FilesShouldMatchCheckoutOfTargetBranch();

            // Add the files back to the index so the git-status that is run during teardown matches
            GitProcess.InvokeProcess(this.ControlGitRepo.RootPath, "update-index --add Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt");
            GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "update-index --add Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt");
        }
示例#6
0
        public void CheckoutBranchWhereFilesTransitionToSymLinks()
        {
            GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart3");
            GitHelpers.CheckGitCommandAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "status",
                "On branch FunctionalTests/20180925_SymLinksPart3",
                "nothing to commit, working tree clean");

            // In this branch testFilePath has been changed to point to newGrandChildFilePath
            string testFilePath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFileName));

            testFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents);
            this.bashRunner.IsSymbolicLink(testFilePath).ShouldBeTrue($"{testFilePath} should be a symlink");
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + TestFileName);

            // There should be a new ChildFolder2Name directory
            string childFolder2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolder2Name));

            this.bashRunner.IsSymbolicLink(childFolder2Path).ShouldBeFalse($"{childFolder2Path} should not be a symlink");
            childFolder2Path.ShouldBeADirectory(this.bashRunner);
            GSDHelpers.ModifiedPathsShouldNotContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildFolder2Name);

            // The rest of the files are unchanged from FunctionalTests/20180925_SymLinksPart2
            string testFile2Path = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, TestFile2Name));

            testFile2Path.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents);
            this.bashRunner.IsSymbolicLink(testFile2Path).ShouldBeFalse($"{testFile2Path} should not be a symlink");

            string childLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildLinkName));

            this.bashRunner.IsSymbolicLink(childLinkPath).ShouldBeTrue($"{childLinkPath} should be a symlink");
            childLinkPath.ShouldBeAFile(this.bashRunner).WithContents(TestFile2Contents);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildLinkName);

            string grandChildLinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolderName, GrandChildLinkName));

            this.bashRunner.IsSymbolicLink(grandChildLinkPath).ShouldBeFalse($"{grandChildLinkPath} should not be a symlink");
            grandChildLinkPath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildLinkNowAFileContents);

            string newGrandChildFilePath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolderName, GrandChildFileName));

            newGrandChildFilePath.ShouldBeAFile(this.bashRunner).WithContents(GrandChildFileContents);
            this.bashRunner.IsSymbolicLink(newGrandChildFilePath).ShouldBeFalse($"{newGrandChildFilePath} should not be a symlink");
        }
        public void GitWithEnvironmentVariables()
        {
            // The trace info is an error, so we can't use CheckGitCommand().
            // We just want to make sure this doesn't throw an exception.
            ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "branch",
                new Dictionary <string, string>
            {
                { "GIT_TRACE_PERFORMANCE", "1" },
                { "git_trace", "1" },
            },
                removeWaitingMessages: false);

            result.Output.ShouldContain("* FunctionalTests");
            result.Errors.ShouldNotContain(ignoreCase: true, unexpectedSubstrings: "exception");
            result.Errors.ShouldContain("trace.c:", "git command:");
        }
示例#8
0
        public void CanReadFileAfterHashObject()
        {
            this.ValidateGitCommand("status");

            // Validate that Scripts\RunUnitTests.bad is not on disk at all
            string filePath = Path.Combine("Scripts", "RunUnitTests.bat");

            this.Enlistment.UnmountGSD();
            this.Enlistment.GetVirtualPathTo(filePath).ShouldNotExistOnDisk(this.FileSystem);
            this.Enlistment.MountGSD();

            // TODO 1087312: Fix 'git hash-oject' so that it works for files that aren't on disk yet
            GitHelpers.InvokeGitAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "hash-object " + GitHelpers.ConvertPathToGitFormat(filePath));

            this.FileContentsShouldMatch(filePath);
        }
示例#9
0
        /* We are using the following method for these scenarios
         * 1. Some commands compute a new commit sha, which is dependent on time and therefore
         *    won't match what is in the control repo.  For those commands, we just ensure that
         *    the errors match what we expect, but we skip comparing the output
         * 2. Using the sparse-checkout feature git will error out before checking the untracked files
         *    so the control repo will show the untracked files as being overwritten while the GSD
         *    repo which is using the sparse-checkout will not.
         * 3. GSD is returning not found for files that are outside the sparse-checkout and there
         *    are cases when git will delete these files during a merge outputting that it removed them
         *    which the GSD repo did not have to remove so the message is missing that output.
         */
        protected void RunGitCommand(string command, bool ignoreErrors = false, bool checkStatus = true)
        {
            string controlRepoRoot = this.ControlGitRepo.RootPath;
            string gvfsRepoRoot    = this.Enlistment.RepoRoot;

            ProcessResult expectedResult = GitProcess.InvokeProcess(controlRepoRoot, command);
            ProcessResult actualResult   = GitHelpers.InvokeGitAgainstGSDRepo(gvfsRepoRoot, command);

            if (!ignoreErrors)
            {
                GitHelpers.ErrorsShouldMatch(command, expectedResult, actualResult);
            }

            if (command != "status" && checkStatus)
            {
                this.ValidateGitCommand("status");
            }
        }
示例#10
0
        private bool ReminderMessagingEnabled()
        {
            for (int count = 0; count < 50; count++)
            {
                ProcessResult result = GitHelpers.InvokeGitAgainstGSDRepo(
                    this.Enlistment.RepoRoot,
                    "status",
                    removeWaitingMessages: true,
                    removeUpgradeMessages: false);

                if (!string.IsNullOrEmpty(result.Errors) &&
                    result.Errors.Contains("A new version of GSD is available."))
                {
                    return(true);
                }
            }

            return(false);
        }
        public void MergeConflictEnsureStatusFailsDueToConfig()
        {
            // This is compared against the message emitted by GSD.Hooks\Program.cs
            string expectedErrorMessagePart = "--no-renames";

            this.ValidateGitCommand("checkout " + GitRepoTests.ConflictTargetBranch);
            this.RunGitCommand("merge " + GitRepoTests.ConflictSourceBranch, checkStatus: false);

            ProcessResult result1 = GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "status");

            result1.Errors.Contains(expectedErrorMessagePart);

            ProcessResult result2 = GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "status --no-renames");

            result2.Errors.Contains(expectedErrorMessagePart);

            // Complete setup to ensure teardown succeeds
            GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "config --local test.renames false");
        }
示例#12
0
        public void SecondCloneSucceedsWithMissingTrees()
        {
            string newCachePath = Path.Combine(this.localCacheParentPath, ".customGvfsCache2");
            GSDFunctionalTestEnlistment enlistment1 = this.CreateNewEnlistment(localCacheRoot: newCachePath, skipPrefetch: true);

            File.ReadAllText(Path.Combine(enlistment1.RepoRoot, WellKnownFile));
            this.AlternatesFileShouldHaveGitObjectsRoot(enlistment1);

            // This Git command loads the commit and root tree for WellKnownCommitSha,
            // but does not download any more reachable objects.
            string        command = "cat-file -p origin/" + WellKnownBranch + "^{tree}";
            ProcessResult result  = GitHelpers.InvokeGitAgainstGSDRepo(enlistment1.RepoRoot, command);

            result.ExitCode.ShouldEqual(0, $"git {command} failed with error: " + result.Errors);

            // If we did not properly check the failed checkout at this step, then clone will fail during checkout.
            GSDFunctionalTestEnlistment enlistment2 = this.CreateNewEnlistment(localCacheRoot: newCachePath, branch: WellKnownBranch, skipPrefetch: true);

            File.ReadAllText(Path.Combine(enlistment2.RepoRoot, WellKnownFile));
        }
示例#13
0
        public void CheckoutBranchWhereSymLinkTransistionsToFolderAndFolderTransitionsToSymlink()
        {
            GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout FunctionalTests/20180925_SymLinksPart4");
            GitHelpers.CheckGitCommandAgainstGSDRepo(
                this.Enlistment.RepoRoot,
                "status",
                "On branch FunctionalTests/20180925_SymLinksPart4",
                "nothing to commit, working tree clean");

            // In this branch ChildLinkName has been changed to a directory and ChildFolder2Name has been changed to a link to ChildFolderName
            string linkNowADirectoryPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildLinkName));

            this.bashRunner.IsSymbolicLink(linkNowADirectoryPath).ShouldBeFalse($"{linkNowADirectoryPath} should not be a symlink");
            linkNowADirectoryPath.ShouldBeADirectory(this.bashRunner);
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildLinkName);

            string directoryNowALinkPath = this.Enlistment.GetVirtualPathTo(Path.Combine(TestFolderName, ChildFolder2Name));

            this.bashRunner.IsSymbolicLink(directoryNowALinkPath).ShouldBeTrue($"{directoryNowALinkPath} should be a symlink");
            GSDHelpers.ModifiedPathsShouldContain(this.Enlistment, this.bashRunner, TestFolderName + "/" + ChildFolder2Name);
        }
        public void CheckoutCleansUpTombstones()
        {
            const string folderToDelete = "Scripts";

            // Delete directory to create the tombstone
            string directoryToDelete = this.Enlistment.GetVirtualPathTo(folderToDelete);

            this.fileSystem.DeleteDirectory(directoryToDelete);
            this.Enlistment.UnmountGSD();

            // Remove the directory entry from modified paths so git will not keep the folder up to date
            string modifiedPathsFile    = Path.Combine(this.Enlistment.DotGSDRoot, TestConstants.Databases.ModifiedPaths);
            string modifiedPathsContent = this.fileSystem.ReadAllText(modifiedPathsFile);

            modifiedPathsContent = string.Join(Delimiter, modifiedPathsContent.Split(new[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries).Where(x => !x.StartsWith($"A {folderToDelete}/")));
            this.fileSystem.WriteAllText(modifiedPathsFile, modifiedPathsContent + Delimiter);

            // Add tombstone folder entry to the placeholder database so the checkout will remove the tombstone
            // and start projecting the folder again
            string placeholderDatabasePath = Path.Combine(this.Enlistment.DotGSDRoot, TestConstants.Databases.GSD);

            GSDHelpers.AddPlaceholderFolder(placeholderDatabasePath, folderToDelete, TombstoneFolderPlaceholderType);

            this.Enlistment.MountGSD();
            directoryToDelete.ShouldNotExistOnDisk(this.fileSystem);

            // checkout branch to remove tombstones and project the folder again
            GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, "checkout -f HEAD");
            directoryToDelete.ShouldBeADirectory(this.fileSystem);

            this.Enlistment.UnmountGSD();

            string placholders = GSDHelpers.GetAllSQLitePlaceholdersAsString(placeholderDatabasePath);

            placholders.ShouldNotContain(ignoreCase: false, unexpectedSubstrings: $"{folderToDelete}{GSDHelpers.PlaceholderFieldDelimiter}{TombstoneFolderPlaceholderType}{GSDHelpers.PlaceholderFieldDelimiter}");
        }
 private ProcessResult InvokeGitAgainstGSDRepo(string command)
 {
     return(GitHelpers.InvokeGitAgainstGSDRepo(this.Enlistment.RepoRoot, command));
 }