Skip to content

Commit 05cc6bd

Browse files
committed
Add TreeDefinition.Add(path, gitLink)
1 parent 07419b2 commit 05cc6bd

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

LibGit2Sharp.Tests/TreeDefinitionFixture.cs

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,27 @@ public void CanAddAnExistingTreeEntryDefinition(string sourcePath, string target
111111
}
112112
}
113113

114+
[Fact]
115+
public void CanAddAnExistingGitLinkTreeEntryDefinition()
116+
{
117+
const string sourcePath = "sm_unchanged";
118+
const string targetPath = "sm_from_td";
119+
120+
using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath))
121+
{
122+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
123+
Assert.Null(td[targetPath]);
124+
125+
TreeEntryDefinition ted = td[sourcePath];
126+
td.Add(targetPath, ted);
127+
128+
TreeEntryDefinition fetched = td[targetPath];
129+
Assert.NotNull(fetched);
130+
131+
Assert.Equal(ted, fetched);
132+
}
133+
}
134+
114135
[Theory]
115136
[InlineData("a8233120f6ad708f843d861ce2b7228ec4e3dec6", "README_TOO")]
116137
[InlineData("a8233120f6ad708f843d861ce2b7228ec4e3dec6", "1/README")]
@@ -136,6 +157,29 @@ public void CanAddAnExistingBlob(string blobSha, string targetPath)
136157
}
137158
}
138159

160+
[Fact]
161+
public void CanAddAnExistingGitLink()
162+
{
163+
const string targetPath = "sm_from_td";
164+
165+
using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath))
166+
{
167+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
168+
Assert.Null(td[targetPath]);
169+
170+
var gitLink = repo.Submodules["sm_unchanged"].GitLink;
171+
172+
td.Add(targetPath, gitLink);
173+
174+
TreeEntryDefinition fetched = td[targetPath];
175+
Assert.NotNull(fetched);
176+
177+
Assert.Equal(gitLink.Id, fetched.TargetId);
178+
Assert.Equal(GitObjectType.Commit, fetched.Type);
179+
Assert.Equal(Mode.GitLink, fetched.Mode);
180+
}
181+
}
182+
139183
[Fact]
140184
public void CanAddAnExistingTree()
141185
{
@@ -217,6 +261,111 @@ public void CanReplaceAnExistingBlobWithATree(string targetPath)
217261
}
218262
}
219263

264+
[Fact]
265+
public void CanReplaceAnExistingTreeWithAGitLink()
266+
{
267+
const string targetPath = "just_a_dir";
268+
269+
using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath))
270+
{
271+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
272+
Assert.Equal(GitObjectType.Tree, td[targetPath].Type);
273+
274+
var gitLink = repo.Submodules["sm_unchanged"].GitLink;
275+
276+
Assert.NotNull(td["just_a_dir/contents"]);
277+
278+
td.Add(targetPath, gitLink);
279+
280+
TreeEntryDefinition fetched = td[targetPath];
281+
Assert.NotNull(fetched);
282+
283+
Assert.Equal(gitLink.Id, fetched.TargetId);
284+
Assert.Equal(GitObjectType.Commit, fetched.Type);
285+
Assert.Equal(Mode.GitLink, fetched.Mode);
286+
287+
Assert.Null(td["just_a_dir/contents"]);
288+
}
289+
}
290+
291+
[Fact]
292+
public void CanReplaceAnExistingGitLinkWithATree()
293+
{
294+
const string treeSha = "607d96653d4d0a4f733107f7890c2e67b55b620d";
295+
const string targetPath = "sm_unchanged";
296+
297+
using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath))
298+
{
299+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
300+
Assert.NotNull(td[targetPath]);
301+
Assert.Equal(GitObjectType.Commit, td[targetPath].Type);
302+
Assert.Equal(Mode.GitLink, td[targetPath].Mode);
303+
304+
var objectId = new ObjectId(treeSha);
305+
var tree = repo.Lookup<Tree>(objectId);
306+
307+
td.Add(targetPath, tree);
308+
309+
TreeEntryDefinition fetched = td[targetPath];
310+
Assert.NotNull(fetched);
311+
312+
Assert.Equal(objectId, fetched.TargetId);
313+
Assert.Equal(GitObjectType.Tree, fetched.Type);
314+
Assert.Equal(Mode.Directory, fetched.Mode);
315+
}
316+
}
317+
318+
[Fact]
319+
public void CanReplaceAnExistingBlobWithAGitLink()
320+
{
321+
const string targetPath = "just_a_file";
322+
323+
using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath))
324+
{
325+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
326+
Assert.NotNull(td[targetPath]);
327+
Assert.Equal(GitObjectType.Blob, td[targetPath].Type);
328+
329+
var gitLink = repo.Submodules["sm_unchanged"].GitLink;
330+
331+
td.Add(targetPath, gitLink);
332+
333+
TreeEntryDefinition fetched = td[targetPath];
334+
Assert.NotNull(fetched);
335+
336+
Assert.Equal(GitObjectType.Commit, td[targetPath].Type);
337+
Assert.Equal(gitLink.Id, fetched.TargetId);
338+
Assert.Equal(Mode.GitLink, fetched.Mode);
339+
}
340+
}
341+
342+
[Fact]
343+
public void CanReplaceAnExistingGitLinkWithABlob()
344+
{
345+
const string blobSha = "42cfb95cd01bf9225b659b5ee3edcc78e8eeb478";
346+
const string targetPath = "sm_unchanged";
347+
348+
using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath))
349+
{
350+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
351+
Assert.NotNull(td[targetPath]);
352+
Assert.Equal(GitObjectType.Commit, td[targetPath].Type);
353+
Assert.Equal(Mode.GitLink, td[targetPath].Mode);
354+
355+
var objectId = new ObjectId(blobSha);
356+
var blob = repo.Lookup<Blob>(objectId);
357+
358+
td.Add(targetPath, blob, Mode.NonExecutableFile);
359+
360+
TreeEntryDefinition fetched = td[targetPath];
361+
Assert.NotNull(fetched);
362+
363+
Assert.Equal(objectId, fetched.TargetId);
364+
Assert.Equal(GitObjectType.Blob, fetched.Type);
365+
Assert.Equal(Mode.NonExecutableFile, fetched.Mode);
366+
}
367+
}
368+
220369
[Fact]
221370
public void CanNotReplaceAnExistingTreeWithATreeBeingAssembled()
222371
{

LibGit2Sharp/TreeDefinition.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,21 @@ public virtual TreeDefinition Add(string targetTreeEntryPath, string filePath, M
159159
return Add(targetTreeEntryPath, ted);
160160
}
161161

162+
/// <summary>
163+
/// Adds or replaces a <see cref="TreeEntryDefinition"/>, dynamically built from the provided <see cref="GitLink"/>, at the specified <paramref name="targetTreeEntryPath"/> location.
164+
/// </summary>
165+
/// <param name="targetTreeEntryPath">The path within this <see cref="TreeDefinition"/>.</param>
166+
/// <param name="gitLink">The <see cref="GitLink"/> to be stored at the described location.</param>
167+
/// <returns>The current <see cref="TreeDefinition"/>.</returns>
168+
public virtual TreeDefinition Add(string targetTreeEntryPath, GitLink gitLink)
169+
{
170+
Ensure.ArgumentNotNull(gitLink, "gitLink");
171+
172+
var ted = TreeEntryDefinition.From(gitLink.Id);
173+
174+
return Add(targetTreeEntryPath, ted);
175+
}
176+
162177
/// <summary>
163178
/// Adds or replaces a <see cref="TreeEntryDefinition"/>, dynamically built from the provided <see cref="Tree"/>, at the specified <paramref name="targetTreeEntryPath"/> location.
164179
/// </summary>
@@ -195,6 +210,7 @@ private TreeDefinition RetrieveOrBuildTreeDefinition(string treeName, bool shoul
195210
break;
196211

197212
case GitObjectType.Blob:
213+
case GitObjectType.Commit:
198214
if (shouldOverWrite)
199215
{
200216
td = new TreeDefinition();

LibGit2Sharp/TreeEntryDefinition.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ internal static TreeEntryDefinition TransientBlobFrom(string filePath, Mode mode
7676
};
7777
}
7878

79+
internal static TreeEntryDefinition From(ObjectId objectId)
80+
{
81+
return new TreeEntryDefinition
82+
{
83+
Mode = Mode.GitLink,
84+
Type = GitObjectType.Commit,
85+
TargetId = objectId,
86+
target = new Lazy<GitObject>(() => { throw new InvalidOperationException("Shouldn't be necessary."); }),
87+
};
88+
}
89+
7990
internal static TreeEntryDefinition From(Tree tree)
8091
{
8192
return new TreeEntryDefinition

0 commit comments

Comments
 (0)