예제 #1
0
    void ShowPendingChanges(Workspace workspace, string[] paths)
    {
        PendingChange[] pendingChanges = workspace.GetPendingChanges(paths, RecursionType.Full, true);
        if (pendingChanges.Length == 0)
        {
            Console.WriteLine("No pending changes.");
            Environment.Exit((int)ExitCode.PartialSuccess);
        }

        string cwd = Environment.CurrentDirectory;

        foreach (PendingChange change in pendingChanges)
        {
            string p = change.LocalItem;
            if (p.StartsWith(cwd))
            {
                p = p.Substring(cwd.Length + 1);
            }

            if (OptionBrief)
            {
                Driver.WriteLine(CanonicalPath(p));
                continue;
            }

            IDiffItem a = new DiffItemNull();
            IDiffItem b = new DiffItemNull();

            string tname = null;
            if (!change.IsAdd)
            {
                tname = Path.GetTempFileName();
                change.DownloadBaseFile(tname);

                a = new DiffItemLocalFile(tname, change.Encoding,
                                          change.CreationDate, true);
            }

            if (!change.IsDelete)
            {
                b = new DiffItemLocalFile(change.LocalItem, change.Encoding,
                                          change.CreationDate, false);
            }

            Difference.DiffFiles(VersionControlServer, a, b,
                                 GetDiffOptions(), p, true);

            if (!String.IsNullOrEmpty(tname))
            {
                File.Delete(tname);
            }
        }
    }
예제 #2
0
    public void ShowOldFiles(Workspace workspace, string path)
    {
        // process command options
        ItemSpec itemSpec = new ItemSpec(path, RecursionType.Full);

        List <ItemSpec> itemSpecs = new List <ItemSpec>();

        itemSpecs.Add(itemSpec);

        ExtendedItem[][] items = workspace.GetExtendedItems(itemSpecs.ToArray(),
                                                            DeletedState.NonDeleted, ItemType.Any);

        foreach (ExtendedItem[] itemArray in items)
        {
            foreach (ExtendedItem item in itemArray)
            {
                if (item.IsLatest)
                {
                    continue;
                }

                string p = item.LocalItem.Substring(path.Length);
                if (OptionBrief)
                {
                    Driver.WriteLine(p);
                    continue;
                }

                IDiffItem a = new DiffItemNull();
                IDiffItem b = new DiffItemNull();

                if ((item.ChangeType & ChangeType.Add) != ChangeType.Add)
                {
                    a = new DiffItemLocalFile(item.LocalItem, item.Encoding,
                                              DateTime.Now, false);
                }

                if ((item.ChangeType & ChangeType.Delete) != ChangeType.Delete)
                {
                    b = new DiffItemVersionedFile(VersionControlServer,
                                                  item.ItemId, item.VersionLatest, item.LocalItem);
                }

                Difference.DiffFiles(VersionControlServer, a, b,
                                     GetDiffOptions(), p, true);
            }
        }
    }
예제 #3
0
        /// <summary>
        /// Generates a report about Edit change
        /// </summary>
        private void GenerateEditReport(string diffFileName, Changeset changeset, Change change)
        {
            IDiffItem origItem = new DiffItemVersionedFile(_sourceControl, change.Item.ServerItem,
                                                           new ChangesetVersionSpec(changeset.ChangesetId - 1));
            IDiffItem newItem = new DiffItemVersionedFile(_sourceControl, change.Item.ServerItem,
                                                          new ChangesetVersionSpec(changeset.ChangesetId));

            using (var writer = new StreamWriter(diffFileName))
            {
                WriteHeader(writer, changeset);

                var diffOptions = new DiffOptions
                {
                    UseThirdPartyTool = false,
                    OutputType        = DiffOutputType.Context,
                    ContextLines      = 0,
                    StreamWriter      = writer
                };

                Difference.DiffFiles(_sourceControl, origItem, newItem, diffOptions, null, true);
            }
        }
