Skip to content

Instantly share code, notes, and snippets.

@C-l-o-u-d
Forked from rodw/backup-github.sh
Last active May 14, 2022 13:03
Show Gist options
  • Select an option

  • Save C-l-o-u-d/84a4a4299899dda80566f2122c286e55 to your computer and use it in GitHub Desktop.

Select an option

Save C-l-o-u-d/84a4a4299899dda80566f2122c286e55 to your computer and use it in GitHub Desktop.

Revisions

  1. C-l-o-u-d revised this gist May 14, 2022. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -70,9 +70,12 @@ check mkdir -p $GHBU_BACKUP_DIR

    $GHBU_SILENT || echo -n "Fetching list of repositories for ${GHBU_ORG}..."

    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos\?per_page=100 -q | check grep "^ \"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'` # hat tip to https://gist.github.com/rodw/3073987#gistcomment-3217943 for the license name workaround
    # NOTE: if you're backing up a *user's* repos, not an organizations, use this instead:
    # REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/user/repos -q | check grep "^ \"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    if [[ "$GHBU_ORG" != "$GHBU_UNAME" ]]; then
    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos\?per_page=100 -q | check grep "^ \"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'` # hat tip to https://gist.github.com/rodw/3073987#gistcomment-3217943 for the license name workaround
    else
    # NOTE: if you're backing up a *user's* repos, not an organizations, use this instead:
    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/user/repos -q | check grep "^ \"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    fi

    $GHBU_SILENT || echo "found `echo $REPOLIST | wc -w` repositories."

  2. C-l-o-u-d revised this gist Apr 16, 2022. 1 changed file with 17 additions and 4 deletions.
    21 changes: 17 additions & 4 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -40,6 +40,7 @@ GHBU_SILENT=${GHBU_SILENT-false} # when `tru
    GHBU_API=${GHBU_API-"https://api.github.com"} # base URI for the GitHub API
    GHBU_GIT_CLONE_CMD="git clone --quiet --mirror git@${GHBU_GITHOST}:" # base command to use to clone GitHub repos
    TSTAMP=`date "+%Y%m%d-%H%M"` # format of timestamp suffix appended to archived files
    TSTAMP_WILDCARD=`date "+%Y%m%d-*"` # format of timestamp suffix appended to archived files with wildcard
    #-------------------------------------------------------------------------------
    # (end config)
    #-------------------------------------------------------------------------------
    @@ -80,13 +81,25 @@ $GHBU_SILENT || (echo "" && echo "=== BACKING UP ===" && echo "")

    for REPO in $REPOLIST; do
    $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}"
    check ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git
    if ls ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP_WILDCARD}.git.tar.gz 1> /dev/null 2>&1; then
    $GHBU_SILENT || echo "... skipping"
    else
    check ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git
    fi

    $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}.wiki (if any)"
    ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.wiki.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git 2>/dev/null && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git
    if ls ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP_WILDCARD}.git.tar.gz 1> /dev/null 2>&1; then
    $GHBU_SILENT || echo "... skipping"
    else
    ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.wiki.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git 2>/dev/null && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git
    fi

    $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO} issues"
    check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/repos/${GHBU_ORG}/${REPO}/issues -q > ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP} && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP}
    if ls ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP_WILDCARD}.tar.gz 1> /dev/null 2>&1; then
    $GHBU_SILENT || echo "... skipping"
    else
    check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/repos/${GHBU_ORG}/${REPO}/issues -q > ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP} && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP}
    fi
    done

    if $GHBU_PRUNE_OLD; then
    @@ -97,4 +110,4 @@ if $GHBU_PRUNE_OLD; then
    fi

    $GHBU_SILENT || (echo "" && echo "=== DONE ===" && echo "")
    $GHBU_SILENT || (echo "GitHub backup completed." && echo "")
    $GHBU_SILENT || (echo "GitHub backup completed." && echo "")
  3. @rodw rodw revised this gist Dec 31, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -27,12 +27,12 @@
    #-------------------------------------------------------------------------------
    # CONFIG:
    #-------------------------------------------------------------------------------
    GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files
    GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up
    # # (if you're backing up a USER's repos, this should be your GitHub username; also see the note below about the `REPOLIST` definition)
    GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API)
    GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account
    #-------------------------------------------------------------------------------
    GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files
    GHBU_GITHOST=${GHBU_GITHOST-"github.com"} # the GitHub hostname (see comments)
    GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} # when `true`, old backups will be deleted
    GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} # the min age (in days) of backup files to delete
  4. @rodw rodw revised this gist Dec 31, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -32,8 +32,8 @@ GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHu
    # # (if you're backing up a USER's repos, this should be your GitHub username; also see the note below about the `REPOLIST` definition)
    GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API)
    GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account
    GHBU_GITHOST=${GHBU_GITHOST-"github.com"} # the GitHub hostname (see comments)
    #-------------------------------------------------------------------------------
    GHBU_GITHOST=${GHBU_GITHOST-"github.com"} # the GitHub hostname (see comments)
    GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} # when `true`, old backups will be deleted
    GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} # the min age (in days) of backup files to delete
    GHBU_SILENT=${GHBU_SILENT-false} # when `true`, only show error messages
  5. @rodw rodw revised this gist Dec 31, 2021. 1 changed file with 33 additions and 8 deletions.
    41 changes: 33 additions & 8 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,48 @@
    #!/bin/bash
    # A simple script to backup an organization's GitHub repositories.

    # NOTE: if you have more than 100 repositories, you'll need to step thru the list of repos
    # returned by GitHub one page at a time, as described at https://gist.github.com/darktim/5582423

    #-------------------------------------------------------------------------------
    # NOTES:
    #-------------------------------------------------------------------------------
    # * Under the heading "CONFIG" below you'll find a number of configuration
    # parameters that must be personalized for your GitHub account and org.
    # Replace the `<CHANGE-ME>` strings with the value described in the comments
    # (or overwrite those values at run-time by providing environment variables).
    #
    # * If you have more than 100 repositories, you'll need to step thru the list
    # of repos returned by GitHub one page at a time, as described at
    # https://gist.github.com/darktim/5582423
    #
    # * If you want to back up the repos for a USER rather than an ORGANIZATION,
    # there's a small change needed. See the comment on the `REPOLIST` definition
    # below (i.e search for "REPOLIST" and make the described change).
    #
    # * Thanks to @Calrion, @vnaum, @BartHaagdorens and other commenters below for
    # various fixes and updates.
    #
    # * Also see those comments (and related revisions and forks) for more
    # information and general troubleshooting.
    #-------------------------------------------------------------------------------

    #-------------------------------------------------------------------------------
    # CONFIG:
    #-------------------------------------------------------------------------------
    GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files
    GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up
    # (if you're backing up a user's repos instead, this should be your GitHub username); also see the note below about the `REPOLIST` definition around line 48
    # # (if you're backing up a USER's repos, this should be your GitHub username; also see the note below about the `REPOLIST` definition)
    GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API)
    GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account
    GHBU_GITHOST=${GHBU_GITHOST-"github.com"} # the GitHub hostname (see comments)
    #-------------------------------------------------------------------------------
    GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} # when `true`, old backups will be deleted
    GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} # the min age (in days) of backup files to delete
    GHBU_SILENT=${GHBU_SILENT-false} # when `true`, only show error messages
    GHBU_API=${GHBU_API-"https://api.github.com"} # base URI for the GitHub API
    GHBU_GIT_CLONE_CMD="git clone --quiet --mirror git@${GHBU_GITHOST}:" # base command to use to clone GitHub repos

    TSTAMP=`date "+%Y%m%d-%H%M"`
    TSTAMP=`date "+%Y%m%d-%H%M"` # format of timestamp suffix appended to archived files
    #-------------------------------------------------------------------------------
    # (end config)
    #-------------------------------------------------------------------------------

    # The function `check` will exit the script if the given command fails.
    function check {
    @@ -45,8 +71,7 @@ $GHBU_SILENT || echo -n "Fetching list of repositories for ${GHBU_ORG}..."

    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos\?per_page=100 -q | check grep "^ \"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'` # hat tip to https://gist.github.com/rodw/3073987#gistcomment-3217943 for the license name workaround
    # NOTE: if you're backing up a *user's* repos, not an organizations, use this instead:
    # REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/users/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    # ALSO NOTE: I haven't personally checked but I suspect the fix noted at https://gist.github.com/rodw/3073987#gistcomment-3217943 is also need in the user-specific case, i.e. change `check grep "\"name\""` to `check grep "^ \"name\""` if you're using the user-specific variation
    # REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/user/repos -q | check grep "^ \"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`

    $GHBU_SILENT || echo "found `echo $REPOLIST | wc -w` repositories."

  6. @rodw rodw revised this gist Oct 7, 2020. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@

    GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files
    GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up
    # (if you're backing up a user's repos instead, this should be your GitHub username)
    # (if you're backing up a user's repos instead, this should be your GitHub username); also see the note below about the `REPOLIST` definition around line 48
    GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API)
    GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account
    GHBU_GITHOST=${GHBU_GITHOST-"github.com"} # the GitHub hostname (see comments)
    @@ -43,9 +43,10 @@ check mkdir -p $GHBU_BACKUP_DIR

    $GHBU_SILENT || echo -n "Fetching list of repositories for ${GHBU_ORG}..."

    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos\?per_page=100 -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos\?per_page=100 -q | check grep "^ \"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'` # hat tip to https://gist.github.com/rodw/3073987#gistcomment-3217943 for the license name workaround
    # NOTE: if you're backing up a *user's* repos, not an organizations, use this instead:
    # REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/user/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    # REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/users/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    # ALSO NOTE: I haven't personally checked but I suspect the fix noted at https://gist.github.com/rodw/3073987#gistcomment-3217943 is also need in the user-specific case, i.e. change `check grep "\"name\""` to `check grep "^ \"name\""` if you're using the user-specific variation

    $GHBU_SILENT || echo "found `echo $REPOLIST | wc -w` repositories."

  7. @rodw rodw revised this gist Feb 22, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -43,7 +43,7 @@ check mkdir -p $GHBU_BACKUP_DIR

    $GHBU_SILENT || echo -n "Fetching list of repositories for ${GHBU_ORG}..."

    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos\?per_page=100 -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    # NOTE: if you're backing up a *user's* repos, not an organizations, use this instead:
    # REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/user/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`

  8. @rodw rodw revised this gist Feb 22, 2016. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,9 @@
    #!/bin/bash
    # A simple script to backup an organization's GitHub repositories.

    # NOTE: if you have more than 100 repositories, you'll need to step thru the list of repos
    # returned by GitHub one page at a time, as described at https://gist.github.com/darktim/5582423

    GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files
    GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up
    # (if you're backing up a user's repos instead, this should be your GitHub username)
  9. @rodw rodw revised this gist Mar 13, 2014. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -39,7 +39,11 @@ $GHBU_SILENT || echo "Using backup directory $GHBU_BACKUP_DIR"
    check mkdir -p $GHBU_BACKUP_DIR

    $GHBU_SILENT || echo -n "Fetching list of repositories for ${GHBU_ORG}..."

    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    # NOTE: if you're backing up a *user's* repos, not an organizations, use this instead:
    # REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/user/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`

    $GHBU_SILENT || echo "found `echo $REPOLIST | wc -w` repositories."


  10. @rodw rodw revised this gist Mar 13, 2014. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -3,9 +3,10 @@

    GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files
    GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up
    # (if you're backing up a user's repos instead, this should be your GitHub username)
    GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API)
    GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account
    GHBU_GITHOST=${GHBU_GITHOST-"<CHANGE-ME>.github.com"} # the GitHub hostname (see comments)
    GHBU_GITHOST=${GHBU_GITHOST-"github.com"} # the GitHub hostname (see comments)
    GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} # when `true`, old backups will be deleted
    GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} # the min age (in days) of backup files to delete
    GHBU_SILENT=${GHBU_SILENT-false} # when `true`, only show error messages
  11. @rodw rodw revised this gist Oct 10, 2013. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to
    GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up
    GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API)
    GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account
    GHBU_GITHOST=${GHBU_GITHOST-"<CHANGE-ME>.github.com"} # the GitHub hostname (see notes)
    GHBU_GITHOST=${GHBU_GITHOST-"<CHANGE-ME>.github.com"} # the GitHub hostname (see comments)
    GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} # when `true`, old backups will be deleted
    GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} # the min age (in days) of backup files to delete
    GHBU_SILENT=${GHBU_SILENT-false} # when `true`, only show error messages
    @@ -63,5 +63,4 @@ if $GHBU_PRUNE_OLD; then
    fi

    $GHBU_SILENT || (echo "" && echo "=== DONE ===" && echo "")
    $GHBU_SILENT || (echo "GitHub backup completed." && echo "")
    ACT SAVE READ SHARE FOLLOW
    $GHBU_SILENT || (echo "GitHub backup completed." && echo "")
  12. @rodw rodw created this gist Jul 9, 2012.
    67 changes: 67 additions & 0 deletions backup-github.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    #!/bin/bash
    # A simple script to backup an organization's GitHub repositories.

    GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files
    GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up
    GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API)
    GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account
    GHBU_GITHOST=${GHBU_GITHOST-"<CHANGE-ME>.github.com"} # the GitHub hostname (see notes)
    GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} # when `true`, old backups will be deleted
    GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} # the min age (in days) of backup files to delete
    GHBU_SILENT=${GHBU_SILENT-false} # when `true`, only show error messages
    GHBU_API=${GHBU_API-"https://api.github.com"} # base URI for the GitHub API
    GHBU_GIT_CLONE_CMD="git clone --quiet --mirror git@${GHBU_GITHOST}:" # base command to use to clone GitHub repos

    TSTAMP=`date "+%Y%m%d-%H%M"`

    # The function `check` will exit the script if the given command fails.
    function check {
    "$@"
    status=$?
    if [ $status -ne 0 ]; then
    echo "ERROR: Encountered error (${status}) while running the following:" >&2
    echo " $@" >&2
    echo " (at line ${BASH_LINENO[0]} of file $0.)" >&2
    echo " Aborting." >&2
    exit $status
    fi
    }

    # The function `tgz` will create a gzipped tar archive of the specified file ($1) and then remove the original
    function tgz {
    check tar zcf $1.tar.gz $1 && check rm -rf $1
    }

    $GHBU_SILENT || (echo "" && echo "=== INITIALIZING ===" && echo "")

    $GHBU_SILENT || echo "Using backup directory $GHBU_BACKUP_DIR"
    check mkdir -p $GHBU_BACKUP_DIR

    $GHBU_SILENT || echo -n "Fetching list of repositories for ${GHBU_ORG}..."
    REPOLIST=`check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/orgs/${GHBU_ORG}/repos -q | check grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`
    $GHBU_SILENT || echo "found `echo $REPOLIST | wc -w` repositories."


    $GHBU_SILENT || (echo "" && echo "=== BACKING UP ===" && echo "")

    for REPO in $REPOLIST; do
    $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}"
    check ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git

    $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}.wiki (if any)"
    ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.wiki.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git 2>/dev/null && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git

    $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO} issues"
    check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/repos/${GHBU_ORG}/${REPO}/issues -q > ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP} && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP}
    done

    if $GHBU_PRUNE_OLD; then
    $GHBU_SILENT || (echo "" && echo "=== PRUNING ===" && echo "")
    $GHBU_SILENT || echo "Pruning backup files ${GHBU_PRUNE_AFTER_N_DAYS} days old or older."
    $GHBU_SILENT || echo "Found `find $GHBU_BACKUP_DIR -name '*.tar.gz' -mtime +$GHBU_PRUNE_AFTER_N_DAYS | wc -l` files to prune."
    find $GHBU_BACKUP_DIR -name '*.tar.gz' -mtime +$GHBU_PRUNE_AFTER_N_DAYS -exec rm -fv {} > /dev/null \;
    fi

    $GHBU_SILENT || (echo "" && echo "=== DONE ===" && echo "")
    $GHBU_SILENT || (echo "GitHub backup completed." && echo "")
    ACT SAVE READ SHARE FOLLOW