Example #1
0
        public void CanFollowFirstParent()
        {
            string path = SandboxStandardTestRepo();
            using (var repo = new Repository(path))
            {
                var branch = repo.CreateBranch("branch");

                // Make an earlier tag on master
                repo.Commit("A", Constants.Signature, Constants.Signature, new CommitOptions { AllowEmptyCommit = true });
                repo.ApplyTag("firstParentTag");

                // Make a later tag on branch
                Commands.Checkout(repo, branch);
                repo.Commit("B", Constants.Signature, Constants.Signature, new CommitOptions { AllowEmptyCommit = true });
                repo.ApplyTag("mostRecentTag");

                Commands.Checkout(repo, "master");
                repo.Commit("C", Constants.Signature, Constants.Signature, new CommitOptions { AllowEmptyCommit = true });
                repo.Merge(branch, Constants.Signature, new MergeOptions() { FastForwardStrategy = FastForwardStrategy.NoFastForward });

                // With OnlyFollowFirstParent = false, the most recent tag reachable should be returned
                Assert.Equal("mostRecentTag-3-gf17be71", repo.Describe(repo.Head.Tip, new DescribeOptions { OnlyFollowFirstParent = false, Strategy = DescribeStrategy.Tags }));

                // With OnlyFollowFirstParent = true, the most recent tag on the current branch should be returned
                Assert.Equal("firstParentTag-2-gf17be71", repo.Describe(repo.Head.Tip, new DescribeOptions { OnlyFollowFirstParent = true, Strategy = DescribeStrategy.Tags }));

            }
        }
Example #2
0
        public void CanCancelCheckoutThroughNotifyCallback()
        {
            string repoPath = InitNewRepository();

            using (var repo = new Repository(repoPath))
            {
                string relativePath = "a.txt";
                Touch(repo.Info.WorkingDirectory, relativePath, "Hello\n");

                repo.Index.Stage(relativePath);
                repo.Commit("Initial commit", Constants.Signature, Constants.Signature);

                // Create 2nd branch
                repo.CreateBranch("branch2");

                // Update file in main
                Touch(repo.Info.WorkingDirectory, relativePath, "Hello from master!\n");
                repo.Index.Stage(relativePath);
                repo.Commit("2nd commit", Constants.Signature, Constants.Signature);

                // Checkout branch2
                repo.Checkout("branch2");

                // Update the context of a.txt - a.txt will then conflict between branch2 and master.
                Touch(repo.Info.WorkingDirectory, relativePath, "Hello From branch2!\n");

                // Verify that we get called for the notify conflict cb
                string conflictPath = string.Empty;
                CheckoutNotificationOptions checkoutNotifications = new CheckoutNotificationOptions((path, flags) => { conflictPath = path; return false; }, CheckoutNotifyFlags.Conflict);
                Assert.Throws<UserCancelledException>(() => repo.Checkout("master", CheckoutModifiers.None, null, checkoutNotifications));
                Assert.Equal(relativePath, conflictPath);
            }
        }
