private void DownloadObject(ProgressMonitor pm, AnyObjectId id)
{
if (_local.HasObject(id)) return;
while (true)
{
if (DownloadPackedObject(pm, id))
return;
string idStr = id.Name;
string subdir = idStr.Slice(0, 2);
string file = idStr.Substring(2);
string looseName = subdir + "/" + file;
for (int i = _lastRemoteIdx; i < _remotes.Count; i++)
{
if (DownloadLooseObject(id, looseName, _remotes[i]))
{
_lastRemoteIdx = i;
return;
}
}
for (int i = 0; i < _lastRemoteIdx; i++)
{
if (DownloadLooseObject(id, looseName, _remotes[i]))
{
_lastRemoteIdx = i;
return;
}
}
while (_noPacksYet.Count > 0)
{
WalkRemoteObjectDatabase wrr = _noPacksYet.First.Value;
_noPacksYet.RemoveFirst();
List<string> packNameList;
try
{
pm.BeginTask("Listing packs", ProgressMonitor.UNKNOWN);
packNameList = wrr.getPackNames();
}
catch (IOException e)
{
RecordError(id, e);
continue;
}
finally
{
pm.EndTask();
}
if (packNameList == null || packNameList.Count == 0)
continue;
foreach (string packName in packNameList)
{
if (!_packsConsidered.Contains(packName))
{
_packsConsidered.Add(packName);
_unfetchedPacks.AddLast(new RemotePack(_lockMessage, _packLocks, _objCheck, _local, wrr, packName));
}
}
if (DownloadPackedObject(pm, id))
return;
}
List<WalkRemoteObjectDatabase> al = ExpandOneAlternate(id, pm);
if (al != null && al.Count > 0)
{
foreach (WalkRemoteObjectDatabase alt in al)
{
_remotes.Add(alt);
_noPacksYet.AddLast(alt);
_noAlternatesYet.AddLast(alt);
}
continue;
}
List<Exception> failures = null;
if (_fetchErrors.ContainsKey(id.Copy()))
{
failures = _fetchErrors[id.Copy()];
}
TransportException te = null;
if (failures != null && failures.Count > 0)
{
te = failures.Count == 1 ?
new TransportException("Cannot get " + id.Name + ".", failures[0]) :
new TransportException("Cannot get " + id.Name + ".", new CompoundException(failures));
}
if (te == null)
{
te = new TransportException("Cannot get " + id.Name + ".");
}
throw te;
}
}