示例#1
0
        internal virtual void execute(ProgressMonitor monitor, FetchResult result)
        {
            _askFor.Clear();
            _localUpdates.Clear();
            _fetchHeadUpdates.Clear();
            _packLocks.Clear();

            try
            {
                executeImp(monitor, result);
            }
            finally
            {
                foreach (PackLock @lock in _packLocks)
                {
                    @lock.Unlock();
                }
            }
        }
示例#2
0
        /// <summary>
        /// Fetch objects and refs from the remote repository to the local one.
        /// <para/>
        /// This is a utility function providing standard fetch behavior. Local
        /// tracking refs associated with the remote repository are automatically
        /// updated if this transport was created from a <see cref="RemoteConfig"/> with
        /// fetch RefSpecs defined.
        /// </summary>
        /// <param name="monitor">
        /// progress monitor to inform the user about our processing
        /// activity. Must not be null. Use <see cref="NullProgressMonitor"/> if
        /// progress updates are not interesting or necessary.
        /// </param>
        /// <param name="toFetch">
        /// specification of refs to fetch locally. May be null or the
        /// empty collection to use the specifications from the
        /// RemoteConfig. Source for each RefSpec can't be null.
        /// </param>
        /// <returns>information describing the tracking refs updated.</returns>
        public FetchResult fetch(ProgressMonitor monitor, List <RefSpec> toFetch)
        {
            if (toFetch == null || toFetch.isEmpty())
            {
                // If the caller did not ask for anything use the defaults.
                //
                if (_fetch.isEmpty())
                {
                    throw new TransportException("Nothing to fetch.");
                }
                toFetch = _fetch;
            }
            else if (!_fetch.isEmpty())
            {
                // If the caller asked for something specific without giving
                // us the local tracking branch see if we can update any of
                // the local tracking branches without incurring additional
                // object transfer overheads.
                //
                var tmp = new List <RefSpec>(toFetch);
                foreach (RefSpec requested in toFetch)
                {
                    string reqSrc = requested.Source;
                    foreach (RefSpec configured in _fetch)
                    {
                        string cfgSrc = configured.Source;
                        string cfgDst = configured.Destination;
                        if (cfgSrc.Equals(reqSrc) && cfgDst != null)
                        {
                            tmp.Add(configured);
                            break;
                        }
                    }
                }
                toFetch = tmp;
            }

            var result = new FetchResult();

            new FetchProcess(this, toFetch).execute(monitor, result);
            return(result);
        }
示例#3
0
        private void deleteStaleTrackingRefs(FetchResult result, RevWalk.RevWalk walk)
        {
            Repository db = _transport.Local;

            foreach (Ref @ref in db.getAllRefs().Values)
            {
                string refname = @ref.Name;
                foreach (RefSpec spec in _toFetch)
                {
                    if (spec.MatchDestination(refname))
                    {
                        RefSpec s = spec.ExpandFromDestination(refname);
                        if (result.GetAdvertisedRef(s.Source) == null)
                        {
                            deleteTrackingRef(result, db, walk, s, @ref);
                        }
                    }
                }
            }
        }
示例#4
0
		public override void Execute()
		{
			Transport tn = Transport.open(Repository._internal_repo, Remote);

			if (Prune != null)
				tn.RemoveDeletedRefs = Prune.Value;
			if (Thin != null)
				tn.FetchThin = Thin.Value;
			tn.DryRun = DryRun;

			try
			{
				Result = tn.fetch(ProgressMonitor, RefSpecs);
				if (Result.TrackingRefUpdates.Count == 0)
					return;
			}
			finally
			{
				tn.Dispose();
			}
			showFetchResult(tn, Result);
		}
示例#5
0
        internal virtual void execute(ProgressMonitor monitor, FetchResult result)
        {
            _askFor.Clear();
            _localUpdates.Clear();
            _fetchHeadUpdates.Clear();
            _packLocks.Clear();

            try
            {
                executeImp(monitor, result);
            }
            finally
            {
                foreach (PackLock @lock in _packLocks)
                {
                    if (@lock != null)
                    {
                        @lock.Unlock();
                    }
                }
            }
        }
