What is Git?
Git is an important part of the modern developers toolkit, It’s part of how things get done in 2013. Git is a Distributed Version Code System (DVCS)
The important parts too that are :
a) it’s version control : means you can undo mistakes, changes.
b) it’s distributed : one person can independently work of other people, meaning no one can lock a file from edit’s and then go on lunch or vacation. I can work completely disconnected from the shared repository. Making a commit doesn’t involve connecting to a remote repository; the change is recorded in your local repository
c) bonus points : you can (should) store your repository off your local machine/network in case it goes down (gets stolen, or burns down) and you haven’t lost all your work.
d) there are 3 party repositories (like gitHub, bitBucket ) make it easy to store your repository off site (whether private or public) , and cheap to do so for private repositories; it is also possible to run / host your own repository server ( like http://gitlabhq.com/ ). The good ones add ational value.
So, why do this?
Even when I’m doing sole work, DVCS allows me :
a) to keep a working version;
b) I focus on one feature, fix or story, at a time;
c) I can trash a branch or try something with minimum / no risk
d) And I have an off site backup.
e) If an emergency occurs, I can move back to master (or the customers branch) and branch for the issue, once the issue is fixed ( and merged to master if appropriate) , then is back to my branch. Yes, I lost focus, but it didn’t lose code and/or had to backout code/work.
This all will save your sanity.
If your company doesn’t have version control you/it deserve to fail. And you will. You will lose work, time, and code.
DVCS was an important improvement over the previous generation of centralized version control (Subversion, CVS, etc ). Unlike CVC’s, Git has low barrier of entry, making it easy to start with. (CVS’s were hard, enterprise-y things that where hard to start and use). It was designed by Linus Torvalds based on the needs of the Linux kernel project. CVS’s see change as something to be controlled and minimized; DVCS’s treat change as normal and makes it as easy to work with as possible. It treats the world as it is : distributed, not as (they) wish it to be : centralized and controlled. 🙂
There are other distributed version control systems (like Mercurial), but Git is the best. (or maybe not the best, but it is the most widely used) Learn it; Use it.
There are stand alone graphical tools, but you will learn more and better by using the command line, there are also editor’s and IDE’s with integrated git functionally. but again the cmd line is your friend. (those graphical tools can be useful for visually branch flow, and it can started but…)
Important Git terminology :
the working directory is your file system for the current branch;
the staging area is files you are watching;
the local repo (repository) is what you have committed to locally;
the remote repo is what you are sharing with others, and they are sharing with you;
in your application root directory (okay this is after it been install and configured) :
# creates the initial (hidden) git directory (.git)
add all files from the root down :
$git add .
Note : there are files you will not want to include, like files with passwords or secrets, or .DS_Store files on osx, use a project .gitignore file or a global .gitignore_global file ( https://help.github.com/articles/ignoring-files )
the normal basic workflow is something like :
# double-check what has changed in the working directory and staging area
# add all new (untracked) files to the staging area
$git add .
# or just add a particular file or 2
$git add app/view/users/new.html.erb app/controller/users.rb
#commit those changes, a snapshot of the staging area, with a message
$git commit -m “explanation of the change”
note : try to note the why as well as files
#send your commit changes to your off site repository
$ git push github master
This sends your master branch commits to GitHub
$ git push origin master
$ git push heroku master
A slightly more advanced workflow involves branching
#create a branch (note that a default ‘master’ branch is created when you start)
$git branch BranchName
note : use branch names that relate to the purpose of the branch like “issue-1234” or “add admin feature” or “feature-543-menu-refactor”
#switch to that branch
$git checkout BranchName
After the issue or feature is finished, ie works, is documented, tested and all test are passed, then it time to merge it back to the master branch. the master branch is created by default
$git checkout master
#get all update changes to master from your off site repository
#merge BranchName with master (master being the current branch)
$git merge –no-ff BranchName
note : if there have been changes to the master branch after you last pulled and switched to the other branch you might have conflicts if some else (or even you) change the same file in both the master branch and the fix branch. you need to resolve them
about the –no-ff option : stands for “no fast forward”, means it keeps the branches commit history in the new branch. Kind of wish this was default. ( fast-forward is useful for short-lived branches, and/or you don’t care about the commit history)
Other commands :
#list all branches
#see the last commit on each branch
$git branch -v
#create and immediately switch to a branch
git checkout -b (branchname)
#variations on git commit
if you leave off the -m option git commit with open a text edit (default is vim on u/l-nix systems) for a more detailed multi line comment
#the -a option commits changed files already being tracked in the working directory, it WILL NOT commit untracked (new) files
$git commit -m “Refactor to simplify” -a
#commit a single file (or a list of files) with a message, rather than all changed (tracked) files. This is a sign that you forget to commit some changes before going on to other related changes.
$git commit -m “Refactor to simplify” app/view/user/show.html.erb
#show the history of commits
#filter by string, note no space between the -S and the string
git log -Sstring
# make a copy of a remote git repository, this will create a dir called yourapp below the current directory
$ git clone git://github.com/
At minimum I’m doing lots of :
$git checkout -b feature-23-add-select-country-to-order
…edit and create files…
$git add .
$git commit -m ” feature added to order views/models/test and initial value”
$git checkout master
$git merge –no-ff feature-23-add-select-country-to-order
$git tag -a v1.4.1 -m ‘rolling out version 1.4.1 to cover sprint 234’
# just before the deployment to production
Also it is good to be aware of Git Ignore ( because ” from time to time there are files you don’t want git to track”) and Global Git Ignore in a wonderful thing : here is one, borrowed from GitHub Ignoring files
This is only touching the surface of what you can do with git. More advanced functions include git diff ; git tag; Git Hooks (pre-commit, post-update actions, like a hook to run the rails best practices gem after pushing to GitHub, or place a message to your BaseCamp board ); git blame; git stash (another scratch pad ); git bisect ( http://mojolingo.com/blog/2013/using-git-bisect-to-troubleshoot-ruby-gems/ )
Whatever your work flow, the philosophy of Git is : Commit early, commit often, each commit representing one idea or one change, because it’s easy to revert unwanted changes later. Think of your working directory, stage, and local repo as scratch pads. Start coding.
More resources :
a thoughtful post A successful Git branching model;
DZone : Getting Started with Git
So, am I doing it right, or more to the point, how are you doing it?
Update : Simple Git workflow is simple on the Atlassian blog site has (as described on the tin) a easy to understand Git worklow. I particularly like their use of rebase during feature development, and explicit (non fast-forward) merge when done. Using “rebase” keeps your feature branch fresh and up to date with the latest changes in master. That means you to have clean merges at the end of the feature development. And “explicit merge” will preserve the context of the work and will make it easy to revert the whole feature if needed. Nice!