Example #3
0
        public void CanCommitALittleBit()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
            string dir = Repository.Init(scd.DirectoryPath);
            Path.IsPathRooted(dir).ShouldBeTrue();
            Directory.Exists(dir).ShouldBeTrue();

            using (var repo = new Repository(dir))
            {
                const string relativeFilepath = "new.txt";
                string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath);

                File.WriteAllText(filePath, "null");
                repo.Index.Stage(relativeFilepath);
                File.AppendAllText(filePath, "token\n");
                repo.Index.Stage(relativeFilepath);

                repo.Head[relativeFilepath].ShouldBeNull();

                var author = new Signature("Author N. Ame", "*****@*****.**", DateTimeOffset.Now.AddSeconds(-10));
                Commit commit = repo.Commit("Initial egotistic commit", author, author);

                AssertBlobContent(repo.Head[relativeFilepath], "nulltoken\n");
                AssertBlobContent(commit[relativeFilepath], "nulltoken\n");

                commit.Parents.Count().ShouldEqual(0);
                repo.Info.IsEmpty.ShouldBeFalse();

                File.WriteAllText(filePath, "nulltoken commits!\n");
                repo.Index.Stage(relativeFilepath);

                var author2 = new Signature(author.Name, author.Email, author.When.AddSeconds(5));
                Commit commit2 = repo.Commit("Are you trying to fork me?", author2, author2);

                AssertBlobContent(repo.Head[relativeFilepath], "nulltoken commits!\n");
                AssertBlobContent(commit2[relativeFilepath], "nulltoken commits!\n");

                commit2.Parents.Count().ShouldEqual(1);
                commit2.Parents.First().Id.ShouldEqual(commit.Id);

                Branch firstCommitBranch = repo.CreateBranch("davidfowl-rules", commit.Id.Sha); //TODO: This cries for a shortcut method :-/
                repo.Branches.Checkout(firstCommitBranch.Name); //TODO: This cries for a shortcut method :-/

                File.WriteAllText(filePath, "davidfowl commits!\n");

                var author3 = new Signature("David Fowler", "*****@*****.**", author.When.AddSeconds(2));
                repo.Index.Stage(relativeFilepath);

                Commit commit3 = repo.Commit("I'm going to branch you backwards in time!", author3, author3);

                AssertBlobContent(repo.Head[relativeFilepath], "davidfowl commits!\n");
                AssertBlobContent(commit3[relativeFilepath], "davidfowl commits!\n");

                commit3.Parents.Count().ShouldEqual(1);
                commit3.Parents.First().Id.ShouldEqual(commit.Id);

                AssertBlobContent(firstCommitBranch[relativeFilepath], "nulltoken\n");
            }
        }
Example #4
0
        public void HonorDeeplyNestedGitIgnoreFile()
        {
            string path = InitNewRepository();
            using (var repo = new Repository(path))
            {
                char pd = Path.DirectorySeparatorChar;

                var gitIgnoreFile = string.Format("deeply{0}nested{0}.gitignore", pd);
                Touch(repo.Info.WorkingDirectory, gitIgnoreFile, "SmtCounters.h");

                Commands.Stage(repo, gitIgnoreFile);
                repo.Commit("Add .gitignore", Constants.Signature, Constants.Signature);

                Assert.False(repo.RetrieveStatus().IsDirty);

                var ignoredFile = string.Format("deeply{0}nested{0}SmtCounters.h", pd);
                Touch(repo.Info.WorkingDirectory, ignoredFile, "Content");
                Assert.False(repo.RetrieveStatus().IsDirty);

                var file = string.Format("deeply{0}nested{0}file.txt", pd);
                Touch(repo.Info.WorkingDirectory, file, "Yeah!");

                var repositoryStatus = repo.RetrieveStatus();
                Assert.True(repositoryStatus.IsDirty);

                Assert.Equal(FileStatus.Ignored, repositoryStatus[ignoredFile].State);
                Assert.Equal(FileStatus.NewInWorkdir, repositoryStatus[file].State);

                Assert.True(repo.Ignore.IsPathIgnored(ignoredFile));
                Assert.False(repo.Ignore.IsPathIgnored(file));
            }
        }
Example #5
0
        public void CanCopeWithExternalChangesToTheIndex()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();

            Touch(scd.DirectoryPath, "a.txt", "a\n");
            Touch(scd.DirectoryPath, "b.txt", "b\n");

            string path = Repository.Init(scd.DirectoryPath);

            using (var repoWrite = new Repository(path))
            using (var repoRead = new Repository(path))
            {
                var writeStatus = repoWrite.RetrieveStatus();
                Assert.True(writeStatus.IsDirty);
                Assert.Equal(0, repoWrite.Index.Count);

                var readStatus = repoRead.RetrieveStatus();
                Assert.True(readStatus.IsDirty);
                Assert.Equal(0, repoRead.Index.Count);

                repoWrite.Stage("*");
                repoWrite.Commit("message", Constants.Signature, Constants.Signature);

                writeStatus = repoWrite.RetrieveStatus();
                Assert.False(writeStatus.IsDirty);
                Assert.Equal(2, repoWrite.Index.Count);

                readStatus = repoRead.RetrieveStatus();
                Assert.False(readStatus.IsDirty);
                Assert.Equal(2, repoRead.Index.Count);
            }
        }
