/// <exception cref="NGit.Errors.TransportException"></exception>
        public virtual void Push(ProgressMonitor monitor, IDictionary <string, RemoteRefUpdate
                                                                       > refUpdates)
        {
            MarkStartedOperation();
            packNames        = null;
            newRefs          = new SortedDictionary <string, Ref>(GetRefsMap());
            packedRefUpdates = new AList <RemoteRefUpdate>(refUpdates.Count);
            // Filter the commands and issue all deletes first. This way we
            // can correctly handle a directory being cleared out and a new
            // ref using the directory name being created.
            //
            IList <RemoteRefUpdate> updates = new AList <RemoteRefUpdate>();

            foreach (RemoteRefUpdate u in refUpdates.Values)
            {
                string n = u.GetRemoteName();
                if (!n.StartsWith("refs/") || !Repository.IsValidRefName(n))
                {
                    u.SetStatus(RemoteRefUpdate.Status.REJECTED_OTHER_REASON);
                    u.SetMessage(JGitText.Get().funnyRefname);
                    continue;
                }
                if (AnyObjectId.Equals(ObjectId.ZeroId, u.GetNewObjectId()))
                {
                    DeleteCommand(u);
                }
                else
                {
                    updates.AddItem(u);
                }
            }
            // If we have any updates we need to upload the objects first, to
            // prevent creating refs pointing at non-existent data. Then we
            // can update the refs, and the info-refs file for dumb transports.
            //
            if (!updates.IsEmpty())
            {
                Sendpack(updates, monitor);
            }
            foreach (RemoteRefUpdate u_1 in updates)
            {
                UpdateCommand(u_1);
            }
            // Is this a new repository? If so we should create additional
            // metadata files so it is properly initialized during the push.
            //
            if (!updates.IsEmpty() && IsNewRepository())
            {
                CreateNewRepository(updates);
            }
            RefWriter refWriter = new _RefWriter_179(this, newRefs.Values);

            if (!packedRefUpdates.IsEmpty())
            {
                try
                {
                    refWriter.WritePackedRefs();
                    foreach (RemoteRefUpdate u_2 in packedRefUpdates)
                    {
                        u_2.SetStatus(RemoteRefUpdate.Status.OK);
                    }
                }
                catch (IOException err)
                {
                    foreach (RemoteRefUpdate u_2 in packedRefUpdates)
                    {
                        u_2.SetStatus(RemoteRefUpdate.Status.REJECTED_OTHER_REASON);
                        u_2.SetMessage(err.Message);
                    }
                    throw new TransportException(uri, JGitText.Get().failedUpdatingRefs, err);
                }
            }
            try
            {
                refWriter.WriteInfoRefs();
            }
            catch (IOException err)
            {
                throw new TransportException(uri, JGitText.Get().failedUpdatingRefs, err);
            }
        }
Ejemplo n.º 2
0
		/// <exception cref="NGit.Errors.TransportException"></exception>
		public virtual void Push(ProgressMonitor monitor, IDictionary<string, RemoteRefUpdate
			> refUpdates)
		{
			MarkStartedOperation();
			packNames = null;
			newRefs = new SortedDictionary<string, Ref>(GetRefsMap());
			packedRefUpdates = new AList<RemoteRefUpdate>(refUpdates.Count);
			// Filter the commands and issue all deletes first. This way we
			// can correctly handle a directory being cleared out and a new
			// ref using the directory name being created.
			//
			IList<RemoteRefUpdate> updates = new AList<RemoteRefUpdate>();
			foreach (RemoteRefUpdate u in refUpdates.Values)
			{
				string n = u.GetRemoteName();
				if (!n.StartsWith("refs/") || !Repository.IsValidRefName(n))
				{
					u.SetStatus(RemoteRefUpdate.Status.REJECTED_OTHER_REASON);
					u.SetMessage(JGitText.Get().funnyRefname);
					continue;
				}
				if (AnyObjectId.Equals(ObjectId.ZeroId, u.GetNewObjectId()))
				{
					DeleteCommand(u);
				}
				else
				{
					updates.AddItem(u);
				}
			}
			// If we have any updates we need to upload the objects first, to
			// prevent creating refs pointing at non-existent data. Then we
			// can update the refs, and the info-refs file for dumb transports.
			//
			if (!updates.IsEmpty())
			{
				Sendpack(updates, monitor);
			}
			foreach (RemoteRefUpdate u_1 in updates)
			{
				UpdateCommand(u_1);
			}
			// Is this a new repository? If so we should create additional
			// metadata files so it is properly initialized during the push.
			//
			if (!updates.IsEmpty() && IsNewRepository())
			{
				CreateNewRepository(updates);
			}
			RefWriter refWriter = new _RefWriter_179(this, newRefs.Values);
			if (!packedRefUpdates.IsEmpty())
			{
				try
				{
					refWriter.WritePackedRefs();
					foreach (RemoteRefUpdate u_2 in packedRefUpdates)
					{
						u_2.SetStatus(RemoteRefUpdate.Status.OK);
					}
				}
				catch (IOException err)
				{
					foreach (RemoteRefUpdate u_2 in packedRefUpdates)
					{
						u_2.SetStatus(RemoteRefUpdate.Status.REJECTED_OTHER_REASON);
						u_2.SetMessage(err.Message);
					}
					throw new TransportException(uri, JGitText.Get().failedUpdatingRefs, err);
				}
			}
			try
			{
				refWriter.WriteInfoRefs();
			}
			catch (IOException err)
			{
				throw new TransportException(uri, JGitText.Get().failedUpdatingRefs, err);
			}
		}