如何提取 Stash 或 Bitbucket 中所有存储库的列表?
How to extract the list of all repositories in Stash or Bitbucket?
我需要提取Bitbucket 中所有项目下的所有repos 列表。是否有相同的 REST API?我找不到一个。
我有本地和云 Bitbucket。
对于 Bitbucket Cloud
您可以使用他们的 REST API 在您的服务器上访问和执行查询。
具体来说,您可以使用 this documentation page, provided by Atlassian, 了解如何列出您的存储库。
对于 Bitbucket 服务器
编辑:截至收到 this tweet from Dan Bennett, I've learnt there is an API/plugin system for Bitbucket Server that could possibly cater for your needs. For docs: See here.
Edit2:找到 this reference 列出可作为解决方案的个人存储库。
AFAIK 除非您为自己构建一个与 Bitbucket Server 实例交互的小 API,否则没有适合您的解决方案。
Atlassian Documentation does indicate 要列出所有当前配置的存储库,您可以执行 git remote -v
。但是我对此表示怀疑,因为这通常不是 git remote -v
的用法;我认为更有可能是 Atlassian 的文档不清楚,而不是 Atlassian 将此功能构建到 Bitbucket Server。
克隆给定存储的所有项目和存储库url
#!/usr/bin/python
#
# @author Jason LeMonier
#
# Clone ALL Projects & Repositories for a given stash url
#
# Loop through all projects: [P1, P2, ...]
# P1 > for each project make a directory with the key "P1"
# Then clone every repository inside of directory P1
# Backup a directory, create P2, ...
#
# Added ACTION_FLAG bit so the same logic can run fetch --all on every repository and/or clone.
import sys
import os
import stashy
ACTION_FLAG = 1 # Bit: +1=Clone, +2=fetch --all
url = os.environ["STASH_URL"] # "https://mystash.com/stash"
user = os.environ["STASH_USER"] # joedoe"
pwd = os.environ["STASH_PWD"] # Yay123
stash = stashy.connect(url, user, pwd)
def mkdir(xdir):
if not os.path.exists(xdir):
os.makedirs(xdir)
def run_cmd(cmd):
print ("Directory cwd: %s "%(os.getcwd() ))
print ("Running Command: \n %s " %(cmd))
os.system(cmd)
start_dir = os.getcwd()
for project in stash.projects:
pk = project_key = project["key"]
mkdir(pk)
os.chdir(pk)
for repo in stash.projects[project_key].repos.list():
for url in repo["links"]["clone"]:
href = url["href"]
repo_dir = href.split("/")[-1].split(".")[0]
if (url["name"] == "http"):
print (" url.href: %s"% href) # https://joedoe@mystash.com/stash/scm/app/ae.git
print ("Directory cwd: %s Project: %s"%(os.getcwd(), pk))
if ACTION_FLAG & 1 > 0:
if not os.path.exists(repo_dir):
run_cmd("git clone %s" % url["href"])
else:
print ("Directory: %s/%s exists already. Skipping clone. "%(os.getcwd(), repo_dir))
if ACTION_FLAG & 2 > 0:
# chdir into directory "ae" based on url of this repo, fetch, chdir back
cur_dir = os.getcwd()
os.chdir(repo_dir)
run_cmd("git fetch --all ")
os.chdir(cur_dir)
break
os.chdir(start_dir) # avoiding ".." in case of incorrect git directories
这个 ruby 脚本不是最好的代码,这是有道理的,因为我不是最好的编码员。但它很清楚,经过测试,并且有效。
该脚本过滤 Bitbucket API 调用的输出,以创建 Bitbucket 服务器上所有存储库的完整报告。报告按项目排列,包括总计和小计,每个回购 link,以及回购是 public 还是个人。我本可以简化它以供一般使用,但它现在非常有用。
没有命令行参数。只是 运行 它。
#!/usr/bin/ruby
#
# @author Bill Cernansky
#
# List and count all repos on a Bitbucket server, arranged by project, to STDOUT.
#
require 'json'
bbserver = 'http(s)://server.domain.com'
bbuser = 'username'
bbpassword = 'password'
bbmaxrepos = 2000 # Increase if you have more than 2000 repos
reposRaw = JSON.parse(`curl -s -u '#{bbuser}':'#{bbpassword}' -X GET #{bbserver}/rest/api/1.0/repos?limit=#{bbmaxrepos}`)
projects = {}
repoCount = reposRaw['values'].count
reposRaw['values'].each do |r|
projID = r['project']['key']
if projects[projID].nil?
projects[projID] = {}
projects[projID]['name'] = r['project']['name']
projects[projID]['repos'] = {}
end
repoName = r['name']
projects[projID]['repos'][repoName] = r['links']['clone'][0]['href']
end
privateProjCount = projects.keys.grep(/^\~/).count
publicProjCount = projects.keys.count - privateProjCount
reportText = ''
privateRepoCount = 0
projects.keys.sort.each do |p|
# Personal project slugs always start with tilde
isPrivate = p[0] == '~'
projRepoCount = projects[p]['repos'].keys.count
privateRepoCount += projRepoCount if isPrivate
reportText += "\nProject: #{p} : #{projects[p]['name']}\n #{projRepoCount} #{isPrivate ? 'PERSONAL' : 'Public'} repositories\n"
projects[p]['repos'].keys.each do |r|
reportText += sprintf(" %-30s : %s\n", r, projects[p]['repos'][r])
end
end
puts "BITBUCKET REPO REPORT\n\n"
puts sprintf(" Total Projects: %5d Public: %5d Personal: %5d", projects.keys.count, publicProjCount, privateProjCount)
puts sprintf(" Total Repos: %5d Public: %5d Personal: %5d", repoCount, repoCount - privateRepoCount, privateRepoCount)
puts reportText
我解决这个问题的方法是获取 html 页面并给它一个荒谬的限制,就像这样。那是 python :
cmd = "curl -s -k --user " + username + " https://URL/projects/<KEY_PROJECT_NAME>/?limit\=10000"
然后我用BeautifulSoup
解析了它
make_list = str((subprocess.check_output(cmd, shell=True)).rstrip().decode("utf-8"))
html = make_list
parsed_html = BeautifulSoup(html,'html.parser')
list1 = []
for a in parsed_html.find_all("a", href=re.compile("/<projects>/<KEY_PROJECT_NAME>/repos/")):
list1.append(a.string)
print(list1)
要使用它,请确保您更改并且,这应该是您要定位的 bitbucket 项目。所有,我正在做的是解析一个 html 文件。
我最终不得不自己在本地安装 Bitbucket,它似乎没有上面讨论的 REST API 可访问,所以我想出了一个简短的脚本来把它从网上抓取页。这种解决方法的优点是您不需要安装任何东西,除了登录到您的 Bitbucket 服务器之外,您无需担心依赖项、证书或登录。如果您对脚本进行 urlencode 并以 javascript:
.
作为前缀,您也可以将其设置为书签
要使用这个:
- 打开您的 bitbucket 服务器 项目 页面,您应该会在其中看到存储库列表。
- 打开浏览器的 devtools 控制台。这通常是
F12
或 ctrl-shift-i
.
- 将以下内容粘贴到那里的命令提示符中。
JSON.stringify(Array.from(document.querySelectorAll('[data-repository-id]')).map(aTag => {
const href = aTag.getAttribute('href');
let projName = href.match(/\/projects\/(.+)\/repos/)[1].toLowerCase();
let repoName = href.match(/\/repos\/(.+)\/browse/)[1];
repoName = repoName.replace(' ', '-');
const templ = `https://${location.host}/scm/${projName}/${repoName}.git`;
return {
href,
name: aTag.innerText,
clone: templ
}
}));
结果是一个 JSON 字符串,其中包含一个数组,其中包含存储库的 URL、名称和克隆 URL。
[{
"href": "/projects/FOO/repos/some-repo-here/browse",
"name": "some-repo-here",
"clone": "https://mybitbucket.company.com/scm/foo/some-repo-here.git"
}]
- 登录后:在右上角,单击您的个人资料照片,然后单击 'View profile'
- 记下您的用户(在下面的示例中 'YourEmail@domain.com',但请记住它区分大小写)
- 单击个人资料图片 > 管理帐户 > 个人访问令牌 > 创建令牌(选择 'Read' 访问类型足以实现此功能)
对于所有项目中的所有回购:
- 打开 CLI 并使用以下命令(记得填写您的服务器域!):
curl -u "YourEmail@domain.com" -X GET https://<my_server_domain>/rest/api/1.0/projects/?limit=1000
- 它会要求您提供个人访问令牌,您遵守并获得一个 JSON 文件,其中包含所有请求的回购协议
对于给定项目中的所有回购:
选择您要从中获取回购协议的项目。在我的例子中,项目 URL 是:/projects/TECH/ 因此我的 {projectKey} 是 'TECH',下面的命令需要它。
打开一个CLI并使用这个命令(记得填写你的服务器域和projectKey!):
curl -u "YourEmail@domain.com" -X GET https://<my_server_domain>/rest/api/1.0/projects/{projectKey}/repos?limit=50
最后润色
- (可选)如果您只想要请求的回购的标题并且您安装了 jq(对于 Windows,下载 exe 并将其添加到 PATH 应该就足够了,但是您需要重新启动 CLI 以检测新添加的内容),您可以使用以下命令:
curl -u $BBUSER -X GET <my_server_domain>/rest/api/1.0/projects/TECH/repos?limit=50 | jq '.values|.[]|.name'
(使用 Data Center/Atlassian Bitbucket v7.9.0 和 powershell CLI 测试)
以下是我从 Bitbucket Cloud 中提取回购列表的方法。
设置 OAauth 消费者
转到您的工作区设置并设置 OAuth 使用者,您应该可以直接使用此 link 转到此处:https://bitbucket.org/{your_workspace}/workspace/settings/api
唯一重要的设置是回调 URL,它可以是任何东西,但我选择了 http://localhost
设置完成后,这将为您的 OAuth 消费者显示密钥和秘密对,我将在下面将它们称为 {oauth_key}
和 {oauth_secret}
使用 API
进行身份验证
转到 https://bitbucket.org/site/oauth2/authorize?client_id={oauth_key}&response_type=code
确保替换 {oauth_key}
这会将您重定向到类似 http://localhost/?code=xxxxxxxxxxxxxxxxxx
的内容,记下该代码,我将在下面将其称为 {oauth_code}
在您的终端中转到 curl -X POST -u "{oauth_key}:{oauth_secret}" https://bitbucket.org/site/oauth2/access_token -d grant_type=authorization_code -d code={oauth_code}
替换占位符。
这应该 return json 包括 access_token,我将该访问令牌称为 {oauth_token}
获取repos列表
您现在可以运行以下内容来获取回购列表。请记住,您的 {oauth_token}
默认持续 2 小时。
curl --request GET \
--url 'https://api.bitbucket.org/2.0/repositories/pageant?page=1' \
--header 'Authorization: Bearer {oauth_token}' \
--header 'Accept: application/json'
此回复已分页,因此您需要翻阅回复,一次 10 个存储库。
我需要提取Bitbucket 中所有项目下的所有repos 列表。是否有相同的 REST API?我找不到一个。
我有本地和云 Bitbucket。
对于 Bitbucket Cloud
您可以使用他们的 REST API 在您的服务器上访问和执行查询。
具体来说,您可以使用 this documentation page, provided by Atlassian, 了解如何列出您的存储库。
对于 Bitbucket 服务器
编辑:截至收到 this tweet from Dan Bennett, I've learnt there is an API/plugin system for Bitbucket Server that could possibly cater for your needs. For docs: See here.
Edit2:找到 this reference 列出可作为解决方案的个人存储库。
AFAIK 除非您为自己构建一个与 Bitbucket Server 实例交互的小 API,否则没有适合您的解决方案。
Atlassian Documentation does indicate 要列出所有当前配置的存储库,您可以执行 git remote -v
。但是我对此表示怀疑,因为这通常不是 git remote -v
的用法;我认为更有可能是 Atlassian 的文档不清楚,而不是 Atlassian 将此功能构建到 Bitbucket Server。
克隆给定存储的所有项目和存储库url
#!/usr/bin/python
#
# @author Jason LeMonier
#
# Clone ALL Projects & Repositories for a given stash url
#
# Loop through all projects: [P1, P2, ...]
# P1 > for each project make a directory with the key "P1"
# Then clone every repository inside of directory P1
# Backup a directory, create P2, ...
#
# Added ACTION_FLAG bit so the same logic can run fetch --all on every repository and/or clone.
import sys
import os
import stashy
ACTION_FLAG = 1 # Bit: +1=Clone, +2=fetch --all
url = os.environ["STASH_URL"] # "https://mystash.com/stash"
user = os.environ["STASH_USER"] # joedoe"
pwd = os.environ["STASH_PWD"] # Yay123
stash = stashy.connect(url, user, pwd)
def mkdir(xdir):
if not os.path.exists(xdir):
os.makedirs(xdir)
def run_cmd(cmd):
print ("Directory cwd: %s "%(os.getcwd() ))
print ("Running Command: \n %s " %(cmd))
os.system(cmd)
start_dir = os.getcwd()
for project in stash.projects:
pk = project_key = project["key"]
mkdir(pk)
os.chdir(pk)
for repo in stash.projects[project_key].repos.list():
for url in repo["links"]["clone"]:
href = url["href"]
repo_dir = href.split("/")[-1].split(".")[0]
if (url["name"] == "http"):
print (" url.href: %s"% href) # https://joedoe@mystash.com/stash/scm/app/ae.git
print ("Directory cwd: %s Project: %s"%(os.getcwd(), pk))
if ACTION_FLAG & 1 > 0:
if not os.path.exists(repo_dir):
run_cmd("git clone %s" % url["href"])
else:
print ("Directory: %s/%s exists already. Skipping clone. "%(os.getcwd(), repo_dir))
if ACTION_FLAG & 2 > 0:
# chdir into directory "ae" based on url of this repo, fetch, chdir back
cur_dir = os.getcwd()
os.chdir(repo_dir)
run_cmd("git fetch --all ")
os.chdir(cur_dir)
break
os.chdir(start_dir) # avoiding ".." in case of incorrect git directories
这个 ruby 脚本不是最好的代码,这是有道理的,因为我不是最好的编码员。但它很清楚,经过测试,并且有效。
该脚本过滤 Bitbucket API 调用的输出,以创建 Bitbucket 服务器上所有存储库的完整报告。报告按项目排列,包括总计和小计,每个回购 link,以及回购是 public 还是个人。我本可以简化它以供一般使用,但它现在非常有用。
没有命令行参数。只是 运行 它。
#!/usr/bin/ruby
#
# @author Bill Cernansky
#
# List and count all repos on a Bitbucket server, arranged by project, to STDOUT.
#
require 'json'
bbserver = 'http(s)://server.domain.com'
bbuser = 'username'
bbpassword = 'password'
bbmaxrepos = 2000 # Increase if you have more than 2000 repos
reposRaw = JSON.parse(`curl -s -u '#{bbuser}':'#{bbpassword}' -X GET #{bbserver}/rest/api/1.0/repos?limit=#{bbmaxrepos}`)
projects = {}
repoCount = reposRaw['values'].count
reposRaw['values'].each do |r|
projID = r['project']['key']
if projects[projID].nil?
projects[projID] = {}
projects[projID]['name'] = r['project']['name']
projects[projID]['repos'] = {}
end
repoName = r['name']
projects[projID]['repos'][repoName] = r['links']['clone'][0]['href']
end
privateProjCount = projects.keys.grep(/^\~/).count
publicProjCount = projects.keys.count - privateProjCount
reportText = ''
privateRepoCount = 0
projects.keys.sort.each do |p|
# Personal project slugs always start with tilde
isPrivate = p[0] == '~'
projRepoCount = projects[p]['repos'].keys.count
privateRepoCount += projRepoCount if isPrivate
reportText += "\nProject: #{p} : #{projects[p]['name']}\n #{projRepoCount} #{isPrivate ? 'PERSONAL' : 'Public'} repositories\n"
projects[p]['repos'].keys.each do |r|
reportText += sprintf(" %-30s : %s\n", r, projects[p]['repos'][r])
end
end
puts "BITBUCKET REPO REPORT\n\n"
puts sprintf(" Total Projects: %5d Public: %5d Personal: %5d", projects.keys.count, publicProjCount, privateProjCount)
puts sprintf(" Total Repos: %5d Public: %5d Personal: %5d", repoCount, repoCount - privateRepoCount, privateRepoCount)
puts reportText
我解决这个问题的方法是获取 html 页面并给它一个荒谬的限制,就像这样。那是 python :
cmd = "curl -s -k --user " + username + " https://URL/projects/<KEY_PROJECT_NAME>/?limit\=10000"
然后我用BeautifulSoup
解析了它make_list = str((subprocess.check_output(cmd, shell=True)).rstrip().decode("utf-8"))
html = make_list
parsed_html = BeautifulSoup(html,'html.parser')
list1 = []
for a in parsed_html.find_all("a", href=re.compile("/<projects>/<KEY_PROJECT_NAME>/repos/")):
list1.append(a.string)
print(list1)
要使用它,请确保您更改并且,这应该是您要定位的 bitbucket 项目。所有,我正在做的是解析一个 html 文件。
我最终不得不自己在本地安装 Bitbucket,它似乎没有上面讨论的 REST API 可访问,所以我想出了一个简短的脚本来把它从网上抓取页。这种解决方法的优点是您不需要安装任何东西,除了登录到您的 Bitbucket 服务器之外,您无需担心依赖项、证书或登录。如果您对脚本进行 urlencode 并以 javascript:
.
要使用这个:
- 打开您的 bitbucket 服务器 项目 页面,您应该会在其中看到存储库列表。
- 打开浏览器的 devtools 控制台。这通常是
F12
或ctrl-shift-i
. - 将以下内容粘贴到那里的命令提示符中。
JSON.stringify(Array.from(document.querySelectorAll('[data-repository-id]')).map(aTag => {
const href = aTag.getAttribute('href');
let projName = href.match(/\/projects\/(.+)\/repos/)[1].toLowerCase();
let repoName = href.match(/\/repos\/(.+)\/browse/)[1];
repoName = repoName.replace(' ', '-');
const templ = `https://${location.host}/scm/${projName}/${repoName}.git`;
return {
href,
name: aTag.innerText,
clone: templ
}
}));
结果是一个 JSON 字符串,其中包含一个数组,其中包含存储库的 URL、名称和克隆 URL。
[{
"href": "/projects/FOO/repos/some-repo-here/browse",
"name": "some-repo-here",
"clone": "https://mybitbucket.company.com/scm/foo/some-repo-here.git"
}]
- 登录后:在右上角,单击您的个人资料照片,然后单击 'View profile'
- 记下您的用户(在下面的示例中 'YourEmail@domain.com',但请记住它区分大小写)
- 单击个人资料图片 > 管理帐户 > 个人访问令牌 > 创建令牌(选择 'Read' 访问类型足以实现此功能)
对于所有项目中的所有回购:
- 打开 CLI 并使用以下命令(记得填写您的服务器域!):
curl -u "YourEmail@domain.com" -X GET https://<my_server_domain>/rest/api/1.0/projects/?limit=1000
- 它会要求您提供个人访问令牌,您遵守并获得一个 JSON 文件,其中包含所有请求的回购协议
对于给定项目中的所有回购:
选择您要从中获取回购协议的项目。在我的例子中,项目 URL 是:
/projects/TECH/ 因此我的 {projectKey} 是 'TECH',下面的命令需要它。 打开一个CLI并使用这个命令(记得填写你的服务器域和projectKey!):
curl -u "YourEmail@domain.com" -X GET https://<my_server_domain>/rest/api/1.0/projects/{projectKey}/repos?limit=50
最后润色
- (可选)如果您只想要请求的回购的标题并且您安装了 jq(对于 Windows,下载 exe 并将其添加到 PATH 应该就足够了,但是您需要重新启动 CLI 以检测新添加的内容),您可以使用以下命令:
curl -u $BBUSER -X GET <my_server_domain>/rest/api/1.0/projects/TECH/repos?limit=50 | jq '.values|.[]|.name'
(使用 Data Center/Atlassian Bitbucket v7.9.0 和 powershell CLI 测试)
以下是我从 Bitbucket Cloud 中提取回购列表的方法。
设置 OAauth 消费者
转到您的工作区设置并设置 OAuth 使用者,您应该可以直接使用此 link 转到此处:https://bitbucket.org/{your_workspace}/workspace/settings/api
唯一重要的设置是回调 URL,它可以是任何东西,但我选择了 http://localhost
设置完成后,这将为您的 OAuth 消费者显示密钥和秘密对,我将在下面将它们称为 {oauth_key}
和 {oauth_secret}
使用 API
进行身份验证转到 https://bitbucket.org/site/oauth2/authorize?client_id={oauth_key}&response_type=code
确保替换 {oauth_key}
这会将您重定向到类似 http://localhost/?code=xxxxxxxxxxxxxxxxxx
的内容,记下该代码,我将在下面将其称为 {oauth_code}
在您的终端中转到 curl -X POST -u "{oauth_key}:{oauth_secret}" https://bitbucket.org/site/oauth2/access_token -d grant_type=authorization_code -d code={oauth_code}
替换占位符。
这应该 return json 包括 access_token,我将该访问令牌称为 {oauth_token}
获取repos列表
您现在可以运行以下内容来获取回购列表。请记住,您的 {oauth_token}
默认持续 2 小时。
curl --request GET \
--url 'https://api.bitbucket.org/2.0/repositories/pageant?page=1' \
--header 'Authorization: Bearer {oauth_token}' \
--header 'Accept: application/json'
此回复已分页,因此您需要翻阅回复,一次 10 个存储库。