~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ngit/NGit/NGit.Storage.File/RefDirectory.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
257
257
                        Ref @ref = null;
258
258
                        foreach (string prefix in SEARCH_PATH)
259
259
                        {
260
 
                                @ref = ReadRef(prefix + needle, packed);
261
 
                                if (@ref != null)
262
 
                                {
263
 
                                        @ref = Resolve(@ref, 0, null, null, packed);
264
 
                                        break;
 
260
                                try
 
261
                                {
 
262
                                        @ref = ReadRef(prefix + needle, packed);
 
263
                                        if (@ref != null)
 
264
                                        {
 
265
                                                @ref = Resolve(@ref, 0, null, null, packed);
 
266
                                                break;
 
267
                                        }
 
268
                                }
 
269
                                catch (IOException e)
 
270
                                {
 
271
                                        if (!(!needle.Contains("/") && string.Empty.Equals(prefix) && e.InnerException is
 
272
                                                 InvalidObjectIdException))
 
273
                                        {
 
274
                                                throw;
 
275
                                        }
265
276
                                }
266
277
                        }
267
278
                        FireRefsChanged();
696
707
                        FireRefsChanged();
697
708
                }
698
709
 
 
710
                /// <summary>Adds a set of refs to the set of packed-refs.</summary>
 
711
                /// <remarks>
 
712
                /// Adds a set of refs to the set of packed-refs. Only non-symbolic refs are
 
713
                /// added. If a ref with the given name already existed in packed-refs it is
 
714
                /// updated with the new value. Each loose ref which was added to the
 
715
                /// packed-ref file is deleted. If a given ref can't be locked it will not be
 
716
                /// added to the pack file.
 
717
                /// </remarks>
 
718
                /// <param name="refs">the refs to be added. Must be fully qualified.</param>
 
719
                /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
 
720
                public virtual void Pack(IList<string> refs)
 
721
                {
 
722
                        if (refs.Count == 0)
 
723
                        {
 
724
                                return;
 
725
                        }
 
726
                        FS fs = parent.FileSystem;
 
727
                        // Lock the packed refs file and read the content
 
728
                        LockFile lck = new LockFile(packedRefsFile, fs);
 
729
                        if (!lck.Lock())
 
730
                        {
 
731
                                throw new IOException(MessageFormat.Format(JGitText.Get().cannotLock, packedRefsFile
 
732
                                        ));
 
733
                        }
 
734
                        try
 
735
                        {
 
736
                                RefDirectory.PackedRefList packed = GetPackedRefs();
 
737
                                RefList<Ref> cur = ReadPackedRefs();
 
738
                                // Iterate over all refs to be packed
 
739
                                foreach (string refName in refs)
 
740
                                {
 
741
                                        Ref @ref = ReadRef(refName, cur);
 
742
                                        if (@ref.IsSymbolic())
 
743
                                        {
 
744
                                                continue;
 
745
                                        }
 
746
                                        // can't pack symbolic refs
 
747
                                        // Add/Update it to packed-refs
 
748
                                        int idx = cur.Find(refName);
 
749
                                        if (idx >= 0)
 
750
                                        {
 
751
                                                cur = cur.Set(idx, PeeledPackedRef(@ref));
 
752
                                        }
 
753
                                        else
 
754
                                        {
 
755
                                                cur = cur.Add(idx, PeeledPackedRef(@ref));
 
756
                                        }
 
757
                                }
 
758
                                // The new content for packed-refs is collected. Persist it.
 
759
                                CommitPackedRefs(lck, cur, packed);
 
760
                                // Now delete the loose refs which are now packed
 
761
                                foreach (string refName_1 in refs)
 
762
                                {
 
763
                                        // Lock the loose ref
 
764
                                        FilePath refFile = FileFor(refName_1);
 
765
                                        if (!refFile.Exists())
 
766
                                        {
 
767
                                                continue;
 
768
                                        }
 
769
                                        LockFile rLck = new LockFile(refFile, parent.FileSystem);
 
770
                                        if (!rLck.Lock())
 
771
                                        {
 
772
                                                continue;
 
773
                                        }
 
774
                                        try
 
775
                                        {
 
776
                                                RefDirectory.LooseRef currentLooseRef = ScanRef(null, refName_1);
 
777
                                                if (currentLooseRef == null || currentLooseRef.IsSymbolic())
 
778
                                                {
 
779
                                                        continue;
 
780
                                                }
 
781
                                                Ref packedRef = cur.Get(refName_1);
 
782
                                                ObjectId clr_oid = currentLooseRef.GetObjectId();
 
783
                                                if (clr_oid != null && clr_oid.Equals(packedRef.GetObjectId()))
 
784
                                                {
 
785
                                                        RefList<RefDirectory.LooseRef> curLoose;
 
786
                                                        RefList<RefDirectory.LooseRef> newLoose;
 
787
                                                        do
 
788
                                                        {
 
789
                                                                curLoose = looseRefs.Get();
 
790
                                                                int idx = curLoose.Find(refName_1);
 
791
                                                                if (idx < 0)
 
792
                                                                {
 
793
                                                                        break;
 
794
                                                                }
 
795
                                                                newLoose = curLoose.Remove(idx);
 
796
                                                        }
 
797
                                                        while (!looseRefs.CompareAndSet(curLoose, newLoose));
 
798
                                                        int levels = LevelsIn(refName_1) - 2;
 
799
                                                        Delete(FileFor(refName_1), levels);
 
800
                                                }
 
801
                                        }
 
802
                                        finally
 
803
                                        {
 
804
                                                rLck.Unlock();
 
805
                                        }
 
806
                                }
 
807
                        }
 
808
                        finally
 
809
                        {
 
810
                                // Don't fire refsChanged. The refs have not change, only their
 
811
                                // storage.
 
812
                                lck.Unlock();
 
813
                        }
 
814
                }
 
