How to pull latest from a specific remote branch without having need to provide user details?
Asked Answered
S

1

7

Requirement:

Using libgit2sharp I want to pull (fetch + merge) latest from a specific git remote branch to my currently checked out local branch, without having to pass any other argument, like user credentials etc. Basically I am trying to replicate git pull origin my-remote-branch

Details:

I want to automate certain Git operations from C#. I can simply do what I want by invoking git.exe (if I know the path), like git.exe --git-dir=my-repo-directory pull origin my-remote-branch. Notice that here the only external parameters I have to supply are my-repo-directory and my-remote-branch. Git gets everything right, like the name, password, email, current working branch (even if it doesnt have remote attached) and git pull simply works. I dont have to pass any of those parameters manually. I assume Git gets them from current Git settings for the repo (from %HOME% folder?).

Is there a way to simulate that in LibGit2Sharp?

What I tried:

using (var repo = new Repository("my-repo-directory"))
{
    PullOptions pullOptions = new PullOptions()
    {
        MergeOptions = new MergeOptions()
        {
            FastForwardStrategy = FastForwardStrategy.Default
        }
    };

    MergeResult mergeResult = Commands.Pull(
        repo,
        new Signature("my name", "my email", DateTimeOffset.Now), // I dont want to provide these
        pullOptions
    );
}

Which fails since it says there is no tracking branch. I dont necessarily need a tracking remote branch. I just want to fetch latest from a specific random remote repo and perform automerge if possible.

Just to see if it works I tried:

using (var repo = new Repository("my-repo-directory"))
{
    var trackingBranch = repo.Branches["remotes/origin/my-remote-branch"];

    if (trackingBranch.IsRemote) // even though I dont want to set tracking branch like this
    {
        var branch = repo.Head;
        repo.Branches.Update(branch, b => b.TrackedBranch = trackingBranch.CanonicalName);
    }

    PullOptions pullOptions = new PullOptions()
    {
        MergeOptions = new MergeOptions()
        {
            FastForwardStrategy = FastForwardStrategy.Default
        }
    };

    MergeResult mergeResult = Commands.Pull(
        repo,
        new Signature("my name", "my email", DateTimeOffset.Now),
        pullOptions
    );
}

This fails with

request failed with status code: 401

Additional info:

I dont want to invoke git.exe directly because I cant hardcode the git exe path. Also, since I cant pass username, email etc at runtime, is there a way libgit2sharp get them by itself from the repository settings, like how git.exe does?

Stinnett answered 19/10, 2017 at 15:30 Comment(0)
S
7

I assume Git gets them from current Git settings for the repo (from %HOME% folder?).

It depends entirely on what the remote "origin" is:

See here for a UsernamePasswordCredentials example.
See also LibGit2Sharp.Tests/TestHelpers/Constants.cs and other occurrences.


Regarding the pull operation, it involves a Command Fetch, which involves a refspec. As in "Git pull/fetch with refspec differences", you can pass the source:destination branch names for your pull (even if there is no tracking information).

That is what is used in LibGit2Sharp.Tests/FetchFixture.cs.

string refSpec = string.Format("refs/heads/{2}:refs/remotes/{0}/{1}", remoteName, localBranchName, remoteBranchName);
Commands.Fetch(repo, remoteName, new string[] { refSpec }, new FetchOptions {
                TagFetchMode = TagFetchMode.None,
                OnUpdateTips = expectedFetchState.RemoteUpdateTipsHandler
}, null);
Suint answered 23/10, 2017 at 16:51 Comment(15)
Will have a look at this later and get back to you.Stinnett
@Stinnett OK. A simple "git remote -v" is a good start to know what kind of URL you are dealing with. And since your main issue is 401 (lack of valid authentication), this answer is about addressing authentication issue.Suint
the problem is even if I manage the user credentials, what would be the API to specify the branch I want to pull from?Stinnett
@Stinnett First, let's resolve the authentication issue. Then, if you have setup the tracking branch (https://mcmap.net/q/1622767/-using-libgit2sharp-to-pull-latest-from-a-branch) a simple pull will be enough.Suint
Hmm, maybe I wasnt clear enough in the question, but I don't want to set a tracking branch. If I do I am messing up with other developers' settings. This is a part of automating pull operations from various remote branches for all the devs. But I think a quick fix would be set it and then reset it to its original tracked branch.Stinnett
@Stinnett Then you need to pass in the pull option the name of the remote branch you want to pull from. But remember: the question is first about authentication: as long as it is not solved, no git command involving a remote will work.Suint
I will work on authentication and all the steps later. Just skimming through the source code I dont see the option to specify remote branch in pull options.Stinnett
@Stinnett you do so by specifying a refspec: github.com/libgit2/libgit2sharp/blob/master/LibGit2Sharp.Tests/… (git-scm.com/book/en/v2/Git-Internals-The-Refspec) like https://mcmap.net/q/13103/-git-pull-fetch-with-refspec-differencesSuint
@Stinnett I have edited the answer to include the pull branch specification part.Suint
I do not see a way to pass in the username/password in either Pull or Fetch. Those test cases dont but succeed and I dont see how.Stinnett
@Stinnett yes you can: the parameter is the refspec you set in the fetch option: it will include the local branch name, remote name (origin) and the remote branch name from which you want to fetch.Suint
True, refspec has branch details. I am talking about credential details. Where in to pass it? I keep getting 401.Stinnett
First, what is your remote url? An https one or an SSH one?Suint
@Stinnett to set credentials with Fetch, pass a CredentialsHandler in your FetchOptions. Return either UsernamePasswordCredentials or DefaultCredentials from your handler, as appropriate.Kolodgie
@EdwardThomson Thank you. I have included your comment in the answer for more visibility.Suint

© 2022 - 2024 — McMap. All rights reserved.