Ejemplo n.º 1
0
        public void Go()
        {
            while (_queue.Any())
                lock (this)
                {
                    if (!_queue.Any()) continue;
                    var current = _queue.First();
                    if (!current.Key.Directory.Exists)
                    {
                        CreateDirectoryTree(current.Value.Source.Directory, current.Key.Directory);
                    }
                    using (Stream src = current.Value.Source.OpenRead())
                    {
                        if (src.Length <= 0)
                        {
                            // Diff/New file is empty, skip it.
                            _queue.Remove(current.Key);
                            continue;
                        }
                        if (current.Key.Exists) // trying to merge/apply data diff
                            if (Diff.IsBinary(src) || _copyAsBinary) // binary blobs are copied whole
                                using (Stream dest = current.Key.Open(FileMode.Truncate, FileAccess.ReadWrite))
                                    src.CopyTo(dest);
                            else
                                using (Stream dest = current.Key.Open(FileMode.Open, FileAccess.ReadWrite))
                                {
                                    var srcBytes = src.toArray();
                                    Patch P = new Patch();

                                    if (P.ParseHunks(srcBytes) == 0)
                                    {
                                        // No diff hunks in the file.
                                        // Diff file not a diff, and not empty.  Handle it as a binary file overwrite.
                                        dest.SetLength(0);
                                        src.CopyTo(dest);
                                        _queue.Remove(current.Key);
                                        continue;
                                    }

                                    var newBytes = P.SimpleApply(dest.toArray());
                                        // Replace this call with a more sophisticated (read "intellegent") diff application method.

                                    dest.Position = 0;
                                    dest.Write(newBytes, 0, newBytes.Length);
                                    dest.SetLength(newBytes.Length);

                                    /*
                                    MergeResult mr = current.Value.Base == null
                                                         ? MergeAlgorithm.merge(new RawText(dest.toArray()),
                                                                                new RawText(src.toArray()),
                                                                                new RawText(dest.toArray())) // use the base as "theirs"
                                                         : MergeAlgorithm.merge(new RawText(dest.toArray()),
                                                                                new RawText(src.toArray()),
                                                                                new RawText(
                                                                                    current.Value.Base.OpenRead()
                                                                                           .toArray()));
                                    bool conflicts = mr.containsConflicts();
                                    bool blurb = conflicts;

                                    */
                                }

                        else
                            using (var dest = current.Key.Create())
                                if (current.Value.Base == null || !current.Value.Base.Exists || Diff.IsBinary(src) ||
                                    _copyAsBinary)
                                    src.CopyTo(dest);
                                else
                                {
                                    byte[] baseBytes = current.Value.Base.OpenRead().toArray();
                                    byte[] srcBytes = src.toArray();
                                    // string baseStr = baseBytes.Aggregate(String.Empty, (current1, b) => current1 + (char) b);
                                    // string srcStr = srcBytes.Aggregate(String.Empty, (current1, b) => current1 + (char)b);

                                    var diff = new Diff(baseBytes, srcBytes);

                                    if (diff.HasDifferences)
                                    {
                                        var df = new DiffFormatter();
                                        df.FormatEdits(dest, new RawText(baseBytes), new RawText(srcBytes),
                                                       diff.GetEdits());
                                        /*
                                        Stream diffStream = new MemoryStream();
                                        df.FormatEdits(diffStream, new RawText(baseBytes), new RawText(srcBytes), diff.GetEdits());
                                        var fh = new CombinedFileHeader(Patch.ReadFully(diffStream), 0);
                                        var outStr = fh.getScriptText();
                                        byte[] bytes = outStr.Cast<byte>().ToArray();
                                        dest.Write(bytes, 0, bytes.Length);
                                        */
                                    }
                                    else // Not really different, just different metadata.  skip it.
                                    {
                                        dest.Close();
                                        current.Key.Delete();
                                        _queue.Remove(current.Key);
                                        continue;
                                    }
                                }
                    }

                    // set the attributes and file timestamps (and ACLs if it's ntfs...)
                    current.Key.Attributes = current.Value.Source.Attributes;
                    if (current.Key.FileSystem is NtfsFileSystem)
                    {
                        var D = (NtfsFileSystem) current.Key.FileSystem;
                        var S = (NtfsFileSystem) current.Value.Source.FileSystem;
                        D.SetSecurity(current.Key.FullName, S.GetSecurity(current.Value.Source.FullName));

                        D.SetFileStandardInformation(current.Key.FullName,
                                                     S.GetFileStandardInformation(current.Value.Source.FullName));
                    }
                    else
                    {
                        current.Key.CreationTimeUtc = current.Value.Source.CreationTimeUtc;
                        current.Key.LastWriteTimeUtc = current.Value.Source.LastWriteTimeUtc;
                        current.Key.LastAccessTimeUtc = current.Value.Source.LastAccessTimeUtc;
                    }

                    _queue.Remove(current.Key);
                }
        }
