如何克隆一个GIT代码库列表?

7
我有一个由70个以上GIT repo URL(学生)组成的列表。是否有任何功能可以允许我一次性克隆它们所有?
如果没有这样的功能,那么有没有同步存储库与服务器的相同功能?
如果没有,我想我需要编写一个快速的shell脚本来完成这个任务。

4
Shell脚本是个不错的选择。 - Bartlomiej Lewandowski
好的,我完成后会将shell脚本发布为答案。 - Kevin Van Ryckegem
我使用Checkoutmanager(https://pypi.python.org/pypi/checkoutmanager),这是一个简单的工具,用于更新存储库列表。 - RemcoGerlich
已完成Shell脚本。明天会发布。 - Kevin Van Ryckegem
4个回答

19

Shell 脚本。

获取代码库

获取代码库的主要思路是

while read repo; do
    git clone "$repo"
done < repolist.txt

假设文件“repolist.txt”每行包含一个仓库URL。

更新仓库

这个有点棘手。

虽然遍历仓库列表很容易,但是“同步”存在概念上的问题。 它的本质在于,当您以“正常”的方式克隆(即不指定修改git clone默认值的不同命令行选项)时,在您的本地仓库中以所谓的“远程分支”的形式创建源仓库的所有分支。 这些远程分支仅跟踪源仓库中匹配分支的状态。然后选择单个分支,在源仓库中标记为“当前”,并从中创建一个本地(也就是只属于你自己的)分支。所以当你克隆一个带有100个分支的仓库时,你最终只会拥有单个本地分支(在99.9%的情况下是“master”)。

接下来,自动“同步”在这里是无意义的: 在通常克隆的仓库中执行git fetch origin时,远程分支将被更新其新内容,并且几乎完全同步。1 请注意,您的本地分支根本没有被触及。 那是因为你可能在本地分支上做了工作, 因此您必须决定如何将远程分支的更新状态与本地分支协调,如果需要。 这仅是Git默认工作模型的一部分,因为这是大多数情况所需的。

如果您不打算在这些仓库的分支上做任何工作,并且仅用于检查,则最简单的方法是使Git根本没有远程分支。

要实现这一点,您可以使用以下几个明确的步骤进行克隆:

  1. 初始化一个空仓库:

    git init <dirname>
    
  2. 配置远程存储库:

  3. git remote add --mirror=fetch origin <url>
    

    --mirror=fetch参数告诉Git建立映射,将要获取的内容与使用获取数据更新的内容进行映射,从而强制性地用远程内容覆盖本地内容。

  4. 获取所有数据 - 覆盖所有本地内容:

  5. git fetch -u origin
    

    -u(或 --update-head-ok)允许 Git 覆盖由HEAD引用指向的分支。这会使索引和工作树不稳定,但我们将在下一步中进行补偿。

  6. 使用新数据强制更新索引和工作树:

  7. git reset --hard HEAD
    

    这将使Git用被HEAD指向的分支的最新状态覆盖索引和工作树 — 通常是"master",但如果您切换到另一个分支(请参见下文),它显然会使用那个分支。

然后,下次更新数据时,执行:

git fetch -u origin
git reset --hard HEAD

然后学习工作树中的内容。

如果您需要查看另一个分支,通常

git branch -a

观察列表并选择一个分支,然后

git checkout <that_branch>

会奏效。

本质上,所有这些明确的仓库初始化和以特殊方式添加远程的舞蹈都是必需的,因为git clone命令的--mirror选项意味着创建一个裸仓库,而我们应该想要一个普通的仓库(我认为是这样的)。

要更新位于目录中的所有存储库,请执行以下操作:

find "$root_dir" -mindepth 1 -maxdepth 1 -type d -print \
    | while read repo; do \
        cd "$repo" && \
        git fetch -u origin && \
        git reset --hard HEAD \
      done

1 远程仓库中删除的分支不会在本地自动删除,需运行git remote prune origin命令来实现。



git clone $repo <------ 不带引号 - Anthony Piñero
@Anthony Piñero,能否详细说明一下?当替换变量时,shell会将它们去掉。 - kostix

1
你可以创建一个“超级项目”,将所有提到的Git仓库作为子模块包含在其中(也可参见Git SCM书籍),或使用像repo这样的工具,使用清单来管理所有仓库。

1
#! /bin/sh
while IFS= read -r line; do
    echo $line
    git clone https://your-git-repo-link/"$line".git
done < cat.txt

cat.txt 文件包含一系列的仓库名称。

customer-service

device-swap

platform-downtime


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

1
我用Python轻松地克隆了一个存储库列表。这段代码可以在不同平台上运行,但并不是百分之百安全的。我建议添加一些try-catch语句。 git_sources.list显然是您的存储库列表,以换行符分隔。 ...
    # filename: clone.py
    # purpose: attempts to git clone repos from a list file
    # beware, there are no try-catches in this script
    # run with: python3 clone.py
    import os

    cmdstr = ""
    sources_path = "git_sources.list"

    # maybe surround all this with a try-catch if you want
    with open(sources_path, "r") as sources_file:
        for line in sources_file:
            print("cloning from:")
            print(line)
            cmdstr= "git clone " + line
            os.system(cmdstr)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接