예제 #4
0
        public static DiffSummary DiffFiles(String source, Int32 sourceCodePage,
                                            String target, Int32 targetCodePage,
                                            DiffOptions diffOptions)
        {
            DiffSegment currSegment = Difference.DiffFiles(source, sourceCodePage, target, targetCodePage, diffOptions);
            DiffSummary summary     = new DiffSummary();

            // Initialize a set of position markers which will be used to walk
            // through the files
            Int32 currentOriginalPosition = 0;
            Int32 currentModifiedPosition = 0;

            while (currSegment != null)
            {
                // Everything between the postiion markers and the start of the current common segment
                // will be either lines which were deleted or lines which were added
                Int32 linesDeleted = currSegment.OriginalStart - currentOriginalPosition;
                Int32 linesAdded   = currSegment.ModifiedStart - currentModifiedPosition;

                summary.TotalLinesModified += Math.Min(linesDeleted, linesAdded);
                summary.TotalLinesAdded    += Math.Max(0, linesAdded - linesDeleted);
                summary.TotalLinesDeleted  += Math.Max(0, linesDeleted - linesAdded);

                // Advance the position markers to the end of the common section
                currentOriginalPosition = currSegment.OriginalStart + currSegment.OriginalLength;
                currentModifiedPosition = currSegment.ModifiedStart + currSegment.ModifiedLength;

                // Move to the next segment in the linked-list
                currSegment = currSegment.Next;
            }

            // After walking the linked-list of common sections, the position markers
            // will be pointing to the end of the file, thus we can infer how many lines
            // are in each file.
            summary.OriginalLineCount = currentOriginalPosition;
            summary.ModifiedLineCount = currentModifiedPosition;

            return(summary);
        }
예제 #5
0
        // Display the differences between the two file versions.
        static void DiffFiles(Item item1, Item item2)
        {
            if (item1.ItemType != ItemType.File)
            {
                return;
            }

            Console.WriteLine();

            DiffItemVersionedFile diffItem1 = new DiffItemVersionedFile(item1,
                                                                        new ChangesetVersionSpec(item1.ChangesetId));
            DiffItemVersionedFile diffItem2 = new DiffItemVersionedFile(item2,
                                                                        new ChangesetVersionSpec(item2.ChangesetId));

            // Here we set up the options to show the diffs in the console with the unified diff
            // format.
            // If you simply want to launch the external diff viewer, rather than get a text diff,
            // you just need to set UseThirdPartyTool to true.  You don't need to set any of the
            // other properties to use the external tool.
            DiffOptions options = new DiffOptions();

            options.UseThirdPartyTool = false;

            // These settings are just for the text diff (not needed for an external tool).
            options.Flags          = DiffOptionFlags.EnablePreambleHandling | DiffOptionFlags.IgnoreWhiteSpace;
            options.OutputType     = DiffOutputType.Unified;
            options.TargetEncoding = Console.OutputEncoding;
            options.SourceEncoding = Console.OutputEncoding;
            options.StreamWriter   = new StreamWriter(Console.OpenStandardOutput(),
                                                      Console.OutputEncoding);
            options.StreamWriter.AutoFlush = true;

            // The last parameter indicates whether the code should block until the external diff
            // viewer exits.  Set it to false if you are calling this from a GUI app.
            Difference.DiffFiles(item1.VersionControlServer, diffItem1, diffItem2,
                                 options, item1.ServerItem, true);
        }
