Skip to content

Commit

Permalink
#100 Get object from commitOperation
Browse files Browse the repository at this point in the history
  • Loading branch information
gaufung committed Dec 6, 2020
1 parent bf57631 commit acf2eda
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 172 deletions.
40 changes: 40 additions & 0 deletions src/Ugit/Operations/DefaultCommitOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,46 @@ public IEnumerable<string> GetCommitHistory(IEnumerable<string> oids)
}
}

public IEnumerable<string> GetObjectHistory(IEnumerable<string> oids)
{
HashSet<string> visited = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

IEnumerable<string> IterObjectInTree(string oid)
{
visited.Add(oid);
yield return oid;

foreach (var (type, subOid, _) in this.treeOperation.IterTreeEntry(oid))
{
if (type == Constants.Tree)
{
foreach(var val in IterObjectInTree(subOid))
{
yield return val;
}
}
else
{
visited.Add(subOid);
yield return subOid;
}
}
}

foreach(var oid in GetCommitHistory(oids))
{
yield return oid;
var commit = GetCommit(oid);
if (!visited.Contains(commit.Tree))
{
foreach(var val in IterObjectInTree(commit.Tree))
{
yield return val;
}
}
}
}

private void CommitValidate()
{
string HEAD = this.dataProvider.GetRef(Constants.HEAD).Value;
Expand Down
55 changes: 3 additions & 52 deletions src/Ugit/Operations/DefaultRemoteOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ internal class DefaultRemoteOperation : IRemoteOperation
private static readonly string RemoteRefsBase = Path.Join(Constants.Refs, Constants.Heads);
private static readonly string LocalRefsBase = Path.Join(Constants.Refs, Constants.Remote);
private readonly IDataProvider localDataProvider;
private readonly ITreeOperation localTreeOperation;
private readonly ICommitOperation localCommitOperation;
private readonly IDataProvider remoteDataProvider;
private readonly ICommitOperation remoteCommitOperation;
private readonly ITreeOperation remoteTreeOperation;

/// <summary>
/// Initializes a new instance of the <see cref="DefaultRemoteOperation"/> class.
Expand All @@ -30,26 +28,21 @@ internal class DefaultRemoteOperation : IRemoteOperation
/// <param name="remoteCommitOperation">remote commit operation.</param>
public DefaultRemoteOperation(
IDataProvider localDataProvider,
ITreeOperation localTreeOperation,
ICommitOperation localCommitOpeartion,
IDataProvider remoteDataProvider,
ITreeOperation remoteTreeOperation,
ICommitOperation remoteCommitOperation)
{
this.localDataProvider = localDataProvider;
this.localTreeOperation = localTreeOperation;
this.localCommitOperation = localCommitOpeartion;
this.remoteDataProvider = remoteDataProvider;
this.remoteTreeOperation = remoteTreeOperation;
this.remoteCommitOperation = remoteCommitOperation;
}

/// <inheritdoc/>
public void Fetch()
{
var refs = this.remoteDataProvider.GetRefsMapping(RemoteRefsBase);
foreach (var oid in this.IterObjectsInCommits(
this.remoteTreeOperation, this.remoteCommitOperation, refs.Values))
foreach (var oid in this.remoteCommitOperation.GetObjectHistory(refs.Values))
{
this.FetchObjectIfMissing(oid);
}
Expand Down Expand Up @@ -77,8 +70,8 @@ public void Push(string refName)
}

IEnumerable<string> knowRemoteRefs = remoteRefs.Values.Where(oid => this.localDataProvider.ObjectExist(oid));
HashSet<string> remoteObjects = new HashSet<string>(this.IterObjectsInCommits(this.localTreeOperation, this.localCommitOperation, knowRemoteRefs));
HashSet<string> localObjects = new HashSet<string>(this.IterObjectsInCommits(this.localTreeOperation, this.localCommitOperation, new[] { localRef }));
HashSet<string> remoteObjects = new HashSet<string>(this.localCommitOperation.GetObjectHistory(knowRemoteRefs));
HashSet<string> localObjects = new HashSet<string>(this.localCommitOperation.GetObjectHistory(new[] { localRef }));
IEnumerable<string> objectsToPush = localObjects.Except(remoteObjects);
foreach (var oid in objectsToPush)
{
Expand All @@ -88,48 +81,6 @@ public void Push(string refName)
this.remoteDataProvider.UpdateRef(refName, RefValue.Create(false, localRef));
}

private IEnumerable<string> IterObjectsInCommits(ITreeOperation treeOpeation, ICommitOperation commitOpeartion, IEnumerable<string> oids)
{
HashSet<string> visited = new HashSet<string>();
IEnumerable<string> IterObjectsInTree(string oid)
{
visited.Add(oid);
yield return oid;

foreach (var (type, subOid, _) in treeOpeation.IterTreeEntry(oid))
{
if (!visited.Contains(subOid))
{
if (type == Constants.Tree)
{
foreach (var val in IterObjectsInTree(subOid))
{
yield return val;
}
}
else
{
visited.Add(subOid);
yield return subOid;
}
}
}
}

foreach (var oid in commitOpeartion.GetCommitHistory(oids))
{
yield return oid;
var commit = commitOpeartion.GetCommit(oid);
if (!visited.Contains(commit.Tree))
{
foreach (var val in IterObjectsInTree(commit.Tree))
{
yield return val;
}
}
}
}

private void FetchObjectIfMissing(string oid)
{
if (this.localDataProvider.ObjectExist(oid))
Expand Down
7 changes: 7 additions & 0 deletions src/Ugit/Operations/ICommitOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,12 @@ internal interface ICommitOperation
/// <param name="oids">oids.</param>
/// <returns>histrory oids.</returns>
IEnumerable<string> GetCommitHistory(IEnumerable<string> oids);

/// <summary>
/// Get object histroy by given object id.
/// </summary>
/// <param name="oid">object id.</param>
/// <returns>List of object id that belongs to this object id.</returns>
IEnumerable<string> GetObjectHistory(IEnumerable<string> oids);
}
}
10 changes: 2 additions & 8 deletions src/Ugit/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,12 @@ private static int Main(string[] args)
private static int Push(PushOption o)
{
IDataProvider remoteDataProvider = new DefaultDataProvider(new FileSystem(), o.Remote);
ITreeOperation remoteTreeOperation = new DefaultTreeOperation(remoteDataProvider);
ICommitOperation remoteCommitOperation = new DefaultCommitOperation(remoteDataProvider, remoteTreeOperation);
ICommitOperation remoteCommitOperation = new DefaultCommitOperation(remoteDataProvider, new DefaultTreeOperation(remoteDataProvider));

IRemoteOperation remoteOperation = new DefaultRemoteOperation(
DataProvider,
TreeOperation,
CommitOperation,
remoteDataProvider,
remoteTreeOperation,
remoteCommitOperation);
string refName = Path.Join("refs", "heads", o.Branch);
remoteOperation.Push(refName);
Expand All @@ -122,15 +119,12 @@ private static int Push(PushOption o)
private static int Fetch(FetchOption o)
{
IDataProvider remoteDataProvider = new DefaultDataProvider(new FileSystem(), o.Remote);
ITreeOperation remoteTreeOperation = new DefaultTreeOperation(remoteDataProvider);
ICommitOperation remoteCommitOperation = new DefaultCommitOperation(remoteDataProvider, remoteTreeOperation);
ICommitOperation remoteCommitOperation = new DefaultCommitOperation(remoteDataProvider, new DefaultTreeOperation(remoteDataProvider));

IRemoteOperation remoteOperation = new DefaultRemoteOperation(
DataProvider,
TreeOperation,
CommitOperation,
remoteDataProvider,
remoteTreeOperation,
remoteCommitOperation);
remoteOperation.Fetch();
return 0;
Expand Down
52 changes: 51 additions & 1 deletion test/UgitTest/DefaultCommitOperationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void GetCommitTest()
public void CommitHistoryTest()
{
string commitMessage1 = string.Join("\n", new[]
{
{
"tree tree-oid",
"parent parent-oid",
"",
Expand All @@ -114,5 +114,55 @@ public void CommitHistoryTest()
CollectionAssert.AreEqual(new string[] { "foo-oid", "parent-oid" }, history.ToArray());
dataProvider.VerifyAll();
}

[TestMethod]
public void GetObjectHistroyTest()
{
string commitMessage1 = string.Join("\n", new[]
{
"tree tree2-oid",
"parent parent-oid",
"",
"this is second commit",
});

string commitMessage2 = string.Join("\n", new[]
{
"tree tree1-oid",
"",
"this is first commit",
});

this.dataProvider.Setup(d => d.GetObject("foo-oid", "commit")).Returns(commitMessage1.Encode());
this.dataProvider.Setup(d => d.GetObject("parent-oid", "commit")).Returns(
commitMessage2.Encode());
this.treeOperation.Setup(t => t.IterTreeEntry(It.IsAny<string>())).Returns<string>((oid)=>{
if (oid == "tree2-oid")
{
return new []{
("tree", "sub-tree-oid", ""),
("blob", "foo.txt-oid", ""),
};
}
if (oid == "sub-tree-oid")
{
return new []{
("blob", "bar.txt-oid", "")
};
}
if (oid == "tree1-oid")
{
return new [] {
("blob", "bar.txt-oid", "")
};
}
throw new System.Exception($"Unknow oid: {oid}");
});
string[] objects = commitOperation.GetObjectHistory(new []{ "foo-oid"}).ToArray();
CollectionAssert.AreEqual(new string[]{
"foo-oid", "tree2-oid", "sub-tree-oid", "bar.txt-oid", "foo.txt-oid", "parent-oid", "tree1-oid", "bar.txt-oid"},
objects);
treeOperation.VerifyAll();
}
}
}
Loading

0 comments on commit acf2eda

Please sign in to comment.