using libgit2sharp to pull latest from a branch - c#

I am using libgit2sharp in a c# solution to switch to a branch and pull in the latest changes. Here is the code I am using:
public void FetchAll()
{
using (var repo = new Repository(_LocalGitPath))
{
foreach (Remote remote in repo.Network.Remotes)
{
FetchOptions options = new FetchOptions();
options.CredentialsProvider = new CredentialsHandler((url, usernameFromUrl, types) => new UsernamePasswordCredentials()
{
Username = _UserName,
Password = _Password
});
repo.Network.Fetch(remote, options);
}
}
}
public string CheckoutBranch(string branchName)
{
using (var repo = new Repository(_LocalGitPath))
{
var trackingBranch = repo.Branches[branchName];
if (trackingBranch.IsRemote)
{
branchName = branchName.Replace("origin/", string.Empty);
var branch = repo.CreateBranch(branchName, trackingBranch.Tip);
repo.Branches.Update(branch, b => b.TrackedBranch = trackingBranch.CanonicalName);
Commands.Checkout(repo, branch, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force });
}
else
{
Commands.Checkout(repo, trackingBranch, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force });
}
return branchName;
}
}
public void PullBranch(string branchName)
{
using (var repo = new Repository(_LocalGitPath))
{
PullOptions options = new PullOptions();
options.MergeOptions = new MergeOptions();
options.MergeOptions.FailOnConflict = true;
options.FetchOptions = new FetchOptions();
options.FetchOptions.CredentialsProvider = new CredentialsHandler((url, usernameFromUrl, types) => new UsernamePasswordCredentials()
{
Username = _UserName,
Password = _Password
});
repo.Network.Pull(new Signature(_UserName, _Password, new DateTimeOffset(DateTime.Now)), options);
}
}
I have no problem fetching, and checking out a branch. When I try to pull latest, I get an error saying, 'There is no tracking information for the current branch.' I believe that this means that the local branch doesn't know what the correct remote repository is to pull changes from, but I haven't been able to figure out how to tell libgit2sharp what the remote repo path is. Anyone have any suggestions?
While doing research on this problem I found this: https://github.com/libgit2/libgit2sharp/issues/1235. Essentially, a libgit2sharp dev describes the exact problem I am seeing, but doesn't provide any code for the fix.
One additional note: I will never be merging or pushing any changes back from this repository. I am pulling it for an automated build, so we can ignore or overwrite any local changes. I just need to get the latest code.
SOLUTION:
I have updated the code above with the solution that I got working. You need to be really careful to make sure that when you checkout a branch, you check the isRemote flag on the branch you are checking out is set to true. If you checkout a branch that isn't a remote it will set the remote to '.' in your git config file, and you need to manually fix it. If there isn't a valid remote you will not be able to pull the branch changes.
Do not use the code sample on the libgit2sharp wiki unless they add this check in.

You can setup the tracking brach information on the local branch by using the Refspec:
using (var repo = new Repository("/Users/sushi/code/redux/mono"))
{
var trackingBranch = repo.Branches["remotes/origin/work-btls"];
if (trackingBranch.IsRemote)
{
var branch = repo.CreateBranch("SomeLocalBranchName", trackingBranch.Tip);
repo.Branches.Update(branch, b => b.TrackedBranch = trackingBranch.CanonicalName);
repo.Checkout(branch, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force });
}
}
You can use git to verify that SomeLocalBranchName is now tracking remotes/origin/work-btls:
>>>git for-each-ref --format='%(refname:short) <- %(upstream:short)' refs/heads
SomeLocalBranchName <- remotes/origin/work-btls
master <- origin/master
>>>git status
On branch SomeLocalBranchName
Your branch is up-to-date with 'remotes/origin/work-btls'.

Related

How to get git branch information about each of commit by using 'LibGit2sharp'

I'd like to make 'Commit History Graph' by using libgit2sharp library like below.
There was a similar question in stackoverflow, but I couldn't get the specific answer.
How do I build a version tree for a Git repository using LibGit2(Sharp)
Here is my source code.
string path = "c:\github\git-gui-app";
var repo = Repository(path);
var commits = repo.Commits();
var list = new List<CommitItem>();
foreach (var item in commits)
{
var commitItem = new CommitItem();
commitItem.Name = item.Message;
commitItem.Sha = item.Sha;
commitItem.ParentSha = item.Parents.FirstOrDefault().Sha;
list.Add(commitItem);
}
foreach (var item in list)
{
item.BranchInfo = GetBranchInfo(item);
}
...
private BranchItem GetBranchInfo(CommitItem item)
{
// How to get branch information in current commit?
}
I succeeded in getting the git repository commit information,
but I still don't know how to get branch information of each commit.

libgit2sharp get all commits since the last 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.

Getting "mergable revisions" with SharpSvn

