How can I archive git branches?

I believe the proper way to do this is to tag the branch. If you delete the branch after you have tagged it then you've effectively kept the branch around but it won't clutter your branch list.

If you need to go back to the branch just check out the tag. It will effectively restore the branch from the tag.

To archive and delete the branch:

git tag archive/<branchname> <branchname>
git branch -d <branchname>

To restore the branch some time later:

git checkout -b <branchname> archive/<branchname>

The history of the branch will be preserved exactly as it was when you tagged it.


Yes, you can create a ref with some non-standard prefix using git update-ref. e.g.

  • Archive the branch: git update-ref refs/archive/old-topic topic && git branch -D topic
  • Restore the branch (if needed): git branch topic refs/archive/old-topic

Refs with non-standard prefix (here refs/archive) won't show up on usual git branch, git log nor git tag. Still, you can list them with git for-each-ref.

I'm using following aliases:

[alias]
    add-archive = "!git update-ref refs/archive/$(date '+%Y%m%d-%s')"
    list-archive = for-each-ref --sort=-authordate --format='%(refname) %(objectname:short) %(contents:subject)' refs/archive/
    rem = !git add-archive
    lsrem = !git list-archive

Also, you may want to configure remotes like push = +refs/archive/*:refs/archive/* to push archived branches automatically (or just specify on push like git push origin refs/archive/*:refs/archive/* for one-shot ).

Another way is to writing down SHA1 somewhere before deleting branch, but it has limitations. Commits without any ref will be GC'd after 3 months (or a couple of weeks without reflog), let alone manual git gc --prune. Commits pointed by refs are safe from GC.

Edit: Found a perl implementation of the same idea by @ap: git-attic

Edit^2: Found a blog post where Gitster himself using the same technique. He named it git hold.


Jeremy's answer is correct in principle, but IMHO the commands he specifies are not quite right.

Here's how to archive a branch to a tag without having to checkout the branch (and, therefore, without having to checkout to another branch before you can delete that branch):

> git tag archive/<branchname> <branchname>
> git branch -D <branchname>

And here's how to restore a branch:

> git checkout -b <branchname> archive/<branchname>

Extending Steve's answer to reflect the changes on the remote, I did

 git tag archive/<branchname> <branchname>
 git branch -D <branchname>
 git branch -d -r origin/<branchname>
 git push --tags
 git push origin :<branchname>

To restore from the remote, see this question.

Tags:

Git