Supplement to the continuous deployment over SSH with Tavis CI.
git --version
# git version 2.5.3
Example: Hexo with gulp-starter
Goal: Do some postprocessing like minifying with Gulp+Webpack on generated Hexo website before deployment.
gulp-starter is an opinionated boilerplate for web development like Google's Web Starter Kit. To add another task to your gulp workflow, it's worth a look at the official Gulp recipes directory.
⚠ In this context we use submodules for ourselves only (and Travis CI as consumer). Mastering submodules in a collaborative project takes much more in depth knowlegde to avoid serious damage! ⚠
- Book "Pro Git v2" by Scott Chacon and Ben Straub
- In-depth article by Christophe Porteneuve
git-submodule(1)
manual pagegitmodules(5)
git-config(1)
Since the URL in the
.gitmodules
file is what Travis CI will try to fetch from, make sure to use a URL it can access (NOT SSH).
git submodule add --branch hexo https://github.com/GH_USER/gulp-starter.git gulp-starter
# Cloning into 'gulp-starter'...
git status
# On branch master
# Your branch is up-to-date with 'origin/master'.
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: .gitmodules
# new file: gulp-starter
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..a3732db
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,4 @@
+[submodule "gulp-starter"]
+ path = gulp-starter
+ url = https://github.com/GH_USER/gulp-starter.git
+ branch = hexo
Submodule gulp-starter 0000000...d331ffc (new submodule)
Although gulp-starter is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Submodules are composed from a so-called gitlink tree entry in the main repository that refers to a particular commit object within the inner repository that is completely separate.
This means, when Travis CI init
and update
the repository, the submodule path 'gulp-starter' is checked out to that particular commit.
But with update --remote
the latest commit from the remote's branch will be checked out.
If the submodule is intended to track a branch other than master, you set it in your .gitmodules
file:
git config -f .gitmodules submodule.gulp-starter.branch <branch>
In the first place, on the checkout to submodule's SHA-1 it's HEAD is detached. You can checkout a branch in all active submodules at once, of course.
# http://stackoverflow.com/a/18799234
git submodule foreach -q --recursive \
'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
[ -z "$branch" ] && \
git checkout master || git checkout $branch'
If submodule's repository has been modified, but superproject's gitlink hasn't pointed to that new SHA-1,
Travis CI will still checkout submodule's new commit in case --remote
will be used to update.
SHA-1 will be prefixed with "-" if the submodule is not initialized
git submodule status
# -9f4094cb7a9dba2eff72f30a9a3be8c6602de86e gulp-starter
- Submodule’s remote repository is being fetched
- Submodule's HEAD refers to the latest commit from the branch
submodule.<name>.branch
in detached state
git submodule update --init --remote --recursive
# Submodule 'gulp-starter' (https://github.com/GH_USER/gulp-starter.git) registered for path 'gulp-starter'
# Cloning into 'gulp-starter'...
# ...
# Submodule path 'gulp-starter': checked out '99d13f81d574dee80df94500bff645452b05b79c'
SHA-1 will be prefixed with "+" if the currently checked out submodule commit does not match the SHA-1 found in the index of the containing repository (superproject)
git submodule status
# +99d13f81d574dee80df94500bff645452b05b79c gulp-starter
git remote add upstream https://github.com/vigetlabs/gulp-starter.git
Useful side note referring to github-as-GH_USER
in the following SSH-URL
git remote set-url --push origin git@github-as-GH_USER:GH_USER/gulp-starter.git
git remote set-url --push upstream no-pushing
git remote -v
# origin https://github.com/GH_USER/gulp-starter.git (fetch)
# origin git@github-as-GH_USER:GH_USER/gulp-starter.git (push)
# upstream https://github.com/vigetlabs/gulp-starter (fetch)
# upstream no-pushing (push)
git pull # almost equal to "update --remote" in superproject
git checkout hexo
git status
# On branch hexo
Now you're able to bring your fork's branch into sync with the upstream repository on demand, without losing your local changes.
git fetch upstream master
git merge upstream/master
⚠ Utterly opinionated, grossly incomplete ⚠
ln -s gulp-starter/gulpfile.js gulpfile.js
More detailed information about modifcation
Accordingly less npm-packages are needed and this leads to less build-time in Travis CI (due to caching node_modules, this is not of importance).
for f in *.js; do mv -- "$f" "${f%.js}.js.off"; done
cd iconFont
for f in *.js; do mv -- "$f" "${f%.js}.js.off"; done
Then enable some tasks again.
mv production.js.off production.js
mv html.js.off html.js
mv images.js.off images.js
mv css.js.off css.js
mv webpackProduction.js.off webpackProduction.js
- "Browserify vs Webpack" by Cory House
- How-to by Pete Hunt
- Beginner's guide by Nader Dabit
mkdir javascripts
touch page1.js page2.js
mv *.js javascripts/
require('../fancybox/jquery.fancybox.pack.js');
require('../js/script.js');
cp after-footer.ejs after-footer.ejs.off
--- after-footer.ejs.off
+++ after-footer.ejs
@@ -18,7 +18,6 @@
<% if (theme.fancybox){ %>
<%- css('fancybox/jquery.fancybox') %>
- <%- js('fancybox/jquery.fancybox.pack') %>
+ <%- js('javascripts/page1') %>
<% } %>
-<%- js('js/script') %>
"Because lifecycles are separate, updating a submodule inside its container project (NB superproject) requires two commits and two pushes." - Christophe Porteneuve
- Submodule (fork of gulp-starter): Commit and push gulp workflow
- Main repo/Superproject (Hexo): Commit and push (triggers Travis CI) i.a. new referenced SHA1 (created in 1.) of the submodule
"Removing a submodule requires several commands and tweaks, some of which are manual and unassisted." - Christophe Porteneuve
Unregister: Remove submodule from .git/config
together with it's directory, which remains empty.
git submodule deinit path/to/submodule
Clean reference in .gitmodules
and working directory
git rm path/to/submodule
error:
A git directory for 'submodule.<name>' is found locally with remote(s)
-
"(..) submodules these days keep all their Git data in the top project’s
.git
directory, so (..) destroying a submodule directory won’t lose any commits or branches that you had." - Chapter 7.11 of Pro Git book.rm -rf .git/modules/path/to/submodule
-
1: Even if the
HostName
andUser
are identical for different SSH-connections, they can still be distinguished in ~/.ssh/config:"
HostName
specifies the real host name to log into. This can be used to specify nicknames or abbreviations for hosts.""Any identities represented by the authentication agent will be used for authentication unless
IdentitiesOnly
is set." -ssh_config(5)
manual page
This work by m3t (96bd6c8bb869fe632b3650fb7156c797ef8c2a055d31dde634565f3edda485ba) <mlt [at] posteo [dot] de> is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.