The replication queue coalesces edits together according to the
replication delay. The default delay IIRC is 30 seconds. So if you
delete a branch and then create it again within 30 seconds that will
coalesce together to simply pushing that branch. Unfortunately its
not recorded as needing to be a force-push. So unless your
replication.config specifies force push on the branch, the push will
fail with a non-fast-forward error.
> To fix it, I had to delete the branches in all the mirrors, then force the
> replication again.
Yes. Sounds like your replication.config didn't specify force push.
> Questions:
> - do branch deletions get replicated?
Yes, like any other change.
> - is this approach of deleting/creating branches through web-ui
> (non-)recommended?
Its fine. It just can cause an issue here with the replication. :-\
A better way to reset a branch would have been to force push it... but
that still would have failed in replication because its sounds like
your replication.config doesn't force push to the remotes.
> - (I didn't test it) If I delete a branch through "git push origin :branch",
> does this deletion gets replicated?
Yes.
> Just trying to understand if there is a bug in the replication.
> My thoughts: yes, it is a bug. Because it is not replicating an action taken
> in the repo.
I'm not sure I would call this a bug. Your replication.config should
be configured to force-push to the remote if the remote is willing to
accept a force push. If the remote absolutely should not get rewound,
then its correct to have replication fail, as it indicates the remote
is out-of-sync with the local Gerrit server.
However, maybe there is a bug here that a rapid delete-create sequence
within the replication delay window isn't actually mirrored as a
delete-create sequence to the remote, but instead got coalesced into
an update. Perhaps we should instead recognize a delete-create
sequence and actually issue that same delete-create on the remote.
Wow, its really not documented.
I assumed you could look this up in the official git docs, like in
git-push [1], because the remote format is the same. Unfortunately
that document doesn't really explain it either!
To configure force-push, add a "+" to the start of the push refspec
you want to enable force-push on. E.g.
[remote "mirror"]
url = mirror1:${project}
push = +refs/heads/master
push = +refs/heads/experimental
push = refs/heads/stable
Will permit force-push on the first two branches (master,
experimental) but not on stable.
If the push variable is not specified in a remote, Gerrit defaults to
"+refs/*:refs/*" so that force push is enabled on all refs [2].
[1] http://www.kernel.org/pub/software/scm/git/docs/git-push.html
[2] http://gerrit.googlecode.com/svn/documentation/2.1.2/config-replication.html#remote.name.push
Correct.
> Quoting your statement earlier in the thread: *"**So unless your*
> *replication.config specifies force push on the branch, the push will
> *
> *fail with a non-fast-forward error.**"*
Right. So if you don't mention the push variable in the relevant
remote section of your replication.config, its a bug that we didn't
replicate the change.
What was the exact error in your error_log?
These errors are because Gerrit tried to do the non-fast-forward
push, but the destination Git has receive.denyNonFastForwards set
to true in its configuration file for the repository, so the remote
server is rejecting the push.