Marsh
Marsh

Reputation: 8125

Checkout remote branch

I have a remote git repository which has all the same files as an unversioned folder on my local machine. I want to add git tracking to my local folder so that I can pull changes from the remote repo as they are made. My local folder has a handful of differences from the remote that I don't want to lose, but is otherwise identical.

So far I have done:

cd /my/local/copy/
git init
git remote add origin [path to remote repo]
git fetch origin master

That worked nicely, now my local folder references the remote repo. The problem I'm at now is that the local folder has no branch checked out. If I try to checkout a remote branch, git refuses because all the folder's contents would be overwritten. If I git checkout -b master, it tells me it has "Switched to new branch 'master'". Okay good, now I just need to track the remote branch and I'm golden. git branch -u origin/master should do the trick. Git responds, "fatal: branch 'master' does not exist". Is it talking about origin/master, or my new local master? git branch -u origin/master2 - I expect this to fail, but it'll tell me which master git meant. Git once again responds, "fatal: branch 'master' does not exist". It's talking about my local branch, the one it just told me I had successfully checked out.

I think my problem is that the local master branch hasn't been officially created yet. As soon as I commit, it would exist, but I don't want to commit until I've added the remote tracking. Of course, I could be wrong, it might be something else.

How do I get from this point to where my local master is tracking origin/master, without stashing or moving all the local files or losing my local differences?

Upvotes: 0

Views: 736

Answers (2)

torek
torek

Reputation: 487755

It is possible to do what you want (by being slightly sneaky and manipulating things behind git's back, as it were) but it's more difficult to do that way. It's much better to use Dan Lowe's method.

That said, here's method (I leave out the initial cd just to avoid naming a directory); you're mostly there already:

$ git init
$ git remote add origin <url>

(at this point make sure that origin.fetch is set to the default +refs/heads/master:refs/remotes/origin/master, then:)

$ git fetch origin         # don't list any branches

This is almost what you did; the key difference is that this will fetch all their branches and put them under the origin/* name space in your own repository. Thus, you will now be able to refer to origin/master. (With the extra master argument, I think even current git fetch doesn't create a new origin/master, it only updates it if it exists. Certainly it won't have fetched any other branches, although that's not particularly important yet.)

In any case, you now have an "unborn branch master" (because that's how git init sets up a new, empty repository). Your first new commit will be a root commit, making your new branch, master. While it's possible to continue from there, I think it will be unnecessarily difficult.

Instead, now I think you should create a local branch master (as a "real branch", not an unborn one) referring to the same commit ID as their master:

$ git branch master origin/master

This should create local master (1) at the given commit (i.e., upstream/master) and (2) as "tracking" origin/master (because the default for this kind of new branch is --track).

You still have an empty index, though, so now it's time to populate it. I think the easiest way is using your current work-tree. But, I think you probably want their .gitignore files too, so let's at least get any top level one (there are more complicated ways to find sub-directory ignores, which might be good as well, but let's go with simple):

$ git show master:.gitignore

If this produces anything, repeat with output redirected:

$ git show master:.gitignore > .gitignore

Now it's probably mostly-safe to git add everything:

$ git add .

and now your index / staging-area is filled in enough to use git status to make progress (check for staged things that shouldn't be, due to .gitignore files being missing, for instance; and check for missing, apparently-removed files).

Upvotes: 3

Dan Lowe
Dan Lowe

Reputation: 56498

Depending on how many differences you have, it may be simpler to clone the repo and then copy your local version over the clone, then resolve the difference and commit it.

git clone <git-url> /new/repo/copy
cd /my/local/copy
tar cf - . | ( cd /new/repo/copy ; tar xf - )
git diff

This is assuming your statement that the repo has "all the same files as an unversioned folder on my local machine" is accurate, of course.

Upvotes: 1

Related Questions