Posted on

Good git Behavior for the CSA Code Team

Man Branches Banner

I am in the midst of training and evaluating people that are interested in working on the Store Locator Plus code projects.   Some people are veteran coders.  Others are learning coding in a team environment for the first time.    Here are some basic guidelines on using git when working on the CSA codebase that can be useful if you are using git version control for any team project.

Use Descriptive Commit Messages

Your commits messages should be descriptive at least 99% of the time.   These are not good commit messages:

Inline image 1
When the team or project lead goes to integrate your code with the work everyone else has contributed they should have some clue what each commit was doing.     A single word is NEVER a good commit message.   At the very least you should almost always be using a noun and a verb in a commit message.   Debug actions would be at least a little better than “debug”.   Better yet, us a short sentence.

Create Separate Debugging Branches

Since we are on the topic of debug commits, they should rarely be in  your “mainline” branch of code.  Yes debugging happens.    Yes, they often end up in a series of commits on a code branch especially when working on a complex piece of code.  However if you start out with a cycle of coding where you know “I’m going to do a lot of debugging to figure out what is going on here” then it is almost always a good idea to start by creating a new “debug_this_whacky_thing” branch and dumping all your “code barf” in there until you figure things out.
When you do, go back to the “real_work” branch and check that out and put the valuable pieces of code from your learned lessons in that branch.
If you manage to stumble across a useful piece of code on your “testing_stuff” branch you can always add it on to your “real_work” branch with something called “cherry picking”.    That is a git command and in SmartGit is simple to execute.  Checkout the real_work branch, then go select the one or two commits that did something useful from the debugging_code_barf branch and “cherry pick” them.

Commit Often

Small frequent commits are better with just about any version control system and ESPECIALLY when using git.   It tends to create fewer code conflicts during a merge.     This does not mean committing every single line of code on a per-commit basis.   However you should commit every time you write code that changed something and are at a “stopping point”.    Typically this is at the point of “ok I am going to test this now and see if it does what I expected”.    Often it is best to do a “dry run” and make sure there are no blatant errors such as syntax errors before committing.     Try to commit unbroken, if not functional, code.    In other words it should not crash whatever you are working on with an immediate and obvious “your forgot a curly bracket” error.

Use Branches

Like the debugging branch noted above, any time you start a new concept, path,  model, design, or feature start a new branch.   Try to work from a root point, such as the last major release of a product or the last tested-to-be-working version of the software.    Unless your new concept requires the code of a prior effort going back to the root “last working base copy we published” is a good starting point.    The project or team lead will merge code into a prerelease or production (master) branch or an integration branch to create a new product release version.
If you have done work on several feature branches that are not dependent on each other but work better together, create your own integration branch.   “my_super_pack” branch can be a merge-commit of your “feature_a”, “super_awesome_feature”, and “feature_b” branches.

CSA Branch Standards

At CSA I like to use a 3-branch methodology for managing projects.    The branches are master, prerelease, and integration. All 3 branches are only aligned when a new production version is released and there is no ongoing development on the project.
master – always points to the latest production release available to the general public.   This is where the current commit pointer ends up after integration and prerelease phases are complete and the production scripts are executed.  This branch is always tagged with the current production release number.  Developers only start new branches here if a prerelease branch does not exist.
git master branch
prerelease – always points to the latest release of the software that was published to the public in prerelease format.  Prerelease software is not fully tested, though usually has passed the rudimentary functional testing.  this is considered the “beta” version of the next master release.  All CSA Premier Members and beta test groups are given access to prerelease software.    This branch is always tagged with the current software version number, which is bumped if further changes are needed before “going to production”.   Developers almost always start new branches here.
git prerelease branch
integration – this branch points to the current integration branch used by the project manager to pull together developer commits in preparation for conflict resolution and rudimentary software testing prior to being given an official “prerelease” stamp.  This is the release used for internal testing and development and should be considered unstable.    Developers rarely start new code branches on this branch.
git integration branch

 

Posted on

Bitbucket Major Outtage

Bitbucket Outage Banner

Bitbucket, an online code management and issue tracking system, used for the Store Locator Plus projects, is currently offline due to what is classified as a “Major Outage”.   Development and patches for the Store Locator Plus products is limited as I wait for the service to come back online.    While development can continue, the longer the service is out the higher the risk of losing local code edits should the development system encounter problems.   The remote code management system not only provides controlled and documented software change control but also serves as a type of “immediate off-site backup” should anything go wrong.   While I do run routine backups of all systems here at CSA, those backups are not very granular, meaning I may have a snapshot from 4 hours ago but not from 4 minutes ago.   4 hours can be a LOT of lines of code written.

