在 bitbucket 多个存储库中搜索并替换为提交

Search and replace with commit in bitbucket multiple repositories

有没有一种方法可以使用 Bitbucket 管理 tools/API/UI 在某些项目下的 Bitbucket git 存储库中搜索和替换某些字符串?修改应该通过 git commit.

想到的唯一方法是构建一些将遍历所有存储库的脚本。

我不得不做这样的手术。当我们从 svn 迁移到 git 时,我们必须更改 pom.xml:

中的 scm developerConnection
<developerConnection>scm:git:git@github.com:codehaus-plexus/plexus-interpolation.git</developerConnection>

在我们所有的 git 回购中,从 svn 开发人员连接到 git 一个。这是我使用的脚本:

#!/usr/bin/python

import stashy
import os
import sys
import urllib2
import json
import base64
import getpass
from git import Repo
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element
from lxml import etree
import itertools
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
bitbucketBaseUrl = "https://bitbucket.company.com"
bitbucketUserName = "admin"


class BitBucketRepo:
    def __init__(self, name, repoUrl):
        self.name = name
        self.repoUrl = repoUrl


class CommentedTreeBuilder(ET.TreeBuilder):
    def __init__(self, *args, **kwargs):
        super(CommentedTreeBuilder, self).__init__(*args, **kwargs)

    def comment(self, data):
        self.start(ET.Comment, {})
        self.data(data)
        self.end(ET.Comment)


def insert(originalfile, string):
    with open(originalfile, 'r') as f:
        with open('pom.xml.bak', 'w') as f2:
            f2.write(string + "\n")
            f2.write(f.read())
    os.rename('pom.xml.bak', originalfile)


def validateScriptParameters():
    if len(sys.argv) != 3:
        sys.exit("Usage: {} [Bit Bucket Module Project key, e.g. mf for Modules - Framework] [Bit Bucket admin password]".format(
            os.path.basename(sys.argv[0])))


def cloneRepo(repository):
    logging.info("Cloning repo [{}]".format(repository.repoUrl))
    repo = Repo.clone_from(repository.repoUrl, repository.name)
    return repo


def updatePomFile(repository):
    resultCode = 1
    ET.register_namespace('xsi', "http://www.w3.org/2001/XMLSchema-instance")
    ET.register_namespace('', "http://maven.apache.org/POM/4.0.0")
    cparser = ET.XMLParser(target = CommentedTreeBuilder())
    if os.path.isfile(os.getcwd() + "/" + repository.name + "/pom.xml"):
        tree = ET.parse(repository.name + "/pom.xml", parser=cparser)
        root = tree.getroot()

        ns = {'nodes': 'http://maven.apache.org/POM/4.0.0'}

        for scm in root.findall('nodes:scm', ns):
            if scm is not None:
                developerConnection = scm.find('nodes:developerConnection', ns)
                scm.remove(developerConnection)
                newDeveloperConnectionElm = Element("developerConnection")
                newDeveloperConnectionElm.tail = "\n\t"
                newDeveloperConnectionElm.text = str("scm:git:" + repository.repoUrl)
                scm.append(newDeveloperConnectionElm)
                resultCode = 0
            else:
                resultCode = 1

        if resultCode == 0:
            logging.info("Updating repository: " + repository.name)
            tree.write(repository.name + "/pom.xml")

    return resultCode


def updateRepo(bitbucket, projectKey):
    xmlVersion = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    repoList = bitbucket.projects[projectKey].repos

    for repoItem in repoList:
        cloneUrl = repoItem['links']['clone'][1]['href']

        if cloneUrl.startswith("http"):
           cloneUrl = repoItem['links']['clone'][0]['href']
        if not cloneUrl.startswith("ssh"):
           logging.error("Unable to retrieve valid clone url [{}], exiting...".format(cloneUrl))
           sys.exit(1)

        repository = BitBucketRepo(repoItem['name'], cloneUrl)
        clonedRepo = cloneRepo(repository)
        resultCode = updatePomFile(repository)
        if resultCode == 0:
             insert(repository.name + "/pom.xml", xmlVersion)
             clonedRepo.index.add([os.getcwd() + "/" + repository.name + "/pom.xml"])
             clonedRepo.index.commit("CM-8991: Updating pom.xml to use git connection string instead of svn")
             clonedRepo.remotes.origin.push()


validateScriptParameters()
logging.info('Bit Bucket URL [' + bitbucketBaseUrl + ']')
logging.info('User name [' + bitbucketUserName + ']')

projectKey = sys.argv[1]
bitbucketPassword = sys.argv[2]

bitbucket = stashy.connect(bitbucketBaseUrl, bitbucketUserName, bitbucketPassword)
logging.info("Module project key: [{}]".format(projectKey))

updateRepo(bitbucket, projectKey)

请注意,它需要 'stashy' python 库,并且是为 python2 编写的。