How to get a list of revision using sharpsvn - c#

How do I get a list of revisions from sharpsvn

If you look at the metadata for SvnLogEventArgs (which is returned as a collection from GetLog) it derives from SvnLoggingEventArgs, which has properties of Author, Revision, Time and LogMessage (amongst others)
Each SvnLogEventArgs item has a collection of ChangedPaths, which have properties for SvnChangeAction, and Path.

You can get a list of all the log info by this method:
var client = new SvnClient();
System.Collections.ObjectModel.Collection<SvnLogEventArgs> logEventArgs;
client.GetLog("targetPath", out logEventArgs);
Iterating through all the logEventArgs will give you some useful information - LogMessage, Author, etc.
I don't know what you're doing, but I am checking the latest version of the working copy using SvnWorkingCopyClient:
var workingCopyClient = new SvnWorkingCopyClient();
SvnWorkingCopyVersion version;
workingCopyClient.GetVersion(workingFolder, out version);
The latest version of the local working repository is then available through
long localRev = version.End;
For a remote repository, use
var client = new SvnClient();
SvnInfoEventArgs info;
client.GetInfo(targetUri, out info);
long remoteRev = info.Revision;
instead.
This is similar to using the svnversion tool from the command line. Hope this helps.

Guessing at what your question really is about the answer is most likely SvnClient.Log(), to get you a list of changes of a path.
Another anwer would be:
for (int i = 1; i < 101; i++)
yield return i;
to get you the first 100 revisisions of a repository ;-)
See Using SharpSvn to retrieve log entries within a date range for some examples on how to use SvnClient.Log()

This is the code form which you can get all the revisions no in list revisions numbers. UriSCpath will be uri for svn path.
SvnTarget tr = SvnTarget.FromUri(UriSCPath);
Collection<SvnLogEventArgs> logEventArgs;
List<Int64> revisionNumbers = new List<Int64>();
SvnLogArgs logArgs = new SvnLogArgs();
DPISVN_Clnt.GetLog(UriSCPath, logArgs, out logEventArgs);
Int64 latestReision = logEventArgs[0].Revision;
foreach (var item in logEventArgs)
{
revisionNumbers.Add(item.Revision);
}

Related

Looking for examples how to use the Google Sheets API FilterCriteria object

I am trying to understand how to construct an AddFilterViewRequest in the Google Sheets API. However, there don't seem to be any good examples that I can locate in any programming language which demonstrate how it is used.
Specifically, I am trying to understand the FilterCriteria object, and what I need to set hiddenValues and condition to.
In my application I am trying to construct a filter that will only show the rows where the cell in the column I have selected is not empty. I can do this manually in the Google Sheets editor, and I want to replicate the same settings in my program.
This is the code as it stands...
Request request = new Request();
request.AddFilterView = new AddFilterViewRequest();
request.AddFilterView.Filter = new FilterView();
request.AddFilterView.Filter.FilterViewId = 0;
request.AddFilterView.Filter.Title = "Hide rows with errors";
request.AddFilterView.Filter.Range = new GridRange();
request.AddFilterView.Filter.Range.SheetId = 0;
request.AddFilterView.Filter.Range.StartColumnIndex = 8;
request.AddFilterView.Filter.Range.EndColumnIndex = 9;
FilterCriteria criteria = new FilterCriteria();
//criteria.Condition = BooleanCondition;
criteria.HiddenValues = new List<string>();
//criteria.HiddenValues.Add("item");
IDictionary<string, FilterCriteria> criteriaDictionary = new Dictionary<string, FilterCriteria>();
//criteriaDictionary.Add("string", criteria);
request.AddFilterView.Filter.Criteria = criteriaDictionary;
The lines that are commented out at the moment are the ones that I can seeking assistance with. I am also trying to find out what the string variable should be for the criteriaDictionary.
After posting this question I realised one way I could answer it myself would be to reverse engineer an existing spreadsheet where this filter was already applied. Based on that, I now have the following working code...
FilterCriteria criteria = new FilterCriteria();
criteria.Condition = new BooleanCondition();
criteria.Condition.Type = "NOT_BLANK";
IDictionary<string, FilterCriteria> criteriaDictionary = new Dictionary<string, FilterCriteria>();
criteriaDictionary.Add("8", criteria);
Request request = new Request();
request.AddFilterView = new AddFilterViewRequest();
request.AddFilterView.Filter = new FilterView();
request.AddFilterView.Filter.FilterViewId = 0;
request.AddFilterView.Filter.Title = "Hide rows with errors";
request.AddFilterView.Filter.Range = range1;
request.AddFilterView.Filter.Criteria = criteriaDictionary;
requests.Add(request);
I don't know why they key value was set to 8, but that's what it was in the existing spreadsheet (and that sheet only had one Filter View in it). Anyway I copied it, and it works, so I haven't found a need to change it.
I don't have a good setup right now to construct the appropriate code here (perhaps someone else can amend this or add an answer with the code inline), but in general your best bet right now for figuring out the "right way" to construct complex objects like this in the API is to create one with the UI and then do a spreadsheets.get call. You can look at the resulting object and mimic the FilterView (with your own modifications as necessary).

