【问题标题】:How do you clone all branches of a git repository into their own folders, without specifying every branch?如何在不指定每个分支的情况下将 git 存储库的所有分支克隆到它们自己的文件夹中?
【发布时间】:2021-03-03 23:08:31
【问题描述】:

我正在尝试编写一个脚本来自动将this repo 及其所有分支拉入它们自己的文件夹或一个大文件夹中。除了手动克隆所有 48 个分支,然后将它们的所有文件复制到一个文件夹中之外,我找不到其他方法来执行此操作,但是,这将花费相当长的时间并且每次更新都不切实际。有没有办法将所有这些分支克隆到自己的文件夹中,而不指定每个分支?

【问题讨论】:

  • 你的意思是“有没有办法将所有这些分支克隆到自己的文件夹中,而不指定每个分支?”但是所有这些分支都有相同的文件夹,所以克隆整个 repo,还是我误解了你的问题?
  • 这些分支包含不同的文件夹以及不同的文件,所以我想从每个分支中获取所有文件夹和文件,以便将它们全部复制到一个文件夹中。
  • 你有没有想过合并分支来组合那里的内容?
  • @ian,每个分支似乎都包含一个单独的主题。它们并不是真正的分支。
  • 您的问题是“他们自己的文件夹,或者......一个大文件夹”。我在下面的回答针对的是前者。后者是不实用的,因为即使 知道分支的内容之间没有重叠,git 也永远不会做出这样的假设(因为坦率地说,这不是分支的使用方式)。

标签: git git-branch git-clone


【解决方案1】:

您可以使用git worktree (https://git-scm.com/docs/git-worktree) 将分支签出到单独的目录。

您可以通过使用git for-each-ref (https://git-scm.com/docs/git-for-each-ref) 编写脚本来自动处理所有分支。

脚本可能会稍微复杂一些,因为默认情况下你有一个工作树并且它有一个分支被签出。 (我考虑使用bare repo 来避免这种情况,但是git 对bare repo 的使用方式做出了不同的假设,因此有些事情不会按照您默认的方式设置。)避免出现问题,您应该将默认工作树置于分离的HEAD 状态。

mkdir my-tfs-style-repo
cd my-tfs-style-repo
got clone url/to/remote/repo
cd repo
git checkout --detach
git for-each-ref refs/remotes/origin --format='../%(refname:lstrip=3) %(refname:lstrip=3)'|grep -v ' HEAD$' |xargs -n 2 git worktree add

对于原始存储库中的每个分支(其名称为 <branchname>,这将创建一个目录 my-tfs-style-repo/<branchname> 并签出该分支。


ps - 这确实不是 git 的预期工作流程,事实上,根据您问题上的 cmets,听起来 repo 确实没有按照在 git 中应该做的方式做事。

因此,即使有这样的解决方案,更新也不会那么容易接收。您必须遍历每个工作树并告诉它从其相应的分支中提取更新。并非不可能 - 甚至可以编写脚本 - 而是潜在问题的症状。

应该怎么样?好吧,我需要更多地了解他们在做什么。 听起来每个分支都应该是一个 repo,它们应该以某种方式组合在一起(也许是 git 子模块,也许是一个将每个分支视为单独包的构建过程)。

【讨论】:

  • 谢谢!这正是我想要的。现在为所有这些主题制作自动更新脚本会容易得多。更新问题应该不是问题,因为我所做的只是将所有这些主题构建到 GitHub 运行器上的单个包中,因此每次都是干净的构建。
【解决方案2】:

喜欢.... 在单个工作树中同时检查所有分支?不是我所知道的......至少不是他们都同时被检查出来。如果所有分支在它们包含的目录/文件方面具有不同的结构,您可能会执行以下操作:

git branch | while read branch; do
    git checkout $branch -- .
done

但这并不是正式让每个分支都被“签出”....只是您要求将所有分支的内容放在工作树上。索引将充满要提交的文件......如果你问我,你是在玩火。

现在,如果可以将它们保存在自己的工作树中,您可以这样做:

git branch | while read branch; do
    git worktree add $branch $branch
done

这将为每个分支创建一个单独的工作树

【讨论】:

  • git branch 不应该真正用于脚本;这就是for-each-ref 的用途。请注意,正如所写,这只适用于已经在本地签出的分支。
【解决方案3】:

如果我理解您的问题,您想克隆每个分支并在单独的文件夹中跟踪它们。

这是一个可以做到这一点的 hacky bash 脚本。每个分支都在自己的文件夹中克隆和跟踪。

remote="https://github.com/rtlewis88/rtl88-Themes.git"
branches=( $( git ls-remote --heads $remote | cut -f2) )
for branch in "${branches[@]}"
do
  bname=$( echo "$branch" | rev | cut -d/ -f1 | rev)
  mkdir $bname
  cd $bname
  git init
  git remote add -t $bname -f origin $remote
  git checkout $bname
  cd ..
done

【讨论】:

  • 这会为每个分支创建一个单独的本地存储库,这是自找麻烦。请改用git worktree
猜你喜欢
  • 1970-01-01
  • 2020-02-20
  • 2017-03-13
  • 2021-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 2011-01-14
相关资源
最近更新 更多