Git is a decentralized version control system as opposed to a centralized version control system, like TFS, SourceGear Vault, Subversion, Visual Source Safe etc.
A centralized version control system, has a single server that contains all the versioned files, including their history, and a number of clients that check out files form that central place.
A decentralized version control system (such as Git, Mercurial, Bazaar, Darcs etc.), mirrors the respository (including all history) to all clients.
Every time you commit, or save the state of your project in Git, it basically takes a “picture” (also revered to as a snapshot) of what all your files look like at that moment and stores that snapshot. You can think of this snapshot as a copy of all files in your working folder (that are tracked).
Storing data efficiently
Git has several mechanisms to store data efficiently:
- Each file is zlib compressed before it is stored as a blob in the .git folder and refered to by a SHA-1 of its content.
- If a file in a snapshot is not changed, the snapshot will not contain a copy of the file, just a pointer (SHA-1) to the file already in git.
- Once in a while, git will comporess multiple blobs into a single packfile, to increase compression ratio.
By using these mechanisms Git does not have to store deltas at the file level, to be efficient on storage and fast will be extremely fast, when previous snapshots should be restored.
The snapshot will get an identifier associated with it (a SHA-1 of the snapshot content). A SHA-1 is a 40-character checksum string composed of hexadecimal characters (0–9 and a–f) that uniquely indentifies the contents of the snapshot.
Now there are serveral ways you can work with Git. This blog post describes the way, we use Git.
Clone remote respository and commit your first change
The following diagram describes the proces of cloning a remote Git repository and making you first change to it on a locale repository.
Fetch and merge changes from remote to local and push changes from local to remote
The following diagram describes the process of fetching and merging remote changes to a local repository and then pushing local changes back to the remote repository:
We use 3 long lived branches and short lived feature branches on the remote git repository:
- all changes that should go in the product will eventualy be merged into master
- all branches will be created from this branch
- when it is time to deploy the software to the acceptance servers, the code from master is pulled to the acceptance branch and a build of this acceptance branch will be deployed to the accepatance servers.
- when it is time to deploy the software to the production servers, the code from the acceptance branch is pulled to the production branch and a build of this production branch will be deployed to the production servers.
- when a bug is found in production, it is fixed on the production branch, then fetched and merged into the acceptance branch and then fetched and merged from the acceptance branch in to the master branch.
- Feature branches
- All development is done in feature branches.
Now this is not perfect, but you can add branches for QA, test or pre-prod, at will, but maybe you don’t want a branch for each “software life cylce” step and just want to use branches foreach release, thats all up to you.