Skip to content

Commit 561afc3

Browse files
author
Edward Thomson
committed
Repository: add ctor for in-memory repo
1 parent 1a815ac commit 561afc3

File tree

5 files changed

+87
-17
lines changed

5 files changed

+87
-17
lines changed

LibGit2Sharp.Tests/RepositoryFixture.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,5 +652,18 @@ public void CanDetectShallowness()
652652
Assert.False(repo.Info.IsShallow);
653653
}
654654
}
655+
656+
[Fact]
657+
public void CanCreateInMemoryRepository()
658+
{
659+
using (var repo = new Repository())
660+
{
661+
Assert.True(repo.Info.IsBare);
662+
Assert.Null(repo.Info.Path);
663+
Assert.Null(repo.Info.WorkingDirectory);
664+
665+
Assert.Throws<BareRepositoryException>(() => { var idx = repo.Index; });
666+
}
667+
}
655668
}
656669
}

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,10 @@ internal static extern int git_repository_message(
11931193
GitBuf buf,
11941194
RepositorySafeHandle repository);
11951195

1196+
[DllImport(libgit2)]
1197+
internal static extern int git_repository_new(
1198+
out RepositorySafeHandle repository);
1199+
11961200
[DllImport(libgit2)]
11971201
internal static extern int git_repository_odb(out ObjectDatabaseSafeHandle odb, RepositorySafeHandle repo);
11981202

LibGit2Sharp/Core/Proxy.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,19 @@ public static string git_repository_message(RepositorySafeHandle repo)
23452345
}
23462346
}
23472347