Example #6
0
        public void CanAmendAnEmptyMergeCommit()
        {
            string path = CloneStandardTestRepo();
            using (var repo = new Repository(path))
            {
                repo.Reset(ResetMode.Hard);
                repo.RemoveUntrackedFiles();

                Touch(repo.Info.Path, "MERGE_HEAD", "f705abffe7015f2beacf2abe7a36583ebee3487e\n");
                Commit newMergedCommit = repo.Commit("Merge commit", Constants.Signature, Constants.Signature);

                Commit amendedCommit = repo.Commit("I'm rewriting the history!", Constants.Signature, Constants.Signature,
                    new CommitOptions { AmendPreviousCommit = true });
                AssertCommitHasBeenAmended(repo, amendedCommit, newMergedCommit);
            }
        }
Example #7
0
        public void CommitOnDetachedHeadShouldInsertReflogEntry()
        {
            string repoPath = CloneStandardTestRepo();

            using (var repo = new Repository(repoPath))
            {
                Assert.False(repo.Info.IsHeadDetached);

                var parentCommit = repo.Head.Tip.Parents.First();
                repo.Checkout(parentCommit.Sha);
                Assert.True(repo.Info.IsHeadDetached);

                const string relativeFilepath = "new.txt";
                string filePath = Path.Combine(repo.Info.WorkingDirectory, relativeFilepath);

                File.WriteAllText(filePath, "content\n");
                repo.Index.Stage(relativeFilepath);

                var author = DummySignature;
                const string commitMessage = "Commit on detached head";
                var commit = repo.Commit(commitMessage, author, author);

                // Assert a reflog entry is created on HEAD
                var reflogEntry = repo.Refs.Log("HEAD").First();
                Assert.Equal(author, reflogEntry.Commiter);
                Assert.Equal(commit.Id, reflogEntry.To);
                Assert.Equal(string.Format("commit: {0}", commitMessage), repo.Refs.Log("HEAD").First().Message);
            }
        }
Example #8
0
        public void CanAmendACommitWithMoreThanOneParent()
        {
            string path = CloneStandardTestRepo();
            using (var repo = new Repository(path))
            {
                var mergedCommit = repo.Lookup<Commit>("be3563a");
                Assert.NotNull(mergedCommit);
                Assert.Equal(2, mergedCommit.Parents.Count());

                repo.Reset(ResetMode.Soft, mergedCommit.Sha);

                CreateAndStageANewFile(repo);
                const string commitMessage = "I'm rewriting the history!";

                Commit amendedCommit = repo.Commit(commitMessage, Constants.Signature, Constants.Signature,
                    new CommitOptions { AmendPreviousCommit = true });

                AssertCommitHasBeenAmended(repo, amendedCommit, mergedCommit);

                AssertRefLogEntry(repo, "HEAD",
                                  amendedCommit.Id,
                                  string.Format("commit (amend): {0}", commitMessage),
                                  mergedCommit.Id,
                                  amendedCommit.Committer);
            }
        }
Example #9
0
        public void CanAmendAnEmptyCommitWhenForced()
        {
            string path = CloneStandardTestRepo();
            using (var repo = new Repository(path))
            {
                repo.Reset(ResetMode.Hard);
                repo.RemoveUntrackedFiles();

                Commit emptyCommit = repo.Commit("Empty commit!", Constants.Signature, Constants.Signature,
                    new CommitOptions { AllowEmptyCommit = true });

                Commit amendedCommit = repo.Commit("I'm rewriting the history!", Constants.Signature, Constants.Signature,
                    new CommitOptions { AmendPreviousCommit = true, AllowEmptyCommit = true });
                AssertCommitHasBeenAmended(repo, amendedCommit, emptyCommit);
            }
        }
