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; } }
private void DownloadObject(ProgressMonitor pm, AnyObjectId id) { if (_local.HasObject(id)) return; while (true) { // Try a pack file we know about, but don't have yet. Odds are // that if it has this object, it has others related to it so // getting the pack is a good bet. // if (DownloadPackedObject(pm, id)) return; // Search for a loose object over all alternates, starting // from the one we last successfully located an object through. // 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; } } // Try to obtain more pack information and search those. // while (_noPacksYet.Count > 0) { WalkRemoteObjectDatabase wrr = _noPacksYet.First.Value; _noPacksYet.RemoveFirst(); ICollection<string> packNameList; try { pm.BeginTask("Listing packs", ProgressMonitor.UNKNOWN); packNameList = wrr.getPackNames(); } catch (IOException e) { // Try another repository. // RecordError(id, e); continue; } finally { pm.EndTask(); } if (packNameList == null || packNameList.Count == 0) continue; foreach (string packName in packNameList) { bool contains = _packsConsidered.Contains(packName); _packsConsidered.Add(packName); if (!contains) { _unfetchedPacks.AddLast(new RemotePack(_lockMessage, _packLocks, _objCheck, _local, wrr, packName)); } } if (DownloadPackedObject(pm, id)) return; } // Try to expand the first alternate we haven't expanded yet. // ICollection<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; } // We could not obtain the object. There may be reasons why. // List<Exception> failures = _fetchErrors.get(id.Copy()); var te = new TransportException("Cannot get " + id.Name + "."); 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)); } throw te; } }