예제 #6
0
    static public void ShowChangeset(VersionControlServer vcs,
                                     ChangesetVersionSpec versionSpec,
                                     bool brief, DiffOptions diffOpts)
    {
        int       changesetId = versionSpec.ChangesetId;
        Changeset changeset   = vcs.GetChangeset(changesetId, true, true);

        // fetch all items in one fell swoop
        List <int> ids = new List <int>();

        foreach (Change change in changeset.Changes)
        {
            ids.Add(change.Item.ItemId);
        }

        // find items in prior changeset
        Item[] items = vcs.GetItems(ids.ToArray(), changesetId - 1, true);
        SortedList <int, Item> itemList = new SortedList <int, Item>();

        foreach (Item item in items)
        {
            // itemId of 0 means a null item, IOW file was added in this changeset
            // and missing in prior changeset
            if (item.ItemId == 0)
            {
                continue;
            }
            itemList.Add(item.ItemId, item);
        }

        foreach (Change change in changeset.Changes)
        {
            // skip folders
            if (change.Item.ItemType == ItemType.Folder)
            {
                continue;
            }
            string p = change.Item.ServerItem.Substring(2);

            if (brief)
            {
                Console.WriteLine(p);
                continue;
            }

            IDiffItem a = new DiffItemNull();
            IDiffItem b = new DiffItemNull();

            string tnameA = null;
            string tnameB = null;

            if (((change.ChangeType & ChangeType.Add) != ChangeType.Add) &&
                (itemList.ContainsKey(change.Item.ItemId)))
            {
                Item itemA = itemList[change.Item.ItemId];

                tnameA = Path.GetTempFileName();
                itemA.DownloadFile(tnameA);

                a = new DiffItemLocalFile(tnameA, itemA.Encoding,
                                          changeset.CreationDate, true);
            }

            if ((change.ChangeType & ChangeType.Delete) != ChangeType.Delete)
            {
                tnameB = Path.GetTempFileName();
                change.Item.DownloadFile(tnameB);

                b = new DiffItemLocalFile(tnameB, change.Item.Encoding,
                                          changeset.CreationDate, true);
            }

            diffOpts.TargetLabel = versionSpec.DisplayString;
            Difference.DiffFiles(vcs, a, b, diffOpts, p, true);

            if (!String.IsNullOrEmpty(tnameA))
            {
                File.Delete(tnameA);
            }

            if (!String.IsNullOrEmpty(tnameB))
            {
                File.Delete(tnameB);
            }
        }
    }
예제 #7
0
        public IAnnotatedFile Annotate(string path, VersionSpec version)
        {
            var options = new DiffOptions
            {
                Flags = DiffOptionFlags.EnablePreambleHandling | DiffOptionFlags.IgnoreLeadingAndTrailingWhiteSpace | DiffOptionFlags.IgnoreEndOfLineDifference
            };

            PendingChange[] pendingChanges = server.GetWorkspace(path).GetPendingChanges(path);
            if (pendingChanges.Length >= 2)
            {
                throw new InvalidOperationException("Expected at most 1 pending change, but got " + pendingChanges.Length);
            }

            Changeset currentChangeset = null;

            AnnotatedFile annotatedFile;
            string        currentPath;
            int           currentEncoding;

            if (pendingChanges.Length == 1 && (pendingChanges[0].ChangeType & ChangeType.Edit) != 0)
            {
                annotatedFile = new AnnotatedFile(path, pendingChanges[0].Encoding);
                if (annotatedFile.IsBinary())
                {
                    return(annotatedFile);
                }
                currentPath     = path;
                currentEncoding = pendingChanges[0].Encoding;
            }
            else
            {
                annotatedFile   = null;
                currentPath     = null;
                currentEncoding = 0;
            }

            using (var historyProvider = new HistoryProvider(server, path, version))
            {
                var done = false;

                while (!done && historyProvider.Next())
                {
                    Changeset previousChangeset = historyProvider.Changeset();

                    string previousPath     = historyProvider.Filename();
                    int    previousEncoding = previousChangeset.Changes[0].Item.Encoding;

                    if (annotatedFile == null)
                    {
                        annotatedFile = new AnnotatedFile(previousPath, previousEncoding);
                        if (annotatedFile.IsBinary())
                        {
                            return(annotatedFile);
                        }
                    }
                    else if (previousEncoding == -1)
                    {
                        annotatedFile.Apply(currentChangeset);
                        done = true;
                    }
                    else
                    {
                        var diff = Diff(Difference.DiffFiles(currentPath, currentEncoding, previousPath, previousEncoding, options));
                        done = annotatedFile.ApplyDiff(currentChangeset, diff);
                    }

                    currentChangeset = previousChangeset;
                    currentEncoding  = previousEncoding;
                    currentPath      = previousPath;
                }

                if (annotatedFile != null)
                {
                    annotatedFile.Apply(currentChangeset);
                }
            }

            return(annotatedFile);
        }