Example #10
0
        public void CanGetBlobAsTextWithVariousEncodings(string encodingName, int expectedContentBytes, string expectedUtf7Chars)
        {
            var path = CloneStandardTestRepo();
            using (var repo = new Repository(path))
            {
                var bomFile = "bom.txt";
                var content = "1234";
                var encoding = Encoding.GetEncoding(encodingName);

                var bomPath = Touch(repo.Info.WorkingDirectory, bomFile, content, encoding);
                Assert.Equal(expectedContentBytes, File.ReadAllBytes(bomPath).Length);

                repo.Stage(bomFile);
                var commit = repo.Commit("bom", Constants.Signature, Constants.Signature);

                var blob = (Blob)commit.Tree[bomFile].Target;
                Assert.Equal(expectedContentBytes, blob.Size);
                using (var stream = blob.GetContentStream())
                {
                    Assert.Equal(expectedContentBytes, stream.Length);
                }

                var textDetected = blob.GetContentText();
                Assert.Equal(content, textDetected);

                var text = blob.GetContentText(encoding);
                Assert.Equal(content, text);

                var utf7Chars = blob.GetContentText(Encoding.UTF7).Select(c => ((int)c).ToString("X2")).ToArray();
                Assert.Equal(expectedUtf7Chars, string.Join(" ", utf7Chars));
            }
        }
Example #11
0
        public void CanAmendACommitWithMoreThanOneParent()
        {
            string path = CloneStandardTestRepo();
            using (var repo = new Repository(path))
            {
                var mergedCommit = repo.Lookup<Commit>("be3563a");
                Assert.NotNull(mergedCommit);
                Assert.Equal(2, mergedCommit.Parents.Count());

                repo.Reset(ResetOptions.Soft, mergedCommit.Sha);

                CreateAndStageANewFile(repo);
                const string commitMessage = "I'm rewriting the history!";

                Commit amendedCommit = repo.Commit(commitMessage, DummySignature, DummySignature, true);

                AssertCommitHasBeenAmended(repo, amendedCommit, mergedCommit);

                // Assert a reflog entry is created
                var reflogEntry = repo.Refs.Log("HEAD").First();
                Assert.Equal(amendedCommit.Committer, reflogEntry.Commiter);
                Assert.Equal(amendedCommit.Id, reflogEntry.To);
                Assert.Equal(string.Format("commit (amend): {0}", commitMessage), reflogEntry.Message);
            }
        }
Example #12
0
 protected static Commit AddOneCommitToHead(Repository repo, string type)
 {
     var randomFile = Path.Combine(repo.Info.WorkingDirectory, Guid.NewGuid().ToString());
     File.WriteAllText(randomFile, string.Empty);
     repo.Index.Stage(randomFile);
     var sign = SignatureBuilder.SignatureNow();
     return repo.Commit(type + " commit", sign, sign);
 }
 public async Task GetBuildVersion_In_Git_But_Head_Lacks_VersionFile()
 {
     Repository.Init(this.RepoPath);
     var repo = new Repository(this.RepoPath); // do not assign Repo property to avoid commits being generated later
     repo.Commit("empty", new CommitOptions { AllowEmptyCommit = true });
     this.WriteVersionFile("3.4");
     var buildResult = await this.BuildAsync();
     Assert.Equal("0.0.1." + repo.Head.Commits.First().GetIdAsVersion().Revision, buildResult.BuildVersion);
     Assert.Equal("0.0.1+g" + repo.Head.Commits.First().Id.Sha.Substring(0, 10), buildResult.AssemblyInformationalVersion);
 }
 protected static void WriteTextFileAndCommit(Repository repo, string fileName, string contents, string commitMessage, bool addRemove)
 {
     File.WriteAllText(Path.Combine(repo.Path, fileName), contents);
     repo.Commit(
         new CommitCommand
         {
             Message = commitMessage,
             AddRemove = addRemove,
         });
 }
        public GeneratorActionResult ExecuteAction(GeneratorArguments arguments, Core.InputFields.ActionInputValues values, Dictionary<string, string> parameters)
        {
            var location = values.GetString("DestinationFolder");

            var repo = new Repository(location);
            repo.Add(new AddCommand().WithPaths(location));

            repo.Commit(string.Format(MercurialCommitMessage, Environment.UserName));

            return new GeneratorActionResult(true, "");
        }
