Skip to content

Instantly share code, notes, and snippets.

@gcstang
Created July 20, 2018 16:29
Show Gist options
  • Save gcstang/bf1a4f6d9022acf362105a2fb5b2c302 to your computer and use it in GitHub Desktop.
Save gcstang/bf1a4f6d9022acf362105a2fb5b2c302 to your computer and use it in GitHub Desktop.
Backup a github repository from Windows. Assumes B2 command lines tools, python, and 7ZIP are installed. Script requires some variables (B2 account, etc) to filled in.
@echo off
SETLOCAL
REM Script to backup git repo to Backblaze B2
REM Set bucket, local directory, password and account to use for the backup.
:: NOTE: might want to import these from the outer environment
:: rather than setting them internally
REM set b2Bucket=%GITHUB_BACKUP_BUCKET%
REM set b2Path=%GITHUB_BACKUP_DIR%
REM set localDir=%LOCALDIR%
REM set zipPassword=%GIT_ZIP_PASSWORD%
REM set b2Path=%GIT_B2BACKUP_DIR%
REM set b2Account=%B2_ACCOUNT_ID%
REM set b2Key=%B2_ACCOUNT_KEY%
REM *************************************************
REM * Set these variables to configure the script
REM *************************************************
set localDir=tempGitToBackblazeB2Backup
set b2Path=gitBackups
set zipPassword=securityThroughObscurityIsAKnownSecurityRisk
set b2Bucket=b2BucketNameGoesHere
set b2Account=7dab0707
set b2Key=aabb44cc34590918af1254e5568d
REM To restore this repo in the future, download it from B2, extract it and then use this command:
REM cd old-repository.git
REM git push --mirror https://github.com/exampleuser/new-repository.git
REM *************************************************
REM * NO NEED TO TOUCH ANYTHING BELOW THIS LINE
REM *************************************************
REM Initial setup of spacers & errcode
REM NOTE! Some editors will turn the TAB character in the next line into spaces,
REM which will be treated as white space by the ECHO cmd built-in, and that
REM will spoil the indents of some error and help messages.
set "tab= "
set 2tb=%tab%%tab%
set 3tb=%2tb%%tab%
set err=0
REM setup for SSH
REM Installing and getting SSH up is beyond the scope
REM of this script. If SSH/GIT is up and working, and
REM GIT is correctly working with it, then switch
REM over to using SSH by setting useSSH to YES
set useSSH=no
:: =============================================================== ::
:: These variables need to be set by the script user
:: Verify that these are all configured
:: =============================================================== ::
if [%b2Bucket%] == [] (
set err=404
echo %tab% Backblaze B2 bucket (b2Bucket) variable is unset.
)
if [%b2Account%] == [] (
set err=404
echo %tab% Backblaze account ID (b2Account) variable is unset.
)
if [%b2Key%] == [] (
set err=404
echo %tab% Backblaze account key (b2Key) variable is unset.
)
if not %err% equ 0 (
goto :ENDOFBATCH
)
:: ============================================================== ::
:: check the arguments for validity
:: ============================================================== ::
REM special case: help request
if /I [%1] == [/h] (
goto :HELPTEXT
)
REM empty arguments?
if [%2] == [] (
set err=102
goto :BADARGS
REM will exit
)
if [%1] == [] (
set err=101
goto :BADARGS
REM will exit
)
REM too many arguments?
if not [%3] == [] (
set err=103
goto :BADARGS
REM will exit
)
REM set zip command tool. It is run as:
REM zipExe zipCmd zipArg [ArchiveFile] [ArchiveDirectory]
REM if there is a password configured, use it, otherwise, don't
set passParam%=
if NOT [%zipPassword%] == [""] (
set passParam=-p%zipPassword%
)
set zipExe=7z
set zipCmd=a
set zipArg=-mx9 -t7z -ms=on -r -y %passParam%
REM Setup repository to name - repo
set repoUser=%1%
set repoName=%2%
set repo=%repoUser%/%repoName%
REM kludge to get locale-independent timestamp
pushd "%temp%"
makecab /D RptFileName=~.rpt /D InfFileName=~.inf /f nul >nul
for /f "tokens=3-7" %%a in ('find /i "makecab"^<~.rpt') do (
set "current-date=%%e_%%b_%%c"
set "initial-time=%%d"
set "weekday=%%a"
)
REM colon is an invalid file-character, so replace with h-m-s
echo %initial-time% > ~.tml
for /f "tokens=1-3 delims=:" %%q in ( ~.tml ) do (
set "init_time=%%qh%%rm%%ss"
)
REM remove any spaces
set current-time=%init_time: =%
popd
set timestamp=%current-date%_%current-time%
REM echo %timestamp%
REM Create the backup directory
if not exist %localDir% (
mkdir %localDir%
if %ERRORLEVEL% neq 0 (
echo "Error (" %ERRORLEVEL% ") creating directory %localDir%
set err=110
goto :ENDOFBATCH
)
)
echo %tab% Backing up %repo% ...
REM if SSH has been enabled, yay. If not ...
if /I [%useSSH%] ==[YES] (
set gitURL=git@github.com:
) else (
set gitURL=https://github.com/
)
REM create a specific timestamped directory
set repoDirectory=%localDir%\%repoName%.%timestamp%.git
REM name of archive
set repo7z=%repoName%.%timestamp%.7z
echo %tab% cloning %gitURL%%repo% to %repoDirectory% ...
git clone --mirror %gitURL%%repo% %repoDirectory% > nul 2>&1
if %ERRORLEVEL% neq 0 (
echo "Error (" %ERRORLEVEL% ") cloning " %repository%
set err=111
goto :ENDOFBATCH
)
echo %tab% ... clone successful
echo %tab% Compressing %repoDirectory% to %repo7z% ...
%zipExe% %zipCmd% %zipArg% %repo7z% %repoDirectory% > nul 2>&1
if %ERRORLEVEL% neq 0 (
echo "Error (" %ERRORLEVEL% ") zipping "%localDir%\%repository%.%timestamp%.git
set err=112
goto :ENDOFBATCH
)
echo %tab% ... compression successful
echo %tab% Uploading to Backblaze B2 ...
b2 authorize-account %b2Account% %b2Key% > nul 2>&1
if %ERRORLEVEL% neq 0 (
echo "Error (" %ERRORLEVEL% ") running b2 authorize-account %b2Account% %b2Key%
set err=121
goto :ENDOFBATCH
)
REM suppress the returned information from B2 UPLOAD-FILE and simply report the errorlevel if not 0
b2 upload-file --noProgress %b2Bucket% %repo7z% %b2Path%/%repo7z% > nul 2>&1
if %ERRORLEVEL% neq 0 (
echo "Error (" %ERRORLEVEL% ") running b2 upload-file --noProgress %b2Bucket% %repo7z% %b2Path%/%repo7z%
set err=122
goto :ENDOFBATCH
)
echo %tab% ... upload successful
echo %tab% Starting cleanup
rmdir /s /q %localDir% > nul 2>&1
if %ERRORLEVEL% neq 0 (
echo "Error (" %ERRORLEVEL% ") removing %localDir%
set err=131
goto :ENDOFBATCH
)
del %repo7z% > nul 2>&1
if %ERRORLEVEL% neq 0 (
echo "Error (" %ERRORLEVEL% ") removing %repo7z%
set err=131
goto :ENDOFBATCH
)
echo %tab% ... cleanup successful
echo %tab% Successfully backed up %repo% to %b2Bucket%/%b2Path%/%repo7z%
:ENDOFBATCH
exit /b %err%
:HELPTEXT
echo %tab% Usage: %~nx0 <git-accountname> <git-repo-name>
echo %2tb% example: %~nx0 henryHiggins elizaSpeechUpgrade
echo %tab% Please note the script has several variables that
echo %tab% must be set by the user.
REM echo %tab%
exit /b %err%
:BADARGS
REM echo %tab%
echo %tab% Unexpected or missing arguments!
echo %tab%%tab% Expected: %~nx0 [gituser] [getrepo]
echo %tab%%tab% Why not try %~nx0 /h instead?
exit /b %err%
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Backing up a Github repository to Backblaze B2 from the Windows Command Line</title>
<link href="https://fonts.googleapis.com/css?family=IBM+Plex+Mono:400,400i,600,600i|IBM+Plex+Serif:400,400i,600,600i" rel="stylesheet"/>
<style>
h1 {
color: indigo;
text-align: center;
font-variant: small-caps;
line-height: 110%;
}
h1 tt {
color: darkgreen;
font-size: 80%;
font-family: "IBM Plex Mono", "Consolas", "Lucida Console", monospace;
font-variant: normal;
}
.primary {
margin: 1em 10px 2em 10px;
font-family: "IBM Plex Serif", serif;
font-size: 1em;
line-height: 115%;
margin: 1em 9px 3em 10px;
}
tt {
font-size: 80%;
font-family: "IBM Plex Mono", "Consolas", "Lucida Console", monospace;
color: darkgreen;
font-weight: bolder;
}
p {
text-indent: 0;
margin: .75em 0 0 0;
}
dl {
margin: 0 4% 0 5%;
}
dt {
margin: .75em;
}
dt tt {
color: darkslateblue;
}
dd p:first-child {
margin: 0;
}
dd blockquote {
margin-top: 0;
margin-bottom: 0;
}
dd blockquote tt {
font-family: monospace;
font-size: 80%;
color: darkgreen;
}
</style>
</head>
<body class="primary">
<h1>Backing up a Github repository to Backblaze B2<br/> From Windows<br/> using <tt>7Zip</tt>, the B2 Command lines Tools, and <tt>Git</tt><br/> from a command batch file</h1>
<p>Recently, we’ve seen interest in backing up the entirety of a <a href="https://www.github.com">Github</a> repository and — because they are large — stashing those repositories in secure cloud storage. This is a quick and simplistic batch file to compress and backup a repository.</p>
<div style="margin: .5em 5% .5em 5%">
<p>Usage:</p>
<div style="margin: .5em 5% .5em 5%">
<tt>github2b2.bat <i>&lt;RepositoryOwner&gt; &lt;RepositoryName&gt;</i></tt>
</div>
<dl>
<dt><tt>RepositoryOwner</tt></dt>
<dd>The GitHub account owner</dd>
<dt><tt>RepositoryName</tt></dt>
<dd>Name of the repository to back up</dd>
</dl>
<p>The repository will be backed up to a (hard-coded, see below) B2 bucket with the name and a current timestamp.</p>
</div>
<p>A few variables in the script need to be set explicitly by the user. The affected lines are:</p>
<dl>
<dt><tt>set b2Account=7dab0707</tt></dt>
<dd>B2 AccountID</dd>
<dt><tt>set b2Key=aabb44cc34590918af1254e5568d</tt></dt>
<dd>B2 AuthorizationSecretKey</dd>
<dt><tt>set b2Bucket=b2BucketNameGoesHere</tt></dt>
<dd>This is the bucket in which the repository goes</dd>
<dt><tt>set localDir=tempGitToBackblazeB2Backup</tt></dt>
<dd>The script will use this as a local directory to produce the archive; it will not be reflected in the archive tree (it is used only as a scratch working area)</dd>
<dt><tt>set b2Path=gitBackups</tt></dt>
<dd>Path within the bucket, thus the repository backup will be: <tt>&lt;bucket&gt;/&lt;path&gt;/reponame.timestamp.7z</tt></dd>
<dt><tt>set zipPassword=securityThroughObscurityIsAKnownSecurityRisk</tt></dt>
<dd>Password for 7zip file. If this is set to the empty string, the archive will not have a password.</dd>
</dl>
<p>Since these are timestamped snapshots, these are compressed in solid-block mode (that is, the archives cannot be updated later), and 7zip is configured to use maximum compression. Additionally, if there is a password, it will be encrypted with AES-256 (per the 7z documentation).</p>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment