Skip to content

Commit

Permalink
Remote: don't download a pack if all objects are available locally
Browse files Browse the repository at this point in the history
Add a Lookup 'event' for asking the plastic DB whether a commit is
available locally, letting us know whether we should even download a
packfile.

References libgit2#212, libgit2#217
  • Loading branch information
carlosmn committed Jun 23, 2012
1 parent 2fbb680 commit 61cc574
Showing 1 changed file with 34 additions and 6 deletions.
40 changes: 34 additions & 6 deletions LibGit2Sharp/Remote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public ProgressEventArgs(PktDemux pkt)

public delegate void ProgressHandler(object sender, ProgressEventArgs args);
public delegate List<ObjectId> CommitRequestHandler(object sender);
public delegate bool LookupHandler(object sender, ObjectId id);

/// <summary>
/// A remote repository whose branches are tracked.
Expand All @@ -34,8 +35,11 @@ public class Remote : IEquatable<Remote>
public List<PktRef> Refs { get; private set; }
public event ProgressHandler Progress;
public event CommitRequestHandler RequestCommits;
public event LookupHandler Lookup;
public bool NeedsPack;
private Lazy<IEnumerable<string>> refnames;
private Lazy<IEnumerable<string>> matching_refs;
private IEnumerable<ObjectId> interesting;
private Indexer indexer;
private ProtocolCapabilities caps;

Expand Down Expand Up @@ -93,13 +97,25 @@ public void Connect()
throw new GitProtocolException((pkt as PktError).Error);
}

/* See what we actually need to download */
if (Lookup != null)
interesting = Refs.Where(s => Refspec.Matches(s.Name) && !Lookup(this, s.Id)).Select(s => s.Id);
else
interesting = Refs.Select(s => s.Id);

NeedsPack = interesting.Count() != 0;

/* Figure out what capabilities we have in common */
caps = new ProtocolCapabilities(Refs[0].CapString);
}

public IndexerStats Stats
{
get {
/* In case somebody asks at the wrong time */
if (indexer == null)
return new IndexerStats();

return indexer.Stats;
}
}
Expand All @@ -108,15 +124,12 @@ public IndexerStats Stats
private void SendWants(StreamWriter writer)
{
bool first = true;
foreach (PktRef p in Refs) {
if (!Refspec.Matches(p.Name))
continue;

foreach (ObjectId id in interesting) {
if (first) {
writer.Write(Pkt.Line("want " + p.Id.Sha + " " + caps.Common));
writer.Write(Pkt.Line("want " + id.Sha + " " + caps.Common));
first = false;
} else {
writer.Write(Pkt.Line("want " + p.Id.Sha));
writer.Write(Pkt.Line("want " + id.Sha));
}
}
/* Flush after the want lines */
Expand All @@ -133,9 +146,23 @@ private int SendHaves(StreamWriter writer)
return haves.Count;
}

/// <summary>
/// Download a packfile and store it in the dir specified by the path.
/// </summary>
/// <param name='path'>
/// The directory where the packfile and its index should be stored
/// </param>
/// <returns>
/// Whether a packfile was downloaded. A return value of false
/// means that the local repository already has all the required objects
/// </returns>
public void Download(string path)
{
Ensure.ArgumentNotNullOrEmptyString(path, "path");

if (!NeedsPack)
return;

if (!Directory.Exists(path))
Directory.CreateDirectory(path);

Expand All @@ -148,6 +175,7 @@ public void Download(string path)
var writer = new StreamWriter(new MemoryStream());

SendWants(writer);

if (RequestCommits != null) {
do {
var n = SendHaves(writer);
Expand Down

0 comments on commit 61cc574

Please sign in to comment.