When setting up a merge, the TortoiseSvn client has a wonderful checkbox labeled "Hide non-mergable revisions". I'm looking to reproduce the list of revisions that shows up when it's enabled using SharpSvn.
The TortoiseSvn documentation explains this checkbox:
When merge tracking is used, the log dialog will show previously merged revisions, and revisions pre-dating the common ancestor point, i.e. before the branch was copied, as greyed out. The Hide non-mergeable revisions checkbox allows you to filter out these revisions completely so you see only the revisions which can be merged.
How can I reproduce this functionality in SharpSvn code? I need a list of SvnLogEventArgs (or similar) that are candidates for merging.
Current status: I've only gotten as far as pulling the logs for both branches. I can't figure out how to get the appropriate svn:mergeinfo attribute or what to do with it once I get it.
I kept plugging away, and following links, and here's what I ended up with:
using (var client = new SvnClient())
{
var release = SvnTarget.FromUri(new Uri(#"https://******/branches/Release"));
var trunk = SvnTarget.FromUri(new Uri(#"https://******/trunk"));
string trunkMergeinfo, releaseMergeinfo;
client.GetProperty(release, "svn:mergeinfo", out releaseMergeinfo);
client.GetProperty(trunk, "svn:mergeinfo", out trunkMergeinfo);
var relInfos = releaseMergeinfo.Split("\n");
var trunkInfos = trunkMergeinfo.Split("\n");
// This is here because I don't know what will happen once I merge something into trunk.
Debug.Assert(relInfos.Except(trunkInfos).Count() == 1,"Too many unknown merge paths");
var trunklist = relInfos.SingleOrDefault(i => i.StartsWith("/trunk:"));
var revisions = trunklist.Replace("/trunk:", "").Split(",").SelectMany(t =>
{
// If the log contains a range, break it out to it's specific revisions.
if (t.Contains("-"))
{
var match = Regex.Match(t, #"(\d+)-(\d+)");
var start = int.Parse(match.Groups[1].Value);
var end = int.Parse(match.Groups[2].Value);
return Enumerable.Range(start, end - start + 1).ToArray();
}
else
return new[] { int.Parse(t) };
}).Select(x => (long)x);
Collection<SvnLogEventArgs> baseRevs;
// Why can't this take "trunk" or a property thereof as an argument?
client.GetLog(new Uri(#"https://******/trunk"), new SvnLogArgs { Start = 1725, End = SvnRevisionType.Head }, out baseRevs);
baseRevs.Reverse().Where(r => !revisions.Contains(r.Revision) ).Select(x => x.LogMessage).Dump();
}
Hopefully, this helps someone else, although I'll note that it does not have a lot of the sanity checking that I'd put in production code - this is the quick-and-dirty version.
Try SvnClient.ListMergesEligible:
http://sharpsvn.qqn.nl/current/html/M_SharpSvn_SvnClient_ListMergesEligible_1.htm
Edit.
SharpSVN seems bugged for me, so I went for cmd.
Check this out:
private static void mergelhetőVerziókListája()
{
string revíziók = cmd("svn", "mergeinfo --show-revs eligible \".../branches/dev\" \".../trunk\"");
}
private static string cmd(string utasítás, string paraméter)
{
StringBuilder eredmény = new StringBuilder();
Process cmd = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = utasítás,
Arguments = paraméter,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
cmd.Start();
while (!cmd.StandardOutput.EndOfStream)
{
string kimenet = cmd.StandardOutput.ReadLine();
eredmény.AppendLine(kimenet); //...
}
return eredmény.ToString();
}

NetSuite custom record search through suiteTalk using C#

We are having an issue with searching a custom record through SuiteTalk. Below is a sample of what we are calling. The issue we are having is in trying to set up the search using the internalId of the record. The issue here lies in in our initial development account the internal id of this custom record is 482 but when we deployed it through the our bundle the record was assigned with the internal Id of 314. It would stand to reason that this internal id is not static in a site per site install so we wondered what property to set up to reference the custom record. When we made the record we assigned its “scriptId’ to be 'customrecord_myCustomRecord' but through suitetalk we do not have a “scriptId”. What is the best way for us to allow for this code to work in all environments and not a specific one? And if so, could you give an example of how it might be used.
Code (C#) that we are attempting to make the call from. We are using the 2013.2 endpoints at this time.
private SearchResult NetSuite_getPackageContentsCustomRecord(string sParentRef)
{
List<object> PackageSearchResults = new List<object>();
CustomRecord custRec = new CustomRecord();
CustomRecordSearch customRecordSearch = new CustomRecordSearch();
SearchMultiSelectCustomField searchFilter1 = new SearchMultiSelectCustomField();
searchFilter1.internalId = "customrecord_myCustomRecord_sublist";
searchFilter1.#operator = SearchMultiSelectFieldOperator.anyOf;
searchFilter1.operatorSpecified = true;
ListOrRecordRef lRecordRef = new ListOrRecordRef();
lRecordRef.internalId = sParentRef;
searchFilter1.searchValue = new ListOrRecordRef[] { lRecordRef };
CustomRecordSearchBasic customRecordBasic = new CustomRecordSearchBasic();
customRecordBasic.recType = new RecordRef();
customRecordBasic.recType.internalId = "314"; // "482"; //THIS LINE IS GIVING US THE TROUBLE
//customRecordBasic.recType.name = "customrecord_myCustomRecord";
customRecordBasic.customFieldList = new SearchCustomField[] { searchFilter1 };
customRecordSearch.basic = customRecordBasic;
// Search for the customer entity
SearchResult results = _service.search(customRecordSearch);
return results;
}
I searched all over for a solution to avoid hardcoding internalId's. Even NetSuite support failed to give me a solution. Finally I stumbled upon a solution in NetSuite's knowledgebase, getCustomizationId.
This returns the internalId, scriptId and name for all customRecord's (or customRecordType's in NetSuite terms! Which is what made it hard to find.)
public string GetCustomizationId(string scriptId)
{
// Perform getCustomizationId on custom record type
CustomizationType ct = new CustomizationType();
ct.getCustomizationTypeSpecified = true;
ct.getCustomizationType = GetCustomizationType.customRecordType;
// Retrieve active custom record type IDs. The includeInactives param is set to false.
GetCustomizationIdResult getCustIdResult = _service.getCustomizationId(ct, false);
foreach (var customizationRef in getCustIdResult.customizationRefList)
{
if (customizationRef.scriptId == scriptId) return customizationRef.internalId;
}
return null;
}
you can make the internalid as an external property so that you can change it according to environment.
The internalId will be changed only when you install first time into an environment. when you deploy it into that environment, the internalid will not change with the future deployments unless you choose Add/Rename option during deployment.

Is it possible to use fluent migrator in application_start?

I'm using fluent migrator to manage my database migrations, but what I'd like to do is have the migrations run at app start. The closest I have managed is this:
public static void MigrateToLatest(string connectionString)
{
using (var announcer = new TextWriterAnnouncer(Console.Out)
{
ShowElapsedTime = true,
ShowSql = true
})
{
var assembly = typeof(Runner).Assembly.GetName().Name;
var migrationContext = new RunnerContext(announcer)
{
Connection = connectionString,
Database = "SqlServer2008",
Target = assembly
};
var executor = new TaskExecutor(migrationContext);
executor.Execute();
}
}
I'm sure I had this working, but I've not looked at it for sometime (hobby project) and it's now throwing null reference exceptions when it gets to the Execute line. Sadly there are no docs for this and I've been banging my head on it for ages.
Has anyone managed to get this kind of thing working with FluentMigrator?
PM> Install-Package FluentMigrator.Tools
Manually add a reference to:
packages\FluentMigrator.Tools.1.6.1\tools\AnyCPU\40\FluentMigrator.Runner.dll
Note that the folder name will vary on version number, this illustration uses the current 1.6.1 release. If you need the .NET 3.5 runner use the \35\ directory.
public static class Runner
{
public class MigrationOptions : IMigrationProcessorOptions
{
public bool PreviewOnly { get; set; }
public string ProviderSwitches { get; set; }
public int Timeout { get; set; }
}
public static void MigrateToLatest(string connectionString)
{
// var announcer = new NullAnnouncer();
var announcer = new TextWriterAnnouncer(s => System.Diagnostics.Debug.WriteLine(s));
var assembly = Assembly.GetExecutingAssembly();
var migrationContext = new RunnerContext(announcer)
{
Namespace = "MyApp.Sql.Migrations"
};
var options = new MigrationOptions { PreviewOnly=false, Timeout=60 };
var factory =
new FluentMigrator.Runner.Processors.SqlServer.SqlServer2008ProcessorFactory();
using (var processor = factory.Create(connectionString, announcer, options))
{
var runner = new MigrationRunner(assembly, migrationContext, processor);
runner.MigrateUp(true);
}
}
}
Note the SqlServer2008ProcessorFactory this is configurable dependent upon your database, there is support for: 2000, 2005, 2008, 2012, and 2014.
I have actually accomplished running migrations in the application_start however it is hard to tell from that code what could be wrong... Since it is open source I would just grab the code and pull it into your solution and build it to find out what the Execute method is complaining about. I found that the source code for Fluent Migrator is organized pretty well.
One thing that you might have to be concerned about if this is a web app is making sure that no one uses the database while you are migrating. I used a strategy of establishing a connection, setting the database to single user mode, running the migrations, setting the database to multi user mode, then closing the connection. This also handles the scenario of a load balanced web application on multiple servers so 2 servers don't try to run migrations against the same database.

Categories

Resources