Bitbucket克隆所有团队存储库

时间:2016-11-04 18:31:03

标签: git macos bitbucket

我想使用bash脚本和http克隆我的所有bitbucket团队存储库。我找到了一些使用Bitbucket api的例子,但它们似乎都没有返回任何存储库。有任何想法吗?使用mac。

11 个答案:

答案 0 :(得分:6)

确保在bitbucket中设置了ssh密钥,并通过手动克隆一个repo来安装git:

这将克隆您拥有的所有回购:

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

要备份您的团队存储库,请使用相同的脚本,但是硬编码您的bitbucket团队名称,如下所示:

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

这是better way

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

答案 1 :(得分:1)

如果您的存储库少于100个,并且添加' pagelen = 100'您只能使用简单的命令。查询,因为这是bitbucket API一次报告的最多。如果您有超过100个存储库,则需要处理" next"返回的JSON中的链接,以获取查询下一组存储库的URL,这对于脚本来说会更容易。

如果您使用http来克隆而不是ssh,那么您需要输入受保护存储库的密码,或者获取bitbucket应用程序密码并修改URL以将其插入到它们中,因此它们看起来像:

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

此外,克隆不会获得所有版本的git LFS文件,因此请注意这一点。根据bitbucket,使用&git fetch --all'在本地复制所有LFS文件版本。

要获取个人存储库的列表,请使用以下URL:

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

要获取团队存储库的列表,请使用这样的URL来获取您所属的所有存储库的列表:

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

以下是一个示例perl脚本,您可以使用http来代替ssh来获取,然后维护存储库的副本。它使--mirror克隆而不是完全填充的工作副本(非常适合移动或灾难恢复)。它备份所有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;

答案 2 :(得分:1)

使用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

答案 3 :(得分:0)

这是一个用于克隆bitbucket中所有团队或用户存储库的python脚本。由于团队存储库通常是私有的,我在使用bitbucket API时会处理这个问题。因此,只需输入您的bitbucket用户名,密码和团队用户名,它将负责为您克隆所有团队存储库。

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"]

答案 4 :(得分:0)

这是一个节点脚本,用于在bitbucket帐户中下载所有存储库。请不要忘记添加必要的npm软件包。

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');
}

您还可以检出此GitHub存储库。 Bitbucket Repository Downloader

答案 5 :(得分:0)

在@ eric-nord的answer的基础上,我用sed jq替换了sed来获得repo slug(考虑到bitbucket输出json,我发现它更简单)。

因此,如果您的存储库少于100个,并且您希望克隆特定项目的存储库,则可以使用以下Shell脚本来解决问题。

#!/usr/bin/env sh

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

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

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

答案 6 :(得分:0)

这是一个通过https下载的Bash脚本。

分别保存到文件download_bitbucket_repos.shchmod +x download_bitbucket_repos.sh./download_bitbucket_repos.sh

#!/bin/bash

USER='yourBitBucketUsername' #not email
PASS='yourPassword'
TEAM='teamNameInBitbucket'

curl -u $USER:$PASS https://api.bitbucket.org/1.0/users/$TEAM > 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 https://$USER@bitbucket.org/$TEAM/$repo_name.git
    echo "---"
done

答案 7 :(得分:0)

这是对我有用的Python:

import subprocess
import json
import cookielib
import urllib2
import base64

def _create_opener(proxy=None):
    cj = cookielib.LWPCookieJar()
    cookie_handler = urllib2.HTTPCookieProcessor(cj)
    if proxy:
        proxy_handler = urllib2.ProxyHandler(proxy)
        opener = urllib2.build_opener(cookie_handler, proxy_handler)
    else:
        opener = urllib2.build_opener(cookie_handler)
    return opener

def get_repos(_opener, _auth, user, password, team_username, paging):
    query_url = 'https://bitbucket.org/!api/2.0/repositories/'+team_username+paging
    try:
        req = urllib2.Request(query_url, None, {"Authorization": _auth })
        handler = _opener.open(req)
    except urllib2.HTTPError, e:
        print e.headers
        raise e
    for unit_dict in json.load(handler)["values"]:
        clone_cmd = "git clone " + unit_dict["links"]["clone"][0]["href"].replace('https://'+user,'https://'+password+':'+password)
        clone_cmd = clone_cmd.split()
        clone_out = subprocess.call(clone_cmd, shell=False)
encodedstring = base64.encodestring("%s:%s" % (user, password))[:-1]
_auth = "Basic %s" % encodedstring
_opener = _create_opener()
get_repos(_opener,_auth,'bitbucket-user','bitbucket-password','team-username','pagelen=100&page=1')

将功劳记入thisthis

答案 8 :(得分:0)

这是我的简单解决方案。制作文件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 ]
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

    cd ..
done

您可以通过以下方式运行它:

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

答案 9 :(得分:0)

我在rust中构建了一个CLI,用于同时克隆和提取git存储库(用户和项目)。 https://github.com/jensim/bitbucket_server_cli 它可以在交互式或批处理模式下工作,具有外壳补全功能,并能够记住交互式模式下的选择,从而获得更快的用户体验。

对于像您这样的mac用户:

$> brew install jensim/bitbucket_server_cli/bitbucket_server_cli
$> bitbucket_server_cli clone

BitBucket server address: http://localhost
BitBucket username: jensim
✔ BitBucket password · ********
Clone/update all projects yes
Fetching users [00:00:15] [########################################] 2011/2011 (eta:0s)
Fetching projects [00:00:00] [########################################] 35/35 (eta:0s)
Working repos [00:01:07] [########################################] 1337/1337 (eta:0s)

免责声明: 据我所知,这是实验性的,因此目前它主要由mac电脑用户使用。.但是,在Github Releases中有可用的Windows和Debian二进制文件。而且,这可以同时工作,并且具有可配置数量的同时http请求/ git克隆,以免杀死您的CI管道

答案 10 :(得分:0)

我在此处提供了一个简单的脚本:https://github.com/mimo84/cloner与Nikolai的答案类似,但是它使用bitbucket上的api来获取它们。它也具有jq作为依赖项。

用法: 下载它(可能正在执行git clone https://github.com/mimo84/cloner.git) 然后

chmod +x ./bitbucket.sh

./bitbucket.sh username:password

它将在当前目录上方创建一个名为“ bitbucket_repos”的新文件夹,并在其中克隆所有存储库。