214 lines
7.6 KiB
Markdown
214 lines
7.6 KiB
Markdown
|
---
|
|||
|
title: Git Ready
|
|||
|
author: geoff-doty
|
|||
|
date: 2012-10-18
|
|||
|
template: article.jade
|
|||
|
---
|
|||
|
|
|||
|
|
|||
|
Primer on Git source-control management
|
|||
|
|
|||
|
## Overview
|
|||
|
|
|||
|
Git is a distributed version control system(DVAC) offering a few killer features that sway more developers towards git than any other version control system, for svn these killer features include:
|
|||
|
- speed
|
|||
|
- local commits
|
|||
|
- branching
|
|||
|
- merging
|
|||
|
|
|||
|
SPEED: Everything in git is local, commits, logs, ignores, settings are all stored locally with in a single `.git` file. This greatly increase the speed at reading logs and reviewing commits.
|
|||
|
|
|||
|
LOCAL COMMITS: The ability to commit, branch and stash locally allows the developer to commit without affecting other developers or the main codebase until s/he is ready to do so. This also leads to more commits providing a greater identification of the scope of work being done.
|
|||
|
|
|||
|
BRANCHING: Branches are fast, light-weight as they are only registered as diffs from the branch your diverging. All history is local, and they can be deleted with confidence.
|
|||
|
|
|||
|
MERGING: Merges are often looked at line-by-line, not file-by-file, so operations tend to be more like: _delete_line X_, and _add_line_X_ operations. This leads to fewer conflicts. Also if no changes have be made locally, git simply fast-forwards the codebase where merging is not required (FAST!).
|
|||
|
|
|||
|
> Everything mentioned in this document is how **git** behaves by default. Reading through the document you may ask yourself, _"but can I do X?"_ and the answer is _almost always_ -- _"YES, there is option for that!"_
|
|||
|
|
|||
|
|
|||
|
## 1. Setup
|
|||
|
|
|||
|
_setup operations here are one-time set-and-forget_
|
|||
|
|
|||
|
Introduce yourself to git
|
|||
|
|
|||
|
git config --global user.name "Your Name"
|
|||
|
git config -- global user.email "my.email@assist-rx.com"
|
|||
|
|
|||
|
**Line Ending Woes (`auto` | `false`)**
|
|||
|
|
|||
|
_Different operating system use different line endings. Text editors can negotiate differences seamlessly, as can your version control system -- if you tell it to!_
|
|||
|
|
|||
|
In mixed environments, `false` maybe the better option, `auto`, however is a safe default`.
|
|||
|
|
|||
|
git config --global core.autocrlf false
|
|||
|
|
|||
|
There are other settings you may be interested in such as
|
|||
|
|
|||
|
git config --global apply.whitespace nowarn
|
|||
|
|
|||
|
to ignore whitespace changes.
|
|||
|
|
|||
|
### Handful of Commands
|
|||
|
|
|||
|
A few git commands your going to be seeing a lot of.
|
|||
|
|
|||
|
Command | Description
|
|||
|
|:---:|---|
|
|||
|
pull | pull commits and merges from a central/shared repo
|
|||
|
push | push commits to central/shared repo
|
|||
|
commit | commit changes locally
|
|||
|
stash | stash code for use later
|
|||
|
rebase | set [branch] as the foundation your changes are applied on top of
|
|||
|
merge | merge [branch] into the active branch
|
|||
|
|
|||
|
|
|||
|
### Remotes
|
|||
|
|
|||
|
_Spring Loops has a ssh key management system, you need to add your public key(if you have one) to the repo you want access to first_
|
|||
|
|
|||
|
git remote add [name] ssh://[user]@[server]/[path]/project.git
|
|||
|
|
|||
|
> _Common practice is to name your remote 'origin'_
|
|||
|
|
|||
|
The first time you `push`/`pull` changes to a remote (if there is only one), you need to identify where your `push`/`pull` should go via
|
|||
|
|
|||
|
git pull origin master
|
|||
|
|
|||
|
after that you can just call
|
|||
|
|
|||
|
git pull
|
|||
|
|
|||
|
### Clone
|
|||
|
|
|||
|
If a git or svn repo already exists you can `clone` it which will add a remote automatically for the clone address.
|
|||
|
|
|||
|
to clone a SVN repo into git use
|
|||
|
|
|||
|
git svn clone <username>@<server>:/<svn>/<path>/
|
|||
|
|
|||
|
_So you have code, now what?_
|
|||
|
|
|||
|
## 2. Git Workflow Loop
|
|||
|
|
|||
|
If you just cloned your repo, you can start coding, however normally you want to `pull` the latest code before you start coding.
|
|||
|
|
|||
|
git pull
|
|||
|
|
|||
|
Again, if you have not previously ran `pull`, you can pass the _[repo]_ and _[branch]_. __Git will let you know!__ As an example:
|
|||
|
|
|||
|
git pull origin master
|
|||
|
|
|||
|
Develop like only you know how! _Netbeans_, _SublimeText_, _TextMate_ -- doesn't matter. Code as you would.
|
|||
|
|
|||
|
> __NOTE__
|
|||
|
>> I find it best to do all code in a `branch`. As it always seems to happen if you get pulled into another project mid-step you can do so without affecting the code that you currently written. You can also `stash` your code.
|
|||
|
ee Section 3 below for more information._
|
|||
|
|
|||
|
When your ready to `commit` your changes, initially you'll find it similar to 'SVN'.
|
|||
|
|
|||
|
1. Choose the files you want to commit
|
|||
|
2. write a `commit` message and
|
|||
|
3. call `commit`
|
|||
|
|
|||
|
There are a few command-line options you can pass to make this easier.
|
|||
|
|
|||
|
git commit -m "[My Commit Message]"
|
|||
|
|
|||
|
`-m` stands for message, and this will commit all modified files, however it will not commit new files, to do that you can pass `-a`, like this:
|
|||
|
|
|||
|
git commit -am "[My Commit Message]"
|
|||
|
|
|||
|
Usually you will code . . . commit . . . code . . . commit, as git lends itself better as a source control system than source backup system, however those commits are local, to share your changes you need(for central setup) to `push` them up to a `master` or central repository.
|
|||
|
|
|||
|
> __BEFORE__ `push`, '`pull` the latest code!
|
|||
|
|
|||
|
git pull
|
|||
|
git push
|
|||
|
|
|||
|
Rinse and repeat!
|
|||
|
|
|||
|
|
|||
|
## 3. Stash, Branch, Tag, and Merge
|
|||
|
|
|||
|
### Stash
|
|||
|
|
|||
|
Git expects a clean working directory for most operations (`pull`, `push`, `rebase`), but what happens if you have files your working on, and you are not ready to commit those, but you need to `pull`, `merge`, or `rebase` your code?
|
|||
|
|
|||
|
You `stash` them!
|
|||
|
|
|||
|
git stash
|
|||
|
|
|||
|
Calling the above stashes your changes and brings you to a clean state to call other commands. such as `pull`.
|
|||
|
|
|||
|
> _New files are ignored by git until you `add` them_
|
|||
|
|
|||
|
When you want your stashed changes back, call
|
|||
|
|
|||
|
git stash pop
|
|||
|
|
|||
|
This will apply your stash on top of your current code and delete the saved stash (if successful)
|
|||
|
|
|||
|
> _Stashes are local only_
|
|||
|
|
|||
|
### Tags
|
|||
|
|
|||
|
Tag specific points in history as being important. Generally, people use this functionality to mark release points (v1.0, and so on) or otherwise known stable points in the history.
|
|||
|
|
|||
|
git tag [tag_name]
|
|||
|
|
|||
|
> Tag names cannot contain spaces, but you can use `.`, `-` or `_`.
|
|||
|
|
|||
|
### Branches
|
|||
|
Git branches are light weight code deviations (stored as _diffs_), that allow you to quickly jump and build features or try experiments without affecting your main code branch; called `master` in *git* or `trunk` in *svn*.
|
|||
|
|
|||
|
Calling `git branch` by itself will list all the branches that exist with an asterisk(*) next to the branch your currently working in.
|
|||
|
|
|||
|
To create a new branch you simply call
|
|||
|
|
|||
|
git branch [name_of_branch]
|
|||
|
|
|||
|
Then checkout your newly created `branch` via
|
|||
|
|
|||
|
git checkout [name_of_branch]
|
|||
|
|
|||
|
Or you can create a `branch` and `checkout` in one line via
|
|||
|
|
|||
|
git checkout -b [name_of_branch]
|
|||
|
|
|||
|
> REMEMBER: branches are created from the active branch
|
|||
|
|
|||
|
Now that you've built this awesome feature in a _branch_, how do you get it back into the main project, lets say `master` for example?
|
|||
|
|
|||
|
That's where merging comes in...
|
|||
|
|
|||
|
### Merging
|
|||
|
|
|||
|
First we need to be on the `branch` that we want to `merge` changes into:
|
|||
|
|
|||
|
git checkout master
|
|||
|
|
|||
|
then `merge` in the changes we want with
|
|||
|
|
|||
|
git merge [name_of_branch]
|
|||
|
|
|||
|
If there were no conflicts, you can now remove the branch and keep you workspace clean with
|
|||
|
|
|||
|
git branch -d [name_of_branch]
|
|||
|
|
|||
|
The branch will be deleted **ONLY IF** the branch changes have been merged successfully. git is smart enough to only delete changes you have used, but should you want to throw away a branch use the `-D` option instead of the `-d` option to force delete the branch.
|
|||
|
|
|||
|
### Squash Merge (advanced)
|
|||
|
|
|||
|
Sometimes it is advantageous to squash a series of commits in a branch when merging into another branch (such as master) to accurately convey a group of commits belong to a single feature or bug fix.
|
|||
|
|
|||
|
git checkout master
|
|||
|
git merge --squash [name_of_branch]
|
|||
|
git commit
|
|||
|
|
|||
|
## Resources
|
|||
|
|
|||
|
- [Git Homepage](http://git-scm.com/)
|
|||
|
- [Git Branches](http://gitref.org/branching/#branch)
|