예제 #8
0
        /// <summary>
        /// Create a difference string from a shelveset
        /// Also sets the URl to the file on the TFS Server
        /// </summary>
        /// <param name="set">The selected PendingSet</param>
        /// <returns>the diff String which is sent to Codestriker</returns>
        public string ReviewShelveset(
            PendingSet set)
        {
            if (set == null)
            {
                throw new ArgumentNullException(nameof(set));
            }


            MemoryStream stream = new MemoryStream();

            StreamWriter writer = new StreamWriter(stream);

            {
                DiffOptions options = new DiffOptions
                {
                    Flags          = DiffOptionFlags.EnablePreambleHandling,
                    OutputType     = DiffOutputType.Unified,
                    TargetEncoding = Encoding.UTF8,
                    SourceEncoding = Encoding.UTF8,
                    Recursive      = true,
                    StreamWriter   = writer
                };

                StringBuilder sb        = new StringBuilder();
                int           streampos = 0;
                foreach (var pendingchange in set.PendingChanges)
                {
                    if (pendingchange.ItemType != ItemType.Folder)
                    {
                        string fileUrl = string.Format(pendingchange.VersionControlServer.TeamProjectCollection.Uri.AbsoluteUri);
                        fileUrl += s_LinkCompletionVersioncontrol;
                        fileUrl +=
                            $"{HttpUtility.UrlEncode(pendingchange.PendingSetName + ";" + pendingchange.PendingSetOwner)}{s_PathParameter}";
                        fileUrl += HttpUtility.UrlEncode(pendingchange.LocalOrServerItem);
                        //the semicolons after s_ActionParameter and pendingchange.FileName are important for the right parsing on codestriker
                        fileUrl += $"{s_ActionParameter}&#path={HttpUtility.UrlEncode(pendingchange.LocalOrServerItem)}{s_ActionParameter};{pendingchange.LocalOrServerItem};";

                        var diffChange  = new DiffItemShelvedChange(set.Name, pendingchange);
                        var diffVersion = Difference.CreateTargetDiffItem(m_VersionControl, pendingchange, null);

                        Difference.DiffFiles(
                            m_VersionControl,
                            diffVersion,
                            diffChange,
                            options,
                            string.Empty,
                            true);

                        writer.Flush();
                        sb.Append(writer.GetHashCode()).Append(Environment.NewLine);
                        string pendingChangeString = Encoding.UTF8.GetString(stream.ToArray().Skip(streampos).ToArray());

                        Regex rgx = new Regex(s_RegexPattern);

                        //replace the filename with the tfs url path of the file
                        //necessary for the link between codestriker and TFS
                        pendingChangeString = rgx.Replace(
                            pendingChangeString,
                            m => m.Groups["prefix"].Value + ": " + fileUrl,
                            1);

                        sb.Append(pendingChangeString);
                        streampos = stream.ToArray().Length;
                    }
                }

                return(sb.ToString());
            }

            #endregion
        }
