Feng erdong's Blog

Life is beautiful

Git Visual Reference Notes

| Comments

This notes is written after reading A Visual Git Reference

basic usage

  • git add copy file from working directory to INDEX/stage

  • git commit save a snapshot of files in INDEX/stage to repo

    • git commit -a
      (first git add all filenames that existed in the latest commit, and then running git commit) when we only modified some file after last commit, then we can directly use git commit -a to skip the git add step.
  • git checkout copy from commit history(local repo) to INDEX and working directory

    • git checkout HEAD files
      copies files from the latest commit to both the stage and the working directory.
    • git checkout local_branch
      if files are not passed, then copy all files from that commit point to both INDEX and working directory, and remove files not in that commit.
    • git checkout tag/remote_branch/commit-hash/relative-commit files
      copy files from specified commit to INDEX and working directory, if commit-hash is not passed, then copy files from INDEX to working directory.
    • git checkout tag/remote_branch/commit-hash/relative-commit IF
      1. files are not passed
      2. not checkout from a local branch
        THEN an anonymous branch is created call detached HEAD, afterward commit will be base on detached HEAD, if switch to another branch, all commit in detached HEAD will be lost, if commits want be stored, it’s better to use ‘git checkout -b new_branch_name’ to create a branch rather than use the anonymous branch.
  • git reset Move current branch to another position, and update INDEX

    • git reset commit-hash move current branch(HEAD) to specified position, and update stage to match the commit-hash. if –hard is given, also update working directory. if –soft is given, neither is updated.
    • git reset no commit-hash given, default to HEAD, move to HEAD, means, branch is not moved, but stage is updated with last commit.
    • git reset [commit-hash] files move to specified commit-hash and update files in INDEX to match that commit. If commit-hash it not given, it defaults to HEAD.
  • git merge

    • git merge from_branch if other commit is ancestor of current commit, do nothing. if current commit is ancestor of other commit, results in a fast-forward merge. if current commit and other commit are not on the same line, then a real merge occur, git find out the common ancestor of the two commits, do merge with the three part, saving the result to both index and working directory, if no conflict, then do a new commit.
  • git cherry-pick

    • git cherry-pick commit-on-other-branch copy a commit, creating a new commit on the current branch with the same message and patch as another commit.
  • git rebase replay commits of another branch onto the current branch, it just like a series of git cherry-pick call

    • git rebase from_branch git merge will generate a new commit with two parents, but after git rebase, the last new commit only have one parent, and all old commits will be deleted.

jQuery事件处理杂记

| Comments

  • .on()中判断事件源
    jQuery的事件处理函数中默认存在event这个对象, 在使用on 这种事件委托机制时,有时候我们想监听的特定元素的事件在收到之前就已经被其他外层的元素捕获到了,这个时候可以通过event.target.nodeName来拿到真正的事件源的结点名。注意,结点名是大写的.
a simple demo may be not that reasonable
1
2
3
4
5
6
7
8
9
10
11
12
$("#resultTable")
//show edit form when click on tr
.on("click", "tr", showUpdateEventForm)
//enable/disable toolbar button when click inner checkbox of tr
.on("click", "tr", function(event){
        var isCheckboxClicked = event.target.nodeName == 'INPUT';
        if (!isCheckboxClicked) {
            var $checkbox = $(this).find(':checkbox');
            $checkbox.attr('checked', !$checkbox.attr('checked'));
        }
        $toolbarButtons.refresh();
    })
  • 建议在.on()的事件处理函数中显式接受event对象
    在chrome中,我们可以直接在on()指定的事件处理函数中使用event对象而不用显式传递这个event,但是在Firefox下必须显式传递这个event对象.

  • 使用事件委托避免inline事件注册
    当使用requireJS, text来异步加载html片段到页面时,这个时间整个页面已经加载完毕,因为无法再给这段html片段中的元素添加事件监听,如果想在这段html片段中使用inline javascript来注册事件的话,又需要使用全局的javascript对象,这违背了使用requireJS来管理javascript的初衷。
    一种比较好的解决办法是,在这段html片段的父元素上使用事件委托机制来监听他的子元素上发生的事件,这样即使这段html片段是后来加入到页面的,也完全可以在$()中完成事件注册.

