Those who read my last post should know — I tend to work alone. I keep good company — the company of one.

But I'm really not so different. For instance, what good is what I learn unless I right it into the future by writing it down? And writing it on this blog benefits you too!

That'll be $5.99 US.No worries!

Beginning with git clone

Everyone that explains git begins with git init. Starting with nothing is awesome, but I'm not trying to teach you am I!  I'm just telling my story, and if you benefit, that'll be $5.99US, please.

Web developers from the future know all about EnyoJS. For the rest of us web coders, it's time to learn that after you get git, you should go get bootplate and start developing like it's nobody's business.

WAIT!!!

Don't get bootplate the way they say you should. That would be boring and maybe even frustrating. Hey don't be dupliforking either. That's just dirty. This is better:


git clone --mirror https://github.com/enyojs/bootplate.git enyojs/bootplate.git

git clone --mirror %URL% %FOLDER%

Now, I look into the folder I just created (enyojs/bootplate.git) and I don't see bootplate, or anything but git's internal structure of the bootplate repo. Next I ran this command:


git clone enyojs/bootplate.git working/bootplate
Whamo!

Hmm, only one problem! Submodule links are broken! Actually, no problem at all. Because of relative urls, I just need to pull all the bare repos (using the mirror option). Time to write some scripts.

/scripts-dir/clone.sh


export ServerMirror="$1"
shift
while [ "$1" != "" ]; do
git clone --mirror $ServerMirror$1 $1
shift
done

/scripts-dir/reflect.sh


while [ "$1" != "" ]; do
pushd $1
git remote update
git --bare update-server-info
popd
shift
done

Hey scripting! That's a great idea! Delete everything and start over. That's what the best ideas require sometimes. Oh wait don't delete the great idea. Actually (= I'm flat wrong), ideas don't require anything. Neat, repeatable, and predictable machine function — these require full deletion, and some day frequently God may require the same. After all, cleanliness is next to godliness.

Time to use the script, and why not just put it in another script.

/scripts-dir/new-server.sh


clone.sh https://github.com/ enyojs/bootplate.git
clone.sh https://github.com/ enyojs/canvas.git enyojs/enyo.git enyojs/layout.git enyojs/onyx.git

Then to pull down updates, I need another script like so:

/scripts-dir/refresh-server.sh


reflect.sh enyojs/bootplate.git
reflect.sh enyojs/canvas.git enyojs/enyo.git enyojs/layout.git enyojs/onyx.git

Awesomeness.

Now I can follow a standard method for cloning bootplate locally. This is the pattern:

Public repos, bare, stored on server
<—mirror—>
Private backup repos, bare, stored on USB or local server
<—push fetch—>
Private working repos, working, stored on disk

And now I've got it!  Here's a normalized plan/log of my steps

  1. Choose a location for my private repositories.
    
    mkdir /my-repos-dir/pvtrs
    
  2. Copy and run my scripts at this new location. This clones the public repositories privately.
    
    cp /scripts-dir/* /my-repos-dir
    cd /my-repos-dir
    new-server.sh
    
  3. Make my own private repositories; a library and a template.
    
    cd pvtrs
    git init --bare jade.git
    git init --bare template.git
    
  4. Make a working directory, and clone my private repositories.
    
    cd /my-working-dir
    git clone /my-repos-dir/pvtrs/template.git
    git clone /my-repos-dir/pvtrs/jade.git
    
  5. After adding files to my jade library, commit and push.
    
    cd jade
    git status
    git commit -a -m "First commit of my new library!"
    git status
    git push
    
  6. Setup my template with a remote to my local copy of bootplate.
    
    cd ../template
    git remote add bootplate /my-repos-dir/enyojs/bootplate.git
    git fetch bootplate
    git merge bootplate/master
    
  7. Branch from a known tag, add submodules, and add links in the code to the new modules. Commit and push the template branch.
    
    git tag
    git branch 2.2-template 2.2.0
    git checkout 2.2-template
    git submodule init
    git submodule update
    git submodule add ../../enyojs/canvas.git lib/canvas
    git submodule add ../../pvtrs/jade.git lib/jade
    
    Use relative URLs :-)
    
    cat .gitmodules
    vi deploy.json
    
    Add libraries to deploy.json build script
    
    git diff
    git status
    git add .
    git status
    git commit
    
    
    git status
    git push
    
  8. Occasionally, I will move to new template branches (after pulling new bootplate tags from the server).
    
    git remote -v
    git fetch bootplate
    git branch
    git checkout 2.2-template
    git checkout -b 2.3-template
    git merge 2.3.0-rc.16
    
    
    git status
    git submodule update
    
    
    edit my-conflicting-files-and-associated-code
    git add
    git commit
    
    
    git branch
    git branch -d 2.2-template
    
    
    git branch -D 2.2-template
    
    
    git branch -r
    git push origin :2.2-template
    
  9. Make a repository for a new and exciting project, merge my template, and update submodules!
    
    cd ..
    git init --bare /my-repos-dir/pvtrs/great-idea.git
    git clone /my-repos-dir/pvtrs/great-idea.git
    cd great-idea
    git remote add template /my-repos-dir/pvtrs/template.git
    git remote -v
    git fetch template
    git merge template/2.3-template
    git submodule init
    git submodule update
    git status
    

    Curiously, status doesn't mention the need to push the merge.  (Hypothesis) This anomaly appears when the origin is empty.

    
    git push
    
  10. As I push fixes to my template, I can merge them with my working project using fetch and merge
    
    git fetch template
    git merge template/2.2-template
    
  11. I can remove or add my template remote:
    
    git remote rm template
    git remote add template /my-repos-dir/pvtrs/template.git
    
  12. I can change location of a remote  (/my-repos-dir/*)
    
    git remote set-url template /my-new-repos-dir/template
    git fetch
    
  13. Periodically, I will update my mirrors from the server
    
    cd /my-repos-dir
    refresh-server.sh
    
  14. After refreshing my mirror, I'll want to fetch remotes from the server, and merge as needed.

Now by this pattern, I can push and fetch to my heart's content, maintain proper backups, carefully choose my merges on my own schedule, and maintain my own templates all on my local host. My only connection to the server is a set of mirrored bare repositories.  With that, I can leave the complexities of a remote server relationship for another day.