815
 
 
816
                /// <summary>Make sure a ref is peeled and has the Storage PACKED.</summary>
 
817
                /// <remarks>
 
818
                /// Make sure a ref is peeled and has the Storage PACKED. If the given ref
 
819
                /// has this attributes simply return it. Otherwise create a new peeled
 
820
                /// <see cref="NGit.ObjectIdRef">NGit.ObjectIdRef</see>
 
821
                /// where Storage is set to PACKED.
 
822
                /// </remarks>
 
823
                /// <param name="f"></param>
 
824
                /// <returns>a ref for Storage PACKED having the same name, id, peeledId as f</returns>
 
825
                /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
 
826
                ///     </exception>
 
827
                /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
 
828
                private Ref PeeledPackedRef(Ref f)
 
829
                {
 
830
                        if (f.GetStorage().IsPacked() && f.IsPeeled())
 
831
                        {
 
832
                                return f;
 
833
                        }
 
834
                        if (!f.IsPeeled())
 
835
                        {
 
836
                                f = Peel(f);
 
837
                        }
 
838
                        if (f.GetPeeledObjectId() != null)
 
839
                        {
 
840
                                return new ObjectIdRef.PeeledTag(RefStorage.PACKED, f.GetName(), f.GetObjectId(), 
 
841
                                        f.GetPeeledObjectId());
 
842
                        }
 
843
                        else
 
844
                        {
 
845
                                return new ObjectIdRef.PeeledNonTag(RefStorage.PACKED, f.GetName(), f.GetObjectId
 
846
                                        ());
 
847
                        }
 
848
                }
 
849
 
699
850
                /// <exception cref="System.IO.IOException"></exception>
700
851
                internal virtual void Log(RefUpdate update, string msg, bool deref)
701
852
                {
762
913
                                return curList;
763
914
                        }
764
915
                        RefDirectory.PackedRefList newList = ReadPackedRefs();
765
 
                        if (packedRefs.CompareAndSet(curList, newList))
 
916
                        if (packedRefs.CompareAndSet(curList, newList) && !curList.id.Equals(newList.id))
766
917
                        {
767
918
                                modCnt.IncrementAndGet();
768
919
                        }