Example #16
0
        public void CommitAgainARepoWithUnmergedEntriesThrows()
        {
            using (var repo = new Repository(MergedTestRepoWorkingDirPath))
            {
                Assert.Equal(false, repo.Index.IsFullyMerged);

                var author = DummySignature;
                Assert.Throws<UnmergedIndexEntriesException>(
                    () => repo.Commit("Try commit unmerged entries", author, author));
            }
        }
Example #17
0
        public void CommitAgainARepoWithUnmergedEntriesThrows()
        {
            var path = SandboxMergedTestRepo();
            using (var repo = new Repository(path))
            {
                Assert.Equal(false, repo.Index.IsFullyMerged);

                var author = Constants.Signature;
                Assert.Throws<UnmergedIndexEntriesException>(
                    () => repo.Commit("Try commit unmerged entries", author, author));
            }
        }
Example #18
0
        public void CanAmendACommitWithMoreThanOneParent()
        {
            TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoPath);
            using (var repo = new Repository(path.RepositoryPath))
            {
                var mergedCommit = repo.Lookup<Commit>("be3563a");
                Assert.NotNull(mergedCommit);
                Assert.Equal(2, mergedCommit.ParentsCount);

                repo.Reset(ResetOptions.Soft, mergedCommit.Sha);

                CreateAndStageANewFile(repo);

                Commit amendedCommit = repo.Commit("I'm rewriting the history!", DummySignature, DummySignature, true);

                AssertCommitHasBeenAmended(repo, amendedCommit, mergedCommit);
            }
        }
Example #19
0
        public void CanDetectedVariousKindsOfRenaming()
        {
            string path = InitNewRepository();
            using (var repo = new Repository(path))
            {
                Touch(repo.Info.WorkingDirectory, "file.txt",
                    "This is a file with enough data to trigger similarity matching.\r\n" +
                    "This is a file with enough data to trigger similarity matching.\r\n" +
                    "This is a file with enough data to trigger similarity matching.\r\n" +
                    "This is a file with enough data to trigger similarity matching.\r\n");

                Commands.Stage(repo, "file.txt");
                repo.Commit("Initial commit", Constants.Signature, Constants.Signature);

                File.Move(Path.Combine(repo.Info.WorkingDirectory, "file.txt"),
                    Path.Combine(repo.Info.WorkingDirectory, "renamed.txt"));

                var opts = new StatusOptions
                {
                    DetectRenamesInIndex = true,
                    DetectRenamesInWorkDir = true
                };

                RepositoryStatus status = repo.RetrieveStatus(opts);

                // This passes as expected
                Assert.Equal(FileStatus.RenamedInWorkdir, status.Single().State);

                Commands.Stage(repo, "file.txt");
                Commands.Stage(repo, "renamed.txt");

                status = repo.RetrieveStatus(opts);

                Assert.Equal(FileStatus.RenamedInIndex, status.Single().State);

                File.Move(Path.Combine(repo.Info.WorkingDirectory, "renamed.txt"),
                    Path.Combine(repo.Info.WorkingDirectory, "renamed_again.txt"));

                status = repo.RetrieveStatus(opts);

                Assert.Equal(FileStatus.RenamedInWorkdir | FileStatus.RenamedInIndex,
                    status.Single().State);
            }
        }
