Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a remote tracking branch to stay up to date with remote origin in a bare Git repository?

I am trying to maintain a bare copy of a Git repository and having some issues keeping the remote tracking branches up to date. I create the remote tracking branches like this:

git branch -t 0.1 origin/0.1

This seems to do what I need to do for that point in time. However, if I make changes to origin and then fetch with the bare repo, things start to fall apart. My workflow looks like this:

git fetch origin

It looks like all of the commits come in at that point, but my local copy of 0.1 is not being updated. I can see that the changes have been brought into the repository by doing the following:

git diff 0.1 refs/remotes/origin/0.1

What do I need to do to get my tracking branch updated with the remote's updates? I feel like I must be missing a step or a flag somewhere.

Updated: Additional Clarification

Normally one would push into a bare repository, rather than run git fetch from within it. If you can arrange to do that, life will be much easier.

Here is a bit of clarification on the workflow.

The project's public git repository is hosted on GitHub. I am managing the project (wiki, issues, forums) using Redmine. Redmine requires a local bare repository in order to operate. When GitHub receives changes it pings Redmine. Redmine then attempts to fetch changes from its origin (GitHub).

This works great if I'm just working with master but it was not working with my tracking branches. The changes were being imported but were not being listed in the branch in Redmine repository browser because the local branches were not being updated.

I'm sure I could have worked this out another way but finding a (generic) solution to getting the tracking branches up and running was definitely my preference as most of the git related plugins for Redmine assume things like "git fetch origin" is all that needs to be done.

See accepted answer for the complete solution. The --mirror solution seems to be exactly what is needed in this case.

like image 738
Beau Simensen Avatar asked Jan 15 '11 08:01

Beau Simensen


People also ask

How do I setup my remote branch to track origin?

You can check tracking branches by running the “git branch” command with the “-vv” option. We can set the upstream branch using the “git push” command. $ git push -u origin branch Total 0 (delta 0), reused 0 (delta 0) * [new branch] branch -> branch Branch 'branch' set up to track remote branch 'branch' from 'origin'.

How can I tell which remote branch is being tracked?

There is a command that gives you about all tracking branches. And to know about the pull and push configuration per branch you can use the command git remote show origin. and you can use -sb option for seeing the upstream. Hope this information will help you to find which branch is tracking.

Does git pull affect remote?

The short answer is simple: no, the remote-tracking branch remains unaffected.

When managing forks which command can you use to fetch and merge the remote branch in a single step?

If you have a branch set up to track a remote branch (see the next section and [ch03-git-branching] for more information), you can use the git pull command to automatically fetch and then merge a remote branch into your current branch.


1 Answers

Normally one would push into a bare repository, rather than run git fetch from within it. If you can arrange to do that, life will be much easier.

If you have to fetch rather than push, and you just want to create a mirror of origin in your bare repository, you could avoid having remote-tracking branches entirely. If you're starting this mirror from scratch, Charles Bailey points out below that git will do all of this setup for you if you initially clone the repository with git clone --mirror.

Otherwise, you could get a similar effect with:

git fetch origin +refs/heads/*:refs/heads/*

The + means that this will overwrite the state of your local branches with those from the remote. Without the +, updates that aren't fast-forward merges will be rejected. However, if this is just a mirror, that shouldn't matter. (You can configure this to be the default action on git fetch origin by setting the config variable remote.origin.fetch to +refs/heads/*:refs/heads/*. If you want to mirror tags and remote-tracking branches from origin as well, you could use +refs/*:refs/* instead.)

However, if, as you originally ask, you want to maintain remote-tracking branches and selectively merge them into local branches, you can use the following steps, but I don't necessarily recommend them unless you're the only person using this bare repository. (Note: originally here I suggested using "git symbolic-ref HEAD refs/heads/whatever" to switch branch and "git reset --soft" to change the branch ref - however, Charles Bailey pointed out in the comments out that one can use "git update-ref refs/heads/whatever refs/remotes/origin/whatever", which doesn't require one to switch branch first.)

First, you might want to check that updating the branch would have been a fast-forward merge, and after that update the branch. Note that there is a race condition here, which is why I say you should only do this if you are the only person using your local bare repository - the check would be useless if someone else moves on the branch between those steps.

  1. You can check that an equivalent merge would be a fast-forward (i.e. that the history of origin/master includes master) by comparing git merge-base master origin/master with git show-ref master - they should be the same. Or you could use the is-ancestor script in this question, which does those commands with some additional checks.)
  2. Finally, you can update your current branch (master in this case) to point to origin/master with git update-ref refs/heads/master refs/remotes/origin/master

However, as I said at the beginning, I imagine that the real solution you want is either:

  • Pushing into your bare repository instead or
  • Mirroring the remote bare repository exactly, as I described above

I hope that's of some use.

like image 83
Mark Longair Avatar answered Oct 20 '22 02:10

Mark Longair