Skip to content

Instantly share code, notes, and snippets.

@linjunpop
Created October 29, 2012 06:34
Show Gist options
  • Save linjunpop/3971950 to your computer and use it in GitHub Desktop.
Save linjunpop/3971950 to your computer and use it in GitHub Desktop.
Git basic

Git basic

Commit

Pricinple

  • One commit one small feature or bug fix
  • Include unit test in one commit
  • Exclude non-associated files
  • Don't commit un-finished or wrong code
  • Don't commit anything with trailing whitespace

white-space-diff

commit message:

  1. First line for summary
  2. Second line BLANK
  3. The third and following lines should explain in detail what the commit did and why. It should also provide any necessary links to information or reasoning behind the commit / change.

A example:

commit-example https://github.com/rails/rails/commit/10f6f90d9d1bbc9598bffea90752fc6bd76904cd

Why?

Easier to find out which commit makes what changes and the reason behind these changes.

Branch

When to create a branch?

  • Feature
  • Issue
  • Refactor
  • Any experimental changes

Create a branch

$(master) git checkout -b integrate-strong_parameters
Switched to a new branch "integrate-strong_parameters"

equals to

$(master) git branch integrate-strong_parameters
$(master) git checkout integrate-strong_parameters
$(integrate-strong_parameters)

Show all branches

$(master) git branch
  integrate-strong_parameters
* master

Switch between branches

$(integrate-strong_parameters) git checkout master
Switched to branch 'master'

Delete branch

$(master) git branch -d new-feature

Track a remote branch

$ git checkout -b integrate-strong_parameters origin/integrate-strong_parameters
Branch integrate-strong_parameters set up to track remote branch integrate-strong_parameters from origin.
Switched to a new branch 'integrate-strong_parameters'

Merge

After you finish work on a branch

$ git checkout master
$ git merge new-feature

but sometimes, BOOM! Conflict!

$(master) git merge new-feature
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Don't panic.

$(master) git status
# On branch master
# You have unmerged paths.
#
# Unmerged paths:
#	both modified:      README.md
#
no changes added to commit

Open README.md

42                                                                                                                                                    
<<<<<<< HEAD                                                                
hhh                                                                         
=======                                              
answer to life                                                         
>>>>>>> new-feature

<<<, === and >>> to mark where the conflict happens.

The lines between <<< HEAD and === are changes on the HEAD(which points to the current branch, master here).

The lines between === and >>> new-feature are changes on the new-feature branch.

After editing

42                                                              
hhh
answer to life   

Then commit

$ git add README.md
$ git commit

Non fast forword merge

Fast forword

$ git merge new_feature
* b3d9ed7 Jun Lin: Add answer to life -   (new-feature) (10 minutes ago)
* 5bc4897 Jun Lin: initial -   (12 minutes ago)

Non fast forword

$ git merge new_feature --no-ff
[master bb74109] Merge branch 'new-feature'
*   bb74109 Jun Lin: Merge branch 'new-feature' -   (HEAD, master) (14 seconds ago)
|\  
| * b3d9ed7 Jun Lin: Add answer to life -   (new-feature) (10 minutes ago)
* |
|/  
* 5bc4897 Jun Lin: initial -   (12 minutes ago)

Fast forword: Only change the reference.

--no-ff: Non fast forword, generate a merge commit.

Why?

* fdd2859 David Heinemeier Hansson: Forgot to include Mixins::Touch by default -   (8 years ago)
* 7359bcc David Heinemeier Hansson: Added ActiveRecord::Mixins::Touch that will record creation and update times of objects [xal] -   (8 years ago)
* 1cf7eb1 David Heinemeier Hansson: Added ActiveRecord::Mixins::List that can decorates an existing class with methods like move_higher/lower, move_to_top/bottom -   (8 years ago)
* 55be0a3 David Heinemeier Hansson: Renamed from ListMixin and mixins/list_mixin.rb to Mixins::List and mixin/list.rb -   (8 years ago)
* 2d483af David Heinemeier Hansson: Unofficially added ListMixin -   (8 years ago)
* ffd93a8 David Heinemeier Hansson: Fixed to_input_field_tag so it no longer explicitly uses InstanceTag.value if value was specified in the options hash [evl] -   (8 years ago)
* c8d68df David Heinemeier Hansson: Killed the out of place alias and made sure you can use the different HTTP methods within the same testaction -   (8 years ago)
* 4e1eaa2 David Heinemeier Hansson: Only nuke the AbstractApplicationController if its available -   (8 years ago)
* 554597d David Heinemeier Hansson: Added named bind-style variable interpolation #281 [Michael Koziarski] -   (8 years ago)
* 5662c7f David Heinemeier Hansson: git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@77 5ecf4fe2-1ee6-0310-87b1-e25e094e27de -   (8 years ago)
* ac606d8 David Heinemeier Hansson: Updated Builder to 1.2.2 -   (8 years ago)
* a775cb1 David Heinemeier Hansson: Added the option for sanitizing find_by_sql and the offset parts in regular finds [Sam Stephenson] -   (8 years ago)
* 7a29764 David Heinemeier Hansson: Forgot another small change with the new generators -   (8 years ago)
* 5f28a62 David Heinemeier Hansson: Forgot a small change with the new generators -   (8 years ago)

Many commits on master, hard to find out which commits are associated with a feature or bug fix.