jQuery高级API

| Comments

jQuery.proxy(function, context) Returns: Function

Takes a function and returns a new one that will always have a particular context.  

function The function whose context will be changed.
context The object to which the context (this) of the function should be set.

using of $.proxy() in bootstrapSource
1
2
3
4
5
6
7
8
9
10
11
12
listen: function () {
      this.$element
        .on('blur',     $.proxy(this.blur, this))
        .on('keypress', $.proxy(this.keypress, this))
        .on('keyup',    $.proxy(this.keyup, this))
      if ($.browser.webkit || $.browser.msie) {
        this.$element.on('keydown', $.proxy(this.keypress, this))
      }
      this.$menu
        .on('click', $.proxy(this.click, this))
        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
    }

.map(callback(index, domElement)) Returns: jQuery

Pass each element in the current matched set through a function, producing a new jQuery object containing the return values.  

callback(index, domElement) A function object that will be invoked for each element in the current set.

As the return value is a jQuery-wrapped array, it’s very common to get() the returned object to work with a basic array.

using of map() in bootstrapSource
1
2
3
4
5
6
7
8
9
10
11
render: function (items) {
          var that = this
            items = $(items).map(function (i, item) {
                i = $(that.options.item).attr('data-value', item)
                i.find('a').html(that.highlighter(item))
                return i[0]
              })
            items.first().addClass('active')
            this.$menu.html(items)
            return this
      }

map()功能上跟each()是类似的,不同之处是each()对elements进行操作完之后返回操作前的elements,而map()返回操作结果的一个集合.

a simpler demo on map()
1
2
3
4
5
6
7
8
var arr = ['steven', 'nicky', 'jerry', 'will'];
console.log(arr);
>>>['steven', 'nicky', 'jerry', 'will']
var arr = $(arr).map(function(index, ele){
    return ele + 1;
    }).get();
console.log(arr);
>>>["steven1", "nicky1", "jerry1", "will1"]

jQuery.data( element, key, value ) Returns: Object

Store arbitrary data associated with the specified element. Returns the value that was set.

element The DOM element to associate with the data.
key A string naming the piece of data to set.
value The new data value.

Note: This is a low-level method; a more convenient .data() is also available.

The jQuery.data() method allows us to attach data of any type to DOM elements in a way that is safe from circular references and therefore free from memory leaks. jQuery ensures that the data is removed when DOM elements are removed via jQuery methods, and when the user leaves the page. We can set several distinct values for a single element and retrieve them later:

data()很容易与 data-name属性(html5属性)混为一谈。他们之间的关系是,如果html里面存在属性data-name, 那么可以通过 data('name')拿到这个值,仅此而已,使用data('name2', value)并不会添加一个 data-name2属性到html元素上,data('name', value)也不会去更新data-name属性的值。通过 data(key,value)绑定到元素的值不会显示为元素的属性.


jQuery.extend( target [, object1] [, objectN] ) Returns: Object

Merge the contents of two or more objects together into the first object.

target An object that will receive the new properties if additional objects are passed in or that will extend the jQuery namespace if it is the sole argument.
object1 An object containing additional properties to merge in.
objectN Additional objects containing properties to merge in.
deep If true, the merge becomes recursive (aka. deep copy).

using of $.extend() in bootstrapSource
1
2
3
4
5
6
7
8
9
10
11
12
var Typeahead = function (element, options) {
    this.$element = $(element)
    this.options = $.extend({}, $.fn.typeahead.defaults, options)
    this.matcher = this.options.matcher || this.matcher
    this.sorter = this.options.sorter || this.sorter
    this.highlighter = this.options.highlighter || this.highlighter
    this.updater = this.options.updater || this.updater
    this.$menu = $(this.options.menu).appendTo('body')
    this.source = this.options.source
    this.shown = false
    this.listen()
}

jQuery.grep( array, function(elementOfArray, indexInArray) [, invert] ) Returns: Array

Finds the elements of an array which satisfy a filter function. The original array is not affected.

