Bitbucket clona todos los repositorios del equipo

10 minutos de lectura

Avatar de usuario de Imran
Imrán

Me gustaría clonar todos los repositorios de mi equipo bitbucket usando un script bash y http. He encontrado algunos ejemplos que usan la API de Bitbucket, sin embargo, todos parecen no devolver repositorios. ¿Algunas ideas? Usando Mac.

  • ¿Está usted autenticado en absoluto? ¿Y el usuario con el que se está autenticando tiene acceso a los repositorios del equipo? Si no, le recomiendo que configure una contraseña de aplicación (en bitbucket.org/account/user//app-passwords) que tenga permisos suficientes (el acceso de lectura a la cuenta/membresía del equipo/proyectos/repositorios debería cubrir la mayoría de las cosas que necesita).

    – JVDL

    8 de noviembre de 2016 a las 4:46

Avatar de usuario de Nikolay Galkin
Nikolái Galkin

Aquí está mi solución simple. hacer archivo downloader.sh

#!/bin/bash

USER=${1}
TEAM=${2}

rm -rf "$TEAM" && mkdir "$TEAM" && cd $TEAM

NEXT_URL="https://api.bitbucket.org/2.0/repositories/${TEAM}?pagelen=100"

while [ ! -z $NEXT_URL ] && [ $NEXT_URL != "null" ]
do
    curl -u $USER $NEXT_URL > repoinfo.json
    jq -r '.values[] | .links.clone[1].href' repoinfo.json > ../repos.txt
    NEXT_URL=`jq -r '.next' repoinfo.json`

    for repo in `cat ../repos.txt`
    do
        echo "Cloning" $repo
        if echo "$repo" | grep -q ".git"; then
            command="git"
        else
            command="hg"
        fi
        $command clone $repo
    done
done

cd ..

puedes ejecutarlo por:

sh downloader.sh username teamname # or username instead team name

  • Aviso: te pedirá contraseña cada 100 repos

    – apreciador de frío

    28 de diciembre de 2021 a las 14:52

  • @chillappreciator no usa el protocolo http. Utilice el protocolo git@ y las claves ssh.

    – Nikolái Galkin

    3 de enero a las 8:03

  • Esto funciona bien, pero cuando bitbucket tiene menos de 100 repositorios, después de descargar todos los repositorios, digamos solo 6, el script me pide una contraseña nuevamente, y si la ingreso, el script lo hará. eliminar todas las carpetas descargadas previamente (por supuesto que podría presionar Ctrl-C y todo estaría bien). Intenté configurar pagelen=2 y este comportamiento ya no ocurre.

    – DAB

    28 de enero a las 9:09


  • Solución a mi comentario anterior: Cambie el ciclo while para verificar $NEXT_URL != “null” ……….. while [ ! -z $NEXT_URL ] && [ $NEXT_URL != “null” ]

    – DAB

    28 de enero a las 9:20

  • Gracias por el guión. Pequeño anexo: bitbucket dejó de usar nombre de usuario+contraseña como método de autenticación. Para que su secuencia de comandos funcione, debe crear una contraseña de aplicación y usar username:apppassword como username en su línea de comando. El nombre de usuario se encuentra en la configuración de la cuenta. El uso de la dirección de correo electrónico con la contraseña de la aplicación generará un mensaje de error.

    – GenError

    4 oct a las 12:56

Avatar de usuario de Eric Nord
eric norte

Asegúrese de tener sus claves ssh configuradas en bitbucket y de que git esté instalado clonando un repositorio manualmente:

Esto clonará todos los repositorios que son de su propiedad:

USER=bitbucket_username; curl --user ${USER} https://api.bitbucket.org/2.0/repositories/${USER} | grep -o '"ssh:[^ ,]\+' | xargs -L1 git clone

Para hacer una copia de seguridad de los repositorios de su equipo, use el mismo script pero codifique el nombre de su equipo de bitbucket de esta manera:

USER=bitbucket_username; curl --user ${USER} https://api.bitbucket.org/2.0/repositories/TEAMNAME | grep -o '"ssh:[^ ,]\+' | xargs -L1 git clone

Aquí está un mejor manera:

curl -u ${1} https://api.bitbucket.org/1.0/users/TEAMNAME > repoinfo

for repo_name in `cat repoinfo | sed -r 's/("name": )/\n\1/g' | sed -r 's/"name": "(.*)"/\1/' | sed -e 's/{//' | cut -f1 -d\" | tr '\n' ' '`
do
    echo "Cloning " $repo_name
    git clone git@bitbucket.org:TEAMNAME/$repo_name.git
    echo "---"
done

  • Solo para aquellos que pueden estar tratando de usar esto. Asegúrate de eso ssh: es la firma adecuada para su repositorio. para mi fue git:. Ver así: USER=myUserName; curl --user ${USER} https://api.bitbucket.org/2.0/repositories/THETEAM | grep -o '"git@[^ ,]\+' | xargs -L1 git clone

    – Mark Odey

    16 de febrero de 2019 a las 1:32

  • en mi mac descargué gsed y reemplazado sed con gsed en el código

    –Shaig Khaligli

    21 de abril de 2019 a las 0:46

Otra alternativa usando jq.

#!/bin/bash

user=username:password

curl -u $user 'https://api.bitbucket.org/2.0/user/permissions/teams?pagelen=100' > teams.json

jq -r '.values[] | .team.username' teams.json > teams.txt

for team in `cat teams.txt`
do
  echo $team

  rm -rf "${team}"

  mkdir "${team}"

  cd "${team}"

  url="https://api.bitbucket.org/2.0/repositories/${team}?pagelen=100"

  echo $url

  curl -u $user $url > repoinfo.json

  jq -r '.values[] | .links.clone[0].href' repoinfo.json > repos.txt

  for repo in `cat repos.txt`
  do
    echo "Cloning" $repo
    git clone $repo
  done

  cd ..

done

  • No pude hacer que esto funcionara con nombre de usuario: contraseña, pero funcionó bien con un --netrc-file. No estoy seguro de eliminar todo el directorio del equipo cada vez… probablemente sea mejor incorporar nuevos cambios, pero no es trivial actualizar el script para eso.

    – mpen

    25 de agosto de 2019 a las 20:56


avatar de usuario de simpleuser
usuariosimple

Solo puede usar un comando simple si tiene menos de 100 repositorios y agregar ‘pagelen=100’ a la consulta, ya que eso es lo máximo que la API de bitbucket informará al mismo tiempo. Si tiene más de 100 repositorios, debe procesar el enlace “siguiente” en el JSON devuelto para obtener la URL para consultar el siguiente conjunto de repositorios, lo que sería más fácil con un script.

Si usa http para clonar en lugar de ssh, entonces debe ingresar la contraseña para los repositorios protegidos u obtener una contraseña de la aplicación bitbucket y modificar las URL para insertarla en ellos, para que se vean así:

https://bitbucketuserhere:apppasswordhere@bitbucket.org/teamorusername/repositoryname.git

Además, la clonación no obtendrá todas las versiones de los archivos git LFS, así que tenga esto en cuenta. Según bitbucket, use ‘git lfs fetch –all’ para copiar todas las versiones de archivos LFS localmente.

Para obtener la lista de sus repositorios personales, use una URL como:

https://api.bitbucket.org/2.0/repositories/BITBUCKETUSERNAME?pagelen=100

Para obtener la lista de los repositorios de su equipo, use una URL como esta para obtener la lista de todos los repositorios de los que es miembro:

https://api.bitbucket.org/2.0/repositories/NOMBRE DEL EQUIPO?pagelen=100&role=member

El siguiente es un script perl de ejemplo que podría usar para clonar y luego mantener copias de sus repositorios, usando http en lugar de ssh para buscar. Hace clones de –mirror en lugar de una copia de trabajo completa (perfecto para mover o recuperación de desastres). Lo hace no copia de seguridad de todos los archivos LFS.

#!/usr/bin/env perl

use warnings;
use strict;
use JSON::Parse 'parse_json';

# CONFIGURATION:
# Bitbucket team or user name to get list of repositories from
my $teamORuserName = "myteam";

# Bitbucket app password with access to query the API for the
# list of repositories. Format: "user-name:app-token"
my $appPassword= "frank-james:LAYDxtc8H6FGKUZeHEef";

#------------------------------------------------------------------------------

my $nextPageLink = "https://api.bitbucket.org/2.0/repositories/$teamORuserName?pagelen=100&role=member";
while (defined $nextPageLink)
{
    $nextPageLink =~ m/page=(\d+)/;
    print "Fetching page " . ($1 || 1). "\n";
    my $response = `curl -q --silent --request GET --user '$appPassword' '$nextPageLink'`;
    my $json = parse_json($response);
    my $values = $json->{values};

    foreach my $repo (@$values)
    {
        die "'$repo->{name}' is not a 'git' repo: $repo->{scm}" unless $repo->{scm} eq "git";
        my $links = $repo->{links} || die "no links data for '$repo->{name}'";
        my $clones = $links->{clone} || die "no clone data for '$repo->{name}'";
        my $url = $clones->[0]->{href} || die "no clone url found for $repo->{name}";

        # use uuid as directory name, to survive project name changes
        my $uuid = $repo->{uuid}; $uuid =~ s/[\{\}]//g;
        if (not -e $uuid)
        {
            print "cloning '$repo->{name}' into $uuid\n";
            # replace user name with token to avoid password prompts
            $url =~ s|(https?://).+(\@bitbucket.org)|$1$appPassword$2|;
            system("git clone --progress --mirror '$url' $uuid") == 0 or die "clone failed";
            # make a human friendly link to current repository name
            symlink $uuid, $repo->{slug} or warn "symlink failed: $!";
        }
        else
        {
            print "updating '$repo->{name}' in $uuid\n";
            system("cd $uuid && git fetch --all --tags --prune") == 0 or die "fetch failed";
        }
        print "\n";
    }

    $nextPageLink = $json->{next};
}
exit 0;

Aquí hay una secuencia de comandos de python para clonar todos los repositorios del equipo o del usuario en bitbucket. Como los repositorios del equipo suelen ser privados, me ocupé de eso mientras usaba la API de bitbucket. Simplemente ingrese su nombre de usuario y contraseña de bitbucket y el nombre de usuario del equipo y se encargará de clonar todo el repositorio del equipo por usted.

import subprocess
import json

cmd = "curl -u <bitbucket_username>:<bitbucket_password>  https://api.bitbucket.org/2.0/repositories/<team_name_or_project_name>"
cmd = cmd.split()

while 1:
    from_api = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    from_api = from_api.communicate()
    json_from_api = json.loads(from_api[0])
    for unit_dict in json_from_api["values"]:
        clone_cmd = "git clone " + unit_dict["links"]["clone"][1]["href"]
        clone_cmd = clone_cmd.split()
        clone_out = subprocess.call(clone_cmd, shell=False)
    if "next" not in json_from_api:
        break
    else:
        cmd[-1] = json_from_api["next"]

Sobre la base de la respuesta de @ eric-nord, he reemplazado sed con jq para llegar al slug del repositorio (que encontré más simple, considerando las salidas de bitbucket json).

Entonces, si tiene menos de 100 repositorios y está buscando clonar los repositorios para un proyecto específico, el siguiente script de shell debería funcionar.

#!/usr/bin/env sh

if [ $# -eq 0 ] || [ "$1" == "-?" ] || [ "$1" == "--help" ] || [ "$1" == "-h" ]
  then
    echo "Usage: `basename $0` <URL> <USERNAME> <PROJECTNAME>"
    echo "e.g. `basename $0` bitbucket_url some_user some_project"
    exit 1
fi

curl -u ${2} https://${1}/rest/api/1.0/projects/${3}/repos?limit=100 > repos.json

for repo_name in `cat repos.json | jq -r '.values[] .slug'`
do
  echo "cloning" $repo_name
  git clone https://${2}@${1}/scm/${3}/$repo_name.git ./${3}/$repo_name
done

Avatar de usuario de Gladwin Henald
Gladwin Henald

Aquí hay un script de nodo para descargar todos los repositorios en una cuenta de bitbucket. No olvide agregar los paquetes npm necesarios.

const argv = require('yargs').argv
const request = require('request');
const nodegit = require('nodegit');

let repos = [];
let opts = {
    fetchOpts: {
        callbacks: {
            credentials: function() {
                return nodegit.Cred.userpassPlaintextNew(argv.username, argv.password);
            },
            certificateCheck: function() {
                return 1;
            }
        }
    }
};

function cloneRepository(index) {
    let repo = repos[index];
    console.log('Cloning ' + repo.full_name);
    nodegit.Clone(repo.links.clone[0].href, 'repositories/' + repo.full_name, opts)
    .then(function(repo) {
        if (repos.length - 1 == index) {
            console.log("All repositories cloned");
        } else {
            cloneRepository(index + 1);
        }
    })
    .catch(function(err) {
        if (err) {
            console.log(err);
        }
    });
}

function loadRepositories(url) {
    request.get(url, {
        'auth': {
            'user': argv.username,
            'pass': argv.password
        }
    }, function (err, response, body) {
        if (err) return console.log(err);
        let data = JSON.parse(body);
        for (var i = 0; i < data.values.length; i++) {
            repos.push(data.values[i]);
        }
        if (data.next){
            loadRepositories(data.next);    
        } else if (repos.length > 0) {
            console.log('Started cloning..');
            cloneRepository(0);
        } else {
            console.log("No repositories found");
        }
    });
}

if (argv.username && argv.password) {
    console.log('Loading all repositories..');
    loadRepositories('https://api.bitbucket.org/2.0/repositories/?role=member');
} else {
    console.log('Please specify both the --username and --password options');
}

También puede consultar este repositorio de GitHub. Descargador de repositorios de Bitbucket

  • El OP pide bash. Esto no se parece al código BASH.

    – Esteban Rauch

    14 de julio de 2018 a las 1:50

  • @StephenRauch, Eric ya proporcionó la respuesta para el script bash. Mi respuesta podría ser útil para otras personas que buscan la implementación de nodejs.

    – Gladwin Henald

    14 de julio de 2018 a las 7:57

¿Ha sido útil esta solución?