3 using System
.Collections
;
4 using System
.Collections
.Generic
;
6 using Microsoft
.TeamFoundation
.Client
;
7 using Microsoft
.TeamFoundation
.VersionControl
.Common
;
8 using Microsoft
.TeamFoundation
.VersionControl
.Client
;
11 [Command("difference", "Show pending changes, latest on server, a changeset, or local changes not pended as a unified diff.", "diff")]
12 class DifferenceCommand
: Command
14 [Option("Output only whether files differ", "q", "brief")]
15 public bool OptionBrief
= false;
17 [Option("Look for modified files", "", "modified")]
18 public bool OptionModified
= false;
20 [Option("Show out of date files (newer version on server)", "", "old")]
21 public bool OptionOld
= false;
23 [Option("Owner name", "O", "owner")]
24 public string OptionOwner
;
26 public DifferenceCommand(Driver driver
, string[] args
): base(driver
, args
)
30 protected DiffOptions
GetDiffOptions()
32 DiffOptions options
= new DiffOptions();
33 options
.UseThirdPartyTool
= false;
34 options
.Flags
= DiffOptionFlags
.EnablePreambleHandling
;
35 options
.OutputType
= DiffOutputType
.Unified
;
36 options
.TargetEncoding
= Console
.OutputEncoding
;
37 options
.SourceEncoding
= Console
.OutputEncoding
;
38 options
.StreamWriter
= new StreamWriter(Console
.OpenStandardOutput(),
39 Console
.OutputEncoding
);
40 options
.StreamWriter
.AutoFlush
= true;
45 public void ShowModifiedFiles(Workspace workspace
, string path
)
47 char[] charsToTrim
= { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}
;
48 string itemPath
= path
.TrimEnd(charsToTrim
);
50 workspace
.RefreshMappings();
51 string serverPath
= workspace
.GetServerItemForLocalItem(itemPath
);
53 // pull item list based on WorkspaceVersion. otherwise might get
54 // new items on server that haven't been pulled yet in the list returned
55 WorkspaceVersionSpec version
= new WorkspaceVersionSpec(workspace
);
57 // get item list from TFS server
58 ItemSpec itemSpec
= new ItemSpec(itemPath
, RecursionType
.Full
);
59 ItemSet itemSet
= VersionControlServer
.GetItems(itemSpec
, version
, DeletedState
.NonDeleted
, ItemType
.Any
, true);
60 Item
[] items
= itemSet
.Items
;
62 foreach (Item item
in items
)
64 if (item
.ItemType
!= ItemType
.File
) continue;
65 if (item
.ServerItem
.Length
== serverPath
.Length
) continue;
66 string serverItem
= item
.ServerItem
.Remove(0, serverPath
.Length
+1);
68 // server item paths are separated with '/', but on windows the file list below has '\' separated paths
69 if (Path
.DirectorySeparatorChar
!= '/')
70 serverItem
= serverItem
.Replace('/', Path
.DirectorySeparatorChar
);
72 // only looking for modifications, not deletes or adds
73 string fname
= Path
.Combine(itemPath
, serverItem
);
74 if (!File
.Exists(fname
)) continue;
75 if (FileAttributes
.ReadOnly
== (File
.GetAttributes(fname
) & FileAttributes
.ReadOnly
))
78 string p
= fname
.Substring(path
.Length
+1);
81 Console
.WriteLine(CanonicalPath(p
));
85 string tnameA
= Path
.GetTempFileName();
86 item
.DownloadFile(tnameA
);
87 IDiffItem a
= new DiffItemLocalFile(tnameA
, item
.Encoding
, DateTime
.Now
, false);
89 IDiffItem b
= new DiffItemLocalFile(fname
, item
.Encoding
, DateTime
.Now
, false);
91 Difference
.DiffFiles(VersionControlServer
, a
, b
,
92 GetDiffOptions(), p
, true);
94 if (!String
.IsNullOrEmpty(tnameA
)) File
.Delete(tnameA
);
98 public void ShowOldFiles(Workspace workspace
, string path
)
100 // process command options
101 ItemSpec itemSpec
= new ItemSpec(path
, RecursionType
.Full
);
103 List
<ItemSpec
> itemSpecs
= new List
<ItemSpec
>();
104 itemSpecs
.Add(itemSpec
);
106 ExtendedItem
[][] items
= workspace
.GetExtendedItems(itemSpecs
.ToArray(),
107 DeletedState
.NonDeleted
, ItemType
.Any
);
109 foreach (ExtendedItem
[] itemArray
in items
)
111 foreach (ExtendedItem item
in itemArray
)
113 if (item
.IsLatest
) continue;
115 string p
= item
.LocalItem
.Substring(path
.Length
);
118 Console
.WriteLine(p
);
122 IDiffItem a
= new DiffItemNull();
123 IDiffItem b
= new DiffItemNull();
125 if ((item
.ChangeType
& ChangeType
.Add
) != ChangeType
.Add
)
127 a
= new DiffItemLocalFile(item
.LocalItem
, item
.Encoding
,
128 DateTime
.Now
, false);
131 if ((item
.ChangeType
& ChangeType
.Delete
) != ChangeType
.Delete
)
133 b
= new DiffItemVersionedFile(VersionControlServer
,
134 item
.ItemId
, item
.VersionLatest
, item
.LocalItem
);
137 Difference
.DiffFiles(VersionControlServer
, a
, b
,
138 GetDiffOptions(), p
, true);
143 void ShowPendingChanges(Workspace workspace
, string path
)
145 PendingChange
[] pendingChanges
= workspace
.GetPendingChanges(path
, RecursionType
.Full
, true);
146 if (pendingChanges
.Length
== 0)
148 Console
.WriteLine("No pending changes.");
152 string cwd
= Environment
.CurrentDirectory
;
153 foreach (PendingChange change
in pendingChanges
)
155 string p
= change
.LocalItem
;
156 if (p
.StartsWith(cwd
)) p
= p
.Substring(cwd
.Length
+1);
160 Console
.WriteLine(CanonicalPath(p
));
164 IDiffItem a
= new DiffItemNull();
165 IDiffItem b
= new DiffItemNull();
170 tname
= Path
.GetTempFileName();
171 change
.DownloadBaseFile(tname
);
173 a
= new DiffItemLocalFile(tname
, change
.Encoding
,
174 change
.CreationDate
, true);
177 if (!change
.IsDelete
)
179 b
= new DiffItemLocalFile(change
.LocalItem
, change
.Encoding
,
180 change
.CreationDate
, false);
183 Difference
.DiffFiles(VersionControlServer
, a
, b
,
184 GetDiffOptions(), p
, true);
186 if (!String
.IsNullOrEmpty(tname
))
191 public override void Run()
193 string path
= Environment
.CurrentDirectory
;
194 if (Arguments
.Length
> 0)
196 path
= Path
.GetFullPath(Arguments
[0]);
199 Workspace workspace
= GetWorkspaceFromCache();
203 ShowOldFiles(workspace
, path
);
209 ShowModifiedFiles(workspace
, path
);
213 if (File
.Exists(path
) || Directory
.Exists(path
))
214 ShowPendingChanges(workspace
, path
);
217 VersionSpec versionSpec
= VersionSpec
.ParseSingleSpec(Arguments
[0], OwnerFromString(OptionOwner
));
218 if (versionSpec
is ChangesetVersionSpec
)
219 DiffHelper
.ShowChangeset(VersionControlServer
,
220 versionSpec
as ChangesetVersionSpec
,
221 OptionBrief
, GetDiffOptions());