I'm trying to make a script to auto pull this repo and all of its branches into either their own folders, or into one large folder. I can't find a way to do this other than manually cloning all 48 branches, then copying all of their files into a folder, however, this would take quite a while and be impractical to do with every update. Is there a way to clone all of these branches into their own folders, without specifying every branch?
-
How do you mean "Is there a way to clone all of these branches into their own folders, without specifying every branch?" But all this branches have the same folder, so clone the whole repo, or do I misunderstand your question? – SwissCodeMen Nov 20 '20 at 15:00
-
These branches contain different folders as well as different files, so I want to get all of the folders and files from every branch to copy them all into a single folder. – Kirna Nov 20 '20 at 15:11
-
Have you thought about merging the branches to combine there content? – ian Nov 20 '20 at 15:28
-
@ian, each branch seems to contain a separate theme. They're not really branches. – jessehouwing Nov 20 '20 at 15:44
-
Your question says "their own folders, or ... one large folder". My answer below addresses the former. The latter is not going to be practical, because even if *you* know there's no overlap between the branches' content, git will never make that assumption (as it's frankly not how branches are meant to be used). – Mark Adelsberger Nov 20 '20 at 16:38
3 Answers
You can check out a branch to a separate directory using git worktree
(https://git-scm.com/docs/git-worktree).
You can automate the processing of all branches by scripting with git for-each-ref
(https://git-scm.com/docs/git-for-each-ref).
The scripting can be slightly complicated because by default you have one worktree and it's got one branch checked out. (I considered using a bare
repo to avoid this, but git makes different assumptions about how a bare
repo will be used and so some things don't get set up the way you'd want them by default.) To avoid problems, you should put the default worktree in detached HEAD
state.
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
For each branch in the origin repo (whose name is, say <branchname>
, this will create a directory my-tfs-style-repo/<branchname>
with that branch checked out.
ps - This really isn't git's expected workflow, and in fact based on the comments on your question, it sounds like the repo is really not doing things the way they should be done in git.
Consequently, even with a solution like this, updates are not going to be that easy to receive. You'll have to iterate over every worktree and tell it to pull updates from its corresponding branch. Not impossilbe - scriptable, even - but a symptom of an underlying problem.
How should it be? Well, I'd need to know more about what they're doing. It sounds like each of those branches should be a repo, and they should be grouped together in some way (maybe git submodules, maybe a build process that treats each one as a separate package).

- 42,148
- 4
- 35
- 52
-
Thank you! This did exactly what I was looking for. Now it will be much easier to make an auto-update script for all of these themes. The updating issue shouldn't be a problem as all I'm doing is building all of these themes into a single package on a GitHub runner, so it's a clean build every time. – Kirna Nov 20 '20 at 16:43
like.... checkout all branches at the same time in a single working tree? Not that I know of... at least not that they are all checked out at the same time. If all branches have different structures in terms of the directories/files that they contain, you might do something like:
git branch | while read branch; do
git checkout $branch -- .
done
But that's not officially making every single branch be "checked out".... it's just that you asked the content from all branches to be put on the working tree. The index will be filled with files to be committed..... you are playing with fire, if you ask me.
Now, if they could be held in their own work-tree, you might do:
git branch | while read branch; do
git worktree add $branch $branch
done
That will create a separate working tree for every branch

- 26,375
- 3
- 36
- 60
-
1`git branch` shouldn't really be used for scripting; that's what `for-each-ref` is for. Note that as written this will only work on branches that have already been locally checked out. – Mark Adelsberger Nov 20 '20 at 16:35
If I understood your question, you want to clone each branch and track them each in a separate folder.
Here's a hacky bash script that can do that. Each branch cloned and tracked in its own folder.
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

- 5,745
- 2
- 25
- 42
-
This creates a separate local repo for each branch, which is asking for trouble. Use `git worktree` instead. – Mark Adelsberger Nov 20 '20 at 16:35