3

I am looking for a way to export a Git repository so that I get a zip or directory for each branch individually.

This is similar to Do a "git export" (like "svn export")?, but instead of a zip of the current branch I am hoping to get a zip for every branch.

Is there a Git or Bash command that could do this?

Community
  • 1
  • 1
Kyeotic
  • 19,697
  • 10
  • 71
  • 128
  • As pointed out in [toydarian's answer](http://stackoverflow.com/a/24371664/456814), `git archive` can accept a branch name to export as an argument, so you just need to write a script that loops through the branch names and passes them to `git archive`, like toydarian has done. –  Jun 23 '14 at 19:03
  • I was asking for a command because I was hoping an OS agnostic method existed. Scripts like toydarians are useful, but wont run on windows. Yes, I could write a windows-compatible one, but I wanted to find out if a normal command could do it; it looks like the answer is no. – Kyeotic Jun 23 '14 at 19:22
  • You say it won't run on Windows, and yet you asked specifically for a Bash command. Are you using Git Bash? It should work as long as you use Git Bash, even on Windows. –  Jun 23 '14 at 19:25
  • I am using Git bash. It does not work. `$ for f in ${$(git branch)[@]:1}; do; git archive --format zip --output /out/${f}.zip $f; done sh.exe": syntax error near unexpected token `;'` – Kyeotic Jun 23 '14 at 22:13
  • There's probably a syntax mistake somewhere in the first line (Bash for loops will work in Windows Git Bash), I'm working on an alternative... –  Jun 23 '14 at 22:48

2 Answers2

5

Use git archive with a branch argument

git archive can accept a branch name to export as an argument, so you just need to write a script that loops through the branch names and passes them to git archive. For example, this will work in Windows Git Bash:

git for-each-ref --format='%(refname:short)' refs/heads | \
while read branch; do
  git archive --format zip --output <outputDirectory>/${branch}.zip $branch
done

I modified it from the 2nd example in the official Linux Kernel documentation for git for-each-ref.

Breakdown

$ git for-each-ref --format='%(refname:short)' refs/heads
foo
master

git for-each-ref will list each local branch under refs/heads, using just the branch name with the refname:short format.

That output is piped into a Bash while loop, which then substitutes the branch name for the git archive arguments:

while read branch; do
  git archive --format zip --output <outputDirectory>/${branch}.zip $branch
done

For-loop solution

Here's a Bash for loop solution, inspired by toydarian's (non-working) solution:

for branch in $(git for-each-ref --format='%(refname:short)' refs/heads); do
  git archive --format zip --output <outputDirectory>/${branch}.zip $branch
done

Documentation

Community
  • 1
  • 1
2

Try this script. Make sure you checked out master before using the script!

for f in ${$(git branch)[@]:1}; do
    git archive --format zip --output /path/to/dir/${f}.zip $f
done

Here's the same commands in one line, to make it easier to copy, paste, and execute:

for f in ${$(git branch)[@]:1}; do; git archive --format zip --output /path/to/dir/${f}.zip $f; done
toydarian
  • 4,246
  • 5
  • 23
  • 35
  • FYI, your commands won't work in Windows Git Bash, you probably have a syntax error somewhere: "`sh.exe": syntax error near unexpected token ``;'`". That's the error the for the one-liner. "`sh.exe": ${$(git branch)[@]:1}: bad substitution`". That's the error for the first one. –  Jun 23 '14 at 22:49
  • Also note that you can actually copy, paste, and execute the first version of your command just fine, it shouldn't be necessary to put everything on one line in a terminal. –  Jun 23 '14 at 23:04
  • FYI, `git branch` is ill-suited to listing branches, unless you strip out the `*` that's listed next to the current branch, because `*` is interpreted as a file glob by `$()`, so it ends up expanding to all the files and directories in the current directory. It's one of Git's "porcelain" commands, vs a "plumbing" command like `git for-each-ref`, which is specifically made for scripting purposes, unlike `git branch`. –  Jun 24 '14 at 02:59