2348+
public static RepositorySafeHandle git_repository_new()
2349+
{
2350+
using (ThreadAffinity())
2351+
{
2352+
RepositorySafeHandle repo;
2353+
2354+
int res = NativeMethods.git_repository_new(out repo);
2355+
Ensure.ZeroResult(res);
2356+
2357+
return repo;
2358+
}
2359+
}
2360+
23482361
public static ObjectDatabaseSafeHandle git_repository_odb(RepositorySafeHandle repo)
23492362
{
23502363
using (ThreadAffinity())

LibGit2Sharp/Repository.cs

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,25 @@ public sealed class Repository : IRepository
3737
private readonly SubmoduleCollection submodules;
3838
private readonly Lazy<PathCase> pathCase;
3939

40+
private enum RepositoryRequiredParameter
41+
{
42+
None = 0,
43+
Path = 1,
44+
Options = 2,
45+
}
46+
47+
/// <summary>
48+
/// Initializes a new instance of the <see cref="Repository"/> class
49+
/// that does not point to an on-disk Git repository. This is
50+
/// suitable only for custom, in-memory Git repositories that are
51+
/// configured with custom object database, reference database and/or
52+
/// configuration backends.
53+
/// </summary>
54+
public Repository()
55+
: this(null, null, RepositoryRequiredParameter.None)
56+
{
57+
}
58+
4059
/// <summary>
4160
/// Initializes a new instance of the <see cref="Repository"/> class.
4261
/// <para>For a standard repository, <paramref name="path"/> may
@@ -51,7 +70,7 @@ public sealed class Repository : IRepository
5170
/// or the path to the working directory.
5271
/// </param>
5372
public Repository(string path) :
54-
this(path, null)
73+
this(path, null, RepositoryRequiredParameter.Path)
5574
{
5675
}
5776

@@ -73,9 +92,22 @@ public Repository(string path) :
7392
/// <param name="options">
7493
/// Overrides to the way a repository is opened.
7594
/// </param>
76-
public Repository(string path, RepositoryOptions options)
95+
public Repository(string path, RepositoryOptions options) :
96+
this(path, options, RepositoryRequiredParameter.Path | RepositoryRequiredParameter.Options)
7797
{
78-
Ensure.ArgumentNotNullOrEmptyString(path, "path");
98+
}
99+
100+
private Repository(string path, RepositoryOptions options, RepositoryRequiredParameter requiredParameter)
101+
{
102+
if ((requiredParameter & RepositoryRequiredParameter.Path) == RepositoryRequiredParameter.Path)
103+
{
104+
Ensure.ArgumentNotNullOrEmptyString(path, "path");
105+
}
106+
107+
if ((requiredParameter & RepositoryRequiredParameter.Options) == RepositoryRequiredParameter.Options)
108+
{
109+
Ensure.ArgumentNotNull(options, "options");
110+
}
79111

80112
try
81113
{
@@ -84,6 +116,14 @@ public Repository(string path, RepositoryOptions options)
84116

85117
isBare = Proxy.git_repository_is_bare(handle);
86118

119+
/* TODO: bug in libgit2, update when fixed by
120+
* https://github.com/libgit2/libgit2/pull/2970
121+
*/
122+
if (path == null)
123+
{
124+
isBare = true;
125+
}
126+
87127
Func<Index> indexBuilder = () => new Index(this);
88128

89129
string configurationGlobalFilePath = null;
@@ -764,7 +804,7 @@ private void CheckoutTree(
764804
IConvertableToGitCheckoutOpts opts)
765805
{
766806

767-
using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(opts, ToFilePaths(paths)))
807+
using(GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(opts, ToFilePaths(paths)))
768808
{
769809
var options = checkoutOptionsWrapper.Options;
770810
Proxy.git_checkout_tree(Handle, tree.Id, ref options);
@@ -935,7 +975,7 @@ private void UpdateHeadAndTerminalReference(Commit commit, string reflogMessage)
935975
return;
936976
}
937977

938-
var symRef = (SymbolicReference)reference;
978+
var symRef = (SymbolicReference) reference;
939979

940980
reference = symRef.Target;
941981

@@ -1294,7 +1334,7 @@ private MergeResult Merge(GitAnnotatedCommitHandle[] annotatedCommits, Signature
12941334
FastForwardStrategy fastForwardStrategy = (options.FastForwardStrategy != FastForwardStrategy.Default) ?
12951335
options.FastForwardStrategy : FastForwardStrategyFromMergePreference(mergePreference);
12961336

1297-
switch (fastForwardStrategy)
1337+
switch(fastForwardStrategy)
12981338
{
12991339
case FastForwardStrategy.Default:
13001340
if (mergeAnalysis.HasFlag(GitMergeAnalysis.GIT_MERGE_ANALYSIS_FASTFORWARD))
@@ -1362,14 +1402,14 @@ private MergeResult NormalMerge(GitAnnotatedCommitHandle[] annotatedCommits, Sig
13621402
MergeResult mergeResult;
13631403

13641404
var mergeOptions = new GitMergeOpts
1365-
{
1366-
Version = 1,
1367-
MergeFileFavorFlags = options.MergeFileFavor,
1368-
MergeTreeFlags = options.FindRenames ? GitMergeTreeFlags.GIT_MERGE_TREE_FIND_RENAMES :
1369-
GitMergeTreeFlags.GIT_MERGE_TREE_NORMAL,
1370-
RenameThreshold = (uint)options.RenameThreshold,
1371-
TargetLimit = (uint)options.TargetLimit,
1372-
};
1405+
{
1406+
Version = 1,
1407+
MergeFileFavorFlags = options.MergeFileFavor,
1408+
MergeTreeFlags = options.FindRenames ? GitMergeTreeFlags.GIT_MERGE_TREE_FIND_RENAMES :
1409+
GitMergeTreeFlags.GIT_MERGE_TREE_NORMAL,
1410+
RenameThreshold = (uint) options.RenameThreshold,
1411+
TargetLimit = (uint) options.TargetLimit,
1412+
};
13731413

13741414
using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options))
13751415
{
@@ -1407,7 +1447,7 @@ private MergeResult NormalMerge(GitAnnotatedCommitHandle[] annotatedCommits, Sig
14071447
private MergeResult FastForwardMerge(GitAnnotatedCommitHandle annotatedCommit, Signature merger, MergeOptions options)
14081448
{
14091449
ObjectId id = Proxy.git_annotated_commit_id(annotatedCommit);
1410-
Commit fastForwardCommit = (Commit)Lookup(id, ObjectType.Commit);
1450+
Commit fastForwardCommit = (Commit) Lookup(id, ObjectType.Commit);
14111451
Ensure.GitObjectIsNotNull(fastForwardCommit, id.Sha);
14121452

14131453
CheckoutTree(fastForwardCommit.Tree, null, new FastForwardCheckoutOptionsAdapter(options));
@@ -1882,7 +1922,7 @@ private IEnumerable<string> RemoveStagedItems(IEnumerable<string> paths, bool re
18821922
case ChangeKind.Unmodified:
18831923
if (removeFromWorkingDirectory && (
18841924
status.HasFlag(FileStatus.Staged) ||
1885-
status.HasFlag(FileStatus.Added)))
1925+
status.HasFlag(FileStatus.Added) ))
18861926
{
18871927
throw new RemoveFromIndexException(string.Format(CultureInfo.InvariantCulture, "Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.",
18881928
treeEntryChanges.Path));

LibGit2Sharp/RepositoryInformation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal RepositoryInformation(Repository repo, bool isBare)
2424
FilePath path = Proxy.git_repository_path(repo.Handle);
2525
FilePath workingDirectoryPath = Proxy.git_repository_workdir(repo.Handle);
2626

27-
Path = path.Native;
27+
Path = path == null ? null : path.Native;
2828
WorkingDirectory = workingDirectoryPath == null ? null : workingDirectoryPath.Native;
2929
IsShallow = Proxy.git_repository_is_shallow(repo.Handle);
3030
}

0 commit comments

Comments
 (0)