示例#6
0
        protected void showFetchResult(GitSharp.Core.Transport.Transport tn, FetchResult r)
        {
            bool shownURI = false;
            foreach (TrackingRefUpdate u in r.TrackingRefUpdates)
            {
                if (!verbose && u.Result == RefUpdate.RefUpdateResult.NoChange)
                    continue;

                char type = shortTypeOf(u.Result);
                string longType = longTypeOf(u);
                string src = AbbreviateRef(u.RemoteName, false);
                string dst = AbbreviateRef(u.LocalName, true);

                if (!shownURI)
                {
                    OutputStream.Write("From ");
                    OutputStream.WriteLine(tn.Uri);
                    shownURI = true;
                }

                OutputStream.WriteLine(" " + type + " " + longType + " " + src + " -> " + dst);
            }
        }
示例#7
0
        private void updateFETCH_HEAD(FetchResult result)
        {
            LockFile @lock = new LockFile(new FileInfo(Path.Combine(_transport.Local.Directory.FullName, "FETCH_HEAD")));
            try
            {
                if (@lock.Lock())
                {
                    StreamWriter w = new StreamWriter(@lock.GetOutputStream());

                    try
                    {
                        foreach (FetchHeadRecord h in _fetchHeadUpdates)
                        {
                            h.Write(w);
                            result.Add(h);
                        }
                    }
                    finally
                    {
                        w.Close();
                    }

                    @lock.Commit();
                }
            }
            finally
            {
                @lock.Unlock();
            }
        }
示例#8
0
        private void executeImp(ProgressMonitor monitor, FetchResult result)
        {
            _connection = _transport.openFetch();
            try
            {
                result.SetAdvertisedRefs(_transport.Uri, _connection.RefsMap);
                HashSet<Ref> matched = new HashSet<Ref>();
                foreach (RefSpec spec in _toFetch)
                {
                    if (spec.Source == null)
                        throw new TransportException("Source ref not specified for refspec: " + spec);

                    if (spec.Wildcard)
                    {
                        expandWildcard(spec, matched);
                    }
                    else
                    {
                        expandSingle(spec, matched);
                    }
                }

                ICollection<Ref> additionalTags = new Collection<Ref>();

                TagOpt tagopt = _transport.TagOpt;
                if (tagopt == TagOpt.AUTO_FOLLOW)
                {
                    additionalTags = expandAutoFollowTags();
                }
                else if (tagopt == TagOpt.FETCH_TAGS)
                {
                    expandFetchTags();
                }

                bool includedTags;
                if (_askFor.Count != 0 && !askForIsComplete())
                {
                    fetchObjects(monitor);
                    includedTags = _connection.DidFetchIncludeTags;

                    // Connection was used for object transfer. If we
                    // do another fetch we must open a new connection.
                    //
                    closeConnection();
                }
                else
                {
                    includedTags = false;
                }

                if (tagopt == TagOpt.AUTO_FOLLOW && additionalTags.Count != 0)
                {
                    // There are more tags that we want to follow, but
                    // not all were asked for on the initial request.
                    foreach(ObjectId key in _askFor.Keys)
                    {
                        _have.Add(key);
                    }

                    _askFor.Clear();
                    foreach (Ref r in additionalTags)
                    {
                        ObjectId id = r.PeeledObjectId;
                        if (id == null || _transport.Local.HasObject(id))
                        {
                            wantTag(r);
                        }
                    }

                    if (_askFor.Count != 0 && (!includedTags || !askForIsComplete()))
                    {
                        reopenConnection();
                        if (_askFor.Count != 0)
                        {
                            fetchObjects(monitor);
                        }
                    }
                }
            }
            finally
            {
                closeConnection();
            }

            using( RevWalk.RevWalk walk = new RevWalk.RevWalk(_transport.Local))
            {
                if (_transport.RemoveDeletedRefs)
                {
                    deleteStaleTrackingRefs(result, walk);
                }

                foreach (TrackingRefUpdate u in _localUpdates)
                {
                    try
                    {
                        u.Update(walk);
                        result.Add(u);
                    }
                    catch (IOException err)
                    {
                        throw new TransportException("Failure updating tracking ref " + u.LocalName + ": " + err.Message, err);
                    }
                }
            }

            if (_fetchHeadUpdates.Count != 0)
            {
                try
                {
                    updateFETCH_HEAD(result);
                }
                catch (IOException err)
                {
                    throw new TransportException("Failure updating FETCH_HEAD: " + err.Message, err);
                }
            }
        }
