I am trying to find an efficient way to get the previous revision of a file to do a text comparison using SharpSVN.
using (SvnClient c = new SvnClient())
{
c.Authentication.DefaultCredentials = new NetworkCredential(
ConfigurationManager.AppSettings.Get("SvnServiceUserName")
, ConfigurationManager.AppSettings.Get("SvnServicePassword")
, ConfigurationManager.AppSettings.Get("SvnServiceDomain")
);
c.Authentication.SslServerTrustHandlers += new EventHandler<SvnSslServerTrustEventArgs>(Authentication_SslServerTrustHandlers);
Collection<SvnFileVersionEventArgs> fileVersionCollection = new Collection<SvnFileVersionEventArgs>();
SvnRevisionRange range = new SvnRevisionRange(0, this.hooks.Revision);
SvnFileVersionsArgs args = new SvnFileVersionsArgs();
args.RetrieveProperties = true;
args.Range = range;
foreach (SvnChangeItem item in log.ChangedPaths)
{
string path = this.repositoryPath + item.Path;
bool gotFileVersions = false;
try
{
if (item.NodeKind == SvnNodeKind.File)
gotFileVersions = c.GetFileVersions(SvnTarget.FromString(path), args, out fileVersionCollection);
The code above is an example of performing my request, however it is extremely inefficient. My goal is to be able to select a revision, and also the previous revision. For example, if my repository is at r185, but I want to view the file at revision 100, and also view the same file's previous revision (which I wouldn't know what is), how can this be done?
I've looked at c.GetInfo() but this seems to only get the previous revision to the most current commit.
Thanks!
Try only getting the versions you're looking for. I'm assuming log is an instance of SvnLoggingEventArgs?
If so, use:
args.Range = new SvnRevisionRange(log.Revision, log.Revision - 1);
That way you'll only retrieve the changes from that revision, and because log.Revision is guaranteed to be the revision number of the change, if you subtract one, you have the previous version.
Do you need the Previous version (the version before the last commit) or the local unmodified version.
The Subversion working copy library has the following 'magic' versions
Working (SvnRevision.None) - What you have in your working copy
(includes local modifications)
Head (SvnRevision.Head) - The last committed version of a url in the
repository
Base (SvnRevision.Base) - The version you last committed or updated to.
Committed (SvnRevision.Comitted) - The last revision <= BASE in which the path was
modified
Previous (SvnRevision.Previous) - The last revision before Committed.
(Literally Committed-1)
To get one of these versions you can use SvnClient.Write()
using (SvnClient c = new SvnClient())
using (Stream to = File.Create(#"C:\temp\my.tmp"))
{
c.Write(new SvnPathTarget(#"F:\projects\file.cs", SvnRevision.Base), to);
}
The files for Working and Base are available locally. For the other versions Subversion has to contact the repository.
Related
I'm using AWS.NET SDK and I'm trying to use S3CopyObjectOperation with CreateJob from batch operations. It works fine, I'm generating manifest on the fly with the following content:
mysourcebucket,folder/subdir/file1.txt
mysourcebucket,folder/subdir/file2.txt
Now I'm creating a job with CreateJob with the following request:
new CreateJobRequest(){
// some values ommited
Operation = new JobOperation(){
S3PutObjectCopy = new S3CopyObjectOperation{
StorageClass = Standard,
TargetResource = dstBucketArn,
TargetKeyPrefix = dstSubdir
}
},
Manifest = new JobManifest(){
Spec = new JobManifestSpec(){Fields={"Bucket","Key"}, Format= JobManifestFormat.S3BatchOperations_CSV_20180820},
Location= new JobManifestLocation(){
ObjectArn = //manifest key,
Etag = // manifest Etag
}
}
}
It is copying the files correctly under dstBucket. Output:
dstSubdir/folder/subdir/file1.txt
dstSubdir/folder/subdir/file2.txt
Is it possible to change target path somehow, so it doesn't include folder? Expected output:
dstSubdir/subdir/file1.txt
dstSubdir/subdir/file2.txt
Edit: Imageine simple scenario where I want to copy these objects and at some point copy them back into the same location. I won't be able to do that if I use TargetPrefix. In above example I'd create
targetbucket,dstSubdir/folder/subdir/file1.txt
targetbucket,dstSubdir/folder/subdir/file2.txt
And output would be in srcbucket:
srcSubdir/dstSubdir/folder/subdir/file1.txt
srcSubdir/dstSubdir/folder/subdir/file2.txt
The only solution that would work is not to use TargetPrefix at all and keep the same structure in src and dst buckets which is quite a big restriction in my case.
Ideally I'd like to pass
my-bucket,{"origKey": "object1key", "newKey": "newObject1Key"}
my-bucket,{"origKey": "object2key", "newKey": "newObject2Key"}
my-bucket,{"origKey": "object3key", "newKey": "newObject3Key"}
as presented in this example https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-invoke-lambda.html
I want to create a push using TFS git client libraries that contains the specified workitems.
The code is basically:
public static async Task<GitPush> CreatePush(
this GitHttpClient git,
GitRepository repo,
GitRefUpdate branchUpdateRef,
GitChange change,
String comment,
IEnumerable<Int32> workitems = null)
{
workitems = (workitems ?? Enumerable.Empty<Int32>()).ToList();
var commit = new GitCommitRef
{
Comment = comment,
Changes = new[]
{
change
},
WorkItems = workitems
.Select(wi => new ResourceRef
{
Id = wi.ToString()
// Perhaps one should also set an URL of some kind
})
.ToList()
};
var push = new GitPush
{
Commits = new[]
{
commit
},
RefUpdates = new[]
{
branchUpdateRef
},
Repository = repo
};
return await git.CreatePushAsync(
push,
project: repo.ProjectReference.Id,
repositoryId: repo.Id);
}
The push is created successfully, though there are no workitem links on the created commit.
I have tried
Setting the URL to the one from https://learn.microsoft.com/en-us/rest/api/vsts/wit/work%20items/get%20work%20item?view=vsts-rest-4.1#workitem .
Settings it to the slightly different workitem URL that is actually returned in GitCommitRef.WorkItems ResourceRef for commits that have related workitems.
But to no avail.
I actually can achieve the desired final result by
Either appending $"#{workitemId}" to the commit comment string
Or by adding commit link to the workitem in question
Still, both of those solutions have minor drawbacks(1 - changing commit message, 2 - possible race condition with CI and etc.) that I'd prefer to avoid.
Basically, is there a way to way to create GitPush with associated workitems in a single operation, or do I have to use the aforementioned workarounds?
No, there isn't any way to achieve this. Even when you create a commit/push from TFS Web UI, TFS still create the commit/push first and then update the work item to link to the push.
I would like to view all of the commits since the last time the user pushed from their machine.
using (var repo = new Repository(repositoryDirectory))
{
var c = repo.Lookup<Commit>(shaHashOfCommit);
// Let's only consider the refs that lead to this commit...
var refs = repo.Refs.ReachableFrom(new []{c});
//...and create a filter that will retrieve all the commits...
var cf = new CommitFilter
{
Since = refs, // ...reachable from all those refs...
Until = c // ...until this commit is met
};
var cs = repo.Commits.QueryBy(cf);
foreach (var co in cs)
{
Console.WriteLine("{0}: {1}", co.Id.ToString(7), co.MessageShort);
}
}
I got this code from another post, but I am not sure how to modify it to get the commits since the date of the last push.
You want the commits that are reachable from c, excluding the ones that are reachable from the remote commit.
If you're talking about master, in a typical setup, the tracking branch for this will be remotes/origin/master. refs/remotes/origin/master will be updated when you push to the remote master branch.
So your CommitFilter should look like:
new CommitFilter { Since = repo.Refs["refs/remotes/origin/master"], Until = c }
Which is equivalent to git log refs/remotes/origin/master..c.
I have a project that will automatically merge and commit from a list of user-selected revisions from one branch to another. If a merge conflict occurs, the process is aborted and the working copy is reverted.
However, when I go to try again and select a revision that would normally not cause a conflict on a pristine working copy, I get the following error:
Merge failed: SharpSvn.SvnWorkingCopyException: Can't merge into conflicted node 'C:\SVN\MyProject\MyBranch\ProjectDirectory\SubDirectory\conflicted-file.cs'
Even if I do a revert on the working copy, it only appears to revert the svn:mergeinfo property, but not the files within (conflicted or not, the old files are still there). Is it not reverting recursively? I'm not seeing an option to do so otherwise.
Here's what I've tried so far:
using (var client = new SvnClient())
{
// [Authentication code goes here...]
var targetPath = $#"{_svnLocalRoot}\{project}\{branch}\";
// Clean Up
var cleanupArgs = new SvnCleanUpArgs()
{
BreakLocks = true,
ClearDavCache = true,
VacuumPristines = true,
FixTimestamps = true
};
client.CleanUp(targetPath, cleanupArgs);
// Revert
var revertArgs = new SvnRevertArgs()
{
Depth = SvnDepth.Infinity,
ClearChangelists = true
};
client.Revert(targetPath);
// Update
var updateArgs = new SvnUpdateArgs()
{
Depth = SvnDepth.Infinity
};
client.Update(targetPath, updateArgs);
// [Merge and commit code goes here...]
}
Short of deleting the entire working directory and doing a check-out (which takes a very long time), what do I need to do to get my working copy to a pristine state with no conflicts and the latest code?
I'm currently using SharpSvn.1.9-x64 version 1.9005.3940.224
It was as simple as a typo.
client.Revert(targetPath);
should have been:
client.Revert(targetPath, revertArgs);
I'd like to build a site which simply displays the top latest (by date, revision?) "n" commit logs plus other associated info.
What's the best way to do this? I started having a quick look at SharpSvn, but the GET seems to be based on Revision ranges rather than date.
I'd like a simple example for .Net in c# based on any available library which gets the job done.
Since you mentioned using SharpSVN, I happen to have written this in BuildMaster:
private static IList<string> GetLatestCommitMessages(Uri repository, int count)
{
using (var client = new SvnClient())
{
System.Collections.ObjectModel.Collection<SvnLogEventArgs> logEntries;
var args = new SvnLogArgs()
{
Limit = count
};
client.GetLog(repository, args, out logEntries);
return logEntries.Select(log => log.LogMessage).ToList();
}
}