*   1743e95 Rafael Mendonça França: Merge pull request #8057 from frodsan/fix_sqlite_mutate_arg -   (HEAD, origin/master, origin/HEAD, master) (3 hours ago)
|\  
| * b5133d0 Stefan Rusterholz: SQLite3Adapter#type_cast should not mutate arguments -   (3 hours ago)
|/  
*   852e376 Rafael Mendonça França: Merge pull request #7750 from xuanxu/none_modificating_relation_in_place -   (5 hours ago)
|\  
| * 300d080 Juanjo Bazán: ActiveRecord::Relation#none! method. -   (6 hours ago)
| * 35ca953 Juanjo Bazán: loaded relations cannot be mutated by extending! -   (6 hours ago)
|/  
*   c6f47c1 Carlos Antonio da Silva: Merge pull request #8053 from henrik/update_columns_with_primary_key -   (7 hours ago)
|\  
| * 1849665 Henrik N: Enable update_column(s) for the primary key attribute. -   (7 hours ago)
|/  
*   5bbe245 Rafael Mendonça França: Merge pull request #8046 from pmahoney/exceptions_as_flow_control -   (7 hours ago)

Clean, One feature finished with one merge commit.

Rebase

Rebase is dangerous, it rewrite history!

When?

master branch has changes and you want to track latest changes from master.

How?

$(new-feature) git rebase master

Only apply to local branch!!

Better not to rebase on a branch that has already been pushed to remote. It will break other people's commits.

But if you really want to include changes on master that occured after you made your branch, tell the others who are also working on this branch to stash their changes, then you can rebase. When you finish $(new-feature) git push --force

Then others should delete their current branch and then checkout from remote again, then apply stashes.

Stashing

Stash your work

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#      modified:   index.html
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#      modified:   lib/simplegit.rb
#

$ git stash
Saved working directory and index state \
  "WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")

$ git status
# On branch master
nothing to commit (working directory clean)

List

$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051... Revert "added file_size"
stash@{2}: WIP on master: 21d80a5... added number to log

Apply stash

$ git stash apply
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#      modified:   index.html
#      modified:   lib/simplegit.rb
#

Drop

$ git stash drop

Remote

Fetch remote changes

Better not to use $ git pull, which equals

$(master) git fetch
$(master) git merge origin/master

Fill commit log with useless commit messages.

Happens especially when many developers are working on same branch.

| * \ \ \   bba5113 programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \  
| * \ \ \ \   41e7002 programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \  
| * \ \ \ \ \   8507289 programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \  
| * \ \ \ \ \ \   a4e8197 programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \  
| * \ \ \ \ \ \ \   b1d1e0d programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \ \  
| * \ \ \ \ \ \ \ \   00c85cf programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \ \ \  
| * \ \ \ \ \ \ \ \ \   f2deec0 programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \ \ \ \  
| * \ \ \ \ \ \ \ \ \ \   fde96ab programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \ \ \ \ \  
| * \ \ \ \ \ \ \ \ \ \ \   49a06da programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \ \ \ \ \ \  
| * \ \ \ \ \ \ \ \ \ \ \ \   0f31a3d programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \ \ \ \ \ \ \  
| * \ \ \ \ \ \ \ \ \ \ \ \ \   7bd3d9c programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)
| |\ \ \ \ \ \ \ \ \ \ \ \ \ \  
| * \ \ \ \ \ \ \ \ \ \ \ \ \ \   68870f7 programmer: Merge branch 'master' of gitolite:mmc -   (3 months ago)

A better way is rebase.

$(master) git pull --rebase

or

$(master) git fetch
$(master) git rebase origin/master

Push branch to remote

$(master) git push origin new-feature

Delete remote branch

$(master) git push origin :new-feature

Git branch model

Long term branches

  • master: always production-ready
  • develop: mainline, developing

branch-model-master-develop

Feature branch

branch-model-develop-feature

git-flow

https://github.com/nvie/gitflow

branch-model-git-flow

Git config

~/.gitconfig file:

Basic config

  • $ git config --global core.editor "mate -w": change default editor
  • $ git config --global color.ui true: color
  • $ git config --global push.default current: Only push current branch

Alias

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

Github

https://github.com

github

99.9% (maybe) of all gems' source code are hosted on Github.

When you write applications, if you find some bug associated with a gem, you can go to http://rubygems.org, find that gem, and there should be a link to http://github.com (ex. https://github.com/rails/rails)

Then scroll down to Contributing if any.

Then follow the instructions.

Then if you do changes, and want to use your own fork.

add github: 'USERNAME/FORK' to Gemfile, then bundle update

an example:

gem 'sassy-buttons', github: 'linjunpop/Sassy-Buttons', branch: 'ie-filter-gradient'

Shell

Bash

$ brew install bash-completion

Add the following lines to your ~/.bash_profile:

if [ -f $(brew --prefix)/etc/bash_completion ]; then
  . $(brew --prefix)/etc/bash_completion
fi

Zsh

Choose a theme: https://github.com/robbyrussell/oh-my-zsh/wiki/Themes

Gui Tools

More...

http://try.github.com/levels/1/challenges/1

References

http://ihower.tw/blog/archives/6696/

https://github.com/rails/rails/commits/master

http://gitready.com/beginner/2009/02/02/push-and-delete-branches.html

http://nvie.com/posts/a-successful-git-branching-model

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment