Skip to content

Commit 9a0a9e7

Browse files
authored
Merge pull request #1522 from libgit2/ethomson/0241_backports
Backports to 0.24.1
2 parents e656b51 + c85f98c commit 9a0a9e7

File tree

8 files changed

+151
-37
lines changed

8 files changed

+151
-37
lines changed

CHANGES.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010
- Windows (x86/amd64): <https://ci.appveyor.com/project/libgit2/libgit2sharp>
1111
- Linux/Mac OS X: <https://travis-ci.org/libgit2/libgit2sharp>
1212

13-
## v0.24 + 1
13+
## v0.24.1
1414

1515
### Additions
1616

17+
- `TreeDefinition.Add` can now add a blob to a tree when given its object ID.
18+
- `ObjectDatabase.Write` can now take a readable `Stream` to support writing
19+
large files to the object database.
20+
1721
### Changes
1822

1923
### Fixes

LibGit2Sharp.Tests/ObjectDatabaseFixture.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,31 @@ public void CanCreateABlobFromAStream(string expectedSha, string hintPath)
121121
}
122122
}
123123

124+
[Fact]
125+
public void CanWriteABlobFromAByteArray()
126+
{
127+
var ba = Encoding.ASCII.GetBytes("libgit2\r\n");
128+
129+
using (var repo = new Repository(InitNewRepository()))
130+
{
131+
var id = repo.ObjectDatabase.Write<Blob>(ba);
132+
Assert.Equal(new ObjectId("99115ea359379a218c47cffc83cd0af8c91c4061"), id);
133+
}
134+
}
135+
136+
[Fact]
137+
public void CanWriteABlobFromAStream()
138+
{
139+
var ba = Encoding.ASCII.GetBytes("libgit2\r\n");
140+
141+
using (var stream = new MemoryStream(ba))
142+
using (var repo = new Repository(InitNewRepository()))
143+
{
144+
var id = repo.ObjectDatabase.Write<Blob>(stream, stream.Length);
145+
Assert.Equal(new ObjectId("99115ea359379a218c47cffc83cd0af8c91c4061"), id);
146+
}
147+
}
148+
124149
Stream PrepareMemoryStream(int contentSize)
125150
{
126151
var sb = new StringBuilder();

LibGit2Sharp.Tests/TreeDefinitionFixture.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,49 @@ public void CanAddAnExistingBlob(string blobSha, string targetPath)
222222
}
223223
}
224224

225+
[Theory]
226+
[InlineData("a8233120f6ad708f843d861ce2b7228ec4e3dec6", "README_TOO")]
227+
[InlineData("a8233120f6ad708f843d861ce2b7228ec4e3dec6", "1/README")]
228+
[InlineData("45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "1/another_one.txt")]
229+
[InlineData("45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "another_one.txt")]
230+
public void CanAddBlobById(string blobSha, string targetPath)
231+
{
232+
string path = SandboxBareTestRepo();
233+
using (var repo = new Repository(path))
234+
{
235+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
236+
Assert.Null(td[targetPath]);
237+
238+
var objectId = new ObjectId(blobSha);
239+
240+
td.Add(targetPath, objectId, Mode.NonExecutableFile);
241+
242+
TreeEntryDefinition fetched = td[targetPath];
243+
Assert.NotNull(fetched);
244+
245+
Assert.Equal(objectId, fetched.TargetId);
246+
Assert.Equal(Mode.NonExecutableFile, fetched.Mode);
247+
}
248+
}
249+
250+
[Fact]
251+
public void CannotAddTreeById()
252+
{
253+
const string treeSha = "7f76480d939dc401415927ea7ef25c676b8ddb8f";
254+
const string targetPath = "1/2";
255+
256+
string path = SandboxBareTestRepo();
257+
using (var repo = new Repository(path))
258+
{
259+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
260+
Assert.Null(td[targetPath]);
261+
262+
var objectId = new ObjectId(treeSha);
263+
264+
Assert.Throws<ArgumentException>(() => td.Add(targetPath, objectId, Mode.Directory));
265+
}
266+
}
267+
225268
[Fact]
226269
public void CanAddAnExistingSubmodule()
227270
{

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public int Provider(IntPtr content, int max_length, IntPtr data)
178178
}
179179

180180
/// <summary>
181-
/// Write an object to the object database
181+
/// Writes an object to the object database.
182182
/// </summary>
183183
/// <param name="data">The contents of the object</param>
184184
/// <typeparam name="T">The type of object to write</typeparam>
@@ -187,6 +187,45 @@ public virtual ObjectId Write<T>(byte[] data) where T : GitObject
187187
return Proxy.git_odb_write(handle, data, GitObject.TypeToKindMap[typeof(T)]);
188188
}
189189

190+
/// <summary>
191+
/// Writes an object to the object database.
192+
/// </summary>
193+
/// <param name="stream">The contents of the object</param>
194+
/// <param name="numberOfBytesToConsume">The number of bytes to consume from the stream</param>
195+
/// <typeparam name="T">The type of object to write</typeparam>
196+
public virtual ObjectId Write<T>(Stream stream, long numberOfBytesToConsume) where T : GitObject
197+
{
198+
Ensure.ArgumentNotNull(stream, "stream");
199+
200+
if (!stream.CanRead)
201+
{
202+
throw new ArgumentException("The stream cannot be read from.", "stream");
203+
}
204+
205+
using (var odbStream = Proxy.git_odb_open_wstream(handle, numberOfBytesToConsume, GitObjectType.Blob))
206+
{
207+
var buffer = new byte[4 * 1024];
208+
long totalRead = 0;
209+
210+
while (totalRead < numberOfBytesToConsume)
211+
{
212+
long left = numberOfBytesToConsume - totalRead;
213+
int toRead = left < buffer.Length ? (int)left : buffer.Length;
214+
var read = stream.Read(buffer, 0, toRead);
215+
216+
if (read == 0)
217+
{
218+
throw new EndOfStreamException("The stream ended unexpectedly");
219+
}
220+
221+
Proxy.git_odb_stream_write(odbStream, buffer, read);
222+
totalRead += read;
223+
}
224+
225+
return Proxy.git_odb_stream_finalize_write(odbStream);
226+
}
227+
}
228+
190229
/// <summary>
191230
/// Inserts a <see cref="Blob"/> into the object database, created from the content of a stream.
192231
/// <para>Optionally, git filters will be applied to the content before storing it.</para>
@@ -294,37 +333,8 @@ private unsafe Blob CreateBlob(Stream stream, string hintpath, long? numberOfByt
294333
/// <returns>The created <see cref="Blob"/>.</returns>
295334
public virtual Blob CreateBlob(Stream stream, long numberOfBytesToConsume)
296335
{
297-
Ensure.ArgumentNotNull(stream, "stream");
298-
299-
if (!stream.CanRead)
300-
{
301-
throw new ArgumentException("The stream cannot be read from.", "stream");
302-
}
303-
304-
using (var odbStream = Proxy.git_odb_open_wstream(handle, numberOfBytesToConsume, GitObjectType.Blob))
305-
{
306-
var buffer = new byte[4 * 1024];
307-
long totalRead = 0;
308-
309-
while (totalRead < numberOfBytesToConsume)
310-
{
311-
long left = numberOfBytesToConsume - totalRead;
312-
int toRead = left < buffer.Length ? (int)left : buffer.Length;
313-
var read = stream.Read(buffer, 0, toRead);
314-
315-
if (read == 0)
316-
{
317-
throw new EndOfStreamException("The stream ended unexpectedly");
318-
}
319-
320-
Proxy.git_odb_stream_write(odbStream, buffer, read);
321-
totalRead += read;
322-
}
323-
324-
var id = Proxy.git_odb_stream_finalize_write(odbStream);
325-
326-
return repo.Lookup<Blob>(id);
327-
}
336+
var id = Write<Blob>(stream, numberOfBytesToConsume);
337+
return repo.Lookup<Blob>(id);
328338
}
329339

330340
/// <summary>

LibGit2Sharp/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@
4242
// by using the '*' as shown below:
4343
// [assembly: AssemblyVersion("1.0.*")]
4444

45-
[assembly: AssemblyVersion("0.24.0")]
46-
[assembly: AssemblyFileVersion("0.24.0")]
47-
[assembly: AssemblyInformationalVersion("0.24.0-dev00000000000000")]
45+
[assembly: AssemblyVersion("0.24.1")]
46+
[assembly: AssemblyFileVersion("0.24.1")]
47+
[assembly: AssemblyInformationalVersion("0.24.1-dev00000000000000")]

LibGit2Sharp/TreeDefinition.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,23 @@ public virtual TreeDefinition Add(string targetTreeEntryPath, string filePath, M
206206
return Add(targetTreeEntryPath, ted);
207207
}
208208

209+
/// <summary>
210+
/// Adds or replaces a <see cref="TreeEntryDefinition"/> from an existing blob specified by its Object ID at the specified <paramref name="targetTreeEntryPath"/> location.
211+
/// </summary>
212+
/// <param name="targetTreeEntryPath">The path within this <see cref="TreeDefinition"/>.</param>
213+
/// <param name="id">The object ID for this entry.</param>
214+
/// <param name="mode">The file related <see cref="Mode"/> attributes.</param>
215+
/// <returns>The current <see cref="TreeDefinition"/>.</returns>
216+
public virtual TreeDefinition Add(string targetTreeEntryPath, ObjectId id, Mode mode)
217+
{
218+
Ensure.ArgumentNotNull(id, "id");
219+
Ensure.ArgumentConformsTo(mode, m => m.HasAny(TreeEntryDefinition.BlobModes), "mode");
220+
221+
TreeEntryDefinition ted = TreeEntryDefinition.From(id, mode);
222+
223+
return Add(targetTreeEntryPath, ted);
224+
}
225+
209226
/// <summary>
210227
/// Adds or replaces a <see cref="TreeEntryDefinition"/>, dynamically built from the provided <see cref="Tree"/>, at the specified <paramref name="targetTreeEntryPath"/> location.
211228
/// </summary>

LibGit2Sharp/TreeEntryDefinition.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ internal static TreeEntryDefinition From(TreeEntry treeEntry)
5454

5555
internal static TreeEntryDefinition From(Blob blob, Mode mode)
5656
{
57+
Ensure.ArgumentNotNull(blob, "blob");
58+
5759
return new TreeEntryDefinition
5860
{
5961
Mode = mode,
@@ -63,6 +65,19 @@ internal static TreeEntryDefinition From(Blob blob, Mode mode)
6365
};
6466
}
6567

68+
internal static TreeEntryDefinition From(ObjectId id, Mode mode)
69+
{
70+
Ensure.ArgumentNotNull(id, "id");
71+
Ensure.ArgumentNotNull(mode, "mode");
72+
73+
return new TreeEntryDefinition
74+
{
75+
Mode = mode,
76+
TargetType = TreeEntryTargetType.Blob,
77+
TargetId = id
78+
};
79+
}
80+
6681
internal static TreeEntryDefinition TransientBlobFrom(string filePath, Mode mode)
6782
{
6883
Ensure.ArgumentConformsTo(mode, m => m.HasAny(BlobModes), "mode");

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ environment:
1818
secure: nuzUT+HecXGIi3KaPd/1hgFEZJan/j6+oNbPV75JKjk=
1919
coverity_email:
2020
secure: eGVilNg1Yuq+Xj+SW8r3WCtjnzhoDV0sNJkma4NRq7A=
21-
version : 0.24.0
21+
version : 0.24.1
2222
matrix:
2323
- xunit_runner: xunit.console.x86.exe
2424
Arch: 32

0 commit comments

Comments
 (0)