Hello list, I wish to publish a fork of an upstream git repository (as a means of distributing modifications to upstream across multiple machines). Let's call the publishing repo fork.git, the machine which hosts fork.git the fork host, and the machines which clone fork.git clients of the fork host. fork.git includes unmodified upstream branches and additional branches not found upstream. The additional branches all share a common namespace; mod-*. For example, mod-master is an additional branch based on upstream branch master. A cron job running on the fork host automatically fetches from upstream every 30 minutes using a mirror refspec, e.g. +refs/heads/master:refs/heads/master. Clients of the fork host also use a mirror refspec for upstream branches and an ordinary fetch refspec for the additional branches, e.g. +refs/heads/mod-master:refs/remotes/forkhost/mod-master. To summarise, the resulting configs look something like this: Fork host config (extract): --8<---------------cut here---------------start------------->8--- [remote "upstream"] url = https://example.com/upstream.git fetch = +refs/heads/master:refs/heads/master --8<---------------cut here---------------end--------------->8--- Fork host client config (extract): --8<---------------cut here---------------start------------->8--- [remote "forkhost"] url = https://fork.host/fork.git fetch = +refs/heads/master:refs/heads/master fetch = +refs/heads/mod-master:refs/remotes/forkhost/mod-master [branch "mod-master"] remote = forkhost merge = refs/heads/mod-master --8<---------------cut here---------------end--------------->8--- In order to keep an additional branch up to date with upstream, a client need only fetch from the fork host, rebase on the upstream branch, and then push (back to the fork host). For example: $ cd mod-master $ git fetch --verbose forkhost […] 4b3de748b0..f35648ba0c master -> master = [up to date] mod-master -> forkhost/mod-master $ git status --short --branch ## mod-master...forkhost/mod-master $ git log --oneline ..master | wc -l 1 $ git rebase master Successfully rebased and updated refs/heads/mod-master. $ git status --short --branch ## mod-master...forkhost/mod-master [ahead 3, behind 2] Note that, although there was only one ‘incoming’ commit, mod-master and forkhost/mod-master have diverged (by 3 and 2 commits respectively). This is because there were (and are) two commits on mod-master not found on master. After fetching, C is the ‘incoming’ commit: master: ---A---B---C mod-master: ---A---B---X---Y forkhost/mod-master: ---A---B---X---Y After reabsing: master: ---A---B---C mod-master: ---A---B---C---X'---Y' forkhost/mod-master: ---A---B---X---Y As you can see, mod-master and forkhost/mod-master now diverge after B (by 3 and 2 commits respectively). This means that when the client tries to push, the updates are rejected: $ git push To [forkhost] ! [rejected] mod-master -> mod-master (non-fast-forward) error: failed to push some refs to [forkhost] hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. unless force is used: $ git push --force […] + cbb90030a9...5299b8bf0d mod-master -> mod-master (forced update) It is obviously dangerous and wrong for a client to use force every time it pushes to fork.git. What if the client failed to notice incoming commits on mod-master (as well as on master)? Those missed, incoming commits might be irretrievably lost. So, how should one _safely_ publish a fork? Sebastian