示例#9
0
        private void deleteTrackingRef(FetchResult result, Repository db, RevWalk.RevWalk walk, RefSpec spec, Ref localRef)
        {
            string name = localRef.Name;
            try
            {
                TrackingRefUpdate u = new TrackingRefUpdate(db, name, spec.Source, true, ObjectId.ZeroId, "deleted");
                result.Add(u);
                if (_transport.DryRun)
                {
                    return;
                }

                u.Delete(walk);

                switch (u.Result)
                {
                    case RefUpdate.RefUpdateResult.New:
                    case RefUpdate.RefUpdateResult.NoChange:
                    case RefUpdate.RefUpdateResult.FastForward:
                    case RefUpdate.RefUpdateResult.Forced:
                        break;

                    default:
                        throw new TransportException(_transport.Uri, "Cannot delete stale tracking ref " + name + ": " + u.Result.ToString());
                }
            }
            catch (System.IO.IOException e)
            {
                throw new TransportException(_transport.Uri, "Cannot delete stale tracking ref " + name, e);
            }
        }
示例#10
0
 private void deleteStaleTrackingRefs(FetchResult result, RevWalk.RevWalk walk)
 {
     Repository db = _transport.Local;
     foreach (Ref @ref in db.getAllRefs().Values)
     {
         string refname = @ref.Name;
         foreach (RefSpec spec in _toFetch)
         {
             if (spec.MatchDestination(refname))
             {
                 RefSpec s = spec.ExpandFromDestination(refname);
                 if (result.GetAdvertisedRef(s.Source) == null)
                 {
                     deleteTrackingRef(result, db, walk, s, @ref);
                 }
             }
         }
     }
 }
示例#11
0
        private static GitSharp.Core.Ref guessHEAD(FetchResult result)
        {
            // Some transports allow us to see where HEAD points to. If that is not so,
            // we'll have to guess.
            GitSharp.Core.Ref head = result.GetAdvertisedRef(Constants.HEAD);
            if (head != null)
            {
                return head;
            }

            var availableHeads = result.AdvertisedRefs.Where(r => r.Name.StartsWith(Constants.R_HEADS));

            // master is our preferred guess, so if it's advertised, return that.
            GitSharp.Core.Ref guessedHead = result.GetAdvertisedRef(Constants.R_HEADS + Constants.MASTER);
            if (guessedHead == null && availableHeads.Count() > 0)
            {
                // if master is not advertised, return any other head.
                guessedHead = availableHeads.First();
            }

            return guessedHead;
        }
示例#12
0
        private void deleteTrackingRef(FetchResult result, Repository db, RevWalk.RevWalk walk, RefSpec spec, Ref localRef)
        {
            string name = localRef.Name;
            try
            {
                TrackingRefUpdate u = new TrackingRefUpdate(db, name, spec.Source, true, ObjectId.ZeroId, "deleted");
                result.Add(u);
                if (_transport.DryRun)
                {
                    return;
                }

                u.Delete(walk);

                switch (u.Result)
                {
                    case RefUpdate.RefUpdateResult.NEW:
                    case RefUpdate.RefUpdateResult.NO_CHANGE:
                    case RefUpdate.RefUpdateResult.FAST_FORWARD:
                    case RefUpdate.RefUpdateResult.FORCED:
                        break;

                    default:
                        throw new TransportException(_transport.Uri, "Cannot delete stale tracking ref " + name + ": " + Enum.GetName(typeof(RefUpdate.RefUpdateResult), u.Result));
                }
            }
            catch (IOException e)
            {
                throw new TransportException(_transport.Uri, "Cannot delete stale tracking ref " + name, e);
            }
        }
