diff options
author | nulltoken <emeric.fermas@gmail.com> | 2012-04-20 14:59:48 +0400 |
---|---|---|
committer | nulltoken <emeric.fermas@gmail.com> | 2012-04-28 05:32:19 +0400 |
commit | a3d5b885eeb3d1fac1bf69c95196e7d8ef167e28 (patch) | |
tree | e41b39c04a954adf9af79e7e41bdf9210222d4af | |
parent | 973d1abd4d1c2d76b1dbd2bad023c69f3cf3d1ef (diff) |
Make TreeDefinition.Add() able to cope with files
-rw-r--r-- | LibGit2Sharp.Tests/ObjectDatabaseFixture.cs | 33 | ||||
-rw-r--r-- | LibGit2Sharp/TreeDefinition.cs | 34 | ||||
-rw-r--r-- | LibGit2Sharp/TreeEntryDefinition.cs | 21 |
3 files changed, 87 insertions, 1 deletions
diff --git a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs index b5e1735c..f7b83f42 100644 --- a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs +++ b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs @@ -149,5 +149,38 @@ namespace LibGit2Sharp.Tests Assert.Equal(GitObjectType.Tree, td["1/tree"].Type); } } + + [Fact] + public void CanCreateATreeContainingABlobFromAFileInTheWorkingDirectory() + { + TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath); + + using (var repo = new Repository(scd.DirectoryPath)) + { + Assert.Equal(FileStatus.Nonexistent, repo.Index.RetrieveStatus("hello.txt")); + File.AppendAllText(Path.Combine(repo.Info.WorkingDirectory, "hello.txt"), "I'm a new file\n"); + + TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree) + .Add("1/new file", "hello.txt", Mode.NonExecutableFile); + + TreeEntryDefinition ted = td["1/new file"]; + Assert.NotNull(ted); + Assert.Equal(ObjectId.Zero, ted.TargetId); + + td.Add("1/2/another new file", ted); + + Tree tree = repo.ObjectDatabase.CreateTree(td); + + TreeEntry te = tree["1/new file"]; + Assert.NotNull(te.Target); + Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", te.Target.Sha); + Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", td["1/new file"].TargetId.Sha); + + te = tree["1/2/another new file"]; + Assert.NotNull(te.Target); + Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", te.Target.Sha); + Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", td["1/2/another new file"].TargetId.Sha); + } + } } } diff --git a/LibGit2Sharp/TreeDefinition.cs b/LibGit2Sharp/TreeDefinition.cs index e781ab11..75d18b80 100644 --- a/LibGit2Sharp/TreeDefinition.cs +++ b/LibGit2Sharp/TreeDefinition.cs @@ -140,6 +140,22 @@ namespace LibGit2Sharp } /// <summary> + /// Adds or replaces a <see cref="TreeEntryDefinition"/>, dynamically built from the content of the file, at the specified <paramref name="targetTreeEntryPath"/> location. + /// </summary> + /// <param name="targetTreeEntryPath">The path within this <see cref="TreeDefinition"/>.</param> + /// <param name="filePath">The path to the file from which a <see cref="Blob"/> will be built and stored at the described location.</param> + /// <param name="mode">The file related <see cref="Mode"/> attributes.</param> + /// <returns>The current <see cref="TreeDefinition"/>.</returns> + public TreeDefinition Add(string targetTreeEntryPath, string filePath, Mode mode) + { + Ensure.ArgumentNotNullOrEmptyString(filePath, "filePath"); + + TreeEntryDefinition ted = TreeEntryDefinition.TransientBlobFrom(filePath, mode); + + return Add(targetTreeEntryPath, ted); + } + + /// <summary> /// Adds or replaces a <see cref="TreeEntryDefinition"/>, dynamically built from the provided <see cref="Tree"/>, at the specified <paramref name="targetTreeEntryPath"/> location. /// </summary> /// <param name="targetTreeEntryPath">The path within this <see cref="TreeDefinition"/>.</param> @@ -209,14 +225,30 @@ namespace LibGit2Sharp using (var builder = new TreeBuilder()) { + var builtTreeEntryDefinitions = new List<Tuple<string, TreeEntryDefinition>>(); + foreach (KeyValuePair<string, TreeEntryDefinition> kvp in entries) { string name = kvp.Key; TreeEntryDefinition ted = kvp.Value; - builder.Insert(name, ted); + var transient = ted as TransientBlobTreeEntryDefinition; + + if (transient == null) + { + builder.Insert(name, ted); + continue; + } + + Blob blob = transient.Builder(repository.ObjectDatabase); + TreeEntryDefinition ted2 = TreeEntryDefinition.From(blob, ted.Mode); + builtTreeEntryDefinitions.Add(new Tuple<string, TreeEntryDefinition>(name, ted2)); + + builder.Insert(name, ted2); } + builtTreeEntryDefinitions.ForEach(t => entries[t.Item1] = t.Item2); + ObjectId treeId = builder.Write(repository); return repository.Lookup<Tree>(treeId); } diff --git a/LibGit2Sharp/TreeEntryDefinition.cs b/LibGit2Sharp/TreeEntryDefinition.cs index ecb2a6a5..969ad7b3 100644 --- a/LibGit2Sharp/TreeEntryDefinition.cs +++ b/LibGit2Sharp/TreeEntryDefinition.cs @@ -60,6 +60,17 @@ namespace LibGit2Sharp }; } + internal static TreeEntryDefinition TransientBlobFrom(string filePath, Mode mode) + { + Ensure.ArgumentConformsTo(mode, m => m.HasAny(new[] { Mode.NonExecutableFile, Mode.ExecutableFile, Mode.NonExecutableGroupWriteableFile }), "mode"); + + return new TransientBlobTreeEntryDefinition + { + Builder = odb => odb.CreateBlob(filePath), + Mode = mode, + }; + } + internal static TreeEntryDefinition From(Tree tree) { return new TreeEntryDefinition @@ -148,4 +159,14 @@ namespace LibGit2Sharp get { return GitObjectType.Tree; } } } + + internal class TransientBlobTreeEntryDefinition : TransientTreeEntryDefinition + { + public override GitObjectType Type + { + get { return GitObjectType.Blob; } + } + + public Func<ObjectDatabase, Blob> Builder { get; set; } + } } |