158

I created a bare repo to publish my repository, but I can't figure out how to update the bare repo with the current state of the main repository.

Braiam
  • 1
  • 11
  • 47
  • 78
Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
  • 3
    See this answer: http://stackoverflow.com/questions/315911/git-for-beginners-the-definitive-practical-guide/2964397#2964397 – Ken Bloom Aug 01 '10 at 16:04

7 Answers7

102

If you want to duplicate all the objects from the main repo, do this inside the main repo:

git push --all <url-of-bare-repo>

Alternatively, do a fetch inside the bare repo:

git fetch <url-of-main-repo>

You cannot do a pull, because a pull wants to merge with HEAD, which a bare repo does not have.

You can add these as remotes to save yourself some typing in the future:

git remote add <whatever-name> <url-of-other-repo>

Then you can simply do

git push --all <whatever-name>

or

git fetch <whatever-name>

depending on what repo you're in. If <whatever-name> is origin, you can even leave it out altogether.


Disclaimer: I'm not a git guru. If I said something wrong, I'd like to be enlightened!

Update: Read the comments!

Update 2022-10-10: if you are fetching inside a bare git repo then you probably need to do a git fetch origin master:master otherwise your git log will not show the new commits. Use git fetch origin *:* to update all local branches. See comments for more info.

vagran
  • 867
  • 1
  • 7
  • 18
Thomas
  • 174,939
  • 50
  • 355
  • 478
  • The push seems to work just fine, thx for the hint I think I will be able to integrate this into a hook or something similar. – Šimon Tóth Aug 01 '10 at 16:18
  • 11
    When I did a `git-fetch --all` inside the bare repository, I didn't see updates I had made to the main repo, but when pushing them from the main repo with `git push --all ` I do see the updates in `git log`. Presumably there's a simple explanation for this - can someone explain? – pho79 Mar 01 '12 at 20:47
  • 1
    What do you mean by "didn't see"? I'm not sure how `git log` behaves in a bare repo; maybe try `git log --all`? – Thomas Mar 02 '12 at 22:06
  • 3
    @Thomas - Yeah, by "didn't see" I mean `git log` doesn't show these updates in the bare repo. (Neither does `git log --all`, and neither does a working repo that created by cloning the bare repo - either via `git log --all` or by simply looking at new files that should show up there). It's a pretty quick test to see for yourself. Mostly I'm just curious what I'm missing. – pho79 Mar 15 '12 at 23:12
  • Right, I see what you mean now. `git push` from the main repo pushes to the `master` branch in the bare repo, and does not concern itself with remote tracking branches. However, using `git fetch` only updates the remote tracking branch `origin/master`, and ignores the local branch `master`. So if the last thing you did was a `fetch`, then `git log origin/master` in the bare repo should show you the new commits. – Thomas Mar 16 '12 at 18:14
  • If you clone the bare repo, the clone also receives the out-of-date `master` branch, but the remote ref is not cloned along with it. To get those changes, do `git pull origin remotes/origin/master` to pull changes from the remote branch *as it exists in the bare repo*. Bottom line: it's probably best to always push, or always fetch, but not mix the two. Hope this makes some sense! – Thomas Mar 16 '12 at 18:16
  • 84
    If your remotest repo is something like github, where you don't have access, can't run push, etc, you can do `git fetch -q origin master:master` inside your local bare repo. This will fetch the new stuff from github's master branch and update your local master branch to it. – Altreus Jul 20 '12 at 11:39
  • 5
    @Altreus Indeed `master:master` is what is required to move HEAD forward to that of the remote repo. In my case because of a problem I couldn't connect to our bare repo anymore because git was missing. Until it gets solved I do a reverse tunnel and fetch to the central repo using: `git fetch ssh://localhost:8765/... master:master` and it works like a charm. Thanks! – estani Jan 22 '13 at 10:49
  • 11
    @Altreus If you want all branches then you can do `git fetch origin *:*` – JBert Aug 08 '19 at 14:08
  • @JBert's answer is what you're looking for – deepdive Jul 13 '22 at 03:56
  • @deepdive I think it is `git fetch -p origin *:*` if you really want to have the same stuff on remote and on origin... – 71GA Jun 30 '23 at 09:45
80

I created a repository using the following command

git clone --bare <remote_repo>

Then I tried to update the bare clone using the answer by Thomas, but it didn't work for me. To get the bare repository to update (which is what I think Let_Me_Be was asking), I had to create a mirror repository:

