How to perform git rebase using LibGit2Sharp? - libgit2sharp

I am writing a program that manipulates a git repo using the LibGit2Sharp library. One of the operations that I need to perform is a rebase to incorporate changes made to the master into a branch. How do I perform a git rebase master command using LibGit2Sharp? I haven't been able to find any examples of this.

What about something like
using(var repo = new Repository("path"))
{
var id = new Identity("name", "email");
var opt = new RebaseOptions();
var rebaseResult = repo.Rebase.Start(
featureBranch,
masterBranch,
null,
id,
opt);
}

The following is based on dontbyteme but will do a git pull --rebase:
using var gitRepo = new LibGit2Sharp.Repository(r.Path);
var remote = r.Network.Remotes["origin"];
var refSpecs = remote.FetchRefSpecs.Select(x => x.Specification);
Commands.Fetch(r, remote.Name, refSpecs, new FetchOptions { Prune = true }, string.Empty);
var id = new Identity("name", "email");
var opt = new RebaseOptions();
var rebaseResult = gitRepo.Rebase.Start(
branch: gitRepo.Head,
upstream: gitRepo.Head.TrackedBranch,
onto: null,
id,
opt
);

Related

How to Git Fetch <remote> using libgit2sharp?

My existing Fetch method looks like this.
public void Fetch(string remote) => CommandLine.Run($"git fetch {remote}", _repoFolder);
I would like to implement the same feature using libgit2sharp.
This is what I have came up with:
public void Fetch(string remote)
{
var repo = new Repository(_folder);
var options = new FetchOptions();
options.Prune = true;
options.TagFetchMode = TagFetchMode.Auto;
var refSpecs = $"+refs/heads/*:refs/remotes/{remote}/*";
Commands.Fetch(repo, remote, new [] {refSpecs}, options, "Fetching remote");
}
However this fails with the following error message:
System.InvalidOperationException: 'authentication cancelled'
I have also tried with the libgit2sharp-ssh package, where the result is error code 401 (unathorized client).
I presume the git command line tool works because it knows how to authorize the access (since there is already a remote). How can I achieve the same using libgit2sharp?
Have you tried something like
using(var repo = new Repository(_folder))
{
var options = new FetchOptions();
options.Prune = true;
options.TagFetchMode = TagFetchMode.Auto;
options.CredentialsProvider = new CredentialsHandler(
(url, usernameFromUrl, types) =>
new UsernamePasswordCredentials()
{
Username = "username",
Password = "password"
});
var remote = repo.Network.Remotes["origin"];
var msg = "Fetching remote";
var refSpecs = remote.FetchRefSpecs.Select(x => x.Specification);
Commands.Fetch(repo, remote.Name, refSpecs, options, msg);
}

LibGit2Sharp - Merge develop in master branch

I want to merge my develop in my master branch with LibGit2Sharp, but I can't find any examples on the GitHub wiki of LibGit2Sharp.
How can I do that?
Code snippet:
using (var repo = new Repository(repoDirectory))
{
var masterBranch = repo.Branches["master"];
var developBranch = repo.Branches["develop"];
Commands.Checkout(repo, masterBranch);
// merge dev in master
// tag master
Commands.Checkout(repo, developBranch);
// merge master in dev
}
I found a solution, I'm not sure if it could be done in another way, but I works.
using (var repo = new Repository(repoDirectory))
{
var masterBranch = repo.Branches["master"];
var developBranch = repo.Branches["develop"];
var merger = new Signature(AuthorName, AuthorEmail, DateTime.Now);
Commands.Checkout(repo, masterBranch);
repo.Merge(developBranch, merger, new MergeOptions());
repo.ApplyTag("v0.1");
Commands.Checkout(repo, developBranch);
repo.Merge(masterBranch, merger, new MergeOptions());
}

Retrieve firstparentonly on master using libgit2sharp

I want to retrieve commits from master first parent only using libgit2sharp, the equivalent command line statement is
git log --first-parent master --oneline
I know of the CommitFilter that I can use with QueryBy, like this
repo.Commits.QueryBy(new CommitFilter() { FirstParentOnly = true })
I'm getting commits on the branch that I'm currently on if I'm not on master. Can I limit the commit results to master, even when I'm on a different branch ?
I believe you are looking for the IncludeReachableFrom in the CommitFilter.
You might want to also use ExcludeReachableFrom at the same time to remove the commits from the branch that you are currently on...
using (var repo = new Repository("/Users/sushi/code/redux/playscript"))
{
var commitLog = repo.Commits.QueryBy(new CommitFilter() { FirstParentOnly = true, IncludeReachableFrom = "master" });
foreach (var commit in commitLog)
{
Console.WriteLine($"{commit.Sha}");
Console.ReadKey();
}
}

History log in sub directory

I'm trying to figure out how to get the commit log for a sub directory. According to this thread, it should work fine in libgit2sharp.
For testing I'm using a small repo, https://github.com/ornatwork/nugetpackages.git that has 8 total entries for the whole repository.
I cloned it locally in root c:/nugetpackages, from that folder I can do.
git log -- devbox
on the command line and I will get two commit entries for the /devbox sub directory as expected.
Sample Xunit test code to do the same using libgit2sharp
[Fact]
public void testSub()
{
// Extract the git commit history
using (var repo = new Repository(#"C:\nugetpackages"))
{
Trace.WriteLine("repo count=" + repo.Commits.Count());
// absolute path
IEnumerable<LogEntry> history = repo.Commits.QueryBy(#"C:\nugetpackages\devbox");
Trace.WriteLine("subdir count=" + history.Count());
}
}
I'm expecting count of 8 and 2, but this is what I get.
repo count=8
subdir count=0
What am I missing ?
Use a relative path from the repository's base diretory:
using (var repo = new Repository(#"/Users/sushi/code/sushi/Xamarin.Forms.Renderer.Tests"))
{
D.WriteLine("repo count=" + repo.Commits.Count());
IEnumerable<LogEntry> history = repo.Commits.QueryBy(#"AlarmSO");
D.WriteLine("subdir count=" + history.Count());
}
ref: FileHistoryFixture.cs
Update:
Follow up, is there a way to combine subdir with a filter, for example. CommitFilter filter = new CommitFilter(); filter.FirstParentOnly = true;
Not sure if this is what you are looking for... if not please in a new question, thanks.
using (var repo = new Repository(#"/Users/sushi/code/sushi/RealmJson"))
{
var subDir = "media";
var commits = repo.Commits.QueryBy(new CommitFilter { FirstParentOnly = true }).Where(
(Commit c) => c.Tree.Any(
(TreeEntry te) => te.Path.StartsWith(subDir, StringComparison.Ordinal)));
foreach (var commit in commits)
{
D.WriteLine($"{commit.Sha} : {commit.MessageShort}");
}
}

Can't update from a remote repository after having local changes

I'm currently trying to update my local repository from a remote one.
This works as long as I don't have any local changes in my files.
using (var r = new LibGit2Sharp.Repository(repo))
{
var options = new MergeOptions
{
MergeFileFavor = MergeFileFavor.Theirs,
};
var result = r.Network.Pull(localSignature, new PullOptions { MergeOptions = options });
}
I found that answer before: StackOverflow.
However, while trying this with the above code, it's just marking my repo as "Up2Date" (status of the result) instead of actually merging my local changes with the remote updates.
How can I actually achieve this?

Resources