array The array to search through.
function(elementOfArray, indexInArray) The function to process each item against. The first argument to the function is the item, and the second argument is the index. The function should return a Boolean value. this will be the global window object.
invert If “invert” is false, or not provided, then the function returns an array consisting of all elements for which “callback” returns true. If “revert” is true, then the function returns an array consisting of all elements for which “callback” returns false.
https://github.com/fedcuit/bootstrap/blob/master/js/bootstrap-typeahead.js#L90

using of $.grep() in bootstrapSource
1
2
3
items = $.grep(this.source, function (item) {
        return that.matcher(item)
        })

Mac配置Octopress问题汇集

| Comments

Psych::SyntaxError

在mac上安装完octopress后执行rake new_post[\title\]提示下面的错误信息:

1
~/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/psych.rb:148:in `parse': couldn't parse YAML at line 4 column 0 (Psych::SyntaxError)`

解决办法:

打开文件 ~/.rvm/gems/ruby-1.9.2-p320/gems/jekyll-0.11.2/lib/jekyll/convertible.rb, 将下面的代码添加到文件首部:

1
2
require 'yaml'
YAML::ENGINE.yamler = 'syck'

YAML Exception

执行rake generate后提示下面的错误消息:

1
2
3
4
5
6
## Generating Site with Jekyll
unchanged sass/screen.scss
Configuration from /Users/edfeng/workspace/octopress/_config.yml
Building site: source -> public
YAML Exception reading 2012-08-02-config-octopress-on-mac.markdown: syntax error on line 7, col -1: `'
Successfully generated site: source -> public'`

解决办法:
出现上面的错误是因为markdown文件的文件头没有遵循yaml规范: yaml文件中冒号后面必须有空格

执行rake generate后提示下面的错误消息:

1
invalid byte sequence in US-ASCII

解决办法:
将下面两句添加到.bashrc中:

1
2
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

Shell Commands Collection

| Comments

User Management

  • Add group sudo groupadd groupname
  • Add user and specify group and home folder sudo useradd username -g groupname -d path_to_home_folder
  • Add user home folder mkdir /path/to/home_folder && sudo chmod -R groupname:username /path/to/home_folder
  • Set password for user sudo passwd username
  • Add existing user to exising group sudo usermod -a -G groupname username
  • Check user information id will show up username, primary group name and all group names
  • Switch user su [username] if no username specified, default switch to supersuer
  • Switch user and load simimar environment as if it’s a direct user login su - username
  • Add user to sudoer list sudo adduser username sudo

Terminal/Console

  • Delete one words before cursor <CTRL+w>
  • Delete all words after cursor <CTRL+k>
  • Move to head of line <CTRL+a>
  • Move to end of line <CTRL+e>
  • Clean line <CTRL+u>
  • Clean screen <CTRL+l>

  • Paste last parameter of last command <ESC+.>

  • Generate random number echo $RANDOM

  • Show full path ls -d $PWD/*

Network

  • MAC refresh DNS sudo dscacheutil -flushcache or sudo discoveryutil udnsflushcaches
  • Windows refresh DNS ipconfig /flushdns
  • Linux refresh DNS sudo /etc/init.d/networking restart
  • show public IP curl ifconfig.me
  • show local DNS cat /etc/resolv.conf
  • Resolve Agent admitted failure to sign using the key
    • generate private key and public key on machine ssh-keygen
    • (ssh-add ~/.ssh/id_dsa.pub) add content of local public key to remote machine’s ~/.ssh/authorized_keys
    • specify location of private key on local machine ssh-add ~/.ssh/id_dsa

File System

  • Check total size of a folder du -shm
    • -s — summarize the sizes of all available files in a folder
    • -h — show resulted value in Human readable format
    • -m — show the result in Megabytes

VIM

  • save read-only file :w !sudo tee %

  • Change to uppercase visual + U

  • Change to lowercase visual + u
  • Toggle case visual + ~

Gnome

  • Fix the problem that title bar dispear on ubuntu compiz-decorator --replace

File Operation

  • Batch moZipve files mv src_folder1 src_folder2 src_folder3 -t dest_folder
  • Compress a folder into zip file zip -r filename.zip folder_name