git clone --mirror <remote_repo>

Then I could run the following command in the mirrored repository to grab the main repository's updates:

git fetch --all

I came across this solution by reading Mirror a Git Repository By Pulling

Community
  • 1
  • 1
austen
  • 3,314
  • 3
  • 25
  • 26
  • 26
    To change an existing bare repo to mirror, all you need to do is add 2 lines to the git config file at .git/config. In the `[remote "origin"]` section, add `fetch = +refs/*:refs/*` and `mirror = true` – Isaac Betesh Aug 30 '13 at 14:39
66

The only solution besides recreating with git clone --mirror is from Gregor:

git config remote.origin.fetch 'refs/heads/*:refs/heads/*'

then you can git fetch and you'll see the updates. The weird thing is that before this, even though there is a remote configured, it has no branches listed in git branch -a.

Community
  • 1
  • 1
Colin D Bennett
  • 11,294
  • 5
  • 49
  • 66
  • 1
    This really helped me out! Capistrano project/repo also uses this setting to allow one-liner `git remote update` to do the job. – Minqi Pan Jul 14 '14 at 09:30
  • 1
    If the remote has force-updated or deleted branches (and you want to reflect those changes), you may need to add `--force` and `--prune` respectively to the `git fetch` line. – Elliott Slaughter Aug 06 '15 at 06:04
  • This is a: the real answer and b: essential to convert a bare repo into something that works will with git worktrees git clone --bare /.bare; cd ; echo "gitdir: ./bare" > .git; git config remote.origin.fetch 'refs/heads/*:refs/heads/*'; git fetch; git worktree add main; cd main; code . – Spitfire19 May 13 '23 at 16:01
50

Assuming:

$ git clone --bare https://github.com/.../foo.git

Fetch with:

$ git --git-dir=foo.git fetch origin +refs/heads/*:refs/heads/* --prune

Note: --git-dir=foo.git is not required if you cd to the directory first.

antak
  • 19,481
  • 9
  • 72
  • 80
  • 2
    Although I'm not aware when that occurs, if `origin` is not defined, you can always replace the `origin` part with the path/url to your original repository. e.g. `$ git --git-dir=foo.git fetch https://github.com/.../foo.git +refs/heads/*:refs/heads/*` – antak Jan 21 '16 at 02:38
  • This is exactly what I was looking for. This worked perfectly. – Maxime Rouiller Jun 25 '19 at 17:58
15

After much messing around I've found that this works for me.

Once:

git clone --mirror ssh://git@source.address:2000/repo
git remote add remote_site ssh://git@remote_site.address/repo
git config remote.origin.fetch 'refs/heads/*:refs/heads/*'

Everytime I want to sync:

cd /home/myhome/repo.git
git --bare fetch ssh://git@source.address:2000/repo
git  fetch ssh://git@source.address:2000/repo
git push --mirror remote_site
peterh
  • 11,875
  • 18
  • 85
  • 108
simonvc
  • 219
  • 2
  • 6
  • 7
    The third line (`git config remote.origin.fetch 'refs/heads/*:refs/heads/*'`) is the key. Good answer, thanks! – peterh Mar 27 '17 at 08:06
  • 2
    As @peterh said, the line `git config remote.origin.fetch 'refs/heads/*:refs/heads/*'` is the answer. After hitting this command, I can just `git fetch` and the repo syncs with the remote one. – joker Jun 21 '18 at 09:51
3

Add the bare repository as a remote repository, then use git push.

Philipp
  • 48,066
  • 12
  • 84
  • 109
  • So if I want to do this without pushing I can't use a bare repository and use a symbolic link or something like that? – Šimon Tóth Aug 01 '10 at 16:07
  • Pushing is the normal method for transferring repository contents to a bare repository, there is no need to avoid it. – Philipp Aug 01 '10 at 16:22
  • 5
    You can't always push. For example, if the bare is in a private network, and the main repos is a public one (on GitHub, for exemple) – fanf42 May 06 '13 at 17:12
2

For me this combination worked:

git remote add remote_site https://github.com/project/repo.git
git fetch -u remote_site +refs/heads/*:refs/heads/*
git fetch -u remote_site +refs/tags/*:refs/tags/*
git push --mirror

-u parameter for fetch was necessary, otherwise I get the error message: "Refusing to fetch into current branch refs/heads/master of non-bare repository" (see also https://stackoverflow.com/a/19205680/4807875)

Alexander Samoylov
  • 2,358
  • 2
  • 25
  • 28