1
votes

I want to clone a repo, and I want the clone to have all the tags from the original. I can do this manually like so

$ git clone --mirror https://github.com/{org}/{SourceProjectName}.git
$ cd {SourceProjectName}.git
$ git push --mirror https://github.com/{org}/{ProjectName}

It seems libgit2sharp is the best way to do this, but if there's a better way let me know.

I don't understand how to do it with libgit2sharp It seems I have to do a clone, then somehow copy refs Then I have to iterate over all of those refs and stage them all... then commit? I started working on doing all this but it feels like I'm re-inventing the wheel...

Where I looked so far:

2

2 Answers

1
votes

I don't know if this is the ideal solution but this seems to do the trick:

private void DuplicateGitHubRepo()
{
    var clonePath = Path.Combine(Path.GetTempPath(), "Temp-" + Guid.NewGuid() + ".git");
    var co = new CloneOptions
    {
        CredentialsProvider = GetGitCredentials()
    };

    Repository.Clone(SourceProjectUrl+".git", clonePath, co);
    using (var repo = new Repository(clonePath))
    {
        repo.Network.Remotes.Update("origin", x => x.Url = TargetProjectUrl);
        var options = new PushOptions
        {
            CredentialsProvider = GetGitCredentials()
        };
        repo.Network.Push(repo.Network.Remotes["origin"],repo.Refs.Select(x=>x.CanonicalName),options);
    }
}
0
votes

Your linked issue had the solution.

A git mirror clone is just a clone with a remote origin set to +refs/*:refs/*

using (var repo = new Repository(Repository.Init(@"path\to\local.git", true)))
{
    var remote = repo.Network.Remotes.Add("origin", "https://github.com/{org}/{SourceProjectName}.git", "+refs/*:refs/*");
    repo.Network.Fetch(remote /* anything for report progress */);
}

The RemoteCollection.Add() method looks like the following: public virtual Remote Add(string name, string url, string fetchRefSpec)

Basically that third parameter is where you need to set that special refspec.