Home > Back-end >  Fetch a remote branch into an existing repo that contains only one branch
Fetch a remote branch into an existing repo that contains only one branch

Time:07-02

I have been cloning a single branch only

git clone -b v1.1.1 --single-branch [myrepo].git

I've made changes that should actually be on branch v1.1.2, which exists on github.

I'm trying to fetch v1.1.2 to my existing repo, then move all my uncommitted files from v1.1.1 to v1.1.2

I've tried:

git clone -b v1.1.2 --single-branch [myrepo].git

But get

fatal: destination path [myrepo] already exists and is not an empty directory

Also from within the directory

git fetch v1.1.2

But get

fatal: v1.1.2 does not appear to be a git repository
fatal: could not read from remote repository

Can anyone help fetching another branch to the existing repo? and then moving my changes to the new branch?

Thanks

CodePudding user response:

You don't really "fetch a branch" (whatever that would mean: the term branch is ambiguous, in Git).1 You really fetch commits. However, at the end of the commit-fetching process, git fetch can update various names in your local repository as well. Normally these are remote-tracking names (which Git formally calls remote-tracking branch names, but that poor word branch, already nearly bludgeoned to death, is doing nothing useful in that phrase).

I have been cloning a single branch only [via] git clone -b v1.1.1 --single-branch [myrepo].git

This creates what Git calls a "single-branch clone". What that is, is a clone in which git fetch operations default to:

  • fetching commits reachable from a single particular branch name in the remote repository; and
  • updating only that one remote-tracking name in the local repository.

Git achieves this by setting remote.origin.fetch (assuming the remote is named origin) to refs/heads/v1.1.1:refs/remotes/origin/v1.1.1.

I'm trying to fetch v1.1.2 to my existing repo

What you want, in other words, is what we might call a "two-branch clone" if we follow the model Git provides (not a very good model, but...). This requires altering the default fetch setting. Fortunately, you don't have to fiddle directly with the remote.origin.fetch line(s) to do this. The git remote command can do this for you:

git remote set-branches --add origin v1.1.2

will do the job, adding a correct second remote.origin.fetch line.

(Side note: v names, in many repositories, are reserved for tag names rather than branch names. But that's just a convention, and apparently one your repository rejects.) After that, just run git fetch origin and origin/v1.1.2 will appear, assuming of course that there's a v1.1.2 branch in the Git repository over in origin.

then move all my uncommitted files from v1.1.1 to v1.1.2

That may be possible: you can try running git switch v1.1.2 (using the --guess mode to create a v.1.1.2 based on origin/v1.1.2). But it may not be possible. (For the gory details on when it's possible, see Checkout another branch when there are uncommitted changes on the current branch. If you can't just switch, either make a commit, or perhaps use git stash. I personally don't like git stash: I'd make a new branch first with git switch -c or git checkout -b, then commit, then switch to v1.1.2, then cherry-pick the commit made on the temporary branch.)


1Since the term branch is so poorly defined, we could just say that whatever commits we fetched were "the branch", and then we fetched "a branch". But that's kind of the Humpty Dumpty way of defining glory. I find the whole thing unsatisfying: too close to the philosophical fallacy of begging the question. That is, we start by saying "git fetch fetches a branch", then define "branch" as whatever git fetch fetches, and we end up no wiser than when we started.

CodePudding user response:

From within the existing repository, you can fetch the desired branch v1.1.2 from [myrepo].git into a new local branch with the same name (v1.1.2):

git fetch origin v1.1.2:v1.1.2

or if the repo isn't known as origin, then

git fetch [myrepo].git v1.1.2:v1.1.2

Left of : is the branch/commit to be fetched
Right of : is the new local branch name

If you omit the :v1.1.2 part, then the fetched commit will be temporarily available as FETCH_HEAD.
You could use that to e.g. run git branch v1.1.2 FETCH_HEAD or git checkout -b v1.1.2 FETCH_HEAD manually.

Note: You probably want to adjust your .git/config after, if you want the single-branch repository to automatically fetch v1.1.2 in future.

  • Related