Git Mailing List Archive mirror
 help / color / mirror / Atom feed
From: Sebastian Tennant <sdt@sebyte.me>
To: git@vger.kernel.org
Subject: How to publish a fork
Date: Fri, 26 May 2023 11:13:49 +0000	[thread overview]
Message-ID: <87pm6ne45u.fsf@sebyte.me> (raw)

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

                 reply	other threads:[~2023-05-26 11:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87pm6ne45u.fsf@sebyte.me \
    --to=sdt@sebyte.me \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).