static function add_gitblog_submodule()
{
# Add gitblog submodule
$roundtrip_temp = false;
$dotgitmodules = gb::$dir . '/.gitmodules';
$did_have_dotgitmodules = is_file($dotgitmodules);
$added = array();
$origin_url = 'git://github.com/rsms/gitblog.git';
# first, find the origin url if any
$broken_gitblog_repo = false;
if (is_dir(gb::$dir . '/.git')) {
try {
gb::log('deducing remote.origin.url for existing gitblog');
$s = trim(git::exec('config remote.origin.url', null, gb::$dir . '/.git', gb::$dir));
if ($s) {
$origin_url = $s;
}
} catch (GitError $e) {
gb::log(LOG_WARNING, 'failed to read config remote.origin.url: %s', $e->getMessage());
$broken_gitblog_repo = true;
}
}
# if gitblog is not a repo or broken, rename existing and clone a fresh copy from upstream
if ($broken_gitblog_repo) {
$stash_dir = gb::$dir . '.old';
$i = 1;
while (file_exists($stash_dir)) {
$stash_dir = gb::$dir . '.old' . $i++;
}
gb::log('moving broken gitblog %s to %s', gb::$dir, $stash_dir);
if (!rename(gb::$dir, $stash_dir)) {
# Note: This is tricky. If we get here, it probably means we are unable to
# write in dirname(gb::$dir) and gb::$site_dir which we will try to do
# further down, where we clone a new copy, which will most likely fail
# because we can not create a new directory called "gitblog" due to lack of
# priveleges.
#
# Now, one solution would be to:
#
# git clone origin /tmp/xy
# mkdir ./gitblog/old
# mv ./gitblog/(?!old)+ ./gitblog/old/
# mv /tmp/xy/* ./gitblog/
# rm -rf ./gitblog/old
#
# But as this is a very thin use case, almost vanishingly small since
# the gitblog itself can not function w/o write rights, we die hard:
gb::log(LOG_CRIT, 'unable to replace gitblog with gitblog submodule (mv %s %s) -- directory not writable? Aborting.', gb::$dir, $stash_dir);
exit;
}
}
try {
# remove "/gitblog" ignore from .gitignore
if (self::gitignore_sub('/(?:\\r?\\n)\\/gitblog([\\t\\s \\r\\n]+|^)/m', '$1')) {
$added[] = git::add('.gitignore');
}
# register (and clone if needed) the gitblog submodule. This might take some time.
try {
git::exec('submodule --quiet add -b ' . escapeshellarg(self::$branch) . ' -- ' . escapeshellarg($origin_url) . ' gitblog');
# add gitblog
$added[] = git::add('gitblog');
} catch (GitError $e) {
if (strpos($e->getMessage(), 'already exists in the index') === false) {
throw $e;
}
}
# move back old shallow gitblog dir
if ($roundtrip_temp) {
$old_dst = gb::$dir . '/gitblog.old';
gb::log('moving %s to %s', $roundtrip_temp, $old_dst);
if (!@rename($roundtrip_temp, $old_dst)) {
gb::log(LOG_ERR, 'failed to move back %s to %s', $roundtrip_temp, $old_dst);
}
# we want to explicitly checkout the branch we requested
git::exec('checkout ' . escapeshellarg(self::$branch), null, gb::$dir . '/.git', gb::$dir);
}
} catch (Exception $e) {
# move back gitblog dir
if ($roundtrip_temp) {
gb::log('moving %s to %s', $roundtrip_temp, gb::$dir);
if (!@rename($roundtrip_temp, gb::$dir)) {
gb::log(LOG_ERR, 'failed to move back %s to %s', $roundtrip_temp, gb::$dir);
}
}
# forward exception
throw $e;
}
# if .submodules did not exist when we started, track it
if (!$did_have_dotgitmodules && is_file(gb::$site_dir . '/.gitmodules')) {
$added[] = git::add('.gitmodules');
}
# commit any modifications
if ($added) {
try {
git::commit('added ' . implode(', ', $added), GBUser::findAdmin()->gitAuthor(), $added);
} catch (GitError $e) {
if (strpos($e->getMessage(), 'no changes added to commit') === false) {
throw $e;
}
}
}
}