示例#13
0
        private void updateFETCH_HEAD(FetchResult result)
        {
            using (LockFile @lock = new LockFile(PathUtil.CombineFilePath(_transport.Local.Directory, "FETCH_HEAD")))
            {
                if (@lock.Lock())
                {
                    using (StreamWriter w = new StreamWriter(@lock.GetOutputStream()))
                    {
                        foreach (FetchHeadRecord h in _fetchHeadUpdates)
                        {
                            h.Write(w);
                            result.Add(h);
                        }
                    }

                    @lock.Commit();
                }
            }
        }
示例#14
0
        private void executeImp(ProgressMonitor monitor, FetchResult result)
        {
            _connection = _transport.openFetch();
            try
            {
                result.SetAdvertisedRefs(_transport.Uri, _connection.RefsMap);
                HashSet <Ref> matched = new HashSet <Ref>();
                foreach (RefSpec spec in _toFetch)
                {
                    if (spec.Source == null)
                    {
                        throw new TransportException("Source ref not specified for refspec: " + spec);
                    }

                    if (spec.Wildcard)
                    {
                        expandWildcard(spec, matched);
                    }
                    else
                    {
                        expandSingle(spec, matched);
                    }
                }

                ICollection <Ref> additionalTags = new Collection <Ref>();

                TagOpt tagopt = _transport.TagOpt;
                if (tagopt == TagOpt.AUTO_FOLLOW)
                {
                    additionalTags = expandAutoFollowTags();
                }
                else if (tagopt == TagOpt.FETCH_TAGS)
                {
                    expandFetchTags();
                }

                bool includedTags;
                if (_askFor.Count != 0 && !askForIsComplete())
                {
                    fetchObjects(monitor);
                    includedTags = _connection.DidFetchIncludeTags;

                    // Connection was used for object transfer. If we
                    // do another fetch we must open a new connection.
                    //
                    closeConnection();
                }
                else
                {
                    includedTags = false;
                }

                if (tagopt == TagOpt.AUTO_FOLLOW && additionalTags.Count != 0)
                {
                    // There are more tags that we want to follow, but
                    // not all were asked for on the initial request.
                    foreach (ObjectId key in _askFor.Keys)
                    {
                        _have.Add(key);
                    }

                    _askFor.Clear();
                    foreach (Ref r in additionalTags)
                    {
                        ObjectId id = r.PeeledObjectId;
                        if (id == null || _transport.Local.HasObject(id))
                        {
                            wantTag(r);
                        }
                    }

                    if (_askFor.Count != 0 && (!includedTags || !askForIsComplete()))
                    {
                        reopenConnection();
                        if (_askFor.Count != 0)
                        {
                            fetchObjects(monitor);
                        }
                    }
                }
            }
            finally
            {
                closeConnection();
            }

            using (RevWalk.RevWalk walk = new RevWalk.RevWalk(_transport.Local))
            {
                if (_transport.RemoveDeletedRefs)
                {
                    deleteStaleTrackingRefs(result, walk);
                }

                foreach (TrackingRefUpdate u in _localUpdates)
                {
                    try
                    {
                        u.Update(walk);
                        result.Add(u);
                    }
                    catch (IOException err)
                    {
                        throw new TransportException("Failure updating tracking ref " + u.LocalName + ": " + err.Message, err);
                    }
                }
            }

            if (_fetchHeadUpdates.Count != 0)
            {
                try
                {
                    updateFETCH_HEAD(result);
                }
                catch (IOException err)
                {
                    throw new TransportException("Failure updating FETCH_HEAD: " + err.Message, err);
                }
            }
        }
示例#15
0
        private static GitSharp.Core.Ref guessHEAD(FetchResult result)
        {
            GitSharp.Core.Ref idHEAD = result.GetAdvertisedRef(Constants.HEAD);
            List<GitSharp.Core.Ref> availableRefs = new List<GitSharp.Core.Ref>();
            GitSharp.Core.Ref head = null;

            foreach (GitSharp.Core.Ref r in result.AdvertisedRefs.Values)
            {
                string n = r.Name;
                if (!n.StartsWith(Constants.R_HEADS))
                    continue;
                availableRefs.Add(r);
                if (idHEAD == null || head != null)
                    continue;

                if (r.ObjectId.Equals(idHEAD.ObjectId))
                    head = r;
            }
            availableRefs.Sort(RefComparator.INSTANCE);
            if (idHEAD != null && head == null)
                head = idHEAD;
            return head;
        }
示例#16
0
        public FetchResult fetch(ProgressMonitor monitor, List<RefSpec> toFetch)
        {
            if (toFetch == null || toFetch.Count == 0)
            {
                if (_fetchSpecs.Count == 0)
                {
                    throw new TransportException("Nothing to fetch.");
                }
                toFetch = _fetchSpecs;
            }
            else if (_fetchSpecs.Count != 0)
            {
                var tmp = new List<RefSpec>(toFetch);
                foreach (RefSpec requested in toFetch)
                {
                    string reqSrc = requested.Source;
                    foreach (RefSpec configured in _fetchSpecs)
                    {
                        string cfgSrc = configured.Source;
                        string cfgDst = configured.Destination;
                        if (cfgSrc.Equals(reqSrc) && cfgDst != null)
                        {
                            tmp.Add(configured);
                            break;
                        }
                    }
                }
                toFetch = tmp;
            }

            var result = new FetchResult();
            new FetchProcess(this, toFetch).execute(monitor, result);
            return result;
        }
示例#17
0
        /// <summary>
        /// Fetch objects and refs from the remote repository to the local one.
        /// <para/>
        /// This is a utility function providing standard fetch behavior. Local
        /// tracking refs associated with the remote repository are automatically
        /// updated if this transport was created from a <see cref="RemoteConfig"/> with
        /// fetch RefSpecs defined.
        /// </summary>
        /// <param name="monitor">
        /// progress monitor to inform the user about our processing
        /// activity. Must not be null. Use <see cref="NullProgressMonitor"/> if
        /// progress updates are not interesting or necessary.
        /// </param>
        /// <param name="toFetch">
        /// specification of refs to fetch locally. May be null or the
        /// empty collection to use the specifications from the
        /// RemoteConfig. Source for each RefSpec can't be null.
        /// </param>
        /// <returns>information describing the tracking refs updated.</returns>
        public FetchResult fetch(ProgressMonitor monitor, List<RefSpec> toFetch)
        {
            if (toFetch == null || toFetch.isEmpty())
            {
                // If the caller did not ask for anything use the defaults.
                //
                if (_fetch.isEmpty())
                {
                    throw new TransportException("Nothing to fetch.");
                }
                toFetch = _fetch;
            }
            else if (!_fetch.isEmpty())
            {
                // If the caller asked for something specific without giving
                // us the local tracking branch see if we can update any of
                // the local tracking branches without incurring additional
                // object transfer overheads.
                //
                var tmp = new List<RefSpec>(toFetch);
                foreach (RefSpec requested in toFetch)
                {
                    string reqSrc = requested.Source;
                    foreach (RefSpec configured in _fetch)
                    {
                        string cfgSrc = configured.Source;
                        string cfgDst = configured.Destination;
                        if (cfgSrc.Equals(reqSrc) && cfgDst != null)
                        {
                            tmp.Add(configured);
                            break;
                        }
                    }
                }
                toFetch = tmp;
            }

            var result = new FetchResult();
            new FetchProcess(this, toFetch).execute(monitor, result);
            return result;
        }