Ejemplo n.º 2
0
        internal virtual int parseBody(Patch script, int end)
        {
            byte[] buf = Buffer;
            int c = RawParseUtils.nextLF(buf, _startOffset), last = c;

            OldLinesDeleted = 0;
            OldLinesAdded = 0;

            for (; c < end; last = c, c = RawParseUtils.nextLF(buf, c))
            {
                bool breakScan;
                switch (buf[c])
                {
                    case (byte)' ':
                    case (byte)'\n':
                        LinesContext++;
                        continue;

                    case (byte)'-':
                        OldLinesDeleted++;
                        continue;

                    case (byte)'+':
                        OldLinesAdded++;
                        continue;

                    case (byte)'\\': // Matches "\ No newline at end of file"
                        continue;

                    default:
                        breakScan = true;
                        break;
                }

                if (breakScan)
                {
                    break;
                }
            }

            if (last < end && LinesContext + OldLinesDeleted - 1 == OldLineCount
                && LinesContext + OldLinesAdded == NewLineCount
                && RawParseUtils.match(buf, last, Patch.SigFooter) >= 0)
            {
                // This is an extremely common occurrence of "corruption".
                // Users add footers with their signatures After this mark,
                // and git diff adds the git executable version number.
                // Let it slide; the hunk otherwise looked sound.
                //
                OldLinesDeleted--;
                return last;
            }

            if (LinesContext + OldLinesDeleted < OldLineCount)
            {
                int missingCount = OldLineCount - (LinesContext + OldLinesDeleted);
                //script.error(buf, _startOffset, "Truncated hunk, at least " + missingCount + " old lines is missing");
                throw new FormatException(String.Format("Truncated hunk, at least {0} old line(s) missing.  Hunk start @ {1}.  Hunk:\n{2}",missingCount, _startOffset, buf));
            }
            else if (LinesContext + OldLinesAdded < NewLineCount)
            {
                int missingCount = NewLineCount - (LinesContext + OldLinesAdded);
                //script.error(buf, _startOffset, "Truncated hunk, at least " + missingCount + " new lines is missing");
                throw new FormatException(String.Format("Truncated hunk, at least {0} new line(s) missing.  Hunk start @ {1}.  Hunk:\n{2}", missingCount, _startOffset, buf));
            }
            else if (LinesContext + OldLinesDeleted > OldLineCount
                     || LinesContext + OldLinesAdded > NewLineCount)
            {
                string oldcnt = OldLineCount + ":" + NewLineCount;
                string newcnt = (LinesContext + OldLinesDeleted) + ":"
                                + (LinesContext + OldLinesAdded);
                //script.warn(buf, _startOffset, "Hunk header " + oldcnt + " does not match body line count of " + newcnt);
                throw new FormatException(String.Format("Hunk header {0} does not match body line count of {1}.  Hunk start @ {1}.  Hunk:\n{2}" + oldcnt, newcnt, _startOffset, buf));
            }

            return c;
        }