3

I'm trying to sync our repository on Bitbucket with a fresh repository on Github, such that when I push code to origin (Bitbucket), it pushes that commit on to the "mirrored" Github repository.

To do this, I created the Github repo and set up the ssh keys etc. I then added a Pipleline to Bitbucket called bitbucket-pipelines.yml which has the following code:

clone:
  depth: full
pipelines:
  default:
    - step:
        script:
          - git push --mirror git@github.com:orgname/nameofrepo.git

This brought over every commit and tag and the branch which I was currently on, but it did not bring over the other branches.

I suspect it has something to do with the fact that they all start with the word origin, but that is just a theory based on the fact that the only branch which did come across did not start with origin.

I've also tried a variation where I use:

      - step:
          clone:
            depth: full # want all so can push all (maybe can optimise this in future?)
          name: 'Sync push on branch to github'
          script:
            - git remote add sync git@github.com:orgname/nameofrepo.git
            - git push sync --all --force
            - git push sync --tags --force

Exact same result.

This is what other people (on blogs etc) have been doing to achieve this and I'm assuming they are trying to sync more than just main.

Can anyone spot what I am doing wrong?

onefootswill
  • 3,707
  • 6
  • 47
  • 101

2 Answers2

4

For you push --mirror to push all branches, you might need first, in your Bitbucket pipeline, to add a step where you make a local branch out of all the remote tracking origin/xxx branches.

I proposed a one-liner before to do that.

for i in $(git for-each-ref --format=%(refname:short) \
  --no-merged=origin/HEAD refs/remotes/origin); do \
    git switch --track $i; \
done

Once your Bitbucket has cloned and created all local branch, you can proceed with a push --mirror.

Note: that would necessitate a Bitbucket pipeline using Docker images as build environments, running a default Docker image.
That would include a recent Git 2.39.1.
The OP confirm in the chat using a build environment with... Git 1.9.1 (March 2014).

Using the default Atlassian image solves this, as it comes with the latest Git 2.39.1

image: atlassian/default-image:4.20230131
clone:
  depth: full
pipelines:
  default:
    - step:
      script:
      - 'for i in $(git for-each-ref --format="%(refname:short)" --no-merged=origin/HEAD refs/remotes/origin); do echo $i; git show-ref --verify --quiet refs/heads/${i#origin/} || git switch --track $i; git branch -l; done; git branch -lvv; git push --mirror git@github.com:you/repo.git'

The script in multiple lines:

for i in $(git for-each-ref --format="%(refname:short)" \
                --no-merged=origin/HEAD refs/remotes/origin); do 
  echo $i; 
  git show-ref --verify --quiet refs/heads/${i#origin/} || git switch --track $i; 
  git branch -l; 
done; 
git branch -lvv; 
git push --mirror git@github.com:you/repo.git
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks. I'm getting a weird error. 1st, I had to add parenthesis around the value passed to `--format` . But the error I'm getting is `error: unknown option no-merged`. I replaced the = operator with a space and get the same error. The command works fine locally, but not on Bitbucket cloud. – onefootswill Feb 18 '23 at 00:10
  • @onefootswill Strange: it is a [valid option](https://git-scm.com/docs/git-for-each-ref#Documentation/git-for-each-ref.txt---no-mergedltobjectgt). What Git version are you using? – VonC Feb 18 '23 at 00:37
  • Indeed. I've tried to ascertain that. [This page](https://confluence.atlassian.com/bbkb/what-version-of-git-do-you-support-1168845106.html) seems to indicate that Bitbucket keeps up to date in terms of Git versions. So, I'm a bit confused by that error as well. And I've confirmed it works locally. – onefootswill Feb 18 '23 at 03:03
  • Also, I just tried putting the whole line between apostrophes (like a string) as I wanted to eliminate the notion that the colon before `short` was the issue. Apparently the colon is fine, as there is no space after it. Worth trying. – onefootswill Feb 18 '23 at 03:16
  • @onefootswill did you try using it as one line, instead of multiple lines as I put it in the answer? – VonC Feb 18 '23 at 08:54
  • Yeah. That's the first step I took. Made it a one-liner. Your solution looks really good and makes me think it would solve the problem. So I'm quite disappointed with Bitbucket pipelines. – onefootswill Feb 18 '23 at 23:28
  • @onefootswill Can you try, in the bitbucket pipeline, to run a command like `git --version`? – VonC Feb 18 '23 at 23:36
  • Great idea **slaps forehead**. And I think we have our answer. The version is 1.9.1 ! I guess I need to figure out a way of doing the same thing without that convenient option. – onefootswill Feb 18 '23 at 23:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251982/discussion-between-vonc-and-onefootswill). – VonC Feb 18 '23 at 23:48
0

I followed this github documentation to mirror my repo. My working bitbucket-pipelines.yml file looks like this:

pipelines:
  default:
    - step:
        clone:
          enabled: false
        script:
          - git clone --bare git@bitbucket.org:<source>/<repo>.git
          - cd <repo>.git
          - git push --mirror git@github.com:<destination>/<repo>.git

Setting the clone "enabled" option to false will prevent bitbucket from automatically cloning the repo as part of the step (which it does automatically). See documentation.

neuquen
  • 3,991
  • 15
  • 58
  • 78