Example #20
0
        public void CommitOnUnbornReferenceShouldCreateReflogEntryWithInitialTag()
        {
            string repoPath = InitNewRepository();

            using (var repo = new Repository(repoPath))
            {
                const string relativeFilepath = "new.txt";
                Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n");
                repo.Index.Stage(relativeFilepath);

                var author = Constants.Signature;
                const string commitMessage = "First commit should be logged as initial";
                repo.Commit(commitMessage, author, author);

                // Assert the reflog entry message is correct
                Assert.Equal(1, repo.Refs.Log("HEAD").Count());
                Assert.Equal(string.Format("commit (initial): {0}", commitMessage), repo.Refs.Log("HEAD").First().Message);
            }
        }
Example #21
0
        private void AssertPush(Action<IRepository> push)
        {
            var scd = BuildSelfCleaningDirectory();

            string originalRepoPath = CloneBareTestRepo();
            string clonedRepoPath = Repository.Clone(originalRepoPath, scd.DirectoryPath);

            using (var originalRepo = new Repository(originalRepoPath))
            using (var clonedRepo = new Repository(clonedRepoPath))
            {
                Remote remote = clonedRepo.Network.Remotes["origin"];

                // Compare before
                Assert.Equal(originalRepo.Refs["HEAD"].ResolveToDirectReference().TargetIdentifier,
                             clonedRepo.Refs["HEAD"].ResolveToDirectReference().TargetIdentifier);
                Assert.Equal(
                    clonedRepo.Network.ListReferences(remote).Single(r => r.CanonicalName == "refs/heads/master"),
                    clonedRepo.Refs.Head.ResolveToDirectReference());

                // Change local state (commit)
                const string relativeFilepath = "new_file.txt";
                Touch(clonedRepo.Info.WorkingDirectory, relativeFilepath, "__content__");
                clonedRepo.Index.Stage(relativeFilepath);
                clonedRepo.Commit("__commit_message__", Constants.Signature, Constants.Signature);

                // Assert local state has changed
                Assert.NotEqual(originalRepo.Refs["HEAD"].ResolveToDirectReference().TargetIdentifier,
                                clonedRepo.Refs["HEAD"].ResolveToDirectReference().TargetIdentifier);
                Assert.NotEqual(
                    clonedRepo.Network.ListReferences(remote).Single(r => r.CanonicalName == "refs/heads/master"),
                    clonedRepo.Refs.Head.ResolveToDirectReference());

                // Push the change upstream (remote state is supposed to change)
                push(clonedRepo);

                // Assert that both local and remote repos are in sync
                Assert.Equal(originalRepo.Refs["HEAD"].ResolveToDirectReference().TargetIdentifier,
                             clonedRepo.Refs["HEAD"].ResolveToDirectReference().TargetIdentifier);
                Assert.Equal(
                    clonedRepo.Network.ListReferences(remote).Single(r => r.CanonicalName == "refs/heads/master"),
                    clonedRepo.Refs.Head.ResolveToDirectReference());
            }
        }
Example #22
0
        public void CanAmendARootCommit()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();

            CommitToANewRepository(scd.DirectoryPath);

            using (var repo = new Repository(scd.DirectoryPath))
            {
                Assert.Equal(1, repo.Head.Commits.Count());

                Commit originalCommit = repo.Head.Tip;
                Assert.Equal(0, originalCommit.ParentsCount);

                CreateAndStageANewFile(repo);

                Commit amendedCommit = repo.Commit("I'm rewriting the history!", DummySignature, DummySignature, true);

                Assert.Equal(1, repo.Head.Commits.Count());

                AssertCommitHasBeenAmended(repo, amendedCommit, originalCommit);
            }
        }