예제 #9
0
        public IAnnotatedFile Annotate(string path, VersionSpec version)
        {
            var options = new DiffOptions();

            options.Flags = DiffOptionFlags.EnablePreambleHandling;

            PendingChange[] pendingChanges = server.GetWorkspace(path).GetPendingChanges(path);
            if (pendingChanges.Length >= 2)
            {
                throw new InvalidOperationException("Expected at most 1 pending change, but got " + pendingChanges.Length);
            }

            Changeset currentChangeset = null;

            AnnotatedFile annotatedFile;
            string        currentPath;
            int           currentEncoding;

            if (pendingChanges.Length == 1 && (pendingChanges[0].ChangeType & ChangeType.Edit) != 0)
            {
                annotatedFile = new AnnotatedFile(path, pendingChanges[0].Encoding);
                if (annotatedFile.IsBinary())
                {
                    return(annotatedFile);
                }
                currentPath     = path;
                currentEncoding = pendingChanges[0].Encoding;
            }
            else
            {
                annotatedFile   = null;
                currentPath     = null;
                currentEncoding = 0;
            }

            var history = server.QueryHistory(path, version, 0, RecursionType.None, null, null, version, int.MaxValue, true, false, true, false);

            using (var historyProvider = new HistoryProvider(server, (IEnumerable <Changeset>)history))
            {
                bool done = false;

                while (!done && historyProvider.Next())
                {
                    Changeset previousChangeset = historyProvider.Changeset();

                    string previousPath     = historyProvider.Filename();
                    int    previousEncoding = previousChangeset.Changes[0].Item.Encoding;

                    if (annotatedFile == null)
                    {
                        annotatedFile = new AnnotatedFile(previousPath, previousEncoding);
                        if (annotatedFile.IsBinary())
                        {
                            return(annotatedFile);
                        }
                    }
                    else if (previousEncoding == -1)
                    {
                        annotatedFile.Apply(currentChangeset);
                        done = true;
                    }
                    else
                    {
                        var diff = Diff(Difference.DiffFiles(currentPath, currentEncoding, previousPath, previousEncoding, options));
                        done = annotatedFile.ApplyDiff(currentChangeset, diff);
                    }

                    currentChangeset = previousChangeset;
                    currentEncoding  = previousEncoding;
                    currentPath      = previousPath;
                }

                if (annotatedFile != null)
                {
                    annotatedFile.Apply(currentChangeset);
                }
            }

            return(annotatedFile);
        }
예제 #10
0
    public void ShowModifiedFiles(Workspace workspace, string path)
    {
        char[] charsToTrim = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
        string itemPath    = path.TrimEnd(charsToTrim);

        workspace.RefreshMappings();
        string serverPath = workspace.GetServerItemForLocalItem(itemPath);

        // pull item list based on WorkspaceVersion. otherwise might get
        // new items on server that haven't been pulled yet in the list returned
        WorkspaceVersionSpec version = new WorkspaceVersionSpec(workspace);

        // get item list from TFS server
        ItemSpec itemSpec = new ItemSpec(itemPath, RecursionType.Full);
        ItemSet  itemSet  = VersionControlServer.GetItems(itemSpec, version, DeletedState.NonDeleted, ItemType.Any, true);

        Item[] items = itemSet.Items;

        foreach (Item item in items)
        {
            if (item.ItemType != ItemType.File)
            {
                continue;
            }
            if (item.ServerItem.Length == serverPath.Length)
            {
                continue;
            }
            string serverItem = item.ServerItem.Remove(0, serverPath.Length + 1);

            // server item paths are separated with '/', but on windows the file list below has '\' separated paths
            if (Path.DirectorySeparatorChar != '/')
            {
                serverItem = serverItem.Replace('/', Path.DirectorySeparatorChar);
            }

            // only looking for modifications, not deletes or adds
            string fname = Path.Combine(itemPath, serverItem);
            if (!File.Exists(fname))
            {
                continue;
            }
            if (FileAttributes.ReadOnly == (File.GetAttributes(fname) & FileAttributes.ReadOnly))
            {
                continue;
            }

            using (FileStream fileStream = new FileStream(fname, FileMode.Open, FileAccess.Read))
            {
                string localHash = Convert.ToBase64String(md5.ComputeHash(fileStream));
                string itemHash  = Convert.ToBase64String(item.HashValue);
                if (itemHash == localHash)
                {
                    continue;
                }
            }

            string p = fname.Substring(path.Length + 1);
            if (OptionBrief)
            {
                Driver.WriteLine(CanonicalPath(p));
                continue;
            }

            string tnameA = Path.GetTempFileName();
            item.DownloadFile(tnameA);
            IDiffItem a = new DiffItemLocalFile(tnameA, item.Encoding, DateTime.Now, false);

            IDiffItem b = new DiffItemLocalFile(fname, item.Encoding, DateTime.Now, false);

            Difference.DiffFiles(VersionControlServer, a, b,
                                 GetDiffOptions(), p, true);

            if (!String.IsNullOrEmpty(tnameA))
            {
                File.Delete(tnameA);
            }
        }
    }