Site content, documentation, and non-code related projects will be underway as I await the return of the Bitbucket service.     With two major outages in a month it may warrant considering a change of service providers which is time consuming and disruptive.    Github, while somewhat more stable is not without its problems and gets costly in a hurry for larger projects like Store Locator Plus.   Repository Hosting gets decent reviews.  May be time to investigate, but I am not looking forward to moving hundreds of logged issues and enhancements.

This is one of the downsides to using third party services.  If you are not fully self-sufficient, and few online service are these days, you are vulnerable to the whims and follies of your vendors.  Sadly many online vendors these days have limited, if any, transparency into their operations.

That is one of the advantages to buy-and-own-it open source projects like Store Locator Plus.    If I go away you still have fully functional code that is readily accessible to your and your development team which limits your potential down time and exposure.    As the Store Locator Plus community builds more developers are getting involved which bolsters the potential longevity of the plugin.   While some people are apprehensive about open source projects I find it is typically from businesses that write applications and are looking to protect their profitability.   For the consumer I have yet to hear a compelling argument as to why well-written open source software is a detriment.

Posted on

SmartGit Tips & Tricks

I have been using SmartGit (http://www.syntevo.com/smartgit/index.html) for nearly a year now.   After having used command-line git and the graphical log viewer, gitk, I have become very accustomed to using SmartGit for managing my code repositories.   After a short learning curve I have become fairly proficient in managing my branches and general code repository issues.

Here are some tips & tricks I’ve learned along the way.  Granted, not many listed here yet, but hopefully other SmartGit users out there will share.

Tagging Code

Tags are very useful for marking key positions in the repository without creating a branch.   We use this at Cyber Sprocket to tag the commit that represents a specific product release.    SmartGit makes this easy, but you will need to create a private key.   Look for our articles on creating OpenSSH keys using PuttyGen to create your key file.

Once you have your key file you can attach it to a project when you set the project up.  SmartGit will store that key for future use, making for easy tagging of your repository.

At this point tagging the repository is easy:

  • Open the log viewer.
  • Right-click on a commit and select “Add Tag”.
  • To publish the tag back to the origin server go to the working tree/project window and select “remote / push advanced” and select the “push selected branches or tags”.  That is where you can select the new tag and push it back to origin.

Finding A Commit By ID

Even though SmartGit is very good at managing branches and encouraging plain text labels for branches and tags, there are times when the only way you can find a specific commit is via the SHA-1 commit ID.    For months I’d been using the command line to locate those commits and manage them, often just to add a tag or a branch so I could find that key commit at a later date.

Turns out SmartGit has an easy, if somewhat hidden, way to find a commit.

  • Bring up the log window.
  • Start typing in the SHA-1 key -or- press ctrl-v to paste in a hash you’ve copied

SmartGit will locate the first matching commit ID doing the typical fast search/filter as you continue typing.

 

Those are my two tips & tricks for today.  If you have any, please share.

Posted on

Working With Git

Here are some basic cheat-sheet style hints for working with the git version control system.

Creating A Repository

These are the steps for starting a new repository with git.  The commands here assume you will be working with a group of people that all need access to the repository from your server.  You will need command line access to the Linux shell to do this.

In our example we assume our developers all belong to the user group “dev” on the Linux box and our storage of the git repositories is in the /devdir/gitrepos directory.

  1. Log in as a user who belongs to the dev group.
  2. Make your way over to /devdir/gitrepos.
  3. Create the directory for your project. Make sure it ends with .git, e.g. wego.git.
  4. Go inside the directory you just made.
  5. Enter git --bare init --shared=group
  6. Finally do a chmod a+x hooks/post-update.

That last step is required because without it you would always have to run git update-server-info in the remote repository after every push. Git comes with a hook that automatically handles that for when you are pushing over SSH or HTTP, or really anything except Git’s own protocol.

Also the part about ending the repo name with .git is not mandatory—simply convention. People tend to suffix that whenever the repository is “bare”, meaning it has no working copy associated with it.

Adding Content To Your Newly Created Repository

Now that you have new, and empty, git repository you are ready to begin work in your development directory.  Here we are assuming you are working on your development server.  This may not be, and often is not, the same server where you store your git repositories.

  1. Login to your development server.
  2. Go to the directory where you want to start working on your new wego project.
  3. Enter git init
  4. Enter git remote add origin ssh://yourname@yourdomain.com/devdir/gitrepos/wego.git/.
    • Obviously substitute your login and repository name above.
  5. Load up something to put in the repo…
    1. touch README
    2. git add README
    3. git commit README
  6. git push origin master

If you clone an existing repo Git will set remote to the http (e.g. http://yourhost.yourdomain.com/wego.git/) address, which you cannot push back to because the server won’t allow it for security reasons—otherwise any one in the world could update our repos. So do this right after you clone the repo:

  • git config remote.origin.url ssh://yourname@yourdomain.com/home/gitrepos/wego.git/

Then git push origin master will do the right thing.

For bonus points you can open the .git/config file inside your local repo (or create it) and add this:

[branch "master"]
[remote "origin"]
        url = ssh://yourname@yourdmain.com/devdir/gitrepos/wego.git/
        fetch = +refs/heads/*:refs/remotes/origin/*

This tells Git that your master branch should track the origin branch. So now you can just type git push and git pull to upload and download commits.

Cloning That Repository Somewhere Else

Now that you’ve got stuff in your git repository other people are going to want to use it.   They can copy (clone) the repository by logging into their development server and using the git clone command:

# git clone ssh://theirname@yourdomain.com/devdir/gitrepos/wego.git/ ./wego

This assumes that theirname@yourdomain.com is a user in your development group on the server where the original repository lives.

On A New Development Server?  Setup Your Environment

This is what you’ll want to do if you are working on your own development server.  It will save you some typing when you add stuff to the repository when working in a shared development environment.

  1. git config --global user.name your name
  2. git config --global user.email your email
  3. git config --global core.autocrlf true
  4. git config --global core.safecrlf warn

On A Shared Server? Setting Author Per Commit

# git commit --author='user <user@email.com>'

Ignore That File

You can tell Git to ignore various files in your directory structure by adding a file .gitignore into the parent directory.  Inside that file you can specify a file name, or a group of files via a wild-card match.   This gets checked against each file regardless of the directory to which it belongs, in essence it is a recursive match.

Ignore the .htaccess file and anything ending with .backup as an extension
 # vi .gitignore
 .htaccess
 *.backup

Show Me The Branches

Get a visual look at the branches from a command line / ASCII terminal.

# git log --graph --oneline --decorate --all

Rename A Git Branch

You named your branch “temp/this-will-never-work” then realized what you did in there actually DID work.  Here is how you rename it locally and back on the remote box.

 # git checkout $branch
 # git branch -m minor/nystore
 # git push origin HEAD

This will add a NEW branch on the remote box, the old branch will still remain, so you’ll need to do some cleanup:

Local cleanup of remote references:

 # git branch -r -d origin/branch-to-delete

For git version 1.6.6.1 or higher:

 # git push origin --delete branch-to-delete

For older git version, you should upgrade, but this trick may help:

 # git push origin :branch-to-delete

Oops, Didn’t Mean That, Redo

To redo a commit you just pushed…

Delete the remote branch (you don’t always want to do this, be careful here) using the method described above in “Renaming A Git Branch”.

Go back to the last group of edits before you made your commit:

  # git reset --soft HEAD^

The HEAD^ says “go back from where I am now (HEAD) by one level”.   The –soft tells git to “keep all my edits please”, as opposed to –hard, which throws away all of your work.

Cherry Picking

Cherry picking allows you to build a new branch based on select commits from other branches.  Here is an example:

# Add the files from this commit to your current branch, but don't commit them yet
# This just puts the updated files in your directory
#
git cherry-pick --no-commit e85cd343234521c392950a208d677843c92a0392
# Change the author on those new files & add them with a commit
#
git commit -a --author='Lance C <Lance-isnt-here@cybersprocket.com>'
# Go get another one...
#
git cherry-pick -n 15a5454403f4fd75f469d6410d6de06ab008027d
# Now commit the new stuff, using the commit message that was
# in the commit ID specified here
#
git commit -c 15a5454403f4fd75f469d6410d6de06ab008027d
# Go and delete the driver/cafepress branch on the origin repo
#
git push origin --delete driver/cafepress
# Rename our driver/temp-cafepress branch to driver/cafepress
#
git branch -m driver/temp-cafepress driver/cafepress
# Go push our stuff back to origin
#
git push origin HEAD

Tagging Your Work

Tags are useful for marking your commits with short phrases, release numbers, or other pieces of info that will help you identify important commits.  Here are some short tips on how to tag your work.

First, you’ll need a PGP key.   Login to your linux box and stay in your home directory.  Run this command:

gpg --gen-key

Look for the key ID in the first few lines of output.  It should look something like this:

gpg: /home/lcleveland/.gnupg/trustdb.gpg: trustdb created
gpg: key D7809C04 marked as ultimately trusted
public and secret key created and signed.

gpg: /home/lcleveland/.gnupg/trustdb.gpg: trustdb createdgpg: key D6808C94 marked as ultimately trustedpublic and secret key created and signed.

This 8-digit number is your signing key.  Now use that to set your git configuration for your user so that your tags can be automatically signed:

git config --global user.signingkey $KEY_ID

Now to tag commits:

git tag -s v1.0
git push --tags origin master