Example #23
0
        public void CanAmendARootCommit()
        {
            string repoPath = InitNewRepository();

            AddCommitToRepo(repoPath);

            using (var repo = new Repository(repoPath))
            {
                Assert.Equal(1, repo.Head.Commits.Count());

                Commit originalCommit = repo.Head.Tip;
                Assert.Equal(0, originalCommit.Parents.Count());

                CreateAndStageANewFile(repo);

                Commit amendedCommit = repo.Commit("I'm rewriting the history!", Constants.Signature, Constants.Signature, true);

                Assert.Equal(1, repo.Head.Commits.Count());

                AssertCommitHasBeenAmended(repo, amendedCommit, originalCommit);
            }
        }
        public void CommitShouldCreateReflogEntryOnHeadAndOnTargetedDirectReference()
        {
            string repoPath = InitNewRepository();

            using (var repo = new Repository(repoPath))
            {
                // setup refs as HEAD => unit_test => master
                var newRef = repo.Refs.Add("refs/heads/unit_test", "refs/heads/master");
                Assert.NotNull(newRef);
                repo.Refs.UpdateTarget(repo.Refs.Head, newRef);

                const string relativeFilepath = "new.txt";
                Touch(repo.Info.WorkingDirectory, relativeFilepath, "content\n");
                repo.Index.Stage(relativeFilepath);

                var author = Constants.Signature;
                const string commitMessage = "Hope reflog behaves as it should";
                Commit commit = repo.Commit(commitMessage, author, author);

                // Assert a reflog entry is created on HEAD
                Assert.Equal(1, repo.Refs.Log("HEAD").Count());
                var reflogEntry = repo.Refs.Log("HEAD").First();
                Assert.Equal(author, reflogEntry.Commiter);
                Assert.Equal(commit.Id, reflogEntry.To);
                Assert.Equal(ObjectId.Zero, reflogEntry.From);

                // Assert the same reflog entry is created on refs/heads/master
                Assert.Equal(1, repo.Refs.Log("refs/heads/master").Count());
                reflogEntry = repo.Refs.Log("HEAD").First();
                Assert.Equal(author, reflogEntry.Commiter);
                Assert.Equal(commit.Id, reflogEntry.To);
                Assert.Equal(ObjectId.Zero, reflogEntry.From);

                // Assert no reflog entry is created on refs/heads/unit_test
                Assert.Equal(0, repo.Refs.Log("refs/heads/unit_test").Count());
            }
        }
        public void CanCommitOnBareRepository()
        {
            string repoPath = InitNewRepository(true);
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
            string workPath = Path.Combine(scd.RootedDirectoryPath, "work");
            Directory.CreateDirectory(workPath);

            var repositoryOptions = new RepositoryOptions
            {
                WorkingDirectoryPath = workPath,
                IndexPath = Path.Combine(scd.RootedDirectoryPath, "index")
            };

            using (var repo = new Repository(repoPath, repositoryOptions))
            {
                const string relativeFilepath = "test.txt";
                Touch(repo.Info.WorkingDirectory, relativeFilepath, "test\n");
                repo.Stage(relativeFilepath);

                Assert.NotNull(repo.Commit("Initial commit", Constants.Signature, Constants.Signature));
                Assert.Equal(1, repo.Head.Commits.Count());
                Assert.Equal(1, repo.Commits.Count());
            }
        }
        public void ExactModeDoesntDetectRenamesWithEdits()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
            var path = Repository.Init(scd.DirectoryPath);
            using (var repo = new Repository(path))
            {
                const string originalPath = "original.txt";
                const string renamedPath = "renamed.txt";

                Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n");

                Commands.Stage(repo, originalPath);

                Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature);

                Commands.Move(repo, originalPath, renamedPath);
                File.AppendAllText(Path.Combine(repo.Info.WorkingDirectory, renamedPath), "e\nf\n");
                Commands.Stage(repo, renamedPath);

                Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature);

                using (var changes = repo.Diff.Compare<TreeChanges>(old.Tree, @new.Tree,
                    compareOptions: new CompareOptions
                    {
                        Similarity = SimilarityOptions.Exact,
                    }))
                {
                    Assert.Equal(2, changes.Count());
                    Assert.Equal(0, changes.Renamed.Count());
                    Assert.Equal(1, changes.Added.Count());
                    Assert.Equal(1, changes.Deleted.Count());
                }
            }
        }
        public void ExactModeDetectsExactCopies()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
            var path = Repository.Init(scd.DirectoryPath);
            using (var repo = new Repository(path))
            {
                const string originalPath = "original.txt";
                const string copiedPath = "copied.txt";
                var originalFullPath = Path.Combine(repo.Info.WorkingDirectory, originalPath);
                var copiedFullPath = Path.Combine(repo.Info.WorkingDirectory, copiedPath);

                Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n");
                Commands.Stage(repo, originalPath);
                Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature);

                File.Copy(originalFullPath, copiedFullPath);
                Commands.Stage(repo, copiedPath);

                Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature);

                using (var changes = repo.Diff.Compare<TreeChanges>(old.Tree, @new.Tree,
                    compareOptions: new CompareOptions
                    {
                        Similarity = SimilarityOptions.Exact,
                    }))
                {
                    Assert.Equal(1, changes.Count());
                    Assert.Equal(1, changes.Copied.Count());
                }
            }
        }
        public void DetectsTheExactRenamingOfFilesByDefault()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
            var path = Repository.Init(scd.DirectoryPath);
            using (var repo = new Repository(path))
            {
                const string originalPath = "original.txt";
                const string renamedPath = "renamed.txt";

                Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n");

                Commands.Stage(repo, originalPath);

                Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature);

                Commands.Move(repo, originalPath, renamedPath);

                Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature);

                using (var changes = repo.Diff.Compare<TreeChanges>(old.Tree, @new.Tree))
                {
                    Assert.Equal(1, changes.Count());
                    Assert.Equal(1, changes.Renamed.Count());
                    Assert.Equal(originalPath, changes.Renamed.Single().OldPath);
                    Assert.Equal(renamedPath, changes.Renamed.Single().Path);
                }
            }
        }
        public void CanNotDetectTheExactRenamingFilesWhenNotEnabled()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
            var path = Repository.Init(scd.DirectoryPath);
            using (var repo = new Repository(path))
            {
                const string originalPath = "original.txt";
                const string renamedPath = "renamed.txt";

                Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n");

                Commands.Stage(repo, originalPath);

                Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature);

                Commands.Move(repo, originalPath, renamedPath);

                Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature);

                using (var changes = repo.Diff.Compare<TreeChanges>(old.Tree, @new.Tree,
                    compareOptions:
                        new CompareOptions
                        {
                            Similarity = SimilarityOptions.None,
                        }))
                {
                    Assert.Equal(2, changes.Count());
                    Assert.Equal(0, changes.Renamed.Count());
                }
            }
        }
        public void CanNotDetectTheExactCopyingOfNonModifiedFilesWhenNotEnabled()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
            var path = Repository.Init(scd.DirectoryPath);
            using (var repo = new Repository(path))
            {
                const string originalPath = "original.txt";
                const string copiedPath = "copied.txt";
                string originalFullPath = Path.Combine(repo.Info.WorkingDirectory, originalPath);
                string copiedFullPath = Path.Combine(repo.Info.WorkingDirectory, copiedPath);

                Touch(repo.Info.WorkingDirectory, originalPath, "a\nb\nc\nd\n");

                Commands.Stage(repo, originalPath);

                Commit old = repo.Commit("Initial", Constants.Signature, Constants.Signature);

                File.Copy(originalFullPath, copiedFullPath);
                Commands.Stage(repo, copiedPath);

                Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature);

                using (var changes = repo.Diff.Compare<TreeChanges>(old.Tree, @new.Tree))
                {
                    Assert.Equal(1, changes.Count());
                    Assert.Equal(0, changes.Copied.Count());
                }
            }
        }