Finding changesets associated with the work item or having specific comment TFS Api

I'm trying to find all changesets associated with the work item using Microsoft.TeamFoundation.WorkItemTracking.Client. Using query I was able to get the information about the work items in question, however I cannot find any changeset information on the object I'm getting back. In addition to that there are some changesets that are not linked to specific work item but easy identifiable by the comment. Is there a quick way to find these using tfs api?
Edit: this is not a duplicate of How to get work items associated with a changeset id using tfs api? b/c in that question person has a changeset and would like to find associated work items. In my case I have a work items and I would like to find all changesets associated with the specific work items. In addition to that I need to find all changesets that have specific string in the comment.
After more googling on the subject and exploring tfs API here is what I ended up with:
If all you changesets are linked to the work items (not really my case but this is what I originally was asking about):
// based on https://etoptanci.wordpress.com/2011/05/04/seeing-all-code-changes-for-a-work-item/
private static void GetChangesForWorkItem()
{
var configurationServer = TfsConfigurationServerFactory.GetConfigurationServer(new Uri(#"http://myserver:8080/tfs"));
var tpcService = configurationServer.GetService<ITeamProjectCollectionService>();
var collectionNodes = configurationServer.CatalogNode.QueryChildren(
new[] { CatalogResourceTypes.ProjectCollection },
false, CatalogQueryOptions.None);
var collectionNode = collectionNodes.First(x => x.Resource.DisplayName == "<collection name>");
// Use the InstanceId property to get the team project collection
Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection collection = configurationServer.GetTeamProjectCollection(collectionId);
var vcs = collection.GetService<VersionControlServer>();
var store = new WorkItemStore(collection);
var workItems = new List<WorkItem>()
{
store.GetWorkItem(1123),
store.GetWorkItem(1145),
};
var associatedChangesets = new List<Changeset>();
foreach (var workItem in workItems)
{
foreach (var link in workItem.Links)
{
if((link==null) || !(link is ExternalLink))
continue;
string externalLink = ((ExternalLink)link).LinkedArtifactUri;
var artifact =LinkingUtilities.DecodeUri(externalLink);
if (artifact.ArtifactType == "Changeset")
associatedChangesets.Add(vcs.ArtifactProvider.GetChangeset(new Uri(externalLink)));
}
}
Console.WriteLine(associatedChangesets.Select(x=>x.ChangesetId).OrderBy(x => x));
}
If you need to get by comment as well then you gate all changesets for the daterange and then filter out by Changeset.Comment which is a string.
Check the REST API:
GET https://{instance}/defaultcollection/_apis/tfvc/changesets/{id}?api-version={version}[&includedetails={boolean}&includeworkitems={boolean}&includesourcerenames={boolean}&maxchangecount={int}&maxcommentlength={int}]
You can also use RestAPI (as stated in the first answer)
https://www.visualstudio.com/en-us/docs/integrate/api/wit/work-items#with-links-and-attachments
You need to filter out "relations" array with rel == "ArtifactLink"

Find a if filename does not exist in array of variable names

I have a list of zipped files that contains a ZipArchive and the zipped filename as a String. I also have a final list of filenames that I need to check with my List and if the files do not match with my final list of filenames they should be dumped from my zipped file list.
I under stand that may not be worded the best so let me try and explain with my code/pseudo code.
Here is my list:
List<ZipContents> importList = new List<ZipContents>();
Which has two parameters:
ZipArchive which is called ZipFile
String which is called FileName
filenames is the finale list of file names that I am trying to check my ZipContents list against.
Here is the start of what I am trying to do:
foreach (var import in importList)
{
var fn = import.FileName;
// do some kind of lookup to see if fn would be List<String> filenames
// If not in list dump from ZipContents
}
The commented out section is what I am unsure about doing. Would someone be able to help get me on the right track? Thanks!
EDIT 1
I know I did not say this originally but I think that LINQ would be the much cleaner route to take. I am just not positive how. I am assuming that using .RemoveAll(..) would be the way I would want to go?
Loop through importList in reverse and remove items when not found in filenames. Assuming you don't have too many items performance should be fine:
for (int i = importList.Count - 1; i >= 0; i--)
{
if (!filenames.Contains(importList[i].FileName))
{
importList.RemoveAt(i);
}
}
You can't remove items from the list using a foreach because it modifies the collection, but you can do it with the construct in my example.
You could do something like:
if (!filenames.Contains(fn)) {
importList.Remove(import);
}
Alternatively, I believe you could use Linq to simplify this logic into just one line.
Edit:
Yes, you can just create a new list of just the ones you want, like this:
var newImportList = importList.Where(il => filenames.Contains(il.FileName)).ToList();
You can do this in one line. Just use LINQ to re-establish your list:
var filenames = new List<string> {"file1", "file2"};
var zipcontents = new List<ZipContents>
{
new ZipContents {FileName = "file1"},
new ZipContents {FileName = "file2"},
new ZipContents {FileName = "file3"}
};
zipcontents = zipcontents.Where(z => filenames.Contains(z.FileName)).ToList();
//zipcontents contains only files that were in 'filenames'
Honestly, this is what LINQ was made for: querying data.

tfs command line 'merge' equivalent in .NET

EDIT: poor wording of my question. What I am trying to achieve is to 'discard' the merge history of the changeset
EDIT 2
I worked out how I can remove the changeset from the merge candidate queue. I don't particularly think it is a good idea but I am including the code simply for 'completeness' sake.
SCENARIO: developer fixes bug on branch and checks in. Developer then fixes bug on trunk instead of merging (trunk has changed dramatically therefore not merging). However the changeset appears in the list when merging from the branch to the trunk. I am trying to mark this changeset to remove it from this list. This can be done using the commandline utility by passing the 'discard' switch...I am tryinh to achive the same using the TFS API..
I think I am pretty close by use of the Merge method but am not sure of the options to pass in. I do NOT want to perform a merge just want to mark the changeset as merged without merging
have got a list of changesets from TFS using a Winforms app and would like be able to merge a changeset by calling discard on it using C#
the merge command is here
can this be done using the TFS .NET libraries or do I have to call the commandline editor from the winforms app?
//get the merge candidates
IEnumerable<MergeCandidate> mergeCandidates =
_vcs.GetMergeCandidates(cboSource.Text, cboTarget.Text, RecursionType.Full)
.OrderByDescending(x => x.Changeset.ChangesetId)
.AsEnumerable();
//user select a changeset from a grid and then I want to discard this changeset from the //'merge list'
string _changeset = grdChangeSets.CurrentRow.Cells[0].Value.ToString();
VersionSpec vfrom = VersionSpec.ParseSingleSpec(_changeset, null);
VersionSpec vto = VersionSpec.ParseSingleSpec(_changeset,null);
_workspaces[0].Merge(cboSource.Text, cboTarget.Text, vfrom, vto, LockLevel.None, RecursionType.Full,
MergeOptions.AlwaysAcceptMine);
EDIT 2 CODE
string _changeSetId = grdChangeSets.CurrentRow.Cells[0].Value.ToString();
VersionSpec vfrom = VersionSpec.ParseSingleSpec(_changeSetId, null);
VersionSpec vto = VersionSpec.ParseSingleSpec(_changeSetId, null);
UsiWorkspace wksp = new UsiWorkspace();
wksp.ResolveConflicts(_workspaces[0]);
GetStatus getStatus = _workspaces[0].Merge(cboSource.Text,
cboTarget.Text,
vfrom,
vto,
LockLevel.None,
RecursionType.Full,
MergeOptions.AlwaysAcceptMine);
var _conflicts = workspaces[0].QueryConflicts(null, true);
foreach (Conflict conflict in _conflicts)
{
conflict.Resolution = Resolution.DeleteConflict;
workspace.ResolveConflict(conflict);
}
var wip = new WorkspaceCheckInParameters(_workspaces[0].GetPendingChanges(),string.Format("CHECKED IN FROM TFS TOOL - {0} {1}", DateTimeOffset.Now.ToString(), Environment.UserName))
{
OverrideGatedCheckIn = ((CheckInOptions2) _vcs.SupportedFeatures & CheckInOptions2.OverrideGatedCheckIn) ==
CheckInOptions2.OverrideGatedCheckIn,
PolicyOverride = new PolicyOverrideInfo("CHECKED IN FROM TFS TOOL - POLICY", null)
};
_workspaces[0].CheckIn(wip);
There is a merge method in the TFS api : http://msdn.microsoft.com/en-us/library/ff731634.aspx
Perhaps something like this :
var status = _workspace.Merge(sourceTfsPath, targetTfsPath, null, null, LockLevel.None, RecursionType.Full,
MergeOptions.AlwaysAcceptMine);
Trace.WriteLine(status.NumOperations);
var conflicts = _workspace.QueryConflicts(null, true);
foreach (var conflict in conflicts)
{
conflict.Resolution = Resolution.AcceptYours;
_workspace.ResolveConflict(conflict);
}

Tracking a user change in active directory

I'm writing an application that needs to know if anything on the users active directory object (eg group membership) has altered since the last time the app was ran.
I was looking at the whenChanged attribute but that appears only to change if the user changes their password. I just need something i can hold in my config file, and check that value in active directory the next time the app is ran.
Anyone know of anything i can reliably use?
Cheers
Luke
Given that you are primarily concerned with groups, I think you'll have to create a hash - modifying group membership won't affect the user object.
Here's a quick example I've knocked up.
public static string HashGroups(string user)
{
DirectoryEntry directoryEntry = default(DirectoryEntry);
DirectorySearcher dirSearcher = default(DirectorySearcher);
List<string> result = new List<string>();
directoryEntry = new DirectoryEntry("LDAP://<YOUR_DOMAIN>");
directoryEntry.RefreshCache();
// Get search object, specify filter and scope,
// perform search.
dirSearcher = new DirectorySearcher(directoryEntry);
dirSearcher.PropertiesToLoad.Add("memberOf");
dirSearcher.Filter = "(&(sAMAccountName=" + user + "))";
SearchResult sr = dirSearcher.FindOne();
// Enumerate groups
foreach (string group in sr.Properties["memberOf"])
{
result.Add(group);
}
// OrderBy is important! Otherwise, your hash might fail because
// the groups come back in different order.
MD5 md5 = MD5.Create();
Byte[] inputBytes = Encoding.ASCII.GetBytes(result.OrderBy(s1 => s1).SelectMany(s2 => s2).ToArray());
byte[] hash = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
PREVIOUS (rubbish) ANSWER
According to the docs, the Modify-Time-Stamp attribute is "A computed attribute representing the date when this object was last changed." which sounds like what you want. It's available in all versions back to 2000.
EDIT It looks like this is computed from whenChanged, so if that is not working for you then this may not.
You could always check the Directory's properties for last write or modification time and maybe keep some XML or some data that keeps track of last write times of files.

Categories

Resources