1

I'm trying to clone a GitHub repository into a existing, non-empty directory. I tried mimicking the way it's done using the git command line:

git init
git remote add origin https://github.com/[...].git
git fetch
git reset --hard origin/branch

var git = Git.Init().SetDirectory(Location).Call();
Repository = git.GetRepository();

var config = Repository.GetConfig();
config.SetString("remote", "origin", "url", "https://github.com/[...].git");
config.Save();

git.Fetch().Call();

git.Reset().SetRef("origin/branch")
    .SetMode(ResetCommand.ResetType.HARD).Call();

In this particular case I got a "Nothing to fetch" error. I've tried a number of different things, including cloning into a temporary dictionary, using BranchCreate, ... but I've always ran into an issue somewhere.

So how would you go about properly cloning a repository and set it up to fetch updates in the future?

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
copygirl
  • 61
  • 8

1 Answers1

1

While cloning is easier than git init . + git remote add origin ... + git fetch + git reset --hard origin/master., that sequence is needed for a non-empty folder indeed.

In that case, you need to tell Git what to fetch, as commented by the OP:

git.Fetch().SetRefSpecs(new RefSpec("+refs/heads/*:refs/remotes/origin/*")).Call();

That will allow the git.Fetch().Call(); to actually fetch something.

(That is what the NGit.Test/NGit.Api/FetchCommandTest.cs L61-L82 is doing)

After extensive discussion in the chat, here is the code the OP is using:

var cloneUrl = ...;
var branchName = ...;
 
var git = Git.Init().SetDirectory(Location).Call();
Repository = git.GetRepository();
 
// Original code in question works, is shorter,
// but this is most likely the "proper" way to do it.
var config = Repository.GetConfig();
RemoteConfig remoteConfig = new RemoteConfig(config, "origin");
remoteConfig.AddURI(new URIish(cloneUrl));
// May use * instead of branch name to fetch all branches.
// Same as config.SetString("remote", "origin", "fetch", ...);
remoteConfig.AddFetchRefSpec(new RefSpec(
    "+refs/heads/" + Settings.Branch +
    ":refs/remotes/origin/" + Settings.Branch));
remoteConfig.Update(config);
config.Save();
 
git.Fetch().Call();
git.BranchCreate().SetName(branchName).SetStartPoint("origin/" + branchName)
    .SetUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK).Call();
git.Checkout().SetName(branchName).Call();
 
// To update the branch:
 
git.Fetch().Call();
git.Reset().SetRef("origin/" + branchName).Call();
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I'd rather avoid moving files if it's not too difficult. Can you explain why this is necessary? Is it a convenience thing in `git` that's not available in JGit? This is corrected fetch command by the way: `git.Fetch().SetRefSpecs(new RefSpec("+refs/heads/*:refs/remotes/origin/*")).Call();`. (Feel free to edit your answer and I'll edit out this part of the comment.) – copygirl Jun 27 '15 at 06:08
  • @copygirl moving files? No file has to be moved (the example might give this impression, but it is a test example). You don't have to `SetRefSpecs` when you `Clone`: the clone will do that for you. – VonC Jun 27 '15 at 06:12
  • [CloneCommand doesn't support cloning into a non-empty directory.](https://github.com/eclipse/jgit/blob/852963db3b6c58533e36104bf17f8758fd6071dc/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java#L150) – copygirl Jun 27 '15 at 06:18
  • To be perfectly honest, I'm not any closer to understanding what's going on. Your current answer is just more code to copy and all one can do is hoping it works. – copygirl Jun 27 '15 at 06:47
  • @copygirl Sure: try just to add the SetRefSpecs to your Fetch: that should be enough for your original code to work. – VonC Jun 27 '15 at 06:48
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81700/discussion-between-copygirl-and-vonc). – copygirl Jun 27 '15 at 06:51
  • @copygirl I have amended and edited the answer in order to include the conclusion of out chat discussion. – VonC Jun 27 '15 at 08:05
  • @copygirl I have updated the answer to take into account your V2 of your Gist (https://gist.github.com/copygirl/64826fc93b5c33db6621/revisions). – VonC Jun 27 '15 at 09:32