774
925
                {
775
926
                        FileSnapshot snapshot = FileSnapshot.Save(packedRefsFile);
776
927
                        BufferedReader br;
 
928
                        MessageDigest digest = Constants.NewMessageDigest();
777
929
                        try
778
930
                        {
779
 
                                br = new BufferedReader(new InputStreamReader(new FileInputStream(packedRefsFile)
780
 
                                        , Constants.CHARSET));
 
931
                                br = new BufferedReader(new InputStreamReader(new DigestInputStream(new FileInputStream
 
932
                                        (packedRefsFile), digest), Constants.CHARSET));
781
933
                        }
782
934
                        catch (FileNotFoundException)
783
935
                        {
786
938
                        }
787
939
                        try
788
940
                        {
789
 
                                return new RefDirectory.PackedRefList(ParsePackedRefs(br), snapshot);
 
941
                                return new RefDirectory.PackedRefList(ParsePackedRefs(br), snapshot, ObjectId.FromRaw
 
942
                                        (digest.Digest()));
790
943
                        }
791
944
                        finally
792
945
                        {
862
1015
                private void CommitPackedRefs(LockFile lck, RefList<Ref> refs, RefDirectory.PackedRefList
863
1016
                         oldPackedList)
864
1017
                {
865
 
                        new _RefWriter_707(this, lck, oldPackedList, refs, refs).WritePackedRefs();
 
1018
                        new _RefWriter_826(this, lck, oldPackedList, refs, refs).WritePackedRefs();
866
1019
                }
867
1020
 
868
 
                private sealed class _RefWriter_707 : RefWriter
 
1021
                private sealed class _RefWriter_826 : RefWriter
869
1022
                {
870
 
                        public _RefWriter_707(RefDirectory _enclosing, LockFile lck, RefDirectory.PackedRefList
 
1023
                        public _RefWriter_826(RefDirectory _enclosing, LockFile lck, RefDirectory.PackedRefList
871
1024
                                 oldPackedList, RefList<Ref> refs, RefList<Ref> baseArg1) : base(baseArg1)
872
1025
                        {
873
1026
                                this._enclosing = _enclosing;
905
1058
                                        throw new ObjectWritingException(MessageFormat.Format(JGitText.Get().unableToWrite
906
1059
                                                , name));
907
1060
                                }
 
1061
                                byte[] digest = Constants.NewMessageDigest().Digest(content);
908
1062
                                this._enclosing.packedRefs.CompareAndSet(oldPackedList, new RefDirectory.PackedRefList
909
 
                                        (refs, lck.GetCommitSnapshot()));
 
1063
                                        (refs, lck.GetCommitSnapshot(), ObjectId.FromRaw(digest)));
910
1064
                        }
911
1065
 
912
1066
                        private readonly RefDirectory _enclosing;
1041
1195
                                        return @ref;
1042
1196
                                }
1043
1197
                        }
1044
 
                        catch (ArgumentException)
 
1198
                        catch (ArgumentException notRef)
1045
1199
                        {
1046
1200
                                while (0 < n && char.IsWhiteSpace((char)buf[n - 1]))
1047
1201
                                {
1048
1202
                                        n--;
1049
1203
                                }
1050
1204
                                string content = RawParseUtils.Decode(buf, 0, n);
1051
 
                                throw new IOException(MessageFormat.Format(JGitText.Get().notARef, name, content)
1052
 
                                        );
 
1205
                                IOException ioException = new IOException(MessageFormat.Format(JGitText.Get().notARef
 
1206
                                        , name, content), notRef);
 
1207
                                throw ioException;
1053
1208
                        }
1054
1209
                        return new RefDirectory.LooseUnpeeled(otherSnapshot, name, id);
1055
1210
                }
1142
1297
                private class PackedRefList : RefList<Ref>
1143
1298
                {
1144
1299
                        internal static readonly RefDirectory.PackedRefList NO_PACKED_REFS = new RefDirectory.PackedRefList
1145
 
                                (RefList.EmptyList(), FileSnapshot.MISSING_FILE);
 
1300
                                (RefList.EmptyList(), FileSnapshot.MISSING_FILE, ObjectId.ZeroId);
1146
1301
 
1147
1302
                        internal readonly FileSnapshot snapshot;
1148
1303
 
1149
 
                        internal PackedRefList(RefList<Ref> src, FileSnapshot s) : base(src)
 
1304
                        internal readonly ObjectId id;
 
1305
 
 
1306
                        internal PackedRefList(RefList<Ref> src, FileSnapshot s, ObjectId i) : base(src)
1150
1307
                        {
1151
1308
                                snapshot = s;
 
1309
                                id = i;
1152
1310
                        }
1153
1311
                }
1154
1312